Skip to content

Commit 37b2853

Browse files
committed
Make sure people use correct API URL and token (+ few other changes)
And some other more-less cosmetical changes. Fix for calling UpdateStatusbar lot of times on window focus. This probably wasn't the cause of freezes (my window froze without triggering those), but it was still worth to optimize it I guess. Fix domain for stats.
1 parent 5552bea commit 37b2853

5 files changed

Lines changed: 142 additions & 42 deletions

File tree

CodeStats/CodeStatsPackage.cs

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,22 @@ class CodeStatsPackage
2525
static Bitmap tbBmp = Properties.Resources.CodeStats;
2626

2727
static ConfigFile _CodeStatsConfigFile;
28-
static CodeStats.Forms.SettingsForm _settingsForm;
28+
public static CodeStats.Forms.SettingsForm _settingsForm;
29+
public static CodeStats.Forms.ApiKeyForm _apikeyForm; // should be null if not needed
2930
static string _lastStatusBarDocTypeText;
3031
static DateTime _lastPulse = DateTime.Now;
3132
static DateTime _lastActivity = DateTime.Now;
3233
static int pulseFrequency = 10000; // ms
3334

3435
public static bool Debug;
3536
public static string ApiKey;
37+
public static string ApiUrl;
3638
public static string Proxy;
3739
public static bool Stats;
3840
public static string Guid;
3941

4042
public static bool _reportedStats = false;
41-
public static bool _shownInvalidApiTokenMessage = false;
43+
public static bool _hasAlreadyShownInvalidApiTokenMessage = false;
4244

4345
//public static string currentLangName = ""; // N++ (ex. HTML, not compatible with Code::Stats names everywhere)
4446
public static string currentLangDesc = ""; // N++ (ex. Hyper Text Markup Language)
@@ -66,6 +68,8 @@ internal static void CommandMenuInit()
6668
{
6769
InitializeAsync();
6870
});
71+
72+
//System.Diagnostics.Debugger.Launch();
6973
}
7074

7175
private static void InitializeAsync()
@@ -106,12 +110,12 @@ private static void InitializeAsync()
106110
{
107111
extensionMappingJson = string.Empty;
108112
Logger.Error("Exception when trying to download latest extension mappings, using local ones instead", ex);
109-
}
113+
} // update extension mapping JSON
110114
}
111115
catch
112116
{
113117
extensionMappingJson = string.Empty;
114-
}
118+
} // get webclient, set proxy, update extension mapping JSON
115119

