pascalabcnet/VisualPlugins/TraningControlPlugin/TeacherControlPlugin.cs
AlexanderZemlyak 342375501b
New languages engine (#3120)
* Implement first version of languages interfaces and classes

ParsersController заменен на LanguageProvider.

* Update ParserTools.csproj

* Update RemoteCompiler.cs

* Update TestRunner

* Rename LanguageIntegrator project to Languages

* Update TestRunner

* Rename Parsers folder

* Rename PascalABCParser.dll to PascalABCLanguage.dll

* Reorganise LanguageIntegrator and rename DocTagsParser

* Update Release Generators

* Update language loading messages

* Update linux version

* Move BaseParser fields to ILanguage interface

* Revert "Update Release Generators"

This reverts commit 26a991c71b81e643d9fbd9a815ddca222768dda9.

* Revert "Rename PascalABCParser.dll to PascalABCLanguage.dll"

* Clean the mess in parser folders

* Organize namespaces properly

* Revert "Rename LanguageIntegrator project to Languages"

* Add new enclosing folders for standard languages

* Organize namespaces of LanguageIntegrator properly

* Rename StandardLanguages to Languages

* Comment the rest of Visual basic source code

* Update OutputPath in pascal parser project

* Move BaseParser methods to IParser

* Restore Pascal parser project initial structure

* Add PascalLanguage project

* Move SyntaxTreeConverters project to Languages\Pascal folder

* Rename SemanticRules in parser project

* Rename Errors1 to Errors in parser project

* Delete LambdaConverter dll from installer

* Update language integrator to load *Language.dll files

* Move lambda converter project to pascal lanuage dir

* Revert "Delete LambdaConverter dll from installer"

This reverts commit dd56f559ebe4f8c4c5c33752d44e6953001b96a5.

* Switch off VBNETParser building

* Delete syntax tree converters controller

* Delete lambda converter dll from repository

* Reorganize syntax tree to semantic tree conversion stage

* Add BaseLanguage class to make language initialization more neat

* Delete syntax tree post processors entity from ILanguage and refactor ABCStatistics calls

* Add new IDocParser interface for documentation comments parser

* Clean up folders

* Add helper data structures to reduce parameters amount in CompileInterface and CompileImplementation

* Add documentation to language classes

* Move Union struct in global namespace and project (ParserTools)

* Add more comments and a safe select language method

* Rename SemanticRules class

* Fix directives format null bug

* Add System.Linq ref to LanguageIntegrator

* Delete SyntaxToSemanticTreeConverter interface

* Add BaseSyntaxTreeConverter

* Call safe select language method in intellisence

* Delete source files providers from parsers

* Rename GetSyntaxTree method

* Change Prebuild tree to be virtual - not abstract

* Refresh documentation a bit

* Add temporary language check for ABCHealth button

* Add parser reference to parser tools

* Move current compilation unit assigning higher to avoid bug with unit check

* Delete null DirectiveInfo's and refactor directives' code

* Add a few more comments
2024-05-25 12:26:32 +03:00

297 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using DBAccessPluginNamespace;
namespace VisualPascalABCPlugins
{
//имя класса *_VisualPascalABCPlugin
public class VisualPascalABCPlugin_TeacherControlPlugin : IExtendedVisualPascalABCPlugin
{
private const string LabelEntered = "Авторизация: ";
private const string LabelNotEntered = "Авторизация: вход не выполнен";
public static string StringsPrefix = "VPP_REGISTER_AND_CONTROL_PLUGIN_";
IVisualEnvironmentCompiler VisualEnvironmentCompiler;
IWorkbench Workbench;
//private TeacherControlForm RegisterForm = new TeacherControlForm(); // старая форма авторизации
//private LoginForm RegisterFormNew = new LoginForm(); // новая форма авторизации
// User
SiteAccessProvider User;
private PluginGUIItem Item;
public string Name { get => "Teacher Control Plugin"; }
public string Version { get => "0.1"; }
public string Copyright { get => "Copyright © 2021-2024 by Stanislav Mikhalkovich"; }
public string Login = null;
public string Password = null;
public LoginForm loginForm;
public ToolStripMenuItem menuItem = null;
public ToolStripButton toolStripButton = null;
// public string AuthFileFullName = "";
public bool IsMechmath;
public VisualPascalABCPlugin_TeacherControlPlugin(IWorkbench Workbench)
{
this.Workbench = Workbench;
VisualEnvironmentCompiler = Workbench.VisualEnvironmentCompiler;
User = new SiteAccessProvider();
if (IsLightPTInWorkingDirectory())
{
IsMechmath = System.Environment.MachineName.ToLower().StartsWith("mil8a-");
User.ServAddr = "https://air.mmcs.sfedu.ru/pascalabc";
loginForm = new LoginForm(this);
}
// RegisterForm.VisualEnvironmentCompiler = VisualEnvironmentCompiler; // Пока форма регистрации никак не связана с компилятором
// Регистрация обработчика
this.Workbench.ServiceContainer.RunService.Starting += RunStartingHandler;
this.Workbench.ServiceContainer.RunService.ChangeArgsBeforeRun += ChangeArgsBeforeRunHandler;
//Workbench.ServiceContainer.BuildService.BeforeCompile += BeforeCompileHandler;
}
public void Execute()
{
loginForm.SiteProvider = User;
loginForm.ShowDialog(); // OK никогда не будет
}
public void AddMessage(string text)
{
Workbench.CompilerConsoleWindow.AddTextToCompilerMessages(text + Environment.NewLine);
}
public void AddMessage(Exception e) => AddMessage(e.ToString());
public string WorkingDirectory()
{
var FileName = Workbench.ServiceContainer.DocumentService.CurrentCodeFileDocument.FileName;
return System.IO.Path.GetDirectoryName(FileName);
}
public string FullLightPTName()
{
var WorkingDir = WorkingDirectory();
var lightptname = Path.Combine(WorkingDir, "lightpt.dat");
if (File.Exists(lightptname))
return lightptname;
return "";
}
public bool IsLightPTInWorkingDirectory()
{
var WorkingDir = WorkingDirectory();
var lightptname = Path.Combine(WorkingDir, "lightpt.dat");
return File.Exists(lightptname);
}
public /*async*/ void TryLogin(string login, string pass)
{
// Гасим все исключения
try
{
var answer = User.Login("", login, pass);
if (answer.Result == "Success")
{
loginForm.ChangeControlsAfterLogin(login);
var Rating = User.GetRating("", login, pass);
loginForm.SetRating(Rating.Result);
}
}
catch (Exception e)
{
AddMessage(e);
}
}
public string FullAuthNameFromNETDisk()
{
var AuthFileFullName = "";
try
{
foreach (var drive in System.IO.DriveInfo.GetDrives())
{
if (drive.DriveType != System.IO.DriveType.Network)
continue;
// Проверять, что диск сетевой!!! Для несетевых - нет!
var auth = System.IO.Path.Combine(drive.Name, "auth.dat");
if (System.IO.File.Exists(auth))
AuthFileFullName = auth;
}
}
catch (Exception)
{ } // Тут исключение быть не может и даже если, то неинформативно
return AuthFileFullName;
}
public string FullAuthNameFromWorkingDirOrParent()
{
var AuthFileFullName = "";
try
{
var WorkingDir = WorkingDirectory();
var auth = Path.Combine(WorkingDir, "auth.dat");
var exists = false;
if (File.Exists(auth)) // искать auth в текущей папке. Если нет, то
exists = true;
else
{
auth = Path.Combine(WorkingDir, "..", "auth.dat"); // искать auth в папке на уровень выше
if (File.Exists(auth))
exists = true;
}
if (exists) // то в auth - его путь Преобразуем его в полный путь
{
var fi = new System.IO.FileInfo(auth);
AuthFileFullName = fi.FullName;
}
}
catch (Exception)
{ }
return AuthFileFullName;
}
public string CalcAuthFullName()
{
var AuthFileFullName = "";
// На мехмате - проверяю все диски на предмет существования в корне файла auth.dat
if (IsMechmath)
AuthFileFullName = FullAuthNameFromNETDisk();
else // Это домашний компьютер
AuthFileFullName = FullAuthNameFromWorkingDirOrParent();
return AuthFileFullName;
}
public void InitItems(List<IPluginGUIItem> MenuItems, List<IPluginGUIItem> ToolBarItems)
{
Item = new PluginGUIItem(StringsPrefix + "NAME", StringsPrefix + "DESCRIPTION", loginForm.PluginImage.Image, loginForm.PluginImage.BackColor, Execute);
MenuItems.Add(Item);
ToolBarItems.Add(Item);
}
public void GetGUI(List<IPluginGUIItem> MenuItems, List<IPluginGUIItem> ToolBarItems)
{
// Для студентов: если в рабочем каталоге нет lightpt.dat, то кнопки не появляются
// На самом деле надо еще проверять диск P: - точнее, сетевой диск с определенной меткой (например, в его корне лежит файл auth.dat
// if (!File.Exists(Path.Combine(WorkingDir,'lightpt.dat'))
// return;
// Scan disks
// Find NET disk with auth.dat in root
// if not - return
//var WorkingDirectory = Workbench.VisualEnvironmentCompiler.Compiler.CompilerOptions.SourceFileDirectory;
// При ручной авторизации - сохранение
// Мехмат: auth сохраняется в корень сетевого диска
// Дома: auth сохраняется в папке на уровень выше текущей. Если это невозможно, то в текущей папке.
// Если это диск C, то тоже не сохранять и тогда сохранять в текущей
// При запуске кнопки плагина показываются
// Дома: всегда у тех, у кого установлен плагин
// Мехмат: при наличии lightpt в текущей папке или при наличии auth.dat в корне сетевого диска !!!
//if (!IsMechmath) // дома - всегда
// InitItems(MenuItems, ToolBarItems);
//else // это мехмат
// SSM 20/06/22 Решил включить плагин в инсталлят и показывать кнопки только если есть lightpt.dat в текущем
// или auth.dat в корне сетевого - убрал это 11.07.23 - только если при запуске lightpt.dat в текущем!!!
{
if (IsLightPTInWorkingDirectory()) // если lightpt.dat существует в текущем
InitItems(MenuItems, ToolBarItems);
/*else
{
var AuthFileFullName = FullAuthNameFromNETDisk();
if (AuthFileFullName != "") // если auth.dat существует в корне сетевого диска
InitItems(MenuItems, ToolBarItems);
}*/
}
}
public void AfterAddInGUI()
{
if (Item == null) // Если не показали кнопки, то нет смысла в дальнейших действиях - плагин неактивен
{
AddMessage("TeacherControlPlugin deactivated"); // Не выполнено условие LightPTExists || AuthExists
return;
}
menuItem = (ToolStripMenuItem)Item.menuItem;
toolStripButton = (ToolStripButton)Item.toolStripButton;
// При запуске auth.dat ищется и делается попытка авторизации:
// Мехмат: в корне сетевого диска (только!). Если находится, делается попытка авторизации
// Дома: в текущей папке. Если нет, ищется в папке на уровень выше. Если находится, делается попытка авторизации
// При этом на мехмате не ищется lightpt.dat в текущем
// Версия. Разрешить на мехмате автоматически авторизоваться если заходим из папки с lightpt.dat
// А если его нет, то ищем auth в корне сетевого
// Последовательность поиска auth.dat на мехмате:
// В текущем, на уровень выше (только если в текущем есть lightpt) и на сетевом
try
{
// Попытка автоматического входа
// AuthFileFullName для мехмата был запомнен в GetGUI
// SSM 11/07/23 - нет, AuthFileFullName для мехмата отдельно теперь не перевычисляется для простоты!!!
// Нет - только на мехмате. Заполнить если дома!!!
// Думаю, здесь всё надо перевычислить. Начать с текущего, потом на уровень выше и потом в корень сетевого диска
// !!! НАДО ТУТ ИСКАТЬ lightpt.dat в текущем!!!
var AuthFileFullName = "";
if (IsLightPTInWorkingDirectory()) // Только если lightPT.dat в текущем, ищем auth.dat в текущем или выше
AuthFileFullName = FullAuthNameFromWorkingDirOrParent();
/*if (AuthFileFullName == "" && IsMechmath)
{
AuthFileFullName = FullAuthNameFromNETDisk();
}*/
if (AuthFileFullName != "")
{
//var ss = File.ReadAllLines(AuthFileFullName);
var ss = TeacherPluginUtils.ReadLoginPassFromAuth(AuthFileFullName);
if (ss.Length >= 2)
{
var login = ss[0];
var pass = ss[1];
// В TryLogin может быть исключение, которое не перехватывается этим кодом, т.к.в другом потоке
System.Threading.Tasks.Task.Run(() => TryLogin(login, pass));
}
}
}
catch (Exception e)
{
AddMessage(e); // И тут уже вывести причину. Она только в ReadLoginPassFromAuth может быть
}
}
private void RunStartingHandler(string filename)
{
}
private void ChangeArgsBeforeRunHandler(ref string args)
{
if (Item == null) // если нет кнопок с человечком, то в глобальную базу писаться не будет в принципе!
return;
args += " " + loginForm.Authorized.ToString();
if (loginForm.Authorized) // Параметр Текст программы добавляется только если зарегистрирован
{
var FileName = Workbench.ServiceContainer.DocumentService.CurrentCodeFileDocument.FileName;
var text = Workbench.VisualEnvironmentCompiler.StandartCompiler.GetSourceFileText(FileName);
if (text.Length > 5000)
text = text.Substring(0, 5000);
text = text.Replace("\\\"", "\\ \"");
text = text.Replace("\"", "\\\"");
args += " " + "\"" + text + "\"";
}
}
}
}