37 Commits

Author SHA1 Message Date
Richard Mwewa
2d79877440 Update to v1.2.0.1 2023-02-19 05:36:28 +02:00
Richard Mwewa
d9d0e58759 Update README.md 2023-02-19 05:32:46 +02:00
Richard Mwewa
3609b6ec87 Update setup.py 2023-02-19 04:14:26 +02:00
Richard Mwewa
0d0581cc25 Update LICENSE 2023-02-19 04:09:56 +02:00
Richard Mwewa
18504e7144 Update setup.py 2023-02-19 04:07:08 +02:00
Richard Mwewa
4e88ba0374 Update README.md 2023-02-14 11:33:09 +02:00
Richard Mwewa
0d6df7e6b5 Create feature_request.md 2023-02-12 03:32:46 +02:00
Richard Mwewa
df05878051 Create config.yml 2023-02-12 03:32:01 +02:00
Richard Mwewa
e12fa0f342 Update README.md 2023-02-12 03:30:25 +02:00
Richard Mwewa
e35fb6ee32 Update README.md 2023-02-12 03:29:58 +02:00
Richard Mwewa
2747082ab6 Update README.md 2023-02-12 03:21:30 +02:00
Richard Mwewa
282e59dd30 Update README.md 2023-02-12 03:20:30 +02:00
Richard Mwewa
6a5ba5a800 Delete rpst.ico 2023-02-12 03:15:19 +02:00
Richard Mwewa
ab5371e2c4 Update README.md 2023-02-12 03:06:04 +02:00
Richard Mwewa
194c53d795 Add files via upload 2023-02-12 03:01:48 +02:00
Richard Mwewa
d0dbff8f31 Update README.md 2023-02-11 06:49:12 +02:00
Richard Mwewa
31a0448d74 Update setup.py 2023-02-11 06:48:12 +02:00
Richard Mwewa
19029b61f1 Update README.md 2023-02-11 06:46:24 +02:00
Richard Mwewa
c4c7999fe0 Update README.md 2023-02-11 06:45:32 +02:00
Richard Mwewa
85eb59d87d Update dependabot.yml 2023-02-11 05:44:21 +02:00
Richard Mwewa
1275c1a780 Create dependabot.yml 2023-02-11 05:43:07 +02:00
Richard Mwewa
5840072639 Update dependabot.yml 2023-02-11 05:41:03 +02:00
Richard Mwewa
20689887bf Update dependabot.yml 2023-02-11 05:38:58 +02:00
Richard Mwewa
8ddbb1eafc Update dependabot.yml 2023-02-11 05:36:26 +02:00
Richard Mwewa
0ffed7cae6 Update dependabot.yml 2023-02-11 05:31:46 +02:00
Richard Mwewa
1ca3f3666c Update dependabot.yml 2023-02-11 05:30:48 +02:00
Richard Mwewa
fe8b08d9a1 Update dependabot.yml 2023-02-11 05:28:41 +02:00
Richard Mwewa
2c5749317c Create dependabot.yml 2023-02-11 05:27:52 +02:00
Richard Mwewa
b39f5ad57a Create python-publish.yml 2023-02-11 05:16:17 +02:00
Richard Mwewa
91abee7fa1 Create codeql.yml 2023-02-11 05:05:51 +02:00
Richard Mwewa
4a06a29963 Update README.md 2023-02-10 20:02:52 +02:00
Richard Mwewa
c5885bb41b Add files via upload 2023-02-10 19:29:02 +02:00
Richard Mwewa
69a6968459 Add files via upload 2023-02-10 19:16:01 +02:00
Richard Mwewa
6cc8002610 Delete Dockerfile 2023-02-10 19:15:26 +02:00
Richard Mwewa
a62154ebbf Delete requirements.txt 2023-02-10 19:15:06 +02:00
Richard Mwewa
fd4e2702ba Delete reddit-post-scraping-tool.py 2023-02-10 19:14:55 +02:00
Richard Mwewa
e025b61445 Update README.md 2023-02-10 18:32:14 +02:00
38 changed files with 4984 additions and 134 deletions

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Richard Mwewa (Telegram)
url: https://t.me/rly0nheart/
about: Please ask and answer questions here.
- name: Richard Mwewa (Twitter)
url: https://m.twitter.com/rly0nheart/
about: Please report security vulnerabilities or bugs here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

18
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "nuget"
schedule:
interval: "daily"
directory: "Reddit Post Scraping Tool"
ignore:
- dependency-name: "Newtonsoft.Json"
- package-ecosystem: "pip"
schedule:
interval: "daily"
directory: "/"

76
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,76 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '26 9 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

39
.github/workflows/python-publish.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Upload Python Package
on:
release:
types: [published]
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

View File

