import datetime import os from . import common from . import exceptions from . import tsdb LINE_FORMAT_TXT = ''' {timestamp}: [{title}]({link}) - /u/{author} (+{score}) '''.replace('\n', '') LINE_FORMAT_HTML = '''
{timestamp}: [{flairtext}] {title} - {author} (+{score})
'''.replace('\n', '') TIMESTAMP_FORMAT = '%Y %b %d' # The time format. # "%Y %b %d" = "2016 August 10" # See http://strftime.org/ HTML_HEADER = ''' ''' HTML_FOOTER = ''' ''' def index( subreddit=None, username=None, do_all=False, do_date=False, do_title=False, do_score=False, do_author=False, do_subreddit=False, do_flair=False, html=False, offline=False, score_threshold=0, ): if not common.is_xor(subreddit, username): raise exceptions.NotExclusive(['subreddit', 'username']) if subreddit: database = tsdb.TSDB.for_subreddit(subreddit, do_create=False) else: database = tsdb.TSDB.for_user(username, do_create=False) kwargs = {'html': html, 'offline': offline, 'score_threshold': score_threshold} wrote = None if do_all or do_date: print('Writing time file') wrote = index_worker(database, suffix='_date', orderby='created ASC', **kwargs) if do_all or do_title: print('Writing title file') wrote = index_worker(database, suffix='_title', orderby='title ASC', **kwargs) if do_all or do_score: print('Writing score file') wrote = index_worker(database, suffix='_score', orderby='score DESC', **kwargs) if not username and (do_all or do_author): print('Writing author file') wrote = index_worker(database, suffix='_author', orderby='author ASC', **kwargs) if username and (do_all or do_subreddit): print('Writing subreddit file') wrote = index_worker(database, suffix='_subreddit', orderby='subreddit ASC', **kwargs) if do_all or do_flair: print('Writing flair file') # Items with flair come before items without. Each group is sorted by time separately. orderby = 'flair_text IS NULL ASC, created ASC' wrote = index_worker(database, suffix='_flair', orderby=orderby, **kwargs) if not wrote: raise Exception('No sorts selected! Read the docstring') print('Done.') def index_worker( database, suffix, orderby, score_threshold=0, html=False, offline=False, ): cur = database.sql.cursor() statement = 'SELECT * FROM submissions WHERE score >= {threshold} ORDER BY {order}' statement = statement.format(threshold=score_threshold, order=orderby) cur.execute(statement) database.index_dir.makedirs(exist_ok=True) extension = '.html' if html else '.txt' mash_basename = database.filepath.replace_extension('').basename mash_basename += suffix + extension mash_filepath = database.index_dir.with_child(mash_basename) mash_handle = mash_filepath.open('w', encoding='UTF-8') if html: mash_handle.write(HTML_HEADER) line_format = LINE_FORMAT_HTML else: line_format = LINE_FORMAT_TXT do_timestamp = '{timestamp}' in line_format for submission in common.fetchgenerator(cur): submission = tsdb.DBEntry(submission) if do_timestamp: timestamp = int(submission.created) timestamp = datetime.datetime.utcfromtimestamp(timestamp) timestamp = timestamp.strftime(TIMESTAMP_FORMAT) else: timestamp = '' if offline: link = f'../offline_reading/{submission.idstr}.html' else: link = f'https://redd.it/{submission.idstr[3:]}' author = submission.author if author.lower() == '[deleted]': author_link = '#' else: author_link = 'https://reddit.com/u/%s' % author line = line_format.format( author=author, authorlink=author_link, flaircss=submission.flair_css_class or '', flairtext=submission.flair_text or '', id=submission.idstr, numcomments=submission.num_comments, score=submission.score, link=link, subreddit=submission.subreddit, timestamp=timestamp, title=submission.title.replace('\n', ' '), url=submission.url or link, ) line += '\n' mash_handle.write(line) if html: mash_handle.write(HTML_FOOTER) mash_handle.close() print('Wrote', mash_filepath.relative_path) return mash_filepath def index_argparse(args): return index( subreddit=args.subreddit, username=args.username, do_all=args.do_all, do_date=args.do_date, do_title=args.do_title, do_score=args.do_score, do_author=args.do_author, do_subreddit=args.do_subreddit, do_flair=args.do_flair, html=args.html, offline=args.offline, score_threshold=common.int_none(args.score_threshold), )