11 Commits

Author SHA1 Message Date
Richard Mwewa
5468d93976 Add files via upload 2023-08-30 03:26:13 +02:00
Richard Mwewa
d186f6f7da Merge pull request #15 from bellingcat/dev
Dev
2023-08-30 03:25:10 +02:00
Richard Mwewa
b5d52e4bb5 Update main.py
dev 1.8.0.0
2023-08-30 03:22:03 +02:00
Richard Mwewa
a2bdc66a03 Update pyproject.toml
dev 1.8.0.0
2023-08-30 03:21:03 +02:00
Richard Mwewa
bb72360699 Update README.md 2023-08-30 03:19:55 +02:00
Richard Mwewa
adc15555e3 Update README.md 2023-08-30 03:19:22 +02:00
Richard Mwewa
07ad626dd2 Add files via upload
dev 1.8.0.0
2023-08-30 03:16:36 +02:00
Richard Mwewa
2729c984bc Delete RPST GUI directory 2023-08-30 03:15:21 +02:00
Richard Mwewa
f3445b8e06 Add files via upload 2023-08-29 19:26:26 +02:00
Richard Mwewa
358f264bdd Merge pull request #14 from bellingcat/dev
dev 1.7.1.0
2023-08-26 15:52:46 +02:00
Richard Mwewa
e3dda99233 dev 1.7.1.0 2023-08-26 15:44:21 +02:00
21 changed files with 3249 additions and 2904 deletions

View File

