Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import csv
- import random
- import sys
- import reddit
- import re
- import time
- from urllib2 import HTTPError
- confirm_thread = 'yip5e'
- giveaway_thread = 'yf9q0'
- #####################################################
- Games = {}
- Users = {}
- banlist = None
- def flush():
- sys.stdout.flush()
- sys.stderr.flush()
- class Game(object):
- name = ""
- stock = 0
- keys = None
- winners = None
- next_game = None
- def __init__(self, line):
- name, stock, next_game, keys = line
- self.winners = set()
- self.name = name.strip()
- self.stock = int(stock)
- self.next_game = next_game.strip() or None
- if keys:
- self.keys = [x.strip() for x in keys.split(',')]
- else:
- self.keys = None
- def __repr__(self):
- return "%s (x%d)" % (self.name, self.stock)
- class User(object):
- name = ""
- steam = ""
- pif_eligible = False
- wants = None
- def prune(self):
- global Users
- removes = []
- for i in xrange(len(self.wants)):
- if self.wants[i].stock <= 0:
- removes.append(i)
- removes.reverse()
- for i in removes:
- self.wants.pop(i)
- if len(self.wants) == 0:
- print "Removing user %s" % self.name
- return True
- else:
- return False
- def win(self):
- global Users
- if len(self.wants) == 0:
- raise ValueError("User %s doesn't want anything" % self.name)
- won = self.wants[0]
- if won.stock <= 0:
- raise ValueError("Oversold game %s" % str(won))
- print "%s wins %s" % (self.name, won.name)
- Users.remove(self)
- won.winners.add(self)
- won.stock = won.stock - 1
- not_winners = set()
- if won.stock == 0:
- for user in Users:
- if user.prune():
- not_winners.add(user)
- for u in not_winners:
- Users.remove(u)
- def __init__(self, line):
- global Games
- self.name = line[1].strip().lower()
- self.steam = line[2].strip()
- games = line[3:12]
- self.wants = []
- for name in games:
- game = Games.get(name)
- while game:
- self.wants.append(game)
- game = Games.get(game.next_game)
- print "%s wants %s" % (self.name, ", ".join(x.name for x in self.wants))
- def __repr__(self):
- return self.name
- with open('banlist.txt', 'r') as banfile:
- banlist = set(x.strip().lower() for x in banfile.readlines())
- print 'Loaded %d banned users' % len(banlist)
- flush()
- r = reddit.Reddit('/u/blueshiftlabs/drawing.py')
- r.config.api_request_delay = 0.5
- print 'Log in to reddit to check users.'
- flush()
- success = False
- while not success:
- try:
- r.login('blueshiftlabs')
- success = True
- except reddit.errors.InvalidUserPass:
- print "Invalid password"
- flush()
- pass
- confirm = r.info(thing_id='t3_'+confirm_thread).next()
- giveaway = r.info(thing_id='t3_'+giveaway_thread).next()
- sgs = r.get_subreddit('SteamGameSwap')
- giveaway_match = re.match(u'\[GIVEAWAY\] (.*)', giveaway.title, re.I)
- if not giveaway_match:
- raise ValueError("Invalid giveaway thread!")
- giveaway_title = giveaway_match.group(1)
- print 'Giveaway name: %s' % giveaway_title
- print
- print '=================='
- print
- flush()
- with open('games.csv', 'r') as gamesfile:
- gamesreader = csv.reader(gamesfile)
- gamesreader.next() # skip header
- for gameline in gamesreader:
- game = Game(gameline)
- Games[game.name] = game
- print 'Added %s' % game
- flush()
- print
- print '=================='
- print
- with open('entries.csv', 'r') as entriesfile:
- entryreader = csv.reader(entriesfile)
- entryreader.next()
- for entry in entryreader:
- flush()
- if len(entry) == 0 or not entry[0]:
- continue
- user = User(entry)
- if not user.wants:
- print 'User %s does not want anything' % user.name
- continue
- username = user.name.lower()
- if username in banlist:
- print 'User %s is banned' % user.name
- else:
- action = 'Updated' if username in Users else 'Added'
- Users[username] = user
- print '%s entry for %s' % (action, user.name)
- print
- print
- print '=================='
- print
- flush()
- # Discard the user-lookup capabilities - we don't need them any longer.
- # Handle user data lookups now too.
- new_users = set()
- time_now = time.time()
- accepted = 0
- rejected = 0
- invalid = 0
- for user in Users.values():
- print 'Looking up %s... ' % user.name,
- flush()
- try:
- # userdata = r.get_redditor(user.name)
- info_url = r.config['user_about'] % user.name
- userdata = reddit.objects.RedditContentObject(r, None, True, info_url)
- # Fix case.
- user.name = userdata.name
- days = int((time_now - userdata.created) / (24 * 60 * 60)) + 1
- karma = userdata.link_karma + userdata.comment_karma
- if days < 60 or karma < 300:
- flair = sgs.get_flair(userdata.name)
- if not flair["flair_css_class"]:
- print '%s does not meet requirements (%d days, %d karma)' % (user.name, days, karma)
- rejected = rejected + 1
- continue
- else:
- print '%s OK by flair (%s, %d days, %d karma)' % (user.name, flair["flair_css_class"], days, karma)
- user.pif_eligible = False
- else:
- print '%s OK by time/karma (%d days, %d karma)' % (user.name, days, karma)
- user.pif_eligible = True
- accepted = accepted + 1
- new_users.add(user)
- except HTTPError:
- print 'Not a valid username!'
- invalid = invalid + 1
- continue
- print 'Processed %d usernames: %d accepted, %d rejected, %d invalid' % (len(Users), accepted, rejected, invalid)
- flush()
- Users = new_users
- print
- print '=================='
- print
- # Draw winners
- while len(Users) > 0:
- winner = random.sample(Users, 1)[0]
- winner.win()
- flush()
- print
- print '=================='
- print
- # Print results
- for game in Games.values():
- print '***'
- print
- print '## %s' % game.name
- print
- print 'Winners: %s' % (', '.join('[%(name)s](/user/%(name)s)' % {'name': x} for x in game.winners))
- print
- if game.stock:
- print 'Stock remaining: %d' % game.stock
- print
- flush()
- print
- print '=================='
- print
- i = 0
- print 'PiF eligible winners:'
- for game in Games.values():
- for winner in game.winners:
- if winner.pif_eligible:
- print '%s [%s]' % (winner.name, game.name)
- i = i + 1
- print '%d total PiF-eligible winners.' % i
- print
- print '=================='
- print
- flush()
- raw_input('Press Enter to send messages.')
- # Send messages
- confirm_message_template = """
- ### Drawing Results: %(giveaway)s
- [Giveaway thread here.](%(thread)s)
- Game | Winner | Confirmed
- :--- | :----- | :--------
- %(results)s"""
- confirm_result_template = "%s | %s | \n"
- def generate_confirm_message():
- wins = ((game.name, winner.name) for game in Games.values() for winner in game.winners)
- results = "".join((confirm_result_template % win) for win in wins)
- return confirm_message_template % {'giveaway': giveaway_title, 'thread': giveaway.permalink, 'results': results}
- confirm_message = generate_confirm_message()
- confirm_comment = confirm.add_comment(confirm_message)
- print
- print ">>> Confirmation post: " + confirm_comment.permalink
- print
- key_message = """Congratulations!
- You won: **%(game)s**
- Your key is: **%(key)s**
- Once you have activated this key, please [confirm receipt here.](%(link)s)
- As a reminder, this key is not to be sold or traded._
- Thanks,
- blueshiftlabs (/r/SGS)"""
- no_key_message = """Congratulations!
- You won: **%(game)s**
- Please **[add me on Steam](steam://friends/add/76561197981125077)** to receive your gift.
- Once you have received your gift, please [confirm receipt here.](%(link)s)
- _As a reminder, your gift is not to be sold or traded._
- Thanks,
- blueshiftlabs (/r/SGS)"""
- for game in Games.values():
- for winner in game.winners:
- message = None
- if game.keys is None:
- message = no_key_message % { 'game': game.name, 'link': confirm_comment.permalink }
- print '<no key provided> -> %s' % winner.name
- else:
- key = game.keys.pop()
- message = key_message % { 'game': game.name, 'link': confirm_comment.permalink, 'key': key }
- print '%s -> %s' % (key, winner.name)
- flush()
- while True:
- try:
- r.compose_message(winner.name, 'Congratulations!', message)
- break
- except reddit.errors.ExceptionList as e:
- print "Error sending: " + str(e)
- new_username = raw_input("Change username? ")
- if new_username:
- winner.name = new_username
- continue
- else:
- print "Message not sent."
- break
- print
- print '=================='
- print
- print 'Remaining keys:'
- for game in Games.values():
- if game.keys:
- print '%s: %s' % (game.name, ', '.join(game.keys))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement