├── .GitImages
├── Anonymisc_00.png
├── Anonymisc_01.png
├── Flairmail0.png
├── Newsletterly_cover1.png
├── Newsletterly_cover2.png
├── README.md
├── RPIReddit256.png
├── Schedulizer00.png
├── Schedulizer01.png
├── Schedulizer02.png
├── Schedulizer03.png
├── SchedulizerM_00.png
├── SchedulizerM_01.png
├── SchedulizerM_02.png
├── SchedulizerM_03.png
├── SubredditBirthday_logo.svg
├── SubredditBirthdays000.ico
├── SubredditBirthdays000.png
├── SubredditBirthdays001.png
├── SubredditBirthdays002.ico
├── SubredditBirthdays002.png
├── SubredditBirthdays003.png
├── Superclippy256.png
├── Superclippy_logo.svg
├── T3_logo.ico
├── T3_logo.svg
├── T3_logo_256.png
├── UN_logo.ico
├── UN_logo.svg
├── UN_logo_2048.png
├── UN_logo_256.png
├── newsletterly_demo_multiplecompose.png
├── newsletterly_demo_multipleresponse.png
├── newsletterly_demo_newposts.png
├── newsletterly_demo_purgedrop.png
├── newsletterly_demo_purgekeep.png
├── newsletterly_demo_report.png
├── newsletterly_demo_subscribe.png
├── newsletterly_demo_subscribemultiple.png
├── redditcakerender128.png
├── tabblet256.png
├── tabbleto256.png
├── timesearch_logo.ico
├── timesearch_logo.svg
├── timesearch_logo_2048.png
└── timesearch_logo_256.png
├── .gitattributes
├── .gitignore
├── CONTACT.md
├── LICENSE.txt
├── LockFinder
├── README.md
├── lockfinder.db
└── lockfinder.py
├── Newsletterbot
├── Newsletterly_x.py
└── README.md
├── README.md
├── SB&U
└── sbu.py
├── SubredditBirthdays
├── Novemberspam
│ ├── !Novemberspam.txt
│ ├── 5.png
│ ├── 6.png
│ ├── Lopidider.png
│ ├── Netciowhitec.png
│ ├── Retcentsira.png
│ ├── Ythlebonro.png
│ └── crezalamom.png
├── README.md
├── Slides
│ ├── 0100.png
│ ├── 0200.png
│ ├── 0300.png
│ ├── 0310.png
│ ├── 0400.png
│ ├── 0500.png
│ ├── 0600.png
│ ├── 0800.png
│ ├── 0900.png
│ ├── 1000.png
│ ├── 1010.png
│ ├── 1100.png
│ ├── 1200.png
│ ├── 1300.png
│ └── 9999.png
├── amageddon
│ ├── Oe0QG1o.png
│ ├── XoL3pdJ.png
│ ├── iama_newmods.PNG
│ ├── modtalk.txt
│ ├── outfile.txt
│ ├── quar_05sep2015.txt
│ ├── quar_06aug2015.txt
│ └── quar_13sep2015.txt
├── amageddontracker.py
├── launch.bat
├── misc
│ ├── banned_quarantined.txt
│ ├── hiddentimes.txt
│ ├── misc_notes.txt
│ ├── restricted_links.html
│ └── restricted_subs.txt
├── sb.py
└── show
│ ├── README.md
│ ├── duplicates.txt
│ ├── jumble-nsfw.txt
│ ├── jumble.txt
│ ├── missing.txt
│ └── statistics.txt
├── Usernames
├── README.md
├── gui.pyw
├── launch.bat
├── show
│ └── stats.txt
├── todo-4char.txt
├── un.py
└── un4.py
├── _old
├── Anonymisc
│ ├── README.md
│ ├── anonymisc.db
│ └── anonymisc.py
├── AutoContributor
│ ├── README.md
│ └── autocontributor.py
├── Automail
│ ├── README.md
│ └── automail.py
├── BeetlejuiceMachine
│ ├── README.md
│ └── beetlejuicemachine.py
├── BetterNew
│ └── betternew.py
├── BioWiki
│ ├── README.md
│ ├── biowiki.db
│ └── biowiki.py
├── ContributorFile
│ ├── README.md
│ ├── contributorfile.py
│ └── names.txt
├── Countries
│ ├── README.md
│ ├── countries.py
│ ├── country_list.txt
│ └── launch.bat
├── Dailyposter
│ ├── README.md
│ └── dailyposter.py
├── DeMobile
│ ├── README.md
│ └── demobile.py
├── DelayBot
│ ├── README.md
│ └── delaybot.py
├── DelayBotT
│ ├── README.md
│ └── delaybotT.py
├── DeleteMe
│ ├── README.md
│ └── deleteme.py
├── DeleteMeT
│ ├── README.md
│ └── deletemet.py
├── DeletedAuthors
│ ├── README.md
│ └── deletedauthors.py
├── EightBall
│ ├── README.md
│ └── eightball.py
├── ErroneousQuotes
│ ├── README.md
│ └── erroneousquotes.py
├── FlairMail
│ ├── README.md
│ └── flairmail.py
├── FlairTimer
│ ├── README.md
│ ├── flairtimer.py
│ └── flairtimer_threestates.py
├── Flaircounting
│ ├── README.md
│ ├── flaircounting.py
│ └── userflair.txt
├── HashBot
│ ├── README.md
│ └── hashbot.py
├── HerokuBot
│ ├── Procfile
│ ├── README.md
│ ├── git.zip
│ ├── herokubot.py
│ ├── requirements.txt
│ └── runtime.txt
├── KarmaDecayRepost
│ ├── kdr.db
│ └── kdr.py
├── Lengthflair
│ ├── README.md
│ └── lengthflair.py
├── LumioseLottery
│ ├── README.md
│ └── lumiose.py
├── MailForwarding
│ ├── README.md
│ └── mailforwarding.py
├── MailMe
│ ├── README.md
│ └── mailme.py
├── MailMePosts
│ └── README.md
├── MailMeUser
│ ├── README.md
│ └── mailmeuser.py
├── MessageArchive
│ ├── README.md
│ └── messagearchive.py
├── MoreFrom
│ ├── README.md
│ ├── morefrom.py
│ └── sql.db
├── Novella
│ ├── README.md
│ ├── novella.py
│ └── sql.db
├── Nsal
│ ├── README.md
│ ├── nsal.py
│ └── sql.db
├── Numberwang
│ ├── README.md
│ ├── numberwang.py
│ └── sql.db
├── Oldflair
│ ├── README.md
│ └── oldflair.py
├── OneThenDone
│ ├── README.md
│ ├── onethendone.py
│ └── sql.db
├── Overlap
│ ├── README.md
│ ├── goldtesting.json
│ ├── overlap.py
│ └── redditdev.json
├── PFStickyComments
│ ├── README.md
│ ├── personalfinance.css
│ ├── stickycomments.db
│ ├── stickycomments.py
│ └── stickycomments_individual.py
├── Pointreminder
│ ├── README.md
│ ├── pointreminder.py
│ └── sql.db
├── PointsBot
│ ├── README.md
│ ├── ScoreboardAddUser.py
│ ├── pointsbot.py
│ ├── pointsbot_scoreboard.py
│ └── sql.db
├── Politician
│ ├── README.md
│ ├── blacklist.txt
│ ├── full.txt
│ ├── nick.txt
│ ├── politician.py
│ ├── sql.db
│ └── subreddit.txt
├── QuoteMe
│ ├── README.md
│ ├── quoteme.py
│ └── sql.db
├── R4R
│ ├── R4R.py
│ ├── README.md
│ ├── results.txt
│ └── resultsummary.txt
├── RafflerC
│ ├── README.md
│ ├── raffler.py
│ └── result.txt
├── RankFlair
│ ├── README.md
│ ├── rankflair.py
│ └── rankflair_gws.py
├── Redmash
│ ├── #goldtesting_breakdown.json
│ ├── #tifu_breakdown.json
│ ├── @erktheerk_breakdown.json
│ ├── @goldensights_breakdown.json
│ ├── README.md
│ └── redmash_db.py
├── ReplyBot
│ ├── README.md
│ ├── replybot.py
│ └── replybot_randwiki.py
├── ReplyDict
│ ├── README.md
│ ├── replydict.py
│ └── snakes.txt
├── ReplyPosts
│ ├── README.md
│ └── replyposts.py
├── Schedulizer-ModTeam
│ ├── README.md
│ └── schedulizerm.py
├── Schedulizer
│ ├── README.md
│ ├── past.txt
│ ├── schedulebot.py
│ ├── scheduleclient.py
│ └── upcoming.txt
├── Scrubber
│ ├── README.md
│ └── scrubber.py
├── SourceExcel
│ ├── README.md
│ └── sourceexcel.py
├── SourceIt
│ ├── README.md
│ ├── s.py
│ └── sourceit.py
├── StateOfTheNetwork
│ ├── 02Nov2014-09-58-43.txt
│ ├── README.md
│ ├── imaginary.txt
│ ├── stateofthenetwork.py
│ └── test.txt
├── Stylist
│ ├── Day.txt
│ ├── Midnight.txt
│ ├── Night.txt
│ ├── README.md
│ └── stylist.py
├── SubDump
│ ├── README.md
│ └── subdump.py
├── SubDumpPost
│ └── README.md
├── SubmissionRatio
│ ├── README.md
│ ├── sql.db
│ ├── submissionratio.py
│ └── wiki.txt
├── SubmissionRatioAS
│ ├── AddUser.py
│ ├── ChangeUser.py
│ ├── README.md
│ ├── submissionratio.py
│ └── wiki.txt
├── SubmissionScoreTracker
│ ├── README.md
│ ├── submissionscoretracker.py
│ ├── t3_3f36wr.txt
│ ├── t3_3fx2au.txt
│ ├── t3_3hs3v4.txt
│ └── t3_3inm1c.txt
├── SuperClippy
│ ├── README.md
│ ├── boot.wav
│ ├── olddata
│ │ ├── Clippy_Flair_Reminders.txt
│ │ ├── Clippy_Function.txt
│ │ ├── Clippy_Points_V3.txt
│ │ ├── Clippy_Welcome.txt
│ │ ├── db_flair.db
│ │ ├── db_points.db
│ │ ├── db_reference.db
│ │ └── db_welcome.db
│ ├── reference.txt
│ ├── superclippy.db
│ └── superclippy.py
├── ThreadReader
│ ├── README.md
│ ├── t3_2kdpba.txt
│ ├── t3_2l1v7k.txt
│ └── threadreader.py
├── TitleNames
│ ├── README.md
│ ├── sql.db
│ └── titlenames.py
├── ToTheMoon
│ ├── README.md
│ ├── sql.db
│ └── tothemoon.py
├── URLChangeV2
│ ├── README.md
│ ├── sql.db
│ └── urlchangev2.py
├── URLchange
│ ├── README.md
│ ├── sql.db
│ └── urlchange.py
├── UnreadWatch
│ └── unreadwatch.py
├── WeeklyUnsolved
│ ├── README.md
│ ├── results_2015Aug24.txt
│ ├── weeklyflairmanagers.py
│ └── weeklyunsolved.py
├── WelcomeBot
│ ├── README.md
│ ├── example.png
│ └── welcomebot.py
├── Wikiname
│ ├── README.md
│ └── wikiname.py
└── bot_template.py
├── bot3.py
└── bot4.py
/.GitImages/Anonymisc_00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Anonymisc_00.png
--------------------------------------------------------------------------------
/.GitImages/Anonymisc_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Anonymisc_01.png
--------------------------------------------------------------------------------
/.GitImages/Flairmail0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Flairmail0.png
--------------------------------------------------------------------------------
/.GitImages/Newsletterly_cover1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Newsletterly_cover1.png
--------------------------------------------------------------------------------
/.GitImages/Newsletterly_cover2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Newsletterly_cover2.png
--------------------------------------------------------------------------------
/.GitImages/README.md:
--------------------------------------------------------------------------------
1 | This folder will contain images that may be embedded in other places
--------------------------------------------------------------------------------
/.GitImages/RPIReddit256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/RPIReddit256.png
--------------------------------------------------------------------------------
/.GitImages/Schedulizer00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Schedulizer00.png
--------------------------------------------------------------------------------
/.GitImages/Schedulizer01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Schedulizer01.png
--------------------------------------------------------------------------------
/.GitImages/Schedulizer02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Schedulizer02.png
--------------------------------------------------------------------------------
/.GitImages/Schedulizer03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Schedulizer03.png
--------------------------------------------------------------------------------
/.GitImages/SchedulizerM_00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SchedulizerM_00.png
--------------------------------------------------------------------------------
/.GitImages/SchedulizerM_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SchedulizerM_01.png
--------------------------------------------------------------------------------
/.GitImages/SchedulizerM_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SchedulizerM_02.png
--------------------------------------------------------------------------------
/.GitImages/SchedulizerM_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SchedulizerM_03.png
--------------------------------------------------------------------------------
/.GitImages/SubredditBirthdays000.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SubredditBirthdays000.ico
--------------------------------------------------------------------------------
/.GitImages/SubredditBirthdays000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SubredditBirthdays000.png
--------------------------------------------------------------------------------
/.GitImages/SubredditBirthdays001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SubredditBirthdays001.png
--------------------------------------------------------------------------------
/.GitImages/SubredditBirthdays002.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SubredditBirthdays002.ico
--------------------------------------------------------------------------------
/.GitImages/SubredditBirthdays002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SubredditBirthdays002.png
--------------------------------------------------------------------------------
/.GitImages/SubredditBirthdays003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/SubredditBirthdays003.png
--------------------------------------------------------------------------------
/.GitImages/Superclippy256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/Superclippy256.png
--------------------------------------------------------------------------------
/.GitImages/T3_logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/T3_logo.ico
--------------------------------------------------------------------------------
/.GitImages/T3_logo_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/T3_logo_256.png
--------------------------------------------------------------------------------
/.GitImages/UN_logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/UN_logo.ico
--------------------------------------------------------------------------------
/.GitImages/UN_logo_2048.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/UN_logo_2048.png
--------------------------------------------------------------------------------
/.GitImages/UN_logo_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/UN_logo_256.png
--------------------------------------------------------------------------------
/.GitImages/newsletterly_demo_multiplecompose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/newsletterly_demo_multiplecompose.png
--------------------------------------------------------------------------------
/.GitImages/newsletterly_demo_multipleresponse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/newsletterly_demo_multipleresponse.png
--------------------------------------------------------------------------------
/.GitImages/newsletterly_demo_newposts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/newsletterly_demo_newposts.png
--------------------------------------------------------------------------------
/.GitImages/newsletterly_demo_purgedrop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/newsletterly_demo_purgedrop.png
--------------------------------------------------------------------------------
/.GitImages/newsletterly_demo_purgekeep.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/newsletterly_demo_purgekeep.png
--------------------------------------------------------------------------------
/.GitImages/newsletterly_demo_report.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/newsletterly_demo_report.png
--------------------------------------------------------------------------------
/.GitImages/newsletterly_demo_subscribe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/newsletterly_demo_subscribe.png
--------------------------------------------------------------------------------
/.GitImages/newsletterly_demo_subscribemultiple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/newsletterly_demo_subscribemultiple.png
--------------------------------------------------------------------------------
/.GitImages/redditcakerender128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/redditcakerender128.png
--------------------------------------------------------------------------------
/.GitImages/tabblet256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/tabblet256.png
--------------------------------------------------------------------------------
/.GitImages/tabbleto256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/tabbleto256.png
--------------------------------------------------------------------------------
/.GitImages/timesearch_logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/timesearch_logo.ico
--------------------------------------------------------------------------------
/.GitImages/timesearch_logo_2048.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/timesearch_logo_2048.png
--------------------------------------------------------------------------------
/.GitImages/timesearch_logo_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/.GitImages/timesearch_logo_256.png
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | *.psd binary
13 | *.zip binary
14 | *.db binary
15 | *.png binary
16 | *.jpg binary
17 | *.ico binary
18 | *.exe binary
19 |
20 | # Standard to msysgit
21 | *.doc diff=astextplain
22 | *.DOC diff=astextplain
23 | *.docx diff=astextplain
24 | *.DOCX diff=astextplain
25 | *.dot diff=astextplain
26 | *.DOT diff=astextplain
27 | *.pdf diff=astextplain
28 | *.PDF diff=astextplain
29 | *.rtf diff=astextplain
30 | *.RTF diff=astextplain
31 |
--------------------------------------------------------------------------------
/CONTACT.md:
--------------------------------------------------------------------------------
1 | Contact
2 | =======
3 |
4 | Please do not open pull requests without talking to me first. For serious issues and bugs, open a GitHub issue. If you just have a question, please send an email to `contact@voussoir.net`. For other contact options, see [voussoir.net/#contact](https://voussoir.net/#contact).
5 |
6 | I also mirror my work to other git services:
7 |
8 | - https://github.com/voussoir
9 |
10 | - https://gitlab.com/voussoir
11 |
12 | - https://codeberg.org/voussoir
13 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2022, Ethan Dalool aka voussoir
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/LockFinder/README.md:
--------------------------------------------------------------------------------
1 | LockFinder
2 | ==========
3 |
4 | This bot finds posts in [/r/all/hot](https://www.reddit.com/r/all/hot/) that have been locked, and makes a submission to [/r/OpenAndGenuine](https://www.reddit.com/r/OpenAndGenuine), using [r.go1dfish.me](http://r.go1dfish.me/hot) to display deleted comments.
--------------------------------------------------------------------------------
/LockFinder/lockfinder.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/LockFinder/lockfinder.db
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | reddit
2 | ======
3 |
4 | A collection of reddit bots and utilities by /u/GoldenSights. I no longer write new bots.
5 |
6 | ---
7 |
8 | ## Before running any bots
9 |
10 | **Use descriptive useragents**. Include a username by which admins can identify you. Tell what your bot is doing and why. Convince the admins that you aren't wasting their bandwidth. Inadequate useragents may cause your bot to get logged out in the middle of your session, and the program will crash. Abusive useragents can get your bot shadowbanned.
11 |
12 | [Reddit API rules](https://github.com/reddit/reddit/wiki/API)
13 |
14 | ---
15 |
16 | ## Bot.py
17 |
18 | To standardize and simplify authentication, all bots rely on `bot.py`. Please download my copy and follow the instructions.
19 |
--------------------------------------------------------------------------------
/SB&U/sbu.py:
--------------------------------------------------------------------------------
1 | import sqlite3
2 | import sys
3 | import time
4 | import traceback
5 |
6 | sys.path.append('..\\SubredditBirthdays')
7 | import sb
8 |
9 | sys.path.append('..\\Usernames')
10 | import un4
11 |
12 | newnames_sql = sqlite3.connect('..\\Usernames\\newnames.db')
13 | newnames_cur = newnames_sql.cursor()
14 |
15 | def migrate():
16 | resume_from = int(open('latest.txt', 'r').read().strip())
17 | sb.cur.execute(
18 | 'SELECT name, created FROM subreddits WHERE subreddit_type == 8 AND created >= ? ORDER BY created ASC',
19 | [resume_from]
20 | )
21 | f = sb.cur.fetchall()
22 | resume_from = f[-1][1]
23 | f = [x[0] for x in f]
24 | for x in f:
25 | newnames_cur.execute('INSERT INTO names3 VALUES(?)', [x])
26 | print('Moved %d records' % len(f))
27 | newnames_sql.commit()
28 | open('latest.txt', 'w').write(str(resume_from))
29 |
30 | def run_newnames():
31 | while True:
32 | try:
33 | if newnames_cur.execute('SELECT count(*) from names3').fetchone() == 0:
34 | break
35 | un4.process_from_database('..\\Usernames\\newnames.db', 'names3', 'name', True)
36 | except sqlite3.OperationalError:
37 | raise
38 | except Exception:
39 | traceback.print_exc()
40 | time.sleep(60)
41 |
42 | def run_modernize():
43 | while True:
44 | try:
45 | sb.modernize(limit=10000)
46 | except Exception:
47 | traceback.print_exc()
48 | time.sleep(60)
49 |
--------------------------------------------------------------------------------
/SubredditBirthdays/Novemberspam/!Novemberspam.txt:
--------------------------------------------------------------------------------
1 | keys = ['Jan2006', 'Feb2006', 'Mar2006', 'Apr2006', 'May2006', 'Jun2006', 'Jul2006', 'Oct2006', 'Mar2007', 'Apr2007', 'May2007', 'Aug2007', 'Sep2007', 'Jan2008', 'Feb2008', 'Mar2008', 'Apr2008', 'May2008', 'Jun2008', 'Jul2008', 'Aug2008', 'Sep2008', 'Oct2008', 'Nov2008', 'Dec2008', 'Jan2009', 'Feb2009', 'Mar2009', 'Apr2009','May2009', 'Jun2009', 'Jul2009', 'Aug2009', 'Sep2009', 'Oct2009', 'Nov2009', 'Dec2009', 'Jan2010', 'Feb2010', 'Mar2010', 'Apr2010', 'May2010', 'Jun2010', 'Jul2010', 'Aug2010', 'Sep2010', 'Oct2010', 'Nov2010', 'Dec2010', 'Jan2011', 'Feb2011', 'Mar2011', 'Apr2011', 'May2011', 'Jun2011', 'Jul2011', 'Aug2011', 'Sep2011', 'Oct2011', 'Nov2011', 'Dec2011', 'Jan2012', 'Feb2012', 'Mar2012', 'Apr2012', 'May2012', 'Jun2012', 'Jul2012', 'Aug2012', 'Sep2012', 'Oct2012', 'Nov2012', 'Dec2012', 'Jan2013', 'Feb2013', 'Mar2013', 'Apr2013', 'May2013', 'Jun2013', 'Jul2013', 'Aug2013', 'Sep2013', 'Oct2013', 'Nov2013', 'Dec2013', 'Jan2014', 'Feb2014', 'Mar2014', 'Apr2014', 'May2014', 'Jun2014', 'Jul2014', 'Aug2014', 'Sep2014', 'Oct2014', 'Nov2014', 'Dec2014']
2 |
3 | vals = [2, 20, 2, 4, 1, 1, 3, 1, 1, 1, 1, 2, 5, 306, 60, 543, 225, 616, 1546, 1523, 1578, 1423, 1257, 1612, 1891, 2147, 2154, 2286, 2411, 2412, 2382, 2954, 3051, 3240, 3794, 2762, 2090, 2424, 3448, 4039, 4115, 3885, 3841, 4563, 4974, 1816, 1631, 1924, 2024, 2381, 2253, 2579, 2713, 3151, 3380, 4144, 5685, 5373, 5571, 5383, 5967, 8577, 8196, 8120, 8722, 8752, 9841, 10929, 12585, 11963, 12632, 11186, 11122, 13547, 13376, 13253, 15094, 14401, 14577, 15264, 14621, 13479, 14028, 14514, 15345, 23059, 26502, 23460, 19223, 19972, 17815, 21154, 22606, 22320, 23701, 40752, 6670]
4 |
5 | plotdict('test', [keys[-15:], vals[-15:]])
6 |
7 |
8 | 34czq, 1415059583, Nov 04 2014 00:06:23 UTC, 0, notuninteresting.................1
9 | 35246, 1416700731, Nov 22 2014 23:58:51 UTC, 0, pacmanvsalgieriwbc...............1
10 |
11 |
12 |
13 |
14 | Reddit was hit with massive account+subreddit creation spam for three days during November 2014 [OC]
15 |
16 | spam begins (roughly)
17 |
18 | ID | Unix time | Human time | nsfw | Name
19 | :- | -: | :- | :- | :-
20 | `34nab` | `1416340781` | `Nov 18 2014 19:59:41 UTC` | `no` | /r/aDTALMel
21 | `351ic` | `1416613575` | `Nov 21 2014 23:46:15 UTC` | `no` | /r/SerVic24
22 | spam ends (roughly)
23 |
24 | subreddits created: 18433 (Not all spam, obviously!)
25 |
26 |
27 |
28 | Here are some surviving subreddits. Notice that the creators names are the same as the subreddit, so there was an equal amount of account spam.
29 | /r/crezalamom - [image](https://raw.githubusercontent.com/voussoir/reddit/master/SubredditBirthdays/Novemberspam/crezalamom.png)
30 | /r/netciowhitec - [image](https://raw.githubusercontent.com/voussoir/reddit/master/SubredditBirthdays/Novemberspam/Netciowhitec.png)
31 | /r/ythlebonro - [image](https://raw.githubusercontent.com/voussoir/reddit/master/SubredditBirthdays/Novemberspam/Ythlebonro.png)
32 | /r/lopidider - [image](https://raw.githubusercontent.com/voussoir/reddit/master/SubredditBirthdays/Novemberspam/Lopidider.png)
33 | /r/retcentsira - [image](https://raw.githubusercontent.com/voussoir/reddit/master/SubredditBirthdays/Novemberspam/Retcentsira.png)
34 |
35 | Here is a small glimpse at the less fortunate
36 | /r/rephemouti
37 | /r/payrinomvi
38 | /r/bergconnene
39 | /r/anbarroti
40 | /r/abensoyto
41 | /r/guivoyteame
42 | /r/eladjucorn
43 | /r/feredoughle
44 | /r/exuphcani
45 | /r/scanevrymap
46 | /r/workdimadel
47 | /r/funbtensuppsi
48 | /r/signtrifhufa
49 | /r/imbibole
50 | /r/blowlyaprehon
51 | /r/matslimebe
52 | /r/terrbatelva
53 | /r/blacgunburec
54 | /r/terfpansembci
55 | /r/tasenperftas
56 | /r/seltheoghousal
57 | /r/tiebackquanchu
58 | /r/piefrishixcomp
59 | /r/confortperlo
60 | /r/ewiretov
61 | /r/ulzimtutatb
62 | /r/dhonookacar
63 | /r/distsmokaddia
64 | /r/spilnenese
65 | /r/volcicere
66 |
67 | _____
68 |
69 | Tools used: Python + PRAW. Images rendered from postscript, exported by the python module "tkinter".
70 | Further information can be found [here](https://github.com/voussoir/reddit/tree/master/SubredditBirthdays)
--------------------------------------------------------------------------------
/SubredditBirthdays/Novemberspam/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Novemberspam/5.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Novemberspam/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Novemberspam/6.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Novemberspam/Lopidider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Novemberspam/Lopidider.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Novemberspam/Netciowhitec.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Novemberspam/Netciowhitec.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Novemberspam/Retcentsira.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Novemberspam/Retcentsira.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Novemberspam/Ythlebonro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Novemberspam/Ythlebonro.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Novemberspam/crezalamom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Novemberspam/crezalamom.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0100.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0200.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0300.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0310.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0400.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0500.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0600.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0600.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0800.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0800.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/0900.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/0900.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/1000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/1000.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/1010.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/1010.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/1100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/1100.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/1200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/1200.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/1300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/1300.png
--------------------------------------------------------------------------------
/SubredditBirthdays/Slides/9999.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/Slides/9999.png
--------------------------------------------------------------------------------
/SubredditBirthdays/amageddon/Oe0QG1o.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/amageddon/Oe0QG1o.png
--------------------------------------------------------------------------------
/SubredditBirthdays/amageddon/XoL3pdJ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/amageddon/XoL3pdJ.png
--------------------------------------------------------------------------------
/SubredditBirthdays/amageddon/iama_newmods.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/amageddon/iama_newmods.PNG
--------------------------------------------------------------------------------
/SubredditBirthdays/amageddon/quar_06aug2015.txt:
--------------------------------------------------------------------------------
1 | I can not guarantee this list is 100% complete. I also can not guarantee that all entries are fresh bans from this morning, but they are relatively new.
2 |
3 | I don't sympathize with these subreddits, but I think the admins should have announced this list.
4 |
5 | #banned
6 |
7 | name | subscribers
8 | :- | -:
9 | /r/CoonTown | 20888
10 | /r/Lolicons | 12339
11 | /r/Pomf | 7360
12 | /r/LoliShota | 3169
13 | /r/WatchNiggersDie | 590
14 | /r/TacticalLolis | 516
15 | /r/LoliFeet | 279
16 | /r/TrueLoli | 237
17 | /r/Rule34NoCensorship | 135
18 | /r/TheLoliLocker | 84
19 | /r/bestofcoontown | 53
20 | /r/lolipee | 32
21 | /r/18datingwomenforsex | 29
22 | /r/FreePSNCodesGenerator | 21
23 | /r/jart | 10
24 | /r/badgirl | 9
25 | /r/letter | 8
26 | /r/ufc190rouvscour | 7
27 | /r/SWBFSWBFSWBFSWBF | 7
28 | /r/RapingEllenPao | 7
29 | /r/Xforce | 7
30 | /r/itachi_circlejerk | 7
31 | /r/FakeMadeReal | 6
32 | /r/MI5 | 6
33 | /r/impostors | 5
34 | /r/BeatingEllenPao | 5
35 | /r/indymedia | 5
36 | /r/Sakura | 5
37 | /r/reactiongiffles | 4
38 | /r/Low | 4
39 | /r/bluemonkeys | 4
40 | /r/Obito | 4
41 |
42 |
43 |
44 |
45 | #quarantined
46 |
47 | name | subscribers
48 | :- | -:
49 | /r/SHHHHHEEEEEEEEIIIITT | 16552
50 | /r/BlackFathers | 9770
51 | /r/GreatApes | 4755
52 | /r/AntiPOZi | 2819
53 | /r/TrayvonMartin | 1340
54 | /r/BlackCrime | 1257
55 | /r/WhitesWinFights | 889
56 | /r/ferguson | 799
57 | /r/KikeTown | 744
58 | /r/N1GGERS | 641
59 | /r/Ben_Garrison | 394
60 | /r/USBlackCulture | 308
61 | /r/NiggerDrama | 331
62 | /r/NiggerFacts | 307
63 | /r/niggersstories | 284
64 | /r/Chimpout | 273
65 | /r/niggervideos | 271
66 | /r/niggerspics | 268
67 | /r/funnyniggers | 213
68 | /r/GreatAbos | 204
69 | /r/didntdonuffins | 201
70 | /r/NiggersNews | 199
71 | /r/GoEbola | 167
72 | /r/WorldStarHP | 167
73 | /r/JustBlackGirlThings | 160
74 | /r/NiggerCartoons | 157
75 | /r/NiggerMythology | 153
76 | /r/gibsmedat | 152
77 | /r/teenapers | 146
78 | /r/WTFniggers | 141
79 | /r/NiggersTIL | 138
80 | /r/TheRacistRedPill | 137
81 | /r/Detoilet | 129
82 | /r/RacistNiggers | 122
83 | /r/NiggersGIFs | 117
84 | /r/apewrangling | 108
85 | /r/Apefrica | 108
86 | /r/muhdick | 106
87 | /r/Hatepire | 94
88 | /r/DrawPeople | 96
89 | /r/Horsey | 88
90 | /r/NiggerDocumentaries | 83
91 | /r/chimpmusic | 81
92 | /r/NegroFree | 77
93 | /r/ChimpinAintEasy | 73
94 | /r/niggerhistorymonth | 65
95 | /r/ChimpireMETA | 64
96 | /r/ChimpireOfftopic | 58
97 | /r/BlackHusbands | 50
98 | /r/RacoonsAreNiggers | 45
99 | /r/blackpeoplehate | 37
100 | /r/NiggerSafari | 16
101 | /r/TIL_4_Niggers | 13
102 | /r/whitesarecriminals | 12
103 | /r/FreddieGray | 12
104 | /r/transrace | 8
105 | /r/LedariusWilliams | 5
106 | /r/Jason_Harrison | 4
107 | /r/IsmaaiylBrinsley | 3
108 | /r/Al_Sharpton | 2
109 | /r/DigitalAgeNiggers | 2
110 | /r/Ismaaiyl_Brinsley | 2
111 | /r/Jordan_Mitchell | 2
112 | /r/terencewalker | 2
113 | /r/NiggerNet | 1
114 | /r/thaddeusmccarroll | 1
115 | /r/VonderritMyers | 1
116 | /r/WilliamChapman | 1
117 | /r/WhiteSmite | 1
--------------------------------------------------------------------------------
/SubredditBirthdays/launch.bat:
--------------------------------------------------------------------------------
1 | echo off
2 | cls
3 | python -i sb.py
--------------------------------------------------------------------------------
/SubredditBirthdays/misc/banned_quarantined.txt:
--------------------------------------------------------------------------------
1 | I can not guarantee this list is 100% complete. I also can not guarantee that all entries are fresh bans from this morning, but they are relatively new.
2 |
3 | I don't sympathize with these subreddits, but I think the admins should have announced this list.
4 |
5 | #banned
6 |
7 | name | subscribers
8 | :- | -:
9 | /r/CoonTown | 20888
10 | /r/Lolicons | 12339
11 | /r/Pomf | 7360
12 | /r/LoliShota | 3169
13 | /r/WatchNiggersDie | 590
14 | /r/TacticalLolis | 516
15 | /r/LoliFeet | 279
16 | /r/TrueLoli | 237
17 | /r/Rule34NoCensorship | 135
18 | /r/TheLoliLocker | 84
19 | /r/bestofcoontown | 53
20 | /r/lolipee | 32
21 | /r/18datingwomenforsex | 29
22 | /r/FreePSNCodesGenerator | 21
23 | /r/jart | 10
24 | /r/badgirl | 9
25 | /r/letter | 8
26 | /r/ufc190rouvscour | 7
27 | /r/SWBFSWBFSWBFSWBF | 7
28 | /r/RapingEllenPao | 7
29 | /r/Xforce | 7
30 | /r/itachi_circlejerk | 7
31 | /r/FakeMadeReal | 6
32 | /r/MI5 | 6
33 | /r/impostors | 5
34 | /r/BeatingEllenPao | 5
35 | /r/indymedia | 5
36 | /r/Sakura | 5
37 | /r/reactiongiffles | 4
38 | /r/Low | 4
39 | /r/bluemonkeys | 4
40 | /r/Obito | 4
41 |
42 |
43 |
44 |
45 | #quarantined
46 |
47 | name | subscribers
48 | :- | -:
49 | /r/SHHHHHEEEEEEEEIIIITT | 16552
50 | /r/BlackFathers | 9770
51 | /r/GreatApes | 4755
52 | /r/AntiPOZi | 2819
53 | /r/TrayvonMartin | 1340
54 | /r/BlackCrime | 1257
55 | /r/WhitesWinFights | 889
56 | /r/ferguson | 799
57 | /r/KikeTown | 744
58 | /r/N1GGERS | 641
59 | /r/Ben_Garrison | 394
60 | /r/USBlackCulture | 308
61 | /r/NiggerDrama | 331
62 | /r/NiggerFacts | 307
63 | /r/niggersstories | 284
64 | /r/Chimpout | 273
65 | /r/niggervideos | 271
66 | /r/niggerspics | 268
67 | /r/funnyniggers | 213
68 | /r/GreatAbos | 204
69 | /r/didntdonuffins | 201
70 | /r/NiggersNews | 199
71 | /r/GoEbola | 167
72 | /r/WorldStarHP | 167
73 | /r/JustBlackGirlThings | 160
74 | /r/NiggerCartoons | 157
75 | /r/NiggerMythology | 153
76 | /r/gibsmedat | 152
77 | /r/teenapers | 146
78 | /r/WTFniggers | 141
79 | /r/NiggersTIL | 138
80 | /r/TheRacistRedPill | 137
81 | /r/Detoilet | 129
82 | /r/RacistNiggers | 122
83 | /r/NiggersGIFs | 117
84 | /r/apewrangling | 108
85 | /r/Apefrica | 108
86 | /r/muhdick | 106
87 | /r/Hatepire | 94
88 | /r/DrawPeople | 96
89 | /r/Horsey | 88
90 | /r/NiggerDocumentaries | 83
91 | /r/chimpmusic | 81
92 | /r/NegroFree | 77
93 | /r/ChimpinAintEasy | 73
94 | /r/niggerhistorymonth | 65
95 | /r/ChimpireMETA | 64
96 | /r/ChimpireOfftopic | 58
97 | /r/BlackHusbands | 50
98 | /r/RacoonsAreNiggers | 45
99 | /r/blackpeoplehate | 37
100 | /r/NiggerSafari | 16
101 | /r/TIL_4_Niggers | 13
102 | /r/whitesarecriminals | 12
103 | /r/FreddieGray | 12
104 | /r/transrace | 8
105 | /r/LedariusWilliams | 5
106 | /r/Jason_Harrison | 4
107 | /r/IsmaaiylBrinsley | 3
108 | /r/Al_Sharpton | 2
109 | /r/DigitalAgeNiggers | 2
110 | /r/Ismaaiyl_Brinsley | 2
111 | /r/Jordan_Mitchell | 2
112 | /r/terencewalker | 2
113 | /r/NiggerNet | 1
114 | /r/thaddeusmccarroll | 1
115 | /r/VonderritMyers | 1
116 | /r/WilliamChapman | 1
117 | /r/WhiteSmite | 1
--------------------------------------------------------------------------------
/SubredditBirthdays/misc/misc_notes.txt:
--------------------------------------------------------------------------------
1 | 17 February 2015
2 | Submitted list of spammers to admins
3 | start=36111
4 | end= 36v8i
5 | http://voussoir.github.io/restricted_subreddit_links.html
6 | http://voussoir.github.io/restricted_subreddit_links_nobanned.html
--------------------------------------------------------------------------------
/SubredditBirthdays/show/README.md:
--------------------------------------------------------------------------------
1 | For the other exports, see the [releases page](https://github.com/voussoir/reddit/releases).
--------------------------------------------------------------------------------
/SubredditBirthdays/show/missing.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/SubredditBirthdays/show/missing.txt
--------------------------------------------------------------------------------
/Usernames/README.md:
--------------------------------------------------------------------------------
1 | Usernames
2 | ========
3 |
4 | ##### 1,122,342 accounts
5 |
6 | This list should not, for any purpose, be considered an accurate representation of all reddit accounts. Since /api/info is blocked for Account data (t2), gathering names is extremely slow and extremely biased towards those with higher activity, recent activity, and higher karma.
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Usernames/launch.bat:
--------------------------------------------------------------------------------
1 | echo off
2 | cls
3 | python -i un4.py
--------------------------------------------------------------------------------
/Usernames/show/stats.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/Usernames/show/stats.txt
--------------------------------------------------------------------------------
/_old/Anonymisc/README.md:
--------------------------------------------------------------------------------
1 | AnonyMisc
2 | ==========
3 |
4 | By sending this bot a PM, it can post comments for you
5 |
6 | The owners of the bot should put their username in the ADMINS list. They can add users to the whitelist.
7 |
8 | For admins:
9 |
10 | - Whitelist user or subreddit by sending the bot a message with this command at the very top. You cannot perform a whitelist action and commission a comment with the same message. One name or multiple separated by spaces. /u/ is implied if not specified:
11 |
12 | whitelist username
13 | whitelist /u/username
14 | whitelist /r/subreddit
15 | whitelist /u/username1 /u/username2 /u/username3
16 |
17 | When whitelisting, the bot does not check whether the username or subreddit is real. You're the owner of the bot, you can type whatever you want.
18 |
19 | - Unwhitelist user. Same as above
20 |
21 | unwhitelist username1 /u/username2 /r/SubredditDrama
22 |
23 | - Display the current whitelist entries
24 |
25 | show
26 |
27 |
28 |
29 | Who can post:
30 |
31 | - Admins, anywhere.
32 |
33 | - Users on the whitelist, anywhere.
34 |
35 | - Moderators of whitelisted subreddits, in that particular subreddit.
36 |
37 |
38 |
39 | How to post:
40 |
41 | - Send a message to the bot with any subject. At the **very top** of the body, paste a URL pointing to a reddit comment or submission. You may use long-form links:
42 |
43 | https://www.reddit.com/r/GoldTesting/comments/26r2ob/how_to_install_and_use_a_python_reddit_bot/
44 |
45 | or submission shortlinks:
46 |
47 | http://redd.it/26r2ob
48 |
49 | - Leave a blank line, and then type your message. The rest of your message, in its entirety, will become the body of the comment.
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/_old/Anonymisc/anonymisc.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Anonymisc/anonymisc.db
--------------------------------------------------------------------------------
/_old/AutoContributor/README.md:
--------------------------------------------------------------------------------
1 | AutoContributor
2 | ==========
3 |
4 | When a user sends a message to modmail with a specific subject line, he will be automatically added as an approved contributor to the subreddit.
5 |
6 | requested by [/u/vanguaaard](http://reddit.com/u/vanguaaard)
--------------------------------------------------------------------------------
/_old/AutoContributor/autocontributor.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 |
6 | '''USER CONFIGURATION'''
7 | APP_ID = ""
8 | APP_SECRET = ""
9 | APP_URI = ""
10 | APP_REFRESH = ""
11 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
12 | USERAGENT = ""
13 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
14 |
15 | SUBREDDIT = "GoldTesting"
16 | #The subreddit you are acting on.
17 | SUBJECTLINE = ['submission']
18 | #If the modmail subject line contains one of these keywords, he will be added
19 |
20 | MAXPOSTS = 100
21 | #The number of modmails to collect at once. 100 can be fetched with a single request
22 | WAIT = 30
23 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
24 | '''All done!'''
25 |
26 |
27 | sql = sqlite3.connect('sql.db')
28 | print('Loaded SQL Database')
29 | cur = sql.cursor()
30 |
31 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
32 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
33 | print('Loaded Users table')
34 |
35 | sql.commit()
36 |
37 | try:
38 | import bot
39 | USERAGENT = bot.aG
40 | except ImportError:
41 | pass
42 | WAITS = str(WAIT)
43 |
44 | print('Logging in.')
45 | r = praw.Reddit(USERAGENT)
46 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
47 | r.refresh_access_information(APP_REFRESH)
48 |
49 | def scanmessages():
50 | print('Getting ' + SUBREDDIT + ' modmail')
51 | subreddit = r.get_subreddit(SUBREDDIT)
52 | modmail = list(subreddit.get_mod_mail(limit=MAXPOSTS))
53 | for message in modmail:
54 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [message.fullname])
55 | if not cur.fetchone():
56 | print(message.fullname)
57 | try:
58 | mauthor = message.author.name
59 | msubject = message.subject.lower()
60 | if any(keyword.lower() in msubject for keyword in SUBJECTLINE):
61 | print('\tApproving ' + mauthor)
62 | subreddit.add_contributor(mauthor)
63 | message.mark_as_read()
64 | except AttributeError:
65 | print('Failed to fetch username')
66 | cur.execute('INSERT INTO oldposts VALUES(?)', [message.fullname])
67 | sql.commit()
68 |
69 |
70 |
71 | while True:
72 | try:
73 | scanmessages()
74 | except Exception as e:
75 | print('ERROR: ' + str(e))
76 | sql.commit()
77 | print('Running again in ' + WAITS + ' seconds \n_________\n')
78 | time.sleep(WAIT)
79 |
--------------------------------------------------------------------------------
/_old/Automail/README.md:
--------------------------------------------------------------------------------
1 | AutoMail
2 | =========
3 |
4 | Send a PM to this bot. If the PM contains a certain keyword, it will reply to you with a preset response based on that keyword
--------------------------------------------------------------------------------
/_old/Automail/automail.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import os
5 | import sys
6 | import sqlite3
7 |
8 | '''USER CONFIGURATION'''
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERAGENT = ""
15 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
16 | TITLE = "AutoMail"
17 | #This is the title of every message sent by the bot.
18 | HEADER = "This is the top of the PM"
19 | #This will be the header of every message
20 | FOOTER = "This is the bottom of the PM"
21 | #This will be the footer of every message sent by the bot.
22 | RESPONSE = {'paypal':'Paypal message', 'bitcoin':'Bitcoin message', 'google wallet':'Google Wallet message'}
23 | #Reponse for each message. Entries and their response are separated by colons (:). Separate entries are separated by commas (,)
24 | WAIT = 30
25 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
26 | '''All done!'''
27 |
28 |
29 | sql = sqlite3.connect('sql.db')
30 | print('Loaded SQL Database')
31 | cur = sql.cursor()
32 |
33 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(name TEXT)')
34 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
35 | print('Loaded Users table')
36 |
37 | sql.commit()
38 |
39 |
40 | try:
41 | import bot
42 | USERAGENT = bot.geta7()
43 | except ImportError:
44 | pass
45 | WAITS = str(WAIT)
46 |
47 | print('Logging in')
48 | r = praw.Reddit(USERAGENT)
49 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
50 | r.refresh_access_information(APP_REFRESH)
51 |
52 |
53 | def scanPM():
54 | print('Searhing Inbox.')
55 | pms = r.get_unread(update_user=True)
56 | for pm in pms:
57 | alreadysent = False
58 | result = []
59 | try:
60 | author = pm.author.name
61 | print('Handling ' + pm.id + ' from ' + author)
62 | cur.execute('SELECT * FROM oldposts WHERE name=?', [author])
63 | if not cur.fetchone():
64 | pbody = pm.body.lower()
65 | for item in RESPONSE:
66 | if item.lower() in pbody:
67 | result.append(RESPONSE[item])
68 | print('\t' + item)
69 | if len(result) > 0:
70 | final = HEADER + '\n\n'
71 | final += '\n\n'.join(result)
72 | final += '\n\n' + FOOTER
73 | r.send_message(author, TITLE, final, captcha=None)
74 | cur.execute('INSERT INTO oldposts VALUES(?)', [author])
75 | pm.mark_as_read()
76 | else:
77 | print('\tNo results')
78 | else:
79 | print('\tAlready sent to ' + author)
80 | except Exception as e:
81 | print(e)
82 | sql.commit()
83 |
84 | print('')
85 |
86 |
87 | while True:
88 | try:
89 | scanPM()
90 | except Exception as e:
91 | print('ERROR: ' + str(e))
92 | sql.commit()
93 | print('Running again in ' + WAITS + ' seconds \n_________\n')
94 | time.sleep(WAIT)
95 |
--------------------------------------------------------------------------------
/_old/BeetlejuiceMachine/README.md:
--------------------------------------------------------------------------------
1 | BeetleJuice's Answering Machine
2 | =========
3 |
4 | This bot looks for threads where there are three "Beetlejuice" comments in a row, and makes a reply
5 |
6 | http://www.reddit.com/r/GoldTesting/comments/2k5q2a/beetlejuice_test_001/
7 |
8 | http://www.reddit.com/r/GoldTesting/comments/2k5qrx/beetlejuice_test_002/
--------------------------------------------------------------------------------
/_old/BetterNew/betternew.py:
--------------------------------------------------------------------------------
1 | def base36encode(number, alphabet='0123456789abcdefghijklmnopqrstuvwxyz'):
2 | """Converts an integer to a base36 string."""
3 | if not isinstance(number, (int)):
4 | raise TypeError('number must be an integer')
5 | base36 = ''
6 | sign = ''
7 | if number < 0:
8 | sign = '-'
9 | number = -number
10 | if 0 <= number < len(alphabet):
11 | return sign + alphabet[number]
12 | while number != 0:
13 | number, i = divmod(number, len(alphabet))
14 | base36 = alphabet[i] + base36
15 | return sign + base36
16 |
17 | def base36decode(number):
18 | return int(number, 36)
19 |
20 | def b36(i):
21 | if type(i) == int:
22 | return base36encode(i)
23 | if type(i) == str:
24 | return base36decode(i)
25 |
26 | import praw
27 | PREFIX = 't3_'
28 | def get_new(r):
29 | subreddit = r.get_subreddit('all')
30 | newestitem = next(subreddit.get_new())
31 | newestitem = b36(newestitem.id)
32 | while True:
33 | window = list(range(newestitem, newestitem+100))
34 | window = [PREFIX + b36(i) for i in window]
35 | #print(window[0], window[-1])
36 | try:
37 | items = list(r.get_submissions(fullnames=window))
38 | except praw.errors.NotFound:
39 | items = None
40 | r.evict(r.config['by_id'])
41 | if items is None:
42 | continue
43 | for item in items:
44 | newestitem = b36(item.id) + 1
45 | yield item
--------------------------------------------------------------------------------
/_old/BioWiki/README.md:
--------------------------------------------------------------------------------
1 | BioWiki
2 | =======
3 |
4 |
5 | This bot gives every user who posts on the subreddit their own customizeable profile at /r/subreddit/wiki/. When they make their first submission, the wiki page will be created and given some default text at the top, `WIKI_PAGE_INITIAL_TEXT`. That submission, and any submission they make in the future, will be placed underneath that. They can edit the wiki page to personalize it as much as they want
--------------------------------------------------------------------------------
/_old/BioWiki/biowiki.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/BioWiki/biowiki.db
--------------------------------------------------------------------------------
/_old/ContributorFile/README.md:
--------------------------------------------------------------------------------
1 | ContributorFile
2 | =========
3 |
4 | Automatically add all names from a .txt file as contributors in your subreddit. It will automatically check for duplicates for you.
--------------------------------------------------------------------------------
/_old/ContributorFile/contributorfile.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import traceback
3 | import praw
4 | import getpass
5 |
6 | """ USER CONFIGURATION """
7 |
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter Bot".
15 |
16 | SUBREDDIT = input("Subreddit: /r/")
17 | FILENAME = input('File: ')
18 | # You can replace these with strings if you want it hardcoded.
19 |
20 | """ That's all! """
21 |
22 | try:
23 | import bot
24 | USERAGENT = bot.aG
25 | except ImportError:
26 | pass
27 |
28 | print('Logging in...')
29 | r = praw.Reddit(USERAGENT)
30 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
31 | r.refresh_access_information(APP_REFRESH)
32 |
33 | def contributorfile():
34 | subreddit = r.get_subreddit(SUBREDDIT)
35 | print("Finding existing contributors...")
36 | contributors = subreddit.get_contributors(limit=None)
37 | contributors = list(contributors)
38 | for x in range(len(contributors)):
39 | contributors[x] = contributors[x].name.lower()
40 | print("Reading file...")
41 | contributorfile = open(FILENAME)
42 | names = []
43 | for line in contributorfile:
44 | if line[0] != "#":
45 | line = line.strip()
46 | line = line.replace('/u/', '')
47 | names.append(line.lower())
48 | names = set(names)
49 | duplicates = True
50 | while duplicates:
51 | duplicates = False
52 | for username in names:
53 | if username in contributors:
54 | print(username + " is already a contributor")
55 | names.remove(username)
56 | duplicates = True
57 | break
58 |
59 | for username in names:
60 | print("Adding " + username)
61 | try:
62 | subreddit.add_contributor(username)
63 | except:
64 | traceback.print_exc()
65 | print('Finished.')
66 | input()
67 |
68 |
69 | contributorfile()
--------------------------------------------------------------------------------
/_old/ContributorFile/names.txt:
--------------------------------------------------------------------------------
1 | # Lines with hashmarks at the front will not be considered
2 | GoldenSights
3 | Unidan
4 | Deimorz
--------------------------------------------------------------------------------
/_old/Countries/README.md:
--------------------------------------------------------------------------------
1 | Countries
2 | ==========
3 |
4 | Good luck finding a way to repurpose this bot for yourself. Written for /u/dont_mind_the_matter on behalf of /r/countrychallenge
5 |
6 | The txt file contains a list of countries, and today's number at the top. Every day, the computer has a new number, so when midnight strikes, the program will notice that the current date and the written date are not the same, and it will post the next country to reddit as a Feeling-Lucky Google search.
7 |
8 | This might not be the cleanest of code. I don't handle txt files very often, so I did what made the most sense to me.
--------------------------------------------------------------------------------
/_old/Countries/country_list.txt:
--------------------------------------------------------------------------------
1 | *2014-10-03
2 | *Georgia
3 | *Bahrain
4 | *Cyprus
5 | *Iran
6 | *Iraq
7 | *Israel
8 | *Jordan
9 | *Kuwait
10 | *Lebanon
11 | *Oman
12 | *Palestine
13 | *Qatar
14 | *Saudi Arabia
15 | *Syria
16 | *Turkey
17 | *United Arab Emirates
18 | *Yemen
19 | *Australia
20 | *New Zealand
21 | *Argentina
22 | *Bolivia
23 | *Brazil
24 | *Chile
25 | *Colombia
26 | *Ecuador
27 | *Guyana
28 | *Paraguay
29 | *Peru
30 | *Suriname
31 | *Uruguay
32 | *Venezuela
33 | *Algeria
34 | *Egypt
35 | *Libya
36 | *Morocco
37 | *Sudan
38 | *Tunisia
39 | *Belarus
40 | *Bulgaria
41 | *Czech Republic
42 | *Hungary
43 | *Moldova
44 | *Poland
45 | *Romania
46 | *Russia
47 | *Slovakia
48 | *Ukraine
49 | *Kazakhstan
50 | *Kyrgyzstan
51 | *Tajikistan
52 | *Turkmenistan
53 | *Uzbekistan
54 | *Fiji
55 | *Papua New Guinea
56 | *Solomon Islands
57 | *Vanuatu
58 | *Costa Rica
59 | *Belize
60 | *El Salvador
61 | *Guatemala
62 | *Honduras
63 | *Nicaragua
64 | *Panama
65 | *Benin
66 | *Burkina Faso
67 | *Cape Verde
68 | *Cote d'Ivoire
69 | *Gambia
70 | *Ghana
71 | *Guinea
72 | *Guinea-Bissau
73 | *Liberia
74 | *Mali
75 | *Mauritania
76 | *Niger
77 | *Nigeria
78 | *Senegal
79 | *Sierra Leone
80 | *Togo
81 | *Albania
82 | *Bosnia and Herzegovina
83 | *Bulgaria
84 | *Croatia
85 | *Greece
86 | *Kosovo
87 | *Macedonia
88 | *Montenegro
89 | Romania
90 | Serbia
91 | Slovenia
92 | Andorra
93 | Italy
94 | Malta
95 | Portugal
96 | San Marino
97 | Spain
98 | Vatican City
99 | Afghanistan
100 | Bangladesh
101 | Bhutan
102 | India
103 | Maldives
104 | Nepal
105 | Pakistan
106 | Sri Lanka
107 | Kiribati
108 | Marshall Islands
109 | Micronesia, Federated States of
110 | Nauru
111 | Palau
112 | Antigua and Barbuda
113 | Barbados
114 | Dominica
115 | Grenada
116 | Saint Kitts and Nevis
117 | Saint Lucia
118 | Saint Vincent and the Grenadines
119 | Trinidad and Tobago
120 | Cuba
121 | Dominican Republic
122 | Haiti
123 | Jamaica
124 | Bahamas
125 | Angola
126 | Cameroon
127 | C African Republic
128 | Chad
129 | Congo, Democratic Republic of the
130 | Congo, Republic of the
131 | Equatorial Guinea
132 | Gabon
133 | Sao Tome and Principe
134 | Austria
135 | Belgium
136 | France
137 | Germany
138 | Liechtenstein
139 | Luxembourg
140 | Monaco
141 | Netherlands
142 | Switzerland
143 | China
144 | Japan
145 | Korea, N
146 | Korea, S
147 | Mongolia
148 | Taiwan
149 | Samoa
150 | Tonga
151 | Tuvalu
152 | Canada
153 | Mexico
154 | United States
155 | Burundi
156 | Djibouti
157 | Eritrea
158 | Ethiopia
159 | Kenya
160 | Malawi
161 | Mozambique
162 | Rwanda
163 | Somalia
164 | S Sudan
165 | Tanzania
166 | Uganda
167 | Zambia
168 | Zimbabwe
169 | Comoros
170 | Madagascar
171 | Mauritius
172 | Seychelles
173 | Estonia
174 | Latvia
175 | Lithuania
176 | Denmark
177 | Finland
178 | Iceland
179 | Norway
180 | Sweden
181 | Ireland
182 | United Kingdom
183 | Cambodia
184 | Laos
185 | Myanmar
186 | Thailand
187 | Vietnam
188 | Brunei
189 | E Timor
190 | Indonesia
191 | Malaysia
192 | Philippines
193 | Singapore
194 | Botswana
195 | Lesotho
196 | Namibia
197 | S Africa
198 | Swaziland
199 |
--------------------------------------------------------------------------------
/_old/Countries/launch.bat:
--------------------------------------------------------------------------------
1 | countries.py
--------------------------------------------------------------------------------
/_old/Dailyposter/README.md:
--------------------------------------------------------------------------------
1 | DailyPoster
2 | =============
3 |
4 | Makes a text-post in your subreddit every day.
5 |
6 | Let me know if you want the body / title to have more customizable parts. I couldn't think of anything except the date.
7 |
8 | [example](http://www.reddit.com/r/GoldTesting/comments/2lbweq/automated_post_for_november_05_2014/)
--------------------------------------------------------------------------------
/_old/Dailyposter/dailyposter.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 | import datetime
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERAGENT = ""
15 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
16 | SUBREDDIT = "GoldTesting"
17 | #This is the sub you will make the post in.
18 | WAIT = 200
19 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
20 |
21 | PTIME = "07:45"
22 | #HH:MM Format
23 | #TWENTY-FOUR HOUR STYLE
24 | #UTC TIMEZONE
25 | #http://www.timeanddate.com/time/map/
26 |
27 |
28 | #The Following Post title and Post text can be customized using the strftime things
29 | # https://docs.python.org/2/library/time.html#time.strftime
30 | # Ex: "Daily thread for %A %B %d %Y" = "Daily thread for Tuesday November 04 2014"
31 | #Don't forget that the text will be wrung through reddit Markdown
32 | PTITLE = "Automated post for %B %d, %Y"
33 | PTEXT = """
34 | This post is being made by a robot
35 |
36 | Creating a new line on reddit requires hitting Enter twice
37 |
38 | *test*
39 |
40 | Heyo | Woah | Numbers
41 | :- | :- | -:
42 | Text | Box | 9000
43 | Foo | Bar | 32
44 | """
45 |
46 |
47 | '''All done!'''
48 |
49 |
50 | WAITS = str(WAIT)
51 | try:
52 | import bot
53 | USERAGENT = bot.aG
54 | except ImportError:
55 | pass
56 |
57 |
58 | sql = sqlite3.connect('sql.db')
59 | cur = sql.cursor()
60 | cur.execute('CREATE TABLE IF NOT EXISTS posts(ID TEXT, STAMP TEXT, CREATED INT)')
61 | print('Loaded SQL Database')
62 | sql.commit()
63 |
64 | print('Logging in')
65 | r = praw.Reddit(USERAGENT)
66 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
67 | r.refresh_access_information(APP_REFRESH)
68 |
69 | ptime = PTIME.split(':')
70 | ptime = (60*int(ptime[0])) + int(ptime[1])
71 |
72 | def dailypost():
73 | subreddit = r.get_subreddit(SUBREDDIT, fetch=True)
74 | #I want to ping reddit on every cycle. I've had bots lose their session before
75 | now = datetime.datetime.now(datetime.timezone.utc)
76 | daystamp = datetime.datetime.strftime(now, "%d%b%Y")
77 | cur.execute('SELECT * FROM posts WHERE STAMP=?', [daystamp])
78 | nowtime = (60*now.hour) + now.minute
79 | print('Now: ' + str(nowtime) + ' ' + datetime.datetime.strftime(now, "%H:%M"))
80 | print('Pst: ' + str(ptime) + ' ' + PTIME)
81 | if not cur.fetchone():
82 | diff = nowtime-ptime
83 | if diff > 0:
84 | print('t+ ' + str(abs(diff)) + ' minutes')
85 | makepost(now, daystamp)
86 | else:
87 | print('t- ' + str(diff) + ' minutes')
88 | else:
89 | print("Already made today's post")
90 |
91 |
92 |
93 | def makepost(now, daystamp):
94 | print('Making post...')
95 | ptitle = datetime.datetime.strftime(now, PTITLE)
96 | ptext = datetime.datetime.strftime(now, PTEXT)
97 | try:
98 | newpost = r.submit(SUBREDDIT, ptitle, text=ptext, captcha=None)
99 | print('Success: ' + newpost.short_link)
100 | cur.execute('INSERT INTO posts VALUES(?, ?, ?)', [newpost.id, daystamp, newpost.created_utc])
101 | sql.commit()
102 | except praw.requests.exceptions.HTTPError as e:
103 | print('ERROR: PRAW HTTP Error.', e)
104 |
105 |
106 | while True:
107 | try:
108 | dailypost()
109 | except Exception as e:
110 | print("ERROR:", e)
111 | print('Sleeping ' + WAITS + ' seconds.\n')
112 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/DeMobile/README.md:
--------------------------------------------------------------------------------
1 | DeMobile
2 | ==========
3 |
4 | This bot finds links that point to mobile websites, and produces non-mobile links.
5 |
6 | This bot is currently running as [/u/demobile_bot](http://reddit.com/u/demobile_bot), but I am not the operator.
--------------------------------------------------------------------------------
/_old/DeMobile/demobile.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 |
6 | '''USER CONFIGURATION'''
7 |
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
15 | SUBREDDIT = "GoldTesting"
16 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
17 | RESPONSE = "I have detected some mobile links in your comment. Here are the non-mobile clickables:\n\n"
18 | #This is what the bot says right before all the fixed links
19 | MOBILES = {"http://m.":"http://", "http://en.m.":"http://en.", "http://i.reddit.":"http://reddit.", "http://mobile.":"http://"}
20 | #These are the different forms of mobile links. To handle each one, scroll down to line 70.
21 | MAXPOSTS = 100
22 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
23 | WAIT = 20
24 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
25 |
26 | DOMAINBLACKLIST = ["imgur"]
27 | #These are domains that you do not want to demobile, ever.
28 |
29 | '''All done!'''
30 |
31 |
32 |
33 |
34 | WAITS = str(WAIT)
35 | try:
36 | import bot
37 | USERAGENT = bot.aG
38 | except ImportError:
39 | pass
40 |
41 | sql = sqlite3.connect('sql.db')
42 | print('Loaded SQL Database')
43 | cur = sql.cursor()
44 |
45 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
46 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
47 | print('Loaded Completed table')
48 |
49 | sql.commit()
50 |
51 | r = praw.Reddit(USERAGENT)
52 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
53 | r.refresh_access_information(APP_REFRESH)
54 |
55 | def scanSub():
56 | print('Searching '+ SUBREDDIT + '.')
57 | subreddit = r.get_subreddit(SUBREDDIT)
58 | posts = subreddit.get_comments(limit=MAXPOSTS)
59 | for post in posts:
60 | corrections = []
61 | pid = post.id
62 | try:
63 | pauthor = post.author.name
64 | except AttributeError:
65 | pauthor = '[DELETED]'
66 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
67 | if not cur.fetchone():
68 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
69 | pbody = post.body
70 | pbodysplit = pbody.split()
71 | for word in pbodysplit:
72 | if any(mobile in word for mobile in MOBILES):
73 | print(pid)
74 | if all(domain not in word for domain in DOMAINBLACKLIST):
75 | if '](' in word:
76 | word = word[word.index('(')+1:]
77 | word = word.replace(')','')
78 |
79 | for item in MOBILES:
80 | word = word.replace(item, MOBILES[item])
81 |
82 | corrections.append(word)
83 |
84 | else:
85 | print('\tDomain is blacklisted.')
86 | if len(corrections) > 0:
87 | print('\t' + pid + ' by ' + pauthor + ': Fixed ' + str(len(corrections)) + ' links.')
88 | f = '\n\n'.join(corrections)
89 | post.reply(RESPONSE + f)
90 |
91 |
92 | sql.commit()
93 |
94 |
95 | while True:
96 | scanSub()
97 | #try:
98 | # scanSub()
99 | #except Exception as e:
100 | # print('An error has occured:', e)
101 | print('Running again in ' + WAITS + ' seconds \n')
102 | sql.commit()
103 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/DelayBot/README.md:
--------------------------------------------------------------------------------
1 | DelayBot
2 | =============
3 |
4 | Written by /u/Goldensights for /u/FourMakesTwoUnless on behalf of /r/pkmntcgtrades
5 |
6 | Probably one of my coolest bots so far. While running, this bot scans your subreddit for new posts, and checks if the user has ever posted there before. If not, they are added to the database and sent a polite welcome message; if so, it checks when their last post was. If their last post was too recent, it will get deleted and have a comment added to it telling them to read the rules.
7 |
8 | The welcome message and warning message are not included in the USER CONFIG section. Scroll down to lines 80 and 104 to change these. They follow reddit's usual Markdown syntax.
--------------------------------------------------------------------------------
/_old/DelayBotT/README.md:
--------------------------------------------------------------------------------
1 | DelayBot T
2 | =============
3 |
4 | This is almost exactly the same as DelayBot, but this one allows for title sensitivity. Perhaps you only want to restrict posts starting with '[Request]'
--------------------------------------------------------------------------------
/_old/DeleteMe/README.md:
--------------------------------------------------------------------------------
1 | DeleteMe
2 | =========
3 |
4 | This is a tool which lets you delete items off your profile with a score below a set threshold. After the initial run-through, you can tell the bot to act continuously using the same threshold.
--------------------------------------------------------------------------------
/_old/DeleteMe/deleteme.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw
3 | import time
4 | import getpass
5 |
6 | USERAGENT = ""
7 | APP_ID = ""
8 | APP_SECRET = ""
9 | APP_URI = ""
10 | APP_REFRESH = ""
11 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
12 |
13 |
14 | print('Logging in to reddit')
15 | r = praw.Reddit(USERAGENT)
16 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
17 | r.refresh_access_information(APP_REFRESH)
18 |
19 | def tprint(thing):
20 | # Slows down the printouts
21 | print(thing)
22 | time.sleep(0.1)
23 |
24 | def create():
25 | tprint('\nEnter a score threshold. All comments and submissions below will be deleted')
26 | THRESHOLD = int(input('>> '))
27 | tprint('\nDeleting all comments and submissions with a score less than ' + str(THRESHOLD) + '.')
28 | tprint('Is this correct? Y/N')
29 | confirm = input('>> ').lower()
30 | if confirm == 'y':
31 | user = r.user
32 |
33 | deletion(user, THRESHOLD)
34 |
35 | tprint('\nWould you like this program to continue running?')
36 | tprint('Y/N')
37 | confirm = input('>> ').lower()
38 | if confirm == 'y':
39 | while True:
40 | deletion(user, THRESHOLD)
41 | tprint('\nSleeping 120 seconds')
42 | time.sleep(120)
43 |
44 | def deletion(user, THRESHOLD):
45 | tprint('\nGathering submissions. Please be patient')
46 | submitted = list(user.get_submitted(limit=1000))
47 | tprint('Found ' + str(len(submitted)) + ' total.')
48 | for item in submitted:
49 | if item.score < THRESHOLD:
50 | print('Deleting item ' + item.fullname + ' with score ' + str(item.score))
51 | item.delete()
52 | time.sleep(2)
53 | else:
54 | tprint('Keeping item ' + item.fullname + ' with score ' + str(item.score))
55 |
56 | tprint('\nGathering comments. Please be patient')
57 | comments = list(user.get_comments(limit=1000))
58 | tprint('Found ' + str(len(comments)) + ' total.')
59 | for item in comments:
60 | if item.score < THRESHOLD:
61 | print('Deleting item ' + item.fullname + ' with score ' + str(item.score))
62 | item.delete()
63 | time.sleep(2)
64 | else:
65 | tprint('Keeping item ' + item.fullname + ' with score ' + str(item.score))
66 |
67 | while True:
68 | create()
--------------------------------------------------------------------------------
/_old/DeleteMeT/README.md:
--------------------------------------------------------------------------------
1 | DeleteMe - Time
2 | =========
3 |
4 | A modified version of DeleteMe, which deletes submissions and comments older than a certain threshold. This tool is written to be super simple, so you have to be specific in specifying the time. Just follow instructions.
--------------------------------------------------------------------------------
/_old/DeleteMeT/deletemet.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw
3 | import time
4 | import getpass
5 | import datetime
6 |
7 | USERAGENT = ""
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 |
14 | print('Logging in to reddit')
15 | r = praw.Reddit(USERAGENT)
16 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
17 | r.refresh_access_information(APP_REFRESH)
18 |
19 | def tprint(thing):
20 | #Having a whole bunch of text appear at once can be jarring
21 | print(thing)
22 | time.sleep(0.1)
23 |
24 | def getTime(bool):
25 | timeNow = datetime.datetime.now(datetime.timezone.utc)
26 | timeUnix = timeNow.timestamp()
27 | if bool is False:
28 | return timeNow
29 | else:
30 | return timeUnix
31 |
32 | def create():
33 | fail = False
34 | tprint('\nEnter a time threshold. Use a number followed by "days", "hours", or "minutes"')
35 | tprint('All submissions and comments older than this will be DELETED.')
36 | t = input('>> ').lower()
37 | tsplit = t.split()
38 | try:
39 | THRESHOLD = float(tsplit[0])
40 | if tsplit[1] not in ['days', 'day', 'hours', 'hour', 'minutes', 'minute']:
41 | print('You entered an improper time. "days", "hours", "minutes"')
42 | input()
43 | fail = True
44 | except ValueError:
45 | print('Could not understand that number')
46 | input()
47 | fail = True
48 | except IndexError:
49 | print('Please enter something.')
50 | input()
51 | fail = True
52 |
53 | if fail is False:
54 | if tsplit[1] == 'days' or tsplit[1] == 'day':
55 | THRESHOLD *= 86400
56 | elif tsplit[1] == 'hours' or tsplit[1] == 'hour':
57 | THRESHOLD *= 3600
58 | elif tsplit[1] == 'minutes' or tsplit[1] == 'minute':
59 | THRESHOLD *= 60
60 |
61 | tprint(t)
62 | tprint(str(THRESHOLD) + ' seconds.')
63 | tprint('Is this correct? Y/N')
64 | confirm = input('>> ').lower()
65 | if confirm == 'y':
66 | user = r.user
67 |
68 | deletion(user, THRESHOLD, lim=1000)
69 |
70 | tprint('\nWould you like this program to continue running?')
71 | tprint('Y/N')
72 | confirm = input('>> ').lower()
73 | if confirm == 'y':
74 | while True:
75 | deletion(user, THRESHOLD, lim=100)
76 | tprint('\nSleeping 60 seconds')
77 | time.sleep(60)
78 |
79 |
80 | def deletion(user, THRESHOLD, lim=1000):
81 | allitems = []
82 |
83 | now = getTime(True)
84 |
85 | tprint('\nGathering submissions. Please be patient')
86 | allitems += list(user.get_submitted(limit=lim))
87 |
88 | tprint('Gathering comments. Please be patient')
89 | allitems += list(user.get_comments(limit=lim))
90 |
91 | allitems.sort(key=lambda x:x.created_utc)
92 |
93 | tprint('Found ' + str(len(allitems)) + ' total.')
94 |
95 | for item in allitems:
96 | diff = now - item.created_utc
97 | if diff > THRESHOLD:
98 | print('Deleting item ' + item.fullname + ' from ' + ("%0.0f" % diff) + ' seconds ago.')
99 | item.delete()
100 | time.sleep(2)
101 | else:
102 | tprint('Keeping item ' + item.fullname + ' from ' + ("%0.0f" % diff) + ' seconds ago.')
103 |
104 |
105 | while True:
106 | create()
--------------------------------------------------------------------------------
/_old/DeletedAuthors/README.md:
--------------------------------------------------------------------------------
1 | DeletedAuthors
2 | ==========
3 |
4 | Removes submissions where the author is listed as "[deleted]". This bot does not keep a database because it needs to re-check posts continuously.
--------------------------------------------------------------------------------
/_old/DeletedAuthors/deletedauthors.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 |
5 | '''USER CONFIGURATION'''
6 |
7 | APP_ID = ""
8 | APP_SECRET = ""
9 | APP_URI = ""
10 | APP_REFRESH = ""
11 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
12 | USERAGENT = ""
13 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
14 | SUBREDDIT = "GoldTesting"
15 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
16 | MAXPOSTS = 1000
17 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
18 | WAIT = 60
19 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
20 |
21 |
22 | '''All done!'''
23 |
24 |
25 | WAITS = str(WAIT)
26 | try:
27 | import bot
28 | USERAGENT = bot.aG
29 | except ImportError:
30 | pass
31 |
32 | print("Logging in")
33 | r = praw.Reddit(USERAGENT)
34 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
35 | r.refresh_access_information(APP_REFRESH)
36 |
37 | def scanSub():
38 | print('Searching '+ SUBREDDIT + '.')
39 | subreddit = r.get_subreddit(SUBREDDIT)
40 | posts = subreddit.get_new(limit=MAXPOSTS)
41 | for post in posts:
42 | try:
43 | pauthor = post.author.name
44 | except AttributeError:
45 | print(post.id, 'is being removed')
46 | post.remove()
47 | print('\tDone')
48 |
49 | while True:
50 | try:
51 | scanSub()
52 | except Exception as e:
53 | print('An error has occured:', e)
54 | print('Running again in ' + WAITS + ' seconds \n')
55 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/EightBall/README.md:
--------------------------------------------------------------------------------
1 | EightBall
2 | ==========
3 |
4 | This is a beefed-up, randomized version of ReplyBot. You can have multiple lists of triggers and corresponding responses. If the person uses a trigger in list A, they will get a response from list A. The response will be chosen randomly out of the list.
--------------------------------------------------------------------------------
/_old/EightBall/eightball.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 | import random
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERAGENT = ""
15 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
16 | SUBREDDIT = "GoldTesting"
17 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
18 |
19 | NAME = ""
20 | TRIGGERSTRINGA = ["I summon you /u/" + NAME, "I summon you great /u/" + NAME, "I summon you " + NAME, "I summon you great " + NAME, "Dear great /u/" + NAME, "Dear great " + NAME, NAME + ", roll the 8-ball", NAME + " roll the 8-ball"]
21 | #These will trigger a response from replystringa
22 | REPLYSTRINGA = ["Yes.", "No.", "That's a stupid question.", "Maybe some day.", "Try asking again.", "You should ask the admins."]
23 | #This is a list of potential replies. Will be randomized.
24 |
25 | TRIGGERSTRINGB = [NAME + " is dumb"]
26 | #A second set of triggers
27 | REPLYSTRINGB = ["No you."]
28 | #A second set of responses. Will be randomized
29 |
30 | TRIGGERLIST = [TRIGGERSTRINGA, TRIGGERSTRINGB]
31 | REPLYLIST = [REPLYSTRINGA, REPLYSTRINGB]
32 | #You can also add a third or fourth set of triggers and responses. Just make sure to add them to TRIGGERLIST and REPLYLIST
33 | #The first list in TRIGGERLIST goes to the first list in REPLYLIST. Keep them in order.
34 | #Triggerlist and Replylist must have the same number of items
35 |
36 | MAXPOSTS = 100
37 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
38 | WAIT = 30
39 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
40 |
41 |
42 | '''All done!'''
43 |
44 |
45 |
46 |
47 | WAITS = str(WAIT)
48 | try:
49 | import bot
50 | USERAGENT = bot.getaG()
51 | except ImportError:
52 | pass
53 |
54 | sql = sqlite3.connect('sql.db')
55 | print('Loaded SQL Database')
56 | cur = sql.cursor()
57 |
58 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
59 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
60 | print('Loaded Completed table')
61 |
62 | sql.commit()
63 | print("Logging in " + NAME)
64 | r = praw.Reddit(USERAGENT)
65 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
66 | r.refresh_access_information(APP_REFRESH)
67 |
68 | def scanSub():
69 | print('Scanning ' + SUBREDDIT)
70 | subreddit = r.get_subreddit(SUBREDDIT)
71 | comments = subreddit.get_comments(limit=MAXPOSTS)
72 | for comment in comments:
73 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [comment.id])
74 | if not cur.fetchone():
75 | cbody = comment.body.lower()
76 | response = ''
77 | for m in range(len(TRIGGERLIST)):
78 | if any(trigger.lower() in cbody for trigger in TRIGGERLIST[m]) and response == '':
79 | print(comment.id)
80 | random.shuffle(REPLYLIST[m])
81 | response = REPLYLIST[m][0]
82 | if response != '':
83 | print('\tPosting response')
84 | comment.reply(response)
85 | cur.execute('INSERT INTO oldposts VALUES(?)',[comment.id])
86 | sql.commit()
87 |
88 |
89 | while True:
90 | try:
91 | scanSub()
92 | except Exception as e:
93 | print('An error has occured:', e)
94 | print('Running again in ' + WAITS + ' seconds \n')
95 | sql.commit()
96 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/ErroneousQuotes/README.md:
--------------------------------------------------------------------------------
1 | ErroneousQuotes
2 | ==========
3 |
4 | This bot will take phrases that people say and erroneously attribute them to famous historical figures.
5 |
6 | The **first** thing in a comment must be /u/Bots-Username. The bot will only respond if the requested quote is less than a certain number of characters.
7 |
8 | /u/GoldenSights Always be careful on the internet, kids!
9 |
10 | V
11 |
12 | >Always be careful on the internet, kids!
13 |
14 | • Napoleon Bonaparte
--------------------------------------------------------------------------------
/_old/ErroneousQuotes/erroneousquotes.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 | import random
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | USERNAME = ""
10 | #This is the bot's Username. In order to send mail, he must have some amount of Karma.
11 | PASSWORD = ""
12 | #This is the bot's Password.
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
15 | SUBREDDIT = "GoldTesting"
16 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
17 | NAMES = ["Abraham Lincoln", "George Washington", "Bill Gates", "Rosa Parks", "GoldenSights", "Unidan", "Napoleon Bonaparte"]
18 | #Famous People
19 | MAXPOSTS = 100
20 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
21 | MAXLENGTH = 150
22 | #To avoid bot abuse, do not generate any quotes longer than this many characters.
23 | WAIT = 20
24 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
25 |
26 |
27 | '''All done!'''
28 |
29 |
30 |
31 |
32 | WAITS = str(WAIT)
33 | try:
34 | import bot #This is a file in my python library which contains my Bot's username and password. I can push code to Git without showing credentials
35 | USERNAME = bot.getuG()
36 | PASSWORD = bot.getpG()
37 | USERAGENT = bot.getaG()
38 | except ImportError:
39 | pass
40 |
41 | cutoff = len(USERNAME) + 4
42 | sql = sqlite3.connect('sql.db')
43 | print('Loaded SQL Database')
44 | cur = sql.cursor()
45 |
46 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
47 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
48 | print('Loaded Completed table')
49 |
50 | sql.commit()
51 |
52 | r = praw.Reddit(USERAGENT)
53 | r.login(USERNAME, PASSWORD)
54 |
55 | def scanSub():
56 | print('Searching '+ SUBREDDIT + '.')
57 | subreddit = r.get_subreddit(SUBREDDIT)
58 | posts = subreddit.get_comments(limit=MAXPOSTS)
59 | for post in posts:
60 | pid = post.id
61 | pbody = post.body
62 | try:
63 | pauthor = post.author.name
64 | except AttributeError:
65 | pauthor = '[DELETED]'
66 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
67 | if not cur.fetchone():
68 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
69 | if pbody.lower()[:cutoff] == '/u/' + USERNAME.lower() + ' ':
70 | quote = pbody.split('\n\n')[0][cutoff:]
71 | if len(quote) <= MAXLENGTH and pauthor != USERNAME:
72 | if ('/u/' + USERNAME) in quote:
73 | print(pid + ': Meatbag detected')
74 | response = 'Nice try, meatbag'
75 | else:
76 | name = NAMES[random.randint(0,len(NAMES)-1)]
77 | print(pid + ': ' + quote + '- ' + name)
78 | response = '>' + quote + '\n\n- ' + name
79 | post.reply(response)
80 | else:
81 | print(pid + ': Comment too long')
82 | sql.commit()
83 |
84 | while True:
85 | try:
86 | scanSub()
87 | except Exception as e:
88 | print('An error has occured:', str(e))
89 | print('Running again in ' + WAITS + ' seconds \n')
90 | sql.commit()
91 | time.sleep(WAIT)
92 |
--------------------------------------------------------------------------------
/_old/FlairMail/README.md:
--------------------------------------------------------------------------------
1 | Flairmail
2 | ==============
3 |
4 | This bot will assign flair to users when they message it. The message must contain a proper subject-line, and then the body of the message will be set as their flair for a single subreddit. Reddit maintains a maximum of 64 characters, but moderators may enforce a lower maximum if they wish. This bot requires moderator permissions.
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/_old/FlairMail/flairmail.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import traceback
3 | import praw
4 | import time
5 |
6 | '''USER CONFIGURATION'''
7 |
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does.
15 | #For example "/u/GoldenSights' Newsletter bot"
16 | SUBREDDIT = "GoldTesting"
17 | #This is the sub for which flair will be distributed.
18 | #Must only be a single subreddit
19 | WAIT = 30
20 | #This is how many seconds you will wait between cycles.
21 | #The bot is completely inactive during this time.
22 |
23 | SUBJECTLINE = ["flair", "re: flair"]
24 | #This is the text that must match the message subject for the bot to take
25 | #action. Leave this emtpy [] if you want to act on *any* mail.
26 | CHARACTER_MAX = 48
27 | #The maximum number of characters the user can have in his flair
28 | #THE REDDIT MAXIMUM IS 64. ANY NUMBER HIGHER THAN 64 IS USELESS.
29 | MESSAGE_SUCCESS = """
30 | Your flair has been set to
31 |
32 | _newflair_
33 | """
34 | #This is what the bot will send back to the user when the flair is successful
35 | #You can include "_newflair_" to have the message include the flair. Optional.
36 | MESSAGE_TOOLONG = """
37 | That flair is too long. It contains {length}/{maximum} characters. This
38 | maximum is enforced by the moderators.
39 | """
40 | MESSAGE_TOOLONG_SITE = """
41 | That flair is too long. It contains {length}/64 characters. This maximum is
42 | enforced by reddit site-wide.
43 | """
44 |
45 | ''' All done! '''
46 |
47 |
48 | try:
49 | import bot
50 | USERAGENT = bot.aG
51 | except ImportError:
52 | pass
53 |
54 | print('Logging in...')
55 | r = praw.Reddit(USERAGENT)
56 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
57 | r.refresh_access_information(APP_REFRESH)
58 |
59 | def flairmail():
60 | print('Getting unread messages')
61 | unreads = list(r.get_unread(limit=None))
62 | for message in unreads:
63 | try:
64 | mauthor = message.author.name
65 | msubject = message.subject.lower()
66 | mbody = message.body
67 | mlength = len(mbody)
68 | if any(trigger.lower() == msubject for trigger in SUBJECTLINE) or SUBJECTLINE==[]:
69 | print('%s has requested flair: %s' % (mauthor, mbody))
70 |
71 | if mlength > 64:
72 | print('\tFlair is too long, sitewide')
73 | message.reply(MESSAGE_TOOLONG_SITE.format(length=mlength))
74 | elif mlength > CHARACTER_MAX:
75 | print('\tFlair is too long, modrules')
76 | message.reply(MESSAGE_TOOLONG.format(length=mlength, maximum=CHARACTER_MAX))
77 | else:
78 | print('\tSetting flair')
79 | mbody = mbody.replace('\n', '')
80 | r.set_flair(SUBREDDIT, mauthor, mbody)
81 | reply = MESSAGE_SUCCESS
82 | reply = reply.replace("_newflair_", mbody)
83 | print('\tWriting reply')
84 | message.reply(reply)
85 |
86 | message.mark_as_read()
87 | except AttributeError:
88 | # Author does not exist
89 | # Or this is a comment
90 | pass
91 |
92 | while True:
93 | flairmail()
94 | print('Sleeping %d seconds...\n' % WAIT)
95 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/FlairTimer/README.md:
--------------------------------------------------------------------------------
1 | FlairTimer
2 | ==========
3 |
4 | When a post is found without flair, it receives the ACTIVE flair. If an Active post is found and is over a certain age, the flair is removed.
--------------------------------------------------------------------------------
/_old/Flaircounting/README.md:
--------------------------------------------------------------------------------
1 | Flaircounting
2 | ==========
3 |
4 | Written for /u/jortbru1299 on behalf of /r/CinemaSins
5 |
6 | Keeps track of everybody's flair by watching new comments and submissions. Also shows how many users have each type of flair
--------------------------------------------------------------------------------
/_old/Flaircounting/flaircounting.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw
3 | import time
4 | import sqlite3
5 | import datetime
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERAGENT = ""
15 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
16 | SUBREDDIT = "Cinemasins"
17 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
18 | PRINTFILE = "userflair.txt"
19 | #The file where the flairs will be shown
20 |
21 | MAXPOSTS = 100
22 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
23 | WAIT = 30
24 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
25 |
26 |
27 | '''All done!'''
28 |
29 |
30 |
31 | WAITS = str(WAIT)
32 | lastwikiupdate = 0
33 |
34 | try:
35 | import bot
36 | USERAGENT = bot.aG
37 | except ImportError:
38 | pass
39 |
40 | sql = sqlite3.connect('sql.db')
41 | print('Loaded SQL Database')
42 | cur = sql.cursor()
43 |
44 | cur.execute('CREATE TABLE IF NOT EXISTS users(NAME TEXT, FLAIR TEXT)')
45 | print('Loaded Completed table')
46 | sql.commit()
47 |
48 | r = praw.Reddit(USERAGENT)
49 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
50 | r.refresh_access_information(APP_REFRESH)
51 |
52 |
53 |
54 | def scan():
55 | print('Scanning ' + SUBREDDIT)
56 | subreddit = r.get_subreddit(SUBREDDIT)
57 | posts = []
58 | posts += subreddit.get_new(limit=MAXPOSTS)
59 | posts += subreddit.get_comments(limit=MAXPOSTS)
60 | for post in posts:
61 | try:
62 | pauthor = post.author.name
63 | try:
64 | pflair = post.author_flair_text
65 | if pflair is not None:
66 | cur.execute('SELECT * FROM users WHERE NAME=?', [pauthor])
67 | fetched = cur.fetchone()
68 | if not fetched:
69 | cur.execute('INSERT INTO users VALUES(?, ?)', [pauthor, pflair])
70 | print('New user flair: ' + pauthor + ' : ' + pflair)
71 | else:
72 | oldflair = fetched[1]
73 | if pflair != oldflair:
74 | cur.execute('UPDATE users SET FLAIR=? WHERE NAME=?', [pflair, pauthor])
75 | print('Updating user flair: ' + pauthor + ' : ' + pflair)
76 | sql.commit()
77 | else:
78 | print(post.id, "No flair")
79 | except AttributeError:
80 | print(post.id, "No flair")
81 | except AttributeError:
82 | print(post.id, "Author is deleted")
83 |
84 | flairfile = open(PRINTFILE, 'w')
85 | cur.execute('SELECT * FROM users')
86 | fetch = cur.fetchall()
87 | fetch.sort(key=lambda x: x[0])
88 | flaircounts = {}
89 | for item in fetch:
90 | itemflair = item[1]
91 | if itemflair not in flaircounts:
92 | flaircounts[itemflair] = 1
93 | else:
94 | flaircounts[itemflair] += 1
95 | print('FLAIR: NO. OF USERS WITH THAT FLAIR', file=flairfile)
96 | presorted = []
97 | for flairkey in flaircounts:
98 | presorted.append(flairkey + ': ' + str(flaircounts[flairkey]))
99 | presorted.sort()
100 | for flair in presorted:
101 | print(flair, file=flairfile)
102 | print('\n\n', file=flairfile)
103 | print('NAME: USER\'S FLAIR', file=flairfile)
104 | for user in fetch:
105 | print(user[0] + ': ' + user[1], file=flairfile)
106 | flairfile.close()
107 |
108 |
109 | while True:
110 | try:
111 | scan()
112 | except EOFError:
113 | print("Error:", e)
114 | sql.commit()
115 | print('Running again in ' + str(WAIT) + ' seconds')
116 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/HashBot/README.md:
--------------------------------------------------------------------------------
1 | HashBot
2 | ======
3 |
4 | This bot looks for hashes in the post titles and generates a twitter link as a comment.
5 |
--------------------------------------------------------------------------------
/_old/HashBot/hashbot.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 |
6 | ''''USER CONFIGURATION'''
7 | APP_ID = ""
8 | APP_SECRET = ""
9 | APP_URI = ""
10 | APP_REFRESH = ""
11 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
12 | USERAGENT = ""
13 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
14 | SUBREDDIT = ""
15 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
16 | MAXPOSTS = 10
17 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
18 | WAIT = 600
19 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
20 |
21 |
22 | '''All done!'''
23 |
24 |
25 |
26 |
27 |
28 | try:
29 | import bot
30 | USERAGENT = bot.geta()
31 | except ImportError:
32 | pass
33 | WAITS = str(WAIT)
34 | sql = sqlite3.connect('sql.db')
35 | print('Loaded SQL Database')
36 | cur = sql.cursor()
37 |
38 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
39 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
40 | print('Loaded Completed table')
41 |
42 |
43 | sql.commit()
44 |
45 | r = praw.Reddit(USERAGENT)
46 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
47 | r.refresh_access_information(APP_REFRESH)
48 |
49 | def scanSub():
50 | print('Searching '+ SUBREDDIT + '.')
51 | subreddit = r.get_subreddit(SUBREDDIT)
52 | posts = subreddit.get_new(limit=MAXPOSTS)
53 | for post in posts:
54 | ptitle = post.title
55 | pauthor = post.author.name
56 | pid = post.id
57 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
58 | if not cur.fetchone():
59 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
60 | titlesplit = ptitle.split()
61 | for word in titlesplit:
62 | if len(word) > 1 and word[0] == '#':
63 | print(pid + ', ' + pauthor + ': ' + word)
64 | hashtag = word[1:]
65 | link = 'http://twitter.com/intent/tweet?button_hashtag=' + hashtag
66 | post.add_comment('[Use this hashtag!](' + link + ')')
67 | sql.commit()
68 |
69 |
70 | while True:
71 | try:
72 | scanSub()
73 | except Exception as e:
74 | print('An error has occured:', e)
75 | print('Running again in ' + WAITS + ' seconds \n')
76 | sql.commit()
77 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/HerokuBot/Procfile:
--------------------------------------------------------------------------------
1 | # Procfile
2 | worker: python herokubot.py
--------------------------------------------------------------------------------
/_old/HerokuBot/git.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/HerokuBot/git.zip
--------------------------------------------------------------------------------
/_old/HerokuBot/herokubot.py:
--------------------------------------------------------------------------------
1 | import praw
2 | import time
3 |
4 | print('Logging in.')
5 | r = praw.Reddit('Testing praw api usage over Heroku')
6 | r.login('qQGusVuAHezHxhYTiYGm', 'qQGusVuAHezHxhYTiYGm')
7 |
8 | print('Getting subreddit info.')
9 | sub = r.get_subreddit('Goldtesting')
10 | print('/r/Goldtesting')
11 | print('\tCreated at: %d' % sub.created_utc)
12 | print('\tSubscribers: %d' % sub.subscribers)
13 |
14 | print('All done!')
15 | while True:
16 | time.sleep(60)
--------------------------------------------------------------------------------
/_old/HerokuBot/requirements.txt:
--------------------------------------------------------------------------------
1 | praw >= 2.1.21
--------------------------------------------------------------------------------
/_old/HerokuBot/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.4.2
--------------------------------------------------------------------------------
/_old/KarmaDecayRepost/kdr.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/KarmaDecayRepost/kdr.db
--------------------------------------------------------------------------------
/_old/Lengthflair/README.md:
--------------------------------------------------------------------------------
1 | Lengthflair
2 | =============
3 |
4 | Written by /u/Goldensights for [/u/KMilliron](http://reddit.com/u/KMilliron) on behalf of [/r/darktales](http://reddit.com/r/darktales)
5 |
6 | Assigns flair to new posts based on the number of words within the selftext. The bot will wait `DELAY` seconds to give the user a chance to put his own flair.
7 |
8 | The flair selector will choose the lowest possible value in the dictionary.
9 |
10 | {100:'Short', 200:'Medium', 300:'Long'} means 0-100 is Short, 101-200 is Medium, 201-inf is Long
--------------------------------------------------------------------------------
/_old/LumioseLottery/README.md:
--------------------------------------------------------------------------------
1 | LumioseLottery
2 | ==========
3 |
4 | Written for /r/LumioseLottery.
5 |
6 | Basically, every pokemon player has a unique 5-digit number called OTN. Any pokemon they catch inherits this number. If you trade pokemon with other players, you will now have a copy of their OTN. There is an in-game lottery that generates a new 5-digit number every day, and checks it against your pokemons' OTNs for a ☒☒☒☒☒, ☐☒☒☒☒, ☐☐☒☒☒, or ☐☐☐☒☒ match. The purpose of this subreddit is to connect you with other OTNs so that you have more potential matches for the lottery, instead of waiting for a match on your OTN only.
7 |
8 | Every day, the bot will post a new Dailythread. If a person posts their lottery number in a root comment on this thread (using proper formatting), the bot will check that number against the database of all OTNs posted to the subreddit, and produce matches in the same 5-star format as above. The bot will give matches from least- to most-matching, and a hyperlink to the thread where that OTN was posted. Then, the commenter can contact the OP of that thread and arrange a pokemon trade.
--------------------------------------------------------------------------------
/_old/MailForwarding/README.md:
--------------------------------------------------------------------------------
1 | MailForwarding
2 | ========
3 |
4 | Forward all comments and Private Messages from one account to another. This bot will store it's unsent mail in an sql file so you will not miss out on messages due to any downtime.
5 |
6 | If the inboxed item was a comment, the forward will include it's permalink. If it was a PM, the forward will include a link to compose a new message with a preset "re: " subjectline. The forward will also include the timestamp of the original message in UTC.
7 |
8 | Subjectlines are limited to 100 chars; body text 10,000. If they are too long, the excess will be silently sliced off. It's a real edge-case for this to be an issue.
9 |
10 | This was done on a whim. Please notify me of bugs.
--------------------------------------------------------------------------------
/_old/MailMe/README.md:
--------------------------------------------------------------------------------
1 | MailMe
2 | =============
3 |
4 | This bot works on the same premise as ReplyBot, but instead of replying to the comments you find, it will send you a PM with a permalink to the comment that included your keyword.
5 |
6 | Also works on submissions. See the `DO_SUBMISSIONS` variable.
7 |
8 | NOTE: MailMe does not want to send mail if the comment that it finds was written by you or the bot. However, without the `identity` OAuth scope, the bot cannot retrieve its own username. This will not be a problem if you don't have the bot writing comments, but just be aware.
--------------------------------------------------------------------------------
/_old/MailMePosts/README.md:
--------------------------------------------------------------------------------
1 | MailMePosts
2 | =============
3 |
4 | This bot has been merged with [MailMe](https://github.com/voussoir/reddit/tree/master/MailMe). Use the `DO_SUBMISSIONS` variable in that bot's config to do this.
--------------------------------------------------------------------------------
/_old/MailMeUser/README.md:
--------------------------------------------------------------------------------
1 | MailMeUser
2 | =============
3 |
4 | This bot works on the same premise as Mailme, but instead of finding comments with a keyword, it will find new comments and submissions made by a certain user or users.
--------------------------------------------------------------------------------
/_old/MailMeUser/mailmeuser.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 |
6 | '''USER CONFIGURATION'''
7 |
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
15 | RECIPIENT = "75000"
16 | #The username that will receive this PM. It can be your username if you want to
17 | MTITLE = "0"
18 | #This will be the title of the PM that you get
19 | REDDITORS = ["Unidan", "GoldenSights"]
20 | #This is the person or people you want to. Add or remove items from this list with commas serparating each.
21 | MAXPOSTS = 10
22 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
23 | WAIT = 20
24 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
25 |
26 |
27 | '''All done!'''
28 |
29 |
30 |
31 |
32 | WAITS = str(WAIT)
33 | try:
34 | import bot
35 | USERAGENT = bot.geta()
36 | except ImportError:
37 | pass
38 |
39 | sql = sqlite3.connect('sql.db')
40 | print('Loaded SQL Database')
41 | cur = sql.cursor()
42 |
43 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
44 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
45 | print('Loaded Completed table')
46 |
47 | sql.commit()
48 |
49 | r = praw.Reddit(USERAGENT)
50 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
51 | r.refresh_access_information(APP_REFRESH)
52 |
53 | def scanSub():
54 | result = []
55 | for REDDITOR in REDDITORS:
56 | print('Searching '+ REDDITOR + '.')
57 | redditor = r.get_redditor(REDDITOR)
58 | posts = redditor.get_overview(limit=MAXPOSTS)
59 | for post in posts:
60 | pid = post.id
61 | plink = post.permalink
62 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
63 | if not cur.fetchone():
64 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
65 | print('Found ' + pid + ' by ' + REDDITOR)
66 | result.append(REDDITOR + ' has made a comment or post. [Find it here.](' + plink + ')')
67 | if len(result) > 0:
68 | r.send_message(RECIPIENT, MTITLE, '\n\n'.join(result), captcha=None)
69 | print('Message sent')
70 |
71 | sql.commit()
72 |
73 |
74 | while True:
75 | scanSub()
76 | print('Running again in ' + WAITS + ' seconds \n')
77 | sql.commit()
78 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/MessageArchive/README.md:
--------------------------------------------------------------------------------
1 | Message Archive
2 | ==========
3 |
4 | Export your mailbox to a text file.
5 |
6 | Step 1: Edit the config at the top of the file to however you want.
7 | Step 2: `> messagearchive.py fetch` generates the database file. It can take some time.
8 | Step 3: `> messagearchive.py render` generates the text file. It's pretty quick.
--------------------------------------------------------------------------------
/_old/MoreFrom/README.md:
--------------------------------------------------------------------------------
1 | MoreFrom
2 | =============
3 |
4 | When a subreddit gets a new post, the bot will do a search on that user and find more of his posts in that subreddit. Lots of customization for ignoring post types.
5 |
6 | - [More Selfposts](http://www.reddit.com/r/GoldTesting/comments/2awtlr/this_is_a_selfpost/)
7 |
8 | - [More Linkposts](http://www.reddit.com/r/GoldTesting/comments/2awtxu/bot_please_ignore_this_link/)
9 |
10 | - [More all types](http://www.reddit.com/r/GoldTesting/comments/2awuto/all_types_welcome/)
11 |
12 | - [Ignoring titles with certain tags](http://www.reddit.com/r/GoldTesting/comments/2awtts/meta_bot_should_ignore_this_post/)
13 |
14 | - [No results, no comment](http://www.reddit.com/r/GoldTesting/comments/2awv2e/u75000/)
--------------------------------------------------------------------------------
/_old/MoreFrom/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/MoreFrom/sql.db
--------------------------------------------------------------------------------
/_old/Novella/README.md:
--------------------------------------------------------------------------------
1 | Novella
2 | =============
3 |
4 | This bot searches for comments that are exceptionally long, and saves them for later reading. You can choose any or all of three modes
5 |
6 | - Reddit Saving. PRAW doesn't allow you to save comments. No clue why. Bot will save the submission to its account
7 |
8 | - MAILME. Bot will construct a list at the end of the cycle and send it to you.
9 |
10 | - SUBDUMP. Bot will post a permalink to the comment as 'Author in /r/Subreddit' in your sub
--------------------------------------------------------------------------------
/_old/Novella/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Novella/sql.db
--------------------------------------------------------------------------------
/_old/Nsal/README.md:
--------------------------------------------------------------------------------
1 | NSALeaks
2 | =============
3 |
4 | Written for /u/erktheerk
5 |
6 | Modification of SubDump. Searches for posts in designated subreddits with certain titles and urls. Dumps them into your own subreddit.
7 |
8 | Links in a designated subreddit (Preferably the dumpsub) will undergo an Other Discussions process which finds other posts on reddit which have used the same submission.
--------------------------------------------------------------------------------
/_old/Nsal/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Nsal/sql.db
--------------------------------------------------------------------------------
/_old/Numberwang/README.md:
--------------------------------------------------------------------------------
1 | That's Numberwang!
2 | ========
3 |
4 | Works on the basis of ReplyBot. The last word of a comment must consist entirely of digits and punctuation, and it must be >= 5 characters long. The first five characters of the word must be digits, but the rest of it may be more digits or some punctuation. If these conditions are met, it is Numberwang!
5 |
6 | [Here's an example](http://www.reddit.com/r/GoldTesting/comments/2703dl)
--------------------------------------------------------------------------------
/_old/Numberwang/numberwang.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 | import string
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERAGENT = ""
15 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
16 | SUBREDDIT = "GoldTesting"
17 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
18 | REPLYSTRING = "That's Numberwang!"
19 | #This is the word you want to put in reply
20 | MAXPOSTS = 10
21 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
22 | WAIT = 20
23 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
24 |
25 |
26 | '''All done!'''
27 |
28 |
29 | NUMS = string.digits
30 | PUNC = string.digits + string.punctuation
31 | WAITS = str(WAIT)
32 | try:
33 | import bot
34 | USERAGENT = bot.getaG()
35 | except ImportError:
36 | pass
37 |
38 | sql = sqlite3.connect('sql.db')
39 | print('Loaded SQL Database')
40 | cur = sql.cursor()
41 |
42 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
43 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
44 | print('Loaded Completed table')
45 |
46 | sql.commit()
47 |
48 | r = praw.Reddit(USERAGENT)
49 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
50 | r.refresh_access_information(APP_REFRESH)
51 |
52 | def scanSub():
53 | print('Searching '+ SUBREDDIT + '.')
54 | subreddit = r.get_subreddit(SUBREDDIT)
55 | posts = subreddit.get_comments(limit=MAXPOSTS)
56 | for post in posts:
57 | pid = post.id
58 | pbodysplit = post.body.split()
59 | pnum = pbodysplit[len(pbodysplit)-1]
60 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
61 | if not cur.fetchone():
62 | if all(c in PUNC for c in pnum) and all(c in NUMS for c in pnum[:5]) and len(pnum) >= 5:
63 | print(pid + ": " + pnum + ' is Numberwang!')
64 | post.reply(REPLYSTRING)
65 | else:
66 | print(pid + ' is not Numberwang.')
67 |
68 |
69 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
70 | sql.commit()
71 |
72 |
73 | while True:
74 | try:
75 | scanSub()
76 | except Exception as e:
77 | print('An error has occured:', e)
78 | print('Running again in ' + WAITS + ' seconds \n')
79 | sql.commit()
80 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/Numberwang/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Numberwang/sql.db
--------------------------------------------------------------------------------
/_old/Oldflair/README.md:
--------------------------------------------------------------------------------
1 | Oldflair
2 | ========
3 |
4 | For [/u/lehmongeloh](http://www.reddit.com/user/lehmongeloh) of [/r/randomactsofcards](http://www.reddit.com/r/randomactsofcards) ([thread](http://www.reddit.com/r/RequestABot/comments/2uk0nv/a_bot_that_scans_posts_30_days_old_and_changes/))
5 |
6 | This bot will check the newest 1,000 items from your subreddit and assign a special flair to them if they are over a certain age. 1,000 is the limit because of the way Reddit stores data, so we can't go back any farther. It's unlikely that any normal user will trek back that far anyway.
--------------------------------------------------------------------------------
/_old/Oldflair/oldflair.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import traceback
3 | import praw
4 | import time
5 | import datetime
6 |
7 | ''' USER CONFIGURATION '''
8 |
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERASGENT = ""
15 | # This is a description of what your bot is doing. Include your username
16 | # and be complete
17 |
18 | SUBREDDIT = "randomactsofcards"
19 | # The subreddit on which to operate
20 |
21 | MINIMUM_AGE = 30 * 24 * 60 * 60
22 | # The number of SECONDS in age for the post to receive oldflair
23 | # The above multiplication is 30 days.
24 | OLDFLAIR_TEXT = "Fulfilled"
25 | OLDFLAIR_CSS_CLASS = "fulfilled"
26 | # The text and css class for the flair which you will assign
27 |
28 | OLDFLAIR_COMMENT = """
29 | Your post is 30 days old, was it ever fulfilled?
30 |
31 | Line 2,
32 |
33 | Line 3, etc etc.
34 | """
35 | # This comment will be left on the post when it is oldflaired
36 | # Make the quotes empty "" if you don't want to leave a comment
37 |
38 | BLACKLIST = ["[Thank You]", "Fulfilled", "thanks"]
39 | # This is a list of phrases that, if they are found in the flair
40 | # OR THE TITLE will cause the post to be skipped from the process
41 | # Letter casing does not matter
42 |
43 | WAIT = 120
44 | # The number of seconds between cycles.
45 | # The bot is completely inactive during this time
46 |
47 | ''' All done! '''
48 |
49 |
50 |
51 | try:
52 | import bot
53 | USERAGENT = bot.aG
54 | except ImportError:
55 | pass
56 |
57 | print('Logging in to reddit')
58 | r = praw.Reddit(USERAGENT)
59 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
60 | r.refresh_access_information(APP_REFRESH)
61 |
62 |
63 |
64 | def oldflair():
65 | print('Getting submissions for %s' % SUBREDDIT)
66 | subreddit = r.get_subreddit(SUBREDDIT)
67 | submissions = subreddit.get_new(limit=1000)
68 | nowstamp = datetime.datetime.now(datetime.timezone.utc)
69 | nowstamp = nowstamp.timestamp()
70 |
71 | for submission in submissions:
72 | sid = submission.id
73 | timedif = nowstamp - submission.created_utc
74 | print('Checking %s: ' % sid, end="")
75 | if timedif > MINIMUM_AGE:
76 | sflair_text = submission.link_flair_text
77 | sflair_text = sflair_text.lower() if sflair_text else ''
78 | sflair_css = submission.link_flair_css_class
79 | sflair_css = sflair_css.lower() if sflair_css else ''
80 | stitle = submission.title.lower()
81 | checks = [sflair_text, sflair_css, stitle]
82 | if sflair_text != OLDFLAIR_TEXT.lower() and sflair_css != OLDFLAIR_CSS_CLASS.lower():
83 | if not any(blacklist.lower() in checks for blacklist in BLACKLIST):
84 | print()
85 | print('\tAssigning oldflair')
86 | submission.set_flair(flair_text=OLDFLAIR_TEXT, flair_css_class=OLDFLAIR_CSS_CLASS)
87 | if OLDFLAIR_COMMENT:
88 | print('\tWriting comment')
89 | oldcomment = submission.add_comment(OLDFLAIR_COMMENT)
90 | print('\tDistinguishing comment')
91 | oldcomment.distinguish()
92 | else:
93 | print('Contains blacklisted phrase')
94 | else:
95 | print('All good')
96 | else:
97 | remaining = MINIMUM_AGE - timedif
98 | print('Too young. %s remain' % format_seconds_to_hhmmss(remaining))
99 |
100 | def format_seconds_to_hhmmss(seconds):
101 | #Copied from Stack Overflow http://stackoverflow.com/a/1384506
102 | hours = seconds // (60*60)
103 | seconds %= (60*60)
104 | minutes = seconds // 60
105 | seconds %= 60
106 | return "%02i:%02i:%02i" % (hours, minutes, seconds)
107 |
108 | while True:
109 | try:
110 | oldflair()
111 | except Exception:
112 | traceback.print_exc()
113 | print('Sleeping 20 additional seconds')
114 | time.sleep(20)
115 | print('Sleeping %d seconds' % WAIT)
116 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/OneThenDone/README.md:
--------------------------------------------------------------------------------
1 | OneThenDone
2 | ==========
3 |
4 | Written for [/u/ReplyYouDidntExpect](http://reddit.com/u/replyyoudidntexpect) for [/r/OneThenDone](http://reddit.com/r/onethendone)
5 |
6 | Users are allowed to make exactly one submission to the subreddit. Any more will be removed. They are still allowed to comment on other submissions. You have the choice of sending them a PM when they make their submission, so the rules are clear.
--------------------------------------------------------------------------------
/_old/OneThenDone/onethendone.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 |
6 | '''USER CONFIGURATION'''
7 |
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
15 | SUBREDDIT = "GoldTesting"
16 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
17 |
18 | SENDMESSAGE = True
19 | #Do you want to send them a message indicating the OneThenDone rule? Use True or False, with capitals, no quotations
20 | MESSAGETITLE = "Your /r/OneThenDone post has been processed"
21 | MESSAGEBODY = "Your fate has been sealed. From now on, any submissions you make to /r/OneThenDone will be removed."
22 | #If SENDMESSAGE is True, this will be sent as a PM when they make their submission
23 | #Remember that it follows markdown formatting, where "\n" will represent hitting Enter
24 |
25 | MAXPOSTS = 100
26 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
27 | WAIT = 20
28 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
29 |
30 |
31 | '''All done!'''
32 |
33 |
34 |
35 |
36 | WAITS = str(WAIT)
37 | try:
38 | import bot
39 | USERAGENT = bot.aG
40 | except ImportError:
41 | pass
42 |
43 | sql = sqlite3.connect('sql.db')
44 | print('Loaded SQL Database')
45 | cur = sql.cursor()
46 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(id TEXT, username TEXT)')
47 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
48 | print('Loaded Completed table')
49 |
50 | sql.commit()
51 |
52 | r = praw.Reddit(USERAGENT)
53 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
54 | r.refresh_access_information(APP_REFRESH)
55 |
56 | def scanSub():
57 | print('Searching '+ SUBREDDIT + '.')
58 | subreddit = r.get_subreddit(SUBREDDIT)
59 | posts = subreddit.get_new(limit=MAXPOSTS)
60 | for post in posts:
61 | pid = post.id
62 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
63 | if not cur.fetchone():
64 | try:
65 | success = False
66 | pauthor = post.author.name
67 | cur.execute('SELECT * FROM oldposts WHERE username=?', [pauthor])
68 | if not cur.fetchone():
69 | print(pid, pauthor + ': Successful submission.')
70 | if SENDMESSAGE:
71 | pass
72 | try:
73 | r.send_message(pauthor, MESSAGETITLE, MESSAGEBODY, captcha=None)
74 | success = True
75 | pass
76 | except:
77 | print(pid, 'Message failed to send. Will not mark in database')
78 | else:
79 | success = True
80 | else:
81 | print(pid, pauthor + ': Duplicate submission, removing')
82 | success = True
83 | post.remove()
84 | if success:
85 | cur.execute('INSERT INTO oldposts VALUES(?, ?)', [pid, pauthor])
86 | except AttributeError:
87 | pauthor = '[DELETED]'
88 | print(pid, 'Deleted Author, ignoring')
89 | sql.commit()
90 |
91 |
92 | while True:
93 | try:
94 | scanSub()
95 | except Exception as e:
96 | print('An error has occured:', e)
97 | print('Running again in ' + WAITS + ' seconds \n')
98 | sql.commit()
99 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/OneThenDone/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/OneThenDone/sql.db
--------------------------------------------------------------------------------
/_old/Overlap/README.md:
--------------------------------------------------------------------------------
1 | Overlap
2 | =======
3 |
4 | See where else your users are posting.
5 |
6 | Still working on features.
--------------------------------------------------------------------------------
/_old/PFStickyComments/README.md:
--------------------------------------------------------------------------------
1 | Sticky Comments
2 | ===============
3 |
4 | [/r/PersonalFinance](http://reddit.com/r/personalfinance) is using some special CSS to make certain comments appear at the top of the thread. This bot will track a designated user / users and sticky every comment they make.
5 |
6 | CSS trick here: https://www.reddit.com/r/modclub/comments/2mv444/true_sticky_comments_with_some_css3_magic/cn0li1k
7 |
8 | Examples here: https://www.reddit.com/r/GoldTesting/comments/39x5b8/testing_the_biowiki_bot_again/
9 |
10 | Seen in stylesheet here: https://www.reddit.com/r/GoldTesting/about/stylesheet/
11 |
12 |
13 |
14 | If the bot cannot find the anchor text that it needs to find the VIP's name and the sticky ID list, it will remove itself as a moderator so that you may fix the issue.
15 |
16 | stickycomments_individual.py keeps the subreddit and username hardcoded. It may be more suitable if you're only running this in a single place.
--------------------------------------------------------------------------------
/_old/PFStickyComments/stickycomments.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/PFStickyComments/stickycomments.db
--------------------------------------------------------------------------------
/_old/Pointreminder/README.md:
--------------------------------------------------------------------------------
1 | Pointreminder
2 | ========
3 |
4 | For [/u/Livebeef](http://reddit.com/u/livebeef) for [/r/TheyDidTheMath](http://reddit.com/r/theydidthemath)
5 |
6 | Based on replybot. Reminds OP to award points to the people who have done his math. Optional `TITLETAG` variable makes this only work on posts with a certain tag in the title or flair.
--------------------------------------------------------------------------------
/_old/Pointreminder/pointreminder.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import traceback
3 | import praw # simple interface to the reddit API, also handles rate limiting of requests
4 | import time
5 | import sqlite3
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERAGENT = ""
15 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
16 | SUBREDDIT = "GoldTesting"
17 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
18 | TITLETAG = "[request]"
19 | #If this is non-blank, then this string must be in the title or flair of the post to work
20 | TRIGGERS = ["thanks"]
21 | #These tell the bot to make the comment
22 | TRIGGERREQUIRED = False
23 | #If this is True, the comment must contain a trigger to post
24 | #If this is False, the comment will be posted as long as there are no anti-triggers
25 | #Anti-triggers will ALWAYS deny the post.
26 | ANTITRIGGERS = ["✓", "thanks but", "thanks, but"]
27 | #These force the bot not to make the comment.
28 | REPLYSTRING = "Dont forget to give a ✓"
29 | #This is the word you want to put in reply
30 | MAXPOSTS = 100
31 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
32 | WAIT = 20
33 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
34 |
35 |
36 | '''All done!'''
37 |
38 |
39 |
40 |
41 | WAITS = str(WAIT)
42 | try:
43 | import bot
44 | USERAGENT = bot.aG
45 | except ImportError:
46 | pass
47 |
48 | sql = sqlite3.connect('sql.db')
49 | print('Loaded SQL Database')
50 | cur = sql.cursor()
51 |
52 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
53 | print('Loaded Completed table')
54 |
55 | sql.commit()
56 |
57 | r = praw.Reddit(USERAGENT)
58 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
59 | r.refresh_access_information(APP_REFRESH)
60 |
61 | def scanSub():
62 | print('Searching '+ SUBREDDIT + '.')
63 | subreddit = r.get_subreddit(SUBREDDIT)
64 | posts = subreddit.get_comments(limit=MAXPOSTS)
65 | for post in posts:
66 | pid = post.fullname
67 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
68 | if not cur.fetchone():
69 | if not post.is_root:
70 | print('Getting submission for ' + pid)
71 | submission = post.submission
72 | if not submission.link_flair_text:
73 | submission.link_flair_text = ""
74 | stitle = submission.title.lower()+' '+submission.link_flair_text.lower()
75 | if TITLETAG == "" or TITLETAG.lower() in stitle:
76 | try:
77 | pauthor = post.author.name
78 | sauthor = submission.author.name
79 | if pauthor == sauthor:
80 | if TRIGGERREQUIRED ==False or any(trig.lower() in post.body.lower() for trig in TRIGGERS):
81 | if not any(atrig.lower() in post.body.lower() for atrig in ANTITRIGGERS):
82 | print('Replying to ' + pauthor + ', ' + pid)
83 | post.reply(REPLYSTRING)
84 | except AttributeError:
85 | print('Either commenter or OP is deleted. Skipping.')
86 |
87 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
88 | sql.commit()
89 |
90 |
91 | while True:
92 | try:
93 | scanSub()
94 | except Exception as e:
95 | traceback.print_exc()
96 | print('Running again in ' + WAITS + ' seconds \n')
97 | sql.commit()
98 | time.sleep(WAIT)
99 |
100 |
--------------------------------------------------------------------------------
/_old/Pointreminder/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Pointreminder/sql.db
--------------------------------------------------------------------------------
/_old/PointsBot/README.md:
--------------------------------------------------------------------------------
1 | PointsBot
2 | =========
3 |
4 | By saying a certain keyword, a user may give a "point" to the person who he replied to. Points are stored as flair. Here are some of the things the config can do:
5 |
6 | - Allow any user to distribute points, or only the OP of the thread
7 |
8 | - Allow only a certain number of points to be distributed in a single thread
9 |
10 | - Put users on an "exempt" list. Exempt users will not receive points. This is useful if they have special flair and you don't want to disrupt it
11 |
12 | [See here](http://www.reddit.com/r/GoldTesting/comments/2bzkp9/thing/)
13 |
14 | There is a new version of pointsbot which keeps a leaderboard in your sidebar and on a wiki page.
15 |
16 | see http://www.reddit.com/r/GoldTesting/wiki/leaderboard
--------------------------------------------------------------------------------
/_old/PointsBot/ScoreboardAddUser.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw
3 | import time
4 | import sqlite3
5 |
6 | '''USER CONFIGURATION'''
7 | APP_ID = ""
8 | APP_SECRET = ""
9 | APP_URI = ""
10 | APP_REFRESH = ""
11 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
12 | USERAGENT = ""
13 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
14 | SUBREDDIT = "goldtesting"
15 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
16 | '''All done!'''
17 |
18 |
19 | try:
20 | import bot
21 | USERAGENT = bot.aG
22 | except ImportError:
23 | pass
24 |
25 | sql = sqlite3.connect('sql.db')
26 | print('Loaded SQL Database')
27 | cur = sql.cursor()
28 | cur.execute('CREATE TABLE IF NOT EXISTS users(NAME TEXT, POINTS TEXT)')
29 | print('Loaded Completed table')
30 | sql.commit()
31 |
32 | print("Logging in")
33 | r = praw.Reddit(USERAGENT)
34 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
35 | r.refresh_access_information(APP_REFRESH)
36 |
37 |
38 | def operate():
39 | subreddit = r.get_subreddit(SUBREDDIT)
40 | name = input('Get flair for /u/')
41 | flair = subreddit.get_flair(name)
42 | name = flair['user']
43 | flair = flair['flair_text']
44 | if flair:
45 | print(flair)
46 | cur.execute('SELECT * FROM users WHERE NAME=?', [name])
47 | f= cur.fetchone()
48 | if f:
49 | print('updating')
50 | cur.execute('UPDATE users SET POINTS=? WHERE NAME=?', [flair, name])
51 | else:
52 | print('new entry')
53 | cur.execute('INSERT INTO users VALUES(?, ?)', [name, flair])
54 | sql.commit()
55 | else:
56 | print(name, "has no flair")
57 | print()
58 |
59 | while True:
60 | operate()
61 | print()
--------------------------------------------------------------------------------
/_old/PointsBot/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/PointsBot/sql.db
--------------------------------------------------------------------------------
/_old/Politician/README.md:
--------------------------------------------------------------------------------
1 | Politician
2 | ==========
3 |
4 | When the bot sees a comment or submission that mentions the name of a US congressperson, it will provide some info from http://opensecrets.org, giving a brief rundown of their fundraising efforts and largest contributors.
5 |
6 | [See here](http://www.reddit.com/r/GoldTesting/comments/2gj3mu/politician_info_testing/) or [here](http://www.reddit.com/r/GoldTesting/comments/2gj5yo/politician_info_test_2/) or [here](http://www.reddit.com/r/GoldTesting/comments/2gj6vm/politician_info_test_3/) for examples.
--------------------------------------------------------------------------------
/_old/Politician/blacklist.txt:
--------------------------------------------------------------------------------
1 | You may only have one username per line
2 |
--------------------------------------------------------------------------------
/_old/Politician/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Politician/sql.db
--------------------------------------------------------------------------------
/_old/Politician/subreddit.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Politician/subreddit.txt
--------------------------------------------------------------------------------
/_old/QuoteMe/README.md:
--------------------------------------------------------------------------------
1 | QuoteMe
2 | =============
3 |
4 | This bot works on the same premise as ReplyBot, but generates replies dynamically instead of posting a pre-designated phrase.
--------------------------------------------------------------------------------
/_old/QuoteMe/quoteme.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 |
6 | '''USER CONFIGURATION'''
7 |
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
15 | SUBREDDIT = "all"
16 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
17 | PARENTSTRING = ["don't quote me", "dont quote me"]
18 | #These are the words you are looking for
19 | MAXPOSTS = 100
20 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
21 | WAIT = 10
22 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
23 |
24 |
25 | '''All done!'''
26 |
27 |
28 |
29 |
30 | WAITS = str(WAIT)
31 | try:
32 | import bot
33 | USERAGENT = bot.getaG()
34 | except ImportError:
35 | pass
36 |
37 | sql = sqlite3.connect('sql.db')
38 | print('Loaded SQL Database')
39 | cur = sql.cursor()
40 |
41 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
42 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
43 | print('Loaded Completed table')
44 |
45 | sql.commit()
46 |
47 | r = praw.Reddit(USERAGENT)
48 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
49 | r.refresh_access_information(APP_REFRESH)
50 |
51 | def scanSub():
52 | print('Searching '+ SUBREDDIT + '.')
53 | subreddit = r.get_subreddit(SUBREDDIT)
54 | posts = subreddit.get_comments(limit=MAXPOSTS)
55 | for post in posts:
56 | pid = post.id
57 | pbody = post.body
58 | pbody = pbody.replace('\n\n', '.\n\n>')
59 | if any(key.lower() in pbody.lower() for key in PARENTSTRING):
60 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
61 | if not cur.fetchone():
62 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
63 | pbodysplit = pbody.split('.')
64 | for sent in pbodysplit:
65 | if any(key.lower() in sent.lower() for key in PARENTSTRING):
66 | try:
67 | pauthor = post.author.name
68 | if pauthor != r.user.name:
69 | response = ">" + sent + "\n\n- /u/" + pauthor
70 | print('Replying to ' + pid + ' by ' + pauthor)
71 | print(sent.strip())
72 | post.reply(response)
73 | break
74 | except Exception:
75 | print('Failed.')
76 | sql.commit()
77 |
78 | while True:
79 | try:
80 | scanSub()
81 | except Exception as e:
82 | print('An error has occured:', str(e))
83 | print('Running again in ' + WAITS + ' seconds \n')
84 | sql.commit()
85 | time.sleep(WAIT)
86 |
--------------------------------------------------------------------------------
/_old/QuoteMe/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/QuoteMe/sql.db
--------------------------------------------------------------------------------
/_old/R4R/README.md:
--------------------------------------------------------------------------------
1 | R4R
2 | ===
3 |
4 | Measure the statistics of R4R interactions
5 |
6 | This program tells you what you already know. There's no real point in running it.
7 |
8 | It scans three of the four popular dirtyR4R subreddits, and measures the popularity of F4M posts and M4F posts. Posts made by females invariably gather more attention than posts made by males, but you can see for yourself.
9 |
--------------------------------------------------------------------------------
/_old/R4R/resultsummary.txt:
--------------------------------------------------------------------------------
1 | penpals 28 male posts, 18 comments total, 0.643 average 47 points total, 1.679 average
2 | dirtypenpals 37 male posts, 0 comments total, 0.000 average 12 points total, 0.324 average
3 | r4r 41 male posts, 3 comments total, 0.073 average 6 points total, 0.146 average
4 | dirtyr4r 43 male posts, 1 comments total, 0.023 average -12 points total, -0.279 average
5 | kikpals 40 male posts, 5 comments total, 0.125 average 5 points total, 0.125 average
6 | dirtykikpals 47 male posts, 3 comments total, 0.064 average -5 points total, -0.106 average
7 | makenewfriendshere 21 male posts, 22 comments total, 1.048 average 28 points total, 1.333 average
8 | needafriend 19 male posts, 14 comments total, 0.737 average 18 points total, 0.947 average
9 | TOTAL: 276 66 0.2391 99 0.3587
10 |
11 |
12 | penpals 14 female posts, 25 comments total, 1.786 average 46 points total, 3.286 average
13 | dirtypenpals 11 female posts, 4 comments total, 0.364 average 9 points total, 0.818 average
14 | r4r 9 female posts, 13 comments total, 1.444 average -1 points total, -0.111 average
15 | dirtyr4r 6 female posts, 9 comments total, 1.500 average 3 points total, 0.500 average
16 | kikpals 10 female posts, 21 comments total, 2.100 average 0 points total, 0.000 average
17 | dirtykikpals 3 female posts, 4 comments total, 1.333 average -2 points total, -0.667 average
18 | makenewfriendshere 7 female posts, 13 comments total, 1.857 average 24 points total, 3.429 average
19 | needafriend 11 female posts, 25 comments total, 2.273 average 34 points total, 3.091 average
20 | TOTAL: 71 114 1.6056 113 1.5915
--------------------------------------------------------------------------------
/_old/RafflerC/README.md:
--------------------------------------------------------------------------------
1 | Raffler (Comments)
2 | ==========
3 |
4 | This is a utility rather than a bot.
5 |
6 | - Give it the permalink or the id number of a thread. If you hit Enter without typing anything, it will take whatever is in your clipboard.
7 |
8 | - It finds the submission object, and pulls all of the root comments.
9 |
10 | - They are put into a .txt file with the oldest comment at the top, numbered starting from 1. Multiple comments by the same user will not be considered.
11 |
12 | - The report will suggest a random user to you, but you could use [Random.org](http://random.org) for true-random instead.
13 |
14 | Gathering the comments can take a very long time on big threads. In order to ensure fairness, the script will grab *every single comment* in the thread. Every time you see the "load more comments" button in a thread, that's where the bot needs to spend an additional 2 seconds to get them. Just let it run.
15 |
--------------------------------------------------------------------------------
/_old/RafflerC/raffler.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | from tkinter import Tk
5 | import random
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | USERAGENT = ""
10 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
11 | PRINTFILE = "result.txt"
12 | #This is the file where the results will go. In the same folder as this py file
13 |
14 | '''All done!'''
15 |
16 |
17 |
18 | try:
19 | import bot
20 | USERAGENT = bot.getaG()
21 | except ImportError:
22 | pass
23 |
24 |
25 | r = praw.Reddit(USERAGENT)
26 |
27 | printfile = open(PRINTFILE, 'a+')
28 | printfile.close()
29 | #Hackjob method of creating file if it does not exist.
30 |
31 | print('Permalink to thread\nLeave empty to paste from clipboard')
32 | i = input('>')
33 | pid = ''
34 | if i == '':
35 | t = Tk()
36 | t.withdraw()
37 | link = t.selection_get(selection = "CLIPBOARD")
38 | elif len(i) == 6:
39 | pid = i
40 | link = ''
41 | else:
42 | link = i
43 | if 'www.reddit.com/r/' in link and '/comments/' in link:
44 | pid = link.split('/comments/')[1].split('/')[0]
45 | if 'http://redd.it/' in link:
46 | pid = link.split('redd.it/')[1]
47 | print('\nThread ID: ' + pid)
48 | print('Grabbing Thread')
49 | try:
50 | post = r.get_info(thing_id='t3_' + pid)
51 | print('Pulling Root comments.')
52 | post.replace_more_comments(limit=None, threshold=0)
53 | comments = praw.helpers.flatten_tree(post.comments)
54 | except:
55 | print('[ERR] Failed')
56 | input()
57 | quit()
58 | clist = []
59 | nlist = []
60 | for comment in comments:
61 | if comment.is_root:
62 | try:
63 | author = comment.author.name
64 | if author not in nlist:
65 | nlist.append(author)
66 | clist.append(comment)
67 | except:
68 | pass
69 | print('Sorting.')
70 | clist.sort(key=lambda x: x.created_utc)
71 | printfile = open(PRINTFILE, 'w')
72 | m = 1
73 | rand = random.randint(1,len(clist))
74 | print('Thread: ' + pid + '\n\n' + str(len(clist)) + ' root comments\n\nRandom Number: ' + str(rand) + ' : ' + clist[rand-1].author.name + '\n', file=printfile)
75 | for name in clist:
76 | print(str(m) + ' : ' + name.author.name, file=printfile)
77 | m+=1
78 | printfile.close()
79 | print('Done.')
80 | input()
--------------------------------------------------------------------------------
/_old/RafflerC/result.txt:
--------------------------------------------------------------------------------
1 | Thread: 2a6925
2 |
3 | 95 comments
4 |
5 | Random Number: 29 : squeeeeenis
6 |
7 | 1 : Buzanks
8 | 2 : TheRatSquid
9 | 3 : captainsinfonia
10 | 4 : iam4real
11 | 5 : refinnej78
12 | 6 : TheKnightsTippler
13 | 7 : who-boppin
14 | 8 : piepiepie2ooo
15 | 9 : OperationRedcue
16 | 10 : one_long_year
17 | 11 : its_interactive
18 | 12 : OverLordBritish
19 | 13 : mrshatnertoyou
20 | 14 : Quadell
21 | 15 : bloodshake
22 | 16 : PM-YOUR-SECRETS
23 | 17 : DementedUnicorn
24 | 18 : Fetus_Soup
25 | 19 : oilslicksunset
26 | 20 : potatobreaker
27 | 21 : MisterWoodles
28 | 22 : inserttitlehere
29 | 23 : burn__the__witch
30 | 24 : gnarfler
31 | 25 : pocketpark
32 | 26 : qaboutp
33 | 27 : Austin_rock
34 | 28 : necrokitty
35 | 29 : squeeeeenis
36 | 30 : molecularity
37 | 31 : MrAggressive
38 | 32 : CapnTBC
39 | 33 : NeedHelpWithExcel
40 | 34 : RamsesThePigeon
41 | 35 : Bluebe123
42 | 36 : ed8484
43 | 37 : essen23
44 | 38 : christiansi1
45 | 39 : rwildhorseranch
46 | 40 : Bkaps
47 | 41 : btbnashua1961
48 | 42 : LegendaryGinger
49 | 43 : forgotten_sound
50 | 44 : rushinftl
51 | 45 : PM_ME_GOALS
52 | 46 : ickypicky
53 | 47 : Im_Not_That_Smart
54 | 48 : Dinosaurus_Rexx
55 | 49 : redcolumbine
56 | 50 : PresidentFecalstein
57 | 51 : fecesinmyreeses
58 | 52 : The_Coonster
59 | 53 : KingDDD
60 | 54 : Jesus_The_Super_Jew
61 | 55 : karmacraze
62 | 56 : floatingonelectrons
63 | 57 : OBAFGKM17
64 | 58 : itouchedthebutt69
65 | 59 : MerkinDealer
66 | 60 : Bassoon_Commie
67 | 61 : damsterick
68 | 62 : pilchums
69 | 63 : Fisdenallus
70 | 64 : ShaggyTraveler
71 | 65 : token_bastard
72 | 66 : rug0408
73 | 67 : space_titties
74 | 68 : ivy1991
75 | 69 : societyred
76 | 70 : KangarooZombie24
77 | 71 : getElephantById
78 | 72 : verygoodyear
79 | 73 : slenderandabitlonely
80 | 74 : violinsontv
81 | 75 : benwilliams9
82 | 76 : hawkin712
83 | 77 : GRIMMnM
84 | 78 : AmeliaPondPandorica
85 | 79 : measuredsharky
86 | 80 : RedheadBanshee
87 | 81 : RJBlain
88 | 82 : BadDreamInc
89 | 83 : TaraRosey
90 | 84 : PM_ME_YOUR_LIGER
91 | 85 : _head_
92 | 86 : ThoughtRiot1776
93 | 87 : FirstAidKit_Kat
94 | 88 : ButtsexEurope
95 | 89 : PsychedelicFish
96 | 90 : Bronzedog
97 | 91 : Ry_Ry_Raincoat
98 | 92 : KelpyCabin
99 | 93 : 123Keks
100 | 94 : jberd45
101 | 95 : NeonMe
102 |
--------------------------------------------------------------------------------
/_old/RankFlair/README.md:
--------------------------------------------------------------------------------
1 | RankFlair
2 | =========
3 |
4 | Assigns flair to posts based on their rank in a subreddit's top-of-all-time listing (ex: [/r/botwatch/top/?sort=top&t=all](http://reddit.com/r/botwatch/top/?sort=top&t=all))
5 |
6 | A post's flair can increase in rank as the post moves upward, but it will never decrease - A post will keep the highest ranking flair it has ever achieved.
7 |
8 | rankflair_gws is modified to be used specifically by /r/gonewildsmiles (nsfw). It was best to make a separate file out of this.
--------------------------------------------------------------------------------
/_old/Redmash/#goldtesting_breakdown.json:
--------------------------------------------------------------------------------
1 | {
2 | "GoldenSights":{"submissions":88, "comments":177},
3 | "75000":{"submissions":4, "comments":56},
4 | "[DELETED]":{"submissions":0, "comments":42},
5 | "WeatherReportBot":{"submissions":1, "comments":26},
6 | "LondonRuek":{"submissions":4, "comments":20},
7 | "LiveBeef":{"submissions":2, "comments":19},
8 | "checks_for_checks":{"submissions":0, "comments":19},
9 | "erktheerk":{"submissions":0, "comments":15},
10 | "HououinKyouma1":{"submissions":0, "comments":12},
11 | "ingenious_testbot":{"submissions":1, "comments":10},
12 | "livebeef_test":{"submissions":1, "comments":8},
13 | "Onikouzou":{"submissions":1, "comments":7},
14 | "Tjstretchalot":{"submissions":0, "comments":7},
15 | "youremailsucks":{"submissions":0, "comments":5},
16 | "doufous":{"submissions":0, "comments":5},
17 | "ingeniousclown":{"submissions":1, "comments":3},
18 | "poisonousdev":{"submissions":1, "comments":2},
19 | "Newsletterly":{"submissions":0, "comments":3},
20 | "Kenblu24":{"submissions":0, "comments":3},
21 | "Katoffels":{"submissions":0, "comments":3},
22 | "ApexRedditr":{"submissions":0, "comments":3},
23 | "sjelsdal":{"submissions":0, "comments":2},
24 | "pineapple___man":{"submissions":1, "comments":1},
25 | "phil_s_stein":{"submissions":0, "comments":2},
26 | "graceryoutubebot":{"submissions":1, "comments":1},
27 | "AngryWeatherBot":{"submissions":0, "comments":2},
28 | "wrestlebot":{"submissions":1, "comments":0},
29 | "r2d8":{"submissions":0, "comments":1},
30 | "r2d10":{"submissions":0, "comments":1},
31 | "prodigytech":{"submissions":0, "comments":1},
32 | "my8thchannel":{"submissions":0, "comments":1},
33 | "mralext20":{"submissions":0, "comments":1},
34 | "madhousechild":{"submissions":0, "comments":1},
35 | "lolbasicsbot":{"submissions":0, "comments":1},
36 | "hungryhungrybot":{"submissions":0, "comments":1},
37 | "gfy_fixer":{"submissions":0, "comments":1},
38 | "fakey2342":{"submissions":0, "comments":1},
39 | "dillonbob":{"submissions":0, "comments":1},
40 | "captobvious24":{"submissions":0, "comments":1},
41 | "autowikibot":{"submissions":0, "comments":1},
42 | "auto-bot":{"submissions":1, "comments":0},
43 | "Wildcat7878":{"submissions":0, "comments":1},
44 | "Undercover5051":{"submissions":0, "comments":1},
45 | "SmBe19":{"submissions":0, "comments":1},
46 | "Sir_Tinklebottom":{"submissions":0, "comments":1},
47 | "SadBearRAWR":{"submissions":1, "comments":0},
48 | "Roar-Of-Time":{"submissions":0, "comments":1},
49 | "QuoteMeBot":{"submissions":0, "comments":1},
50 | "Ninja-Clone":{"submissions":0, "comments":1},
51 | "MrDHC":{"submissions":0, "comments":1},
52 | "MoederPoeder":{"submissions":0, "comments":1},
53 | "IllusionBot":{"submissions":1, "comments":0},
54 | "Eat_The_Muffin":{"submissions":0, "comments":1}
55 | }
56 |
--------------------------------------------------------------------------------
/_old/Redmash/@goldensights_breakdown.json:
--------------------------------------------------------------------------------
1 | {
2 | "GoldTesting":{"submissions":88, "comments":0},
3 | "CopperplateGothic":{"submissions":49, "comments":0},
4 | "spumwack":{"submissions":17, "comments":0},
5 | "spam":{"submissions":8, "comments":0},
6 | "learnpython":{"submissions":8, "comments":0},
7 | "test":{"submissions":5, "comments":0},
8 | "redditdev":{"submissions":4, "comments":0},
9 | "cutouts":{"submissions":4, "comments":0},
10 | "softwaregore":{"submissions":3, "comments":0},
11 | "reddittips":{"submissions":3, "comments":0},
12 | "notinteresting":{"submissions":3, "comments":0},
13 | "tipofmytongue":{"submissions":2, "comments":0},
14 | "switcharoo":{"submissions":2, "comments":0},
15 | "shittyprogramming":{"submissions":2, "comments":0},
16 | "mindcrack":{"submissions":2, "comments":0},
17 | "ideasfortheadmins":{"submissions":2, "comments":0},
18 | "dataisbeautiful":{"submissions":2, "comments":0},
19 | "countrychallenge":{"submissions":2, "comments":0},
20 | "bugs":{"submissions":2, "comments":0},
21 | "SourceEngine":{"submissions":2, "comments":0},
22 | "NoStupidQuestions":{"submissions":2, "comments":0},
23 | "windowsphone":{"submissions":1, "comments":0},
24 | "whatstheword":{"submissions":1, "comments":0},
25 | "wartrade":{"submissions":1, "comments":0},
26 | "wacom":{"submissions":1, "comments":0},
27 | "tf2":{"submissions":1, "comments":0},
28 | "tekkit":{"submissions":1, "comments":0},
29 | "techsupport":{"submissions":1, "comments":0},
30 | "reditr":{"submissions":1, "comments":0},
31 | "redditrequest":{"submissions":1, "comments":0},
32 | "rage":{"submissions":1, "comments":0},
33 | "newsubreddits":{"submissions":1, "comments":0},
34 | "loadingicon":{"submissions":1, "comments":0},
35 | "krush":{"submissions":1, "comments":0},
36 | "howto":{"submissions":1, "comments":0},
37 | "hammer":{"submissions":1, "comments":0},
38 | "findareddit":{"submissions":1, "comments":0},
39 | "explainlikeimtwitter":{"submissions":1, "comments":0},
40 | "excgarated":{"submissions":1, "comments":0},
41 | "casualiama":{"submissions":1, "comments":0},
42 | "botwatch":{"submissions":1, "comments":0},
43 | "botsrights":{"submissions":1, "comments":0},
44 | "Vaporwave":{"submissions":1, "comments":0},
45 | "TheStopGirl":{"submissions":1, "comments":0},
46 | "Terraria":{"submissions":1, "comments":0},
47 | "RequestABot":{"submissions":1, "comments":0},
48 | "Random_Acts_Of_Amazon":{"submissions":1, "comments":0},
49 | "RESissues":{"submissions":1, "comments":0},
50 | "ProgrammerHumor":{"submissions":1, "comments":0},
51 | "Playdate":{"submissions":1, "comments":0},
52 | "Mangoes":{"submissions":1, "comments":0},
53 | "InvisiBall":{"submissions":1, "comments":0},
54 | "GitarhamQuotes":{"submissions":1, "comments":0},
55 | "CrazyIdeas":{"submissions":1, "comments":0},
56 | "CrappyDesign":{"submissions":1, "comments":0},
57 | "AnimalsWithoutNecks":{"submissions":1, "comments":0},
58 | "195":{"submissions":1, "comments":0},
59 | "1920x1080":{"submissions":1, "comments":0}
60 | }
61 |
--------------------------------------------------------------------------------
/_old/Redmash/README.md:
--------------------------------------------------------------------------------
1 | REDMASH
2 | ==========
3 |
4 | This file is being merged with timesearch. https://github.com/voussoir/reddit/tree/master/Prawtimestamps
--------------------------------------------------------------------------------
/_old/ReplyBot/README.md:
--------------------------------------------------------------------------------
1 | ReplyBot
2 | ========
3 |
4 | 22 Apr 2015 - ReplyBot will now auto-clean its database every 10 cycles. It will keep the latest (2 * MAXPOSTS) items, so disk space isn't wasted by comments you'll never see again anyway.
5 |
6 | The most basic bot. Searches a subreddit's comments for certain keywords, and replies to the comment if it finds any. You can have multiple keyword triggers, but you only have one reply out-of-the-box.
7 |
8 | People ask for these all the time. Be aware of how spammy they can get. If people think your bot is stupid, they will report it. Use ReplyBot as a learning tool, but do not rehash old jokes for the sake of rehashed jokes.
9 |
10 | [Want multiple responses?](https://github.com/voussoir/reddit/tree/master/ReplyDict)
11 |
--------------------------------------------------------------------------------
/_old/ReplyDict/README.md:
--------------------------------------------------------------------------------
1 | ReplyDict
2 | ==========
3 |
4 | A modified version of ReplyBot that puts a heavy emphasis on a JSON-like dict stored in a txt file. If the item on the left is found in a comment, the bot will reply with the item on the right.
5 |
6 | You may change the RESULTFORM variable to change how the data appears.
7 |
8 | [example](http://www.reddit.com/r/GoldTesting/comments/2hl7ic/replydict_testing/)
--------------------------------------------------------------------------------
/_old/ReplyDict/snakes.txt:
--------------------------------------------------------------------------------
1 | {
2 | "Agkistrodon contortrix":"http://en.wikipedia.org/wiki/Agkistrodon_contortrix",
3 | "Agkistrodon piscivorus":"http://en.wikipedia.org/wiki/Agkistrodon_piscivorus",
4 | "Carphophis amoenus":"http://en.wikipedia.org/wiki/Carphophis_amoenus",
5 | "Cemophora coccinea copei":"http://en.wikipedia.org/wiki/Cemophora_coccinea_copei",
6 | "Coluber Constrictor":"http://en.wikipedia.org/wiki/Coluber_constrictor",
7 | "Crotalus horridus":"http://en.wikipedia.org/wiki/Crotalus_horridus",
8 | "Crotalus oreganus cerberus":"http://en.wikipedia.org/wiki/Crotalus_oreganus_cerberus",
9 | "Diadophis punctatus":"http://en.wikipedia.org/wiki/Diadophis_punctatus",
10 | "Elaphe guttata":"http://en.wikipedia.org/wiki/Corn_snake",
11 | "Elaphe obsoleta":"http://en.wikipedia.org/wiki/Western_rat_snake",
12 | "Farancia abacura":"http://en.wikipedia.org/wiki/Mud_snake",
13 | "Farancia erytrogramma":"http://en.wikipedia.org/wiki/Farancia_erytrogramma",
14 | "Heterodon":"http://en.wikipedia.org/wiki/Heterodon",
15 | "Lampropeltis calligaster":"http://en.wikipedia.org/wiki/Lampropeltis_calligaster",
16 | "Lampropeltis elapsoides":"http://en.wikipedia.org/wiki/Lampropeltis_elapsoides",
17 | "Lampropeltis getula":"http://en.wikipedia.org/wiki/Lampropeltis_getula",
18 | "Lampropeltis Triangulum":"http://en.wikipedia.org/wiki/Milk_snake",
19 | "Masticophis flagellum":"http://en.wikipedia.org/wiki/Masticophis_flagellum",
20 | "Micrurus fulvius":"http://en.wikipedia.org/wiki/Micrurus_fulvius",
21 | "Nerodia":"http://en.wikipedia.org/wiki/Nerodia",
22 | "Opheodrys aestivus":"http://en.wikipedia.org/wiki/Opheodrys_aestivus",
23 | "Pantherophis obsoletus":"http://en.wikipedia.org/wiki/Western_rat_snake",
24 | "Pituophis melanoleucus":"http://en.wikipedia.org/wiki/Pituophis_melanoleucus",
25 | "Regina rigida":"http://en.wikipedia.org/wiki/Regina_rigida",
26 | "Regina septemvittata":"http://en.wikipedia.org/wiki/Queen_snake",
27 | "Rhadinaea flavilata":"http://en.wikipedia.org/wiki/Pine_woods_snake",
28 | "Seminatrix":"http://en.wikipedia.org/wiki/Seminatrix",
29 | "Sistrurus miliarius":"http://en.wikipedia.org/wiki/Sistrurus_miliarius",
30 | "Storeria dekayi":"http://en.wikipedia.org/wiki/Storeria_dekayi",
31 | "Storeria occipitomaculata":"http://en.wikipedia.org/wiki/Storeria_occipitomaculata",
32 | "Tantilla coronate":"http://en.wikipedia.org/wiki/Southeastern_crown_snake",
33 | "Thamnophis sauritus":"http://en.wikipedia.org/wiki/Eastern_Ribbon_Snake",
34 | "Thamnophis":"http://en.wikipedia.org/wiki/Garter_snake",
35 | "Virginia striatula":"http://en.wikipedia.org/wiki/Virginia_striatula",
36 | "Virginia valeriae":"http://en.wikipedia.org/wiki/Virginia_valeriae"
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/_old/ReplyPosts/README.md:
--------------------------------------------------------------------------------
1 | ReplyPosts
2 | ========
3 |
4 | This bot has been merged with [ReplyBot](https://github.com/voussoir/reddit/tree/master/ReplyBot). See the `DO_SUBMISSIONS` and `DO_COMMENTS` variables.
--------------------------------------------------------------------------------
/_old/ReplyPosts/replyposts.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import traceback
3 | import praw
4 | import time
5 | import sqlite3
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERAGENT = ""
15 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
16 | SUBREDDIT = "GoldTesting"
17 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
18 | SEARCHTITLE = True
19 | SEARCHTEXT = False
20 | #Should the bot check within the title?
21 | #Should the bot check within the selftext?
22 | KEYWORDS = ["phrase 1", "phrase 2", "phrase 3", "phrase 4"]
23 | #These are the words you are looking for.
24 | #Make empty to reply to ANY post that also matches keyauthor
25 | KEYAUTHORS = ["GoldenSights"]
26 | #These are the names of the authors you are looking for
27 | #Any authors not on this list will not be replied to.
28 | #Make empty to allow anybody
29 | REPLYSTRING = "Hi hungry, I'm dad"
30 | #This is the word you want to put in reply
31 | MAXPOSTS = 100
32 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
33 | WAIT = 20
34 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
35 |
36 | try:
37 | import bot
38 | USERAGENT = bot.getaG()
39 | except ImportError:
40 | pass
41 |
42 | sql = sqlite3.connect('replyposts.db')
43 | print('Loaded SQL Database')
44 | cur = sql.cursor()
45 |
46 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
47 | print('Loaded Completed table')
48 |
49 | sql.commit()
50 |
51 | r = praw.Reddit(USERAGENT)
52 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
53 | r.refresh_access_information(APP_REFRESH)
54 |
55 |
56 | def scansub():
57 | print('Searching '+ SUBREDDIT + '.')
58 | subreddit = r.get_subreddit(SUBREDDIT)
59 | posts = subreddit.get_new(limit=MAXPOSTS)
60 | for post in posts:
61 | # Anything that needs to happen every loop goes here.
62 | pid = post.id
63 |
64 | try:
65 | pauthor = post.author.name.lower()
66 | except AttributeError:
67 | # Author is deleted and we don't care about this post
68 | continue
69 |
70 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
71 | if cur.fetchone():
72 | # This post is already marked in the database
73 | continue
74 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
75 | sql.commit()
76 |
77 | if KEYAUTHORS != [] and all(auth.lower() != pauthor for auth in KEYAUTHORS):
78 | # This post was not made by a keyauthor
79 | continue
80 |
81 | pbody = ''
82 | if SEARCHTITLE:
83 | pbody += post.title + '\n'
84 | if SEARCHTEXT:
85 | pbody += post.selftext
86 | if KEYWORDS == [] or any(key.lower() in pbody.lower() for key in KEYWORDS):
87 | print('Replying to ' + pid + ' by ' + pauthor)
88 | post.add_comment(REPLYSTRING)
89 |
90 |
91 | while True:
92 | try:
93 | scansub()
94 | except Exception as e:
95 | traceback.print_exc()
96 | print('Running again in %d seconds \n' % WAIT)
97 | sql.commit()
98 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/Schedulizer/README.md:
--------------------------------------------------------------------------------
1 | Schedulizer
2 | ========
3 |
4 | Schedulize your posts! Tell this bot what to post, where to post it, and, most importantly, *when* to post it.
5 |
6 | When you run scheduleclient.py, it will open a console window as well. This console will tell you when you've done something incorrectly, and when your post has successfully been saved (you can then view the post in the "Upcoming" tab). I'm sure you'd just love it if the GUI window told you this kind of stuff, but we can't all have what we want, okay?
7 |
8 | The Client does not connect to reddit, meaning it's not going to know if you've spelled a subreddit incorrectly, or if the subreddit is private. That's for you to know and the bot to find out during runtime.
9 |
10 | In order for the posts to actually get made, you have to leave schedulebot.py running. You may open and close scheduleclient.py as much as you wish. You may use the client while the bot is off.
11 |
12 |
13 | ###Images
14 |
15 | 
16 | 
17 | 
18 | 
--------------------------------------------------------------------------------
/_old/Schedulizer/past.txt:
--------------------------------------------------------------------------------
1 | '1', 'GoldTesting', 'Sep 08 19:30', 'Schedulizer Test III', 'This post is being made fully automatically with Schedulizer!!\n', '2fvbzh'
2 | '2', 'GoldTesting', 'Sep 08 19:50', 'Schedulizer Test IV', 'How many of you have robots to do your reddit posting for you?\n', '2fvdyx'
3 | '3', 'CopperplateGothic', 'Sep 08 20:00', 'Mile 1 Real Estate', 'http://i.imgur.com/pq201mF.jpg', '2fvexi'
4 | '33', 'Goldtesting', 'Sep 11 14:40', 'Two posts at the same time', '\n', '2g57ia'
5 | '34', 'Goldtesting', 'Sep 11 14:40', 'Two posts At the also same time', '\n', '2g57ik'
6 |
--------------------------------------------------------------------------------
/_old/Schedulizer/schedulebot.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 | import datetime
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 | USERAGENT = ""
15 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
16 |
17 | MAXPOSTS = 100
18 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
19 | WAIT = 40
20 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
21 |
22 |
23 | '''All done!'''
24 |
25 |
26 | WAITS = str(WAIT)
27 | try:
28 | import bot
29 | USERAGENT = bot.aG
30 | except ImportError:
31 | pass
32 |
33 | sql = sqlite3.connect('sql.db')
34 | print('Loaded SQL Database')
35 | cur = sql.cursor()
36 |
37 | cur.execute('CREATE TABLE IF NOT EXISTS upcoming(ID TEXT, SUBREDDIT TEXT, TIME INT, TITLE TEXT, URL TEXT, BODY TEXT)')
38 | cur.execute('CREATE TABLE IF NOT EXISTS past(ID TEXT, SUBREDDIT TEXT, TIME INT, TITLE TEXT, URL TEXT, BODY TEXT, POSTLINK TEXT)')
39 | cur.execute('CREATE TABLE IF NOT EXISTS internal(NAME TEXT, ID INT)')
40 | print('Loaded Completed table')
41 | cur.execute('SELECT * FROM internal')
42 | f = cur.fetchone()
43 | if not f:
44 | print('Database is new. Adding ID counter')
45 | cur.execute('INSERT INTO internal VALUES(?, ?)', ['counter', 1])
46 | else:
47 | print('Current ID counter: ' + str(f[1]))
48 |
49 | sql.commit()
50 |
51 | r = praw.Reddit(USERAGENT)
52 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
53 | r.refresh_access_information(APP_REFRESH)
54 | print(r.user)
55 |
56 | def getTime(bool):
57 | timeNow = datetime.datetime.now(datetime.timezone.utc)
58 | timeUnix = timeNow.timestamp()
59 | if bool is False:
60 | return timeNow
61 | else:
62 | return timeUnix
63 |
64 | print()
65 | def runtime():
66 | print('Checking Database')
67 | now = getTime(True)
68 | print('Now:' + '.'*15, now)
69 | cur.execute('SELECT * FROM upcoming')
70 | fetched = cur.fetchall()
71 | fetched.sort(key=lambda x: x[2], reverse=False)
72 | try:
73 | print('Earliest post:' + '.'*5,fetched[0][2], 'Item ' + fetched[0][0] + ',', round(fetched[0][2] - now), 'seconds')
74 | except:
75 | pass
76 |
77 | for member in fetched:
78 | mtime = member[2]
79 | if now > mtime:
80 | iid = member[0]
81 | title = member[3]
82 | print('Posting to /r/' + member[1] + ': ' + title)
83 | if member[5] == '':
84 | url = member[4]
85 | text = None
86 | if member[4] == '':
87 | text = member[5]
88 | url =None
89 | try:
90 | if text is not None:
91 | newpost = r.submit(member[1], title, text=text, captcha=None, resubmit=True, send_replies=True)
92 | if url is not None:
93 | newpost = r.submit(member[1], title, url=url, captcha=None, resubmit=True, send_replies=True)
94 | cur.execute('DELETE FROM upcoming WHERE ID=?', [iid])
95 | cur.execute('INSERT INTO past VALUES(?, ?, ?, ?, ?, ?, ?)', [iid, member[1], member[2], member[3], member[4], member[5], newpost.id])
96 | sql.commit()
97 | print('\tDone!')
98 | except Exception as e:
99 | print(e)
100 |
101 | while True:
102 | runtime()
103 | print('Sleeping ' + WAITS + ' seconds\n')
104 | time.sleep(WAIT)
105 |
--------------------------------------------------------------------------------
/_old/Schedulizer/upcoming.txt:
--------------------------------------------------------------------------------
1 | '35', 'GoldTesting', 'Oct 11 15:52', 'Test', 'This is the test that never ends.\n'
2 | '36', 'Test', 'Oct 11 15:57', 'test', '\n'
3 |
--------------------------------------------------------------------------------
/_old/Scrubber/README.md:
--------------------------------------------------------------------------------
1 | Scrubber
2 | ==========
3 |
4 | Banning a user from your subreddit is one thing, but sometimes you need to wipe out all traces of their existence.
5 |
6 | It will scan /r/subreddit/new, /top, and /comments. It will then scan /u/user/submitted and /comments. It will also do a search using the author:"" tag. Any submissions or comments in your subreddit made by the user will be removed.
7 |
8 | Reddit only allows us to grab 1,000 items from each of the five areas mentioned. We can also use the search bar to find submissions, but not comments. It may be impossible to truly scrub the user, but if it's that far back in all directions, it's probably not worth worrying about.
9 |
10 | You must log in as a moderator, obviously.
11 |
12 |
13 |
14 | Check out the [timesearch tools](https://github.com/voussoir/reddit/tree/master/Prawtimestamps) for finding submissions as old as the subreddit itself. May help with additional scrubbing.
--------------------------------------------------------------------------------
/_old/Scrubber/scrubber.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sys
5 | import string
6 |
7 | ''''USER CONFIGURATION'''
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
15 | SUBREDDIT = "GoldTesting"
16 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
17 |
18 | '''All done!'''
19 |
20 | try:
21 | import bot
22 | USERAGENT = bot.aG
23 | except ImportError:
24 | pass
25 |
26 | print('Logging in.')
27 | r = praw.Reddit(USERAGENT)
28 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
29 | r.refresh_access_information(APP_REFRESH)
30 | def start():
31 | print('\nWho do you want to scrub?')
32 | USER = input('>/u/')
33 | print('\nYou are about to scrub /u/' + USER + "'s existence from /r/" + SUBREDDIT)
34 | print('Are you sure? Y/N')
35 | confirm = input('>')
36 | if confirm.lower() not in ['yes','y']:
37 | pass
38 | else:
39 | SCRUB(USER)
40 |
41 | def work(posts):
42 | #By subreddit
43 | for post in posts:
44 | try:
45 | pauthor = post.author.name
46 | pid = post.id
47 | if pauthor.lower() == USER.lower() and post.banned_by is None:
48 | print(pid + ' - Removing', end='')
49 | sys.stdout.flush()
50 | post.remove()
51 | print('\r' + pid + ' - Done ')
52 | except:
53 | pass
54 |
55 | def worku(posts):
56 | #By user's profile page
57 | for post in posts:
58 | try:
59 | psub = post.subreddit.display_name
60 | pid = post.id
61 | if psub.lower() == SUBREDDIT.lower() and post.banned_by is None:
62 | print(pid + ' - Removing', end='')
63 | sys.stdout.flush()
64 | post.remove()
65 | print('\r' + pid + ' - Done ')
66 | except:
67 | pass
68 |
69 | def works(USER):
70 | #By subreddit search bar
71 | number = 1
72 | stage = 1
73 | print('Searching /r/' + SUBREDDIT + ' by author:"' + USER + '" || Stage ' + str(stage))
74 | while number > 0:
75 | stage+=1
76 | number = 0
77 | posts = r.search('author:"' + USER + '"', subreddit=SUBREDDIT,limit=1000)
78 | for post in posts:
79 | number +=1
80 | try:
81 | pauthor = post.author.name
82 | pid = post.id
83 | if pauthor.lower() == USER.lower() and post.banned_by is None:
84 | print(pid + ' - Removing', end='')
85 | sys.stdout.flush()
86 | post.remove()
87 | print('\r' + pid + ' - Done ')
88 | except:
89 | pass
90 | print('Found ' + str(number) + ' items this run.')
91 | print('Waiting 15s to give the cache a moment to refresh...\n')
92 | time.sleep(15)
93 |
94 | def SCRUB(USER):
95 | try:
96 | redditor = r.get_redditor(USER)
97 | print('\nBeginning scrub in 5 seconds...')
98 | time.sleep(5)
99 | print('Scrubbing /u/' + USER + ' from /r/' + SUBREDDIT + '\n')
100 | subreddit = r.get_subreddit(SUBREDDIT)
101 | print('Scanning /r/' + SUBREDDIT + '/New')
102 | posts = subreddit.get_new(limit=None)
103 | work(posts)
104 |
105 | print('Scanning /r/' + SUBREDDIT + '/top')
106 | posts = subreddit.get_top_from_all(limit=None)
107 | work(posts)
108 |
109 | print('Scanning /r/' + SUBREDDIT + '/comments')
110 | posts = subreddit.get_comments(limit=None)
111 | work(posts)
112 |
113 | redditor = r.get_redditor(USER,fetch=True)
114 | print('Scanning /u/' + USER + '/submitted')
115 | posts = redditor.get_submitted(limit=None)
116 | worku(posts)
117 |
118 | print('Scanning /u/' + USER + '/comments')
119 | posts = redditor.get_comments(limit=None)
120 | worku(posts)
121 |
122 | works(USER)
123 |
124 | print('\nFinished')
125 | input()
126 | except praw.requests.exceptions.HTTPError:
127 | print('That user does not exist')
128 | input()
129 |
130 | while True:
131 | start()
--------------------------------------------------------------------------------
/_old/SourceExcel/README.md:
--------------------------------------------------------------------------------
1 | SourceExcel
2 | ==========
3 |
4 | Written for /u/fearnotthewrath on behalf of /r/Excel
5 |
6 | When a user makes a post asking for help, AutoModerator will give it the flair "Unsolved"
7 |
8 | If an unsolved post has no comments, nothing happens
9 |
10 | If an unsolved post receives a comment written by *someone other than OP*, the thread will get "Waiting on OP" flair.
11 |
12 | If a Waiting thread does not have any comments written by OP, he has a limited amount of time to make a comment. His post will be removed if he does not participate in his own thread.
13 |
14 | If a Waiting thread has no comments (meaning the original commenter deletd it), the bot will allow the post to stay until a new comment triggers it.
15 |
16 | The code does have its loopholes, but only an unreasonable person will abuse them.
--------------------------------------------------------------------------------
/_old/SourceIt/README.md:
--------------------------------------------------------------------------------
1 | SourceIt
2 | ==========
3 |
4 | When a user makes a post in the subreddit, he has a certain amount of time to provide a comment describing the post or providing a source. If he does not, the post will be removed and a warning left.
5 |
6 | [This](http://www.reddit.com/r/GoldTesting/comments/26wjq1/red/) post met the requirement. [This](http://www.reddit.com/r/GoldTesting/comments/26whfo/pyre/) one didn't.
7 |
8 | ________
9 | As of reddit 21, sourceit.py has received a major upgrade. The original is available as s.py in case there are bugs in the new one.
10 |
11 | **New Things**:
12 |
13 | - Minimum length enforcement. MINLENGTH is how long the person's comment must be. 0 would mean any comment is okay
14 | - If a comment is not found, and there is time left, nothing happens
15 | - If a comment is not found, and there is no time left, the post is removed with a note from the mods
16 |
17 | - If a comment is found, and there is time left, but the comment is too short, they receive a warning
18 | - If a comment is found, and there is no time left, and it is too short, the post will be reported. A moderator may decide if the short comment is okay.
19 | - If a comment is found, and meets all requirements, nothing happens and the post passes.
20 |
--------------------------------------------------------------------------------
/_old/StateOfTheNetwork/02Nov2014-09-58-43.txt:
--------------------------------------------------------------------------------
1 | November 02 2014, 09:58:43 UTC
2 |
3 | Rank | Subreddit | Subscribers
4 | -: | :- | -:
5 | 1 | /r/redditdev | 7349
6 | 2 | /r/botwatch | 2047
7 | 3 | /r/bugs | 1424
8 | 4 | /r/RequestABot | 568
9 | 5 | /r/GoldTesting | 10
10 |
--------------------------------------------------------------------------------
/_old/StateOfTheNetwork/README.md:
--------------------------------------------------------------------------------
1 | State of the Network
2 | ==========
3 |
4 | For [/u/Greypo](http://reddit.com/u/greypo)
5 |
6 | Takes a list of subreddits, and compiles their subscriber counts into a table. That table is written to a txt file and can posted to a subreddit with a click of your keyboard
7 |
8 | see [here](http://www.reddit.com/r/GoldTesting/comments/2l1ybo/stateofthenetwork_november_02_2014_094729_utc/)
9 |
10 | [Thread](http://www.reddit.com/r/RequestABot/comments/2l1uh2/request_a_bot_that_collects_subscriber_numbers/)
--------------------------------------------------------------------------------
/_old/StateOfTheNetwork/imaginary.txt:
--------------------------------------------------------------------------------
1 | ImaginaryCityscapes
2 | ImaginaryWesteros
3 | ImaginaryLeviathans
4 | ImaginaryStarscapes
5 | ImaginaryBattlefields
6 | ArtistOfTheDay
7 | ImaginaryMaps
8 | ImaginaryWildlands
9 | ImaginaryWastelands
10 | ImaginaryJedi
11 | ImaginaryHistory
12 | ImaginaryInteriors
13 | ImaginaryFutureWar
14 | ImaginaryStarships
15 | ImaginaryBoners
16 | ImaginaryCyberpunk
17 | ImaginaryArmor
18 | ImaginaryVehicles
19 | ImaginaryBehemoths
20 | ImaginaryWeaponry
21 | ImaginaryDragons
22 | ImaginaryCastles
23 | ImaginaryArchitecture
24 | ImaginaryHorrors
25 | ImaginaryRobotics
26 | ImaginaryBeasts
27 | ImaginaryMechs
28 | ImaginaryAzeroth
29 | ImaginaryDemons
30 | ImaginarySteampunk
31 | ImaginarySeascapes
32 | ImaginaryWarships
33 | ImaginaryVillages
34 | ImaginaryScience
35 | ImaginaryMiddleEarth
36 | ImaginaryWarriors
37 | ImaginarySoldiers
38 | ImaginaryRuins
39 | ImaginaryGallifrey
40 | ImaginaryNetwork
41 | ImaginaryArchers
42 | ImaginaryAngels
43 | ImaginaryKnights
44 | ImaginaryAstronauts
45 | ImaginaryDinosaurs
46 | ImaginaryWizards
47 | ImaginaryMonuments
48 | ImaginaryAetherpunk
49 | ImaginaryBlueprints
50 | ImaginaryImmortals
51 | ImaginaryElementals
52 | ImaginaryWorlds
53 | ImaginaryTrees
54 | ImaginaryAssassins
55 | ImaginaryElves
56 | ImaginaryWinterscapes
57 | ImaginaryTemples
58 | ImaginaryDieselpunk
59 | ImaginarySkyscapes
60 | ImaginaryTowers
61 | ImaginaryPirates
62 | ImaginaryKanto
63 | ImaginaryUndead
64 | ImaginaryDwarves
65 | ImaginaryArrakis
66 | ImaginaryIslands
67 | ImaginaryPolitics
68 | ImaginaryWitches
69 | ImaginaryVikings
70 | ImaginaryGaming
71 | ImaginaryHogwarts
72 | ImaginaryGiants
73 | ImaginaryArtifacts
74 | ImaginarySpirits
75 | ImaginaryFaeries
76 | ImaginaryDerelicts
77 | ImaginaryBooks
78 | ImaginaryForests
79 | ImaginaryTamriel
80 | ImaginaryNinjas
81 | ImaginaryFallout
82 | ImaginaryVampires
83 | ImaginaryMerfolk
84 | ImaginaryWerewolves
85 | ImaginaryOrcs
86 | ImaginaryClerics
87 | ImaginaryPropaganda
88 | ImaginaryNobles
89 | ImaginaryEquestria
90 | ImaginaryGoblins
91 | ImaginaryHumans
92 | ImaginaryCaves
93 | ImaginaryCentaurs
94 | ImaginaryFactories
95 | ImaginaryTrolls
96 | ImaginaryNatives
97 | ImaginaryDisney
98 | ImaginaryMountains
99 | ImaginaryDesigns
100 | ImaginaryAsylums
101 | ImaginaryAdrenaline
102 | ImaginaryMutants
103 | ImaginaryCowboys
104 | ImaginaryAnime
105 | ImaginaryWalls
106 | ImaginaryDeserts
107 | ImaginaryVolcanoes
108 | ImaginaryAliens
109 | ImaginarySunnydale
110 | ImaginaryCarnage
111 | ImaginaryCanyons
112 | ImaginaryWaterfalls
113 | ImaginaryStarcraft
114 | ImaginaryRivers
115 | ImaginaryPrisons
116 | ImaginaryTyria
117 | ImaginaryBakerSt
118 | ImaginaryGlaciers
119 | ImaginaryLakes
120 | ImaginaryGotham
121 | ImaginaryMusic
122 | ImaginaryVerse
123 | ImaginaryCybertron
124 | ImaginarySanctuary
125 | ImaginaryRuneterra
126 | ImaginaryGnomes
127 | ImaginaryFederation
128 | ImaginaryTitans
129 | ImaginaryLadyBoners
130 | ImaginaryNarnia
131 | ImaginaryNewEden
132 | ImaginaryOldKingdom
133 | ImaginaryCybernetics
134 | ImaginaryJerk
135 | ImaginaryAperture
136 | ImaginaryFood
137 | ImaginaryUmbrellaCorp
138 |
--------------------------------------------------------------------------------
/_old/StateOfTheNetwork/test.txt:
--------------------------------------------------------------------------------
1 | botwatch
2 | requestabot
3 | goldtesting
4 | redditdev
5 | bugs
6 |
--------------------------------------------------------------------------------
/_old/Stylist/Midnight.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Stylist/Midnight.txt
--------------------------------------------------------------------------------
/_old/Stylist/Night.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/Stylist/Night.txt
--------------------------------------------------------------------------------
/_old/Stylist/README.md:
--------------------------------------------------------------------------------
1 | Stylist
2 | ==========
3 |
4 | Set your subreddit's stylesheet based on the time of day!
5 |
6 | Each of your stylesheets should be saved as a .txt file in the same directory as this bot. You configure the times with the TIMES variable.
7 |
8 | Times refer to the UTC timezone, must be zero-padded, and must be in 24h mode. See examples.
9 |
10 | http://www.timeanddate.com/time/map/
11 |
12 | You can add or remove as many schedules as you want. You must restart the bot for it to notice new .txt files or changes to the schedule.
--------------------------------------------------------------------------------
/_old/SubDump/README.md:
--------------------------------------------------------------------------------
1 | SubDump
2 | =============
3 |
4 | - 2016 06 05
5 | - Merged SubDumpPosts with this. Use the `DO_LINKPOSTS` and `DO_SELFPOSTS` variables. I have not yet fully tested it.
6 |
7 |
8 |
9 | This bot searches for comments or submissions that contain your keyword, and saves them. You can choose any or all of three modes
10 |
11 | - Reddit Saving.
12 |
13 | - MAILME. Bot will construct a list at the end of the cycle and send it to you.
14 |
15 | - SUBDUMP. Bot will post a permalink to the comment as 'Author in /r/Subreddit' in your sub
16 |
--------------------------------------------------------------------------------
/_old/SubDumpPost/README.md:
--------------------------------------------------------------------------------
1 | SubDump - Post version
2 | =============
3 |
4 | Merged with [SubDump](https://github.com/voussoir/reddit/tree/master/SubDump). Use the `DO_LINKPOSTS` and `DO_SELFPOSTS` variables.
--------------------------------------------------------------------------------
/_old/SubmissionRatio/README.md:
--------------------------------------------------------------------------------
1 | SubmissionRatio
2 | ===
3 |
4 | This measures the ratio of users' comments-to-submissions on your subreddit. If a users' ratio falls below a certain threshold, you can receive a message in modmail.
5 |
6 | The ratios can then be published to a subreddit [wiki page](http://www.reddit.com/r/GoldTesting/wiki/heyo).
7 |
8 | #SETTING UP
9 |
10 | Seriously, read this
11 |
12 | The first time you run the bot, set MAXPOSTS to 1000 and turn the modmail warning off. This is your initial data collection to start building the database. Once you see "Running again in 20 seconds", shut the bot down, and turn MAXPOSTS back to 100.
13 |
14 | Because Reddit only allows us to get [1,000](http://www.reddit.com/r/redditdev/comments/2ffide/listing_old_comments/ck8qlme) submissions and 1,000 comments, there are probably going to be a **TON** of people who didn't make it into your database, or are not fairly represented in your database. For this reason, you may not want to enable the modmail warning until you think the database has enough data.
15 |
16 | You should download my wiki.txt file as a starting point, and modify it to your liking. Compare the contents of wiki.txt to [this page](http://www.reddit.com/r/GoldTesting/wiki/heyo) to understand how they match up.
--------------------------------------------------------------------------------
/_old/SubmissionRatio/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/SubmissionRatio/sql.db
--------------------------------------------------------------------------------
/_old/SubmissionRatio/wiki.txt:
--------------------------------------------------------------------------------
1 | This is the content of the wiki page!
2 |
3 | #Lines starting with a Hash will not be pushed to the wiki
4 |
5 | #Inserting __STRFTIME("")__ with a proper strftime format between the quotation marks will give the wiki a UTC timestamp
6 | #https://docs.python.org/2/library/time.html#time.strftime
7 | #You should only have 1 strftime thing on each line. Or else you might break it. Please don't break it.
8 |
9 | This page was updated __STRFTIME("%B %d, %Y at %H:%M:%S UTC")__
10 |
11 | #Inserting __BUILDTABLE__ anywhere in this document will give the wiki a table containing usernames, submission count, and comment count
12 | #The order of the table is controled by the TABLESORT variable in submissionratio.py
13 |
14 | [See here for more information](https://github.com/voussoir/reddit/tree/master/SubmissionRatio)
15 |
16 | The following data comes from /r/letsplaycritiques and /r/GoldTesting
17 |
18 | __BUILDTABLE__
--------------------------------------------------------------------------------
/_old/SubmissionRatioAS/ChangeUser.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw
3 | import time
4 | import sqlite3
5 |
6 |
7 | sql = sqlite3.connect('sql.db')
8 | print('Loaded SQL Database')
9 | cur = sql.cursor()
10 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
11 | cur.execute('CREATE TABLE IF NOT EXISTS users(NAME TEXT, COMMENTS INT, SUBMISSIONS INT, RATIO REAL, FLAIR TEXT)')
12 | print('Loaded Completed table')
13 | sql.commit()
14 |
15 |
16 |
17 | print("Forcibly change a user's information")
18 | def operate():
19 | username = input('/u/').lower()
20 | cur.execute('SELECT * FROM users WHERE lower(NAME)=?', [username.lower()])
21 | f = cur.fetchone()
22 | if not f:
23 | print('That user does not exist in the database')
24 | else:
25 | print(f[0] + ': ' + str(f[1]) + ' comments, ' + str(f[2]) + ' submissions, flair= "' + f[4] + '"')
26 | print("Forcibly changing /u/" + username + "'s information. Is this correct? Y/N")
27 | confirm = input('>> ').lower()
28 | if confirm == 'y':
29 | name = f[0]
30 | comments = int(input('Comments: '))
31 | submissions = int(input('Submissions: '))
32 | userflair = input('Flair: ')
33 | denominator = (1 if submissions == 0 else submissions)
34 | ratio = "%0.2f" % (comments / denominator)
35 | print('Ratio: ' + ratio)
36 | ratio = float(ratio)
37 | cur.execute('UPDATE users SET COMMENTS=?, SUBMISSIONS=?, RATIO=?, FLAIR=? WHERE NAME=?', [comments, submissions, ratio, userflair, name])
38 | sql.commit()
39 | print('Success')
40 |
41 |
42 | while True:
43 | operate()
44 | print()
--------------------------------------------------------------------------------
/_old/SubmissionRatioAS/README.md:
--------------------------------------------------------------------------------
1 | SubmissionRatio -- Flaired users only
2 | ===
3 |
4 | This modified version of SR will only log data of users whose flair is non-empty. All punishments have been removed.
5 |
6 | The data is published to a subreddit [wiki page](http://www.reddit.com/r/GoldTesting/wiki/batman).
7 |
8 | ______
9 |
10 |
11 | You may use AddUser.py to scan a user's profile for material in your subreddit to augment what the bot was able to collect. This is subject to the same 1k limits as usual, but may pick up the scraps.
12 |
13 | You may use ChangeUser.py to manually enter a user's information, but you need to run AddUser on him first.
14 |
15 | You should download my wiki.txt file as a starting point, and modify it if you're feeling brave. Compare the contents of wiki.txt to [this page](http://www.reddit.com/r/GoldTesting/wiki/batman) to understand how they match up.
16 |
17 | [Thread](http://www.reddit.com/r/redditdev/comments/2gzq42/gathering_posting_data_on_flaired_users/)
--------------------------------------------------------------------------------
/_old/SubmissionRatioAS/wiki.txt:
--------------------------------------------------------------------------------
1 | #Lines starting with a Hash will not be pushed to the wiki
2 |
3 | #Inserting __STRFTIME("")__ with a proper strftime format between the quotation marks will give the wiki a UTC timestamp
4 | #https://docs.python.org/2/library/time.html#time.strftime
5 | #You should only have 1 strftime thing on each line. Or else you might break it. Please don't break it.
6 |
7 | This page was updated __STRFTIME("%B %d, %Y at %H:%M:%S UTC")__
8 |
9 | #Inserting __BUILDTABLE__ anywhere in this document will give the wiki a table containing usernames, submission count, and comment count
10 | #The order of the table is controled by the TABLESORT variable in submissionratio.py
11 |
12 | [See here for more information](https://github.com/voussoir/reddit/tree/master/SubmissionRatioAS)
13 |
14 | The following data comes from /r/AskScience
15 |
16 | __BUILDTABLE__
--------------------------------------------------------------------------------
/_old/SubmissionScoreTracker/README.md:
--------------------------------------------------------------------------------
1 | Submission Score Tracker
2 | ========================
3 |
4 |
5 | Creates a text file and logs the submission's score every five seconds. It works on comments too.
6 |
7 | Usage:
8 |
9 | submissionscoretracker.py 26r2ob
10 | # or
11 | submissionscoretracker.py t3_26r2ob
12 | # or
13 | submissionscoretrackerpy t1_cthfkoh
14 |
--------------------------------------------------------------------------------
/_old/SubmissionScoreTracker/submissionscoretracker.py:
--------------------------------------------------------------------------------
1 | import praw
2 | import sys
3 | import time
4 | import traceback
5 |
6 | USERAGENT = ""
7 | APP_ID = ""
8 | APP_SECRET = ""
9 | APP_URI = ""
10 | APP_REFRESH = ""
11 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
12 |
13 | try:
14 | import bot
15 | USERAGENT = bot.aG
16 | APP_ID = bot.oG_id
17 | APP_SECRET = bot.oG_secret
18 | APP_URI = bot.oG_uri
19 | APP_REFRESH = bot.oG_scopes['all']
20 | except ImportError:
21 | pass
22 |
23 | print('logging in')
24 | r = praw.Reddit(USERAGENT)
25 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
26 | r.refresh_access_information(APP_REFRESH)
27 |
28 | def submissionscoretracker(submissionid):
29 | if '_' not in submissionid:
30 | submissionid = 't3_' + submissionid
31 | submission = r.get_info(thing_id=submissionid)
32 |
33 | outfile = open(submission.fullname + '.txt', 'a+')
34 | last_refresh = time.time()
35 | while True:
36 | try:
37 | if time.time() - last_refresh:
38 | r.refresh_access_information()
39 | last_refresh = time.time()
40 | submission.refresh()
41 | print('%s, %d' % (time.strftime('%H:%M:%S'), submission.score))
42 | outfile.write('%d, %d\n' % (int(time.time()), submission.score))
43 | outfile.flush()
44 | except KeyboardInterrupt:
45 | outfile.close()
46 | return
47 | except:
48 | traceback.print_exc()
49 |
50 | if __name__ == '__main__':
51 | if len(sys.argv) == 1:
52 | submissionid = input('id: ')
53 | else:
54 | submissionid = sys.argv[1]
55 | submissionscoretracker(submissionid)
--------------------------------------------------------------------------------
/_old/SubmissionScoreTracker/t3_3f36wr.txt:
--------------------------------------------------------------------------------
1 | 1438209519, 5
2 | 1438209526, 6
3 | 1438209531, 7
4 | 1438209538, 6
5 | 1438209544, 7
6 | 1438209549, 7
7 | 1438209555, 7
8 | 1438209561, 6
9 | 1438209567, 7
10 | 1438209574, 7
11 | 1438209580, 6
12 | 1438209585, 7
13 | 1438209592, 6
14 | 1438209598, 7
15 | 1438209604, 8
16 | 1438209609, 7
17 | 1438209615, 8
18 | 1438209622, 8
19 | 1438209628, 8
20 | 1438209633, 8
21 | 1438209639, 8
22 | 1438209645, 7
23 | 1438209651, 7
24 | 1438209658, 8
25 | 1438209664, 8
26 | 1438209670, 7
27 | 1438209675, 7
28 | 1438209682, 8
29 | 1438209687, 8
30 | 1438209694, 8
31 | 1438209700, 8
32 | 1438209705, 7
33 | 1438209712, 8
34 | 1438209718, 7
35 | 1438209724, 8
36 | 1438209730, 9
37 | 1438209735, 8
38 | 1438209741, 8
39 | 1438209748, 9
40 | 1438209753, 9
41 | 1438209760, 8
42 | 1438209766, 9
43 | 1438209772, 9
44 | 1438209777, 9
45 | 1438209784, 9
46 | 1438209790, 8
47 | 1438209796, 9
48 | 1438209801, 9
49 | 1438209808, 9
50 | 1438209814, 9
51 | 1438209819, 9
52 | 1438209825, 9
53 | 1438209832, 9
54 | 1438209838, 9
55 | 1438209844, 9
56 | 1438209850, 8
57 | 1438209855, 9
58 | 1438209861, 8
59 | 1438209867, 9
60 | 1438209874, 9
61 | 1438209879, 9
62 | 1438209885, 9
63 | 1438209891, 10
64 | 1438209898, 9
65 | 1438209904, 10
66 | 1438209909, 9
67 | 1438209915, 9
68 | 1438209922, 10
69 | 1438209928, 10
70 | 1438209933, 9
71 | 1438209939, 10
72 | 1438209945, 10
73 | 1438209951, 9
74 | 1438209958, 10
75 | 1438209963, 10
76 | 1438209973, 10
77 | 1438209978, 9
78 | 1438209984, 9
79 | 1438209990, 9
80 | 1438209996, 10
81 | 1438210002, 10
82 | 1438210008, 9
83 | 1438210014, 10
84 | 1438210020, 10
85 | 1438210026, 10
86 | 1438210032, 10
87 | 1438210038, 10
88 | 1438210045, 10
89 | 1438210051, 9
90 | 1438210057, 10
91 | 1438210063, 10
92 | 1438210069, 10
93 | 1438210075, 10
94 | 1438210081, 10
95 | 1438210087, 10
96 | 1438210093, 10
97 | 1438210099, 9
98 | 1438210105, 10
99 | 1438210111, 10
100 | 1438210117, 9
101 | 1438210123, 10
102 | 1438210129, 10
103 | 1438210135, 10
104 | 1438210141, 10
105 | 1438210147, 10
106 | 1438210160, 10
107 | 1438210166, 10
108 |
--------------------------------------------------------------------------------
/_old/SuperClippy/README.md:
--------------------------------------------------------------------------------
1 | SuperClippy
2 | =========
3 |
4 |
5 |
6 |
7 |
8 | The Clippy to end all Clippies.
9 |
10 | Combines all of the different bots which were previously being run individually on [/r/Excel](http://reddit.com/r/Excel).
11 |
12 | 1. Sends a Welcome message to users if they have just made their first post on the subreddit
13 |
14 | 2. Distributes points when users leave a "Solution Verified" comment in reply to people who help them
15 |
16 | 3. Manages the Unsolved / Waiting / Solved flair based on post status
17 |
18 | 4. Provides information about Excel function in response to summons
--------------------------------------------------------------------------------
/_old/SuperClippy/boot.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/SuperClippy/boot.wav
--------------------------------------------------------------------------------
/_old/SuperClippy/olddata/Clippy_Welcome.txt:
--------------------------------------------------------------------------------
1 | #This bot was written by /u/GoldenSights for /u/FourMakesTwoUNLESS on behalf of /r/pkmntcgtrades. Uploaded to Git with permission.
2 | import praw
3 | import time
4 | import datetime
5 | import sqlite3
6 |
7 | '''USER CONFIGURATION'''
8 |
9 | USERNAME = "Clippy_Office_Asst"
10 | #This is the bot's Username. In order to send mail, he must have some amount of Karma.
11 | PASSWORD = ""
12 | #This is the bot's Password.
13 | USERAGENT = "/r/Excel New User Welcome"
14 |
15 | SUBREDDIT = "excel"
16 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
17 | MAXPOSTS = 100
18 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
19 | WAIT = 300
20 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
21 | DELAY = 5
22 | #This is the time limit between a user's posts, IN SECONDS. 1h = 3600 || 12h = 43200 || 24h = 86400 || 144h = 518400
23 |
24 | '''All done!'''
25 |
26 |
27 |
28 | WAITS = str(WAIT)
29 | sql = sqlite3.connect('sql.db')
30 | print('Loaded SQL Database')
31 | cur = sql.cursor()
32 | cur.execute('CREATE TABLE IF NOT EXISTS users(name TEXT, lastpost TEXT)')
33 | print('Loaded Users')
34 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(id TEXT)')
35 | print('Loaded Oldposts')
36 | sql.commit()
37 |
38 | r = praw.Reddit(USERAGENT)
39 |
40 | Trying = True
41 | while Trying:
42 | try:
43 | r.login(USERNAME, PASSWORD)
44 | print('Successfully logged in')
45 | Trying = False
46 | except praw.errors.InvalidUserPass:
47 | print('Wrong Username or Password')
48 | quit()
49 | except Exception as e:
50 | print("%s" % e)
51 | time.sleep(5)
52 |
53 | def getTime(bool):
54 | timeNow = datetime.datetime.now(datetime.timezone.utc)
55 | timeUnix = timeNow.timestamp()
56 | if bool == False:
57 | return timeNow
58 | else:
59 | return timeUnix
60 |
61 | def scan():
62 | print('Scanning ' + SUBREDDIT)
63 | subreddit = r.get_subreddit(SUBREDDIT)
64 | posts = subreddit.get_new(limit=MAXPOSTS)
65 | for post in posts:
66 | try:
67 | pauthor = post.author.name
68 | except Exception:
69 | pauthor = '[deleted]'
70 | pid = post.id
71 | plink = post.short_link
72 | ptime = post.created_utc
73 | cur.execute('SELECT * FROM oldposts WHERE id=?', [pid])
74 | if not cur.fetchone():
75 | cur.execute('SELECT * FROM users WHERE name=?', [pauthor])
76 | if not cur.fetchone():
77 | print('Found new user: ' + pauthor)
78 | cur.execute('INSERT INTO users VALUES(?, ?)', (pauthor, pid))
79 | r.send_message(pauthor, 'Welcome to /r/Excel, I am here to help!','Hi! ' + pauthor + ',\n\n It looks like you are new to posting in /r/Excel. Did you know we have a few ways to help you recieve better help?\n\n\n How can I help you?\n\n\n[How to Share Your Questions](/r/excel/wiki/sharingquestions)\n\n[Changing Link Flair](/r/excel/wiki/flair)\n\n[ClippyPoints^TM](/r/excel/wiki/clippy)\n\n\n ^This ^message ^is ^auto-generated ^and ^is ^not ^monitored ^on ^a ^regular ^basis, ^replies ^to ^this ^message ^may ^not ^go ^answered.' , captcha=None)
80 | sql.commit()
81 | print('\t' + pauthor + ' has been added to the database.')
82 | time.sleep(5)
83 |
84 | sql.commit()
85 |
86 | while True:
87 | try:
88 | scan()
89 | except Exception as e:
90 | print('An error has occured:', e)
91 | print('Running again in ' + WAITS + ' seconds.\n')
92 | time.sleep(WAIT)
93 |
--------------------------------------------------------------------------------
/_old/SuperClippy/olddata/db_flair.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/SuperClippy/olddata/db_flair.db
--------------------------------------------------------------------------------
/_old/SuperClippy/olddata/db_points.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/SuperClippy/olddata/db_points.db
--------------------------------------------------------------------------------
/_old/SuperClippy/olddata/db_reference.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/SuperClippy/olddata/db_reference.db
--------------------------------------------------------------------------------
/_old/SuperClippy/olddata/db_welcome.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/SuperClippy/olddata/db_welcome.db
--------------------------------------------------------------------------------
/_old/SuperClippy/superclippy.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/SuperClippy/superclippy.db
--------------------------------------------------------------------------------
/_old/ThreadReader/README.md:
--------------------------------------------------------------------------------
1 | ThreadReader
2 | ========
3 |
4 | Download reddit threads to a text file.
5 |
6 | This script will be **extremely** slow on large threads. Any time you see a "load (x) more comments" button on the website is a place that this bot has to spend an additional 2 seconds loading those comments. No, it's not frozen, it's just working.
--------------------------------------------------------------------------------
/_old/ThreadReader/threadreader.py:
--------------------------------------------------------------------------------
1 | import praw
2 | import textwrap
3 | import time
4 | import datetime
5 |
6 |
7 | FALLBACKID = ""
8 | USERAGENT = ""
9 |
10 | try:
11 | pid=input('Thread ID: ')
12 | except EOFError:
13 | if FALLBACKID == '':
14 | print('\nCannot run in this environment. Your device is not accepting input')
15 | print('You may run this program another way, or edit the FALLBACKID variable with the ID')
16 | time.sleep(99999)
17 | else:
18 | pid = FALLBACKID
19 |
20 | print('Connecting to reddit')
21 | r=praw.Reddit(USERAGENT)
22 |
23 | print('Getting post')
24 | post = r.get_info(thing_id='t3_' + pid)
25 | print('Getting all comments')
26 | post.replace_more_comments(limit=None, threshold=1)
27 | comments = post.comments
28 |
29 | print('Creating file')
30 | outfile = open('t3_' + pid + '.txt', 'w', encoding='utf-8')
31 |
32 | print('/r/' + post.subreddit.display_name, file=outfile)
33 | print(post.title + '\n', file=outfile)
34 |
35 | if post.selftext != "":
36 | selftext = post.selftext
37 | pbody = post.selftext.replace('\n\n', '\n')
38 | pfinal = ''
39 | for paragraph in pbody.split('\n\n'):
40 | pfinal += '\n'.join(textwrap.wrap(paragraph))
41 | pfinal += '\n'
42 | else:
43 | pfinal = post.url
44 |
45 | print(pfinal, file=outfile)
46 | print(post.permalink + '\n\n\n', file=outfile)
47 |
48 | DEPTHSYMBOL = " "
49 |
50 | def recursivereplies(inlist, depth):
51 | for reply in inlist:
52 | print(' ', file=outfile)
53 | try:
54 | cauthor = reply.author.name
55 | except AttributeError:
56 | cauthor = "[DELETED]"
57 | print(DEPTHSYMBOL * depth + '/u/' + cauthor + ', ' + reply.id + ', ' + humanize(reply.created_utc), file=outfile)
58 | cbody = reply.body
59 | cbody = DEPTHSYMBOL*depth + cbody
60 | #cbody = cbody.replace('\n\n', '\n')
61 | cfinal = ''
62 | for paragraph in cbody.split('\n'):
63 | cfinal += ('\n').join(textwrap.wrap(paragraph, 120))
64 | cfinal += '\n'
65 | cfinal = cfinal[:-1]
66 |
67 | cfinal = cfinal.replace('\n', '\n' + DEPTHSYMBOL*depth)
68 | print(cfinal, file=outfile)
69 | print(DEPTHSYMBOL*depth + '-'*10, file=outfile)
70 | recursivereplies(reply.replies, depth+1)
71 |
72 |
73 | def humanize(instamp):
74 | date = datetime.datetime.utcfromtimestamp(instamp)
75 | date = datetime.datetime.strftime(date, "%b %d %Y %H:%M:%S UTC")
76 | return date
77 |
78 |
79 |
80 | for comment in comments:
81 | try:
82 | cauthor = comment.author.name
83 | except AttributeError:
84 | cauthor = "[DELETED]"
85 | print('/u/' + cauthor + ', ' + comment.id + ', ' + humanize(comment.created_utc), file=outfile)
86 | cbody = comment.body
87 | #cbody = cbody.replace('\n\n', '\n')
88 | cbody = '\n'.join(textwrap.wrap(cbody))
89 | print(cbody, file=outfile)
90 | print('-'*10, file=outfile)
91 | recursivereplies(comment.replies, 1)
92 | print('*'*50, file=outfile)
93 |
94 |
95 | outfile.close()
96 | print('Done')
97 | input()
--------------------------------------------------------------------------------
/_old/TitleNames/README.md:
--------------------------------------------------------------------------------
1 | TitleNames
2 | ======
3 |
4 | What a curiously specific bot. Written for /u/DuckVimes_
5 |
6 | Searches for posts whose titles contain /u/. Generates usernames based on these words, and builds a comment containing some links about this username. Users can be registered as "Special users" and given a custom remark.
7 |
8 | The bot will strip the username of any characters which do not belong in usernames. This means that the name can be touching punctuation and a lot of characters which normally would break a /u/ link.
9 |
10 | [See here](http://www.reddit.com/r/GoldTesting/comments/27rniu/04_unewsletterly_u75000_uduckvimes_uautomoderator/) for a demonstration because I'm not sure how to describe this.
11 |
12 | [Example 2](http://redd.it/27rp6r)
--------------------------------------------------------------------------------
/_old/TitleNames/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/TitleNames/sql.db
--------------------------------------------------------------------------------
/_old/ToTheMoon/README.md:
--------------------------------------------------------------------------------
1 | ToTheMoon
2 | =============
3 |
4 | This bot scans a subreddit for new posts, and comments on every single post without discrimination. This was written with the purpose of DogeTipping every person who posts into /r/DogeCoin. Abuse of this bot could easily get you banned.
5 |
6 | This bot got me my first reddit gold. The Dogecoin community is too goddamn cool.
--------------------------------------------------------------------------------
/_old/ToTheMoon/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/ToTheMoon/sql.db
--------------------------------------------------------------------------------
/_old/ToTheMoon/tothemoon.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 |
6 | '''USER CONFIGURATION'''
7 |
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
15 | SUBREDDIT = "Goldtesting"
16 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
17 | COMMENT = "moon"
18 | #This is the word you want to put in reply
19 | MAXPOSTS = 20
20 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
21 | WAIT = 20
22 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
23 | THRESHOLD = 0
24 | #The bot will only post on submissions with at least this many points.
25 |
26 |
27 | '''All done!'''
28 |
29 |
30 |
31 |
32 | WAITS = str(WAIT)
33 | try:
34 | import bot
35 | USERAGENT = bot.geta()
36 | except ImportError:
37 | pass
38 |
39 | sql = sqlite3.connect('sql.db')
40 | print('Loaded SQL Database')
41 | cur = sql.cursor()
42 |
43 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
44 | print('Loaded Completed table')
45 |
46 | sql.commit()
47 |
48 | r = praw.Reddit(USERAGENT)
49 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
50 | r.refresh_access_information(APP_REFRESH)
51 |
52 | def scanSub():
53 | print('Searching '+ SUBREDDIT + '.')
54 | subreddit = r.get_subreddit(SUBREDDIT)
55 | posts = subreddit.get_new(limit=MAXPOSTS)
56 | for post in posts:
57 | pid = post.id
58 | try:
59 | pauthor = post.author.name
60 | except AttributeError:
61 | pauthor = "[DELETED]"
62 |
63 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
64 | if not cur.fetchone():
65 | if post.score >= THRESHOLD:
66 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
67 | print('Tipping ' + pauthor + ' on thread ' + post.id)
68 | post.add_comment(COMMENT)
69 |
70 | sql.commit()
71 |
72 |
73 | while True:
74 | scanSub()
75 | print('Running again in ' + WAITS + ' seconds \n')
76 | sql.commit()
77 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/URLChangeV2/README.md:
--------------------------------------------------------------------------------
1 | URLChange, 2
2 | =============
3 |
4 | A modified version of URLChange. This will check submissions and comments and do some further string manipulation.
--------------------------------------------------------------------------------
/_old/URLChangeV2/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/URLChangeV2/sql.db
--------------------------------------------------------------------------------
/_old/URLchange/README.md:
--------------------------------------------------------------------------------
1 | URLChange
2 | =============
3 |
4 | Finds a comment containing a certain string, and replies with a fixed version. Built for /r/SimpleRockets
--------------------------------------------------------------------------------
/_old/URLchange/sql.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/URLchange/sql.db
--------------------------------------------------------------------------------
/_old/URLchange/urlchange.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw # simple interface to the reddit API, also handles rate limiting of requests
3 | import time
4 | import sqlite3
5 |
6 | '''USER CONFIGURATION'''
7 |
8 | APP_ID = ""
9 | APP_SECRET = ""
10 | APP_URI = ""
11 | APP_REFRESH = ""
12 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
13 | USERAGENT = ""
14 | #This is a short description of what the bot does. For example "/u/GoldenSights' Newsletter bot"
15 | SUBREDDIT = "GoldTesting"
16 | #This is the sub or list of subs to scan for new posts. For a single sub, use "sub1". For multiple subreddits, use "sub1+sub2+sub3+..."
17 | HEADER = "I have detected some ship designs in your comment. Here are the viewing links:\n\n"
18 | #This will be at the top of the comment above the results
19 | PARENTSTRING = "http://jundroo.com/ViewShip.html?id="
20 | #These are the words you are looking for
21 | REPLACESTRING = "http://sr.5of0.com/ViewShip.html?id="
22 | #This is what parentstring gets replaced with.
23 | MAXPOSTS = 100
24 | #This is how many posts you want to retrieve all at once. PRAW can download 100 at a time.
25 | WAIT = 10
26 | #This is how many seconds you will wait between cycles. The bot is completely inactive during this time.
27 |
28 |
29 | '''All done!'''
30 |
31 |
32 |
33 | PLEN = len(PARENTSTRING)
34 | WAITS = str(WAIT)
35 | try:
36 | import bot
37 | USERAGENT = bot.getaG()
38 | except ImportError:
39 | pass
40 |
41 | sql = sqlite3.connect('sql.db')
42 | print('Loaded SQL Database')
43 | cur = sql.cursor()
44 |
45 | cur.execute('CREATE TABLE IF NOT EXISTS oldposts(ID TEXT)')
46 | cur.execute('CREATE INDEX IF NOT EXISTS oldpost_index ON oldposts(id)')
47 | print('Loaded Completed table')
48 |
49 | sql.commit()
50 |
51 | r = praw.Reddit(USERAGENT)
52 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
53 | r.refresh_access_information(APP_REFRESH)
54 |
55 | def scanSub():
56 | print('Searching '+ SUBREDDIT + '.')
57 | subreddit = r.get_subreddit(SUBREDDIT)
58 | posts = subreddit.get_comments(limit=MAXPOSTS)
59 | for post in posts:
60 | result = []
61 | pid = post.id
62 | pbody = post.body
63 | if PARENTSTRING.lower() in pbody.lower():
64 | cur.execute('SELECT * FROM oldposts WHERE ID=?', [pid])
65 | if not cur.fetchone():
66 | pbodysplit = pbody.split()
67 | print(pid)
68 | for sent in pbodysplit:
69 | if PARENTSTRING.lower() in sent.lower():
70 | try:
71 | url = sent.replace(PARENTSTRING, REPLACESTRING)
72 | if '(' in url:
73 | url = url[url.index('(')+1:]
74 | url = url.replace(')', '')
75 | int(url[PLEN:-1])
76 | pauthor = post.author.name
77 | if pauthor != r.user.name:
78 | result.append(url)
79 | except ValueError:
80 | print('Not a valid url')
81 | except AttributeError:
82 | print('Comment author does not exist')
83 | except Exception:
84 | print('Error.')
85 | if len(result) > 0:
86 | final = HEADER + '\n\n'.join(result)
87 | post.reply(final)
88 | cur.execute('INSERT INTO oldposts VALUES(?)', [pid])
89 | sql.commit()
90 |
91 | while True:
92 | try:
93 | scanSub()
94 | except Exception as e:
95 | print('An error has occured:', str(e))
96 | print('Running again in ' + WAITS + ' seconds \n')
97 | sql.commit()
98 | time.sleep(WAIT)
99 |
--------------------------------------------------------------------------------
/_old/UnreadWatch/unreadwatch.py:
--------------------------------------------------------------------------------
1 | import os
2 | import praw
3 | import time
4 |
5 | ''' User Config '''
6 | USERAGENT = ""
7 | APP_ID = ""
8 | APP_SECRET = ""
9 | APP_URI = ""
10 | APP_REFRESH = ""
11 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
12 | ''' All done '''
13 |
14 | try:
15 | import bot
16 | USERAGENT = bot.aG
17 | APP_ID = bot.oG_id
18 | APP_SECRET = bot.oG_secret
19 | APP_URI = bot.oG_uri
20 | APP_REFRESH = bot.oG_scopes['all']
21 | except ImportError:
22 | pass
23 |
24 | r = praw.Reddit(USERAGENT)
25 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
26 | r.refresh_access_information(APP_REFRESH)
27 | last_refresh = time.time()
28 |
29 | def clearscreen():
30 | if os.system('cls') != 0:
31 | os.system('clear')
32 |
33 | def unreadwatch():
34 | r.handler.clear_cache()
35 | unread = list(r.get_unread(limit=None))
36 | now = time.strftime('%H:%M:%S')
37 | clearscreen()
38 | print(now, len(unread))
39 | for item in unread:
40 | print('\t%s: %s' % (item.author, item.subject))
41 |
42 | while True:
43 | try:
44 | unreadwatch()
45 | except:
46 | traceback.print_exc()
47 | time.sleep(15)
--------------------------------------------------------------------------------
/_old/WeeklyUnsolved/README.md:
--------------------------------------------------------------------------------
1 | Weekly Unsolved
2 | ===============
3 |
4 | Written for [/r/Excel](http://reddit.com/r/excel). It's pretty specific.
5 |
6 | This script only works properly if the last 1,000 submissions on your subreddit fit into the past week. It does not make use of any advanced methods to go farther than that.
--------------------------------------------------------------------------------
/_old/WeeklyUnsolved/results_2015Aug24.txt:
--------------------------------------------------------------------------------
1 | title | author | time | comments
2 | :- | :- | -: | -:
3 | [(Mac) add-in to copy tables to wiki?](http://redd.it/3hrir2) | /u/mzinz | 20 Aug 2015 20:37:39 | 0
4 | [Using custom map backgrounds in Powermap: How to assign geography?](http://redd.it/3hu8rl) | /u/PurpleMan | 21 Aug 2015 12:10:41 | 0
5 | [Some way to create and import Minitab Capability charts into multiple excel sheets?](http://redd.it/3hujp6) | /u/Nonamenewname | 21 Aug 2015 13:46:00 | 0
6 |
--------------------------------------------------------------------------------
/_old/WeeklyUnsolved/weeklyflairmanagers.py:
--------------------------------------------------------------------------------
1 | import bot
2 | import datetime
3 | import praw
4 | import warnings
5 | warnings.filterwarnings('ignore')
6 | print('logging in')
7 | r=bot.oG()
8 |
9 | FLAIR_UNSOLVED = 'unsolved'
10 | MAX_ROOT_COMMENTS = 1
11 | MAX_TOTAL_COMMENTS = 24
12 | IGNORE_DELETED_AUTHORS = True
13 | SAVE_TO_TXT = 'results_%Y%b%d.txt'
14 |
15 | MINIMUM_AGE = 60 * 60 * 24
16 | MAXIMUM_AGE = 7 * 60 * 60 * 24
17 |
18 | now = datetime.datetime.now(datetime.timezone.utc)
19 | nowstamp = now.timestamp()
20 | outfile = now.strftime(SAVE_TO_TXT)
21 |
22 | print('getting new')
23 | subreddit = r.get_subreddit('excel')
24 | new = subreddit.get_new(limit=1000)
25 | results = []
26 | old_in_a_row = 0
27 | for submissionindex, submission in enumerate(new):
28 | print('Checked %d submissions\r' % (submissionindex), end='')
29 | age = nowstamp - submission.created_utc
30 | if age < MINIMUM_AGE:
31 | continue
32 |
33 | if age > MAXIMUM_AGE:
34 | old_in_a_row += 1
35 | if old_in_a_row >= 10:
36 | break
37 | continue
38 | old_in_a_row = 0
39 | if submission.link_flair_text != FLAIR_UNSOLVED:
40 | continue
41 |
42 | if IGNORE_DELETED_AUTHORS and submission.author is None:
43 | continue
44 |
45 | # make sure to perform this part AS LATE AS POSSIBLE to avoid
46 | # api calls.
47 | submission.replace_more_comments(limit=None, threshold=1)
48 | roots = submission.comments[:]
49 | total = praw.helpers.flatten_tree(submission.comments)
50 | submission.croots = roots
51 | submission.ctotal = total
52 | if len(total) > MAX_TOTAL_COMMENTS:
53 | continue
54 |
55 | # only counts roots
56 | if len(roots) > MAX_ROOT_COMMENTS:
57 | continue
58 |
59 | results.append(submission)
60 | print()
61 | results.sort(key=lambda s: (s.created_utc, s.num_comments))
62 | for (submissionindex, submission) in enumerate(results):
63 | author = '/u/'+submission.author.name if submission.author else '[deleted]'
64 | timeformat = datetime.datetime.utcfromtimestamp(submission.created_utc)
65 | timeformat = timeformat.strftime('%d %b %Y %H:%M:%S')
66 |
67 | formatted = '[%s](%s) | %s | %s | %d' % (submission.title, submission.short_link, author, timeformat, len(submission.ctotal))
68 | results[submissionindex] = formatted
69 |
70 | table = 'title | author | time | comments\n'
71 | table += ':- | :- | -: | -:\n'
72 | table += '\n'.join(results)
73 |
74 | outfile = open(outfile, 'w')
75 | print(table, file=outfile)
76 | outfile.close()
77 |
--------------------------------------------------------------------------------
/_old/WeeklyUnsolved/weeklyunsolved.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import praw
3 |
4 | ''' USER CONFIG '''
5 | USERAGENT = ""
6 | APP_ID = ""
7 | APP_SECRET = ""
8 | APP_URI = ""
9 | APP_REFRESH = ""
10 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
11 |
12 | SUBREDDIT = 'Excel'
13 | IGNORE_DELETED_AUTHORS = True
14 | TXT_FILENAME = 'results_%Y%b%d.txt'
15 |
16 | MINIMUM_AGE = 60 * 60 * 24
17 | MAXIMUM_AGE = 7 * 60 * 60 * 24
18 | # In seconds.
19 |
20 | TABLE_HEADER = 'title | author | time | comments'
21 | TABLE_ALIGNMENT = ':- | :- | -: | -:'
22 | TABLE_ROW = '[_title_](_permalink_) | _author_ | _timestamp_ | _comments_'
23 | # Available injectors:
24 | # _title_
25 | # _permalink_
26 | # _author_
27 | # _timestamp_
28 | # _comments_
29 | # _score_
30 | ''' All done! '''
31 |
32 | try:
33 | import bot
34 | USERAGENT = bot.aG
35 | APP_ID = bot.oG_id
36 | APP_SECRET = bot.oG_secret
37 | APP_URI = bot.oG_uri
38 | APP_REFRESH = bot.oG_scopes['all']
39 | except ImportError:
40 | pass
41 |
42 | r = praw.Reddit(USERAGENT)
43 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
44 | r.refresh_access_information(APP_REFRESH)
45 |
46 | def find_unsolved():
47 | print('getting new')
48 | subreddit = r.get_subreddit(SUBREDDIT)
49 | new = subreddit.get_new(limit=1000)
50 | results = []
51 |
52 | now = datetime.datetime.now(datetime.timezone.utc)
53 | nowstamp = now.timestamp()
54 | for (index, submission) in enumerate(new):
55 | age = nowstamp - submission.created_utc
56 | if age < MINIMUM_AGE:
57 | continue
58 |
59 | if age > MAXIMUM_AGE:
60 | continue
61 |
62 | if IGNORE_DELETED_AUTHORS and submission.author is None:
63 | continue
64 |
65 | if submission.link_flair_text not in ['unsolved', 'Waiting on OP']:
66 | continue
67 |
68 | # make sure to perform this part AS LATE AS POSSIBLE to avoid
69 | # api calls.
70 | submission.replace_more_comments(limit=None, threshold=1)
71 | total = praw.helpers.flatten_tree(submission.comments)
72 | submission.flat_comments = total
73 |
74 | if submission.link_flair_text == 'unsolved' and len(total) != 0:
75 | continue
76 |
77 | if submission.link_flair_text == 'Waiting on OP' and len(total) != 1:
78 | continue
79 |
80 | results.append(submission)
81 | return results
82 |
83 | def create_table(results):
84 | rows = []
85 | results.sort(key=lambda s: (s.created_utc, s.num_comments))
86 | for (index, submission) in enumerate(results):
87 | if submission.author is None:
88 | author = '[deleted]'
89 | else:
90 | author = '/u/%s' % submission.author.name
91 |
92 | timestamp = datetime.datetime.utcfromtimestamp(submission.created_utc)
93 | timestamp = timestamp.strftime('%d %b %Y %H:%M:%S')
94 |
95 | row = TABLE_ROW
96 | row = row.replace('_title_', submission.title)
97 | row = row.replace('_permalink_', submission.permalink)
98 | row = row.replace('_author_', author)
99 | row = row.replace('_timestamp_', timestamp)
100 | row = row.replace('_comments_', len(submission.flat_comments))
101 | row = row.replace('_score_', submission.score)
102 | row = row.strip()
103 |
104 | rows.append(row)
105 |
106 | header = TABLE_HEADER.strip()
107 | alignment = TABLE_ALIGNMENT.strip()
108 | rows = '\n'.join(rows)
109 |
110 | table = '\n'.join([header, alignment, rows])
111 | return table
112 |
113 |
--------------------------------------------------------------------------------
/_old/WelcomeBot/README.md:
--------------------------------------------------------------------------------
1 | WelcomeBot
2 | =============
3 |
4 | Sends a PM to people who post in your subreddit for the first time. Can be configured to notice submissions, comments, or both.
5 |
6 | If the PM fails to send, the name will still be saved to the database. It's better to drop out early and miss somebody than to end up on an infinite loop of sending spam.
--------------------------------------------------------------------------------
/_old/WelcomeBot/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voussoir/reddit/d928ca56a4ab54c6aff5250a228bf063c2a27818/_old/WelcomeBot/example.png
--------------------------------------------------------------------------------
/_old/WelcomeBot/welcomebot.py:
--------------------------------------------------------------------------------
1 | #/u/GoldenSights
2 | import praw
3 | import time
4 | import traceback
5 | import sqlite3
6 | import sys
7 |
8 | ''' USER CONFIG '''
9 |
10 | APP_ID = ""
11 | APP_SECRET = ""
12 | APP_URI = ""
13 | APP_REFRESH = ""
14 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
15 | USERAGENT = ""
16 | # This is a short description of what the bot does.
17 | # For example "/u/GoldenSights' Newsletter bot to notify of new posts"
18 | SUBREDDIT = "GoldTesting"
19 | # This is the sub or list of subs to scan for new posts. For a single sub, use "sub1".
20 | # For multiple subs, use "sub1+sub2+sub3+...". For all use "all"
21 |
22 | CHECK_SUBMISSIONS = True
23 | CHECK_COMMENTS = True
24 | # Should the bot check first-time posts / comments
25 |
26 | MESSAGE_SUBJECT = "Welcome to /r/subreddit, _author_!"
27 | MESSAGE_BODY = """
28 | Hey _author_,
29 |
30 | This is the first time we've seen you post in /r/subreddit, welcome! Here
31 | are some things you need to know
32 |
33 | - one
34 | - two
35 |
36 | Thanks,
37 |
38 | /r/subreddit mod team
39 | """
40 | # The subject and body of the message you will to send to new users.
41 | # If you put _author_ in either one of these texts, it will be automatically
42 | # replaced with their usename.
43 | # Feel free to send me a message if you want more injectors
44 |
45 | MAXPOSTS = 100
46 | # How many submissions / how many comments to get on each run
47 | # PRAW can get up to 100 in a single call
48 | # Submissions and comments will EACH get this many
49 | # I recommend leaving it at 100
50 |
51 | WAIT = 30
52 | # How many seconds to wait between runs.
53 | # The bot is completely inactive during this time.
54 | ERROR_WAIT = 20
55 | # An additional waiting period, used when the bot hits an error.
56 | # Can help prevent unecessary timeouts by waiting for the servers
57 |
58 | ''' All done! '''
59 |
60 | try:
61 | import bot
62 | USERAGENT = bot.aG
63 | except ImportError:
64 | pass
65 |
66 | sql = sqlite3.connect('sql.db')
67 | cur = sql.cursor()
68 | cur.execute('CREATE TABLE IF NOT EXISTS users(name TEXT)')
69 | cur.execute('CREATE INDEX IF NOT EXISTS userindex on users(name)')
70 | sql.commit()
71 |
72 | print('Logging in')
73 | r = praw.Reddit(USERAGENT)
74 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
75 | r.refresh_access_information(APP_REFRESH)
76 |
77 | def welcomebot():
78 | print('Scanning /r/%s' % SUBREDDIT)
79 | posts = []
80 | subreddit = r.get_subreddit(SUBREDDIT)
81 | if CHECK_SUBMISSIONS:
82 | print('Getting submissions')
83 | posts += list(subreddit.get_new(limit=MAXPOSTS))
84 | if CHECK_COMMENTS:
85 | print('Getting comments')
86 | posts += list(subreddit.get_comments(limit=MAXPOSTS))
87 |
88 | for post in posts:
89 | try:
90 | pauthor = post.author.name
91 | cur.execute('SELECT * FROM users WHERE name=?', [pauthor])
92 | fetch = cur.fetchone()
93 | if fetch is None:
94 | cur.execute('INSERT INTO users VALUES(?)', [pauthor])
95 | sql.commit()
96 | message_subject = MESSAGE_SUBJECT.replace('_author_', pauthor)
97 | message_body = MESSAGE_BODY.replace('_author_', pauthor)
98 | print('%s, %s ... ' % (post.fullname, pauthor), end="")
99 | sys.stdout.flush()
100 | r.send_message(pauthor, message_subject, message_body, captcha=None)
101 | print('Message sent!')
102 | except AttributeError:
103 | #Post is deleted so we don't care about it
104 | pass
105 |
106 | while True:
107 | try:
108 | welcomebot()
109 | except:
110 | traceback.print_exc()
111 | print('Waiting %d grace period' % ERROR_WAIT)
112 | time.sleep(ERROR_WAIT)
113 | print('Sleeping %d seconds\n' % WAIT)
114 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/_old/Wikiname/README.md:
--------------------------------------------------------------------------------
1 | WikiNames
2 | =============
3 |
4 | This bot will scan a subreddit for new submissions. The authors' names will be added to a wiki page as a hyperlink to that post. Only one entry will exist per user, pointing to their most recent post. Names are alphabetized with bold headers
5 |
6 | See [here](http://www.reddit.com/r/GoldTesting/wiki/gold) for an example
--------------------------------------------------------------------------------
/_old/bot_template.py:
--------------------------------------------------------------------------------
1 | # /u/GoldenSights
2 | import praw
3 | #import sqlite3
4 | import time
5 | import traceback
6 |
7 | ''' USER CONFIG '''
8 | USERAGENT = ""
9 | APP_ID = ""
10 | APP_SECRET = ""
11 | APP_URI = ""
12 | APP_REFRESH = ""
13 | # https://www.reddit.com/comments/3cm1p8/how_to_make_your_bot_use_oauth2/
14 |
15 | WAIT = 60
16 | # The number of seconds between each cycle. The bot is completely inactive during this time.
17 | ''' All done! '''
18 |
19 | try:
20 | import bot
21 | USERAGENT = bot.aG
22 | APP_ID = bot.oG_id
23 | APP_SECRET = bot.oG_secret
24 | APP_URI = bot.oG_uri
25 | APP_REFRESH = bot.oG_scopes['all']
26 | except ImportError:
27 | pass
28 |
29 | #sql = sqlite3.connect('filename.db')
30 | #cur = sql.cursor()
31 | #cur.execute('CREATE TABLE IF NOT EXISTS tablename(column TEXT)')
32 | #cur.execute('CREATE INDEX IF NOT EXISTS indexname ON tablename(column)')
33 | p
34 | rint('Logging in.')
35 | r = praw.Reddit(USERAGENT)
36 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
37 | r.refresh_access_information(APP_REFRESH)
38 |
39 |
40 | def main():
41 | pass
42 |
43 |
44 | while True:
45 | try:
46 | main()
47 | except Exception as e:
48 | traceback.print_exc()
49 | print('Running again in %d seconds\n' % WAIT)
50 | time.sleep(WAIT)
--------------------------------------------------------------------------------
/bot3.py:
--------------------------------------------------------------------------------
1 | '''
2 | bot.py template for PRAW3
3 |
4 | This file will be imported by all bots, and provides a standard way to log in.
5 |
6 | You should never place this file in a git repository or any place where it will
7 | get shared.
8 |
9 | The requirements for this file are:
10 |
11 | 1 A function `anonymous` with no arguments, which returns a `praw.Reddit`
12 | instance that has a Useragent but is otherwise anonymous / unauthenticated.
13 | This will be used in bots that need to make requests but don't need any
14 | permissions.
15 |
16 | 2 A function `login` with optional parameter `r`, which returns an
17 | authenticated Reddit instance.
18 | If `r` is provided, authenticate it.
19 | If not, create one using `anonymous` and authenticate that.
20 | Either way, return the instance when finished.
21 |
22 | The exact workings of these functions, and the existence of any other variables
23 | and functions are up to you.
24 |
25 | I suggest placing this file in a private directory and adding that directory to
26 | your `PYTHONPATH` environment variable. This makes it importable from anywhere.
27 |
28 | However, you may place it in your default Python library. An easy way to find
29 | this is by importing a standard library module and checking its location:
30 | >>> import os
31 | >>> os
32 |
33 |
34 | But placing the file in the standard library means you will have to copy it over
35 | when you upgrade Python.
36 |
37 | If you need multiple separate bots, I would suggest creating copies of this file
38 | with different names, and then using `import specialbot as bot` within the
39 | application, so that the rest of the interface can stay the same.
40 | '''
41 |
42 | import praw
43 |
44 | # https://praw.readthedocs.io/en/latest/tutorials/refresh_token.html
45 | CONTACT_INFO = ''
46 | USERAGENT = 'xxx'
47 | APP_ID = 'xxx'
48 | APP_SECRET = 'xxx'
49 | APP_URI = 'xxx'
50 | APP_REFRESH = 'xxx'
51 |
52 | def anonymous():
53 | r = praw.Reddit(USERAGENT)
54 | return r
55 |
56 | def login(r=None):
57 | if r is None:
58 | r = anonymous()
59 |
60 | if r.access_token is not None:
61 | return r
62 |
63 | r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
64 | r.refresh_access_information(APP_REFRESH)
65 | r.config.api_request_delay = 1
66 | return r
67 |
--------------------------------------------------------------------------------