diff --git a/.gitignore b/.gitignore index 103db3d..f08db5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,399 @@ -bin/ -obj/ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory .vs/ -packages/ \ No newline at end of file +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +/.idea \ No newline at end of file diff --git a/ntfysh_client/Form1.Designer.cs b/ntfysh_client/Form1.Designer.cs index e9b6d1e..91caa7e 100644 --- a/ntfysh_client/Form1.Designer.cs +++ b/ntfysh_client/Form1.Designer.cs @@ -40,12 +40,12 @@ namespace ntfysh_client this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.label1 = new System.Windows.Forms.Label(); this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ntfyshWebsiteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.label1 = new System.Windows.Forms.Label(); this.trayContextMenu.SuspendLayout(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); @@ -75,8 +75,7 @@ namespace ntfysh_client // // notificationTopics // - this.notificationTopics.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.notificationTopics.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.notificationTopics.FormattingEnabled = true; this.notificationTopics.Location = new System.Drawing.Point(12, 50); this.notificationTopics.Name = "notificationTopics"; @@ -96,9 +95,7 @@ namespace ntfysh_client // // trayContextMenu // - this.trayContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.showControlWindowToolStripMenuItem, - this.exitToolStripMenuItem}); + this.trayContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.showControlWindowToolStripMenuItem, this.exitToolStripMenuItem }); this.trayContextMenu.Name = "trayContextMenu"; this.trayContextMenu.Size = new System.Drawing.Size(190, 48); // @@ -121,9 +118,7 @@ namespace ntfysh_client // menuStrip1 // this.menuStrip1.BackColor = System.Drawing.Color.White; - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.fileToolStripMenuItem, - this.helpToolStripMenuItem}); + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.fileToolStripMenuItem, this.helpToolStripMenuItem }); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(353, 24); @@ -132,45 +127,24 @@ namespace ntfysh_client // // fileToolStripMenuItem // - this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.exitToolStripMenuItem1}); + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.exitToolStripMenuItem1 }); this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); this.fileToolStripMenuItem.Text = "File"; // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.ntfyshWebsiteToolStripMenuItem, - this.toolStripMenuItem1, - this.aboutToolStripMenuItem}); - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); - this.helpToolStripMenuItem.Text = "Help"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 34); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(145, 13); - this.label1.TabIndex = 1; - this.label1.Text = "Subscribed notification topics"; - // // exitToolStripMenuItem1 // this.exitToolStripMenuItem1.Image = ((System.Drawing.Image)(resources.GetObject("exitToolStripMenuItem1.Image"))); this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1"; - this.exitToolStripMenuItem1.Size = new System.Drawing.Size(180, 22); + this.exitToolStripMenuItem1.Size = new System.Drawing.Size(93, 22); this.exitToolStripMenuItem1.Text = "Exit"; // - // aboutToolStripMenuItem + // helpToolStripMenuItem // - this.aboutToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("aboutToolStripMenuItem.Image"))); - this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; - this.aboutToolStripMenuItem.Size = new System.Drawing.Size(185, 22); - this.aboutToolStripMenuItem.Text = "About"; - this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.ntfyshWebsiteToolStripMenuItem, this.toolStripMenuItem1, this.aboutToolStripMenuItem }); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "Help"; // // ntfyshWebsiteToolStripMenuItem // @@ -185,6 +159,23 @@ namespace ntfysh_client this.toolStripMenuItem1.Name = "toolStripMenuItem1"; this.toolStripMenuItem1.Size = new System.Drawing.Size(182, 6); // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("aboutToolStripMenuItem.Image"))); + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(185, 22); + this.aboutToolStripMenuItem.Text = "About"; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 34); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(145, 13); + this.label1.TabIndex = 1; + this.label1.Text = "Subscribed notification topics"; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -213,7 +204,6 @@ namespace ntfysh_client this.menuStrip1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); - } #endregion diff --git a/ntfysh_client/Form1.cs b/ntfysh_client/Form1.cs index 2963b0b..e3e441c 100644 --- a/ntfysh_client/Form1.cs +++ b/ntfysh_client/Form1.cs @@ -36,7 +36,7 @@ namespace ntfysh_client if (result == DialogResult.OK) { - notificationListener.SubscribeToTopic(dialog.getTopicId()); + notificationListener.SubscribeToTopic(dialog.getTopicId(), dialog.getServerUrl(), dialog.getUsername(), dialog.getPassword()); notificationTopics.Items.Add(dialog.getTopicId()); this.SaveTopicsToFile(); } @@ -117,7 +117,7 @@ namespace ntfysh_client while (!reader.EndOfStream) { var topic = reader.ReadLine(); - notificationListener.SubscribeToTopic(topic); + notificationListener.SubscribeToTopic(topic, "https://ntfy.sh", null, null); notificationTopics.Items.Add(topic); } } diff --git a/ntfysh_client/Form1.resx b/ntfysh_client/Form1.resx index 4b4cee7..7adc2ca 100644 --- a/ntfysh_client/Form1.resx +++ b/ntfysh_client/Form1.resx @@ -124,6 +124,24 @@ 123, 17 + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAiklE + QVQ4T8WPQQqAIBBFvUOrXIhu3dcZOkqtu5R1ia4SdRDrxyyGGKmBIOGBDL6nmk9WCGE9yUpW0q9Ads7V + GuCQ/kHAe79joAEO6dcLFmttpQEO6c+Bvpm2oZ0zwB4zVQBiF8cIsMdMDPCb+G2vA/wgP/z6C6WAhBgo + fUFCDGi4BxIGShLpvy5jDoPes/0oNG3VAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAgUlE + QVQ4T2OgGjjOLq4AZeIFWNWBBI9yib06zC3uABXCCkDyIHVYDTnMI2pzhEvs5VFucSeoEAo4wiNii08e + DHAZQshwFICumCTNMADyK1gTl2gJiCYUNlgBSDPQ1v8gGipEPKDIBRSFAa6oIsoQQvGM1xCqpESsglgA + seroBRgYAOoOWBJbfVcRAAAAAElFTkSuQmCC + + AAABAAEAMjIAAAEAIADIKAAAFgAAACgAAAAyAAAAZAAAAAEAIAAAAAAAECcAACMuAAAjLgAAAAAAAAAA @@ -303,16 +321,10 @@ /////8AA////////wAD////////AAA== - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 - JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAiklE - QVQ4T8WPQQqAIBBFvUOrXIhu3dcZOkqtu5R1ia4SdRDrxyyGGKmBIOGBDL6nmk9WCGE9yUpW0q9Ads7V - GuCQ/kHAe79joAEO6dcLFmttpQEO6c+Bvpm2oZ0zwB4zVQBiF8cIsMdMDPCb+G2vA/wgP/z6C6WAhBgo - fUFCDGi4BxIGShLpvy5jDoPes/0oNG3VAAAAAElFTkSuQmCC - - - + + 269, 17 + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAgUlE @@ -321,9 +333,6 @@ seroBRgYAOoOWBJbfVcRAAAAAElFTkSuQmCC - - 269, 17 - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 @@ -343,15 +352,6 @@ dDIA6OTNQHX/YXysBjAxMcUxMjKuBrGB9DIgPxqmARhwOUBD3sD4WA0QERGRBHLvCwoKygLpm6KiohIw DVBNz5HY2L0AtHkOEE8F4okgvoyMjDSSJsIGsLOzuwKFfnBycppJS0vLAJ39BUQTbQA6RnYBMkY3YAVI gES8Aqp9QAEDAwCq9oYvtggceQAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 - JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAgUlE - QVQ4T2OgGjjOLq4AZeIFWNWBBI9yib06zC3uABXCCkDyIHVYDTnMI2pzhEvs5VFucSeoEAo4wiNii08e - DHAZQshwFICumCTNMADyK1gTl2gJiCYUNlgBSDPQ1v8gGipEPKDIBRSFAa6oIsoQQvGM1xCqpESsglgA - seroBRgYAOoOWBJbfVcRAAAAAElFTkSuQmCC diff --git a/ntfysh_client/NotificationListener.cs b/ntfysh_client/NotificationListener.cs index 75f6118..54e5bf1 100644 --- a/ntfysh_client/NotificationListener.cs +++ b/ntfysh_client/NotificationListener.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -19,7 +20,7 @@ namespace ntfysh_client private bool disposedValue; - public Dictionary subscribedTopics; + public readonly Dictionary SubscribedTopics = new Dictionary(); public delegate void NotificationReceiveHandler(object sender, NotificationReceiveEventArgs e); public event NotificationReceiveHandler OnNotificationReceive; @@ -27,22 +28,32 @@ namespace ntfysh_client public NotificationListener() { httpClient = new HttpClient(); - subscribedTopics = new Dictionary(); httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite); ServicePointManager.DefaultConnectionLimit = 100; } - public async Task SubscribeToTopic(string topicId) + public async Task SubscribeToTopic(string topicId, string serverUrl, string username, string password) { - HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Get, $"https://ntfy.sh/{HttpUtility.UrlEncode(topicId)}/json"); - using (var response = await httpClient.SendAsync(msg, HttpCompletionOption.ResponseHeadersRead)) + if (string.IsNullOrWhiteSpace(username)) username = null; + if (string.IsNullOrWhiteSpace(password)) password = null; + + HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Get, $"{serverUrl}/{HttpUtility.UrlEncode(topicId)}/json"); + + if (username != null && password != null) { - using (var body = await response.Content.ReadAsStreamAsync()) + byte[] boundCredentialsBytes = Encoding.UTF8.GetBytes($"{username}:{password}"); + + msg.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(boundCredentialsBytes)); + } + + using (HttpResponseMessage response = await httpClient.SendAsync(msg, HttpCompletionOption.ResponseHeadersRead)) + { + using (Stream body = await response.Content.ReadAsStreamAsync()) { using (StreamReader reader = new StreamReader(body)) { - subscribedTopics.Add(topicId, reader); + SubscribedTopics.Add(topicId, new SubscribedTopic(topicId, serverUrl, username, password, reader)); try { @@ -71,9 +82,9 @@ namespace ntfysh_client // If the topic is still registered, then that stream wasn't mean to be closed (maybe network failure?) // Restart it - if (subscribedTopics.ContainsKey(topicId)) + if (SubscribedTopics.ContainsKey(topicId)) { - SubscribeToTopic(topicId); + SubscribeToTopic(topicId, serverUrl, username, password); } } } @@ -85,12 +96,12 @@ namespace ntfysh_client { Debug.WriteLine($"Removing topic {topicId}"); - if (subscribedTopics.ContainsKey(topicId)) + if (SubscribedTopics.ContainsKey(topicId)) { // Not moronic to store it in a variable; this solves a race condition in SubscribeToTopic - var topic = subscribedTopics[topicId]; - subscribedTopics.Remove(topicId); - topic.Close(); + var topic = SubscribedTopics[topicId]; + SubscribedTopics.Remove(topicId); + topic.Stream.Close(); } } diff --git a/ntfysh_client/SubscribeDialog.Designer.cs b/ntfysh_client/SubscribeDialog.Designer.cs index e7d369e..30d5a60 100644 --- a/ntfysh_client/SubscribeDialog.Designer.cs +++ b/ntfysh_client/SubscribeDialog.Designer.cs @@ -30,10 +30,16 @@ namespace ntfysh_client private void InitializeComponent() { this.panel1 = new System.Windows.Forms.Panel(); - this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); this.label1 = new System.Windows.Forms.Label(); this.topicId = new System.Windows.Forms.TextBox(); + this.serverUrl = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.username = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.password = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); this.panel1.SuspendLayout(); this.SuspendLayout(); // @@ -43,23 +49,11 @@ namespace ntfysh_client this.panel1.Controls.Add(this.button2); this.panel1.Controls.Add(this.button1); this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.panel1.Location = new System.Drawing.Point(0, 81); + this.panel1.Location = new System.Drawing.Point(0, 175); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(297, 44); this.panel1.TabIndex = 0; // - // button1 - // - this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.button1.Location = new System.Drawing.Point(212, 11); - this.button1.Margin = new System.Windows.Forms.Padding(3, 10, 10, 10); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(75, 23); - this.button1.TabIndex = 2; - this.button1.Text = "Subscribe"; - this.button1.UseVisualStyleBackColor = true; - this.button1.Click += new System.EventHandler(this.button1_Click); - // // button2 // this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); @@ -72,10 +66,22 @@ namespace ntfysh_client this.button2.UseVisualStyleBackColor = true; this.button2.Click += new System.EventHandler(this.button2_Click); // + // button1 + // + this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.button1.Location = new System.Drawing.Point(212, 11); + this.button1.Margin = new System.Windows.Forms.Padding(3, 10, 10, 10); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 2; + this.button1.Text = "Subscribe"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 23); + this.label1.Location = new System.Drawing.Point(12, 9); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(51, 13); this.label1.TabIndex = 1; @@ -83,20 +89,85 @@ namespace ntfysh_client // // topicId // - this.topicId.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.topicId.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.topicId.Location = new System.Drawing.Point(15, 39); + this.topicId.Location = new System.Drawing.Point(12, 25); this.topicId.Name = "topicId"; this.topicId.Size = new System.Drawing.Size(273, 20); this.topicId.TabIndex = 0; this.topicId.KeyDown += new System.Windows.Forms.KeyEventHandler(this.topicId_KeyDown); // + // serverUrl + // + this.serverUrl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.serverUrl.Location = new System.Drawing.Point(12, 64); + this.serverUrl.Name = "serverUrl"; + this.serverUrl.Size = new System.Drawing.Size(273, 20); + this.serverUrl.TabIndex = 2; + this.serverUrl.Text = "https://ntfy.sh"; + this.serverUrl.KeyDown += new System.Windows.Forms.KeyEventHandler(this.serverUrl_KeyDown); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(10, 48); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(66, 13); + this.label2.TabIndex = 3; + this.label2.Text = "Server URL:"; + // + // username + // + this.username.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.username.Location = new System.Drawing.Point(12, 103); + this.username.Name = "username"; + this.username.Size = new System.Drawing.Size(273, 20); + this.username.TabIndex = 4; + this.username.KeyDown += new System.Windows.Forms.KeyEventHandler(this.username_KeyDown); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(10, 87); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(58, 13); + this.label3.TabIndex = 5; + this.label3.Text = "Username:"; + // + // password + // + this.password.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.password.Location = new System.Drawing.Point(12, 142); + this.password.Name = "password"; + this.password.Size = new System.Drawing.Size(273, 20); + this.password.TabIndex = 6; + this.password.UseSystemPasswordChar = true; + this.password.KeyDown += new System.Windows.Forms.KeyEventHandler(this.password_KeyDown); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(10, 126); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(56, 13); + this.label4.TabIndex = 7; + this.label4.Text = "Password:"; + // // SubscribeDialog // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.White; - this.ClientSize = new System.Drawing.Size(297, 125); + this.ClientSize = new System.Drawing.Size(297, 219); + this.Controls.Add(this.password); + this.Controls.Add(this.label4); + this.Controls.Add(this.username); + this.Controls.Add(this.label3); + this.Controls.Add(this.serverUrl); + this.Controls.Add(this.label2); this.Controls.Add(this.topicId); this.Controls.Add(this.label1); this.Controls.Add(this.panel1); @@ -114,6 +185,9 @@ namespace ntfysh_client } + private System.Windows.Forms.TextBox serverUrl; + private System.Windows.Forms.Label label2; + #endregion private System.Windows.Forms.Panel panel1; @@ -121,5 +195,9 @@ namespace ntfysh_client private System.Windows.Forms.Button button1; private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox topicId; + private System.Windows.Forms.TextBox username; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox password; + private System.Windows.Forms.Label label4; } } \ No newline at end of file diff --git a/ntfysh_client/SubscribeDialog.cs b/ntfysh_client/SubscribeDialog.cs index 7e4ded3..861f3fe 100644 --- a/ntfysh_client/SubscribeDialog.cs +++ b/ntfysh_client/SubscribeDialog.cs @@ -1,11 +1,4 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace ntfysh_client @@ -21,6 +14,21 @@ namespace ntfysh_client { return topicId.Text; } + + public string getServerUrl() + { + return serverUrl.Text; + } + + public string getUsername() + { + return username.Text; + } + + public string getPassword() + { + return password.Text; + } private void button1_Click(object sender, EventArgs e) { @@ -32,6 +40,30 @@ namespace ntfysh_client return; } + if (serverUrl.Text.Length < 1) + { + MessageBox.Show("You must specify a server URL. The default is https://ntfy.sh", "Server URL not specified", MessageBoxButtons.OK, MessageBoxIcon.Error); + DialogResult = DialogResult.None; + serverUrl.Focus(); + return; + } + + if (username.Text.Length > 0 && password.Text.Length < 1) + { + MessageBox.Show("You must specify a password alongside the username", "Password not specified", MessageBoxButtons.OK, MessageBoxIcon.Error); + DialogResult = DialogResult.None; + password.Focus(); + return; + } + + if (password.Text.Length > 0 && username.Text.Length < 1) + { + MessageBox.Show("You must specify a username alongside the password", "Username not specified", MessageBoxButtons.OK, MessageBoxIcon.Error); + DialogResult = DialogResult.None; + username.Focus(); + return; + } + DialogResult = DialogResult.OK; } @@ -48,5 +80,32 @@ namespace ntfysh_client e.SuppressKeyPress = true; } } + + private void serverUrl_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyData == Keys.Enter) + { + button1.PerformClick(); + e.SuppressKeyPress = true; + } + } + + private void username_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyData == Keys.Enter) + { + button1.PerformClick(); + e.SuppressKeyPress = true; + } + } + + private void password_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyData == Keys.Enter) + { + button1.PerformClick(); + e.SuppressKeyPress = true; + } + } } } diff --git a/ntfysh_client/SubscribedTopic.cs b/ntfysh_client/SubscribedTopic.cs new file mode 100644 index 0000000..5d51bef --- /dev/null +++ b/ntfysh_client/SubscribedTopic.cs @@ -0,0 +1,23 @@ +using System.IO; + +namespace ntfysh_client +{ + public class SubscribedTopic + { + public SubscribedTopic(string topicId, string serverUrl, string username, string password, StreamReader stream) + { + TopicId = topicId; + ServerUrl = serverUrl; + Username = username; + Password = password; + Stream = stream; + } + + public string TopicId { get; } + public string ServerUrl { get; } + public string Username { get; } + public string Password { get; } + + public StreamReader Stream { get; } + } +} \ No newline at end of file diff --git a/ntfysh_client/ntfysh_client.csproj b/ntfysh_client/ntfysh_client.csproj index b6e42a2..ad03786 100644 --- a/ntfysh_client/ntfysh_client.csproj +++ b/ntfysh_client/ntfysh_client.csproj @@ -74,6 +74,7 @@ SubscribeDialog.cs + AboutBox.cs