/// <summary> /// Gets an object with the latest release info /// </summary> public static void CheckForUpdate(bool alwaysGetFeedBack) { if (_latestReleaseInfo != null) { // we already checked and there is a new version if (!_warnedUserAboutUpdateAvail || alwaysGetFeedBack) { NotifyUpdateAvailable(); } return; } if (_checking) { return; } try { var wb = new WebServiceJson(WebServiceJson.WebRequestMethod.Get, Config.ReleasesApi); wb.TimeOut = 3000; wb.OnRequestEnded += json => WbOnOnRequestEnded(json, alwaysGetFeedBack); wb.Execute(); } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error when checking for updates"); } }
public static void DisplayBugs() { var wb = new WebServiceJson(WebServiceJson.WebRequestMethod.Get, Config.BugsGetWebWervice); wb.OnRequestEnded += webServ => { if (webServ.StatusCodeResponse != HttpStatusCode.OK) { UserCommunication.Notify(webServ.ResponseException.ToString()); } else { UserCommunication.Notify(webServ.JsonResponse); } }; wb.Execute(); }
/// <summary> /// Sends the given report to the web service of 3P /// </summary> private static void SendBugReport(ExceptionInfo bugReport) { var wb = new WebServiceJson(WebServiceJson.WebRequestMethod.Post, Config.BugsPostWebWervice); wb.Serialize(bugReport); // save the request in a file var fileName = Path.Combine(Config.FolderLog, "unreported_" + DateTime.Now.ToString("yy.MM.dd_HH-mm-ss_") + _nbErrors++ + ".json"); Utils.FileWriteAllText(fileName, wb.JsonRequest.ToString()); wb.OnRequestEnded += webServ => { // request ok -> delete the json if (webServ.StatusCodeResponse == HttpStatusCode.OK) { Utils.DeleteFile(fileName); } }; wb.Execute(); }
/// <summary> /// This method pings a webservice deployed for 3P, it simply allows to do /// statistics on the number of users of the software /// </summary> public static void Ping() { try { DateTime lastPing; if (!DateTime.TryParseExact(Config.Instance.TechnicalLastPing, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out lastPing)) { lastPing = DateTime.MinValue; } // ping once every hour if (DateTime.Now.Subtract(lastPing).TotalMinutes > 59) { var webServiceJson = new WebServiceJson(WebServiceJson.WebRequestMethod.Post, Config.PingPostWebWervice); webServiceJson.AddToReq("UUID", UniqueId); webServiceJson.AddToReq("userName", Name); webServiceJson.AddToReq("version", AssemblyInfo.Version); webServiceJson.OnRequestEnded += req => { if (req.StatusCodeResponse == HttpStatusCode.OK) { Config.Instance.TechnicalLastPing = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } }; webServiceJson.Execute(); } } catch (Exception e) { if (Config.IsDevelopper) ErrorHandler.ShowErrors(e); } }
/// <summary> /// Sends an comment to a given GITHUB issue url /// </summary> /// <param name="message"></param> /// <param name="url"></param> public static bool SendComment(string message, string url) { // https://api.github.com/repos/jcaillon/3p/issues/1/comments // handle spam (10s min between 2 posts) if (Utils.IsSpamming("SendComment", 10000)) return false; var wb = new WebServiceJson(WebServiceJson.WebRequestMethod.Post, url); // Convert.ToBase64String(Encoding.ASCII.GetBytes("user:mdp")); wb.OnInitHttpWebRequest += request => request.Headers.Add("Authorization", "Basic " + Config._3PUserCredentials); wb.AddToReq("body", "### " + Environment.UserName + " (" + Environment.MachineName + ") ###\r\n" + "#### 3P version : " + AssemblyInfo.Version + ", Notepad++ version : " + Npp.GetNppVersion + " ####\r\n" + message ); wb.Execute(); return false; }
/// <summary> /// Called when the gitub api for releases responses /// </summary> private static void WbOnOnRequestEnded(WebServiceJson webServiceJson, bool alwaysGetFeedBack) { try { if (webServiceJson.StatusCodeResponse == HttpStatusCode.OK && webServiceJson.ResponseException == null) { Config.Instance.LastCheckUpdateOk = true; // get the releases var releases = webServiceJson.DeserializeArray <ReleaseInfo>(); if (releases != null && releases.Count > 0) { // sort by descring order releases.Sort((o, o2) => o.tag_name.IsHigherVersionThan(o2.tag_name) ? -1 : 1); var localVersion = AssemblyInfo.Version; var outputBody = new StringBuilder(); foreach (var release in releases) { if (string.IsNullOrEmpty(release.tag_name)) { continue; } // For each version higher than the local one, append to the release body // Will be used to display the version log to the user if (release.tag_name.IsHigherVersionThan(localVersion) && (Config.Instance.UserGetsPreReleases || !release.prerelease) && release.assets != null && release.assets.Count > 0 && release.assets.Exists(asset => asset.name.EqualsCi(Config.FileGitHubAssetName))) { // in case something is undefined (but shouldn't happen) if (string.IsNullOrEmpty(release.tag_name)) { release.tag_name = "vX.X.X.X"; } if (string.IsNullOrEmpty(release.name)) { release.name = "unknown"; } if (string.IsNullOrEmpty(release.body)) { release.body = "..."; } if (string.IsNullOrEmpty(release.published_at)) { release.published_at = DateTime.Now.ToString(CultureInfo.CurrentCulture); } // h1 outputBody.AppendLine("## " + release.tag_name + " : " + release.name + " ##\n\n"); // body outputBody.AppendLine(release.body + "\n\n"); // the first higher release encountered is the latest if (_latestReleaseInfo == null) { _latestReleaseInfo = release; } } } // There is a distant version higher than the local one if (_latestReleaseInfo != null) { // to display all the release notes _latestReleaseInfo.body = outputBody.ToString(); // delete existing dir Utils.DeleteDirectory(Config.FolderUpdate, true); Utils.DownloadFile(_latestReleaseInfo.assets.First(asset => asset.name.EqualsCi(Config.FileGitHubAssetName)).browser_download_url, Config.FileLatestReleaseZip, OnDownloadFileCompleted); } else if (alwaysGetFeedBack) { UserCommunication.NotifyUnique("UpdateChecked", "Congratulations! You already possess the latest <b>" + (!Config.Instance.UserGetsPreReleases && !AssemblyInfo.IsPreRelease ? "stable" : "beta") + "</b> version of 3P!", MessageImg.MsgOk, "Update check", "You own the version " + AssemblyInfo.Version, null); } } } else { // failed to retrieve the list if (alwaysGetFeedBack || Config.Instance.LastCheckUpdateOk) { UserCommunication.NotifyUnique("ReleaseListDown", "For your information, I couldn't manage to retrieve the latest published version on github.<br><br>A request has been sent to :<br>" + Config.ReleasesApi.ToHtmlLink() + "<br>but was unsuccessul, you might have to check for a new version manually if this happens again.", MessageImg.MsgHighImportance, "Couldn't reach github", "Connection failed", null); } Config.Instance.LastCheckUpdateOk = false; // check if there is an update available in the Shared config folder if (!string.IsNullOrEmpty(Config.Instance.SharedConfFolder) && Directory.Exists(Config.Instance.SharedConfFolder)) { var potentialUpdate = Path.Combine(Config.Instance.SharedConfFolder, AssemblyInfo.AssemblyName); // if the .dll exists, is higher version and (the user get beta releases or it's a stable release) if (File.Exists(potentialUpdate) && Utils.GetDllVersion(potentialUpdate).IsHigherVersionThan(AssemblyInfo.Version) && (Config.Instance.UserGetsPreReleases || Utils.GetDllVersion(potentialUpdate).EndsWith(".0"))) { // copy to local update folder and warn the user if (Utils.CopyFile(potentialUpdate, Config.FileDownloadedPlugin)) { _latestReleaseInfo = new ReleaseInfo { name = "Updated from shared directory", tag_name = Utils.GetDllVersion(Config.FileDownloadedPlugin), prerelease = Utils.GetDllVersion(Config.FileDownloadedPlugin).EndsWith(".1"), published_at = "???", html_url = Config.UrlCheckReleases }; // write the version log Utils.FileWriteAllText(Config.FileVersionLog, @"This version has been updated from the shared directory" + Environment.NewLine + Environment.NewLine + @"Find more information on this release [here](" + Config.UrlCheckReleases + @")", Encoding.Default); // set up the update so the .dll file downloaded replaces the current .dll _3PUpdater.Instance.AddFileToMove(Config.FileDownloadedPlugin, AssemblyInfo.Location); NotifyUpdateAvailable(); } } } } } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error when checking the latest release "); } _checking = false; }
/// <summary> /// Sends the given report to the web service of 3P /// </summary> private static void SendBugReport(ExceptionInfo bugReport) { var wb = new WebServiceJson(WebServiceJson.WebRequestMethod.Post, Config.BugsPostWebWervice); wb.Serialize(bugReport); // save the request in a file var fileName = Path.Combine(Config.FolderLog, "unreported_" + DateTime.Now.ToString("yy.MM.dd_HH-mm-ss_") + _nbErrors++ + ".json"); Utils.FileWriteAllText(fileName, wb.JsonRequest.ToString()); wb.OnRequestEnded += webServ => { // request ok -> delete the json if (webServ.StatusCodeResponse == HttpStatusCode.OK) Utils.DeleteFile(fileName); }; wb.Execute(); }
/// <summary> /// Gets an object with the latest release info /// </summary> public static void CheckForUpdate(bool alwaysGetFeedBack) { if (_latestReleaseInfo != null) { // we already checked and there is a new version if (!_warnedUserAboutUpdateAvail || alwaysGetFeedBack) NotifyUpdateAvailable(); return; } if (_checking) return; try { var wb = new WebServiceJson(WebServiceJson.WebRequestMethod.Get, Config.ReleasesApi); wb.TimeOut = 3000; wb.OnRequestEnded += json => WbOnOnRequestEnded(json, alwaysGetFeedBack); wb.Execute(); } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error when checking for updates"); } }
/// <summary> /// Called when the gitub api for releases responses /// </summary> private static void WbOnOnRequestEnded(WebServiceJson webServiceJson, bool alwaysGetFeedBack) { try { if (webServiceJson.StatusCodeResponse == HttpStatusCode.OK && webServiceJson.ResponseException == null) { Config.Instance.LastCheckUpdateOk = true; // get the releases var releases = webServiceJson.DeserializeArray<ReleaseInfo>(); if (releases != null && releases.Count > 0) { // sort by descring order releases.Sort((o, o2) => o.tag_name.IsHigherVersionThan(o2.tag_name) ? -1 : 1); var localVersion = AssemblyInfo.Version; var outputBody = new StringBuilder(); foreach (var release in releases) { if (string.IsNullOrEmpty(release.tag_name)) continue; // For each version higher than the local one, append to the release body // Will be used to display the version log to the user if (release.tag_name.IsHigherVersionThan(localVersion) && (Config.Instance.UserGetsPreReleases || !release.prerelease) && release.assets != null && release.assets.Count > 0 && release.assets.Exists(asset => asset.name.EqualsCi(Config.FileGitHubAssetName))) { // in case something is undefined (but shouldn't happen) if (string.IsNullOrEmpty(release.tag_name)) release.tag_name = "vX.X.X.X"; if (string.IsNullOrEmpty(release.name)) release.name = "unknown"; if (string.IsNullOrEmpty(release.body)) release.body = "..."; if (string.IsNullOrEmpty(release.published_at)) release.published_at = DateTime.Now.ToString(CultureInfo.CurrentCulture); // h1 outputBody.AppendLine("## " + release.tag_name + " : " + release.name + " ##\n\n"); // body outputBody.AppendLine(release.body + "\n\n"); // the first higher release encountered is the latest if (_latestReleaseInfo == null) _latestReleaseInfo = release; } } // There is a distant version higher than the local one if (_latestReleaseInfo != null) { // to display all the release notes _latestReleaseInfo.body = outputBody.ToString(); // delete existing dir Utils.DeleteDirectory(Config.FolderUpdate, true); Utils.DownloadFile(_latestReleaseInfo.assets.First(asset => asset.name.EqualsCi(Config.FileGitHubAssetName)).browser_download_url, Config.FileLatestReleaseZip, OnDownloadFileCompleted); } else if (alwaysGetFeedBack) { UserCommunication.NotifyUnique("UpdateChecked", "Congratulations! You already possess the latest <b>" + (!Config.Instance.UserGetsPreReleases && !AssemblyInfo.IsPreRelease ? "stable" : "beta") + "</b> version of 3P!", MessageImg.MsgOk, "Update check", "You own the version " + AssemblyInfo.Version, null); } } } else { // failed to retrieve the list if (alwaysGetFeedBack || Config.Instance.LastCheckUpdateOk) UserCommunication.NotifyUnique("ReleaseListDown", "For your information, I couldn't manage to retrieve the latest published version on github.<br><br>A request has been sent to :<br>" + Config.ReleasesApi.ToHtmlLink() + "<br>but was unsuccessul, you might have to check for a new version manually if this happens again.", MessageImg.MsgHighImportance, "Couldn't reach github", "Connection failed", null); Config.Instance.LastCheckUpdateOk = false; // check if there is an update available in the Shared config folder if (!string.IsNullOrEmpty(Config.Instance.SharedConfFolder) && Directory.Exists(Config.Instance.SharedConfFolder)) { var potentialUpdate = Path.Combine(Config.Instance.SharedConfFolder, AssemblyInfo.AssemblyName); // if the .dll exists, is higher version and (the user get beta releases or it's a stable release) if (File.Exists(potentialUpdate) && Utils.GetDllVersion(potentialUpdate).IsHigherVersionThan(AssemblyInfo.Version) && (Config.Instance.UserGetsPreReleases || Utils.GetDllVersion(potentialUpdate).EndsWith(".0"))) { // copy to local update folder and warn the user if (Utils.CopyFile(potentialUpdate, Config.FileDownloadedPlugin)) { _latestReleaseInfo = new ReleaseInfo { name = "Updated from shared directory", tag_name = Utils.GetDllVersion(Config.FileDownloadedPlugin), prerelease = Utils.GetDllVersion(Config.FileDownloadedPlugin).EndsWith(".1"), published_at = "???", html_url = Config.UrlCheckReleases }; // write the version log Utils.FileWriteAllText(Config.FileVersionLog, @"This version has been updated from the shared directory" + Environment.NewLine + Environment.NewLine + @"Find more information on this release [here](" + Config.UrlCheckReleases + @")", Encoding.Default); // set up the update so the .dll file downloaded replaces the current .dll _3PUpdater.Instance.AddFileToMove(Config.FileDownloadedPlugin, AssemblyInfo.Location); NotifyUpdateAvailable(); } } } } } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error when checking the latest release "); } _checking = false; }