Skip to content

Instantly share code, notes, and snippets.

@13steinj
Last active September 23, 2017 15:20

Revisions

  1. 13steinj revised this gist Jan 15, 2016. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion modapplicationposter.py
    Original file line number Diff line number Diff line change
    @@ -252,7 +252,8 @@ def profanitycheck(badwords, *args):
    for check in check_list:
    if re.search(word.lower(), check.lower()):
    badwordusage +=1
    profanity_usage[word] = badwordusage
    if badwordusage:
    profanity_usage[word] = badwordusage
    badwordtotalusage += badwordusage
    return badwordtotalusage, profanity_usage

  2. 13steinj revised this gist Nov 28, 2015. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions modapplicationposter.py
    Original file line number Diff line number Diff line change
    @@ -169,8 +169,9 @@ def background_check(reddit_session, username, badwords=[], post_sub=None):
    body += timeposttext + "\n\n"
    comments = list(user.get_comments(limit=None))
    totalprofanities, specificprofanities = profanitycheck(badwords, posts, comments)
    orderedprofanities = sorted(specificprofanities.keys(), key=str.lower)
    profanitytable = "Profanity | Times Used\n---|---"
    for word in specificprofanities:
    for word in orderedprofanities:
    profanitytable += "\n"
    profanitytable += "{0} | {1}".format(word, specificprofanities[word])
    profanitytable += "\n**Total** | {0}".format(totalprofanities)
    @@ -249,7 +250,7 @@ def profanitycheck(badwords, *args):
    for word in badwords:
    badwordusage = 0
    for check in check_list:
    if re.search(word, check):
    if re.search(word.lower(), check.lower()):
    badwordusage +=1
    profanity_usage[word] = badwordusage
    badwordtotalusage += badwordusage
  3. 13steinj revised this gist Nov 28, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion modapplicationposter.py
    Original file line number Diff line number Diff line change
    @@ -127,7 +127,7 @@ def background_check(reddit_session, username, badwords=[], post_sub=None):
    username = username[3:]
    elif username.lower().startswith('u/'):
    username = username[2:]
    body = "#Background Check:\n\n" if not title else "/u/{0}:\n\n".format(username)
    body = "#Background Check -- /u/{0}:\n\n".format(username) if not title else "/u/{0}:\n\n".format(username)
    if title:
    print("Running background check on /u/{0}".format(username))
    user = reddit_session.get_redditor(username)
  4. 13steinj revised this gist Nov 28, 2015. 1 changed file with 10 additions and 2 deletions.
    12 changes: 10 additions & 2 deletions theinfo.md
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,11 @@
    Named theinfo.md because if it was README.md github gists has a bug that changes the title name of the gist to README.md

    praw and openpyxl must be installed. OAuth2Util is optional. In a terminal with root access:
    praw and openpyxl must be installed. BeautifulSoup's requirement is dependant on whether or not a profanity check is run, but better safe than sorry. OAuth2Util is optional. In a terminal with root access:

    pip3 install openpyxl
    pip3 install praw
    pip3 install praw-OAuth2Util
    pip3 install BeautifulSoup4

    Recommended usage is as follows:

    @@ -27,6 +28,13 @@ Note: Like above, you may need to replace `python3` with `py -3`

    `**kw` are any of the other params as mentioned by the docstring in modapplicationposter.py.


    For profanity checks, words in the badwords list SHOULD NOT have both themselves and themselves endings attached, uch as doing `['fuck', 'fucking']`, as there will be skewed results.

    This may take some time, even more if background checks are enabled, so set it to run, and put up netflix and chill while watching it just in case

    Note: If you get some weird language when you get an error, it's because I was drunk when I first wrote this, and when I continued and was sober, I found it funny and kept it in.

    Also: READ THE DOCSTRINGS
    Also: READ THE DOCSTRINGS

    Running a plain background check is the same running the main instance, just fit the paramaters accordingly.
  5. 13steinj revised this gist Nov 28, 2015. 2 changed files with 92 additions and 21 deletions.
    111 changes: 91 additions & 20 deletions modapplicationposter.py
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    BAD_WORDS = ['shit', 'piss', 'fuck']

    def run(workbookname, usernamecolletter=None, subreddit=None, notifyme=False, useragent=None, username=None, password=None):
    def run(workbookname, usernamecolletter=None, subreddit=None, badwords=[], notifyme=False, runbackgroundcheck=True, useragent=None, username=None, password=None):
    """
    Main instance
    @@ -13,6 +13,9 @@ def run(workbookname, usernamecolletter=None, subreddit=None, notifyme=False, us
    :param notifyme: whether or not to send inbox replies to the account that is making the posts. default is False.
    :param subreddit: the sub to post to (string or praw.objects.Subreddit object). While it is a
    keyword argument, that's only cause technicalities. IT IS REQUIRED.
    :param badwords: list of badwords for background checks. Default is BAD_WORDS in this file.
    :param runbackgroundcheck: Boolean, whether or not to add a background check to the post.
    BACKGROUND CHECKS CAN TAKE SOME TIME. If there is no username found from the spreadsheet, it will be skipped
    :param useragent: optional useragent to specify. The default is
    'Mod application to subreddit poster posting to /r/{subreddit} by /u/13steinj'
    :params username, password: A username and password to specify if you wish to use LoginAuth.
    @@ -25,6 +28,7 @@ def run(workbookname, usernamecolletter=None, subreddit=None, notifyme=False, us
    raise TypeError("run() missing required keyword argument subreddit, dipshit")
    import praw
    import openpyxl
    badwords = badwords or BAD_WORDS
    useragent = (useragent or
    ("Mod application to subreddit "
    "poster posting to /r/{0} by /u/13steinj".format(subreddit)))
    @@ -81,29 +85,59 @@ def run(workbookname, usernamecolletter=None, subreddit=None, notifyme=False, us
    continue
    else:
    username = cell.value if cell.column == usernamecolletter else None
    titleinfo = "at {0}".format(row[0].value) if not username else "by {0}".format(username)
    title = "Moderator Application #{0} {1}".format(rownum, titleinfo)
    post = r.submit(subreddit, title, text=body, send_replies=notifyme)
    print("Submitted {0}".format(post.permalink))
    if username and username.startswith("/u/"):
    username = username[3:]
    elif username and username.startswith("u/"):
    username = username[2:]
    if username and runbackgroundcheck:
    body += background_check(r, username, badwords=badwords)
    if len(body) > 40000:
    bodies = list(_util_bodies(40000, body))
    else:
    bodies = [body]
    titleinfo = "at /u/{0}".format(row[0].value) if not username else "by /u/{0}".format(username)
    maintitle = "Moderator Application #{0} {1}".format(rownum, titleinfo)
    for body in bodies:
    if bodies.index(body) > 0:
    title = "{0} Part {1}".format(maintitle, (bodies.index(body) + 1))
    else:
    title = maintitle
    post = r.submit(subreddit, title, text=body, send_replies=notifyme)
    print("Submitted {0}".format(post.permalink))
    print("I've just posted {0} applications, dipshit. I'm done now. Call me when you want me again. But you could at least ask me out to dinner first, you rascal!".format(rownum))
    return rownum, subreddit

    def background_check(reddit_session, username, post_sub=None, badwords=[]):
    def background_check(reddit_session, username, badwords=[], post_sub=None):
    """Run a background check on a username
    :param reddit_session: a reddit session via praw, usually r
    :param username: username to check
    :param badwords: list of badwords to run in the profanitychecker
    :param post_sub: if you want to post this check to a sub, this
    should be the sub name or the subreddit object of this sub name
    :returns: post if post_sub is defined, else a background check string.
    """
    from praw.errors import NotFound, Forbidden
    import datetime
    cannot_submit = reddit_session.user == None and not reddit_session.is_oauth_session()
    if cannot_submit and post_sub != None:
    raise ValueError("Can't post without being logged in, dipshit")
    title = "Background Check: {0}".format(username) if post_sub else None
    body = "Background Check:\n\n" if not title else ""
    if username.lower().startswith('/u/'):
    username = username[3:]
    elif username.lower().startswith('u/'):
    username = username[2:]
    body = "#Background Check:\n\n" if not title else "/u/{0}:\n\n".format(username)
    if title:
    print("Running background check on /u/{0}".format(username))
    user = reddit_session.get_redditor(username)
    try:
    dumblist = list(user.get_overview())
    except NotFound:
    body += "Account doesn't exist"
    body += "Account doesn't exist or deleted or shadowbanned"
    return body
    except Forbidden:
    body += "Account deleted or shadowbanned or permanently suspended"
    body += "Account permanently suspended"
    return body
    ucreated = datetime.datetime.fromtimestamp(user.created_utc)
    utimeago = "Account made {0} ago".format(str(datetime.datetime.now() - ucreated))
    @@ -114,7 +148,7 @@ def background_check(reddit_session, username, post_sub=None, badwords=[]):
    try:
    timepost = posts[100]
    timepostnum = 100
    timepostord = ordinal(timepostnum)
    timepostord = _util_ordinal(timepostnum)
    timepostpre = timepostord + " post"
    timepostdate = datetime.datetime.fromtimestamp(timepost.created_utc)
    timeago = "made {0} ago".format(str(datetime.datetime.now() - timepostdate))
    @@ -124,7 +158,7 @@ def background_check(reddit_session, username, post_sub=None, badwords=[]):
    try:
    timepost = posts[-1]
    timepostnum = (posts.index(timepost) + 1)
    timepostord = ordinal(timepostnum)
    timepostord = _util_ordinal(timepostnum)
    timepostpre = "last({0}) post".format(timepostord)
    timepostdate = datetime.datetime.fromtimestamp(timepost.created_utc)
    timeago = "made {0} ago".format(str(datetime.datetime.now() - timepostdate))
    @@ -135,15 +169,29 @@ def background_check(reddit_session, username, post_sub=None, badwords=[]):
    body += timeposttext + "\n\n"
    comments = list(user.get_comments(limit=None))
    totalprofanities, specificprofanities = profanitycheck(badwords, posts, comments)
    table = "Profanity | Times Used\n---|---"
    profanitytable = "Profanity | Times Used\n---|---"
    for word in specificprofanities:
    table += "\n"
    table += "{0} | {1}".format(word, specificprofanities[word])
    profanitytable += "\n"
    profanitytable += "{0} | {1}".format(word, specificprofanities[word])
    profanitytable += "\n**Total** | {0}".format(totalprofanities)
    if specificprofanities:
    body += "Profanities used in the last 1000 posts and comments"
    body += table
    body += "Profanities used in the last 1000 posts and comments:\n\n"
    body += profanitytable + "\n\n"
    totalsubs, subhistory = historycheck(posts, comments)
    orderedsubs = sorted(subhistory.keys(), key=str.lower)
    historytable = "Subreddit | Times Used\n---|---"
    for subreddit in orderedsubs:
    historytable += '\n'
    historytable += "/r/{0} | {1}".format(subreddit, subhistory[subreddit])
    historytable += "\n**Total** | {0}".format(totalsubs)
    body += "Subreddit history over last 1000 posts and comments:\n\n"
    body += historytable + "\n\n"
    if title:
    post = reddit_session.submit(post_sub, title, text=body)
    return post
    return body

    def ordinal(value):
    def _util_ordinal(value):
    """
    Converts zero or a *postive* integer (or their string
    representations) to an ordinal value.
    @@ -170,11 +218,17 @@ def ordinal(value):

    return ordval

    def _util_bodies(num, string):
    """Produce `num`-character chunks from `string`."""
    for start in range(0, len(string), num):
    yield string[start:start+num]

    def profanitycheck(badwords, *args):
    """
    Profanity Checker
    :param badwords: list of badwords
    :param args: comma delimited list of lists of posts or comments
    :param badwords: list of badwords. Recommended to not contain endings i.e "ing",
    "ed" for best results, as containing those may make for duplicates.
    :param args: comma delimited list of iters of posts or comments
    :returns: dict of word: usagecount for each word in badwords
    """
    import re
    @@ -199,4 +253,21 @@ def profanitycheck(badwords, *args):
    badwordusage +=1
    profanity_usage[word] = badwordusage
    badwordtotalusage += badwordusage
    return badwordtotalusage, profanity_usage
    return badwordtotalusage, profanity_usage

    def historycheck(*args):
    """
    Subreddit History Checker
    :param args: comma delimited list of iters of posts or comments
    """
    obj_list = []
    subreddit_history = {}
    for l in args:
    obj_list += l
    for Thing in obj_list:
    subtotal = subreddit_history.get(Thing.subreddit.display_name, 0)
    subreddit_history.update({Thing.subreddit.display_name: (subtotal+1)})
    totalsubs = 0
    for num in subreddit_history.values():
    totalsubs += num
    return totalsubs, subreddit_history
    2 changes: 1 addition & 1 deletion theinfo.md
    Original file line number Diff line number Diff line change
    @@ -29,4 +29,4 @@ Note: Like above, you may need to replace `python3` with `py -3`

    Note: If you get some weird language when you get an error, it's because I was drunk when I first wrote this, and when I continued and was sober, I found it funny and kept it in.

    Also: READ THE DOCSTRING
    Also: READ THE DOCSTRINGS
  6. 13steinj revised this gist Nov 27, 2015. 1 changed file with 116 additions and 1 deletion.
    117 changes: 116 additions & 1 deletion modapplicationposter.py
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    BAD_WORDS = ['shit', 'piss', 'fuck']

    def run(workbookname, usernamecolletter=None, subreddit=None, notifyme=False, useragent=None, username=None, password=None):
    """
    Main instance
    @@ -84,4 +86,117 @@ def run(workbookname, usernamecolletter=None, subreddit=None, notifyme=False, us
    post = r.submit(subreddit, title, text=body, send_replies=notifyme)
    print("Submitted {0}".format(post.permalink))
    print("I've just posted {0} applications, dipshit. I'm done now. Call me when you want me again. But you could at least ask me out to dinner first, you rascal!".format(rownum))
    return rownum, subreddit
    return rownum, subreddit

    def background_check(reddit_session, username, post_sub=None, badwords=[]):
    from praw.errors import NotFound, Forbidden
    import datetime
    cannot_submit = reddit_session.user == None and not reddit_session.is_oauth_session()
    if cannot_submit and post_sub != None:
    raise ValueError("Can't post without being logged in, dipshit")
    title = "Background Check: {0}".format(username) if post_sub else None
    body = "Background Check:\n\n" if not title else ""
    user = reddit_session.get_redditor(username)
    try:
    dumblist = list(user.get_overview())
    except NotFound:
    body += "Account doesn't exist"
    return body
    except Forbidden:
    body += "Account deleted or shadowbanned or permanently suspended"
    return body
    ucreated = datetime.datetime.fromtimestamp(user.created_utc)
    utimeago = "Account made {0} ago".format(str(datetime.datetime.now() - ucreated))
    utimeon = "on " + str(ucreated)
    utimetext = " ".join([utimeago, utimeon])
    body += utimetext + "\n\n"
    posts = list(user.get_submitted(limit=None))
    try:
    timepost = posts[100]
    timepostnum = 100
    timepostord = ordinal(timepostnum)
    timepostpre = timepostord + " post"
    timepostdate = datetime.datetime.fromtimestamp(timepost.created_utc)
    timeago = "made {0} ago".format(str(datetime.datetime.now() - timepostdate))
    timeon = "on " + str(timepostdate)
    timeposttext = " ".join([timepostpre, timeago, timeon])
    except IndexError:
    try:
    timepost = posts[-1]
    timepostnum = (posts.index(timepost) + 1)
    timepostord = ordinal(timepostnum)
    timepostpre = "last({0}) post".format(timepostord)
    timepostdate = datetime.datetime.fromtimestamp(timepost.created_utc)
    timeago = "made {0} ago".format(str(datetime.datetime.now() - timepostdate))
    timeon = "on " + str(timepostdate)
    timeposttext = " ".join([timepostpre, timeago, timeon])
    except IndexError:
    timeposttext = "User has not made a single post, or all are deleted"
    body += timeposttext + "\n\n"
    comments = list(user.get_comments(limit=None))
    totalprofanities, specificprofanities = profanitycheck(badwords, posts, comments)
    table = "Profanity | Times Used\n---|---"
    for word in specificprofanities:
    table += "\n"
    table += "{0} | {1}".format(word, specificprofanities[word])
    if specificprofanities:
    body += "Profanities used in the last 1000 posts and comments"
    body += table

    def ordinal(value):
    """
    Converts zero or a *postive* integer (or their string
    representations) to an ordinal value.
    http://code.activestate.com/recipes/576888-format-a-number-as-an-ordinal/
    """
    try:
    value = int(value)
    except ValueError:
    return value

    if value % 100//10 != 1:
    if value % 10 == 1:
    ordval = u"%d%s" % (value, "st")
    elif value % 10 == 2:
    ordval = u"%d%s" % (value, "nd")
    elif value % 10 == 3:
    ordval = u"%d%s" % (value, "rd")
    else:
    ordval = u"%d%s" % (value, "th")
    else:
    ordval = u"%d%s" % (value, "th")

    return ordval

    def profanitycheck(badwords, *args):
    """
    Profanity Checker
    :param badwords: list of badwords
    :param args: comma delimited list of lists of posts or comments
    :returns: dict of word: usagecount for each word in badwords
    """
    import re
    from bs4 import BeautifulSoup
    obj_list = []
    html_list = []
    check_list = []
    profanity_usage = {}
    for l in args:
    obj_list += l
    html_list += [obj.selftext_html for obj in obj_list if hasattr(obj, 'selftext_html')]
    html_list += [obj.body_html for obj in obj_list if hasattr(obj, 'body_html')]
    for html in html_list:
    if html == None:
    continue
    check_list += BeautifulSoup(html).get_text().split()
    badwordtotalusage = 0
    for word in badwords:
    badwordusage = 0
    for check in check_list:
    if re.search(word, check):
    badwordusage +=1
    profanity_usage[word] = badwordusage
    badwordtotalusage += badwordusage
    return badwordtotalusage, profanity_usage
  7. 13steinj revised this gist Nov 27, 2015. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions theinfo.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,11 @@
    Named theinfo.md because if it was README.md github gists has a bug that changes the title name of the gist to README.md

    praw and openpyxl must be installed. OAuth2Util is optional. In a terminal with root access:

    pip3 install openpyxl
    pip3 install praw
    pip3 install praw-OAuth2Util

    Recommended usage is as follows:

    Place the Microsoft Office(`xlsx`) (not Microsoft Office Legacy(`xls`), those don't work as well or may not at all, don't know) and this script in the same folder. If you have an OAuth2Util oauth.ini, put that in here to. The script will attempt to use OAuth if it can, else it will default to the username ad password arguments, if possible, else raise an error.
  8. 13steinj revised this gist Nov 27, 2015. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion theinfo.md
    Original file line number Diff line number Diff line change
    @@ -21,4 +21,6 @@ Note: Like above, you may need to replace `python3` with `py -3`

    `**kw` are any of the other params as mentioned by the docstring in modapplicationposter.py.

    Note: If you get some weird language when you get an error, it's because I was drunk when I first wrote this, and when I continued and was sober, I found it funny and kept it in.
    Note: If you get some weird language when you get an error, it's because I was drunk when I first wrote this, and when I continued and was sober, I found it funny and kept it in.

    Also: READ THE DOCSTRING
  9. 13steinj renamed this gist Nov 27, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion INFO.md → theinfo.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    Named INFO.md because if it was README.md github gists has a bug that changes the title name of the gist to README.md
    Named theinfo.md because if it was README.md github gists has a bug that changes the title name of the gist to README.md

    Recommended usage is as follows:

    @@ -21,3 +21,4 @@ Note: Like above, you may need to replace `python3` with `py -3`

    `**kw` are any of the other params as mentioned by the docstring in modapplicationposter.py.

    Note: If you get some weird language when you get an error, it's because I was drunk when I first wrote this, and when I continued and was sober, I found it funny and kept it in.
  10. 13steinj revised this gist Nov 27, 2015. 1 changed file with 23 additions and 0 deletions.
    23 changes: 23 additions & 0 deletions INFO.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    Named INFO.md because if it was README.md github gists has a bug that changes the title name of the gist to README.md

    Recommended usage is as follows:

    Place the Microsoft Office(`xlsx`) (not Microsoft Office Legacy(`xls`), those don't work as well or may not at all, don't know) and this script in the same folder. If you have an OAuth2Util oauth.ini, put that in here to. The script will attempt to use OAuth if it can, else it will default to the username ad password arguments, if possible, else raise an error.

    To run, either:

    Open python3 in a terminal, depending on the OS it's either `python3` or `py -3`.
    Type

    >>> from modapplicationposter import run
    >>> run('nameofworkbookwithoutxlsx', 'columnletterforusernamesifapplicable',
    ... subreddit='subreddityouarepostingtowithout/r/' **kw)

    You can also do this in a terminal/cmd:

    python3 -c "from modapplicationposter import run; run('nameofworkbookwithoutxlsx', 'columnletterforusernamesifapplicable', subreddit='subreddityouarepostingtowithout/r/' **kw)"

    Note: Like above, you may need to replace `python3` with `py -3`

    `**kw` are any of the other params as mentioned by the docstring in modapplicationposter.py.

  11. 13steinj revised this gist Nov 27, 2015. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion modapplicationposter.py
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,6 @@ def run(workbookname, usernamecolletter=None, subreddit=None, notifyme=False, us
    raise TypeError("run() missing required keyword argument subreddit, dipshit")
    import praw
    import openpyxl
    from openpyxl.cell import get_column_letter as gcl
    useragent = (useragent or
    ("Mod application to subreddit "
    "poster posting to /r/{0} by /u/13steinj".format(subreddit)))
  12. 13steinj revised this gist Nov 27, 2015. 1 changed file with 60 additions and 24 deletions.
    84 changes: 60 additions & 24 deletions modapplicationposter.py
    Original file line number Diff line number Diff line change
    @@ -1,52 +1,88 @@
    def run(workbookname, subreddit, useragent=None, usernamecol=None, notifyme=True):
    def run(workbookname, usernamecolletter=None, subreddit=None, notifyme=False, useragent=None, username=None, password=None):
    """
    Main instance
    :param usernamecol: the text in the column that denotes the applicant's username
    :param notifyme: whether or not to send inbox replies to the account that is making the posts
    The user that is OAuthed or LoginAuthed must be an approved contributor to the sub to post apps
    and must be an approved submitter to the sub. Just making it a mod won't work.
    :param usernamecolletter: the letter of the column that denotes the applicant's username.
    If not specified, it will make the title have the timestamp instead of the user's name. This
    script assumes that the timestamp row is the first row, so it uses appropiate grammar to comply.
    :param notifyme: whether or not to send inbox replies to the account that is making the posts. default is False.
    :param subreddit: the sub to post to (string or praw.objects.Subreddit object). While it is a
    keyword argument, that's only cause technicalities. IT IS REQUIRED.
    :param useragent: optional useragent to specify. The default is
    'Mod application to subreddit poster posting to /r/{subreddit} by /u/13steinj'
    :params username, password: A username and password to specify if you wish to use LoginAuth.
    If OAuth is available, OAuth will have priority. If it fails, login auth will be used.
    IN PRAW4 LOGIN AUTH WILL BE DEPRECATED, JUST AS A REMINDER IN CASE YOU SAY THIS SCRIPT DOESN'T WORK WHEN IT'S OUT
    :returns: The amount of posts made and the sub they were made to.
    """
    if subreddit == None:
    raise TypeError("run() missing required keyword argument subreddit, dipshit")
    import praw
    import OAuth2Util
    import openpyxl
    from openpyxl.cell import get_column_letter as gcl
    useragent = (useragent or
    ("Mod application to subreddit "
    "poster posting to /r/{0}".format(subreddit)))
    "poster posting to /r/{0} by /u/13steinj".format(subreddit)))
    r = praw.Reddit(useragent)
    o = OAuth2Util.OAuth2Util(r)
    o.refresh(force=True)
    spreadsheet = openpyxl.load_workbook('{0}.xlsx'.format(workbookname))
    sheets = spreadsheet.get_sheet_names()
    try:
    import OAuth2Util
    o = OAuth2Util.OAuth2Util(r)
    o.refresh(force=True)
    except Exception as e:
    if e.__class__ == ImportError and username and password:
    print("OAuth2Util not installed, using login")
    r.login(username, password)
    elif username and password:
    print("OAuth2Util failure, attempting to use login")
    r.login(username, password)
    print("Success")
    else:
    raise
    workbook = openpyxl.load_workbook('{0}.xlsx'.format(workbookname))
    sheets = workbook.get_sheet_names()
    if len(sheets) > 1:
    sheetlist = '\n'.join(['{0}: {1}'.format((sheets.index(i)+1), i) for i in sheets]))
    num = input("Which sheet would you like?\n{0}\n".format(sheetlist)
    sheetlist = '\n'.join(['{0}: {1}'.format((sheets.index(i)+1), i) for i in sheets])
    num = input("Which sheet would you like?\n{0}\n".format(sheetlist))
    try:
    num = int(num)
    if num <= 0:
    raise IndexError('What a dipshit this user is. If only we could replace them with more code...')
    raise IndexError("What a dipshit this user is. If only we could replace them with more code...")
    sheet = sheets[num-1]
    except ValueError:
    raise ValueError('You had to choose a number, dipshit')
    raise ValueError("You had to choose a number, dipshit")
    except IndexError:
    raise IndexError('That sheet doesn't exist, dipshit.')
    raise IndexError("That sheet doesn't exist, dipshit.")
    else:
    sheet = sheets[0]
    spreadsheet = spreadsheet[sheet]
    rows = spreadsheet.rows
    spreadsheet = workbook[sheet]
    rows = list(spreadsheet.rows)
    questionrow = rows.pop(0)
    questionvals = {cell.column: cell.value for cell in questionrow}
    try:
    usernamecolnum = {v: k for k, v in questionvals.iteritems()}[usernamecol] if usernamecol else None
    except KeyError:
    raise KeyError('That usernamecolumn doesn't exist, dipshit')
    questionvals = {cell.column: cell.value for cell in questionrow if cell.value is not None}
    if usernamecolletter and usernamecolletter not in questionvals:
    raise KeyError("That usernamecolumnletter doesn't exist, dipshit")
    rownum = 0
    for row in rows:
    # clear out username, title, and body for next run
    rownum += 1
    username = None
    body = ''
    # make body
    for cell in row:
    if cell.column not in questionvals:
    continue
    body += "#{0}\n\n".format(questionvals[cell.column])
    body += "{0}\n\n---\n\n".format(cell.value)
    titleinfo = "at {0}".format(row[1]) if not usernamecolnum else "by {0}".format(row[usernamecolnum])
    body += "{0}\n\n---\n\n".format(cell.value if cell.value else "*No Answer*")
    if username:
    continue
    else:
    username = cell.value if cell.column == usernamecolletter else None
    titleinfo = "at {0}".format(row[0].value) if not username else "by {0}".format(username)
    title = "Moderator Application #{0} {1}".format(rownum, titleinfo)
    r.submit(subreddit, title, text=body, send_replies=notifyme)
    post = r.submit(subreddit, title, text=body, send_replies=notifyme)
    print("Submitted {0}".format(post.permalink))
    print("I've just posted {0} applications, dipshit. I'm done now. Call me when you want me again. But you could at least ask me out to dinner first, you rascal!".format(rownum))
    return rownum, subreddit
  13. 13steinj created this gist Nov 21, 2015.
    52 changes: 52 additions & 0 deletions modapplicationposter.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    def run(workbookname, subreddit, useragent=None, usernamecol=None, notifyme=True):
    """
    Main instance
    :param usernamecol: the text in the column that denotes the applicant's username
    :param notifyme: whether or not to send inbox replies to the account that is making the posts
    """
    import praw
    import OAuth2Util
    import openpyxl
    useragent = (useragent or
    ("Mod application to subreddit "
    "poster posting to /r/{0}".format(subreddit)))
    r = praw.Reddit(useragent)
    o = OAuth2Util.OAuth2Util(r)
    o.refresh(force=True)
    spreadsheet = openpyxl.load_workbook('{0}.xlsx'.format(workbookname))
    sheets = spreadsheet.get_sheet_names()
    if len(sheets) > 1:
    sheetlist = '\n'.join(['{0}: {1}'.format((sheets.index(i)+1), i) for i in sheets]))
    num = input("Which sheet would you like?\n{0}\n".format(sheetlist)
    try:
    num = int(num)
    if num <= 0:
    raise IndexError('What a dipshit this user is. If only we could replace them with more code...')
    sheet = sheets[num-1]
    except ValueError:
    raise ValueError('You had to choose a number, dipshit')
    except IndexError:
    raise IndexError('That sheet doesn't exist, dipshit.')
    else:
    sheet = sheets[0]
    spreadsheet = spreadsheet[sheet]
    rows = spreadsheet.rows
    questionrow = rows.pop(0)
    questionvals = {cell.column: cell.value for cell in questionrow}
    try:
    usernamecolnum = {v: k for k, v in questionvals.iteritems()}[usernamecol] if usernamecol else None
    except KeyError:
    raise KeyError('That usernamecolumn doesn't exist, dipshit')
    rownum = 0
    for row in rows:
    rownum += 1
    body = ''
    for cell in row:
    body += "#{0}\n\n".format(questionvals[cell.column])
    body += "{0}\n\n---\n\n".format(cell.value)
    titleinfo = "at {0}".format(row[1]) if not usernamecolnum else "by {0}".format(row[usernamecolnum])
    title = "Moderator Application #{0} {1}".format(rownum, titleinfo)
    r.submit(subreddit, title, text=body, send_replies=notifyme)
    print("I've just posted {0} applications, dipshit. I'm done now. Call me when you want me again. But you could at least ask me out to dinner first, you rascal!".format(rownum))
    return rownum, subreddit