├── .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 | Timesearch 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 | Flairmail example 54 |

55 | 56 |

57 | Flairmail example 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 | Flairmail example 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 | ![Create tab](/../master/.GitImages/Schedulizer00.png?raw=true) 16 | ![Making a post](/../master/.GitImages/Schedulizer01.png?raw=true) 17 | ![Check upcoming](/../master/.GitImages/Schedulizer02.png?raw=true) 18 | ![Check history](/../master/.GitImages/Schedulizer03.png?raw=true) -------------------------------------------------------------------------------- /_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 | Always watching, always helping. 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 | --------------------------------------------------------------------------------