def tell_cb(client): if Message.count(): for player in client.online_players: for msg in Message.filter(recipient=player): client.whisper(player, msg.text) msg.remove() get_connection().commit() close_connection()
def rebuild(local=False): opened = False try: start = time.time() Price.clear_table() if local: f = open('manamarket.html') else: f = urllib.urlopen('http://manamarket.sagdas.net/manamarket.html') opened = True for L in f: L = L.strip() if L == '</table>': # We're done :) break # In the name of speed... (rather than .startswith()) elif L[:4] != '<tr>': continue # chop off the "<tr> <td>" (9 chars) at the beginning, split at the # cell borders ("</td> <td>"), and keep the first 3 rows, which # will be completely de-HTMLed :) keep = L[9:].split('</td> <td>')[:3] # Create and add the entry Price({'item': keep[0], 'quantity': int(keep[1].replace(',', '')), 'price': int(keep[2].replace(',', '')) }).add() except Exception: # Output the error sys.excepthook(*sys.exc_info()) w, success = 'failed', False get_connection().rollback() else: w, success = 'has been completed', False get_connection().commit() if opened: f.close() taken = time.time() - start print 'Rebuilding the TMW price database %s after %s seconds.' % (w, taken) close_connection() return success
def listen(client, nick, crawler): """ .listen [true|false|yes|no] -- Set/get your listening status. """ text = crawler.chain do_listen = text[0].lower() in 'yt' if text else None listener = Listener.get(listener=nick) if not listener: do_listen = False if do_listen is False else True Listener(dict(listener=nick, listening=do_listen)).add() elif do_listen is None: do_listen = listener.listening else: listener.listening = do_listen get_connection().commit() close_connection() return 'You are%s listening.' % ('' if do_listen else 'n\'t')
def tell(client, nick, crawler): """ `.tell <nick>|all <some thing>` -- send a message to a possibly offline player, or to everyone listening. """ try: rec = crawler.quoted().lower() msg = crawler.chain except ValueError: return "You must specify a recipient and a message." # Check for broadcast, which requires mod_listen. As a very optional # feature, though if rec in ["*", "all"]: lmod = client.installed_mods.get("listen") if lmod: return lmod.forward(nick, msg) else: return "This feature requires mod_listen, which is not available." # Check for sym-nick rec = t_sym_nicks.get(rec, rec) # Refresh the playerlist to avoid droppage client.installed_mods["online"].get_playerlist(client) if rec in client.online_players: client.whisper(rec, '%s says to tell you: "%s"' % (nick, msg)) return "Sent." text = time.strftime("At %H:%M:%S on %d %B %Y, ", time.gmtime()) + '%s said to tell you: "%s"' % (nick, msg) Message(dict(text=text, recipient=rec)).add() get_connection().commit() close_connection() return "Saved. If you're wondering what that means, it means the person you are trying to send a message to is offline and the message will be saved until they come online again."
def record_submission_reply(submission, comment_reply, flags=0): target_id = submission.id reply_id = comment_reply.id target_created_utc = submission.created_utc db = get_connection() sql = 'SELECT 1 FROM t3_reply WHERE target_id=?' c = db.execute(sql, (target_id, )) if c.fetchone(): # This shouldn't happen, but just in case update the fields sql = '''UPDATE t3_reply SET reply_id=?, target_created_utc=?, content_flags=?, is_set=?, is_obstructed=? WHERE target_id=? ''' with db: db.execute(sql, (reply_id, target_created_utc, flags, 1, 0, target_id)) else: sql = '''INSERT INTO t3_reply ( target_id, reply_id, target_created_utc, content_flags, is_set, is_obstructed) VALUES (?,?,?,?,?,?) ''' with db: db.execute(sql, (target_id, reply_id, target_created_utc, flags, 1, 0))
def main(): script_path = Path(__file__).resolve() os.chdir(script_path.parent) logger = logging.getLogger(__name__) #logger.disabled = True logger.setLevel(logging.INFO) #logger.addHandler(logging.StreamHandler()) log_file = script_path.parent / 'log' / script_path.with_suffix( '.log').name if log_file.parent.is_dir(): log_format = '%(asctime)s %(levelname)s %(funcName)s:%(lineno)d | %(message)s' rfh_config = { 'filename': log_file, 'encoding': 'utf-8', 'maxBytes': 5 * 1024 * 1024, # i.e., 5 megabytes 'backupCount': 8 } rfh = logging.handlers.RotatingFileHandler(**rfh_config) rfh.setFormatter(logging.Formatter(log_format)) logger.addHandler(rfh) logger.info('Log ({}): {}'.format(logger.name, log_file.absolute())) reddit = praw.Reddit(**praw_config) sleep_seconds = 30 forget_after = 60 * 60 * 24 * 10 # 10 days revisit_sql = '''SELECT * FROM t3_reply WHERE is_set = 1 AND is_obstructed = 0 AND (strftime('%s', 'now') - target_created_utc) <= {} '''.format(forget_after) db = get_connection() while 1: try: c = db.execute(revisit_sql) for row in c: target_id = row['target_id'] reply_id = row['reply_id'] content_flags = row['content_flags'] submission = reddit.submission(target_id) try: submission._fetch() except prawcore.exceptions.NotFound: # This should never happen, even if the submission was deleted. logger.warning( 'Skip: recorded submission not found: {}'.format( target_id)) with db: sql = 'UPDATE t3_reply SET is_set=0 WHERE target_id=?' db.execute(sql, (target_id, )) continue b = match_control.check_all(submission.selftext) if b == 0: # The author has fixed their post. Success! comment = reddit.comment(reply_id) try: comment.refresh() except praw.exceptions.PRAWException: # The comment has disappeared. It may have been deleted with db: sql = 'UPDATE t3_reply SET is_set=0 WHERE target_id=?' db.execute(sql, (target_id, )) continue if len(comment.replies): # Don't delete the comment if there are replies logger.info( f'Skip: found replies on comment `{reply_id}`') with db: sql = 'UPDATE t3_reply SET is_obstructed=1 WHERE target_id=?' db.execute(sql, (target_id, )) else: comment.delete() with db: sql = 'UPDATE t3_reply SET is_set=0 WHERE target_id=?' db.execute(sql, (target_id, )) logger.info(f'Success: deleted comment `{reply_id}`') else: if b != content_flags: with db: sql = 'UPDATE t3_reply SET content_flags=? WHERE target_id=?' db.execute(sql, (b, target_id)) time.sleep(sleep_seconds) except (praw.exceptions.PRAWException, prawcore.exceptions.PrawcoreException) as e: if isinstance(e, praw.exceptions.APIException): if e.error_type == 'RATELIMIT': logger.info('Exception: ratelimit exceeded: {}'.format( e.message), exc_info=True) time.sleep(11 * 60) else: logger.warning( 'Exception: unhandled PRAW APIException exception:', exc_info=True) elif isinstance(e, prawcore.exceptions.ResponseException): logger.info('Exception: ResponseException: {}'.format( e.response), exc_info=True) time.sleep(5) elif isinstance(e, prawcore.exceptions.RequestException): logger.info('Exception: RequestException: {}'.format( e.original_exception), exc_info=True) time.sleep(5) else: logger.warning('Exception: unhandled PRAW exception:', exc_info=True)