mirror of
https://github.com/developersIndia/deviras.git
synced 2025-05-31 14:11:43 +05:30
Compare commits
73 Commits
all-contri
...
remove-col
Author | SHA1 | Date | |
---|---|---|---|
4f9f286e82 | |||
e41335edc3 | |||
bd986018d2 | |||
9f0bf8bfc5 | |||
ee24bdcbf6 | |||
1c85fa5adc | |||
9cce47796f | |||
5d7700d61b | |||
e1e6dbd929 | |||
66ae6427d7 | |||
fb06e4287d | |||
6b244fa451 | |||
0d562ab223 | |||
1eba42ecd8 | |||
97e90ca32a | |||
92a5d11fbb | |||
bfe81b439d | |||
cc1b6467c6 | |||
9b6f542623 | |||
19efcb83ab | |||
f7a559aeb7 | |||
a9cb37dbd3 | |||
73ba9c6d81 | |||
b252f92e02 | |||
5a18457c55 | |||
d6fed619fd | |||
a606dec66a | |||
97adb8a6e8 | |||
dd08a66b5d | |||
201eeace96 | |||
0b4f522426 | |||
e620696ec0 | |||
d5bc01156c | |||
a40760a63d | |||
d0525e27ba | |||
753567f319 | |||
0060d1aeed | |||
dda14476df | |||
1e4f32431c | |||
bc372531f2 | |||
34586d0281 | |||
d721a6a611 | |||
f8087bb256 | |||
ccb9479aa2 | |||
74dffe0214 | |||
ef6dabe4e6 | |||
a6f3ed1b92 | |||
c8c1cdd81f | |||
df213fb36a | |||
98db840054 | |||
8d9b7a9d34 | |||
899674b01c | |||
e315e5acce | |||
3549398fab | |||
08a32473e3 | |||
ee3efe7c13 | |||
e32aec9b27 | |||
a909135aa0 | |||
aadd308260 | |||
1b4d263a51 | |||
1c08df1867 | |||
e3224212c3 | |||
06f0a269ae | |||
a82489d0a6 | |||
13498be553 | |||
48e2a025d0 | |||
2cfb455b64 | |||
589a47a315 | |||
9d9db1de7f | |||
d76225cf32 | |||
e269052344 | |||
6d80f2b388 | |||
98aa67d8a4 |
@ -41,6 +41,15 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ni5arga",
|
||||
"name": "Nisarga Adhikary",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/45588772?v=4",
|
||||
"profile": "https://nisarga.me/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
@ -49,5 +58,6 @@
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true,
|
||||
"commitConvention": "angular"
|
||||
"commitConvention": "angular",
|
||||
"commitType": "docs"
|
||||
}
|
||||
|
37
.github/workflows/aoc.yml
vendored
Normal file
37
.github/workflows/aoc.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name : AoC leaderboard
|
||||
|
||||
on:
|
||||
# schedule:
|
||||
# Every 2 hours”
|
||||
# - cron: '0 */2 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
- name: Update Learderboard
|
||||
env:
|
||||
REDDIT_CLIENT_ID: ${{ secrets.REDDIT_CLIENT_ID }}
|
||||
REDDIT_CLIENT_SECRET: ${{ secrets.REDDIT_CLIENT_SECRET }}
|
||||
REDDIT_PASSWORD: ${{ secrets.REDDIT_PASSWORD }}
|
||||
REDDIT_USERNAME: ${{ secrets.REDDIT_USERNAME }}
|
||||
AOC_SESSION_COOKIE: ${{ secrets.AOC_SESSION_COOKIE }}
|
||||
AOC_LEADERBOARD_CODE: ${{ secrets.AOC_LEADERBOARD_CODE }}
|
||||
REDDIT_POST_ID: ${{ secrets.REDDIT_POST_ID }}
|
||||
run: |
|
||||
cd aoc
|
||||
python main.py
|
37
.github/workflows/collection-thread-updater.yml
vendored
Normal file
37
.github/workflows/collection-thread-updater.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name : Community Threads Wiki Updater
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
post_url:
|
||||
description: 'The URL of the Reddit post to add'
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
- name: Update Wiki
|
||||
env:
|
||||
REDDIT_CLIENT_ID: ${{ secrets.REDDIT_CLIENT_ID }}
|
||||
REDDIT_CLIENT_SECRET: ${{ secrets.REDDIT_CLIENT_SECRET }}
|
||||
REDDIT_PASSWORD: ${{ secrets.REDDIT_PASSWORD }}
|
||||
REDDIT_USERNAME: ${{ secrets.REDDIT_USERNAME }}
|
||||
GIST_ID: ${{ secrets.GIST_ID }}
|
||||
GIST_TOKEN: ${{ secrets.GIST_TOKEN }}
|
||||
run: |
|
||||
cd community-threads
|
||||
python main.py ${{ github.event.inputs.post_url }}
|
35
.github/workflows/community-roundup.yml
vendored
Normal file
35
.github/workflows/community-roundup.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
name: Community Roundup
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run at 3:25 AM UTC (8:55 AM IST) every day
|
||||
- cron: '25 3 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Create Community Roundup Post
|
||||
env:
|
||||
REDDIT_CLIENT_ID: ${{ secrets.REDDIT_CLIENT_ID }}
|
||||
REDDIT_CLIENT_SECRET: ${{ secrets.REDDIT_CLIENT_SECRET }}
|
||||
REDDIT_PASSWORD: ${{ secrets.REDDIT_PASSWORD }}
|
||||
REDDIT_USERNAME: ${{ secrets.REDDIT_USERNAME }}
|
||||
GIST_ID: ${{ secrets.GIST_ID }}
|
||||
GIST_TOKEN: ${{ secrets.GIST_TOKEN }}
|
||||
run: |
|
||||
cd community-roundup
|
||||
python -m pip install --upgrade pip
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
python main.py
|
34
.github/workflows/flair-usage-stats.yml
vendored
Normal file
34
.github/workflows/flair-usage-stats.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
name: User Flair Usage Stats
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Runs every day at 3:30 PM UTC (9 PM IST)
|
||||
- cron: '30 15 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
send_discord_message:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
- name: Get Stats
|
||||
env:
|
||||
REDDIT_CLIENT_ID: ${{ secrets.REDDIT_CLIENT_ID }}
|
||||
REDDIT_CLIENT_SECRET: ${{ secrets.REDDIT_CLIENT_SECRET }}
|
||||
REDDIT_PASSWORD: ${{ secrets.REDDIT_PASSWORD }}
|
||||
REDDIT_USERNAME: ${{ secrets.REDDIT_USERNAME }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run: |
|
||||
cd user-flair-usage
|
||||
python -m pip install --upgrade pip
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
python main.py
|
35
.github/workflows/showcase-sunday.yml
vendored
Normal file
35
.github/workflows/showcase-sunday.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
name: Showcase Sunday Thread
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run at 3:25 AM UTC (8:55 AM IST) every day
|
||||
- cron: '25 3 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
- name: Create Showcase Sunday Thread
|
||||
env:
|
||||
REDDIT_CLIENT_ID: ${{ secrets.REDDIT_CLIENT_ID }}
|
||||
REDDIT_CLIENT_SECRET: ${{ secrets.REDDIT_CLIENT_SECRET }}
|
||||
REDDIT_PASSWORD: ${{ secrets.REDDIT_PASSWORD }}
|
||||
REDDIT_USERNAME: ${{ secrets.REDDIT_USERNAME }}
|
||||
run: |
|
||||
cd showcase-sunday
|
||||
python main.py
|
@ -1,14 +1,10 @@
|
||||
name: r/developersIndia titles updater
|
||||
name: About Widget Titles Updater
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# At 19:30 on every 2nd day-of-week.”
|
||||
- cron: '30 19 * * */2'
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"python.formatting.provider": "black"
|
||||
}
|
39
README.md
39
README.md
@ -1,19 +1,42 @@
|
||||
# deviras
|
||||
|
||||
> Bunch of scripts to automate stuff around the developersIndia subreddit
|
||||
|
||||
> Bunch of scripts to automate stuff in r/developersIndia.
|
||||
|
||||
[](https://discordapp.com/invite/MKXMSNC)
|
||||
[](https://www.reddit.com/r/developersIndia/)
|
||||
[](https://www.reddit.com/r/developersIndia/)
|
||||
[](#contributors-)
|
||||
|
||||
## Scripts
|
||||
|
||||
### [idcard_update](https://github.com/developersIndia/deviras/blob/idcard_update)
|
||||
### [idcard_update](https://github.com/developersIndia/deviras/blob/main/idcard_update/main.py)
|
||||
|
||||
Used for changing the text below total members & live members count in a subreddit.
|
||||
- Used for changing the text below _total members_ & _live members_ count on the Subreddit.
|
||||
- 
|
||||
|
||||
### [aoc](https://github.com/developersIndia/deviras/blob/main/aoc/main.py)
|
||||
|
||||
- Used for updating the Advent of Code User Scores in the [leaderboard post](https://www.reddit.com/r/developersIndia/comments/1889ar3/advent_of_code_rdevelopersindia_leaderboard_year/).
|
||||
- 
|
||||
|
||||
### [community-threads](https://github.com/developersIndia/deviras/blob/main/community-threads/main.py)
|
||||
|
||||
- Used for grabbing the posts from [community threads collection](https://www.reddit.com/r/developersIndia/collection/958aef35-f9cb-414d-ab33-08bc639e47de/) and adding it to the [wiki](https://www.reddit.com/r/developersIndia/wiki/community-threads/).
|
||||
- 
|
||||
|
||||
### [job-thread](https://github.com/developersIndia/deviras/blob/main/job-thread/main.py)
|
||||
|
||||
- Used for creating [hiring threads](https://www.reddit.com/r/developersIndia/?f=flair_name%3A%22Hiring%22) in the subreddit that gets the job from our [job board](https://developersindia.in/job-board/).
|
||||
|
||||
### [showcase-sunday](https://github.com/developersIndia/deviras/blob/main/showcase-sunday/main.py)
|
||||
|
||||
- Used for creating [Showcase Sunday Megathreads](https://www.reddit.com/r/developersIndia/search/?q=flair%3A%20Showcase%20Sunday&restrict_sr=1) posts in the subreddit.
|
||||
- 
|
||||
|
||||
### [ama-summarizer](https://github.com/developersIndia/deviras/blob/main/ama-summarizer/main.py/)
|
||||
- The Python script to help during AMAs. It generates a markdown file of questions and links of the questions the AMA guest has answered.
|
||||
|
||||
|
||||

|
||||
|
||||
## Setup
|
||||
|
||||
@ -40,9 +63,6 @@ Used for changing the text below total members & live members count in a subredd
|
||||
python -m unittest
|
||||
```
|
||||
|
||||
## Resources & Learning Material
|
||||
|
||||
- [PRAW Docs](https://praw.readthedocs.io/en/stable/code_overview/other/idcard.html)
|
||||
|
||||
## Contributors ✨
|
||||
|
||||
@ -58,6 +78,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://pavanjadhaw.me"><img src="https://avatars.githubusercontent.com/u/26551780?v=4?s=100" width="100px;" alt="Pavan Jadhaw"/><br /><sub><b>Pavan Jadhaw</b></sub></a><br /><a href="#ideas-pavanjadhaw" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://animesh-ghosh.github.io/"><img src="https://avatars.githubusercontent.com/u/34956994?v=4?s=100" width="100px;" alt="MaDDogx"/><br /><sub><b>MaDDogx</b></sub></a><br /><a href="https://github.com/developersIndia/deviras/commits?author=Animesh-Ghosh" title="Code">💻</a> <a href="https://github.com/developersIndia/deviras/commits?author=Animesh-Ghosh" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://pratham.cc"><img src="https://avatars.githubusercontent.com/u/67585967?v=4?s=100" width="100px;" alt="Pratham"/><br /><sub><b>Pratham</b></sub></a><br /><a href="https://github.com/developersIndia/deviras/commits?author=git-bruh" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://nisarga.me/"><img src="https://avatars.githubusercontent.com/u/45588772?v=4?s=100" width="100px;" alt="Nisarga Adhikary"/><br /><sub><b>Nisarga Adhikary</b></sub></a><br /><a href="https://github.com/developersIndia/deviras/commits?author=ni5arga" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
1
ama-summarizer/.gitignore
vendored
Normal file
1
ama-summarizer/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
questions.md
|
65
ama-summarizer/main.py
Normal file
65
ama-summarizer/main.py
Normal file
@ -0,0 +1,65 @@
|
||||
import praw
|
||||
import os
|
||||
|
||||
|
||||
def get_reddit_instance():
|
||||
# Reddit API credentials
|
||||
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 14.2; rv:109.0) Gecko/20100101 Firefox/121.0"
|
||||
client_id = os.environ["REDDIT_CLIENT_ID"]
|
||||
client_secret = os.environ["REDDIT_CLIENT_SECRET"]
|
||||
reddit_pass = os.environ["REDDIT_PASSWORD"]
|
||||
username = os.environ["REDDIT_USERNAME"]
|
||||
|
||||
# Create a Reddit instance
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
password=reddit_pass,
|
||||
user_agent=user_agent,
|
||||
username=username,
|
||||
)
|
||||
return reddit
|
||||
|
||||
|
||||
def get_post_url():
|
||||
post_url = input("Enter the AMA post URL: ") # reddit.com URLs preferred
|
||||
return post_url
|
||||
|
||||
|
||||
def get_guest_username():
|
||||
guest_username = input("Enter the AMA guest username: ")
|
||||
return guest_username
|
||||
|
||||
|
||||
def main():
|
||||
reddit = get_reddit_instance()
|
||||
|
||||
post_url = get_post_url()
|
||||
guest_username = get_guest_username()
|
||||
|
||||
submission = reddit.submission(url=post_url)
|
||||
submission.comments.replace_more(limit=None)
|
||||
|
||||
markdown_file = ""
|
||||
question_number = 1
|
||||
|
||||
for comment in submission.comments.list():
|
||||
if comment.author and comment.author.name.lower() == guest_username.lower():
|
||||
# TODO truncate long questions with ellipsis
|
||||
question_text = comment.parent().body.replace("\n", " ")
|
||||
# avoid deleted questions/comments
|
||||
if question_text != "[deleted]":
|
||||
question_link = "https://reddit.com" + comment.parent().permalink
|
||||
markdown_file += (
|
||||
f"{question_number}. [{question_text}]({question_link})\n"
|
||||
)
|
||||
question_number += 1
|
||||
|
||||
with open("questions.md", "w", encoding="utf-8") as file:
|
||||
file.write(markdown_file)
|
||||
|
||||
print(f"{question_number} questions generated successfully.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
5
ama-summarizer/readme.md
Normal file
5
ama-summarizer/readme.md
Normal file
@ -0,0 +1,5 @@
|
||||
# ama-summarizer
|
||||
|
||||
- The Python script to help during [AMAs](https://developersindia.in/ama-archive/). It generates a markdown file of questions and links to the questions the AMA guest has answered.
|
||||
- This script is designed to generate a Markdown file containing questions and links from a Reddit post's comments. It specifically focuses on questions or comments answered by a specific user.
|
||||
- The resulting Markdown file will contain a list of questions or comments that the specified guest has answered, with each question numbered and linked to the corresponding Reddit comment.
|
1
ama-summarizer/requirements.txt
Normal file
1
ama-summarizer/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
praw
|
0
aoc/__init__.py
Normal file
0
aoc/__init__.py
Normal file
BIN
aoc/cookie.png
Normal file
BIN
aoc/cookie.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
64
aoc/main.py
Normal file
64
aoc/main.py
Normal file
@ -0,0 +1,64 @@
|
||||
import praw
|
||||
import requests
|
||||
import os
|
||||
|
||||
client_id = os.environ["REDDIT_CLIENT_ID"]
|
||||
client_secret = os.environ["REDDIT_CLIENT_SECRET"]
|
||||
reddit_pass = os.environ["REDDIT_PASSWORD"]
|
||||
username = os.environ["REDDIT_USERNAME"]
|
||||
user_agent = 'AdventOfCode Leaderboard Updater (by https://github.com/ni5arga/)'
|
||||
aoc_session_cookie = os.environ["AOC_SESSION_COOKIE"]
|
||||
aoc_leaderboard_code = os.environ["AOC_LEADERBOARD_CODE"]
|
||||
reddit_post_id = os.environ.get("REDDIT_POST_ID")
|
||||
|
||||
aoc_url = f'https://adventofcode.com/{{year}}/leaderboard/private/view/{aoc_leaderboard_code}.json'
|
||||
|
||||
def get_leaderboard_data():
|
||||
response = requests.get(aoc_url.format(year=2023), cookies={'session': aoc_session_cookie})
|
||||
data = response.json()
|
||||
return data
|
||||
|
||||
def format_leaderboard(data, num_players=100):
|
||||
leaderboard_stats = "r/developersIndia Advent of Code Leaderboard Stats\n\n"
|
||||
leaderboard_stats += "| Rank | Player | Stars | Score |\n"
|
||||
leaderboard_stats += "|------|--------|-------|-------|\n"
|
||||
|
||||
# Sort members by stars in descending order
|
||||
sorted_members = sorted(data['members'].values(), key=lambda x: x['local_score'], reverse=True)
|
||||
|
||||
# Include only the top players
|
||||
for i, member_data in enumerate(sorted_members[:num_players]):
|
||||
# check for non-zero local_score
|
||||
if member_data['local_score'] > 0:
|
||||
leaderboard_stats += f"| {i + 1} | {member_data['name']} | {member_data['stars']} | {member_data['local_score']} |\n"
|
||||
|
||||
leaderboard_stats += f"\n[Advent of Code Leaderboard](https://adventofcode.com/2023/leaderboard/private/view/{aoc_leaderboard_code})\n"
|
||||
leaderboard_stats += f"\nUpdated every 24 hours"
|
||||
|
||||
return leaderboard_stats
|
||||
|
||||
def update_reddit_post(reddit, post_id, new_stats):
|
||||
post = reddit.submission(id=post_id)
|
||||
post.edit(new_stats)
|
||||
|
||||
def main():
|
||||
if not reddit_post_id:
|
||||
print("Please set the REDDIT_POST_ID environment variable.")
|
||||
return
|
||||
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
username=username,
|
||||
password=reddit_pass,
|
||||
user_agent=user_agent
|
||||
)
|
||||
|
||||
leaderboard_data = get_leaderboard_data()
|
||||
|
||||
formatted_stats = format_leaderboard(leaderboard_data)
|
||||
|
||||
update_reddit_post(reddit, reddit_post_id, formatted_stats)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
48
aoc/readme.md
Normal file
48
aoc/readme.md
Normal file
@ -0,0 +1,48 @@
|
||||
# AoC Private Leaderboard Stats Updater Script for Reddit
|
||||
|
||||
## Required Environment Variables
|
||||
|
||||
|
||||
1. `REDDIT_CLIENT_ID`: Reddit API client ID.
|
||||
2. `REDDIT_CLIENT_SECRET`: Reddit API client secret.
|
||||
3. `REDDIT_PASSWORD`: Reddit account password.
|
||||
4. `REDDIT_USERNAME`: Reddit account username.
|
||||
5. `AOC_SESSION_COOKIE`: Session cookie for the Advent of Code website.
|
||||
6. `AOC_LEADERBOARD_CODE`: Code for the Advent of Code leaderboard.
|
||||
7. `REDDIT_POST_ID`: ID of Reddit post which is used as leaderboard.
|
||||
|
||||
----
|
||||
## Instructions on how to get `AOC_SESSION_COOKIE`
|
||||
1. **Create an Advent of Code Account:**
|
||||
- If you don't have an Advent of Code account, go to the [Advent of Code website](https://adventofcode.com/), and sign up for an account.
|
||||
|
||||
2. **Log into Your AoC Account & open the leaderboard**
|
||||
- After creating an account, log into the AoC website using your credentials. Make sure you have joined the private leaderboard which's ID you have set in `AOC_LEADERBOARD_CODE`. Now navigate to the leaderboard page.
|
||||
|
||||
3. **Open Developer Tools in Your Browser:**
|
||||
- Open the browser's developer tools. You can usually do this by right-clicking on the web page, selecting "Inspect" or "Inspect Element," and then navigating to the "Network" tab.
|
||||
|
||||
4. **Go to the Network Tab:**
|
||||
- In the developer tools, go to the "Network" tab. This tab will show all network requests made by the website.
|
||||
|
||||
5. **Refresh the Page:**
|
||||
- Refresh the Advent of Code website. This will trigger various network requests, including the one that authenticates your session.
|
||||
|
||||
6. **Look for the Request with the Cookie:**
|
||||
- In the "Network" tab, look for a network request that is related to the Advent of Code website. It might be named something like "session" or "authenticate."
|
||||
- Click on this request to view its details.
|
||||
|
||||
7. **Find the Cookie Information:**
|
||||
- In the details of the network request, look for a section named "Request Headers" or "Cookies." You are interested in the value of the `session` cookie.
|
||||
|
||||
8. **Copy the Session Cookie Value:**
|
||||
- Copy the value of the `session` cookie. It is usually a long hex string of letters and numbers.
|
||||
|
||||
9. **Use the Session Cookie:**
|
||||
- Paste the copied session cookie value into the appropriate environment variable (`AOC_SESSION_COOKIE` in this case) in your code or set it as an environment variable.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
1
automod-announcements-updater/.gitignore
vendored
Normal file
1
automod-announcements-updater/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
automod.yml
|
3
automod-announcements-updater/README.md
Normal file
3
automod-announcements-updater/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Learnings
|
||||
|
||||
- Make sure the automod file doesn't end with `---`.
|
0
automod-announcements-updater/__init__.py
Normal file
0
automod-announcements-updater/__init__.py
Normal file
9
automod-announcements-updater/announcement.json
Normal file
9
automod-announcements-updater/announcement.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"filler_text": ">Namaste!\nThanks for submitting to r/developersIndia. Make sure to follow the subreddit [Code of Conduct](https://developersindia.in/code-of-conduct/) while participating in this thread.",
|
||||
"announcements": [
|
||||
{
|
||||
"title": "Announcemnt 1",
|
||||
"url": "http://www.google.com"
|
||||
}
|
||||
]
|
||||
}
|
109
automod-announcements-updater/main.py
Normal file
109
automod-announcements-updater/main.py
Normal file
@ -0,0 +1,109 @@
|
||||
import praw
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
import ruamel.yaml
|
||||
from io import StringIO
|
||||
|
||||
yaml = ruamel.yaml.YAML()
|
||||
yaml.default_flow_style = False
|
||||
|
||||
sub_name = os.environ["SUBREDDIT_NAME"]
|
||||
client_id = os.environ["REDDIT_CLIENT_ID"]
|
||||
client_secret = os.environ["REDDIT_CLIENT_SECRET"]
|
||||
reddit_pass = os.environ["REDDIT_PASSWORD"]
|
||||
username = os.environ["REDDIT_USERNAME"]
|
||||
|
||||
# Create a Reddit instance
|
||||
reddit = praw.Reddit(client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
user_agent=f"Automod reader by u/{username}",
|
||||
username=username,
|
||||
password=reddit_pass)
|
||||
|
||||
# Get the subreddit object
|
||||
subreddit = reddit.subreddit(sub_name)
|
||||
|
||||
def find_automod_wiki():
|
||||
for wikipage in subreddit.wiki:
|
||||
if wikipage == f"{sub_name}/config/automoderator":
|
||||
content = subreddit.wiki["config/automoderator"]
|
||||
break
|
||||
|
||||
if content is None:
|
||||
print("AutoModerator configuration page not found in the subreddit's wiki")
|
||||
exit(1)
|
||||
|
||||
return content
|
||||
|
||||
# Parse the AutoModerator configuration file
|
||||
def get_automod_rules(content):
|
||||
# Split the content into sections
|
||||
config_text = content.content_md
|
||||
yaml_sections = re.split(r'(?m)^---\n', config_text)[1:]
|
||||
|
||||
rules = []
|
||||
|
||||
# Parse each YAML section to get the rules
|
||||
for yaml_text in yaml_sections:
|
||||
rule = {}
|
||||
comment_pattern = r"^\s*#\s*(.*)$"
|
||||
comments = [
|
||||
match.group(1)
|
||||
for match in re.finditer(comment_pattern, yaml_text, re.MULTILINE)
|
||||
]
|
||||
# Load the YAML data using ruamel.yaml
|
||||
yaml_data = yaml.load(yaml_text)
|
||||
|
||||
if len(comments) > 0:
|
||||
rule[comments[0]] = yaml_data
|
||||
rules.append(rule)
|
||||
|
||||
return rules
|
||||
|
||||
def formatted_announcement(announcements):
|
||||
announcement_block = ""
|
||||
announcement_block += f"""{announcements["filler_text"]}\n\n"""
|
||||
announcement_block += "## Recent Announcements\n\n"
|
||||
for announcement in announcements["announcements"]:
|
||||
announcement_block += f"- **[{announcement['title']}]({announcement['url']})**\n"
|
||||
|
||||
return announcement_block
|
||||
|
||||
def update_automod_rule(rules, announcements):
|
||||
for rule in rules:
|
||||
for rulename, config in rule.items():
|
||||
if rulename == "New post comment":
|
||||
# print(config)
|
||||
config["comment"] = announcements
|
||||
# new_content = yaml.dump(config)
|
||||
stream = StringIO()
|
||||
yaml.dump(rules, stream)
|
||||
yaml_text = stream.getvalue()
|
||||
stream.close()
|
||||
print(yaml_text)
|
||||
# TODO: Update the wiki page with the new content
|
||||
# subreddit.wiki["config/automoderator"].edit(yaml_text, reason="Update automod comment")
|
||||
|
||||
|
||||
def get_comment():
|
||||
with open('new_post_automod.yaml', 'r') as file:
|
||||
yaml_content = file.read()
|
||||
|
||||
# Load the YAML content into a Python object
|
||||
yaml_object = yaml.load(yaml_content, ruamel.yaml.RoundTripLoader)
|
||||
return yaml_object
|
||||
|
||||
# read the announcements from announcements.json
|
||||
def read_announcements():
|
||||
with open('announcement.json', 'r') as file:
|
||||
announcements = json.load(file)
|
||||
return announcements
|
||||
|
||||
|
||||
content = find_automod_wiki()
|
||||
announcement = read_announcements()
|
||||
form_anno = formatted_announcement(announcement)
|
||||
|
||||
rules = get_automod_rules(content)
|
||||
update_automod_rule(rules, form_anno)
|
225
community-roundup/main.py
Normal file
225
community-roundup/main.py
Normal file
@ -0,0 +1,225 @@
|
||||
import datetime
|
||||
import praw
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import requests
|
||||
|
||||
client_id = os.environ["REDDIT_CLIENT_ID"]
|
||||
client_secret = os.environ["REDDIT_CLIENT_SECRET"]
|
||||
reddit_pass = os.environ["REDDIT_PASSWORD"]
|
||||
username = os.environ["REDDIT_USERNAME"]
|
||||
user_agent = "Community Roundup Post"
|
||||
token = os.environ["GIST_TOKEN"]
|
||||
gist_id = os.environ["GIST_ID"]
|
||||
sub = "developersIndia"
|
||||
|
||||
|
||||
def is_last_day_of_month():
|
||||
today = datetime.date.today()
|
||||
tomorrow = today + datetime.timedelta(days=1)
|
||||
return tomorrow.day == 1
|
||||
|
||||
|
||||
def get_posts_by_flair(subreddit, flair):
|
||||
current_year = datetime.date.today().year
|
||||
current_month = datetime.date.today().month
|
||||
posts = []
|
||||
for post in subreddit.search(f'flair_name:"{flair}"', time_filter="month"):
|
||||
post_date = datetime.datetime.fromtimestamp(post.created_utc)
|
||||
if post_date.year == current_year and post_date.month == current_month:
|
||||
post.title = post.title.replace("|", "\\|") # Escape the "|" character
|
||||
posts.append(post)
|
||||
|
||||
posts = sorted(posts, key=lambda post: post.created_utc, reverse=True)
|
||||
return posts
|
||||
|
||||
|
||||
def get_weekly_discussion_posts(subreddit):
|
||||
flair = next(
|
||||
filter(
|
||||
lambda flair: "Weekly Discussion" in flair["flair_text"],
|
||||
subreddit.flair.link_templates.user_selectable(),
|
||||
)
|
||||
)
|
||||
|
||||
return get_posts_by_flair(subreddit, flair["flair_text"])
|
||||
|
||||
|
||||
def get_ama_posts(subreddit):
|
||||
flair = next(
|
||||
filter(
|
||||
lambda flair: "AMA" in flair["flair_text"],
|
||||
subreddit.flair.link_templates.user_selectable(),
|
||||
)
|
||||
)
|
||||
|
||||
return get_posts_by_flair(subreddit, flair["flair_text"])
|
||||
|
||||
|
||||
def get_i_made_this_posts(subreddit):
|
||||
flair = next(
|
||||
filter(
|
||||
lambda flair: "I Made This" in flair["flair_text"],
|
||||
subreddit.flair.link_templates.user_selectable(),
|
||||
)
|
||||
)
|
||||
|
||||
# Get all posts with the specified flair
|
||||
posts = get_posts_by_flair(subreddit, flair["flair_text"])
|
||||
|
||||
# Sort the posts by upvotes and then comments in descending order
|
||||
posts = sorted(
|
||||
posts, key=lambda post: (post.score, post.num_comments), reverse=True
|
||||
)
|
||||
|
||||
# Return only the top 10 posts
|
||||
return posts[:10]
|
||||
|
||||
|
||||
def get_announcement_posts(subreddit):
|
||||
flair = next(
|
||||
filter(
|
||||
lambda flair: "Announcement" in flair["flair_text"],
|
||||
subreddit.flair.link_templates.user_selectable(),
|
||||
)
|
||||
)
|
||||
|
||||
return get_posts_by_flair(subreddit, flair["flair_text"])
|
||||
|
||||
|
||||
def get_gist_content(gist_id):
|
||||
headers = {
|
||||
"Authorization": f"token {token}",
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
}
|
||||
response = requests.get(f"https://api.github.com/gists/{gist_id}", headers=headers)
|
||||
gist = response.json()
|
||||
filename = list(gist["files"].keys())[0]
|
||||
return gist["files"][filename]["content"]
|
||||
|
||||
|
||||
def get_community_threads():
|
||||
saved_collection_posts = json.loads(get_gist_content(gist_id))
|
||||
# filter posts for this month & year
|
||||
saved_collection_posts = list(
|
||||
filter(
|
||||
lambda post: datetime.datetime.strptime(
|
||||
post["created_at"], "%Y-%m-%dT%H:%M:%S"
|
||||
).year
|
||||
== datetime.date.today().year
|
||||
and datetime.datetime.strptime(
|
||||
post["created_at"], "%Y-%m-%dT%H:%M:%S"
|
||||
).month
|
||||
== datetime.date.today().month,
|
||||
saved_collection_posts["posts"],
|
||||
)
|
||||
)
|
||||
return saved_collection_posts
|
||||
|
||||
|
||||
def create_community_roundup_post(
|
||||
subreddit,
|
||||
posts,
|
||||
i_made_this_posts,
|
||||
weekly_discussion_posts,
|
||||
ama_posts,
|
||||
announcement_posts,
|
||||
):
|
||||
flair = next(
|
||||
filter(
|
||||
lambda flair: "Community Roundup" in flair["flair_text"],
|
||||
subreddit.flair.link_templates.user_selectable(),
|
||||
)
|
||||
)
|
||||
|
||||
title = "Community Roundup: List of must read posts & discussions that happened this month - {month} {year}".format(
|
||||
month=datetime.date.today().strftime("%B"), year=datetime.date.today().year
|
||||
)
|
||||
|
||||
footer_text = """\n\n
|
||||
---
|
||||
|
||||
**Community Roundup is posted on the last day of each month. To explore a compilation of all interesting posts and community threads over time, [visit our wiki](https://www.reddit.com/r/developersIndia/wiki/community-threads/).**\n
|
||||
The collection is curated by our volunteer team & is independent of the number of upvotes and comments (except for "I made This" posts). If you believe we may have overlooked any engaging posts or discussions, please share them with us via [modmail](https://reddit.com/message/compose?to=r/developersIndia&subject=Community%20Threads%20Collection%20Suggestion&message=Hey%20folks%2C%0A%0A%3Cpost%20link%3E).\n
|
||||
"""
|
||||
|
||||
if len(announcement_posts) > 0:
|
||||
text = "## Announcements\n||\n|--------|\n"
|
||||
for post in announcement_posts:
|
||||
text += f"| [**{post.title}**]({post.url}) |\n"
|
||||
else:
|
||||
print("No announcements found. Skipping")
|
||||
|
||||
if len(ama_posts) > 0:
|
||||
text = "\n## AMAs\n||\n|--------|\n"
|
||||
for post in ama_posts:
|
||||
text += f"| [**{post.title}**]({post.url}) |\n"
|
||||
else:
|
||||
print("No AMAs found. Skipping")
|
||||
|
||||
if len(posts) > 0:
|
||||
text += "\n## Community Threads\n|S.No|Discussions started by members|\n|--------|--------|\n"
|
||||
posts_counter = 0
|
||||
for post in posts:
|
||||
posts_counter += 1
|
||||
text += f"| {posts_counter} | [**{post['title']}**]({post['url']}) |\n"
|
||||
else:
|
||||
print("No posts found in the collection for this month. Skipping")
|
||||
|
||||
if len(weekly_discussion_posts) > 0:
|
||||
text += "\n## Weekly Discussions\n|Started by Volunteer/Mod Team|\n|--------|\n"
|
||||
for post in weekly_discussion_posts:
|
||||
text += f"| [**{post.title}**]({post.url}) |\n"
|
||||
else:
|
||||
print("No weekly discussions found. Skipping")
|
||||
|
||||
if len(i_made_this_posts) > 0:
|
||||
text += "\n## I Made This\n|Top 10 posts|\n|--------|\n"
|
||||
for post in i_made_this_posts:
|
||||
text += f"| [**{post.title}**]({post.url}) |\n"
|
||||
else:
|
||||
print("No I Made This posts found. Skipping")
|
||||
|
||||
text = text + footer_text
|
||||
|
||||
submission = subreddit.submit(
|
||||
title,
|
||||
selftext=text,
|
||||
flair_id=flair["flair_template_id"],
|
||||
)
|
||||
submission.mod.approve()
|
||||
submission.mod.sticky()
|
||||
submission.mod.distinguish()
|
||||
submission.mod.lock()
|
||||
|
||||
return submission
|
||||
|
||||
|
||||
def main():
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
username=username,
|
||||
password=reddit_pass,
|
||||
user_agent=user_agent,
|
||||
)
|
||||
|
||||
subreddit = reddit.subreddit(sub)
|
||||
|
||||
if is_last_day_of_month():
|
||||
posts = get_community_threads()
|
||||
i_made_this_posts = get_i_made_this_posts(subreddit)
|
||||
weekly_discussion_posts = get_weekly_discussion_posts(subreddit)
|
||||
ama_posts = get_ama_posts(subreddit)
|
||||
announcement_posts = get_announcement_posts(subreddit)
|
||||
create_community_roundup_post(
|
||||
subreddit, posts, i_made_this_posts, weekly_discussion_posts, ama_posts, announcement_posts
|
||||
)
|
||||
print("Community Roundup post created successfully!")
|
||||
else:
|
||||
print("Skipping. Not the last day of the month")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
2
community-roundup/requirements.txt
Normal file
2
community-roundup/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
praw
|
||||
requests
|
0
community-threads/__init__.py
Normal file
0
community-threads/__init__.py
Normal file
142
community-threads/main.py
Normal file
142
community-threads/main.py
Normal file
@ -0,0 +1,142 @@
|
||||
import praw
|
||||
import os
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
import json
|
||||
from collections import defaultdict
|
||||
import requests
|
||||
|
||||
client_id = os.environ["REDDIT_CLIENT_ID"]
|
||||
client_secret = os.environ["REDDIT_CLIENT_SECRET"]
|
||||
reddit_pass = os.environ["REDDIT_PASSWORD"]
|
||||
username = os.environ["REDDIT_USERNAME"]
|
||||
token = os.environ["GIST_TOKEN"]
|
||||
gist_id = os.environ["GIST_ID"]
|
||||
sub = "developersIndia"
|
||||
|
||||
|
||||
def get_gist_content(gist_id):
|
||||
headers = {
|
||||
"Authorization": f"token {token}",
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
}
|
||||
response = requests.get(f"https://api.github.com/gists/{gist_id}", headers=headers)
|
||||
gist = response.json()
|
||||
filename = list(gist["files"].keys())[0]
|
||||
return gist["files"][filename]["content"]
|
||||
|
||||
|
||||
def update_gist(gist_id, filename, content, description=""):
|
||||
headers = {
|
||||
"Authorization": f"token {token}",
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
}
|
||||
data = {"description": description, "files": {filename: {"content": content}}}
|
||||
response = requests.patch(
|
||||
f"https://api.github.com/gists/{gist_id}", headers=headers, json=data
|
||||
)
|
||||
return response.json()
|
||||
|
||||
# farewell, reddit collections
|
||||
# def get_collection(reddit):
|
||||
# collection = reddit.subreddit(sub).collections(
|
||||
# permalink="https://reddit.com/r/developersIndia/collection/958aef35-f9cb-414d-ab33-08bc639e47de"
|
||||
# )
|
||||
# return collection
|
||||
|
||||
def get_post_data(reddit, post_url):
|
||||
submission = reddit.submission(url=post_url)
|
||||
post = {
|
||||
"title": submission.title,
|
||||
"url": submission.url,
|
||||
"id": submission.id,
|
||||
"num_comments": submission.num_comments,
|
||||
"created_at": datetime.utcfromtimestamp(
|
||||
submission.created_utc
|
||||
).isoformat(),
|
||||
"flair_text": submission.link_flair_text,
|
||||
}
|
||||
return post
|
||||
|
||||
def update_wiki(reddit, wikipage, posts):
|
||||
# Group posts by year
|
||||
posts_by_year = defaultdict(list)
|
||||
for post in posts:
|
||||
year = datetime.strptime(post['created_at'], '%Y-%m-%dT%H:%M:%S').year
|
||||
posts_by_year[year].append(post)
|
||||
|
||||
# Sort posts within each year
|
||||
for year in posts_by_year:
|
||||
posts_by_year[year] = sorted(posts_by_year[year], key=lambda k: k['created_at'], reverse=True)
|
||||
|
||||
# Calculate total posts and years
|
||||
total_posts = sum(len(posts) for posts in posts_by_year.values())
|
||||
total_years = len(posts_by_year)
|
||||
|
||||
wiki_header = """# A collection of must read discussions started by community members"""
|
||||
content = wiki_header + "\n\n"
|
||||
content += f"A handpicked collection of **{total_posts}** interesting posts, discussions & high-quality threads gathered over **{total_years}** years & counting.\n\n"
|
||||
content += "If you spot a post that could be in this list, send us a [modmail](https://reddit.com/message/compose?to=r/developersIndia&subject=Community%20Threads%20Collection%20Suggestion&message=Hey%20folks%2C%0A%0A%3Cpost%20link%3E)\n\n"
|
||||
|
||||
for year in sorted(posts_by_year.keys(), reverse=True):
|
||||
content += f"## {year}\n\n"
|
||||
# Add the posts for this year
|
||||
for post in posts_by_year[year]:
|
||||
formatted_date = datetime.strptime(post['created_at'], '%Y-%m-%dT%H:%M:%S').strftime('%d %b, %Y')
|
||||
content += f"- `{formatted_date}` [**{post['title']}**]({post['url']})\n\n"
|
||||
|
||||
# given a wiki link, update the wiki page with new markdown
|
||||
wikipage = reddit.subreddit(sub).wiki[wikipage]
|
||||
wikipage.edit(content=content)
|
||||
print("Wiki updated successfully!")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Update Community Threads Collection.')
|
||||
parser.add_argument('post_url', help='The URL of the Reddit post to add.')
|
||||
args = parser.parse_args()
|
||||
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
username=username,
|
||||
password=reddit_pass,
|
||||
user_agent=f"Automod reader by u/{username}",
|
||||
)
|
||||
|
||||
saved_collection_posts = json.loads(get_gist_content(gist_id))
|
||||
saved_collection_ids = [post["id"] for post in saved_collection_posts["posts"]]
|
||||
|
||||
print(f"Database was last updated on {saved_collection_posts['collection_last_updated']}")
|
||||
|
||||
posts = []
|
||||
for submission_id in saved_collection_posts["posts"]:
|
||||
post = {
|
||||
"title": submission_id["title"],
|
||||
"url": submission_id["url"],
|
||||
"id": submission_id["id"],
|
||||
"num_comments": submission_id["num_comments"],
|
||||
"created_at": submission_id["created_at"],
|
||||
"flair_text": submission_id["flair_text"],
|
||||
}
|
||||
posts.append(post)
|
||||
|
||||
new_post = get_post_data(reddit, args.post_url)
|
||||
if new_post["id"] not in saved_collection_ids:
|
||||
posts.append(new_post)
|
||||
posts = sorted(posts, key=lambda k: k["created_at"])
|
||||
|
||||
collection_json = {
|
||||
"collection_last_updated": datetime.utcnow().isoformat(),
|
||||
"posts": posts,
|
||||
}
|
||||
|
||||
update_gist(gist_id, "collection.json", json.dumps(collection_json, indent=4))
|
||||
print("Internal database updated successfully!")
|
||||
update_wiki(reddit, "community-threads", posts)
|
||||
else:
|
||||
print("Post is already in the collection. No changes were made.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
10
idcard_update/README.md
Normal file
10
idcard_update/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
## idcard_update
|
||||
|
||||
Used for changing the text below total members & live members count in a subreddit.
|
||||
|
||||

|
||||
|
||||
|
||||
## Resources & Learning Material
|
||||
|
||||
- [PRAW Docs](https://praw.readthedocs.io/en/stable/code_overview/other/idcard.html)
|
@ -1,28 +1,47 @@
|
||||
{
|
||||
"titles": [
|
||||
"ranting about jira",
|
||||
"siting in a meeting",
|
||||
"squashing bugs",
|
||||
"centering divs",
|
||||
"waiting for staging deployment",
|
||||
"writing tests",
|
||||
"pushing directly to prod",
|
||||
"doing code review",
|
||||
"deleting jira tickets",
|
||||
"creating a pull request",
|
||||
"forgot to run DB migrations",
|
||||
"broke production",
|
||||
"running on staging ENV",
|
||||
"merging git branches",
|
||||
"releasing the MVP",
|
||||
"finding jira tickets",
|
||||
"resolving merge conflicts",
|
||||
"receiving KT",
|
||||
"removing unused containers",
|
||||
"creating bugs to earn bread",
|
||||
"learning DSA",
|
||||
"trying to get out of vim",
|
||||
"making db indexes",
|
||||
"fixing YAML issues"
|
||||
"wrestling with Jira",
|
||||
"trapped in endless meetings",
|
||||
"exterminating code critters",
|
||||
"centering divs for fun",
|
||||
"impatiently waiting on staging",
|
||||
"crafting elegant tests",
|
||||
"yolo pushing to prod",
|
||||
"code review detectives",
|
||||
"assassinating Jira tickets",
|
||||
"forging majestic pull requests",
|
||||
"DB migration amnesiacs",
|
||||
"lgtm",
|
||||
"staging environment warriors",
|
||||
"taming wild git branches",
|
||||
"unleashing the MVP",
|
||||
"Jira ticket treasure hunters",
|
||||
"merge conflict negotiators",
|
||||
"absorbing knowledge transfer",
|
||||
"purging container hoarders",
|
||||
"bug creators and breadwinners",
|
||||
"DSA explorers",
|
||||
"escaping Vim's clutches",
|
||||
"indexing database maestros",
|
||||
"YAML whisperers",
|
||||
"debugging code in dreams",
|
||||
"refactoring like it's an art",
|
||||
"living on Stack Overflow",
|
||||
"mastering regex incantations",
|
||||
"performing git magic",
|
||||
"cursing the spaghetti code",
|
||||
"battling imposter syndrome",
|
||||
"optimizing for maximum coffee",
|
||||
"keyboard shortcut ninjas",
|
||||
"embracing the rubber duck",
|
||||
"design pattern aficionados",
|
||||
"missing semicolon sleuths",
|
||||
"navigating dependency hell",
|
||||
"tackling time zone torment",
|
||||
"praying to the CI/CD gods",
|
||||
"refining their Google-fu",
|
||||
"upgrading their tech stacks",
|
||||
"writing self-documenting code",
|
||||
"drowning in technical debt"
|
||||
]
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ def update_titles():
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
password=reddit_pass,
|
||||
user_agent="testscript by u/BhupeshV",
|
||||
username="BhupeshV",
|
||||
user_agent="Update Titles by u/devsIndiaBot",
|
||||
username="devsIndiaBot",
|
||||
)
|
||||
widgets = reddit.subreddit("developersIndia").widgets
|
||||
id_card = widgets.id_card
|
||||
|
@ -14,6 +14,10 @@ SECONDS_IN_WEEK = 60 * 60 * 24 * 7
|
||||
# Date Month, Year
|
||||
STRFTIME_FORMAT = "%d %B, %Y"
|
||||
|
||||
import ssl
|
||||
if hasattr(ssl, '_create_unverified_context'):
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
|
||||
class Config:
|
||||
DB_PATH = "db.json"
|
||||
SUBREDDIT = "developersindia"
|
||||
@ -176,6 +180,9 @@ def create_job_post(subreddit) -> Post:
|
||||
flair_id=flair["flair_template_id"],
|
||||
)
|
||||
submission.mod.sticky()
|
||||
submission.mod.distinguish()
|
||||
submission.mod.approve()
|
||||
submission.mod.lock()
|
||||
|
||||
return Post(post_id=submission.id, epoch=submission.created_utc)
|
||||
|
2
job-thread/requirements.txt
Normal file
2
job-thread/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
praw
|
||||
feedparser
|
@ -1 +1,5 @@
|
||||
praw
|
||||
feedparser
|
||||
pyyaml
|
||||
ruamel.yaml
|
||||
requests
|
67
showcase-sunday/main.py
Normal file
67
showcase-sunday/main.py
Normal file
@ -0,0 +1,67 @@
|
||||
import datetime
|
||||
import praw
|
||||
import os
|
||||
|
||||
client_id = os.environ["REDDIT_CLIENT_ID"]
|
||||
client_secret = os.environ["REDDIT_CLIENT_SECRET"]
|
||||
reddit_pass = os.environ["REDDIT_PASSWORD"]
|
||||
username = os.environ["REDDIT_USERNAME"]
|
||||
user_agent = 'Showcase Sunday Megathread'
|
||||
sub = "developersIndia"
|
||||
|
||||
def is_second_sunday():
|
||||
today = datetime.date.today()
|
||||
first_day_of_month = today.replace(day=1)
|
||||
day_of_week = first_day_of_month.weekday()
|
||||
# Calculate the date of the second Sunday
|
||||
second_sunday = first_day_of_month + datetime.timedelta(days=(6 - day_of_week + 7) % 7 + 7)
|
||||
return today == second_sunday
|
||||
|
||||
|
||||
def create_showcase_sunday_megathread(subreddit):
|
||||
flair = next(
|
||||
filter(
|
||||
lambda flair: "Showcase Sunday" in flair["flair_text"],
|
||||
subreddit.flair.link_templates.user_selectable(),
|
||||
)
|
||||
)
|
||||
|
||||
title = "Showcase Sunday Megathread - {month} {year}".format(month=datetime.date.today().strftime("%B"), year=datetime.date.today().year)
|
||||
text = """
|
||||
It's time for our monthly showcase thread where we celebrate the incredible talent in our community. Whether it's an app, a website, a tool, or anything else you've built, we want to see it! Share your latest creations, side projects, or even your work-in-progress.
|
||||
|
||||
Let's inspire each other and celebrate the diverse skills we have. Comment below with details about what you've built, the tech stack used, and any interesting challenges faced along the way.
|
||||
|
||||
**Showcase Sunday thread is posted on the second Sunday of every month. You can find the [schedule on our calendar](https://developersindia.in/events-calendar).**
|
||||
"""
|
||||
|
||||
submission = subreddit.submit(
|
||||
title,
|
||||
selftext=text,
|
||||
flair_id=flair["flair_template_id"],
|
||||
)
|
||||
submission.mod.approve()
|
||||
submission.mod.sticky()
|
||||
submission.mod.distinguish()
|
||||
|
||||
return submission
|
||||
|
||||
def main():
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
username=username,
|
||||
password=reddit_pass,
|
||||
user_agent=user_agent
|
||||
)
|
||||
|
||||
subreddit = reddit.subreddit(sub)
|
||||
|
||||
if is_second_sunday():
|
||||
create_showcase_sunday_megathread(subreddit)
|
||||
print("Showcase Sunday Megathread created successfully!")
|
||||
else:
|
||||
print("Skipping. Not the second Sunday of the month")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
37
showcase-sunday/test_main.py
Normal file
37
showcase-sunday/test_main.py
Normal file
@ -0,0 +1,37 @@
|
||||
import unittest
|
||||
import datetime
|
||||
from main import is_second_sunday
|
||||
import unittest.mock
|
||||
|
||||
|
||||
# Unit test class
|
||||
class TestIsSecondSunday(unittest.TestCase):
|
||||
def test_second_sunday(self):
|
||||
# Define test cases as a list of tuples containing (input_date, expected_result)
|
||||
test_cases = [
|
||||
(datetime.date(2023, 12, 10), True),
|
||||
(datetime.date(2024, 1, 14), True),
|
||||
(datetime.date(2024, 2, 11), True),
|
||||
]
|
||||
|
||||
for input_date, expected_result in test_cases:
|
||||
with unittest.mock.patch("datetime.date") as mock_date:
|
||||
mock_date.today.return_value = input_date
|
||||
self.assertEqual(is_second_sunday(), expected_result)
|
||||
|
||||
def test_not_second_sunday(self):
|
||||
# Define test cases as a list of tuples containing (input_date, expected_result)
|
||||
test_cases = [
|
||||
(datetime.date(2023, 12, 12), False),
|
||||
(datetime.date(2023, 12, 5), False),
|
||||
(datetime.date(2023, 12, 19), False),
|
||||
]
|
||||
|
||||
for input_date, expected_result in test_cases:
|
||||
with unittest.mock.patch('datetime.date') as mock_date:
|
||||
mock_date.today.return_value = input_date
|
||||
self.assertEqual(is_second_sunday(), expected_result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
86
user-flair-usage/main.py
Normal file
86
user-flair-usage/main.py
Normal file
@ -0,0 +1,86 @@
|
||||
import praw
|
||||
from collections import defaultdict
|
||||
import os
|
||||
import json
|
||||
import requests
|
||||
|
||||
client_id = os.environ["REDDIT_CLIENT_ID"]
|
||||
client_secret = os.environ["REDDIT_CLIENT_SECRET"]
|
||||
reddit_pass = os.environ["REDDIT_PASSWORD"]
|
||||
username = os.environ["REDDIT_USERNAME"]
|
||||
webhook_url = os.environ["DISCORD_WEBHOOK_URL"]
|
||||
user_agent = 'User Flair Usage'
|
||||
sub = "developersIndia"
|
||||
|
||||
# Create a Reddit instance
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
username=username,
|
||||
password=reddit_pass,
|
||||
user_agent=user_agent
|
||||
)
|
||||
|
||||
# Select the subreddit
|
||||
subreddit = reddit.subreddit(sub)
|
||||
|
||||
# Initialize a dictionary to count flairs
|
||||
flair_count = defaultdict(int)
|
||||
|
||||
# Iterate over all the flairs
|
||||
emoji_flair_count = 0
|
||||
emoji_flair_users = []
|
||||
for flair in subreddit.flair(limit=None):
|
||||
f = flair['flair_text'].strip()
|
||||
|
||||
if f.startswith(":") or f.endswith(":"):
|
||||
emoji_flair_count += 1
|
||||
emoji_flair_users.append(
|
||||
dict(
|
||||
user=flair['user'],
|
||||
flair_text=f
|
||||
)
|
||||
)
|
||||
else:
|
||||
flair_count[flair['flair_text'].strip()] += 1
|
||||
|
||||
# Convert the dictionary to a list of tuples and sort it by the count
|
||||
sorted_flairs = sorted(flair_count.items(), key=lambda x: x[1], reverse=True)
|
||||
|
||||
# Fetch the list of available user flairs
|
||||
available_flairs = []
|
||||
for flair in subreddit.flair.templates:
|
||||
if not flair['mod_only']:
|
||||
available_flairs.append(flair['text'].strip())
|
||||
|
||||
|
||||
# Initialize a dictionary to count available flairs
|
||||
available_flair_count = defaultdict(int)
|
||||
old_available_flair_count = defaultdict(int)
|
||||
# Iterate over the sorted flairs
|
||||
for flair, count in sorted_flairs:
|
||||
# If the flair is available, increment its count
|
||||
if flair in available_flairs:
|
||||
available_flair_count[flair] += count
|
||||
else:
|
||||
old_available_flair_count[flair] += count
|
||||
|
||||
|
||||
total_count = sum(available_flair_count.values())
|
||||
old_flairs_total_count = sum(old_available_flair_count.values())
|
||||
|
||||
# print(f"Users with un-supported (old) text flairs: {old_flairs_total_count}")
|
||||
# print(f"Users with supported text flairs: {total_count}")
|
||||
# print(f"Users with emoji only flairs: {emoji_flair_count}")
|
||||
# print(f"Total count of user-flairs: {total_count + emoji_flair_count + old_flairs_total_count}")
|
||||
|
||||
data = {
|
||||
'Users with un-supported (old) text flairs': f"**{old_flairs_total_count}**",
|
||||
'Users with supported text flairs': f"**{total_count}**",
|
||||
'Users with emoji only flairs': f"**{emoji_flair_count}**",
|
||||
'Total count of user-flairs': f"**{total_count + emoji_flair_count + old_flairs_total_count}**"
|
||||
}
|
||||
|
||||
formatted_data = "\n".join([f"{k}: {v}" for k, v in data.items()]) # Format the data as a string with each item on a new line
|
||||
|
||||
requests.post(webhook_url, json={"content": formatted_data})
|
2
user-flair-usage/requirements.txt
Normal file
2
user-flair-usage/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
praw
|
||||
requests
|
140
verifier/main.py
Normal file
140
verifier/main.py
Normal file
@ -0,0 +1,140 @@
|
||||
import os
|
||||
import sys
|
||||
import praw
|
||||
import datetime
|
||||
|
||||
client_id = os.environ["REDDIT_CLIENT_ID"]
|
||||
client_secret = os.environ["REDDIT_CLIENT_SECRET"]
|
||||
reddit_pass = os.environ["REDDIT_PASSWORD"]
|
||||
username = os.environ["REDDIT_USERNAME"]
|
||||
sub = "developersIndia"
|
||||
|
||||
|
||||
def get_last_activity_times(reddit, username):
|
||||
user = reddit.redditor(username)
|
||||
|
||||
# Get the user's last comment time in the subreddit
|
||||
last_comment_time = None
|
||||
for comment in user.comments.new(
|
||||
limit=100
|
||||
): # look at the user's 100 most recent comments
|
||||
if comment.subreddit.display_name == sub:
|
||||
last_comment_time = datetime.datetime.fromtimestamp(comment.created_utc)
|
||||
break
|
||||
|
||||
# Get the user's last post creation time and title in the subreddit
|
||||
last_post_time = None
|
||||
last_post_title = None
|
||||
for submission in user.submissions.new(
|
||||
limit=100
|
||||
): # look at the user's 100 most recent posts
|
||||
if submission.subreddit.display_name == sub:
|
||||
last_post_time = datetime.datetime.fromtimestamp(submission.created_utc)
|
||||
last_post_title = submission.title
|
||||
break
|
||||
|
||||
return last_comment_time, last_post_time, last_post_title
|
||||
|
||||
def get_current_flair(reddit, username):
|
||||
subreddit = reddit.subreddit(sub)
|
||||
flair = next(subreddit.flair(username))
|
||||
template = get_flair_template_from_text(reddit, flair["flair_text"])
|
||||
|
||||
if template is None:
|
||||
return None, None
|
||||
|
||||
return flair["flair_text"], template["id"]
|
||||
|
||||
|
||||
def assign_user_flair(reddit, username, flair_text):
|
||||
subreddit = reddit.subreddit(sub)
|
||||
flair = next(subreddit.flair(username))
|
||||
|
||||
template = get_flair_template_from_text(reddit, flair["flair_text"])
|
||||
subreddit.flair.set(username, text=flair_text, flair_template_id=template["id"])
|
||||
|
||||
|
||||
def get_flair_templates(reddit):
|
||||
subreddit = reddit.subreddit(sub)
|
||||
return subreddit.flair.templates
|
||||
|
||||
|
||||
def get_flair_template_from_text(reddit, flair_text):
|
||||
templates = get_flair_templates(reddit)
|
||||
for template in templates:
|
||||
if template["text"] == flair_text:
|
||||
return template
|
||||
|
||||
|
||||
def send_message(reddit, username, flair_text):
|
||||
message_subject = 'Woohoo! You are now a verified member of r/developersIndia! 🚀'
|
||||
message_text = """
|
||||
Hi there,\n
|
||||
As requested your user-flair has now been updated to a verified version. You now have the **{flair}** flair on r/developersIndia ✨\n
|
||||
|
||||
This means that you are now a trusted member of the community and we hope that you will continue to contribute to the community in a positive way. \n
|
||||
|
||||
As a reminder,\n
|
||||
- Make sure to follow [Code of Conduct](https://developersindia.in/code-of-conduct/) before participating in discussions.
|
||||
- Go through [rules](https://www.reddit.com/r/developersIndia/wiki/community-rules/) before creating a new post.\n
|
||||
If you know someone who is active on r/developersIndia, please send them this [wiki on how to get verified](https://www.reddit.com/r/developersIndia/wiki/verified-flair)\n
|
||||
|
||||
\n\n
|
||||
PS: This was an automated messaage, no need to reply. [Reach out to mods](https://www.reddit.com/message/compose?to=/r/developersIndia) if you have any questions.
|
||||
|
||||
Namaste 🙏
|
||||
"""
|
||||
reddit.redditor(username).message(
|
||||
subject=message_subject, message=message_text.format(flair=flair_text), from_subreddit=reddit.subreddit(sub)
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
reddit = praw.Reddit(
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
username=username,
|
||||
password=reddit_pass,
|
||||
user_agent=f"Automod reader by u/{username}",
|
||||
)
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: python main.py <username> <flair_text>")
|
||||
sys.exit(1)
|
||||
|
||||
# get username from CLI args
|
||||
reddit_username = sys.argv[1]
|
||||
# get flair text from CLI args
|
||||
flair_text = sys.argv[2]
|
||||
|
||||
# get last activity times
|
||||
print(f"Getting last activity times for {reddit_username}...")
|
||||
last_comment_time, last_post_time, last_post_title = get_last_activity_times(reddit, reddit_username)
|
||||
if last_comment_time is not None:
|
||||
print(f"{reddit_username}'s last comment time on developersIndia was {last_comment_time}")
|
||||
if last_post_time is not None:
|
||||
print(f"{reddit_username}'s last post on developersIndia was \"{last_post_title}\" on {last_post_time}")
|
||||
|
||||
|
||||
# get current flair
|
||||
current_flair_text, current_flair_template_id = get_current_flair(reddit, reddit_username)
|
||||
if current_flair_text is None:
|
||||
print(f"{reddit_username} does not have a flair on r/developersIndia")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print(f"{reddit_username}'s current flair is \"{current_flair_text}\", template id: {current_flair_template_id}")
|
||||
|
||||
# ask for user input
|
||||
user_input = input(f"Do you want to verify {reddit_username}? [Y/n]: ")
|
||||
if user_input.lower() != 'y':
|
||||
print("Cancelled verification operation.")
|
||||
sys.exit(0)
|
||||
|
||||
assign_user_flair(reddit, reddit_username, flair_text)
|
||||
print(f"Updated {reddit_username}'s flair to \"{flair_text}\"")
|
||||
send_message(reddit, reddit_username, flair_text)
|
||||
print(f"Sent verification confirmation message to {reddit_username}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
verifier/requirements.txt
Normal file
1
verifier/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
praw
|
Reference in New Issue
Block a user