#!!!!!!!!!!!!!!!!!!!!!!!!! #!! !! #!! PROJECT DEPRECIATED !! #!! 2019-05-10 !! #!! !! #!!!!!!!!!!!!!!!!!!!!!!!!! import pymail, os, time, datetime, re login = 'bpwestley1@gmail.com' password = '[[REDACTED EMAIL PASSWORD]]' admin = 'brendanwestley@ofr5.com' subject = 'Request' uploadfolder = '13ydOQTh-TWwzuE0cRZz188wKV_CQKWk3' home = os.path.dirname(os.path.abspath(__file__)) help_text = ''' Quick help: Send the an email to bpwestley1@gmail.com with the subject "Request" and the body in the format below. A google drive download link will be sent back to you shortly. REDDIT dankmemes entitledparents cats 30 downloads 30 posts each from r/dankmemes, r/entitledparents, and r/cats link sent in ~2 minutes VIDEO E9vF215E5lw downloads https://www.youtube.com/watch?v=E9vF215E5lw link sent in ~3+ minutes (longer videos -> longer time) General instructions: * Subject must be "Request". * Body (text) must follow format described in below sections. * If you do not receive a reply within 3 minutes it is either offline or your request is invalid; send "PING" to check if it is online. * Please send sugestions / feedback / problems to brendanwestley@ofr5.com. * Please don't spam; I can track requests. * Files stored on google drive folder may be periodicaly deleted to free space. Reddit download: This function downloads a static copy of multiple subreddits for offline veiwing, uploads it to google drive, and sends you a download link. To use this feature simply email: REDDIT ... subreddit: subreddit name without "r/"; specify as many as you want posts: number of posts to download per subreddit for example: REDDIT dankmemes entitledparents cats 30 downloads 30 posts each from r/dankmemes, r/entitledparents, and r/cats Youtube download: This function downloads videos from youtube, uploads it to google drive, amd sends you a download link. To use this feature simply email: VIDEO videoID: the video id for example: VIDEO E9vF215E5lw downloads https://www.youtube.com/watch?v=E9vF215E5lw Thank you for using! ''' def log(info, fn='LOG.txt'): log = open(fn, 'a') now = datetime.datetime.now().isoformat() print(f'[{now}]: {info}') log.write(f'[{now}]: {info}\n') log.close() def readTemp(): f = open(f'{home}/temp.txt') s = f.read() f.close() return s def execute(cmd): log('EXECUTING: ' + cmd) os.system(cmd) def ignoreFilter(imapserver, uid, msg): return uid not in ignoreUIDS def validate(req): if re.fullmatch('[A-Z ]{1,25}', req): #cmd return 1 elif re.fullmatch('VIDEO [\w -]{1,25}', req): #video return 2 elif re.fullmatch('MEME [\w -]{1,40}', req): #meme return 3 elif re.fullmatch('REDDIT ([A-Za-z0-9][A-Za-z0-9_]{2,20} )+\d{1,3}', req): #reddit return 4 else: return 0 def dateStr(date): d = str(date.day).zfill(2) m = str(date.month).zfill(2) y = str(date.year).zfill(4) return y+'-'+m+'-'+d def all_subdirs_of(b='.'): result = [] for d in os.listdir(b): bd = os.path.join(b, d) if os.path.isdir(bd): result.append(bd) return result running = True reconnecttime = 11 * 60 retryLimit = 2 retry = 0 ignoreUIDS = [] log('START') log('CONNECTING') client = pymail.User(login, password) log('SCANNING') logintime = time.time() while running: try: #query requests requests = client.read(f'SUBJECT "{subject}"', '', ignoreFilter) if requests['text'] != []: #if there are requests for i in range(0, len(requests['text'])): #for each request #get sender information current_request = requests['text'][i].strip() request_sender = requests['raw'][i]['From'] request_sender_name = request_sender.split('<')[0] request_sender_email = request_sender.split('<')[1].split('>')[0] uid = requests['uid'][i] request_type = validate(current_request) if request_type == 0:#invalid request; ignore log(f'REQUEST IGNORED: FROM: {request_sender} UID: {uid}') ignoreUIDS.append(requests['uid'][i]) #add uid to ignore list continue #log request information log(f'REQUESTED: {current_request} BY: {request_sender} UID: {uid}') #handle request if current_request == 'TERMINATE': #stop server running = False #send information email to admin client.send(login, [admin], 'BrendanYT server TERMINATED', f'Terminated by {request_sender}.') elif current_request == 'PING': #request ping #reply client.send(login, [request_sender_email], 'BrendanYT server ping', '') elif current_request == 'HELP': #help #reply client.send(login, [request_sender_email], 'Help - BrendanYT', help_text) elif current_request == 'LOG': #request log file #reply client.send(login, [request_sender_email], 'BrendanYT server log', 'Attached is the current server log as of '+datetime.datetime.now().isoformat()+'.', ['LOG.txt']) elif request_type == 3: #meme request ''' match = re.fullmatch('MEME (VIDEO|PLAYLIST) ([\w-]{1,30})', current_request) typ = 'v' if match.group(1) == 'VIDEO' else 'p' videoID = match.group(2) #download and extract memes execute(f'py {home}/memes/main.py {typ} {videoID}') #upload latest_subdir = max(all_subdirs_of(f'{home}/memes'), key=os.path.getmtime) #TODO: upload newest folder in memedownloader directory and send download link ''' elif request_type == 4: #reddit match = re.fullmatch('REDDIT (([A-Za-z0-9][A-Za-z0-9_]{2,20} )+)(\d{1,3})', current_request) subs = match.group(1).split().join(', ') count = match.group(3) fn = 'reddit-'+dateStr(dt.date.today())+'.html' #download fn = home+'/redditbot/reddit-'+dateStr(dt.date.today())+'.html' execute(f'py {home}/redditbot/main.py "{subs}" {count} "{fn}"') #TODO download reddit and upload and send link #upload log('DRIVE UPLOAD') execute(f'{home}/gdrive upload -c {home}/gauth -p {uploadfolder} "{fn}" > {home}/temp.txt') fileID = re.search('Uploaded (\S+)', readTemp()).group(1) #get file id execute(f'{home}/gdrive share -c {home}/gauth {fileID}') #share file execute(f'{home}/gdrive info -c {home}/gauth {fileID} > {home}/temp.txt') link = re.search('DownloadUrl: (.+)', readTemp()).group(1) #get link #send reply email return_message = f'\nThank you {request_sender_name}for using our service. Visit the following link to download your reddit download {link}. Please remember that all use may be subject to monitoring and logging.' log('RETURN EMAIL') client.send(login, [request_sender_email], 'Reddit Download Processed - BrendanYT', return_message) elif request_type == 2: #video download request current_request = current_request.lstrip('VIDEO ') #get video filename execute(f'{home}/yt "{current_request}" --get-filename > {home}/temp.txt') fn = readTemp().strip() if fn == '': #request failed log(f'REQUEST FAILED IGNORING: DOWNLOADER ERROR') ignoreUIDS.append(requests['uid'][i]) #add uid to ignore list continue #download video execute(f'{home}/yt {current_request}') #reply if os.stat(fn).st_size > 22000000 or True: #disable attachment #upload video log('DRIVE UPLOAD') execute(f'{home}/gdrive upload -c {home}/gauth -p {uploadfolder} "{fn}" > {home}/temp.txt') fileID = re.search('Uploaded (\S+)', readTemp()).group(1) #get file id execute(f'{home}/gdrive share -c {home}/gauth {fileID}') #share file execute(f'{home}/gdrive info -c {home}/gauth {fileID} > {home}/temp.txt') link = re.search('DownloadUrl: (.+)', readTemp()).group(1) #get link #send reply email return_message = f'\nThank you {request_sender_name}for using our service. Visit the following link to download your video {link}. Please remember that all use may be subject to monitoring and logging.' log('RETURN EMAIL') client.send(login, [request_sender_email], 'Video Processed - BrendanYT', return_message) else: #send attachment log('ATTACHMENT UPLOAD') log('RETURN EMAIL') return_message = f'\nThank you {request_sender_name}for using our service. Your video is attached. Please remember that all use may be subject to monitoring and logging.' client.send(login, [request_sender_email], 'Video Processed - BrendanYT', return_message, [fn]) log('DELETING') os.unlink(fn) #delete email client.imap.uid('STORE', requests['uid'][i], '+FLAGS', '(\Deleted)') client.imap.expunge() log('SCANNING') if time.time()-logintime > reconnecttime: log('RECONNECTING') client.close() time.sleep(5) client = pymail.User(login, password) logintime = time.time() log('SCANNING') time.sleep(5) except KeyboardInterrupt: client.send(login, [admin], 'BrendanYT server TERMINATED', 'Terminated from server.') break except Exception as e: retry += 1 client.send(login, [admin], 'BrendanYT server error', f'Retry {retry} of {retryLimit}\n\n' + str(e)) log(f'ERROR: RETRY {retry} OF {retryLimit} TEXT: {e}') if retry >= retryLimit: log('RETRY LIMIT REACHED, SHUTTING DOWN') client.send(login, [admin], 'BrendanYT server log', 'Attached is the current server log as of '+datetime.datetime.now().isoformat()+'.', ['LOG.txt']) break time.sleep(5) log('CLOSING CONNECTIONS') client.close() log('STOP')