@@ -1,11 +1,11 @@
FROM python:latest
ADD requirements.txt /
ADD reddit-post-scraping-tool.py /
COPY ./reddit-post-scraping-tool.py ./
RUN pip install -r requirements.txt
ENTRYPOINT ["python", "./reddit-post-scraping-tool.py"]
# syntax=docker/dockerfile:1
FROM python:latest
WORKDIR /app
COPY . .
RUN pip install --upgrade pip && pip install build && python -m build && pip install dist/*.whl
ENTRYPOINT ["reddit_post_scraping_tool"]

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2022 Richard Mwewa
Copyright (c) 2023 Richard Mwewa
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,53 +1,30 @@
![Screenshot 2022-10-15 231821](https://user-images.githubusercontent.com/74001397/197303749-45032662-810d-4577-b546-13b93d4986d5.png)
# Reddit Post Scraping Tool
Given a subreddit name and a keyword, this script will return all posts from a specified listing (default is 'top') that contain the provided keyword.
# Installation
**1. Clone the repo**
```
git clone https://github.com/rly0nheart/reddit-post-scraping-tool.git
```
**2. Move to reddit-post-scraping-tool directory**
```
cd reddit-post-scraping-tool
```
**3. Install dependencies**
```
pip3 install -r requirements.txt
```
# Windows GUI
## Prerequisites
* **.NET 6.0 or later**
### 1. Download the GUI from the releases page
You can download the latest release of the gui from [here](https://github.com/bellingcat/octosuite/releases/latest)
[![Upload Python Package](https://github.com/rly0nheart/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/rly0nheart/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)
![Screenshot 2023-02-10 195818](https://user-images.githubusercontent.com/74001397/218163494-245f6676-1fb3-4680-a6b5-bd15fb1dea5e.png)
![Screenshot_20230210_193329](https://user-images.githubusercontent.com/74001397/218158084-9295abb7-df33-4f86-8df8-e109cac7cde6.png)
### 2. Extract the downloaded `.zip`
![Screenshot_20230210_181651](https://user-images.githubusercontent.com/74001397/218141653-991a91cd-93d5-4640-b2f2-37d29e6a9c62.png)
# Features (GUI)
- [x] Auto dark mode from 6pm - 6am
- [x] Saves results to a JSON
- [ ] Other features coming soon...
### 3. Run the binary
# TODO (GUI)
- [ ] Make it a stand alone executable
- [ ] Add manual dark mode option, that will be remembered in all sessions
- [ ] Make it save results to a CSV file
Once extracted, you can then run the program by double clicking on a binary named `RPST.exe`
![Screenshot_20230210_181933](https://user-images.githubusercontent.com/74001397/218142422-70f19a0a-db39-42ee-8ad4-22fe380e249b.png)
# Wiki
[Refer to the Wiki](https://github.com/rly0nheart/reddit-post-scraping-tool/wiki) for installation instructions, in addition to all other documentation.
![Screenshot_20230210_182210](https://user-images.githubusercontent.com/74001397/218142782-0a9ca4fb-7609-4855-a96b-c58885161166.png)
# Note
> This is one of the projects I am working on, while learning Visual Basic, so the implementation/code may be messed up. If that's the case, please feel free to open a pull request using the available templates. Otherwise, enjoy!
# Donations
If you like `Reddit Post Scraping Tool` and would like to show support, you can Buy A Coffee for the developer using the button below
# Usage
<a href="https://www.buymeacoffee.com/189381184" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
```
python3 reddit-post-scraping-tool.py --keyword [keyword] --subreddit [subreddit name (without 'r/')]
```
## Optional arguments
| Option | Argument | Choices | Usage |
| -------------|:-----------:|-----------:|:---------:|
| -l/--listing | LISTING | [controversial, hot, best, new, rising] | listing: controversial, hot, best, new, rising (default: top) |
| -c/--limit | NUMBER | 1-100 | results limit (default: 10)|
| -t/--timeframe| TIMEFRAME | [hour, day, week, month, year] | timeframe: hour, day, week, month, year (default: all) |
Your support will be much appreciated😊

View File

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33213.308
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Reddit Post Scraping Tool", "Reddit Post Scraping Tool\Reddit Post Scraping Tool.vbproj", "{46C2541E-6F65-461A-A479-F65D445C36EA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{46C2541E-6F65-461A-A479-F65D445C36EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46C2541E-6F65-461A-A479-F65D445C36EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46C2541E-6F65-461A-A479-F65D445C36EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46C2541E-6F65-461A-A479-F65D445C36EA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {11BEF8E8-2590-4D78-9D49-C518F26F3D47}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,59 @@
Imports System.IO
Imports System.Net.Http
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class ApiHandler
Public logfile As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "RedditPostScrapingTool", "logs", $"debug.log")
Public headers As String = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15"
Public UpdatesEndpoint As String = "https://api.github.com/repos/bellingcat/reddit-post-scraping-tool/releases/latest"
Public Function ScrapeReddit(subreddit, listing, limit, timeframe) As JObject
Dim ApiEndpoint As String = $"https://reddit.com/r/{subreddit}/{listing}.json?limit={limit}&t={timeframe}').json()"
Try
Dim httpClient As New HttpClient()
httpClient.DefaultRequestHeaders.Add("User-Agent", headers)
Dim response As HttpResponseMessage = httpClient.GetAsync(ApiEndpoint).Result
If response.IsSuccessStatusCode Then
Dim json As String = response.Content.ReadAsStringAsync().Result
Dim data As JObject = JsonConvert.DeserializeObject(Of JObject)(json)
Return data
Else
' handle the case when the response status is not successful
' return an empty JObject or throw an exception
Return New JObject()
MessageBox.Show(response.ReasonPhrase, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Catch ex As Exception
' handle the exception
' return an empty JObject or throw an exception
Return New JObject()
My.Computer.FileSystem.WriteAllText(logfile, $"{DateTime.Now}: {ex}{Environment.NewLine}", True)
MessageBox.Show($"{ex.Message}. Please see the debug log '{logfile}' for more information.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return New JObject()
End Function
' Gets remote version information from the repository release page
Public Function CheckUpdates() As JObject
Try
Dim httpClient As New HttpClient()
httpClient.DefaultRequestHeaders.Add("User-Agent", headers)
Dim response As HttpResponseMessage = httpClient.GetAsync(UpdatesEndpoint).Result
If response.IsSuccessStatusCode Then
Dim json As String = response.Content.ReadAsStringAsync().Result
Dim data As JObject = JsonConvert.DeserializeObject(Of JObject)(json)
Return data
Else
'Return New JObject()
MessageBox.Show(response.ReasonPhrase, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Catch ex As Exception
'Return New JObject()
My.Computer.FileSystem.WriteAllText(logfile, $"{DateTime.Now}: {ex}{Environment.NewLine}", True)
MessageBox.Show($"{ex.Message}. Please see the debug log '{logfile}' for more information.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return New JObject()
End Function
End Class

View File

@@ -0,0 +1,29 @@
Imports Microsoft.VisualBasic.ApplicationServices
Namespace My
' The following events are available for MyApplication:
' Startup: Raised when the application starts, before the startup form is created.
' Shutdown: Raised after all application forms are closed. This event is not raised if the application terminates abnormally.
' UnhandledException: Raised if the application encounters an unhandled exception.
' StartupNextInstance: Raised when launching a single-instance application and the application is already active.
' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
' **NEW** ApplyApplicationDefaults: Raised when the application queries default values to be set for the application.
' Example:
' Private Sub MyApplication_ApplyApplicationDefaults(sender As Object, e As ApplyApplicationDefaultsEventArgs) Handles Me.ApplyApplicationDefaults
'
' ' Setting the application-wide default Font:
' e.Font = New Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular)
'
' ' Setting the HighDpiMode for the Application:
' e.HighDpiMode = HighDpiMode.PerMonitorV2
'
' ' If a splash dialog is used, this sets the minimum display time:
' e.MinimumSplashScreenDisplayTime = 4000
' End Sub
Partial Friend Class MyApplication
End Class
End Namespace

View File

@@ -0,0 +1,87 @@
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Class DeveloperForm
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DeveloperForm))
Me.AboutMeLinkLabel = New System.Windows.Forms.LinkLabel()
Me.BuyMeACoffeeLinkLabel = New System.Windows.Forms.LinkLabel()
Me.GreetingLabel = New System.Windows.Forms.Label()
Me.SuspendLayout()
'
'AboutMeLinkLabel
'
Me.AboutMeLinkLabel.AutoSize = True
Me.AboutMeLinkLabel.BackColor = System.Drawing.Color.White
Me.AboutMeLinkLabel.Location = New System.Drawing.Point(33, 426)
Me.AboutMeLinkLabel.Name = "AboutMeLinkLabel"
Me.AboutMeLinkLabel.Size = New System.Drawing.Size(60, 15)
Me.AboutMeLinkLabel.TabIndex = 0
Me.AboutMeLinkLabel.TabStop = True
Me.AboutMeLinkLabel.Text = "About.me"
'
'BuyMeACoffeeLinkLabel
'
Me.BuyMeACoffeeLinkLabel.AutoSize = True
Me.BuyMeACoffeeLinkLabel.Location = New System.Drawing.Point(33, 451)
Me.BuyMeACoffeeLinkLabel.Name = "BuyMeACoffeeLinkLabel"
Me.BuyMeACoffeeLinkLabel.Size = New System.Drawing.Size(96, 15)
Me.BuyMeACoffeeLinkLabel.TabIndex = 1
Me.BuyMeACoffeeLinkLabel.TabStop = True
Me.BuyMeACoffeeLinkLabel.Text = "Buy Me A Coffee"
'
'GreetingLabel
'
Me.GreetingLabel.AutoSize = True
Me.GreetingLabel.Font = New System.Drawing.Font("Verdana", 27.75!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point)
Me.GreetingLabel.Location = New System.Drawing.Point(62, 22)
Me.GreetingLabel.Name = "GreetingLabel"
Me.GreetingLabel.Size = New System.Drawing.Size(382, 45)
Me.GreetingLabel.TabIndex = 3
Me.GreetingLabel.Text = "Hello, I'm Ritchie"
'
'DeveloperForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 15.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.BackgroundImage = CType(resources.GetObject("$this.BackgroundImage"), System.Drawing.Image)
Me.ClientSize = New System.Drawing.Size(510, 510)
Me.Controls.Add(Me.BuyMeACoffeeLinkLabel)
Me.Controls.Add(Me.AboutMeLinkLabel)
Me.Controls.Add(Me.GreetingLabel)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.MaximizeBox = False
Me.Name = "DeveloperForm"
Me.ShowIcon = False
Me.ShowInTaskbar = False
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
Me.Text = "Developer"
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents AboutMeLinkLabel As LinkLabel
Friend WithEvents BuyMeACoffeeLinkLabel As LinkLabel
Friend WithEvents PictureBox1 As PictureBox
Friend WithEvents GreetingLabel As Label
End Class

View File

@@ -0,0 +1,829 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
/9j/4AAQSkZJRgABAQEAAAAAAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAIQAABtbnRyUkdCIFhZ
WiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAA
AHRyWFlaAAABZAAAABRnWFlaAAABeAAAABRiWFlaAAABjAAAABRyVFJDAAABoAAAAChnVFJDAAABoAAA
AChiVFJDAAABoAAAACh3dHB0AAAByAAAABRjcHJ0AAAB3AAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAA
AFgAAAAcAHMAUgBHAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAA
AAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z3BhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAA
E9AAAApbAAAAAAAAAABYWVogAAAAAAAA9tYAAQAAAADTLW1sdWMAAAAAAAAAAQAAAAxlblVTAAAAIAAA
ABwARwBvAG8AZwBsAGUAIABJAG4AYwAuACAAMgAwADEANv/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAgAC
AAMBIgACEQEDEQH/xAAfAAEAAQQDAQEBAAAAAAAAAAAABwQFBggDCQoCCwH/xABFEAABAwMCBAQDBQcC
BAUFAQEBAgMEAAURBiEHEjFBCBNRYRQicQkVMoGRI0KhscHR8FJiChYk4RczcoLxJUOywtI0kv/EABwB
AQACAwEBAQAAAAAAAAAAAAAFBgMEBwIBCP/EAD8RAAEEAQMCBAMFBwEIAgMAAAEAAgMRBBIhMQVBBhNR
YSJxgQcykaHBFCNCUrHR8BUWJENicpLh8TOCNGOy/9oADAMBAAIRAxEAPwD1YUpSrQqulKUoiUpSiJSl
KIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpS
iJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUo
iUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKI
lKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJ
SlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiU
pSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlK
UoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSl
KIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpS
iJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUo
iUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKI
lKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJ
SlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiU
pSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlK
UoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSl
KIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpS
iJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUo
iUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKIlKUoiUpSiJSlKI
lKUoiUpSiJSlKIlKUoiUpSiJSlW67Xi02GA/db5c7fZ7ZFCDIuFzmR4EJjzHEtNh2TKcaZQXXVoabSpY
Ljq0NoClqSk/HOa0FznBrWgkucQAAOSSaAA7kr01rnuaxjXPe4hrWNBc5ziaDWtAJJJ2AAJJ4VxpWg3F
fx46G0uXbdw9jtanuKQgm9XVuXDsLWfgH8M25Kol5uPmMuToTwkLsPwktlmVHVdYiyFaY6u+0G4oy1ST
br5CsrD6HG/hbVZrYENpWtxZ8iVcI9wuTDiErSw26meXUoabUF+cXX3K3meLOj4jnNEz8lzdj+zNa9l+
gkc9jXciywuG/Jo1d+mfZ54l6lGyX9mjwo3kV+2ufHIWmqd5LI5JGk7gNkDHWDYAIJ7xwCTgDJOwA6k+
lYhdeIOgrFLVAvmt9IWacgKK4V11LZrdLSEuuMqKo0yay8kJeZdaUSgAOtONn50KA83GrvFRr/UrK4V3
1lqO6w8nEa6X+63FkJ8xDyUpZmSpDPKHW0OABOA4htey2kkRYri5JUSoyDkkk4cx1OegVjuagZvHsX/A
w216yz79v4WsAHfh7uPdW7F+yHILQ7M6mbIBDMfG4ut9cshsb8eWCvVRbdXaUvSGHLPqfT12bleb8M5b
b1bZyJHklxL3kKiyXUveUWnQ75ZV5ZacC8FCsX5t1t5RS04h1QBUUtrStQSCASQkk4BIBOMZI9a8ly+L
0lJKfPJ9+Y9iR6/19KpTxdkZKfNUem4Vg7j9O/cY2rG3x+NteCw776cmvT1jcR3Pf9VmP2OyOvy+rPYO
wkw2uNkju3JZYANcCyL2Gw9cCkLQQFpUgkBQCklJKTkBQyBkEggEbbGvmvJdG4quA+Y5LXlK8pClJxsS
Mb5AwCoYGwJO22KmzR/iz4maQMQaf4galgswm1NRYJur8y0tNqYeYS2bPPVLtDjbLch1TDUiE61HkFMt
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
</value>
</data>
</root>

View File

@@ -0,0 +1,17 @@
Public Class DeveloperForm
Private Sub DeveloperForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
GreetingLabel.BackColor = Color.Transparent
AboutMeLinkLabel.BackColor = Color.Transparent
BuyMeACoffeeLinkLabel.BackColor = Color.Transparent
End Sub
Private Sub AboutMeLinkLabel_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles AboutMeLinkLabel.LinkClicked
' I couldn't find a proper way to open a url
' Process.Start() did not work
Shell("cmd /c start https://about.me/rly0nheart")
End Sub
Private Sub BuyMeACoffeeLinkLabel_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles BuyMeACoffeeLinkLabel.LinkClicked
Shell("cmd /c start https://buymeacoffee.com/189381184")
End Sub
End Class

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Richard Mwewa
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,39 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
'NOTE: This file is auto-generated; do not modify it directly. To make changes,
' or if you encounter build errors in this file, go to the Project Designer
' (go to Project Properties or double-click the My Project node in
' Solution Explorer), and make changes on the Application tab.
'
Partial Friend Class MyApplication
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Public Sub New()
MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows)
Me.IsSingleInstance = false
Me.EnableVisualStyles = true
Me.SaveMySettingsOnExit = true
Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses
Me.HighDpiMode = HighDpiMode.DpiUnaware
End Sub
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Protected Overrides Sub OnCreateMainForm()
Me.MainForm = Global.Reddit_Post_Scraping_Tool.StartForm
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-16"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>true</MySubMain>
<MainForm>StartForm</MainForm>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -0,0 +1,63 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'This class was auto-generated by the StronglyTypedResourceBuilder
'class via a tool like ResGen or Visual Studio.
'To add or remove a member, edit your .ResX file then rerun ResGen
'with the /str option, or rebuild your VS project.
'''<summary>
''' A strongly-typed resource class, for looking up localized strings, etc.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RPST.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Overrides the current thread's CurrentUICulture property for all
''' resource lookups using this strongly typed resource class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
End Module
End Namespace

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, 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="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,56 @@
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class PostsForm
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.DataGridViewPosts = New System.Windows.Forms.DataGridView()
CType(Me.DataGridViewPosts, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'DataGridViewPosts
'
Me.DataGridViewPosts.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
Me.DataGridViewPosts.Dock = System.Windows.Forms.DockStyle.Fill
Me.DataGridViewPosts.Location = New System.Drawing.Point(0, 0)
Me.DataGridViewPosts.Name = "DataGridViewPosts"
Me.DataGridViewPosts.ReadOnly = True
Me.DataGridViewPosts.RowTemplate.Height = 25
Me.DataGridViewPosts.Size = New System.Drawing.Size(800, 450)
Me.DataGridViewPosts.TabIndex = 3
'
'PostsForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 15.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(800, 450)
Me.Controls.Add(Me.DataGridViewPosts)
Me.Name = "PostsForm"
Me.ShowIcon = False
Me.ShowInTaskbar = False
Me.Text = "PostsForm"
CType(Me.DataGridViewPosts, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Friend WithEvents DataGridViewPosts As DataGridView
End Class

View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,3 @@
Public Class PostsForm
End Class

View File

@@ -0,0 +1,29 @@
# Reddit Post Scraping Tool
Given a subreddit name and a keyword, this script will return all posts from a specified listing (default is 'top') that contain the provided keyword.
[![Upload Python Package](https://github.com/rly0nheart/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/rly0nheart/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)
![Screenshot 2023-02-10 195818](https://user-images.githubusercontent.com/74001397/218163494-245f6676-1fb3-4680-a6b5-bd15fb1dea5e.png)
![Screenshot_20230210_193329](https://user-images.githubusercontent.com/74001397/218158084-9295abb7-df33-4f86-8df8-e109cac7cde6.png)
# Features (GUI)
- [x] Auto dark mode from 6pm - 6am
- [x] Saves results to a JSON
- [ ] Other features coming soon...
# TODO (GUI)
- [ ] Make it a stand alone executable
- [ ] Add manual dark mode option, that will be remembered in all sessions
# Wiki
[Refer to the Wiki](https://github.com/rly0nheart/reddit-post-scraping-tool/wiki) for installation instructions, in addition to all other documentation.
# Note
> This is one of the projects I am working on, while learning Visual Basic, so the implementation/code may be messed up. If that's the case, please feel free to open a pull request using the available templates. Otherwise, enjoy!
# Donations
If you like `Reddit Post Scraping Tool` and would like to show support, you can Buy A Coffee for the developer using the button below
<a href="https://www.buymeacoffee.com/189381184" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
Your support will be much appreciated😊

View File

@@ -0,0 +1,76 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<StartupObject>Reddit_Post_Scraping_Tool.My.MyApplication</StartupObject>
<UseWindowsForms>true</UseWindowsForms>
<MyType>WindowsForms</MyType>
<ApplicationIcon>icon.ico</ApplicationIcon>
<Company>Richard Mwewa</Company>
<Description>Given a subreddit name and a keyword, this program returns all top (by default) posts that contain the specified keyword. </Description>
<Copyright>Copyright (c) 2023 Richard Mwewa. All rights reserved.</Copyright>
<PackageProjectUrl>https://github.com/bellingcat/reddit-post-scraping-tool</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/bellingcat/reddit-post-scraping-tool</RepositoryUrl>
<AssemblyVersion>1.2.0.1</AssemblyVersion>
<FileVersion>1.2.0.1</FileVersion>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<Version>1.2.0</Version>
<PackageTags>reddit;scraper;reddit-scraper;osint</PackageTags>
<PackageReleaseNotes>Deploys to new PyPI
Minor improvements</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<Content Include="icon.ico" />
</ItemGroup>
<ItemGroup>
<Import Include="System.Data" />
<Import Include="System.Drawing" />
<Import Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>
<ItemGroup>
<Compile Update="My Project\Application.Designer.vb">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Update="My Project\Resources.Designer.vb">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="My Project\Resources.resx">
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="LICENSE">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Update="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Update="README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Update="DeveloperForm.vb">
<SubType>Form</SubType>
</Compile>
<Compile Update="PostsForm.vb">
<SubType>Form</SubType>
</Compile>
<Compile Update="StartForm.vb">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,321 @@
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Class StartForm
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(StartForm))
Me.KeywordTextBox = New System.Windows.Forms.TextBox()
Me.SubredditTextBox = New System.Windows.Forms.TextBox()
Me.Button1 = New System.Windows.Forms.Button()
Me.TimeframeComboBox = New System.Windows.Forms.ComboBox()
Me.ListingComboBox = New System.Windows.Forms.ComboBox()
Me.Label1 = New System.Windows.Forms.Label()
Me.Label2 = New System.Windows.Forms.Label()
Me.Label3 = New System.Windows.Forms.Label()
Me.Label4 = New System.Windows.Forms.Label()
Me.Label5 = New System.Windows.Forms.Label()
Me.ContextMenuStrip1 = New System.Windows.Forms.ContextMenuStrip(Me.components)
Me.SaveResultsJSONToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.JSONToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.CSVToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.FileMenuStrip = New System.Windows.Forms.MenuStrip()
Me.ToolsToolStripMenuTools = New System.Windows.Forms.ToolStripMenuItem()
Me.AboutToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.LicensceToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.DeveloperToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.ChekUpdatesToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.ToolStripSeparator2 = New System.Windows.Forms.ToolStripSeparator()
Me.QuitToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.LimitNumericUpDown = New System.Windows.Forms.NumericUpDown()
Me.ContextMenuStrip1.SuspendLayout()
Me.FileMenuStrip.SuspendLayout()
CType(Me.LimitNumericUpDown, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'KeywordTextBox
'
Me.KeywordTextBox.BackColor = System.Drawing.SystemColors.Window
Me.KeywordTextBox.ForeColor = System.Drawing.SystemColors.WindowText
Me.KeywordTextBox.Location = New System.Drawing.Point(89, 60)
Me.KeywordTextBox.Name = "KeywordTextBox"
Me.KeywordTextBox.PlaceholderText = "Keyword"
Me.KeywordTextBox.Size = New System.Drawing.Size(100, 23)
Me.KeywordTextBox.TabIndex = 0
'
'SubredditTextBox
'
Me.SubredditTextBox.Location = New System.Drawing.Point(89, 92)
Me.SubredditTextBox.Name = "SubredditTextBox"
Me.SubredditTextBox.PlaceholderText = "Subreddit"
Me.SubredditTextBox.Size = New System.Drawing.Size(100, 23)
Me.SubredditTextBox.TabIndex = 4
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(257, 191)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(76, 28)
Me.Button1.TabIndex = 6
Me.Button1.Text = "Scrape"
Me.Button1.UseVisualStyleBackColor = True
'
'TimeframeComboBox
'
Me.TimeframeComboBox.FormattingEnabled = True
Me.TimeframeComboBox.Items.AddRange(New Object() {"Hour", "Day", "Week", "Month", "Year"})
Me.TimeframeComboBox.Location = New System.Drawing.Point(89, 191)
Me.TimeframeComboBox.Name = "TimeframeComboBox"
Me.TimeframeComboBox.Size = New System.Drawing.Size(100, 23)
Me.TimeframeComboBox.TabIndex = 8
Me.TimeframeComboBox.Text = "All"
'
'ListingComboBox
'
Me.ListingComboBox.FormattingEnabled = True
Me.ListingComboBox.Items.AddRange(New Object() {"Controversial", "Hot", "Best", "New", "Rising"})
Me.ListingComboBox.Location = New System.Drawing.Point(89, 157)
Me.ListingComboBox.Name = "ListingComboBox"
Me.ListingComboBox.Size = New System.Drawing.Size(100, 23)
Me.ListingComboBox.TabIndex = 9
Me.ListingComboBox.Text = "Top"
'
'Label1
'
Me.Label1.AutoEllipsis = True
Me.Label1.Font = New System.Drawing.Font("Segoe UI Semibold", 9.0!, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point)
Me.Label1.ForeColor = System.Drawing.Color.Black
Me.Label1.Location = New System.Drawing.Point(12, 60)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(56, 23)
Me.Label1.TabIndex = 10
Me.Label1.Text = "Keyword"
'
'Label2
'
Me.Label2.AutoEllipsis = True
Me.Label2.Font = New System.Drawing.Font("Segoe UI Semibold", 9.0!, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point)
Me.Label2.ForeColor = System.Drawing.Color.Black
Me.Label2.Location = New System.Drawing.Point(12, 92)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(63, 23)
Me.Label2.TabIndex = 11
Me.Label2.Text = "Subreddit"
'
'Label3
'
Me.Label3.AutoEllipsis = True
Me.Label3.Font = New System.Drawing.Font("Segoe UI Semibold", 9.0!, CType((System.Drawing.FontStyle.Bold Or System.Drawing.FontStyle.Underline), System.Drawing.FontStyle), System.Drawing.GraphicsUnit.Point)
Me.Label3.ForeColor = System.Drawing.Color.Black
Me.Label3.Location = New System.Drawing.Point(12, 125)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(56, 23)
Me.Label3.TabIndex = 12
Me.Label3.Text = "Limit"
'
'Label4
'
Me.Label4.AutoEllipsis = True
Me.Label4.Font = New System.Drawing.Font("Segoe UI Semibold", 9.0!, CType((System.Drawing.FontStyle.Bold Or System.Drawing.FontStyle.Underline), System.Drawing.FontStyle), System.Drawing.GraphicsUnit.Point)
Me.Label4.ForeColor = System.Drawing.Color.Black
Me.Label4.Location = New System.Drawing.Point(12, 157)
Me.Label4.Name = "Label4"
Me.Label4.Size = New System.Drawing.Size(56, 23)
Me.Label4.TabIndex = 13
Me.Label4.Text = "Listing"
'
'Label5
'
Me.Label5.AutoEllipsis = True
Me.Label5.Font = New System.Drawing.Font("Segoe UI Semibold", 9.0!, CType((System.Drawing.FontStyle.Bold Or System.Drawing.FontStyle.Underline), System.Drawing.FontStyle), System.Drawing.GraphicsUnit.Point)
Me.Label5.ForeColor = System.Drawing.Color.Black
Me.Label5.Location = New System.Drawing.Point(12, 191)
Me.Label5.Name = "Label5"
Me.Label5.Size = New System.Drawing.Size(71, 23)
Me.Label5.TabIndex = 14
Me.Label5.Text = "Timeframe"
'
'ContextMenuStrip1
'
Me.ContextMenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.SaveResultsJSONToolStripMenuItem})
Me.ContextMenuStrip1.Name = "ContextMenuStrip1"
Me.ContextMenuStrip1.Size = New System.Drawing.Size(144, 26)
'
'SaveResultsJSONToolStripMenuItem
'
Me.SaveResultsJSONToolStripMenuItem.AutoToolTip = True
Me.SaveResultsJSONToolStripMenuItem.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.JSONToolStripMenuItem, Me.CSVToolStripMenuItem})
Me.SaveResultsJSONToolStripMenuItem.Image = CType(resources.GetObject("SaveResultsJSONToolStripMenuItem.Image"), System.Drawing.Image)
Me.SaveResultsJSONToolStripMenuItem.Name = "SaveResultsJSONToolStripMenuItem"
Me.SaveResultsJSONToolStripMenuItem.Size = New System.Drawing.Size(143, 22)
Me.SaveResultsJSONToolStripMenuItem.Text = "Save posts to"
Me.SaveResultsJSONToolStripMenuItem.ToolTipText = "Save results to a JSON file"
'
'JSONToolStripMenuItem
'
Me.JSONToolStripMenuItem.AutoToolTip = True
Me.JSONToolStripMenuItem.CheckOnClick = True
Me.JSONToolStripMenuItem.Image = CType(resources.GetObject("JSONToolStripMenuItem.Image"), System.Drawing.Image)
Me.JSONToolStripMenuItem.Name = "JSONToolStripMenuItem"
Me.JSONToolStripMenuItem.Size = New System.Drawing.Size(185, 22)
Me.JSONToolStripMenuItem.Text = "JSON"
'
'CSVToolStripMenuItem
'
Me.CSVToolStripMenuItem.AutoToolTip = True
Me.CSVToolStripMenuItem.Enabled = False
Me.CSVToolStripMenuItem.Image = CType(resources.GetObject("CSVToolStripMenuItem.Image"), System.Drawing.Image)
Me.CSVToolStripMenuItem.Name = "CSVToolStripMenuItem"
Me.CSVToolStripMenuItem.Size = New System.Drawing.Size(185, 22)
Me.CSVToolStripMenuItem.Text = "CSV (coming soon...)"
'
'FileMenuStrip
'
Me.FileMenuStrip.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.ToolsToolStripMenuTools})
Me.FileMenuStrip.Location = New System.Drawing.Point(0, 0)
Me.FileMenuStrip.Name = "FileMenuStrip"
Me.FileMenuStrip.Size = New System.Drawing.Size(355, 24)
Me.FileMenuStrip.TabIndex = 0
Me.FileMenuStrip.Text = "MenuStrip1"
'
'ToolsToolStripMenuTools
'
Me.ToolsToolStripMenuTools.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.AboutToolStripMenuItem, Me.LicensceToolStripMenuItem, Me.DeveloperToolStripMenuItem, Me.ChekUpdatesToolStripMenuItem, Me.ToolStripSeparator2, Me.QuitToolStripMenuItem})
Me.ToolsToolStripMenuTools.Image = CType(resources.GetObject("ToolsToolStripMenuTools.Image"), System.Drawing.Image)
Me.ToolsToolStripMenuTools.Name = "ToolsToolStripMenuTools"
Me.ToolsToolStripMenuTools.Size = New System.Drawing.Size(53, 20)
Me.ToolsToolStripMenuTools.Text = "File"
'
'AboutToolStripMenuItem
'
Me.AboutToolStripMenuItem.AutoToolTip = True
Me.AboutToolStripMenuItem.Image = CType(resources.GetObject("AboutToolStripMenuItem.Image"), System.Drawing.Image)
Me.AboutToolStripMenuItem.Name = "AboutToolStripMenuItem"
Me.AboutToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.AboutToolStripMenuItem.Text = "About"
'
'LicensceToolStripMenuItem
'
Me.LicensceToolStripMenuItem.AutoToolTip = True
Me.LicensceToolStripMenuItem.Image = CType(resources.GetObject("LicensceToolStripMenuItem.Image"), System.Drawing.Image)
Me.LicensceToolStripMenuItem.Name = "LicensceToolStripMenuItem"
Me.LicensceToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.LicensceToolStripMenuItem.Text = "License"
'
'DeveloperToolStripMenuItem
'
Me.DeveloperToolStripMenuItem.AutoToolTip = True
Me.DeveloperToolStripMenuItem.Image = CType(resources.GetObject("DeveloperToolStripMenuItem.Image"), System.Drawing.Image)
Me.DeveloperToolStripMenuItem.Name = "DeveloperToolStripMenuItem"
Me.DeveloperToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.DeveloperToolStripMenuItem.Text = "Developer"
'
'ChekUpdatesToolStripMenuItem
'
Me.ChekUpdatesToolStripMenuItem.AutoToolTip = True
Me.ChekUpdatesToolStripMenuItem.Image = CType(resources.GetObject("ChekUpdatesToolStripMenuItem.Image"), System.Drawing.Image)
Me.ChekUpdatesToolStripMenuItem.Name = "ChekUpdatesToolStripMenuItem"
Me.ChekUpdatesToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.ChekUpdatesToolStripMenuItem.Text = "Check updates"
'
'ToolStripSeparator2
'
Me.ToolStripSeparator2.Name = "ToolStripSeparator2"
Me.ToolStripSeparator2.Size = New System.Drawing.Size(149, 6)
'
'QuitToolStripMenuItem
'
Me.QuitToolStripMenuItem.AutoToolTip = True
Me.QuitToolStripMenuItem.Image = CType(resources.GetObject("QuitToolStripMenuItem.Image"), System.Drawing.Image)
Me.QuitToolStripMenuItem.Name = "QuitToolStripMenuItem"
Me.QuitToolStripMenuItem.Size = New System.Drawing.Size(152, 22)
Me.QuitToolStripMenuItem.Text = "Quit"
'
'LimitNumericUpDown
'
Me.LimitNumericUpDown.Location = New System.Drawing.Point(89, 125)
Me.LimitNumericUpDown.Minimum = New Decimal(New Integer() {5, 0, 0, 0})
Me.LimitNumericUpDown.Name = "LimitNumericUpDown"
Me.LimitNumericUpDown.ReadOnly = True
Me.LimitNumericUpDown.Size = New System.Drawing.Size(100, 23)
Me.LimitNumericUpDown.TabIndex = 15
Me.LimitNumericUpDown.Value = New Decimal(New Integer() {5, 0, 0, 0})
'
'StartForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 15.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.BackColor = System.Drawing.Color.White
Me.ClientSize = New System.Drawing.Size(355, 255)
Me.ContextMenuStrip = Me.ContextMenuStrip1
Me.Controls.Add(Me.LimitNumericUpDown)
Me.Controls.Add(Me.FileMenuStrip)
Me.Controls.Add(Me.Label5)
Me.Controls.Add(Me.Label4)
Me.Controls.Add(Me.Label3)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.ListingComboBox)
Me.Controls.Add(Me.TimeframeComboBox)
Me.Controls.Add(Me.SubredditTextBox)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.KeywordTextBox)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
Me.MainMenuStrip = Me.FileMenuStrip
Me.MaximizeBox = False
Me.Name = "StartForm"
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
Me.Text = "Reddit Post Scraping Tool"
Me.ContextMenuStrip1.ResumeLayout(False)
Me.FileMenuStrip.ResumeLayout(False)
Me.FileMenuStrip.PerformLayout()
CType(Me.LimitNumericUpDown, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents KeywordTextBox As TextBox
Friend WithEvents SubredditTextBox As TextBox
Friend WithEvents Button1 As Button
Friend WithEvents TimeframeComboBox As ComboBox
Friend WithEvents ListingComboBox As ComboBox
Friend WithEvents Label1 As Label
Friend WithEvents Label2 As Label
Friend WithEvents Label3 As Label
Friend WithEvents Label4 As Label
Friend WithEvents Label5 As Label
Friend WithEvents ContextMenuStrip1 As ContextMenuStrip
Friend WithEvents FileMenuStrip As MenuStrip
Friend WithEvents ToolsToolStripMenuTools As ToolStripMenuItem
Friend WithEvents AboutToolStripMenuItem As ToolStripMenuItem
Friend WithEvents DeveloperToolStripMenuItem As ToolStripMenuItem
Friend WithEvents ToolStripSeparator2 As ToolStripSeparator
Friend WithEvents QuitToolStripMenuItem As ToolStripMenuItem
Friend WithEvents SaveResultsJSONToolStripMenuItem As ToolStripMenuItem
Friend WithEvents ChekUpdatesToolStripMenuItem As ToolStripMenuItem
Friend WithEvents LicensceToolStripMenuItem As ToolStripMenuItem
Friend WithEvents JSONToolStripMenuItem As ToolStripMenuItem
Friend WithEvents CSVToolStripMenuItem As ToolStripMenuItem
Friend WithEvents LimitNumericUpDown As NumericUpDown
End Class

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,275 @@
Imports System.IO
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class StartForm
' Create the program's directory
' We will store information about the user and current machine in it
Private Sub PathFinder()
Dim directoryPath As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "RedditPostScrapingTool", "logs")
If Not Directory.Exists(directoryPath) Then
Directory.CreateDirectory(directoryPath)
Else
' DO NOTHING
End If
End Sub
Private Sub LicenseNotice()
MessageBox.Show("MIT License
Copyright (c) 2023 Richard Mwewa
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the ""Software""), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.", "License", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
' Create a file in C:\Users\<username>\AppData\Roaming\RedditPostScrapingTool, this will be used to determine
' Whether the program has been run before
' If it has not been run before, display the license notice
Private Sub LogFirstTimeLaunch()
Dim filePath As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "RedditPostScrapingTool", "logs", "first_launch.log")
Dim textToWrite As String = $"
{My.Application.Info.AssemblyName}
-------------------------
User: {Environment.UserName}
Host: {Environment.MachineName}
OS: {Environment.OSVersion}
x64: {Environment.Is64BitOperatingSystem}
First launched on: {DateTime.Now}"
If Not File.Exists(filePath) Then
LicenseNotice()
File.WriteAllText(filePath, textToWrite)
Else
' DO NOTHING
End If
End Sub
' Check the current time
' add a dark background to the program if it's evening
' This is my way of implementing auto dark-mode (you could help if you know a better way :) )
Private Sub DarkModeProperties()
Dim currentHour As Integer = DateTime.Now.Hour
If currentHour >= 6 And currentHour < 18 Then
Me.BackColor = ColorTranslator.FromHtml("#FFFFFFFF")
KeywordTextBox.BackColor = ColorTranslator.FromHtml("#FFFFFFFF")
KeywordTextBox.ForeColor = ColorTranslator.FromHtml("#FF121212")
SubredditTextBox.BackColor = ColorTranslator.FromHtml("#FFFFFFFF")
SubredditTextBox.ForeColor = ColorTranslator.FromHtml("#FF121212")
LimitNumericUpDown.BackColor = ColorTranslator.FromHtml("#FFFFFFFF")
LimitNumericUpDown.ForeColor = ColorTranslator.FromHtml("#FF121212")
LimitNumericUpDown.BackColor = ColorTranslator.FromHtml("#FFFFFFFF")
LimitNumericUpDown.ForeColor = ColorTranslator.FromHtml("#FF121212")
ListingComboBox.BackColor = ColorTranslator.FromHtml("#FFFFFFFF")
ListingComboBox.ForeColor = ColorTranslator.FromHtml("#FF121212")
TimeframeComboBox.BackColor = ColorTranslator.FromHtml("#FFFFFFFF")
TimeframeComboBox.ForeColor = ColorTranslator.FromHtml("#FF121212")
Label1.ForeColor = ColorTranslator.FromHtml("#FF121212")
Label2.ForeColor = ColorTranslator.FromHtml("#FF121212")
Label3.ForeColor = ColorTranslator.FromHtml("#FF121212")
Label4.ForeColor = ColorTranslator.FromHtml("#FF121212")
Label5.ForeColor = ColorTranslator.FromHtml("#FF121212")
Else
Me.BackColor = ColorTranslator.FromHtml("#FF121212")
KeywordTextBox.BackColor = ColorTranslator.FromHtml("#FF2E2E2E")
KeywordTextBox.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
SubredditTextBox.BackColor = ColorTranslator.FromHtml("#FF2E2E2E")
SubredditTextBox.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
LimitNumericUpDown.BackColor = ColorTranslator.FromHtml("#FF2E2E2E")
LimitNumericUpDown.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
LimitNumericUpDown.BackColor = ColorTranslator.FromHtml("#FF2E2E2E")
LimitNumericUpDown.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
ListingComboBox.BackColor = ColorTranslator.FromHtml("#FF2E2E2E")
ListingComboBox.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
TimeframeComboBox.BackColor = ColorTranslator.FromHtml("#FF2E2E2E")
TimeframeComboBox.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
Label1.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
Label2.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
Label3.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
Label4.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
Label5.ForeColor = ColorTranslator.FromHtml("#FFFFFFFF")
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim ApiHandler As New ApiHandler
Dim Keyword As String = KeywordTextBox.Text
Dim Subreddit As String = SubredditTextBox.Text
Dim Listing As String = ListingComboBox.Text.ToLower()
Dim Limit As Integer = LimitNumericUpDown.Value
Dim Timeframe As String = TimeframeComboBox.Text.ToLower()
Dim FoundPosts As Integer = 0
Dim TotalPosts As Integer = 0
' Clear the Columns and Rows before adding Items to them
PostsForm.DataGridViewPosts.Rows.Clear()
PostsForm.DataGridViewPosts.Columns.Clear()
PostsForm.DataGridViewPosts.Columns.Add("PostCount", "Post Number")
PostsForm.DataGridViewPosts.Columns.Add("PostAuthor", "Author")
PostsForm.DataGridViewPosts.Columns.Add("PostID", "ID")
PostsForm.DataGridViewPosts.Columns.Add("PostSubreddit", "Subreddit")
PostsForm.DataGridViewPosts.Columns.Add("SubredditVisibility", "Subreddit Visibility")
PostsForm.DataGridViewPosts.Columns.Add("PostThumbnail", "Thumbnail")
PostsForm.DataGridViewPosts.Columns.Add("PostIsNSFW", "NSFW")
PostsForm.DataGridViewPosts.Columns.Add("PostIsGilded", "Gilded")
PostsForm.DataGridViewPosts.Columns.Add("PostUpvotes", "Upvotes")
PostsForm.DataGridViewPosts.Columns.Add("PostUpvoteRatio", "Upvote Ratio")
PostsForm.DataGridViewPosts.Columns.Add("PostDownvotes", "Downvotes")
PostsForm.DataGridViewPosts.Columns.Add("PostAwards", "Awards")
PostsForm.DataGridViewPosts.Columns.Add("PostTopAward", "Top Award")
PostsForm.DataGridViewPosts.Columns.Add("PostIsCrosspostable", "Is Crosspostable?")
PostsForm.DataGridViewPosts.Columns.Add("PostScore", "Score")
PostsForm.DataGridViewPosts.Columns.Add("PostText", "Text")
PostsForm.DataGridViewPosts.Columns.Add("PostCategory", "Category")
PostsForm.DataGridViewPosts.Columns.Add("PostDomain", "Domain")
PostsForm.DataGridViewPosts.Columns.Add("PostPermalink", "Permalink")
PostsForm.DataGridViewPosts.Columns.Add("PostCreatedAt", "Created At")
PostsForm.DataGridViewPosts.Columns.Add("PostApprovedAt", "Approved At")
PostsForm.DataGridViewPosts.Columns.Add("PostApprovedBy", "Approved By")
If Limit > 100 Then
MessageBox.Show("Limit should not be over 100. Defaulting to 10", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
If Listing = "" Then
Listing = "top"
End If
If Timeframe = "" Then
Timeframe = "all"
End If
If Keyword = "" Then
MessageBox.Show("Keyword should not be emtpy", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
ElseIf Subreddit = "" Then
MessageBox.Show("Subreddit should not be emtpy", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
PostsForm.Text = $"Reddit Post Scraping Tool - {Keyword}"
Dim Posts As JObject = ApiHandler.ScrapeReddit(Subreddit, Listing, Limit, Timeframe)
For Each Post In Posts("data")("children")
TotalPosts += 1
If Post("data")("selftext").ToString.ToLower().Contains(KeywordTextBox.Text.ToLower()) Then
FoundPosts += 1
PostsForm.DataGridViewPosts.Rows.Add(TotalPosts, 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")("selftext"),
Post("data")("category"), Post("data")("domain"), Post("data")("permalink"), Post("data")("created"),
Post("data")("approved_at_utc"), Post("data")("approved_by"))
End If
Next
'Don't show the results form if found posts are not greater than 0
If FoundPosts > 0 Then
MessageBox.Show($"Keyword `{Keyword}` was found in {FoundPosts}/" + Posts("data")("children").Count.ToString _
+ $" {Listing} posts from r/{Subreddit}", "Found", MessageBoxButtons.OK, MessageBoxIcon.Information)
PostsForm.Show()
Else
MessageBox.Show($"Keyword `{Keyword}` was not found in either one of the " + Posts("data")("children").Count.ToString _
+ $" {Listing} posts from r/{Subreddit}", "Not Found", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
If JSONToolStripMenuItem.Checked Then
Dim saveFileDialog As New SaveFileDialog()
saveFileDialog.Filter = "JSON files (*.json)|*.json"
saveFileDialog.Title = "Save posts to JSON"
If saveFileDialog.ShowDialog() = DialogResult.OK Then
Dim fileName As String = saveFileDialog.FileName
Dim serializerSettings As New JsonSerializerSettings()
serializerSettings.Formatting = Formatting.Indented
Dim json As String = JsonConvert.SerializeObject(Posts("data"), serializerSettings)
System.IO.File.WriteAllText(fileName, json)
MessageBox.Show($"Results saved to {fileName} successfully!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
End If
End Sub
' StartForm load event
Private Sub StartForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PathFinder()
LogFirstTimeLaunch()
DarkModeProperties()
ToolsToolStripMenuTools.Text = Environment.UserName
Me.Text = $"{My.Application.Info.AssemblyName} v{My.Application.Info.Version}"
End Sub
Private Sub AboutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AboutToolStripMenuItem.Click
Shell("cmd /c start https:github.com/bellingcat/reddit-post-scraping-tool/wiki")
End Sub
Private Sub QuitToolStripMenuItem_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)
If result = DialogResult.Yes Then
Me.Close()
End If
End Sub
Private Sub DeveloperToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DeveloperToolStripMenuItem.Click
DeveloperForm.ShowDialog()
End Sub
Private Sub ChekUpdatesToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ChekUpdatesToolStripMenuItem.Click
Dim ApiHandler As New ApiHandler()
Dim data As JObject = ApiHandler.CheckUpdates()
If data("tag_name").ToString = $"{My.Application.Info.Version}" Then
MessageBox.Show($"You're running the current version v{My.Application.Info.Version} of {My.Application.Info.ProductName}. Check again soon! :)", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
Dim confirm As DialogResult = MessageBox.Show($"A new version v{data("tag_name")} of {My.Application.Info.ProductName} is availble, would you like to get it?
What's new in v{data("tag_name")}?
{data("body")}
", "Update", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If confirm = DialogResult.Yes Then
Shell($"cmd /c start https://github.com/bellingcat/reddit-post-scraping-tool/releases/tag/{data("tag_name")}")
End If
End If
End Sub
Private Sub LicensceToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LicensceToolStripMenuItem.Click
LicenseNotice()
End Sub
End Class

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,30 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict Off
Option Explicit On
Imports System
Imports System.Reflection
<Assembly: System.Reflection.AssemblyCompanyAttribute("Richard Mwewa"), _
Assembly: System.Reflection.AssemblyConfigurationAttribute("Debug"), _
Assembly: System.Reflection.AssemblyCopyrightAttribute("Copyright (c) 2023 Richard Mwewa. All rights reserved."), _
Assembly: System.Reflection.AssemblyDescriptionAttribute("Given a subreddit name and a keyword, this program returns all top (by default) p"& _
"osts that contain the specified keyword. "), _
Assembly: System.Reflection.AssemblyFileVersionAttribute("1.2.0.1"), _
Assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.2.0"), _
Assembly: System.Reflection.AssemblyProductAttribute("Reddit Post Scraping Tool"), _
Assembly: System.Reflection.AssemblyTitleAttribute("Reddit Post Scraping Tool"), _
Assembly: System.Reflection.AssemblyVersionAttribute("1.2.0.1"), _
Assembly: System.Reflection.AssemblyMetadataAttribute("RepositoryUrl", "https://github.com/bellingcat/reddit-post-scraping-tool"), _
Assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0"), _
Assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")>
'Generated by the MSBuild WriteCodeFragment class.

View File

@@ -0,0 +1,17 @@
is_global = true
build_property.ApplicationManifest =
build_property.StartupObject = Reddit_Post_Scraping_Tool.My.MyApplication
build_property.ApplicationDefaultFont =
build_property.ApplicationHighDpiMode =
build_property.ApplicationUseCompatibleTextRendering =
build_property.ApplicationVisualStyles =
build_property.TargetFramework = net6.0-windows
build_property.TargetPlatformMinVersion = 7.0
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = Reddit_Post_Scraping_Tool
build_property.ProjectDir = C:\Users\rly0nheart\Documents\Visual Studio 2022\VB.Net Projects\Reddit Post Scraping Tool\Reddit Post Scraping Tool\

View File

@@ -1,77 +0,0 @@
import logging
import argparse
import requests
from rich.tree import Tree
from datetime import datetime
from rich import print as xprint
class RedditPostScraper:
def __init__(self, args):
self.session = requests.session()
self.session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15'}
def start(self):
response = self.session.get(f'https://reddit.com/r/{args.subreddit}/{args.listing}.json?limit={args.limit}&t={args.timeframe}').json()
found_posts = 0
for post in response['data']['children']:
if args.keyword.lower() in post['data']['selftext'] or args.keyword.lower() in post['data']['title']:
found_posts += 1
self.get_posts(post)
logging.info(f"Keyword ('{args.keyword}') was found in {found_posts}/{len(response['data']['children'])} {args.listing} posts from r/{args.subreddit}.")
# Getting posts
def get_posts(self, post):
post_data = {'Author': post['data']['author'],
'ID': post['data']['id'],
'Subreddit': post["data"]["subreddit_name_prefixed"],
'Visibility': post['data']['subreddit_type'],
#'Author': post["data"]["author_fullname"],
'Thumbnail': post["data"]["thumbnail"],
#'Flair': post["data"]["link_flair_text"],
'NSFW': post['data']['over_18'],
'Gilded': post['data']['gilded'],
'Upvotes': post["data"]["ups"],
'Upvote ratio': post["data"]["upvote_ratio"],
'Downvotes': post["data"]["downs"],
'Awards': post["data"]["total_awards_received"],
'Top award': post['data']['top_awarded_type'],
'Is crosspostable?': post['data']['is_crosspostable'],
'Score': post["data"]["score"],
'Category': post['data']['category'],
'Domain': post["data"]["domain"],
'Created': post['data']['created'],
'Approved at': post['data']['approved_at_utc'],
'Approved by': post['data']['approved_by'],}
post_tree = Tree("\n" + post['data']['title'])
for post_key, post_value in post_data.items():
post_tree.add(f"{post_key}: {post_value}")
xprint(post_tree)
print(post['data']['selftext']+"\n")
# Parsing command line arguments
parser = argparse.ArgumentParser(description=f'reddit-post-scraping-tool — by Richard Mwewa | https://about.me/rly0nheart', epilog=f'Given a subreddit name and a keyword, this script will return all top (by default) posts that contain the specified word.')
parser.add_argument('-k','--keyword',help='kewyword', required = True)
parser.add_argument('-s','--subreddit',help='subreddit', required = True)
parser.add_argument('-c','--limit',help='results limit (1-100) (default: %(default)s)', default=10, type=int)
parser.add_argument('-l', '--listing', default='top', const='top', nargs='?', choices=['controversial', 'hot', 'best', 'new', 'rising'], help='listings: controversial, hot, best, new, rising (default: %(default)s)')
parser.add_argument('-t','--timeframe', default='all', const='all', nargs='?', choices=['hour', 'day', 'week', 'month', 'year'], help='timeframe: hour, day, week, month, year (default: %(default)s)')
args = parser.parse_args()
start_time = datetime.now()
logging.basicConfig(format=f'[%(asctime)s] %(message)s', datefmt=f'%H:%M:%S%p', level=logging.DEBUG)
if __name__ == '__main__':
try:
RedditPostScraper(args).start()
except KeyboardInterrupt:
logging.warning(f'Process interrupted with (Ctrl+C).')
except Exception as e:
logging.error(f'An error occured: {e}')
logging.info(f'Finished in {datetime.now()-start_time} seconds.')

View File

@@ -0,0 +1,12 @@
from reddit_post_scraping_tool.reddit_post_scraping_tool import *
def main():
try:
reddit_post_scraper()
except KeyboardInterrupt:
log.warning(f"User interruption detected.")
except Exception as e:
log.error(e)
finally:
log.info(f'Finished in {datetime.now() - start_time} seconds.')

View File

@@ -0,0 +1,75 @@
import logging
import argparse
import requests
from rich.tree import Tree
from datetime import datetime
from rich import print as xprint
from rich.logging import RichHandler
start_time = datetime.now()
logging.basicConfig(level="NOTSET", format="%(message)s", handlers=[RichHandler(markup=True, log_time_format='[%H:%M:%S%p]')])
log = logging.getLogger("rich")
# Getting posts
def get_posts(post):
post_data = {'Author': post['data']['author'],
'ID': post['data']['id'],
'Subreddit': post["data"]["subreddit_name_prefixed"],
'Visibility': post['data']['subreddit_type'],
# 'Author': post["data"]["author_fullname"],
'Thumbnail': post["data"]["thumbnail"],
# 'Flair': post["data"]["link_flair_text"],
'NSFW': post['data']['over_18'],
'Gilded': post['data']['gilded'],
'Upvotes': post["data"]["ups"],
'Upvote ratio': post["data"]["upvote_ratio"],
'Downvotes': post["data"]["downs"],
'Awards': post["data"]["total_awards_received"],
'Top award': post['data']['top_awarded_type'],
'Is crosspostable?': post['data']['is_crosspostable'],
'Score': post["data"]["score"],
'Category': post['data']['category'],
'Domain': post["data"]["domain"],
'Created': post['data']['created'],
'Approved at': post['data']['approved_at_utc'],
'Approved by': post['data']['approved_by'], }
post_tree = Tree("\n" + post['data']['title'])
for post_key, post_value in post_data.items():
post_tree.add(f"{post_key}: {post_value}")
xprint(post_tree)
print(post['data']['selftext'] + "\n")
def reddit_post_scraper():
session = requests.session()
session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15'}
response = session.get(f'https://reddit.com/r/{args.subreddit}/{args.listing}.json?limit={args.limit}&t={args.timeframe}').json()
found_posts = 0
for post in response['data']['children']:
if args.keyword.lower() in post['data']['selftext'] or args.keyword.lower() in post['data']['title']:
found_posts += 1
get_posts(post)
log.info(f"Keyword ('{args.keyword}') was found in {found_posts}/{len(response['data']['children'])} {args.listing} posts from r/{args.subreddit}.")
def create_parser():
parser = argparse.ArgumentParser(
description=f'reddit-post-scraping-tool — by Richard Mwewa | https://about.me/rly0nheart',
epilog=f'Given a subreddit name and a keyword, this program returns all top (by default) posts that contain the specified word. ')
parser.add_argument('-k', '--keyword', help='kewyword', required=True)
parser.add_argument('-s', '--subreddit', help='subreddit', required=True)
parser.add_argument('-c', '--limit', help='results limit (1-100) (default: %(default)s)', default=10, type=int)
parser.add_argument('-l', '--listing', default='top', const='top', nargs='?',
choices=['controversial', 'hot', 'best', 'new', 'rising'],
help='listings: controversial, hot, best, new, rising (default: %(default)s)')
parser.add_argument('-t', '--timeframe', default='all', const='all', nargs='?',
choices=['hour', 'day', 'week', 'month', 'year'],
help='timeframe: hour, day, week, month, year (default: %(default)s)')
return parser
_parser = create_parser()
args = _parser.parse_args()

View File

@@ -1,2 +0,0 @@
rich
requests

31
setup.py Normal file
View File

@@ -0,0 +1,31 @@
import setuptools
with open("README.md", "r", encoding="utf-8") as file:
long_description = file.read()
setuptools.setup(
name="reddit-post-scraping-tool",
version="1.2.0.1",
author="Richard Mwewa",
author_email="rly0nheart@duck.com",
packages=["reddit_post_scraping_tool"],
description="Given a subreddit name and a keyword, this program returns all top (by default) posts that contain the specified word.",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/bellingcat/reddit-post-scraping-tool",
license="MIT License",
install_requires=["rich", "requests"],
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Information Technology',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Natural Language :: English',
'Programming Language :: Python :: 3'
],
entry_points={
"console_scripts": [
"reddit_post_scraping_tool=reddit_post_scraping_tool.main:main",
]
},
)