@@ -4,24 +4,38 @@ Given a subreddit name and a keyword, RPST will return all posts from a specifie
[![Upload Python Package](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/python-publish.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/python-publish.yml) [![CodeQL](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/codeql.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/codeql.yml) ![.Net](https://img.shields.io/badge/.NET-5C2D91?style=flat&logo=.net&logoColor=white) ![Python](https://img.shields.io/badge/python-3670A0?style=flat&logo=python&logoColor=ffdd54) [![Upload Python Package](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/python-publish.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/python-publish.yml) [![CodeQL](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/codeql.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/codeql.yml) ![.Net](https://img.shields.io/badge/.NET-5C2D91?style=flat&logo=.net&logoColor=white) ![Python](https://img.shields.io/badge/python-3670A0?style=flat&logo=python&logoColor=ffdd54)
# ✅ Features # ✅ Features
## GUI ## *GUI*
- [x] Dark mode (*Right-click*) - [x] Dark mode (*Right-click*).
- [x] Saves results to a JSON file (*Right-click*) - [x] Saves results to a JSON file (*Right-click*).
- [x] Logs errors to a file - [x] Logs errors to a file.
- [x] In-App feature to check for Updates.
## CLI ## *CLI*
- [x] Saves results to JSON (*specifiy* `--json`) - [x] Saves results to JSON (*specifiy* `--json`).
- [x] Saves results to CSV (*specify* `--csv`) - [x] Saves results to CSV (*specify* `--csv`).
- [x] Automatically checks for new updates, and notifies user if updates were found. - [x] Automatically checks for new updates, and notifies user if updates were found.
# 📃 TODO # 📃 TODO
## GUI ## *GUI*
- [ ] Make it installable with a setup.exe/setup.msi file. - [ ] Make it installable with a setup.exe/setup.msi file.
- [x] Add manual dark mode option, that will be persistent in all sessions - [x] Add manual dark mode option, that will be persistent in all sessions.
- [ ] Make it save results to a CSV file - [x] Make settings persistent in all sessions.
- [x] Make it save results to a CSV file.
# 🖥️ Tested environments
## *GUI*
- [x] Microsoft Windows 11
## *CLI*
- [x] Android Termux
- [x] Microsoft Windows 11
- [x] Ubuntu 22.04 - latest versions
# 📖 Wiki # 📖 Wiki
[Refer to the Wiki](https://github.com/bellingcat/reddit-post-scraping-tool/wiki) for installation instructions, in addition to all other documentation. [Refer to the Wiki](https://github.com/bellingcat/reddit-post-scraping-tool/wiki) for installation instructions, in addition to all other documentation.
# 🖼️ Screenshots
You can view a collection of screenshots for both the *CLI* and *GUI* [here](https://github.com/bellingcat/reddit-post-scraping-tool/tree/master/images)
*** ***
<a href="https://www.buymeacoffee.com/_rly0nheart"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=_rly0nheart&button_colour=40DCA5&font_colour=ffffff&font_family=Comic&outline_colour=000000&coffee_colour=FFDD00" /></a> <a href="https://www.buymeacoffee.com/_rly0nheart"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=_rly0nheart&button_colour=40DCA5&font_colour=ffffff&font_family=Comic&outline_colour=000000&coffee_colour=FFDD00" /></a>

View File

@@ -26,9 +26,9 @@ Partial Class AboutBox
PictureBoxLogo = New PictureBox() PictureBoxLogo = New PictureBox()
LabelProgramName = New Label() LabelProgramName = New Label()
LabelProgramDescription = New Label() LabelProgramDescription = New Label()
LabelVersion = New Label()
LinkLabelReadtheWiki = New LinkLabel() LinkLabelReadtheWiki = New LinkLabel()
Panel1 = New Panel() Panel1 = New Panel()
LinkLabelVersion = New LinkLabel()
LicenseRichTextBox = New RichTextBox() LicenseRichTextBox = New RichTextBox()
CType(PictureBoxLogo, ComponentModel.ISupportInitialize).BeginInit() CType(PictureBoxLogo, ComponentModel.ISupportInitialize).BeginInit()
Panel1.SuspendLayout() Panel1.SuspendLayout()
@@ -67,17 +67,6 @@ Partial Class AboutBox
LabelProgramDescription.TabIndex = 4 LabelProgramDescription.TabIndex = 4
LabelProgramDescription.Text = "Description" LabelProgramDescription.Text = "Description"
' '
' LabelVersion
'
LabelVersion.AutoSize = True
LabelVersion.Font = New Font("Segoe UI", 9F, FontStyle.Underline, GraphicsUnit.Point)
LabelVersion.ForeColor = SystemColors.ControlText
LabelVersion.Location = New Point(347, 17)
LabelVersion.Name = "LabelVersion"
LabelVersion.Size = New Size(45, 15)
LabelVersion.TabIndex = 5
LabelVersion.Text = "Version"
'
' LinkLabelReadtheWiki ' LinkLabelReadtheWiki
' '
LinkLabelReadtheWiki.AutoSize = True LinkLabelReadtheWiki.AutoSize = True
@@ -92,15 +81,25 @@ Partial Class AboutBox
' Panel1 ' Panel1
' '
Panel1.BackColor = SystemColors.Control Panel1.BackColor = SystemColors.Control
Panel1.Controls.Add(LinkLabelVersion)
Panel1.Controls.Add(LabelProgramDescription) Panel1.Controls.Add(LabelProgramDescription)
Panel1.Controls.Add(LabelProgramName) Panel1.Controls.Add(LabelProgramName)
Panel1.Controls.Add(LinkLabelReadtheWiki) Panel1.Controls.Add(LinkLabelReadtheWiki)
Panel1.Controls.Add(LabelVersion)
Panel1.Location = New Point(106, 12) Panel1.Location = New Point(106, 12)
Panel1.Name = "Panel1" Panel1.Name = "Panel1"
Panel1.Size = New Size(409, 93) Panel1.Size = New Size(409, 93)
Panel1.TabIndex = 7 Panel1.TabIndex = 7
' '
' LinkLabelVersion
'
LinkLabelVersion.AutoSize = True
LinkLabelVersion.Location = New Point(347, 17)
LinkLabelVersion.Name = "LinkLabelVersion"
LinkLabelVersion.Size = New Size(45, 15)
LinkLabelVersion.TabIndex = 7
LinkLabelVersion.TabStop = True
LinkLabelVersion.Text = "Version"
'
' LicenseRichTextBox ' LicenseRichTextBox
' '
LicenseRichTextBox.Font = New Font("Cambria", 9.75F, FontStyle.Regular, GraphicsUnit.Point) LicenseRichTextBox.Font = New Font("Cambria", 9.75F, FontStyle.Regular, GraphicsUnit.Point)
@@ -137,8 +136,8 @@ Partial Class AboutBox
Friend WithEvents PictureBoxLogo As PictureBox Friend WithEvents PictureBoxLogo As PictureBox
Friend WithEvents LabelProgramName As Label Friend WithEvents LabelProgramName As Label
Friend WithEvents LabelProgramDescription As Label Friend WithEvents LabelProgramDescription As Label
Friend WithEvents LabelVersion As Label
Friend WithEvents LinkLabelReadtheWiki As LinkLabel Friend WithEvents LinkLabelReadtheWiki As LinkLabel
Friend WithEvents Panel1 As Panel Friend WithEvents Panel1 As Panel
Friend WithEvents LicenseRichTextBox As RichTextBox Friend WithEvents LicenseRichTextBox As RichTextBox
Friend WithEvents LinkLabelVersion As LinkLabel
End Class End Class

View File

@@ -18,7 +18,7 @@
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value> <value>[base64 mime encoded serialized .NET Framework object]</value>
</data> </data>

View File

@@ -31,13 +31,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SO
''' <param name="e">The event data.</param> ''' <param name="e">The event data.</param>
Private Sub AboutBox_Load(sender As Object, e As EventArgs) Handles MyBase.Load Private Sub AboutBox_Load(sender As Object, e As EventArgs) Handles MyBase.Load
settings.LoadSettings() settings.LoadSettings()
settings.ToggleDarkMode(settings.DarkMode) settings.ToggleSettings(settings.DarkMode, "darkmode")
LabelProgramName.Text = My.Application.Info.ProductName LabelProgramName.Text = My.Application.Info.ProductName
LabelProgramDescription.Text = "Given a subreddit name and a keyword, LabelProgramDescription.Text = "Given a subreddit name and a keyword,
RPST returns all top posts (by default) RPST returns all top posts (by default)
that contain the specified keyword." that contain the specified keyword."
LabelVersion.Text = $"v{My.Application.Info.Version}" LinkLabelVersion.Text = $"v{My.Application.Info.Version}"
LicenseRichTextBox.Text = LicenseText LicenseRichTextBox.Text = LicenseText
End Sub End Sub
@@ -50,4 +50,8 @@ that contain the specified keyword."
Private Sub LinkLabelReadtheWiki_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabelReadtheWiki.LinkClicked Private Sub LinkLabelReadtheWiki_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabelReadtheWiki.LinkClicked
Shell("cmd /c start https://github.com/bellingcat/reddit-post-scraping-tool/wiki") Shell("cmd /c start https://github.com/bellingcat/reddit-post-scraping-tool/wiki")
End Sub End Sub
Private Sub LinkLabelVersion_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabelVersion.LinkClicked
Shell($"cmd /c start https://github.com/bellingcat/reddit-post-scraping-tool/releases/tag/{My.Application.Info.Version}")
End Sub
End Class End Class

View File

@@ -6,32 +6,34 @@ Public Class DataGridViewHandler
''' </summary> ''' </summary>
''' <param name="dataGridView">The DataGridView to be initialized.</param> ''' <param name="dataGridView">The DataGridView to be initialized.</param>
Public Shared Sub AddColumn(dataGridView As DataGridView) Public Shared Sub AddColumn(dataGridView As DataGridView)
' Clear the Columns and Rows before adding Items to them ''' <summary>
''' Clear the Columns and Rows before adding Items to them.
''' <summary>
dataGridView.Rows.Clear() dataGridView.Rows.Clear()
dataGridView.Columns.Clear() dataGridView.Columns.Clear()
dataGridView.Columns.Add("PostCount", "INDEX") dataGridView.Columns.Add("PostCount", "🔢 Index")
dataGridView.Columns.Add("PostAuthor", "AUTHOR") dataGridView.Columns.Add("PostAuthor", "👤 Author")
dataGridView.Columns.Add("PostID", "ID") dataGridView.Columns.Add("PostID", "🆔 ID")
dataGridView.Columns.Add("PostText", "TEXT") dataGridView.Columns.Add("PostText", "📝 Text")
dataGridView.Columns.Add("PostSubreddit", "SUBREDDIT") dataGridView.Columns.Add("PostSubreddit", "🫂 Subreddit")
dataGridView.Columns.Add("SubredditVisibility", "VISIBILITY") dataGridView.Columns.Add("SubredditVisibility", "🫣 Visibility")
dataGridView.Columns.Add("PostThumbnail", "THUMBNAIL") dataGridView.Columns.Add("PostThumbnail", "🖼️ Thumbnail")
dataGridView.Columns.Add("PostIsNSFW", "NSFW") dataGridView.Columns.Add("PostIsNSFW", "🔞 NSFW")
dataGridView.Columns.Add("PostIsGilded", "GILDED") dataGridView.Columns.Add("PostIsGilded", "🥇 Gilded")
dataGridView.Columns.Add("PostUpvotes", "UPVOTES") dataGridView.Columns.Add("PostUpvotes", "⬆️ Upvotes")
dataGridView.Columns.Add("PostUpvoteRatio", "UPVOTE RATIO") dataGridView.Columns.Add("PostUpvoteRatio", "📊 Upvote Ratio")
dataGridView.Columns.Add("PostDownvotes", "DOWNVOTES") dataGridView.Columns.Add("PostDownvotes", "⬇️ Downvotes")
dataGridView.Columns.Add("PostAwards", "AWARDS") dataGridView.Columns.Add("PostAwards", "🏆 Awards")
dataGridView.Columns.Add("PostTopAward", "TOP AWARD") dataGridView.Columns.Add("PostTopAward", "🏆 Top Award")
dataGridView.Columns.Add("PostIsCrosspostable", "IS CROSS-POSTABLE?") dataGridView.Columns.Add("PostIsCrosspostable", "↪️ Is cross-postable?")
dataGridView.Columns.Add("PostScore", "SCORE") dataGridView.Columns.Add("PostScore", "📈 Score")
dataGridView.Columns.Add("PostCategory", "CATEGORY") dataGridView.Columns.Add("PostCategory", "🟢 Category")
dataGridView.Columns.Add("PostDomain", "DOMAIN") dataGridView.Columns.Add("PostDomain", "🌐 Domain")
dataGridView.Columns.Add("PostPermalink", "PERMALINK") dataGridView.Columns.Add("PostPermalink", "🔗 Permalink")
dataGridView.Columns.Add("PostCreatedAt", "CREATED AT") dataGridView.Columns.Add("PostCreatedAt", "📅 Created At")
dataGridView.Columns.Add("PostApprovedAt", "APPROVED ATt") dataGridView.Columns.Add("PostApprovedAt", "📅 Approved At")
dataGridView.Columns.Add("PostApprovedBy", "APPROVED BY") dataGridView.Columns.Add("PostApprovedBy", "👤 Approved By")
End Sub End Sub
Public Shared Sub AddRow(dataGridView As DataGridView, post As JObject, postNumber As Integer) Public Shared Sub AddRow(dataGridView As DataGridView, post As JObject, postNumber As Integer)

View File

@@ -61,7 +61,7 @@ Partial Class DeveloperBox
GreetingLabel.TabIndex = 3 GreetingLabel.TabIndex = 3
GreetingLabel.Text = "👋🏾Hello, I'm Ritchie" GreetingLabel.Text = "👋🏾Hello, I'm Ritchie"
' '
' DeveloperForm ' DeveloperBox
' '
AutoScaleDimensions = New SizeF(7F, 15F) AutoScaleDimensions = New SizeF(7F, 15F)
AutoScaleMode = AutoScaleMode.Font AutoScaleMode = AutoScaleMode.Font
@@ -73,7 +73,7 @@ Partial Class DeveloperBox
FormBorderStyle = FormBorderStyle.FixedSingle FormBorderStyle = FormBorderStyle.FixedSingle
MaximizeBox = False MaximizeBox = False
MinimizeBox = False MinimizeBox = False
Name = "DeveloperForm" Name = "DeveloperBox"
ShowIcon = False ShowIcon = False
ShowInTaskbar = False ShowInTaskbar = False
StartPosition = FormStartPosition.CenterParent StartPosition = FormStartPosition.CenterParent

File diff suppressed because it is too large Load Diff

View File

@@ -35,14 +35,15 @@ Partial Class FormMain
LabelListing = New Label() LabelListing = New Label()
LabelTimeframe = New Label() LabelTimeframe = New Label()
ContextMenuStripRightClick = New ContextMenuStrip(components) ContextMenuStripRightClick = New ContextMenuStrip(components)
ToolStripMenuItemDarkMode = New ToolStripMenuItem() SettingsToolStripMenuItem = New ToolStripMenuItem()
ToolStripMenuItemSavePosts = New ToolStripMenuItem() DarkModeToolStripMenuItem = New ToolStripMenuItem()
ToolStripMenuItemtoJSON = New ToolStripMenuItem() SavePostsToolStripMenuItem = New ToolStripMenuItem()
ToolStripMenuItemtoCSV = New ToolStripMenuItem() ToJSONToolStripMenuItem = New ToolStripMenuItem()
ToolStripMenuItemAbout = New ToolStripMenuItem() ToCSVToolStripMenuItem = New ToolStripMenuItem()
ToolStripMenuItemDeveloper = New ToolStripMenuItem() AboutToolStripMenuItem = New ToolStripMenuItem()
ToolStripMenuItemCheckUpdates = New ToolStripMenuItem() DeveloperToolStripMenuItem = New ToolStripMenuItem()
ToolStripMenuItemQuit = New ToolStripMenuItem() CheckForUpdatesToolStripMenuItem = New ToolStripMenuItem()
QuitToolStripMenuItem = New ToolStripMenuItem()
NumericUpDownLimit = New NumericUpDown() NumericUpDownLimit = New NumericUpDown()
ToolTip = New ToolTip(components) ToolTip = New ToolTip(components)
ContextMenuStripRightClick.SuspendLayout() ContextMenuStripRightClick.SuspendLayout()
@@ -55,19 +56,19 @@ Partial Class FormMain
TextBoxKeyword.ForeColor = SystemColors.WindowText TextBoxKeyword.ForeColor = SystemColors.WindowText
TextBoxKeyword.Location = New Point(118, 20) TextBoxKeyword.Location = New Point(118, 20)
TextBoxKeyword.Name = "TextBoxKeyword" TextBoxKeyword.Name = "TextBoxKeyword"
TextBoxKeyword.PlaceholderText = "Keyword" TextBoxKeyword.PlaceholderText = "*Keyword"
TextBoxKeyword.Size = New Size(100, 23) TextBoxKeyword.Size = New Size(100, 23)
TextBoxKeyword.TabIndex = 0 TextBoxKeyword.TabIndex = 0
ToolTip.SetToolTip(TextBoxKeyword, "Enter the keyword you want to search for.") ToolTip.SetToolTip(TextBoxKeyword, "[required] The keyword to search for.")
' '
' TextBoxSubreddit ' TextBoxSubreddit
' '
TextBoxSubreddit.Location = New Point(118, 49) TextBoxSubreddit.Location = New Point(118, 49)
TextBoxSubreddit.Name = "TextBoxSubreddit" TextBoxSubreddit.Name = "TextBoxSubreddit"
TextBoxSubreddit.PlaceholderText = "Subreddit" TextBoxSubreddit.PlaceholderText = "*Subreddit"
TextBoxSubreddit.Size = New Size(100, 23) TextBoxSubreddit.Size = New Size(100, 23)
TextBoxSubreddit.TabIndex = 4 TextBoxSubreddit.TabIndex = 4
ToolTip.SetToolTip(TextBoxSubreddit, "Provide the subreddit to search in.") ToolTip.SetToolTip(TextBoxSubreddit, "[required] The subreddit to search in.")
' '
' ButtonScrape ' ButtonScrape
' '
@@ -76,7 +77,7 @@ Partial Class FormMain
ButtonScrape.Size = New Size(51, 28) ButtonScrape.Size = New Size(51, 28)
ButtonScrape.TabIndex = 6 ButtonScrape.TabIndex = 6
ButtonScrape.Text = "Scrape" ButtonScrape.Text = "Scrape"
ToolTip.SetToolTip(ButtonScrape, "You can also just hit ENTER to start scraping.") ToolTip.SetToolTip(ButtonScrape, "Hitting ENTER will also start the scraping process.")
ButtonScrape.UseVisualStyleBackColor = True ButtonScrape.UseVisualStyleBackColor = True
' '
' ComboBoxTimeframe ' ComboBoxTimeframe
@@ -91,7 +92,7 @@ Partial Class FormMain
ComboBoxTimeframe.Size = New Size(100, 23) ComboBoxTimeframe.Size = New Size(100, 23)
ComboBoxTimeframe.TabIndex = 8 ComboBoxTimeframe.TabIndex = 8
ComboBoxTimeframe.Text = "All" ComboBoxTimeframe.Text = "All"
ToolTip.SetToolTip(ComboBoxTimeframe, "Select the time period for the posts. Default value is `All`.") ToolTip.SetToolTip(ComboBoxTimeframe, "The time period for the posts. Default value is `All`.")
' '
' ComboBoxListing ' ComboBoxListing
' '
@@ -105,7 +106,7 @@ Partial Class FormMain
ComboBoxListing.Size = New Size(100, 23) ComboBoxListing.Size = New Size(100, 23)
ComboBoxListing.TabIndex = 9 ComboBoxListing.TabIndex = 9
ComboBoxListing.Text = "Top" ComboBoxListing.Text = "Top"
ToolTip.SetToolTip(ComboBoxListing, "Choose the type of post listings. Default value is `Top`.") ToolTip.SetToolTip(ComboBoxListing, "The type of post listings. Default value is `Top`.")
' '
' LabelKeyword ' LabelKeyword
' '
@@ -123,7 +124,7 @@ Partial Class FormMain
LabelSubreddit.AutoEllipsis = True LabelSubreddit.AutoEllipsis = True
LabelSubreddit.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold Or FontStyle.Underline, GraphicsUnit.Point) LabelSubreddit.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold Or FontStyle.Underline, GraphicsUnit.Point)
LabelSubreddit.ForeColor = Color.Black LabelSubreddit.ForeColor = Color.Black
LabelSubreddit.Location = New Point(19, 52) LabelSubreddit.Location = New Point(19, 51)
LabelSubreddit.Name = "LabelSubreddit" LabelSubreddit.Name = "LabelSubreddit"
LabelSubreddit.Size = New Size(71, 23) LabelSubreddit.Size = New Size(71, 23)
LabelSubreddit.TabIndex = 11 LabelSubreddit.TabIndex = 11
@@ -134,7 +135,7 @@ Partial Class FormMain
LabelLimit.AutoEllipsis = True LabelLimit.AutoEllipsis = True
LabelLimit.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold Or FontStyle.Underline, GraphicsUnit.Point) LabelLimit.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold Or FontStyle.Underline, GraphicsUnit.Point)
LabelLimit.ForeColor = Color.Black LabelLimit.ForeColor = Color.Black
LabelLimit.Location = New Point(19, 75) LabelLimit.Location = New Point(19, 80)
LabelLimit.Name = "LabelLimit" LabelLimit.Name = "LabelLimit"
LabelLimit.Size = New Size(56, 23) LabelLimit.Size = New Size(56, 23)
LabelLimit.TabIndex = 12 LabelLimit.TabIndex = 12
@@ -145,7 +146,7 @@ Partial Class FormMain
LabelListing.AutoEllipsis = True LabelListing.AutoEllipsis = True
LabelListing.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold Or FontStyle.Underline, GraphicsUnit.Point) LabelListing.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold Or FontStyle.Underline, GraphicsUnit.Point)
LabelListing.ForeColor = Color.Black LabelListing.ForeColor = Color.Black
LabelListing.Location = New Point(19, 107) LabelListing.Location = New Point(19, 108)
LabelListing.Name = "LabelListing" LabelListing.Name = "LabelListing"
LabelListing.Size = New Size(56, 23) LabelListing.Size = New Size(56, 23)
LabelListing.TabIndex = 13 LabelListing.TabIndex = 13
@@ -156,7 +157,7 @@ Partial Class FormMain
LabelTimeframe.AutoEllipsis = True LabelTimeframe.AutoEllipsis = True
LabelTimeframe.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold Or FontStyle.Underline, GraphicsUnit.Point) LabelTimeframe.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold Or FontStyle.Underline, GraphicsUnit.Point)
LabelTimeframe.ForeColor = Color.Black LabelTimeframe.ForeColor = Color.Black
LabelTimeframe.Location = New Point(19, 136) LabelTimeframe.Location = New Point(19, 137)
LabelTimeframe.Name = "LabelTimeframe" LabelTimeframe.Name = "LabelTimeframe"
LabelTimeframe.Size = New Size(81, 23) LabelTimeframe.Size = New Size(81, 23)
LabelTimeframe.TabIndex = 14 LabelTimeframe.TabIndex = 14
@@ -164,78 +165,85 @@ Partial Class FormMain
' '
' ContextMenuStripRightClick ' ContextMenuStripRightClick
' '
ContextMenuStripRightClick.Items.AddRange(New ToolStripItem() {ToolStripMenuItemDarkMode, ToolStripMenuItemSavePosts, ToolStripMenuItemAbout, ToolStripMenuItemDeveloper, ToolStripMenuItemCheckUpdates, ToolStripMenuItemQuit}) ContextMenuStripRightClick.Items.AddRange(New ToolStripItem() {AboutToolStripMenuItem, DeveloperToolStripMenuItem, CheckForUpdatesToolStripMenuItem, SettingsToolStripMenuItem, QuitToolStripMenuItem})
ContextMenuStripRightClick.Name = "ContextMenuStrip1" ContextMenuStripRightClick.Name = "ContextMenuStrip1"
ContextMenuStripRightClick.Size = New Size(154, 136) ContextMenuStripRightClick.Size = New Size(172, 114)
' '
' ToolStripMenuItemDarkMode ' SettingsToolStripMenuItem
' '
ToolStripMenuItemDarkMode.AutoToolTip = True SettingsToolStripMenuItem.DropDownItems.AddRange(New ToolStripItem() {DarkModeToolStripMenuItem, SavePostsToolStripMenuItem})
ToolStripMenuItemDarkMode.CheckOnClick = True SettingsToolStripMenuItem.Image = CType(resources.GetObject("SettingsToolStripMenuItem.Image"), Image)
ToolStripMenuItemDarkMode.Image = CType(resources.GetObject("ToolStripMenuItemDarkMode.Image"), Image) SettingsToolStripMenuItem.Name = "SettingsToolStripMenuItem"
ToolStripMenuItemDarkMode.Name = "ToolStripMenuItemDarkMode" SettingsToolStripMenuItem.Size = New Size(171, 22)
ToolStripMenuItemDarkMode.Size = New Size(153, 22) SettingsToolStripMenuItem.Text = "Settings"
ToolStripMenuItemDarkMode.Text = "Dark Mode"
' '
' ToolStripMenuItemSavePosts ' DarkModeToolStripMenuItem
' '
ToolStripMenuItemSavePosts.AutoToolTip = True DarkModeToolStripMenuItem.CheckOnClick = True
ToolStripMenuItemSavePosts.DropDownItems.AddRange(New ToolStripItem() {ToolStripMenuItemtoJSON, ToolStripMenuItemtoCSV}) DarkModeToolStripMenuItem.Image = CType(resources.GetObject("DarkModeToolStripMenuItem.Image"), Image)
ToolStripMenuItemSavePosts.Image = CType(resources.GetObject("ToolStripMenuItemSavePosts.Image"), Image) DarkModeToolStripMenuItem.Name = "DarkModeToolStripMenuItem"
ToolStripMenuItemSavePosts.Name = "ToolStripMenuItemSavePosts" DarkModeToolStripMenuItem.Size = New Size(180, 22)
ToolStripMenuItemSavePosts.Size = New Size(153, 22) DarkModeToolStripMenuItem.Text = "Dark Mode"
ToolStripMenuItemSavePosts.Text = "Save Posts"
ToolStripMenuItemSavePosts.ToolTipText = "Save found posts to..."
' '
' ToolStripMenuItemtoJSON ' SavePostsToolStripMenuItem
' '
ToolStripMenuItemtoJSON.AutoToolTip = True SavePostsToolStripMenuItem.AutoToolTip = True
ToolStripMenuItemtoJSON.CheckOnClick = True SavePostsToolStripMenuItem.DropDownItems.AddRange(New ToolStripItem() {ToJSONToolStripMenuItem, ToCSVToolStripMenuItem})
ToolStripMenuItemtoJSON.Image = CType(resources.GetObject("ToolStripMenuItemtoJSON.Image"), Image) SavePostsToolStripMenuItem.Image = CType(resources.GetObject("SavePostsToolStripMenuItem.Image"), Image)
ToolStripMenuItemtoJSON.Name = "ToolStripMenuItemtoJSON" SavePostsToolStripMenuItem.Name = "SavePostsToolStripMenuItem"
ToolStripMenuItemtoJSON.Size = New Size(116, 22) SavePostsToolStripMenuItem.Size = New Size(180, 22)
ToolStripMenuItemtoJSON.Text = "to JSON" SavePostsToolStripMenuItem.Text = "Save posts"
' '
' ToolStripMenuItemtoCSV ' ToJSONToolStripMenuItem
' '
ToolStripMenuItemtoCSV.AutoToolTip = True ToJSONToolStripMenuItem.AutoToolTip = True
ToolStripMenuItemtoCSV.Enabled = False ToJSONToolStripMenuItem.CheckOnClick = True
ToolStripMenuItemtoCSV.Image = CType(resources.GetObject("ToolStripMenuItemtoCSV.Image"), Image) ToJSONToolStripMenuItem.Image = CType(resources.GetObject("ToJSONToolStripMenuItem.Image"), Image)
ToolStripMenuItemtoCSV.Name = "ToolStripMenuItemtoCSV" ToJSONToolStripMenuItem.Name = "ToJSONToolStripMenuItem"
ToolStripMenuItemtoCSV.Size = New Size(116, 22) ToJSONToolStripMenuItem.Size = New Size(180, 22)
ToolStripMenuItemtoCSV.Text = "to CSV" ToJSONToolStripMenuItem.Text = "to JSON"
' '
' ToolStripMenuItemAbout ' ToCSVToolStripMenuItem
' '
ToolStripMenuItemAbout.AutoToolTip = True ToCSVToolStripMenuItem.AutoToolTip = True
ToolStripMenuItemAbout.Image = CType(resources.GetObject("ToolStripMenuItemAbout.Image"), Image) ToCSVToolStripMenuItem.CheckOnClick = True
ToolStripMenuItemAbout.Name = "ToolStripMenuItemAbout" ToCSVToolStripMenuItem.Image = CType(resources.GetObject("ToCSVToolStripMenuItem.Image"), Image)
ToolStripMenuItemAbout.Size = New Size(153, 22) ToCSVToolStripMenuItem.Name = "ToCSVToolStripMenuItem"
ToolStripMenuItemAbout.Text = "About" ToCSVToolStripMenuItem.Size = New Size(180, 22)
ToCSVToolStripMenuItem.Text = "to CSV"
' '
' ToolStripMenuItemDeveloper ' AboutToolStripMenuItem
' '
ToolStripMenuItemDeveloper.AutoToolTip = True AboutToolStripMenuItem.AutoToolTip = True
ToolStripMenuItemDeveloper.Image = CType(resources.GetObject("ToolStripMenuItemDeveloper.Image"), Image) AboutToolStripMenuItem.Image = CType(resources.GetObject("AboutToolStripMenuItem.Image"), Image)
ToolStripMenuItemDeveloper.Name = "ToolStripMenuItemDeveloper" AboutToolStripMenuItem.Name = "AboutToolStripMenuItem"
ToolStripMenuItemDeveloper.Size = New Size(153, 22) AboutToolStripMenuItem.Size = New Size(171, 22)
ToolStripMenuItemDeveloper.Text = "Developer" AboutToolStripMenuItem.Text = "About"
' '
' ToolStripMenuItemCheckUpdates ' DeveloperToolStripMenuItem
' '
ToolStripMenuItemCheckUpdates.AutoToolTip = True DeveloperToolStripMenuItem.AutoToolTip = True
ToolStripMenuItemCheckUpdates.Image = CType(resources.GetObject("ToolStripMenuItemCheckUpdates.Image"), Image) DeveloperToolStripMenuItem.Image = CType(resources.GetObject("DeveloperToolStripMenuItem.Image"), Image)
ToolStripMenuItemCheckUpdates.Name = "ToolStripMenuItemCheckUpdates" DeveloperToolStripMenuItem.Name = "DeveloperToolStripMenuItem"
ToolStripMenuItemCheckUpdates.Size = New Size(153, 22) DeveloperToolStripMenuItem.Size = New Size(171, 22)
ToolStripMenuItemCheckUpdates.Text = "Check Updates" DeveloperToolStripMenuItem.Text = "Developer"
' '
' ToolStripMenuItemQuit ' CheckForUpdatesToolStripMenuItem
' '
ToolStripMenuItemQuit.AutoToolTip = True CheckForUpdatesToolStripMenuItem.AutoToolTip = True
ToolStripMenuItemQuit.Image = CType(resources.GetObject("ToolStripMenuItemQuit.Image"), Image) CheckForUpdatesToolStripMenuItem.Image = CType(resources.GetObject("CheckForUpdatesToolStripMenuItem.Image"), Image)
ToolStripMenuItemQuit.Name = "ToolStripMenuItemQuit" CheckForUpdatesToolStripMenuItem.Name = "CheckForUpdatesToolStripMenuItem"
ToolStripMenuItemQuit.Size = New Size(153, 22) CheckForUpdatesToolStripMenuItem.Size = New Size(171, 22)
ToolStripMenuItemQuit.Text = "Quit" CheckForUpdatesToolStripMenuItem.Text = "Check for Updates"
'
' QuitToolStripMenuItem
'
QuitToolStripMenuItem.AutoToolTip = True
QuitToolStripMenuItem.Font = New Font("Segoe UI Semibold", 9F, FontStyle.Bold, GraphicsUnit.Point)
QuitToolStripMenuItem.Image = CType(resources.GetObject("QuitToolStripMenuItem.Image"), Image)
QuitToolStripMenuItem.Name = "QuitToolStripMenuItem"
QuitToolStripMenuItem.Size = New Size(171, 22)
QuitToolStripMenuItem.Text = "Quit"
' '
' NumericUpDownLimit ' NumericUpDownLimit
' '
@@ -245,7 +253,7 @@ Partial Class FormMain
NumericUpDownLimit.ReadOnly = True NumericUpDownLimit.ReadOnly = True
NumericUpDownLimit.Size = New Size(100, 23) NumericUpDownLimit.Size = New Size(100, 23)
NumericUpDownLimit.TabIndex = 15 NumericUpDownLimit.TabIndex = 15
ToolTip.SetToolTip(NumericUpDownLimit, "Set how many posts you want to go through. Default value is `10`.") ToolTip.SetToolTip(NumericUpDownLimit, "Number of posts to go through. Default value is `10`.")
NumericUpDownLimit.Value = New Decimal(New Integer() {10, 0, 0, 0}) NumericUpDownLimit.Value = New Decimal(New Integer() {10, 0, 0, 0})
' '
' ToolTip ' ToolTip
@@ -298,14 +306,16 @@ Partial Class FormMain
Friend WithEvents LabelListing As Label Friend WithEvents LabelListing As Label
Friend WithEvents LabelTimeframe As Label Friend WithEvents LabelTimeframe As Label
Friend WithEvents ContextMenuStripRightClick As ContextMenuStrip Friend WithEvents ContextMenuStripRightClick As ContextMenuStrip
Friend WithEvents ToolStripMenuItemSavePosts As ToolStripMenuItem Friend WithEvents SavePostsToolStripMenuItem As ToolStripMenuItem
Friend WithEvents ToolStripMenuItemtoJSON As ToolStripMenuItem Friend WithEvents ToJSONToolStripMenuItem As ToolStripMenuItem
Friend WithEvents ToolStripMenuItemtoCSV As ToolStripMenuItem Friend WithEvents ToCSVToolStripMenuItem As ToolStripMenuItem
Friend WithEvents NumericUpDownLimit As NumericUpDown Friend WithEvents NumericUpDownLimit As NumericUpDown
Friend WithEvents ToolStripMenuItemDarkMode As ToolStripMenuItem Friend WithEvents AboutToolStripMenuItem As ToolStripMenuItem
Friend WithEvents ToolStripMenuItemAbout As ToolStripMenuItem Friend WithEvents DeveloperToolStripMenuItem As ToolStripMenuItem
Friend WithEvents ToolStripMenuItemDeveloper As ToolStripMenuItem Friend WithEvents CheckForUpdatesToolStripMenuItem As ToolStripMenuItem
Friend WithEvents ToolStripMenuItemCheckUpdates As ToolStripMenuItem Friend WithEvents QuitToolStripMenuItem As ToolStripMenuItem
Friend WithEvents ToolStripMenuItemQuit As ToolStripMenuItem
Friend WithEvents ToolTip As ToolTip Friend WithEvents ToolTip As ToolTip
Friend WithEvents SettingsToolStripMenuItem As ToolStripMenuItem
Friend WithEvents DarkModeToolStripMenuItem As ToolStripMenuItem
Friend WithEvents SaveFoundPostsToolStripMenuItem As ToolStripMenuItem
End Class End Class

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,4 @@
Imports System.IO Imports Newtonsoft.Json.Linq
Imports System.Windows.Forms.VisualStyles.VisualStyleElement
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class FormMain Public Class FormMain
ReadOnly settings As New SettingsManager() ReadOnly settings As New SettingsManager()
@@ -14,32 +11,25 @@ Public Class FormMain
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param> ''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
settings.LoadSettings() settings.LoadSettings()
settings.ToggleDarkMode(settings.DarkMode) settings.ToggleSettings(settings.DarkMode, "darkmode")
settings.ToggleSettings(settings.SaveToJson, "json")
settings.ToggleSettings(settings.SaveToCsv, "csv")
Utilities.PathFinder() Utilities.PathFinder()
Utilities.LogFirstTimeLaunch() Utilities.LogFirstTimeLaunch()
Me.Text = My.Application.Info.AssemblyName Me.Text = My.Application.Info.AssemblyName
End Sub End Sub
''' <summary>
''' Event handler for the 'Dark Mode' checkbox change event.
''' It toggles the dark mode of the application based on the checkbox status.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub DarkModeToolStripMenuItem_CheckedChanged(sender As Object, e As EventArgs) Handles ToolStripMenuItemDarkMode.CheckedChanged
settings.ToggleDarkMode(ToolStripMenuItemDarkMode.Checked)
End Sub
''' <summary> ''' <summary>
''' Event handler for the 'About' menu item click. ''' Event handler for the 'About' menu item click.
''' It shows the 'About' box. ''' It shows the 'About' box.
''' </summary> ''' </summary>
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param> ''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub ToolStripMenuItemAbout_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItemAbout.Click Private Sub ToolStripMenuItemAbout_Click(sender As Object, e As EventArgs) Handles AboutToolStripMenuItem.Click
AboutBox.Show() AboutBox.Show()
End Sub End Sub
@@ -50,7 +40,7 @@ Public Class FormMain
''' </summary> ''' </summary>
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param> ''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub ToolStripMenuItemDeveloper_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItemDeveloper.Click Private Sub ToolStripMenuItemDeveloper_Click(sender As Object, e As EventArgs) Handles DeveloperToolStripMenuItem.Click
DeveloperBox.ShowDialog() DeveloperBox.ShowDialog()
End Sub End Sub
@@ -61,7 +51,7 @@ Public Class FormMain
''' </summary> ''' </summary>
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param> ''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub ToolStripMenuItemCheckUpdates_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItemCheckUpdates.Click Private Sub ToolStripMenuItemCheckUpdates_Click(sender As Object, e As EventArgs) Handles CheckForUpdatesToolStripMenuItem.Click
Dim data As JObject = ApiHandler.CheckUpdates() Dim data As JObject = ApiHandler.CheckUpdates()
If data("tag_name").ToString = My.Application.Info.Version.ToString Then If data("tag_name").ToString = My.Application.Info.Version.ToString Then
MessageBox.Show($"You're running the latest version v{My.Application.Info.Version} of {Me.Text}. Check again soon! :)", $"{Me.Text} v{My.Application.Info.Version}", MessageBoxButtons.OK, MessageBoxIcon.Information) MessageBox.Show($"You're running the latest version v{My.Application.Info.Version} of {Me.Text}. Check again soon! :)", $"{Me.Text} v{My.Application.Info.Version}", MessageBoxButtons.OK, MessageBoxIcon.Information)
@@ -83,7 +73,7 @@ Public Class FormMain
''' </summary> ''' </summary>
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param> ''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub ToolStripMenuItemQuit_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItemQuit.Click Private Sub ToolStripMenuItemQuit_Click(sender As Object, e As EventArgs) Handles QuitToolStripMenuItem.Click
Dim result As DialogResult = MessageBox.Show("This will close the program, continue?", "Quit", MessageBoxButtons.YesNo, MessageBoxIcon.Question) Dim result As DialogResult = MessageBox.Show("This will close the program, continue?", "Quit", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If result = DialogResult.Yes Then If result = DialogResult.Yes Then
Me.Close() Me.Close()
@@ -99,7 +89,8 @@ Public Class FormMain
''' <param name="sender">The sender of the event.</param> ''' <param name="sender">The sender of the event.</param>
''' <param name="e">The EventArgs instance containing the event data.</param> ''' <param name="e">The EventArgs instance containing the event data.</param>
Private Sub ButtonScrape_Click(sender As Object, e As EventArgs) Handles ButtonScrape.Click Private Sub ButtonScrape_Click(sender As Object, e As EventArgs) Handles ButtonScrape.Click
Utilities.ProcessRedditPosts(ToolStripMenuItemtoJSON) settings.LoadSettings()
PostsProcessor.ProcessRedditPosts(settings:=settings)
End Sub End Sub
@@ -110,11 +101,13 @@ Public Class FormMain
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param> ''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param>
Private Sub TextBoxKeyword_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBoxKeyword.KeyDown Private Sub TextBoxKeyword_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBoxKeyword.KeyDown
settings.LoadSettings()
' Check if the Enter key is pressed ' Check if the Enter key is pressed
If e.KeyCode = Keys.Enter Then If e.KeyCode = Keys.Enter Then
' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox ' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox
e.SuppressKeyPress = True e.SuppressKeyPress = True
Utilities.ProcessRedditPosts(ToolStripMenuItemtoJSON) PostsProcessor.ProcessRedditPosts(settings:=settings)
End If End If
End Sub End Sub
@@ -126,11 +119,13 @@ Public Class FormMain
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param> ''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param>
Private Sub TextBoxSubreddit_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBoxSubreddit.KeyDown Private Sub TextBoxSubreddit_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBoxSubreddit.KeyDown
settings.LoadSettings()
' Check if the Enter key is pressed ' Check if the Enter key is pressed
If e.KeyCode = Keys.Enter Then If e.KeyCode = Keys.Enter Then
' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox ' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox
e.SuppressKeyPress = True e.SuppressKeyPress = True
Utilities.ProcessRedditPosts(ToolStripMenuItemtoJSON) PostsProcessor.ProcessRedditPosts(settings:=settings)
End If End If
End Sub End Sub
@@ -142,11 +137,13 @@ Public Class FormMain
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param> ''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param>
Private Sub NumericUpDownLimit_KeyDown(sender As Object, e As KeyEventArgs) Handles NumericUpDownLimit.KeyDown Private Sub NumericUpDownLimit_KeyDown(sender As Object, e As KeyEventArgs) Handles NumericUpDownLimit.KeyDown
settings.LoadSettings()
' Check if the Enter key is pressed ' Check if the Enter key is pressed
If e.KeyCode = Keys.Enter Then If e.KeyCode = Keys.Enter Then
' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox ' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox
e.SuppressKeyPress = True e.SuppressKeyPress = True
Utilities.ProcessRedditPosts(ToolStripMenuItemtoJSON) PostsProcessor.ProcessRedditPosts(settings:=settings)
End If End If
End Sub End Sub
@@ -158,11 +155,13 @@ Public Class FormMain
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param> ''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param>
Private Sub ComboBoxListing_KeyDown(sender As Object, e As KeyEventArgs) Handles ComboBoxListing.KeyDown Private Sub ComboBoxListing_KeyDown(sender As Object, e As KeyEventArgs) Handles ComboBoxListing.KeyDown
settings.LoadSettings()
' Check if the Enter key is pressed ' Check if the Enter key is pressed
If e.KeyCode = Keys.Enter Then If e.KeyCode = Keys.Enter Then
' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox ' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox
e.SuppressKeyPress = True e.SuppressKeyPress = True
Utilities.ProcessRedditPosts(ToolStripMenuItemtoJSON) PostsProcessor.ProcessRedditPosts(settings:=settings)
End If End If
End Sub End Sub
@@ -174,11 +173,43 @@ Public Class FormMain
''' <param name="sender">The source of the event.</param> ''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param> ''' <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param>
Private Sub ComboBoxTimeframe_KeyDown(sender As Object, e As KeyEventArgs) Handles ComboBoxTimeframe.KeyDown Private Sub ComboBoxTimeframe_KeyDown(sender As Object, e As KeyEventArgs) Handles ComboBoxTimeframe.KeyDown
settings.LoadSettings()
' Check if the Enter key is pressed ' Check if the Enter key is pressed
If e.KeyCode = Keys.Enter Then If e.KeyCode = Keys.Enter Then
' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox ' Prevent the beep sound that usually comes with the Enter key in a single-line TextBox
e.SuppressKeyPress = True e.SuppressKeyPress = True
Utilities.ProcessRedditPosts(ToolStripMenuItemtoJSON) PostsProcessor.ProcessRedditPosts(settings:=settings)
End If End If
End Sub End Sub
''' <summary>
''' Event handler for the 'Dark Mode' checkbox change event.
''' It toggles the dark mode of the application based on the checkbox status.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub ToolStripMenuItemDarkMode_CheckedChanged(sender As Object, e As EventArgs) Handles DarkModeToolStripMenuItem.CheckedChanged
settings.ToggleSettings(DarkModeToolStripMenuItem.Checked, "darkmode")
End Sub
''' <summary>
''' Event handler for the 'to CSV' checkbox change event.
''' It toggles the dark mode of the application based on the checkbox status.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub ToCSVToolStripMenuItem_CheckedChanged(sender As Object, e As EventArgs) Handles ToCSVToolStripMenuItem.CheckedChanged
settings.ToggleSettings(ToCSVToolStripMenuItem.Checked, "csv")
End Sub
''' <summary>
''' Event handler for the 'to JSON' checkbox change event.
''' It toggles the dark mode of the application based on the checkbox status.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">An EventArgs that contains the event data.</param>
Private Sub ToJSONToolStripMenuItem_CheckedChanged(sender As Object, e As EventArgs) Handles ToJSONToolStripMenuItem.CheckedChanged
settings.ToggleSettings(ToJSONToolStripMenuItem.Checked, "json")
End Sub
End Class End Class

