<s> import calendar <EOL> import datetime <EOL> import itertools <EOL> import os <EOL> import re <EOL> import time <EOL> import zlib <EOL> from base . constants import CONSTANTS <EOL> from datasources import thumbnails , twitter , twitterappengine , twitterdisplay <EOL> from datasources . oauth_keys import SERVICE_PROVIDERS <EOL> TWITTER_SERVICE_PROVIDER = SERVICE_PROVIDERS [ '<STR_LIT>' ] <EOL> DIGEST_LENGTH_SEC = <NUM_LIT> * <NUM_LIT> * <NUM_LIT> <EOL> TWITTER_USERNAME_RE = re . compile ( '<STR_LIT>' ) <EOL> def _get_digest_twitter_api ( max_cache_age , key ) : <EOL> access_token = TWITTER_SERVICE_PROVIDER . access_tokens [ <EOL> zlib . adler32 ( key . encode ( '<STR_LIT:utf-8>' ) ) % <EOL> len ( TWITTER_SERVICE_PROVIDER . access_tokens ) ] <EOL> api = twitter . Api ( <EOL> consumer_key = TWITTER_SERVICE_PROVIDER . consumer . key , <EOL> consumer_secret = TWITTER_SERVICE_PROVIDER . consumer . secret , <EOL> access_token_key = access_token . key , <EOL> access_token_secret = access_token . secret , <EOL> cache = twitterappengine . MemcacheCache ( ) ) <EOL> api . SetCacheTimeout ( max_cache_age ) <EOL> api . SetUserAgent ( '<STR_LIT>' % ( <EOL> os . environ . get ( '<STR_LIT>' , '<STR_LIT:1>' ) , <EOL> CONSTANTS . APP_URL , <EOL> ) ) <EOL> return api <EOL> def _get_digest_timestamps ( ) : <EOL> now = time . gmtime ( ) <EOL> digest_end_time = calendar . timegm ( [ <EOL> now . tm_year , <EOL> now . tm_mon , <EOL> now . tm_mday , <EOL> <NUM_LIT:0> , <EOL> <NUM_LIT:0> , <EOL> <NUM_LIT:0> , <EOL> now . tm_wday , <EOL> now . tm_yday , <EOL> now . tm_isdst <EOL> ] ) <EOL> digest_start_time = digest_end_time - DIGEST_LENGTH_SEC <EOL> max_cache_age = calendar . timegm ( now ) - digest_end_time <EOL> return digest_start_time , digest_end_time , max_cache_age <EOL> def get_digest_dates ( ) : <EOL> digest_start_time , digest_end_time , max_cache_age = _get_digest_timestamps ( ) <EOL> return ( datetime . datetime . fromtimestamp ( digest_start_time ) , <EOL> datetime . datetime . fromtimestamp ( digest_end_time ) ) <EOL> def _process_digest_statuses ( <EOL> statuses , <EOL> digest_start_time , <EOL> digest_end_time , <EOL> error_info , <EOL> dev_mode , <EOL> timezone = None ) : <EOL> if not dev_mode : <EOL> digest_statuses = [ <EOL> s for s in statuses <EOL> if s . created_at_in_seconds <= digest_end_time and <EOL> s . created_at_in_seconds > digest_start_time <EOL> ] <EOL> else : <EOL> digest_statuses = statuses <EOL> digest_statuses . sort ( <EOL> lambda x , y : int ( x . created_at_in_seconds - y . created_at_in_seconds ) ) <EOL> if dev_mode : <EOL> digest_statuses . reverse ( ) <EOL> status_groups = [ ] <EOL> for username , statuses in itertools . groupby ( <EOL> digest_statuses , lambda status : status . user . id ) : <EOL> statuses = list ( statuses ) <EOL> status_groups . append ( twitterdisplay . DisplayStatusGroup ( <EOL> user = statuses [ <NUM_LIT:0> ] . user , <EOL> statuses = statuses , <EOL> thumbnail_size = thumbnails . SMALL_THUMBNAIL , <EOL> timezone = timezone ) ) <EOL> return status_groups , error_info <EOL> class TwitterFetcher ( object ) : <EOL> def fetch ( self ) : <EOL> data , had_error = twitterappengine . exec_twitter_api ( <EOL> self . _fetch , error_detail = self . _id ( ) ) <EOL> return data or [ ] , had_error <EOL> class ListTwitterFetcher ( TwitterFetcher ) : <EOL> def __init__ ( self , api , list_owner , list_id , digest_start_time ) : <EOL> self . _api = api <EOL> self . _list_owner = list_owner <EOL> self . _list_id = list_id <EOL> self . _digest_start_time = digest_start_time <EOL> def _fetch ( self ) : <EOL> statuses = [ ] <EOL> while True : <EOL> max_id = len ( statuses ) and statuses [ - <NUM_LIT:1> ] . id - <NUM_LIT:1> or None <EOL> chunk = self . _api . GetListTimeline ( <EOL> slug = self . _list_id , <EOL> owner_screen_name = self . _list_owner , <EOL> max_id = max_id , <EOL> count = <NUM_LIT> , <EOL> include_rts = True , <EOL> include_entities = True ) <EOL> statuses . extend ( chunk ) <EOL> if not chunk or chunk [ - <NUM_LIT:1> ] . created_at_in_seconds < self . _digest_start_time : <EOL> break <EOL> return statuses <EOL> def _id ( self ) : <EOL> return '<STR_LIT>' % ( self . _list_owner , self . _list_id ) <EOL> class UserTwitterFetcher ( TwitterFetcher ) : <EOL> def __init__ ( <EOL> self , <EOL> api , <EOL> username , <EOL> digest_start_time , <EOL> digest_end_time , <EOL> dev_mode ) : <EOL> self . _api = api <EOL> self . _username = username <EOL> self . _digest_start_time = digest_start_time <EOL> self . _digest_end_time = digest_end_time <EOL> self . _dev_mode = dev_mode <EOL> def _fetch ( self ) : <EOL> timeline = self . _api . GetUserTimeline ( <EOL> screen_name = self . _username , <EOL> count = <NUM_LIT> ) <EOL> if not self . _dev_mode : <EOL> timeline = [ <EOL> s for s in timeline <EOL> if s . created_at_in_seconds <= self . _digest_end_time and <EOL> s . created_at_in_seconds > self . _digest_start_time <EOL> ] <EOL> return timeline <EOL> def _id ( self ) : <EOL> return '<STR_LIT>' % self . _username <EOL> def get_digest_for_list ( list_owner , list_id , dev_mode ) : <EOL> digest_start_time , digest_end_time , max_cache_age = _get_digest_timestamps ( ) <EOL> api = _get_digest_twitter_api ( <EOL> max_cache_age , key = '<STR_LIT>' % ( list_owner , list_id ) ) <EOL> user , had_error = twitterappengine . exec_twitter_api ( <EOL> lambda : api . GetUser ( screen_name = list_owner , include_entities = False ) , <EOL> error_detail = '<STR_LIT>' % list_owner ) <EOL> if not had_error : <EOL> timezone = twitterdisplay . get_timezone_for_user ( user ) <EOL> else : <EOL> timezone = None <EOL> fetcher = ListTwitterFetcher ( api , list_owner , list_id , digest_start_time ) <EOL> statuses , had_error = fetcher . fetch ( ) <EOL> return _process_digest_statuses ( <EOL> statuses , <EOL> digest_start_time , <EOL> digest_end_time , <EOL> had_error , <EOL> dev_mode , <EOL> timezone = timezone ) <EOL> def get_digest_for_usernames ( usernames , dev_mode ) : <EOL> digest_start_time , digest_end_time , max_cache_age = _get_digest_timestamps ( ) <EOL> statuses = [ ] <EOL> error_usernames = [ ] <EOL> for username in usernames : <EOL> api = _get_digest_twitter_api ( max_cache_age , key = username ) <EOL> fetcher = UserTwitterFetcher ( <EOL> api , <EOL> username , <EOL> digest_start_time , <EOL> digest_end_time , <EOL> dev_mode ) <EOL> user_statuses , had_error = fetcher . fetch ( ) <EOL> if had_error : <EOL> error_usernames . append ( username ) <EOL> else : <EOL> statuses . extend ( user_statuses ) <EOL> return _process_digest_statuses ( <EOL> statuses , <EOL> digest_start_time , <EOL> digest_end_time , <EOL> error_usernames , <EOL> dev_mode , <EOL> timezone = None ) <EOL> class UserListsTwitterFetcher ( TwitterFetcher ) : <EOL> def __init__ ( self , api , username ) : <EOL> self . _api = api <EOL> self . _username = username <EOL> def _fetch ( self ) : <EOL> return self . _api . GetLists ( screen_name = self . _username ) <EOL> def _id ( self ) : <EOL> return '<STR_LIT>' % self . _username <EOL> def get_lists ( username ) : <EOL> api = _get_digest_twitter_api ( <NUM_LIT> , key = username ) <EOL> fetcher = UserListsTwitterFetcher ( api , username ) <EOL> lists , had_error = fetcher . fetch ( ) <EOL> return had_error and None or lists <EOL> def is_valid_twitter_username ( username ) : <EOL> return TWITTER_USERNAME_RE . match ( username ) is not None </s>
