public static void SendHeartbeat(string fileName, bool isWrite) { PythonCliParameters.Key = ApiKey; PythonCliParameters.File = fileName; PythonCliParameters.Plugin = string.Format("{0}/{1} {2}/{3}", WakaTimeConstants.EditorName, WakaTimeConstants.EditorVersion, WakaTimeConstants.PluginName, WakaTimeConstants.PluginVersion); PythonCliParameters.IsWrite = isWrite; PythonCliParameters.Project = GetProjectName(); var pythonBinary = PythonManager.GetPython(); if (pythonBinary != null) { var process = new RunProcess(pythonBinary, PythonCliParameters.ToArray()); if (Debug) { Logger.Debug(string.Format("[\"{0}\", \"{1}\"]", pythonBinary, string.Join("\", \"", PythonCliParameters.ToArray(true)))); process.Run(); Logger.Debug(string.Format("CLI STDOUT: {0}", process.Output)); Logger.Debug(string.Format("CLI STDERR: {0}", process.Error)); } else { process.RunInBackground(); } if (!process.Success) { Logger.Error(string.Format("Could not send heartbeat: {0}", process.Error)); } } else { Logger.Error("Could not send heartbeat because python is not installed"); } }
public static void SendHeartbeat(string windowTitle) { PythonCliParameters.Key = ApiKey; PythonCliParameters.Entity = windowTitle; PythonCliParameters.Plugin = $"{WakaTimeConstants.PluginName}/{_version}"; var pythonBinary = PythonManager.GetPython(); if (pythonBinary != null) { var process = new RunProcess(pythonBinary, PythonCliParameters.ToArray()); if (Debug) { Logger.Debug($"[\"{pythonBinary}\", \"{string.Join("\", \"", PythonCliParameters.ToArray(true))}\"]"); process.Run(); Logger.Debug($"CLI STDOUT: {process.Output}"); Logger.Debug($"CLI STDERR: {process.Error}"); } else { process.RunInBackground(); } if (!process.Success) { Logger.Error($"Could not send heartbeat: {process.Error}"); } } else { Logger.Error("Could not send heartbeat because python is not installed"); } }
public void InitializeAsync() { try { Logger.Info(string.Format("Initializing WakaTime v{0}", WakaTimeConstants.PluginVersion)); // VisualStudio Object _docEvents = ObjDte.Events.DocumentEvents; _windowEvents = ObjDte.Events.WindowEvents; _solutionEvents = ObjDte.Events.SolutionEvents; // Settings Form _settingsForm = new SettingsForm(); _settingsForm.ConfigSaved += SettingsFormOnConfigSaved; try { // Make sure python is installed if (!PythonManager.IsPythonInstalled()) { Downloader.DownloadAndInstallPython(); } if (!DoesCliExist() || !IsCliLatestVersion()) { Downloader.DownloadAndInstallCli(); } } catch (WebException ex) { Logger.Error("Are you behind a proxy? Try setting a proxy in iTimeTrack Settings with format https://user:pass@host:port. Exception Traceback:", ex); } catch (Exception ex) { Logger.Error("Error detecting dependencies. Exception Traceback:", ex); } // Add our command handlers for menu (commands must exist in the .vsct file) var mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (mcs != null) { // Create the command for the menu item. var menuCommandId = new CommandID(GuidList.GuidWakaTimeCmdSet, (int)PkgCmdIdList.UpdateWakaTimeSettings); var menuItem = new MenuCommand(MenuItemCallback, menuCommandId); mcs.AddCommand(menuItem); } // setup event handlers _docEvents.DocumentOpened += DocEventsOnDocumentOpened; _docEvents.DocumentSaved += DocEventsOnDocumentSaved; _windowEvents.WindowActivated += WindowEventsOnWindowActivated; _solutionEvents.Opened += SolutionEventsOnOpened; Logger.Info(string.Format("Finished initializing WakaTime v{0}", WakaTimeConstants.PluginVersion)); } catch (Exception ex) { Logger.Error("Error initializing Wakatime", ex); } }
static bool IsCliLatestVersion() { var process = new RunProcess(PythonManager.GetPython(), PythonCliParameters.Cli, "--version"); process.Run(); if (process.Success) { var currentVersion = process.Error.Trim(); Logger.Info(string.Format("Current wakatime-cli version is {0}", currentVersion)); Logger.Info("Checking for updates to wakatime-cli..."); var latestVersion = WakaTimeConstants.LatestWakaTimeCliVersion(); if (currentVersion.Equals(latestVersion)) { Logger.Info("wakatime-cli is up to date."); return(true); } else { Logger.Info(string.Format("Found an updated wakatime-cli v{0}", latestVersion)); } } return(false); }
static public void Download() { string url = PythonManager.GetPythonDownloadUrl(); www = new WWW(url); EditorApplication.update = WhileDownloading; }
public static void SendHeartbeat(PythonCliParameters cliParameters) { var pythonBinary = PythonManager.GetPython(); if (pythonBinary != null) { var process = new RunProcess(pythonBinary, cliParameters.ToArray()); if (WakaTimeConfigFile.Debug) { Logger.Debug(string.Format("[\"{0}\", \"{1}\"]", pythonBinary, string.Join("\", \"", cliParameters.ToArray(true)))); process.Run(); Logger.Debug(string.Format("CLI STDOUT: {0}", process.Output)); Logger.Debug(string.Format("CLI STDERR: {0}", process.Error)); } else { process.RunInBackground(); } if (!process.Success) { Logger.Error(string.Format("Could not send heartbeat: {0}", process.Error)); } } else { Logger.Error("Could not send heartbeat because python is not installed"); } }
static void DownloadCompleted() { EditorUtility.ClearProgressBar(); if (Main.IsDebug) { UnityEngine.Debug.Log("Python downloaded: " + www.size.ToString()); } string dir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData); string localFile = dir + PythonManager.GetPythonFileName(); try { System.IO.FileStream stream = new System.IO.FileStream(localFile, System.IO.FileMode.Create, System.IO.FileAccess.Write); stream.Write(www.bytes, 0, www.bytes.Length); // close file stream stream.Close(); www = null; } catch (Exception ex) { if (Main.IsDebug) { UnityEngine.Debug.LogError("Python download failed: " + ex.Message); } } Install(); }
public void Initialize() { SetNotifyIconToolTip(); _version = $"{CoreAssembly.Version.Major}.{CoreAssembly.Version.Minor}.{CoreAssembly.Version.Build}"; try { Logger.Info($"Initializing WakaTime v{_version}"); SettingsForm = new SettingsForm(); SettingsForm.ConfigSaved += SettingsFormOnConfigSaved; _wakaTimeConfigFile = new WakaTimeConfigFile(); // Make sure python is installed if (!PythonManager.IsPythonInstalled()) { var dialogResult = MessageBox.Show(@"Let's download and install Python now?", @"WakaTime requires Python", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.Yes) { var url = PythonManager.PythonDownloadUrl; Downloader.DownloadPython(url, WakaTimeConstants.UserConfigDir); } else { MessageBox.Show( @"Please install Python (https://www.python.org/downloads/) and restart Visual Studio to enable the WakaTime plugin.", @"WakaTime", MessageBoxButtons.OK, MessageBoxIcon.Information); } } if (!DoesCliExist() || !IsCliLatestVersion()) { try { Directory.Delete($"{WakaTimeConstants.UserConfigDir}\\wakatime-master", true); } catch { /* ignored */ } Downloader.DownloadCli(WakaTimeConstants.CliUrl, WakaTimeConstants.UserConfigDir); } GetSettings(); if (string.IsNullOrEmpty(ApiKey)) { PromptApiKey(); } StartListeningForWindowChanges(); Logger.Info($"Finished initializing WakaTime v{_version}"); } catch (Exception ex) { Logger.Error("Error initializing Wakatime", ex); } }
static bool IsCliLatestVersion() { var process = new RunProcess(PythonManager.GetPython(), PythonCliParameters.Cli, "--version"); process.Run(); var wakatimeVersion = WakaTimeConstants.CurrentWakaTimeCliVersion(); return(process.Success && process.Error.Equals(wakatimeVersion)); }
static bool IsCliLatestVersion() { var process = new RunProcess(PythonManager.GetPython(), GetCliPath(), "--version"); process.Run(); var version = GetLatestWakaTimeCliVersion(); return(process.Success && process.Error.Equals(version.ToString())); }
public static void HeartBeat(string apiKey, string file, bool write = false) { if (!PythonManager.IsPythonInstalled()) { return; } string arguments = "--key " + apiKey + " --file " + "\"" + file + "\"" + " --plugin " + WakaTimeConstants.PLUGIN_NAME + " --project " + Main.GetProjectName() + " --verbose"; if (Main.IsDebug) { UnityEngine.Debug.Log("Sending file: " + PythonManager.GetPythonPath() + " " + GetClientPath() + " " + arguments); } Process p = new Process { StartInfo = { FileName = PythonManager.GetPythonPath(), Arguments = "\"" + GetClientPath() + "\" " + arguments, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, WorkingDirectory = Application.dataPath, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true } }; p.Start(); if (Main.IsDebug) { var output = p.StandardOutput.ReadToEnd(); if (output.Length > 0) { UnityEngine.Debug.Log("Wakatime Output: " + output); } var errors = p.StandardError.ReadToEnd(); if (errors.Length > 0) { UnityEngine.Debug.LogError("Wakatime Error: " + errors); } } p.Close(); }
static public void DownloadAndInstall() { if (!PythonManager.IsPythonInstalled()) { if (!IsDownloaded()) { Download(); } else { Install(); } } }
public static bool CheckPython() { bool isInstalled = PythonManager.IsPythonInstalled(); if (IsEnabled && !isInstalled && !PythonInstaller.IsInstalling()) { if (EditorUtility.DisplayDialog("Python is required", "The plugin is about to install Python. Do you want to continue?", "Install Python", "Disable Wakatime")) { PythonInstaller.DownloadAndInstall(); } else { IsEnabled = false; } } return(isInstalled); }
private static void InitializeWakaTimeAsync() { // Make sure python is installed if (!PythonManager.IsPythonInstalled()) { Downloader.DownloadAndInstallPython(); } if (!DoesCliExist() || !IsCliLatestVersion()) { Downloader.DownloadAndInstallCli(); } if (string.IsNullOrEmpty(ApiKey)) { PromptApiKey(); } }
/// <summary> /// Sends a heart-beat to wakatime. /// Only works if the client is not installed. /// </summary> /// <param name="apiKey"></param> /// <param name="projectName"></param> /// <param name="file"></param> /// <param name="dataPath"></param> /// <param name="clientPath"></param> protected static void MakeRequest(string apiKey, string file, string projectName, string dataPath, string clientPath) { try { string arguments = "--key " + apiKey + " --file " + "\"" + file + "\"" + " --plugin " + WakaTimeConstants.PLUGIN_NAME + " --project " + "\"" + projectName + "\"" + " --verbose"; if (Main.IsDebug) { UnityEngine.Debug.Log("[wakatime] Sending file: " + file); } Process p = new Process { StartInfo = { FileName = PythonManager.GetPythonPath(), Arguments = "\"" + clientPath + "\" " + arguments, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, WorkingDirectory = dataPath, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, } }; p.Start(); p.WaitForExit(5000); UnityEngine.Debug.Log("[wakatime] Finished sending file " + file); } catch (Exception ex) { if (Main.IsDebug) { UnityEngine.Debug.LogError("[wakatime] Error found while sending heartbeat to wakatime for file " + file + ": " + ex); } } }
public static void HeartBeat(string apiKey, string file, bool write = false) { if (PythonManager.IsPythonInstalled()) { string arguments = "--key " + apiKey + " --file " + file + " --plugin " + WakaTimeConstants.PLUGIN_NAME + " --project " + Main.GetProjectName() + " --verbose"; if (Main.IsDebug) { UnityEngine.Debug.Log("Sending file: " + PythonManager.GetPythonPath() + " " + GetClientPath() + " " + arguments); } Process p = new Process(); p.StartInfo.FileName = PythonManager.GetPythonPath(); p.StartInfo.Arguments = GetClientPath() + " " + arguments; p.StartInfo.CreateNoWindow = true; p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; p.StartInfo.WorkingDirectory = Application.dataPath; #if UNITY_EDITOR_WIN p.StartInfo.UseShellExecute = true; #else p.StartInfo.UseShellExecute = false; #endif p.Start(); // UnityEngine.Debug.Log (p.StandardOutput.ReadToEnd ()); // UnityEngine.Debug.Log (p.StandardError.ReadToEnd ()); p.Close(); } }
public void CheckPrerequisites() { PythonManager.Initialize(); }
static string GetFilePath() { return(GetFileFolder() + PythonManager.GetPythonFileName()); }
public void InitializeAsync() { try { Logger.Info(string.Format("Initializing WakaTime v{0}", WakaTimeConstants.PluginVersion)); // VisualStudio Object objDte = (DTE2)GetService(typeof(DTE)); _docEvents = objDte.Events.DocumentEvents; _windowEvents = objDte.Events.WindowEvents; _solutionEvents = objDte.Events.SolutionEvents; // Settings Form _settingsForm = new SettingsForm(); _settingsForm.ConfigSaved += SettingsFormOnConfigSaved; // Load config file _wakaTimeConfigFile = new WakaTimeConfigFile(); GetSettings(); try { // Make sure python is installed if (!PythonManager.IsPythonInstalled()) { Downloader.DownloadAndInstallPython(); } if (!DoesCliExist() || !IsCliLatestVersion()) { try { Directory.Delete(Path.Combine(WakaTimeConstants.UserConfigDir, "wakatime-master"), true); } catch { /* ignored */ } Downloader.DownloadAndInstallCli(); } } catch (System.Net.WebException ex) { Logger.Error("Are you behind a proxy? Try setting a proxy in WakaTime Settings with format https://user:pass@host:port. Exception Traceback:", ex); } if (string.IsNullOrEmpty(ApiKey)) { PromptApiKey(); } // Add our command handlers for menu (commands must exist in the .vsct file) var mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (mcs != null) { // Create the command for the menu item. var menuCommandId = new CommandID(GuidList.GuidWakaTimeCmdSet, (int)PkgCmdIdList.UpdateWakaTimeSettings); var menuItem = new MenuCommand(MenuItemCallback, menuCommandId); mcs.AddCommand(menuItem); } // setup event handlers _docEvents.DocumentOpened += DocEventsOnDocumentOpened; _docEvents.DocumentSaved += DocEventsOnDocumentSaved; _windowEvents.WindowActivated += WindowEventsOnWindowActivated; _solutionEvents.Opened += SolutionEventsOnOpened; Logger.Info(string.Format("Finished initializing WakaTime v{0}", WakaTimeConstants.PluginVersion)); } catch (Exception ex) { Logger.Error("Error initializing Wakatime", ex); } }
public void InitializeAsync() { _version = string.Format("{0}.{1}.{2}", CoreAssembly.Version.Major, CoreAssembly.Version.Minor, CoreAssembly.Version.Build); try { Logger.Info(string.Format("Initializing WakaTime v{0}", _version)); base.Initialize(); _objDte = (DTE2)GetService(typeof(DTE)); _docEvents = _objDte.Events.DocumentEvents; _windowEvents = _objDte.Events.WindowEvents; _solutionEvents = _objDte.Events.SolutionEvents; _editorVersion = _objDte.Version; _settingsForm = new SettingsForm(); _settingsForm.ConfigSaved += SettingsFormOnConfigSaved; _wakaTimeConfigFile = new WakaTimeConfigFile(); // Make sure python is installed if (!PythonManager.IsPythonInstalled()) { var dialogResult = MessageBox.Show(@"Let's download and install Python now?", @"WakaTime requires Python", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.Yes) { var url = PythonManager.PythonDownloadUrl; Downloader.DownloadPython(url, WakaTimeConstants.UserConfigDir); } else { MessageBox.Show( @"Please install Python (https://www.python.org/downloads/) and restart Visual Studio to enable the WakaTime plugin.", @"WakaTime", MessageBoxButtons.OK, MessageBoxIcon.Information); } } if (!DoesCliExist() || !IsCliLatestVersion()) { try { Directory.Delete(string.Format("{0}\\wakatime-master", WakaTimeConstants.UserConfigDir), true); } catch { /* ignored */ } Downloader.DownloadCli(WakaTimeConstants.CliUrl, WakaTimeConstants.UserConfigDir); } GetSettings(); if (string.IsNullOrEmpty(ApiKey)) { PromptApiKey(); } // Add our command handlers for menu (commands must exist in the .vsct file) var mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (mcs != null) { // Create the command for the menu item. var menuCommandId = new CommandID(GuidList.GuidWakaTimeCmdSet, (int)PkgCmdIdList.UpdateWakaTimeSettings); var menuItem = new MenuCommand(MenuItemCallback, menuCommandId); mcs.AddCommand(menuItem); } // setup event handlers _docEvents.DocumentOpened += DocEventsOnDocumentOpened; _docEvents.DocumentSaved += DocEventsOnDocumentSaved; _windowEvents.WindowActivated += WindowEventsOnWindowActivated; _solutionEvents.Opened += SolutionEventsOnOpened; Logger.Info(string.Format("Finished initializing WakaTime v{0}", _version)); } catch (Exception ex) { Logger.Error("Error initializing Wakatime", ex); } }
private static void ProcessHeartbeats() { var pythonBinary = PythonManager.GetPython(); #if NET35 if (pythonBinary == null || string.IsNullOrEmpty(pythonBinary.Trim())) #else if (string.IsNullOrWhiteSpace(pythonBinary)) #endif { Logger.Error("Could not send heartbeat because python is not installed"); return; } // get first heartbeat from queue var gotOne = heartbeatQueue.TryDequeue(out Heartbeat heartbeat); if (!gotOne) { return; } // remove all extra heartbeats from queue var extraHeartbeats = new List <Heartbeat>(); while (heartbeatQueue.TryDequeue(out Heartbeat hbOut)) { extraHeartbeats.Add(hbOut.Clone()); } var hasExtraHeartbeats = extraHeartbeats.Any(); var cliParams = new PythonCliParameters { Key = WakaTimeConfigFile.ApiKey, Plugin = string.Format("{0}/{1} {2}/{3}", editorInfo.Name, editorInfo.Version, editorInfo.PluginKey, editorInfo.PluginVersion), File = heartbeat.FileName, Time = heartbeat.Timestamp, IsWrite = heartbeat.IsWrite, HasExtraHeartbeats = hasExtraHeartbeats, }; string extraHeartbeatsJSON = null; if (hasExtraHeartbeats) { #if NET45 var serializer = new JavaScriptSerializer(); serializer.RegisterConverters(new JavaScriptConverter[] { new DataContractJavaScriptConverter(true) }); extraHeartbeatsJSON = serializer.Serialize(extraHeartbeats); #else extraHeartbeatsJSON = JsonConvert.SerializeObject(extraHeartbeats, Formatting.None); #endif } var process = new RunProcess(pythonBinary, cliParams.ToArray()); if (WakaTimeConfigFile.Debug) { Logger.Debug(string.Format("[\"{0}\", \"{1}\"]", pythonBinary, string.Join("\", \"", cliParams.ToArray(true)))); process.Run(extraHeartbeatsJSON); if (process.Output != null && process.Output != "") { Logger.Debug(process.Output); } if (process.Error != null && process.Error != "") { Logger.Debug(process.Error); } } else { process.RunInBackground(extraHeartbeatsJSON); } if (!process.Success) { Logger.Error("Could not send heartbeat."); if (process.Output != null && process.Output != "") { Logger.Error(process.Output); } if (process.Error != null && process.Error != "") { Logger.Error(process.Error); } } }
/// <summary>Implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being loaded.</summary> /// <param term='application'>Root object of the host application.</param> /// <param term='connectMode'>Describes how the Add-in is being loaded.</param> /// <param term='addInInst'>Object representing this Add-in.</param> /// <seealso class='IDTExtensibility2' /> public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) { Logger.Info(string.Format("Initializing WakaTime v{0}", _version)); try { _applicationObject = (DTE2)application; _addInInstance = (AddIn)addInInst; _editorVersion = _applicationObject.Version; _docEvents = _applicationObject.Events.DocumentEvents; _docEvents.DocumentOpened += DocEventsOnDocumentOpened; _docEvents.DocumentSaved += DocEventsOnDocumentSaved; _windowsEvents = _applicationObject.Events.WindowEvents; _windowsEvents.WindowActivated += WindowsEventsOnWindowActivated; if (connectMode == ext_ConnectMode.ext_cm_UISetup) { object[] contextGUIDS = new object[] { }; Commands2 commands = (Commands2)_applicationObject.Commands; string toolsMenuName = "Tools"; //Place the command on the tools menu. //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items: CommandBar menuBarCommandBar = ((CommandBars)_applicationObject.CommandBars)["MenuBar"]; //Find the Tools command bar on the MenuBar command bar: CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName]; CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl; //This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in, // just make sure you also update the QueryStatus/Exec method to include the new command names. try { //Add a command to the Commands collection: Command command = commands.AddNamedCommand2(_addInInstance, "WakaTime", "WakaTime", "WakaTime Settings", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); //Add a control for the command to the tools menu: if ((command != null) && (toolsPopup != null)) { command.AddControl(toolsPopup.CommandBar, 1); } } catch (ArgumentException) { //If we are here, then the exception is probably because a command with that name // already exists. If so there is no need to recreate the command and we can // safely ignore the exception. } } // Make sure python is installed if (!PythonManager.IsPythonInstalled()) { var url = PythonManager.PythonDownloadUrl; Downloader.DownloadPython(url, WakaTimeConstants.UserConfigDir); } if (!DoesCliExist() || !IsCliLatestVersion()) { try { Directory.Delete(string.Format("{0}\\wakatime-master", WakaTimeConstants.UserConfigDir), true); } catch { /* ignored */ } Downloader.DownloadCli(WakaTimeConstants.CliUrl, WakaTimeConstants.UserConfigDir); } GetSettings(); if (string.IsNullOrEmpty(ApiKey)) { PromptApiKey(); } Logger.Info(string.Format("Finished initializing WakaTime v{0}", _version)); } catch (Exception ex) { Logger.Error("Error initializing Wakatime", ex); } }