def main(): board = np.reshape(np.array(list(map(lambda x: int(x), request.args.get('board').split(',')[:-1]))), (6, 7)) algorithm = request.args.get('algorithm') difficulty = request.args.get('difficulty') turn = 1 if len(np.where(np.reshape(board, (42,)) != 0)[0]) % 2 == 0 else -1 response = {} if len(np.where(np.reshape(board, (42,)) != 0)[0]) < 3: response['action'] = 3 return response if algorithm == 'mcts': tree = mcts(board, turn, MCTS_DIFFICULTIES[difficulty]) actions = get_action_space(board) np.random.shuffle(actions) next_idxs = [np.where(np.all(tree[:, :-2]==flatten(simulate_move(board.copy(), action, turn)),axis=1))[0][0] for action in actions] values = [tree[i, -2] for i in next_idxs] if turn == 1: best_action = actions[np.argmax(values)] else: best_action = actions[np.argmin(values)] response['action'] = int(best_action) elif algorithm == 'ab': _, action = alpha_beta(turn, board, 1, turn * np.inf, AB_DIFFICULTIES[difficulty]) response['action'] = int(action) return jsonify(response)
def on_timeline(self, tweet, prefix): """ Defines actions to take on a timeline tweet. tweet - a tweepy.Status object. You can access the text with tweet.text prefix - the @-mentions for this reply. No need to include this in the reply string; it's provided so you can use it to make sure the value you return is within the 140 character limit with this. It's up to you to ensure that the prefix and tweet are less than 140 characters. When calling post_tweet, you MUST include reply_to=tweet, or Twitter won't count it as a reply. """ photos = get_photos_from_tweet(tweet) face_regions = core.flatten( [self.face_regions(photo) for photo in photos]) recognitions = [] for region in face_regions: try: recognitions.append( self.face_recognizer.recognize_face(region)) except cv2.error as e: logging.error("Error recognizing face region: " + e.message) likely_recognitions = filter( lambda (_, margin): margin < self.get_confidence(), recognitions) recognized_labels = set([label for (label, _) in likely_recognitions]) for label in recognized_labels: recognized = self.store.get_friend(label) # it's possible someone is in the model but not in the database, # e.g. people that asked to be forgotten if recognized and recognized.get('twitter_id', None): twitter_friend = self.api.get_user(recognized['twitter_id']) self.favorite_tweet(tweet) self.post_tweet( prefix + ' ' + compliments.get_compliment() + ' ' + '@' + twitter_friend.screen_name, reply_to=tweet)
def _expand_as(func, predicate_string, *namespaces): """Pre-parse predicate string and register meta function""" args, varargs, kw, defaults = arginfo = inspect.getargspec(func) argnames = list(flatten(filter(None, [args, varargs, kw]))) parsed = parser.expr(predicate_string).totuple(1)[1] builder = CriteriaBuilder( dict([(arg,Local(arg)) for arg in argnames]), *namespaces ) bindings = {} for b in builder.bindings[-len(namespaces):][::-1]: bindings.update(b) # Make a function that just gets the arguments we want c = Code.from_function(func) c.return_(Call(Const(locals),fold=False)) getargs = new.function( c.code(), func.func_globals, func.func_name, func.func_defaults, func.func_closure ) def expand(builder, *args): builder.push(bindings) # globals, locals, etc. builder.bind(apply_meta(builder, (getargs, {}, arginfo), *args)) # build in the newly-isolated namespace result = build(builder, parsed) builder.pop() return result meta_functions[func] = expand c = Code.from_function(func) c.return_() if func.func_code.co_code == c.code().co_code: # function body is empty c = Code.from_function(func) c.return_(build(builder, parsed)) func.func_code = c.code() return func
def _expand_as(func, predicate_string, *namespaces): """Pre-parse predicate string and register meta function""" args, varargs, kw, defaults = arginfo = inspect.getargspec(func) argnames = list(flatten(filter(None, [args, varargs, kw]))) parsed = parser.expr(predicate_string).totuple(1)[1] builder = CriteriaBuilder(dict([(arg, Local(arg)) for arg in argnames]), *namespaces) bindings = {} for b in builder.bindings[-len(namespaces):][::-1]: bindings.update(b) # Make a function that just gets the arguments we want c = Code.from_function(func) c.return_(Call(Const(locals), fold=False)) getargs = new.function(c.code(), func.func_globals, func.func_name, func.func_defaults, func.func_closure) def expand(builder, *args): builder.push(bindings) # globals, locals, etc. builder.bind(apply_meta(builder, (getargs, {}, arginfo), *args)) # build in the newly-isolated namespace result = build(builder, parsed) builder.pop() return result meta_functions[func] = expand func.__doc__ # workaround for PyPy issue #1293 c = Code.from_function(func) c.return_() if func.func_code.co_code == c.code().co_code: # function body is empty c = Code.from_function(func) c.return_(build(builder, parsed)) func.func_code = c.code() return func
def process_torrent(input_directory, input_name, input_category, input_hash, input_id, client_agent): status = 1 # 1 = failed | 0 = success root = 0 found_file = 0 if client_agent != 'manual' and not core.DOWNLOADINFO: logger.debug('Adding TORRENT download info for directory {0} to database'.format(input_directory)) my_db = main_db.DBConnection() input_directory1 = input_directory input_name1 = input_name try: encoded, input_directory1 = char_replace(input_directory) encoded, input_name1 = char_replace(input_name) except Exception: pass control_value_dict = {'input_directory': text_type(input_directory1)} new_value_dict = { 'input_name': text_type(input_name1), 'input_hash': text_type(input_hash), 'input_id': text_type(input_id), 'client_agent': text_type(client_agent), 'status': 0, 'last_update': datetime.date.today().toordinal(), } my_db.upsert('downloads', new_value_dict, control_value_dict) logger.debug('Received Directory: {0} | Name: {1} | Category: {2}'.format(input_directory, input_name, input_category)) # Confirm the category by parsing directory structure input_directory, input_name, input_category, root = core.category_search(input_directory, input_name, input_category, root, core.CATEGORIES) if input_category == '': input_category = 'UNCAT' usercat = input_category try: input_name = input_name.encode(core.SYS_ENCODING) except UnicodeError: pass try: input_directory = input_directory.encode(core.SYS_ENCODING) except UnicodeError: pass logger.debug('Determined Directory: {0} | Name: {1} | Category: {2}'.format (input_directory, input_name, input_category)) # auto-detect section section = core.CFG.findsection(input_category).isenabled() if section is None: section = core.CFG.findsection('ALL').isenabled() if section is None: logger.error('Category:[{0}] is not defined or is not enabled. ' 'Please rename it or ensure it is enabled for the appropriate section ' 'in your autoProcessMedia.cfg and try again.'.format (input_category)) return [-1, ''] else: usercat = 'ALL' if len(section) > 1: logger.error('Category:[{0}] is not unique, {1} are using it. ' 'Please rename it or disable all other sections using the same category name ' 'in your autoProcessMedia.cfg and try again.'.format (usercat, section.keys())) return [-1, ''] if section: section_name = section.keys()[0] logger.info('Auto-detected SECTION:{0}'.format(section_name)) else: logger.error('Unable to locate a section with subsection:{0} ' 'enabled in your autoProcessMedia.cfg, exiting!'.format (input_category)) return [-1, ''] section = dict(section[section_name][usercat]) # Type cast to dict() to allow effective usage of .get() torrent_no_link = int(section.get('Torrent_NoLink', 0)) keep_archive = int(section.get('keep_archive', 0)) extract = int(section.get('extract', 0)) extensions = section.get('user_script_mediaExtensions', '').lower().split(',') unique_path = int(section.get('unique_path', 1)) if client_agent != 'manual': core.pause_torrent(client_agent, input_hash, input_id, input_name) # In case input is not directory, make sure to create one. # This way Processing is isolated. if not os.path.isdir(os.path.join(input_directory, input_name)): basename = os.path.basename(input_directory) basename = core.sanitize_name(input_name) \ if input_name == basename else os.path.splitext(core.sanitize_name(input_name))[0] output_destination = os.path.join(core.OUTPUTDIRECTORY, input_category, basename) elif unique_path: output_destination = os.path.normpath( core.os.path.join(core.OUTPUTDIRECTORY, input_category, core.sanitize_name(input_name).replace(' ', '.'))) else: output_destination = os.path.normpath( core.os.path.join(core.OUTPUTDIRECTORY, input_category)) try: output_destination = output_destination.encode(core.SYS_ENCODING) except UnicodeError: pass if output_destination in input_directory: output_destination = input_directory logger.info('Output directory set to: {0}'.format(output_destination)) if core.SAFE_MODE and output_destination == core.TORRENT_DEFAULTDIR: logger.error('The output directory:[{0}] is the Download Directory. ' 'Edit outputDirectory in autoProcessMedia.cfg. Exiting'.format (input_directory)) return [-1, ''] logger.debug('Scanning files in directory: {0}'.format(input_directory)) if section_name in ['HeadPhones', 'Lidarr']: core.NOFLATTEN.extend( input_category) # Make sure we preserve folder structure for HeadPhones. now = datetime.datetime.now() if extract == 1: input_files = core.list_media_files(input_directory, archives=False, other=True, otherext=extensions) else: input_files = core.list_media_files(input_directory, other=True, otherext=extensions) if len(input_files) == 0 and os.path.isfile(input_directory): input_files = [input_directory] logger.debug('Found 1 file to process: {0}'.format(input_directory)) else: logger.debug('Found {0} files in {1}'.format(len(input_files), input_directory)) for inputFile in input_files: file_path = os.path.dirname(inputFile) file_name, file_ext = os.path.splitext(os.path.basename(inputFile)) full_file_name = os.path.basename(inputFile) target_file = core.os.path.join(output_destination, full_file_name) if input_category in core.NOFLATTEN: if not os.path.basename(file_path) in output_destination: target_file = core.os.path.join( core.os.path.join(output_destination, os.path.basename(file_path)), full_file_name) logger.debug('Setting outputDestination to {0} to preserve folder structure'.format (os.path.dirname(target_file))) try: target_file = target_file.encode(core.SYS_ENCODING) except UnicodeError: pass if root == 1: if not found_file: logger.debug('Looking for {0} in: {1}'.format(input_name, inputFile)) if any([core.sanitize_name(input_name) in core.sanitize_name(inputFile), core.sanitize_name(file_name) in core.sanitize_name(input_name)]): found_file = True logger.debug('Found file {0} that matches Torrent Name {1}'.format (full_file_name, input_name)) else: continue if root == 2: mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(inputFile)) ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(inputFile)) if not found_file: logger.debug('Looking for files with modified/created dates less than 5 minutes old.') if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): found_file = True logger.debug('Found file {0} with date modified/created less than 5 minutes ago.'.format (full_file_name)) else: continue # This file has not been recently moved or created, skip it if torrent_no_link == 0: try: core.copy_link(inputFile, target_file, core.USELINK) core.remove_read_only(target_file) except Exception: logger.error('Failed to link: {0} to {1}'.format(inputFile, target_file)) input_name, output_destination = convert_to_ascii(input_name, output_destination) if extract == 1: logger.debug('Checking for archives to extract in directory: {0}'.format(input_directory)) core.extract_files(input_directory, output_destination, keep_archive) if input_category not in core.NOFLATTEN: # don't flatten hp in case multi cd albums, and we need to copy this back later. core.flatten(output_destination) # Now check if video files exist in destination: if section_name in ['SickBeard', 'NzbDrone', 'Sonarr', 'CouchPotato', 'Radarr']: num_videos = len( core.list_media_files(output_destination, media=True, audio=False, meta=False, archives=False)) if num_videos > 0: logger.info('Found {0} media files in {1}'.format(num_videos, output_destination)) status = 0 elif extract != 1: logger.info('Found no media files in {0}. Sending to {1} to process'.format(output_destination, section_name)) status = 0 else: logger.warning('Found no media files in {0}'.format(output_destination)) # Only these sections can handling failed downloads # so make sure everything else gets through without the check for failed if section_name not in ['CouchPotato', 'Radarr', 'SickBeard', 'NzbDrone', 'Sonarr']: status = 0 logger.info('Calling {0}:{1} to post-process:{2}'.format(section_name, usercat, input_name)) if core.TORRENT_CHMOD_DIRECTORY: core.rchmod(output_destination, core.TORRENT_CHMOD_DIRECTORY) result = ProcessResult( message='', status_code=0, ) if section_name == 'UserScript': result = external_script(output_destination, input_name, input_category, section) elif section_name in ['CouchPotato', 'Radarr']: result = movies.process(section_name, output_destination, input_name, status, client_agent, input_hash, input_category) elif section_name in ['SickBeard', 'NzbDrone', 'Sonarr']: if input_hash: input_hash = input_hash.upper() result = tv.process(section_name, output_destination, input_name, status, client_agent, input_hash, input_category) elif section_name in ['HeadPhones', 'Lidarr']: result = music.process(section_name, output_destination, input_name, status, client_agent, input_category) elif section_name == 'Mylar': result = comics.process(section_name, output_destination, input_name, status, client_agent, input_category) elif section_name == 'Gamez': result = games.process(section_name, output_destination, input_name, status, client_agent, input_category) plex_update(input_category) if result.status_code != 0: if not core.TORRENT_RESUME_ON_FAILURE: logger.error('A problem was reported in the autoProcess* script. ' 'Torrent won\'t resume seeding (settings)') elif client_agent != 'manual': logger.error('A problem was reported in the autoProcess* script. ' 'If torrent was paused we will resume seeding') core.resume_torrent(client_agent, input_hash, input_id, input_name) else: if client_agent != 'manual': # update download status in our DB core.update_download_info_status(input_name, 1) # remove torrent if core.USELINK == 'move-sym' and not core.DELETE_ORIGINAL == 1: logger.debug('Checking for sym-links to re-direct in: {0}'.format(input_directory)) for dirpath, dirs, files in os.walk(input_directory): for file in files: logger.debug('Checking symlink: {0}'.format(os.path.join(dirpath, file))) replace_links(os.path.join(dirpath, file)) core.remove_torrent(client_agent, input_hash, input_id, input_name) if not section_name == 'UserScript': # for user script, we assume this is cleaned by the script or option USER_SCRIPT_CLEAN # cleanup our processing folders of any misc unwanted files and empty directories core.clean_dir(output_destination, section_name, input_category) return result
def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, clientAgent): status = 1 # 1 = failed | 0 = success root = 0 foundFile = 0 uniquePath = 1 if clientAgent != 'manual' and not core.DOWNLOADINFO: logger.debug('Adding TORRENT download info for directory %s to database' % (inputDirectory)) myDB = nzbToMediaDB.DBConnection() encoded, inputDirectory1 = CharReplace(inputDirectory) encoded, inputName1 = CharReplace(inputName) controlValueDict = {"input_directory": unicode(inputDirectory1)} newValueDict = {"input_name": unicode(inputName1), "input_hash": unicode(inputHash), "input_id": unicode(inputID), "client_agent": unicode(clientAgent), "status": 0, "last_update": datetime.date.today().toordinal() } myDB.upsert("downloads", newValueDict, controlValueDict) logger.debug("Received Directory: %s | Name: %s | Category: %s" % (inputDirectory, inputName, inputCategory)) inputDirectory, inputName, inputCategory, root = core.category_search(inputDirectory, inputName, inputCategory, root, core.CATEGORIES) # Confirm the category by parsing directory structure if inputCategory == "": inputCategory = "UNCAT" usercat = inputCategory try: inputName = inputName.encode(core.SYS_ENCODING) except: pass try: inputDirectory = inputDirectory.encode(core.SYS_ENCODING) except: pass logger.debug("Determined Directory: %s | Name: %s | Category: %s" % (inputDirectory, inputName, inputCategory)) # auto-detect section section = core.CFG.findsection(inputCategory).isenabled() if section is None: section = core.CFG.findsection("ALL").isenabled() if section is None: logger.error( 'Category:[%s] is not defined or is not enabled. Please rename it or ensure it is enabled for the appropriate section in your autoProcessMedia.cfg and try again.' % ( inputCategory)) return [-1, ""] else: usercat = "ALL" if len(section) > 1: logger.error( 'Category:[%s] is not unique, %s are using it. Please rename it or disable all other sections using the same category name in your autoProcessMedia.cfg and try again.' % ( usercat, section.keys())) return [-1, ""] if section: sectionName = section.keys()[0] logger.info('Auto-detected SECTION:%s' % (sectionName)) else: logger.error("Unable to locate a section with subsection:%s enabled in your autoProcessMedia.cfg, exiting!" % ( inputCategory)) return [-1, ""] try: Torrent_NoLink = int(section[usercat]["Torrent_NoLink"]) except: Torrent_NoLink = 0 try: extract = int(section[usercat]['extract']) except: extract = 0 try: uniquePath = int(section[usercat]["unique_path"]) except: uniquePath = 1 if clientAgent != 'manual': core.pause_torrent(clientAgent, inputHash, inputID, inputName) # Incase input is not directory, make sure to create one. # This way Processing is isolated. if not os.path.isdir(os.path.join(inputDirectory, inputName)): basename = os.path.splitext(core.sanitizeName(inputName))[0] outputDestination = os.path.join(core.OUTPUTDIRECTORY, inputCategory, basename) elif uniquePath: outputDestination = os.path.normpath( core.os.path.join(core.OUTPUTDIRECTORY, inputCategory, core.sanitizeName(inputName))) else: outputDestination = os.path.normpath( core.os.path.join(core.OUTPUTDIRECTORY, inputCategory)) try: outputDestination = outputDestination.encode(core.SYS_ENCODING) except: pass logger.info("Output directory set to: %s" % (outputDestination)) if core.SAFE_MODE and outputDestination == core.TORRENT_DEFAULTDIR: logger.error( 'The output directory:[%s] is the Download Directory. Edit outputDirectory in autoProcessMedia.cfg. Exiting' % ( inputDirectory)) return [-1, ""] logger.debug("Scanning files in directory: %s" % (inputDirectory)) if sectionName == 'HeadPhones': core.NOFLATTEN.extend( inputCategory) # Make sure we preserve folder structure for HeadPhones. now = datetime.datetime.now() inputFiles = core.listMediaFiles(inputDirectory) logger.debug("Found %s files in %s" % (str(len(inputFiles)), inputDirectory)) for inputFile in inputFiles: filePath = os.path.dirname(inputFile) fileName, fileExt = os.path.splitext(os.path.basename(inputFile)) fullFileName = os.path.basename(inputFile) targetFile = core.os.path.join(outputDestination, fullFileName) if inputCategory in core.NOFLATTEN: if not os.path.basename(filePath) in outputDestination: targetFile = core.os.path.join( core.os.path.join(outputDestination, os.path.basename(filePath)), fullFileName) logger.debug( "Setting outputDestination to %s to preserve folder structure" % (os.path.dirname(targetFile))) try: targetFile = targetFile.encode(core.SYS_ENCODING) except: pass if root == 1: if not foundFile: logger.debug("Looking for %s in: %s" % (inputName, inputFile)) if (core.sanitizeName(inputName) in core.sanitizeName(inputFile)) or ( core.sanitizeName(fileName) in core.sanitizeName(inputName)): foundFile = True logger.debug("Found file %s that matches Torrent Name %s" % (fullFileName, inputName)) else: continue if root == 2: mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(inputFile)) ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(inputFile)) if not foundFile: logger.debug("Looking for files with modified/created dates less than 5 minutes old.") if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): foundFile = True logger.debug("Found file %s with date modifed/created less than 5 minutes ago." % (fullFileName)) else: continue # This file has not been recently moved or created, skip it if Torrent_NoLink == 0: try: core.copy_link(inputFile, targetFile, core.USELINK) core.rmReadOnly(targetFile) except: logger.error("Failed to link: %s to %s" % (inputFile, targetFile)) inputName, outputDestination = convert_to_ascii(inputName, outputDestination) if extract == 1: logger.debug('Checking for archives to extract in directory: %s' % (outputDestination)) core.extractFiles(outputDestination) if not inputCategory in core.NOFLATTEN: #don't flatten hp in case multi cd albums, and we need to copy this back later. core.flatten(outputDestination) # Now check if video files exist in destination: if sectionName in ["SickBeard", "NzbDrone", "CouchPotato"]: numVideos = len( core.listMediaFiles(outputDestination, media=True, audio=False, meta=False, archives=False)) if numVideos > 0: logger.info("Found %s media files in %s" % (numVideos, outputDestination)) status = 0 elif extract != 1: logger.info("Found no media files in %s. Sending to %s to process" % (outputDestination, sectionName)) status = 0 else: logger.warning("Found no media files in %s" % outputDestination) # Only these sections can handling failed downloads so make sure everything else gets through without the check for failed if not sectionName in ['CouchPotato', 'SickBeard', 'NzbDrone']: status = 0 logger.info("Calling %s:%s to post-process:%s" % (sectionName, usercat, inputName)) if core.TORRENT_CHMOD_DIRECTORY: core.rchmod(outputDestination, core.TORRENT_CHMOD_DIRECTORY) result = [ 0, "" ] if sectionName == 'UserScript': result = external_script(outputDestination, inputName, inputCategory, section[usercat]) elif sectionName == 'CouchPotato': result = core.autoProcessMovie().process(sectionName,outputDestination, inputName, status, clientAgent, inputHash, inputCategory) elif sectionName in ['SickBeard','NzbDrone']: if inputHash: inputHash = inputHash.upper() result = core.autoProcessTV().processEpisode(sectionName,outputDestination, inputName, status, clientAgent, inputHash, inputCategory) elif sectionName == 'HeadPhones': result = core.autoProcessMusic().process(sectionName,outputDestination, inputName, status, clientAgent, inputCategory) elif sectionName == 'Mylar': result = core.autoProcessComics().processEpisode(sectionName,outputDestination, inputName, status, clientAgent, inputCategory) elif sectionName == 'Gamez': result = core.autoProcessGames().process(sectionName,outputDestination, inputName, status, clientAgent, inputCategory) plex_update(inputCategory) if result[0] != 0: if not core.TORRENT_RESUME_ON_FAILURE: logger.error("A problem was reported in the autoProcess* script. torrent won't resume seeding (settings)") elif clientAgent != 'manual': logger.error( "A problem was reported in the autoProcess* script. If torrent was paused we will resume seeding") core.resume_torrent(clientAgent, inputHash, inputID, inputName) else: if clientAgent != 'manual': # update download status in our DB core.update_downloadInfoStatus(inputName, 1) # remove torrent core.remove_torrent(clientAgent, inputHash, inputID, inputName) if not sectionName == 'UserScript': # for user script, we assume this is cleaned by the script or option USER_SCRIPT_CLEAN # cleanup our processing folders of any misc unwanted files and empty directories core.cleanDir(outputDestination, sectionName, inputCategory) return result
def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, clientAgent): status = 1 # 1 = failed | 0 = success root = 0 foundFile = 0 uniquePath = 1 if clientAgent != 'manual' and not core.DOWNLOADINFO: logger.debug('Adding TORRENT download info for directory %s to database' % (inputDirectory)) myDB = nzbToMediaDB.DBConnection() encoded = False inputDirectory1 = inputDirectory inputName1 = inputName try: encoded, inputDirectory1 = CharReplace(inputDirectory) encoded, inputName1 = CharReplace(inputName) except: pass controlValueDict = {"input_directory": unicode(inputDirectory1)} newValueDict = {"input_name": unicode(inputName1), "input_hash": unicode(inputHash), "input_id": unicode(inputID), "client_agent": unicode(clientAgent), "status": 0, "last_update": datetime.date.today().toordinal() } myDB.upsert("downloads", newValueDict, controlValueDict) logger.debug("Received Directory: %s | Name: %s | Category: %s" % (inputDirectory, inputName, inputCategory)) inputDirectory, inputName, inputCategory, root = core.category_search(inputDirectory, inputName, inputCategory, root, core.CATEGORIES) # Confirm the category by parsing directory structure if inputCategory == "": inputCategory = "UNCAT" usercat = inputCategory try: inputName = inputName.encode(core.SYS_ENCODING) except: pass try: inputDirectory = inputDirectory.encode(core.SYS_ENCODING) except: pass logger.debug("Determined Directory: %s | Name: %s | Category: %s" % (inputDirectory, inputName, inputCategory)) # auto-detect section section = core.CFG.findsection(inputCategory).isenabled() if section is None: section = core.CFG.findsection("ALL").isenabled() if section is None: logger.error( 'Category:[%s] is not defined or is not enabled. Please rename it or ensure it is enabled for the appropriate section in your autoProcessMedia.cfg and try again.' % ( inputCategory)) return [-1, ""] else: usercat = "ALL" if len(section) > 1: logger.error( 'Category:[%s] is not unique, %s are using it. Please rename it or disable all other sections using the same category name in your autoProcessMedia.cfg and try again.' % ( usercat, section.keys())) return [-1, ""] if section: sectionName = section.keys()[0] logger.info('Auto-detected SECTION:%s' % (sectionName)) else: logger.error("Unable to locate a section with subsection:%s enabled in your autoProcessMedia.cfg, exiting!" % ( inputCategory)) return [-1, ""] try: Torrent_NoLink = int(section[usercat]["Torrent_NoLink"]) except: Torrent_NoLink = 0 try: keep_archive = int(section[usercat]["keep_archive"]) except: keep_archive = 0 try: extract = int(section[usercat]['extract']) except: extract = 0 try: uniquePath = int(section[usercat]["unique_path"]) except: uniquePath = 1 if clientAgent != 'manual': core.pause_torrent(clientAgent, inputHash, inputID, inputName) # Incase input is not directory, make sure to create one. # This way Processing is isolated. if not os.path.isdir(os.path.join(inputDirectory, inputName)): basename = os.path.basename(inputDirectory) basename = core.sanitizeName(inputName) \ if inputName == basename else os.path.splitext(core.sanitizeName(inputName)[0]) outputDestination = os.path.join(core.OUTPUTDIRECTORY, inputCategory, basename) elif uniquePath: outputDestination = os.path.normpath( core.os.path.join(core.OUTPUTDIRECTORY, inputCategory, core.sanitizeName(inputName))) else: outputDestination = os.path.normpath( core.os.path.join(core.OUTPUTDIRECTORY, inputCategory)) try: outputDestination = outputDestination.encode(core.SYS_ENCODING) except: pass if outputDestination in inputDirectory: outputDestination = inputDirectory logger.info("Output directory set to: %s" % (outputDestination)) if core.SAFE_MODE and outputDestination == core.TORRENT_DEFAULTDIR: logger.error( 'The output directory:[%s] is the Download Directory. Edit outputDirectory in autoProcessMedia.cfg. Exiting' % ( inputDirectory)) return [-1, ""] logger.debug("Scanning files in directory: %s" % (inputDirectory)) if sectionName == 'HeadPhones': core.NOFLATTEN.extend( inputCategory) # Make sure we preserve folder structure for HeadPhones. now = datetime.datetime.now() if extract == 1: inputFiles = core.listMediaFiles(inputDirectory, archives=False) else: inputFiles = core.listMediaFiles(inputDirectory) logger.debug("Found %s files in %s" % (str(len(inputFiles)), inputDirectory)) for inputFile in inputFiles: filePath = os.path.dirname(inputFile) fileName, fileExt = os.path.splitext(os.path.basename(inputFile)) fullFileName = os.path.basename(inputFile) targetFile = core.os.path.join(outputDestination, fullFileName) if inputCategory in core.NOFLATTEN: if not os.path.basename(filePath) in outputDestination: targetFile = core.os.path.join( core.os.path.join(outputDestination, os.path.basename(filePath)), fullFileName) logger.debug( "Setting outputDestination to %s to preserve folder structure" % (os.path.dirname(targetFile))) try: targetFile = targetFile.encode(core.SYS_ENCODING) except: pass if root == 1: if not foundFile: logger.debug("Looking for %s in: %s" % (inputName, inputFile)) if (core.sanitizeName(inputName) in core.sanitizeName(inputFile)) or ( core.sanitizeName(fileName) in core.sanitizeName(inputName)): foundFile = True logger.debug("Found file %s that matches Torrent Name %s" % (fullFileName, inputName)) else: continue if root == 2: mtime_lapse = now - datetime.datetime.fromtimestamp(os.path.getmtime(inputFile)) ctime_lapse = now - datetime.datetime.fromtimestamp(os.path.getctime(inputFile)) if not foundFile: logger.debug("Looking for files with modified/created dates less than 5 minutes old.") if (mtime_lapse < datetime.timedelta(minutes=5)) or (ctime_lapse < datetime.timedelta(minutes=5)): foundFile = True logger.debug("Found file %s with date modifed/created less than 5 minutes ago." % (fullFileName)) else: continue # This file has not been recently moved or created, skip it if Torrent_NoLink == 0: try: core.copy_link(inputFile, targetFile, core.USELINK) core.rmReadOnly(targetFile) except: logger.error("Failed to link: %s to %s" % (inputFile, targetFile)) inputName, outputDestination = convert_to_ascii(inputName, outputDestination) if extract == 1: logger.debug('Checking for archives to extract in directory: %s' % (inputDirectory)) core.extractFiles(inputDirectory, outputDestination, keep_archive) if not inputCategory in core.NOFLATTEN: #don't flatten hp in case multi cd albums, and we need to copy this back later. core.flatten(outputDestination) # Now check if video files exist in destination: if sectionName in ["SickBeard", "NzbDrone", "CouchPotato"]: numVideos = len( core.listMediaFiles(outputDestination, media=True, audio=False, meta=False, archives=False)) if numVideos > 0: logger.info("Found %s media files in %s" % (numVideos, outputDestination)) status = 0 elif extract != 1: logger.info("Found no media files in %s. Sending to %s to process" % (outputDestination, sectionName)) status = 0 else: logger.warning("Found no media files in %s" % outputDestination) # Only these sections can handling failed downloads so make sure everything else gets through without the check for failed if not sectionName in ['CouchPotato', 'SickBeard', 'NzbDrone']: status = 0 logger.info("Calling %s:%s to post-process:%s" % (sectionName, usercat, inputName)) if core.TORRENT_CHMOD_DIRECTORY: core.rchmod(outputDestination, core.TORRENT_CHMOD_DIRECTORY) result = [ 0, "" ] if sectionName == 'UserScript': result = external_script(outputDestination, inputName, inputCategory, section[usercat]) elif sectionName == 'CouchPotato': result = core.autoProcessMovie().process(sectionName,outputDestination, inputName, status, clientAgent, inputHash, inputCategory) elif sectionName in ['SickBeard','NzbDrone']: if inputHash: inputHash = inputHash.upper() result = core.autoProcessTV().processEpisode(sectionName,outputDestination, inputName, status, clientAgent, inputHash, inputCategory) elif sectionName == 'HeadPhones': result = core.autoProcessMusic().process(sectionName,outputDestination, inputName, status, clientAgent, inputCategory) elif sectionName == 'Mylar': result = core.autoProcessComics().processEpisode(sectionName,outputDestination, inputName, status, clientAgent, inputCategory) elif sectionName == 'Gamez': result = core.autoProcessGames().process(sectionName,outputDestination, inputName, status, clientAgent, inputCategory) plex_update(inputCategory) if result[0] != 0: if not core.TORRENT_RESUME_ON_FAILURE: logger.error("A problem was reported in the autoProcess* script. torrent won't resume seeding (settings)") elif clientAgent != 'manual': logger.error( "A problem was reported in the autoProcess* script. If torrent was paused we will resume seeding") core.resume_torrent(clientAgent, inputHash, inputID, inputName) else: if clientAgent != 'manual': # update download status in our DB core.update_downloadInfoStatus(inputName, 1) # remove torrent if core.USELINK == 'move-sym' and not core.DELETE_ORIGINAL == 1: logger.debug('Checking for sym-links to re-direct in: %s' % (inputDirectory)) for dirpath, dirs, files in os.walk(inputDirectory): for file in files: logger.debug('Checking symlink: %s' % (os.path.join(dirpath,file))) core.replace_links(os.path.join(dirpath,file)) core.remove_torrent(clientAgent, inputHash, inputID, inputName) if not sectionName == 'UserScript': # for user script, we assume this is cleaned by the script or option USER_SCRIPT_CLEAN # cleanup our processing folders of any misc unwanted files and empty directories core.cleanDir(outputDestination, sectionName, inputCategory) return result
def main(): global log options, args = build_parser() # update the opts dictionary with new values opts.update(eval(options.__str__())) # convert the formats in the args to valid formats for lame and oggenc opts['oggencopts'] = ' --' + ' --'.join(opts['oggencopts'].split(':')) opts['opusencopts'] = ' --' + ' --'.join(opts['opusencopts'].split(':')) # lame is not consistent, sometimes using long opts,sometimes not # so we need to specify on command line with dashes whether it is a long op or # short opts['lameopts'] = ' -' + ' -'.join(opts['lameopts'].split(':')) # ffmpeg uses colons as delimiters, just like flac2all (of course), so we had to # switch to commas for this one opts['ffmpegopts'] = opts['ffmpegopts'].split(',') opts['ffmpegopts'] = list( flatten([x.split(' ') for x in opts['ffmpegopts']])) try: opts['mode'] = args[0] except (IndexError): # if no arguments specified print("No mode specified! Run with '-h' for help") sys.exit(1) # quit the program with non-zero status try: opts['dirpath'] = os.path.abspath(args[1]) except (IndexError): print("No directory specified! Run with '-h' for help") sys.exit(2) # quit the program with non-zero status # end command line checking # Commence main logic if options.curses is True: log = cconsole() # switch to cconsole, if specified as option else: log = console(stderr=True) # Check if we have the special mode "all", which really brings flac2all into # perspective. We convert to every single format supported. This is mainly added for # testing reasons. if opts['mode'] == "all": opts['mode'] = ','.join( [x[0] for x in modetable if not x[0].startswith("_")]) # In this version, we can convert multiple format at once, so for e.g. # mode = mp3,vorbis will create both in parallel for mode in opts['mode'].split(','): if mode != "": # When copying, we don't want a _copy dir, but one representing # the mode being copied to, so we check and update mode here if "copymode" in opts: mode = opts['copymode'] # As the copy folder is created in the shell module, we # do not have to do anything else here continue try: os.mkdir(os.path.join(opts['outdir'], mode)) except OSError as e: if e.errno == 17: log.info("Folder %s already exists, reusing..." % mode) elif e.errno == 2: log.info("Parent path %s does not exist! quitting..." % (opts['outdir'])) else: # everything else, raise error raise e # Magic goes here :) if opts['master_enable']: clustered_encode() else: clustered_encode(localworkers=True) if options.curses is True: log.__del__( ) # If we are using the curses interface, clean up properly at the end.