View File

@@ -26,4 +26,63 @@ Public Class PostsProcessor
Return post("data")("selftext").ToString.ToLower(Globalization.CultureInfo.InvariantCulture).Contains(keyword.ToLower(System.Globalization.CultureInfo.InvariantCulture)) Return post("data")("selftext").ToString.ToLower(Globalization.CultureInfo.InvariantCulture).Contains(keyword.ToLower(System.Globalization.CultureInfo.InvariantCulture))
End Function End Function
''' <summary>
''' Collects user inputs, fetches Reddit posts based on the inputs, checks if posts contain the keyword, and saves posts to a JSON file if necessary.
''' </summary>
''' <param name="JSONToolStripMenuItem">Indicates whether to save the posts to a JSON file.</param>
''' <remarks>
''' This function initializes the DataGridView, iterates over each post, adds the posts containing the keyword to the DataGridView and updates the UI.
''' It also shows a message if the keyword was not found in any of the posts or if the inputs are empty.
''' </remarks>
Public Shared Sub ProcessRedditPosts(settings)
' Collect inputs from the user.
Dim inputs = Utilities.CollectInputs()
If inputs.HasValue Then
' Initialize the DataGridView.
DataGridViewHandler.AddColumn(FormPosts.DataGridViewPosts)
' Fetch Reddit posts based on the inputs.
Dim processor As New PostsProcessor()
Dim posts As JObject = processor.FetchPosts(inputs.Value.Subreddit, inputs.Value.Listing, inputs.Value.Limit, inputs.Value.Timeframe)
Dim totalPosts As Integer = 0
Dim keywordFound As Boolean = False
Dim foundPosts As Integer = 0
Dim foundPostsList As New JArray
' Iterate over each post.
For Each post In posts("data")("children")
totalPosts += 1
' Check if the post contains the keyword
If PostsProcessor.PostContainsKeyword(post, inputs.Value.Keyword.ToLower(Globalization.CultureInfo.InvariantCulture)) Then
foundPosts += 1
foundPostsList.Add(post)
' Add the post to the DataGridView.
DataGridViewHandler.AddRow(FormPosts.DataGridViewPosts, post, totalPosts)
FormPosts.Show()
keywordFound = True
End If
Next
' Check if the keyword was found in any posts
If Not keywordFound Then
MessageBox.Show($"Keyword `{inputs.Value.Keyword}` was not found in any of the " + posts("data")("children").Count.ToString(Globalization.CultureInfo.InvariantCulture) _
+ $" {inputs.Value.Listing} posts from r/{inputs.Value.Subreddit}", "Not Found", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
If settings.SaveToJson Then
' Save posts to a JSON file if SaveToJson is True.
Utilities.SavePostsToJson(foundPostsList)
End If
If settings.SaveToCsv Then
' Save posts to a CSV file if SaveToCsv is True.
Utilities.SavePostsToCSV(foundPostsList)
End If
Else
End If
End Sub
End Class End Class

View File

@@ -4,41 +4,39 @@ Given a subreddit name and a keyword, RPST will return all posts from a specifie
[![Upload Python Package](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/python-publish.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/python-publish.yml) [![CodeQL](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/codeql.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/codeql.yml) ![.Net](https://img.shields.io/badge/.NET-5C2D91?style=flat&logo=.net&logoColor=white) ![Python](https://img.shields.io/badge/python-3670A0?style=flat&logo=python&logoColor=ffdd54) [![Upload Python Package](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/python-publish.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/python-publish.yml) [![CodeQL](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/codeql.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/codeql.yml) ![.Net](https://img.shields.io/badge/.NET-5C2D91?style=flat&logo=.net&logoColor=white) ![Python](https://img.shields.io/badge/python-3670A0?style=flat&logo=python&logoColor=ffdd54)
# ✅ Features # ✅ Features
## GUI ## *GUI*
- [x] Dark mode (*Right-click*) - [x] Dark mode (*Right-click*).
- [x] Saves results to a JSON file (*Right-click*) - [x] Saves results to a JSON file (*Right-click*).
- [x] Logs errors to a file - [x] Logs errors to a file.
- [x] In-App feature to check for Updates.
## CLI ## *CLI*
- [x] Saves results to JSON (*specifiy* `--json`) - [x] Saves results to JSON (*specifiy* `--json`).
- [x] Saves results to CSV (*specify* `--csv`) - [x] Saves results to CSV (*specify* `--csv`).
- [x] Automatically checks for new updates, and notifies user if updates were found. - [x] Automatically checks for new updates, and notifies user if updates were found.
# 📃 TODO # 📃 TODO
## GUI ## *GUI*
- [ ] Make it installable with a setup.exe/setup.msi file. - [ ] Make it installable with a setup.exe/setup.msi file.
- [x] Add manual dark mode option, that will be persistent in all sessions - [x] Add manual dark mode option, that will be persistent in all sessions.
- [ ] Make it save results to a CSV file - [x] Make settings persistent in all sessions.
- [x] Make it save results to a CSV file.
# Images & Screenshots
## GUI
* ![2023-08-09_04-05](https://github.com/bellingcat/reddit-post-scraping-tool/assets/74001397/d8917a35-3eac-44ce-aa96-1f9685095254)
* ![2023-08-09_04-05_1](https://github.com/bellingcat/reddit-post-scraping-tool/assets/74001397/d2fe7269-91d4-49ad-87fb-44282c5637a7)
## CLI
* ![2023-08-25_15-39](https://github.com/bellingcat/reddit-post-scraping-tool/assets/74001397/4bca09b3-271f-452d-81a7-39c9986539f2)
* ![2023-08-25_15-30](https://github.com/bellingcat/reddit-post-scraping-tool/assets/74001397/2b39bdfa-87d0-4038-90cd-14e7d3b6a84b)
* ![2023-08-25_15-35](https://github.com/bellingcat/reddit-post-scraping-tool/assets/74001397/47ba23ad-8d32-49c5-8c16-34a903fbc581)
# 🖥️ Tested environments
## *GUI*
- [x] Microsoft Windows 11
## *CLI*
- [x] Android Termux
- [x] Microsoft Windows 11
- [x] Ubuntu 22.04 - latest versions
# 📖 Wiki # 📖 Wiki
[Refer to the Wiki](https://github.com/bellingcat/reddit-post-scraping-tool/wiki) for installation instructions, in addition to all other documentation. [Refer to the Wiki](https://github.com/bellingcat/reddit-post-scraping-tool/wiki) for installation instructions, in addition to all other documentation.
# 😁 Donations # 🖼️ Screenshots
If you like `RPST` and would like to show support, you can Buy A Coffee for the developer using the button below You can view a collection of screenshots for both the *CLI* and *GUI* [here](https://github.com/bellingcat/reddit-post-scraping-tool/tree/master/images)
***
<a href="https://www.buymeacoffee.com/_rly0nheart"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=_rly0nheart&button_colour=40DCA5&font_colour=ffffff&font_family=Comic&outline_colour=000000&coffee_colour=FFDD00" /></a>
<a href="https://www.buymeacoffee.com/_rly0nheart" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a> ![me](https://github.com/bellingcat/reddit-post-scraping-tool/assets/74001397/21e0bb33-7a84-45d6-92ba-00e40891ba31)
Your support will be much appreciated😊

View File

@@ -13,11 +13,11 @@
<PackageProjectUrl>https://github.com/bellingcat/reddit-post-scraping-tool</PackageProjectUrl> <PackageProjectUrl>https://github.com/bellingcat/reddit-post-scraping-tool</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile> <PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/bellingcat/reddit-post-scraping-tool</RepositoryUrl> <RepositoryUrl>https://github.com/bellingcat/reddit-post-scraping-tool</RepositoryUrl>
<AssemblyVersion>1.7.0.1</AssemblyVersion> <AssemblyVersion>1.8.0.0</AssemblyVersion>
<FileVersion>1.7.0.1</FileVersion> <FileVersion>1.8.0.0</FileVersion>
<PackageLicenseFile>LICENSE</PackageLicenseFile> <PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance> <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<Version>1.7.0</Version> <Version>1.8.0</Version>
<PackageTags>reddit;scraper;reddit-scraper;osint</PackageTags> <PackageTags>reddit;scraper;reddit-scraper;osint</PackageTags>
<PackageReleaseNotes></PackageReleaseNotes> <PackageReleaseNotes></PackageReleaseNotes>
<AnalysisLevel>6.0-recommended</AnalysisLevel> <AnalysisLevel>6.0-recommended</AnalysisLevel>

View File

@@ -10,8 +10,10 @@ Public Class SettingsManager
''' Indicates whether the dark mode is enabled or disabled. ''' Indicates whether the dark mode is enabled or disabled.
''' </summary> ''' </summary>
Public Property DarkMode As Boolean Public Property DarkMode As Boolean
Public Property SaveToJson As Boolean
Public Property SaveToCsv As Boolean
Private ReadOnly settingsFilePath As String = Path.Combine(Environment.CurrentDirectory, "settings.json") Private ReadOnly settingsFilePath As String = Path.Combine(Environment.CurrentDirectory, "config.json")
''' <summary> ''' <summary>
''' Loads application settings from the 'settings.json' file. ''' Loads application settings from the 'settings.json' file.
@@ -23,34 +25,55 @@ Public Class SettingsManager
If File.Exists(settingsFilePath) Then If File.Exists(settingsFilePath) Then
Dim json As String = File.ReadAllText(settingsFilePath) Dim json As String = File.ReadAllText(settingsFilePath)
Dim options As New JsonSerializerOptions With {.PropertyNameCaseInsensitive = True} Dim options As New JsonSerializerOptions With {.PropertyNameCaseInsensitive = True}
Dim settings = Text.Json.JsonSerializer.Deserialize(Of SettingsManager)(json, options) Dim settings = JsonSerializer.Deserialize(Of SettingsManager)(json, options)
Me.DarkMode = settings.DarkMode
FormMain.ToolStripMenuItemDarkMode.Checked = settings.DarkMode DarkMode = settings.DarkMode
SaveToJson = settings.SaveToJson
SaveToCsv = settings.SaveToCsv
FormMain.DarkModeToolStripMenuItem.Checked = settings.DarkMode
FormMain.ToJSONToolStripMenuItem.Checked = settings.SaveToJson
FormMain.ToCSVToolStripMenuItem.Checked = settings.SaveToCsv
Else Else
' Settings file does not exist ' Settings file does not exist
' Create a new file with default settings 'False' ' Create a new file with default settings 'False'
Dim defaultSettings = New SettingsManager With {.DarkMode = False} Dim defaultSettings = New SettingsManager With {.DarkMode = False, .SaveToCsv = False, .SaveToJson = False}
Dim jsonOutput = Text.Json.JsonSerializer.Serialize(defaultSettings) Dim jsonOutput = JsonSerializer.Serialize(defaultSettings)
File.WriteAllText(settingsFilePath, jsonOutput) File.WriteAllText(settingsFilePath, jsonOutput)
Me.DarkMode = False DarkMode = False
FormMain.ToolStripMenuItemDarkMode.Checked = False SaveToJson = False
SaveToCsv = False
FormMain.ToJSONToolStripMenuItem.Checked = False
FormMain.ToCSVToolStripMenuItem.Checked = False
FormMain.DarkModeToolStripMenuItem.Checked = False
End If End If
End Sub End Sub
''' <summary> ''' <summary>
''' Toggles the Dark Mode setting on or off based on the provided parameter. ''' Retrieves application settings from a JSON file.
''' </summary> ''' </summary>
''' <param name="enabled">A Boolean indicating if Dark Mode should be enabled or not.</param> ''' <returns>A Dictionary containing the names and values of all settings.
Public Sub ToggleDarkMode(enabled As Boolean) ''' If the settings file doesn't exist, returns a Dictionary with default values.</returns>
Dim json As String = File.ReadAllText(settingsFilePath) Private Function GetSettings() As Dictionary(Of String, Object)
Dim options As New JsonSerializerOptions With {.PropertyNameCaseInsensitive = True} Dim settings As New Dictionary(Of String, Object)
Dim settings As SettingsManager = JsonSerializer.Deserialize(Of SettingsManager)(json, options) If File.Exists(settingsFilePath) Then
settings.DarkMode = enabled ' Read and parse the JSON settings file.
SaveSettings(settings) Dim json As String = File.ReadAllText(settingsFilePath)
ApplyTheme() Dim jObject As JObject = JObject.Parse(json)
End Sub
' Loop through each property in the JObject and add it to the settings Dictionary.
For Each item As JProperty In jObject.Properties()
settings.Add(item.Name, item.Value.ToObject(Of Object)())
Next
Else
End If
Return settings
End Function
''' <summary> ''' <summary>
''' Saves the provided settings to the 'settings.json' file. ''' Saves the provided settings to the 'settings.json' file.
@@ -63,12 +86,20 @@ Public Class SettingsManager
''' <summary> ''' <summary>
''' Applies the visual theme based on the Dark Mode setting. ''' Applies the current settings to the application's interface. This includes
''' If Dark Mode is enabled, a dark theme is applied. If it's disabled, a light theme is set. ''' toggling SaveToJson, SaveToCsv, and applying the visual theme based on the Dark Mode setting.
''' </summary> ''' </summary>
Public Sub ApplyTheme() Public Sub ApplySettings()
Dim DarkMode As Boolean = GetDarkMode() ' Retrieve the current settings
If DarkMode Then Dim settings As Dictionary(Of String, Object) = GetSettings()
' Apply the SaveToJson setting to the menu item checkbox
FormMain.ToJSONToolStripMenuItem.Checked = CBool(settings("SaveToJson"))
' Apply the SaveToCsv setting to the menu item checkbox
FormMain.ToCSVToolStripMenuItem.Checked = CBool(settings("SaveToCsv"))
If CBool(settings("DarkMode")) Then
' Enable dark mode for the Main form ' Enable dark mode for the Main form
' Background colours (I know 'Colours'/'Colors'😆) ' Background colours (I know 'Colours'/'Colors'😆)
FormMain.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.BackColor = ColorTranslator.FromHtml("#FF121212")
@@ -94,23 +125,25 @@ Public Class SettingsManager
' Enable dark mode on 'Right Click Menu' items ' Enable dark mode on 'Right Click Menu' items
' Background colours ' Background colours
FormMain.ToolStripMenuItemDarkMode.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.SettingsToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
FormMain.ToolStripMenuItemSavePosts.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.DarkModeToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
FormMain.ToolStripMenuItemtoJSON.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.SavePostsToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
FormMain.ToolStripMenuItemtoCSV.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.ToJSONToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
FormMain.ToolStripMenuItemAbout.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.ToCSVToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
FormMain.ToolStripMenuItemDeveloper.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.AboutToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
FormMain.ToolStripMenuItemCheckUpdates.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.DeveloperToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
FormMain.ToolStripMenuItemQuit.BackColor = ColorTranslator.FromHtml("#FF121212") FormMain.CheckForUpdatesToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
FormMain.QuitToolStripMenuItem.BackColor = ColorTranslator.FromHtml("#FF121212")
' Foreground colours ' Foreground colours
FormMain.ToolStripMenuItemDarkMode.ForeColor = SystemColors.Control FormMain.SettingsToolStripMenuItem.ForeColor = SystemColors.Control
FormMain.ToolStripMenuItemSavePosts.ForeColor = SystemColors.Control FormMain.DarkModeToolStripMenuItem.ForeColor = SystemColors.Control
FormMain.ToolStripMenuItemtoJSON.ForeColor = SystemColors.Control FormMain.SavePostsToolStripMenuItem.ForeColor = SystemColors.Control
FormMain.ToolStripMenuItemtoCSV.ForeColor = SystemColors.Control FormMain.ToJSONToolStripMenuItem.ForeColor = SystemColors.Control
FormMain.ToolStripMenuItemAbout.ForeColor = SystemColors.Control FormMain.ToCSVToolStripMenuItem.ForeColor = SystemColors.Control
FormMain.ToolStripMenuItemDeveloper.ForeColor = SystemColors.Control FormMain.AboutToolStripMenuItem.ForeColor = SystemColors.Control
FormMain.ToolStripMenuItemCheckUpdates.ForeColor = SystemColors.Control FormMain.DeveloperToolStripMenuItem.ForeColor = SystemColors.Control
FormMain.ToolStripMenuItemQuit.ForeColor = SystemColors.Control FormMain.CheckForUpdatesToolStripMenuItem.ForeColor = SystemColors.Control
FormMain.QuitToolStripMenuItem.ForeColor = SystemColors.Control
' Enable dark mode for the About box ' Enable dark mode for the About box
@@ -123,10 +156,10 @@ Public Class SettingsManager
AboutBox.LicenseRichTextBox.ForeColor = SystemColors.Control AboutBox.LicenseRichTextBox.ForeColor = SystemColors.Control
AboutBox.LabelProgramName.ForeColor = SystemColors.Control AboutBox.LabelProgramName.ForeColor = SystemColors.Control
AboutBox.LabelProgramDescription.ForeColor = SystemColors.Control AboutBox.LabelProgramDescription.ForeColor = SystemColors.Control
AboutBox.LabelVersion.ForeColor = SystemColors.Control AboutBox.LinkLabelVersion.ForeColor = SystemColors.Control
' If dark mode is enabled, set the 'Dark Mode' text value to 'Light mode' ' If dark mode is enabled, set the 'Dark Mode' text value to 'Light mode'
FormMain.ToolStripMenuItemDarkMode.Text = "Light Mode" FormMain.DarkModeToolStripMenuItem.Text = "Dark Mode: Enabled"
Else Else
' Disable dark mode for the Main Form ' Disable dark mode for the Main Form
' Background colours ' Background colours
@@ -152,23 +185,25 @@ Public Class SettingsManager
' Disable dark mode on 'Right Click Menu' items ' Disable dark mode on 'Right Click Menu' items
' Background colours ' Background colours
FormMain.ToolStripMenuItemDarkMode.BackColor = Color.Gainsboro FormMain.SettingsToolStripMenuItem.BackColor = Color.Gainsboro
FormMain.ToolStripMenuItemSavePosts.BackColor = Color.Gainsboro FormMain.DarkModeToolStripMenuItem.BackColor = Color.Gainsboro
FormMain.ToolStripMenuItemtoJSON.BackColor = Color.Gainsboro FormMain.SavePostsToolStripMenuItem.BackColor = Color.Gainsboro
FormMain.ToolStripMenuItemtoCSV.BackColor = Color.Gainsboro FormMain.ToJSONToolStripMenuItem.BackColor = Color.Gainsboro
FormMain.ToolStripMenuItemAbout.BackColor = Color.Gainsboro FormMain.ToCSVToolStripMenuItem.BackColor = Color.Gainsboro
FormMain.ToolStripMenuItemDeveloper.BackColor = Color.Gainsboro FormMain.AboutToolStripMenuItem.BackColor = Color.Gainsboro
FormMain.ToolStripMenuItemCheckUpdates.BackColor = Color.Gainsboro FormMain.DeveloperToolStripMenuItem.BackColor = Color.Gainsboro
FormMain.ToolStripMenuItemQuit.BackColor = Color.Gainsboro FormMain.CheckForUpdatesToolStripMenuItem.BackColor = Color.Gainsboro
FormMain.QuitToolStripMenuItem.BackColor = Color.Gainsboro
' Foreground colours ' Foreground colours
FormMain.ToolStripMenuItemDarkMode.ForeColor = Color.Black FormMain.SettingsToolStripMenuItem.ForeColor = Color.Black
FormMain.ToolStripMenuItemSavePosts.ForeColor = Color.Black FormMain.DarkModeToolStripMenuItem.ForeColor = Color.Black
FormMain.ToolStripMenuItemtoJSON.ForeColor = Color.Black FormMain.SavePostsToolStripMenuItem.ForeColor = Color.Black
FormMain.ToolStripMenuItemtoCSV.ForeColor = Color.Black FormMain.ToJSONToolStripMenuItem.ForeColor = Color.Black
FormMain.ToolStripMenuItemAbout.ForeColor = Color.Black FormMain.ToCSVToolStripMenuItem.ForeColor = Color.Black
FormMain.ToolStripMenuItemDeveloper.ForeColor = Color.Black FormMain.AboutToolStripMenuItem.ForeColor = Color.Black
FormMain.ToolStripMenuItemCheckUpdates.ForeColor = Color.Black FormMain.DeveloperToolStripMenuItem.ForeColor = Color.Black
FormMain.ToolStripMenuItemQuit.ForeColor = Color.Black FormMain.CheckForUpdatesToolStripMenuItem.ForeColor = Color.Black
FormMain.QuitToolStripMenuItem.ForeColor = Color.Black
' Disable dark mode for the About box ' Disable dark mode for the About box
' Background colours ' Background colours
@@ -181,26 +216,39 @@ Public Class SettingsManager
AboutBox.Panel1.ForeColor = SystemColors.WindowText AboutBox.Panel1.ForeColor = SystemColors.WindowText
AboutBox.LabelProgramName.ForeColor = SystemColors.WindowText AboutBox.LabelProgramName.ForeColor = SystemColors.WindowText
AboutBox.LabelProgramDescription.ForeColor = SystemColors.WindowText AboutBox.LabelProgramDescription.ForeColor = SystemColors.WindowText
AboutBox.LabelVersion.ForeColor = SystemColors.WindowText AboutBox.LinkLabelVersion.ForeColor = SystemColors.WindowText
' If dark mode is disabled, set the 'Light Mode' text value to 'Dark Mode' ' If dark mode is disabled, set the 'Light Mode' text value to 'Dark Mode'
FormMain.ToolStripMenuItemDarkMode.Text = "Dark Mode" FormMain.DarkModeToolStripMenuItem.Text = "Dark Mode: Disabled"
End If End If
End Sub End Sub
''' <summary> ''' <summary>
''' Retrieves the Dark Mode setting value from 'settings.json'. ''' Toggles specific settings on or off based on the provided parameters.
''' If the settings file doesn't exist, defaults to returning 'False' (Dark Mode off).
''' </summary> ''' </summary>
''' <returns>A Boolean indicating if Dark Mode is enabled or not.</returns> ''' <param name="enabled">A Boolean indicating if the setting option should be enabled or not.</param>
Private Function GetDarkMode() As Boolean ''' <param name="saveTo">A String specifying the type of setting to toggle ('json', 'csv', or 'darkmode').</param>
If File.Exists(settingsFilePath) Then Public Sub ToggleSettings(enabled As Boolean, saveTo As String)
Dim json As String = File.ReadAllText(settingsFilePath) ' Read the existing settings from the settings file
Dim settings As JObject = JObject.Parse(json) Dim json As String = File.ReadAllText(settingsFilePath)
Return settings(NameOf(DarkMode)).ToObject(Of Boolean)() Dim options As New JsonSerializerOptions With {.PropertyNameCaseInsensitive = True}
Dim settings As SettingsManager = JsonSerializer.Deserialize(Of SettingsManager)(json, options)
' Update the settings based on the specified saveTo parameter
If saveTo.ToLower(Globalization.CultureInfo.InvariantCulture) = "json" Then
settings.SaveToJson = enabled
ElseIf saveTo.ToLower(Globalization.CultureInfo.InvariantCulture) = "csv" Then
settings.SaveToCsv = enabled
ElseIf saveTo.ToLower(Globalization.CultureInfo.InvariantCulture) = "darkmode" Then
settings.DarkMode = enabled
Else Else
Return False ' Handle unexpected value of saveTo (if needed)
End If End If
End Function
' Save the updated settings back to the settings file
SaveSettings(settings)
' Apply the updated settings to the application
ApplySettings()
End Sub
End Class End Class

View File

@@ -3,54 +3,6 @@ Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq Imports Newtonsoft.Json.Linq
Public Class Utilities Public Class Utilities
''' <summary>
''' Collects user inputs, fetches Reddit posts based on the inputs, checks if posts contain the keyword, and saves posts to a JSON file if necessary.
''' </summary>
''' <param name="JSONToolStripMenuItem">Indicates whether to save the posts to a JSON file.</param>
''' <remarks>
''' This function initializes the DataGridView, iterates over each post, adds the posts containing the keyword to the DataGridView and updates the UI.
''' It also shows a message if the keyword was not found in any of the posts or if the inputs are empty.
''' </remarks>
Public Shared Sub ProcessRedditPosts(JSONToolStripMenuItem As ToolStripMenuItem)
' Collect inputs from the user
Dim inputs = CollectInputs()
If inputs.HasValue Then
' Initialize the DataGridView
DataGridViewHandler.AddColumn(FormPosts.DataGridViewPosts)
' Fetch Reddit posts based on the inputs
Dim processor As New PostsProcessor()
Dim posts As JObject = processor.FetchPosts(inputs.Value.Subreddit, inputs.Value.Listing, inputs.Value.Limit, inputs.Value.Timeframe)
Dim totalPosts As Integer = 0
Dim keywordFound As Boolean = False
' Iterate over each post
For Each post In posts("data")("children")
totalPosts += 1
' Check if the post contains the keyword
If PostsProcessor.PostContainsKeyword(post, inputs.Value.Keyword.ToLower(Globalization.CultureInfo.InvariantCulture)) Then
' Add the post to the DataGridView
DataGridViewHandler.AddRow(FormPosts.DataGridViewPosts, post, totalPosts)
FormPosts.Show()
keywordFound = True
End If
Next
' Check if the keyword was found in any posts
If Not keywordFound Then
MessageBox.Show($"Keyword `{inputs.Value.Keyword}` was not found in any of the " + posts("data")("children").Count.ToString(Globalization.CultureInfo.InvariantCulture) _
+ $" {inputs.Value.Listing} posts from r/{inputs.Value.Subreddit}", "Not Found", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
If JSONToolStripMenuItem.Checked Then
' Save posts to a JSON file if the JSONToolStripMenuItem is checked
Utilities.SavePostsToJson(posts("data"))
End If
Else
End If
End Sub
''' <summary> ''' <summary>
''' Checks for the existence of the 'logs' directory under the 'RPST' directory within the user's AppData\Roaming folder. ''' Checks for the existence of the 'logs' directory under the 'RPST' directory within the user's AppData\Roaming folder.
@@ -87,14 +39,18 @@ Public Class Utilities
Public Shared Function CollectInputs() As (Keyword As String, Subreddit As String, Listing As String, Limit As Integer, Timeframe As String)? Public Shared Function CollectInputs() As (Keyword As String, Subreddit As String, Listing As String, Limit As Integer, Timeframe As String)?
Dim keyword As String = FormMain.TextBoxKeyword.Text.Trim() Dim keyword As String = FormMain.TextBoxKeyword.Text.Trim()
Dim subreddit As String = FormMain.TextBoxSubreddit.Text.Trim() Dim subreddit As String = FormMain.TextBoxSubreddit.Text.Trim()
' Convert the Listing and Subreddit to lowercase using InvariantCulture ''' <summary>
''' Convert the Listing and Subreddit to lowercase using InvariantCulture.
''' <summary>
Dim listing As String = If(String.IsNullOrEmpty(FormMain.ComboBoxListing.Text), "top", FormMain.ComboBoxListing.Text.ToLower(Globalization.CultureInfo.InvariantCulture).Trim()) Dim listing As String = If(String.IsNullOrEmpty(FormMain.ComboBoxListing.Text), "top", FormMain.ComboBoxListing.Text.ToLower(Globalization.CultureInfo.InvariantCulture).Trim())
Dim timeframe As String = If(String.IsNullOrEmpty(FormMain.ComboBoxTimeframe.Text), "all", FormMain.ComboBoxTimeframe.Text.ToLower(Globalization.CultureInfo.InvariantCulture).Trim()) Dim timeframe As String = If(String.IsNullOrEmpty(FormMain.ComboBoxTimeframe.Text), "all", FormMain.ComboBoxTimeframe.Text.ToLower(Globalization.CultureInfo.InvariantCulture).Trim())
Dim limit As Integer = FormMain.NumericUpDownLimit.Value Dim limit As Integer = FormMain.NumericUpDownLimit.Value
' Validate inputs ''' <summary>
''' Validate inputs.
''' <summary>
If String.IsNullOrEmpty(keyword) AndAlso String.IsNullOrEmpty(subreddit) Then If String.IsNullOrEmpty(keyword) AndAlso String.IsNullOrEmpty(subreddit) Then
MessageBox.Show("Keyword and Subreddit fields should not be empty.", "Invalid Inputs", MessageBoxButtons.OK, MessageBoxIcon.Warning) MessageBox.Show("Keyword and Subreddit should not be empty.", "Invalid Inputs", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Return Nothing Return Nothing
ElseIf String.IsNullOrEmpty(keyword) Then ElseIf String.IsNullOrEmpty(keyword) Then
MessageBox.Show("Keyword field should not be empty.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Warning) MessageBox.Show("Keyword field should not be empty.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Warning)
@@ -137,6 +93,42 @@ Public Class Utilities
End Sub End Sub
''' <summary>
''' Saves Reddit posts contained in a JArray to a CSV file.
''' </summary>
''' <param name="posts">A JArray containing the Reddit posts to be saved.</param>
''' <remarks>
''' This function displays a SaveFileDialog to allow the user to specify the file name and location.
''' It then iterates through the JArray to write each post's details (totalPosts, title, subreddit, author, score) into the selected CSV file.
''' </remarks>
Public Shared Sub SavePostsToCSV(posts As JArray)
Dim saveFileDialog As New SaveFileDialog With {
.Filter = "CSV files (*.csv)|*.csv",
.Title = "Save posts to CSV"
}
If saveFileDialog.ShowDialog() = DialogResult.OK Then
Dim fileName As String = saveFileDialog.FileName
Using csvWriter As New StreamWriter(fileName)
''' <summary>
''' Write the header.
''' <summary>
csvWriter.WriteLine("Index,Author,ID,Subreddit,Visibility,Thumbnail,NSFW,Gilded,Upvotes,Upvote Ratio,Downvotes,Award,Top Award,Is cross-postable?,Score,Category,Text,Domain,Permalink,Created At,Approved At,Approved By")
Dim postCount As Integer = 0
For Each post In posts
postCount += 1
csvWriter.WriteLine($"{postCount},{post("data")("author")},{post("data")("id")},{post("data")("subreddit_name_prefixed")},{post("data")("subreddit_type")},{post("data")("thumbnail")},{post("data")("over_18")},{post("data")("gilded")},{post("data")("ups")},{post("data")("upvote_ratio")},{post("data")("downs")},{post("data")("total_awards_received")},{post("data")("top_awarded_type")},{post("data")("is_crosspostable")},{post("data")("score")},{post("data")("category")},{post("data")("selftext")},{post("data")("domain")},{post("data")("permalink")},{post("data")("created")},{post("data")("approved_at_utc")},{post("data")("approved_by")}")
Next
End Using
MessageBox.Show($"Posts saved to {fileName}", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
''' <summary> ''' <summary>
''' Shows the license notice in a messagebox. ''' Shows the license notice in a messagebox.
''' </summary> ''' </summary>

BIN
images/2023-08-30_03-11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
images/2023-08-30_03-12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -7,7 +7,7 @@ packages = ["rpst"]
[project] [project]
name = "reddit-post-scraping-tool" name = "reddit-post-scraping-tool"
version = "1.7.0.1" version = "1.8.0.0"
description = "Given a subreddit name and a keyword, RPST returns all top (by default) posts that contain the specified keyword." description = "Given a subreddit name and a keyword, RPST returns all top (by default) posts that contain the specified keyword."
readme = "README.md" readme = "README.md"
requires-python = ">=3.8" requires-python = ">=3.8"

View File

@@ -14,20 +14,20 @@ def run():
parser = create_parser() parser = create_parser()
args = parser.parse_args() args = parser.parse_args()
log = set_loglevel(args=args) log = set_loglevel(debug_mode=args.debug)
# Record the start time # Record the start time
start_time = datetime.now() start_time = datetime.now()
try: try:
# Check for updates # Check for updates
check_updates(version_tag="1.7.0.1") check_updates(version_tag="1.8.0.0")
# Get posts with the provided/parsed arguments # Get posts with the provided/parsed arguments
get_posts(args=args) get_posts(args=args)
except KeyboardInterrupt: except KeyboardInterrupt:
log.warning("User interruption detected.") log.warning("User interruption detected ([yellow]Ctrl+C[/]).")
except Exception as e: except Exception as e:
log.error(f"An error occurred: {e}") log.error(f"An error occurred: [red]{e}[/]")
finally: finally:
log.info(f"Finished in {datetime.now() - start_time} seconds.") log.info(f"Finished in {datetime.now() - start_time} seconds.")

View File

@@ -3,8 +3,8 @@ from datetime import datetime
import requests import requests
from glyphoji import glyph from glyphoji import glyph
from rich import print
from rich.tree import Tree from rich.tree import Tree
from rich import print as xprint
from .utils import convert_timestamp_to_datetime, write_post_data from .utils import convert_timestamp_to_datetime, write_post_data
@@ -128,4 +128,4 @@ def get_posts(args: argparse):
f"{glyph.check_mark_button} Keyword ('{keyword}') was found in " f"{glyph.check_mark_button} Keyword ('{keyword}') was found in "
f"{found_posts}/{len(response['data']['children'])} {listing} posts from r/{subreddit}." f"{found_posts}/{len(response['data']['children'])} {listing} posts from r/{subreddit}."
) )
xprint(main_tree) print(main_tree)

View File

@@ -7,8 +7,9 @@ from datetime import datetime
import requests import requests
from glyphoji import glyph from glyphoji import glyph
from rich import print
from rich.tree import Tree from rich.tree import Tree
from rich import print as xprint
from rich.markdown import Markdown from rich.markdown import Markdown
from rich.logging import RichHandler from rich.logging import RichHandler
@@ -84,7 +85,7 @@ def create_parser():
parser.add_argument( parser.add_argument(
"-d", "-d",
"--debug", "--debug",
help="run rpst in debug mode (show network logs)", help="run rpst in debug mode",
action="store_true", action="store_true",
) )
@@ -110,50 +111,30 @@ def check_updates(version_tag: str):
raw_release_notes = response["body"] raw_release_notes = response["body"]
# Log an info message about the new release. # Log an info message about the new release.
xprint( print(
f"{glyph.up_arrow} A new release of RPST is available ({response['tag_name']}). " f"{glyph.up_arrow} A new release of RPST is available ({response['tag_name']}). "
f"Run 'pip install --upgrade reddit-post-scraping-tool' to get the updates." f"Run 'pip install --upgrade reddit-post-scraping-tool' to get the updates."
) )
# Print the release notes. # Print the release notes.
xprint(Markdown(raw_release_notes)) print(Markdown(raw_release_notes))
def set_loglevel(args: argparse) -> logging.getLogger: def set_loglevel(debug_mode: bool) -> logging.getLogger:
""" """
Configures the logging level based on the provided arguments. Configure and return a logging object with the specified log level.
If `args.debug` is True, the logging level is set to "NOTSET," allowing all log messages to be displayed. :param debug_mode: If True, the log level is set to "NOTSET". Otherwise, it is set to "INFO".
Otherwise, the logging level is set to "INFO," and only informational and higher-severity messages are displayed. :return: A logging object configured with the specified log level.
The function also configures a RichHandler for formatting the log messages,
including a specific time format and hiding the log level.
:param args: A namespace object from argparse containing the debugging option (args.debug).
:return: A logger object associated with the name "rich."
""" """
if args.debug: logging.basicConfig(
logging.basicConfig( level="NOTSET" if debug_mode else "INFO",
level="NOTSET", format="%(message)s",
format="%(message)s", handlers=[
handlers=[ RichHandler(markup=True, log_time_format="[%I:%M:%S %p]", show_level=False)
RichHandler( ],
markup=True, log_time_format="[%H:%M:%S%p]", show_level=False )
) return logging.getLogger("RPST")
],
)
else:
logging.basicConfig(
level="INFO",
format="%(message)s",
handlers=[
RichHandler(
markup=True, log_time_format="[%H:%M:%S%p]", show_level=False
)
],
)
return logging.getLogger("rich")
def write_post_data(post_data: dict, filename: str, args, tree_branch: Tree): def write_post_data(post_data: dict, filename: str, args, tree_branch: Tree):