116120
if (String.IsNullOrWhiteSpace(extensionMappingJson))
117121
{
@@ -150,9 +154,9 @@ private static void InitializeAsync()
150154
_CodeStatsConfigFile = new ConfigFile();
151155
GetSettings();
152156

157+
// Check for updates
153158
try
154159
{
155-
// Check for updates
156160
string latest = Constants.LatestPluginVersion();
157161
if (Constants.PluginVersion != latest && !String.IsNullOrWhiteSpace(latest))
158162
{
@@ -189,6 +193,7 @@ private static void InitializeAsync()
189193

190194
internal static void SetToolBarIcon()
191195
{
196+
// TODO: Maybe check out https://docs.microsoft.com/en-us/windows/desktop/controls/embed-nonbutton-controls-in-toolbars to create counter within toolbar as alternative?
192197
toolbarIcons tbIcons = new toolbarIcons();
193198
tbIcons.hToolbarBmp = tbBmp.GetHbitmap();
194199
IntPtr pTbIcons = Marshal.AllocHGlobal(Marshal.SizeOf(tbIcons));
@@ -212,17 +217,20 @@ public static void OnNotification(ScNotification notification)
212217
// TODO: NPPN_SHUTDOWN - save unpulsed to config (or do it in plugin unload sequence rather on bottom of this file)
213218
if (notification.Header.Code == (uint)NppMsg.NPPN_LANGCHANGED) // Does not seem to be triggered?
214219
{
220+
Logger.Debug("[notification] NPPN_LANGCHANGED");
215221
//currentLangDesc = GetCurrentLangDesc(); - below does this
216222
UpdateStatusbar();
217223
}
218224
if (notification.Header.Code == (uint)NppMsg.NPPN_READY) // IMPORTANT: It triggers SCN_MODIFIED for each opened file before this
219225
{
226+
Logger.Debug("[notification] NPPN_READY");
220227
nppStarted = true;
221228
UpdateStatusbar();
222229
}
223230
if (nppStarted && (notification.Header.Code == (uint)SciMsg.SCN_MODIFIED || notification.Header.Code == (uint)NppMsg.NPPN_TBMODIFICATION))
224231
{
225-
UpdateStatusbar();
232+
//Logger.Debug("[notification] SCN_MODIFIED #1");
233+
//UpdateStatusbar();
226234
}
227235

228236
/*if (notification.Header.Code == (uint)NppMsg.NPPN_FILESAVED) // It does count as 1 XP in Visual Studio Code, though not sure if intended!
@@ -245,24 +253,26 @@ public static void OnNotification(ScNotification notification)
245253

246254
if (notification.Header.Code == (uint)SciMsg.SCN_CHARADDED) // our best bet
247255
{
256+
Logger.Debug("[notification] SCN_CHARADDED");
248257
HandleActicity();
249-
Logger.Debug("SCN_CHARADDED - File: " + GetCurrentFile() + ", char: " + notification.character + ", lang: " + GetCurrentLanguage());
258+
if (Debug) Logger.Debug("SCN_CHARADDED - File: " + GetCurrentFile() + ", char: " + (char)notification.character + " (" + notification.character + "), lang: " + GetCurrentLanguage());
250259
}
251260

252261
int SC_PERFORMED_USER_AND_SC_MOD_DELETETEXT = (int)SciMsg.SC_PERFORMED_USER | (int)SciMsg.SC_MOD_DELETETEXT;
253262
if (nppStarted && notification.Header.Code == (uint)SciMsg.SCN_MODIFIED && ((notification.ModificationType & SC_PERFORMED_USER_AND_SC_MOD_DELETETEXT) == SC_PERFORMED_USER_AND_SC_MOD_DELETETEXT))
254263
{
264+
Logger.Debug("[notification] SCN_MODIFIED #2");
255265
// Looks like we can use this to track deleted stuff once Notepad++ is started and ready
256266
// It doesn't trigger on file close either, unlike on open with SC_MOD_INSERTTEXT, so we only use this, and SCN_CHARADDED for inserts
257267
// It will skip Ctrl+V if it wasn't pasted on some existing text, but never mind, it is still counting the most we want
258268
// And we would not like it to count random file opens or other actions in
259269
HandleActicity();
260-
Logger.Debug("SC_PERFORMED_USER & SC_MOD_DELETETEXT - File: " + GetCurrentFile() + ", char: " + notification.character + ", flags: " + notification.ModificationType.ToString("X"));
270+
if (Debug) Logger.Debug("SC_PERFORMED_USER & SC_MOD_DELETETEXT - File: " + GetCurrentFile() + ", char: " + notification.character + ", flags: " + notification.ModificationType.ToString("X"));
261271
}
262272

263273
if (notification.Header.Code == (uint)SciMsg.SCEN_CHANGE) // Does not seem to be ever triggered (ah, right, GTK+ only it seems?)
264274
{
265-
Logger.Debug("SCEN_CHANGE - File: " + GetCurrentFile() + ", char: " + notification.character + ", lang: " + GetCurrentLanguage());
275+
if (Debug) Logger.Debug("SCEN_CHANGE - File: " + GetCurrentFile() + ", char: " + notification.character + ", lang: " + GetCurrentLanguage());
266276
}
267277
// http://docs.notepad-plus-plus.org/index.php/Messages_And_Notifications
268278
// http://www.scintilla.org/ScintillaDoc.html
@@ -336,12 +346,14 @@ private static void ProcessPulses()
336346
var jsonSerializer = new JavaScriptSerializer();
337347

338348
string URL;
339-
if (String.IsNullOrWhiteSpace(_CodeStatsConfigFile.ApiUrl))
349+
bool usesCustomEndpoint = false;
350+
if (String.IsNullOrWhiteSpace(ApiUrl))
340351
{
341352
URL = Constants.ApiMyPulsesEndpoint;
342353
} else
343354
{
344-
URL = _CodeStatsConfigFile.ApiUrl;
355+
URL = ApiUrl;
356+
usesCustomEndpoint = true;
345357
}
346358
client.Headers[HttpRequestHeader.UserAgent] = Constants.PluginUserAgent;
347359
client.Headers[HttpRequestHeader.ContentType] = "application/json";
@@ -373,14 +385,33 @@ private static void ProcessPulses()
373385
if (ex.Status == WebExceptionStatus.ProtocolError)
374386
{
375387
var response = ex.Response as HttpWebResponse;
376-
if (response != null && (int)response.StatusCode == 403)
388+
if (response != null)
377389
{
378-
if (!_shownInvalidApiTokenMessage) // we want to inform user only once, and if he does not provide the token, let's not bomb him with error each time after he types something
390+
if ((int)response.StatusCode == 403)
391+
{
392+
Logger.Error("Could not pulse (error 403). Please make sure you entered a valid API token in Code::Stats settings.", ex);
393+
if (!_hasAlreadyShownInvalidApiTokenMessage) // we want to inform user only once, and if they do not provide the token, let's not bomb him with error each time after they type something
394+
{
395+
MessageBox.Show("Could not pulse. Please make sure you entered a valid API token in Code::Stats settings.\nAll recorded XP from this session will be lost if you do not provide the correct API token!", "Code::Stats – error 403", MessageBoxButtons.OK, MessageBoxIcon.Error);
396+
_hasAlreadyShownInvalidApiTokenMessage = true;
397+
PromptApiKey();
398+
}
399+
}
400+
else if ((int)response.StatusCode == 404 && usesCustomEndpoint)
379401
{
380-
MessageBox.Show("Could not pulse. Please make sure you entered a valid API token in Code::Stats settings.", "Code::Stats - error 403", MessageBoxButtons.OK, MessageBoxIcon.Error);
381-
_shownInvalidApiTokenMessage = true;
402+
Logger.Error("Could not pulse (error 404). The entered custom endpoint (" + URL + ") is invalid. ", ex);
403+
MessageBox.Show("Could not pulse. Invalid API endpoint URL. Please make sure you entered a valid API URL in Code::Stats settings or delete the value altogether to restore the default.\nAll recorded XP from this session will be lost if you do not provide the correct API URL path!", "Code::Stats – error 404", MessageBoxButtons.OK, MessageBoxIcon.Error);
404+
405+
//_settingsForm.txtAPIURL.Focus();
406+
//_settingsForm.txtAPIURL.SelectAll();
407+
_settingsForm.FocusTxtAPIURL();
408+
SettingsPopup();
409+
_settingsForm.ShowAPIURLTooltip();
410+
}
411+
else
412+
{
413+
Logger.Error("Could not pulse - HTTP error " + (int)response.StatusCode + ". ", ex);
382414
}
383-
Logger.Error("Could not pulse. Please make sure you entered a valid API token in Code::Stats settings.", ex);
384415
}
385416
else
386417
{
@@ -574,6 +605,7 @@ private static void GetSettings()
574605
{
575606
_CodeStatsConfigFile.Read();
576607
ApiKey = _CodeStatsConfigFile.ApiKey;
608+
ApiUrl = _CodeStatsConfigFile.ApiUrl;
577609
Debug = _CodeStatsConfigFile.Debug;
578610
Proxy = _CodeStatsConfigFile.Proxy;
579611
Stats = _CodeStatsConfigFile.Stats;
@@ -583,20 +615,21 @@ private static void GetSettings()
583615
private static void PromptApiKey()
584616
{
585617
Logger.Info("Please input your API token into the Code::Stats window.");
586-
var form = new CodeStats.Forms.ApiKeyForm();
587-
form.ShowDialog();
618+
/*var form*/_apikeyForm = new CodeStats.Forms.ApiKeyForm();
619+
_apikeyForm.ShowDialog();
588620
}
589621

590622
private static void SettingsPopup()
591623
{
624+
_settingsForm.Visible = false;
592625
_settingsForm.ShowDialog();
593626
}
594627

595628
public static void ReportStats()
596629
{
597630
var client = new WebClient { Proxy = CodeStatsPackage.GetProxy() };
598631
client.Headers[HttpRequestHeader.UserAgent] = Constants.PluginUserAgent;
599-
string HtmlResult = client.DownloadString("https://p0358.cf/codestats/report.php?pluginver=" + Constants.PluginVersion + "&cid=" + CodeStatsPackage.Guid + "&editorname=" + Constants.EditorName + "&editorver=" + Constants.EditorVersion + "&is64proc=" + ProcessorArchitectureHelper.Is64BitProcess.ToString().ToLowerInvariant()); // expected response: ok
632+
string HtmlResult = client.DownloadString("https://p0358.net/codestats/report.php?pluginver=" + Constants.PluginVersion + "&cid=" + CodeStatsPackage.Guid + "&editorname=" + Constants.EditorName + "&editorver=" + Constants.EditorVersion + "&is64process=" + ProcessorArchitectureHelper.Is64BitProcess.ToString().ToLowerInvariant() + "&is64sys=" + ProcessorArchitectureHelper.Is64BitOperatingSystem.ToString().ToLowerInvariant()); // expected response: ok
600633
if (HtmlResult.Contains("ok")) _reportedStats = true;
601634
}
602635

@@ -613,6 +646,12 @@ public static WebProxy GetProxy()
613646
{
614647
WebProxy proxy = null;
615648

649+
if (String.IsNullOrWhiteSpace(Proxy))
650+
{
651+
Logger.Debug("No proxy will be used. It's not set.");
652+
return proxy;
653+
}
654+
616655
try
617656
{
618657
var proxyStr = Proxy;

CodeStats/Forms/ApiKeyForm.Designer.cs

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CodeStats/Forms/ApiKeyForm.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ private void ApiKeyForm_Load(object sender, EventArgs e)
2828

2929
private void btnOk_Click(object sender, EventArgs e)
3030
{
31+
try
32+
{
33+
if (CodeStatsPackage._settingsForm != null && CodeStatsPackage._settingsForm.Visible)
34+
{
35+
CodeStatsPackage._settingsForm.Close();
36+
}
37+
}
38+
finally { }
39+
3140
try
3241
{
3342
string apiKey = txtAPIKey.Text.Trim();
@@ -36,6 +45,7 @@ private void btnOk_Click(object sender, EventArgs e)
3645
_CodeStatsConfigFile.ApiKey = apiKey;
3746
_CodeStatsConfigFile.Save();
3847
CodeStatsPackage.ApiKey = apiKey;
48+
CodeStatsPackage._hasAlreadyShownInvalidApiTokenMessage = false;
3949
/*}
4050
else // - kept in case we check API tokens in future
4151
{

0 commit comments

Comments
 (0)