def main(logfile, job): """main dvd processing function""" logging.info("Starting Disc identification") identify.identify(job, logfile) # Check db for entries matching the crc and successful have_dupes, crc_jobs = utils.job_dupe_check(job) if crc_jobs is not None: # This might need some tweaks to because of title/year manual job.title = crc_jobs[0][ 'title'] if crc_jobs[0]['title'] != "" else job.label job.year = crc_jobs[0]['year'] if crc_jobs[0]['year'] != "" else "" job.poster_url = crc_jobs[0][ 'poster_url'] if crc_jobs[0]['poster_url'] != "" else None crc_jobs[0]['hasnicetitle'] = bool(crc_jobs[0]['hasnicetitle']) job.hasnicetitle = crc_jobs[0]['hasnicetitle'] if crc_jobs[0][ 'hasnicetitle'] else False job.video_type = crc_jobs[0][ 'video_type'] if crc_jobs[0]['hasnicetitle'] != "" else "unknown" db.session.commit() # DVD disk entry if job.disctype in ["dvd", "bluray"]: # Send the notifications utils.notify( job, "ARM notification", f"Found disc: {job.title}. Disc type is {job.disctype}. Main Feature is {job.config.MAINFEATURE}" f". Edit entry here: http://" + str(check_ip()) + ":" f"{job.config.WEBSERVER_PORT}/jobdetail?job_id={job.job_id}") elif job.disctype == "music": utils.notify(job, "ARM notification", f"Found music CD: {job.label}. Ripping all tracks") elif job.disctype == "data": utils.notify(job, "ARM notification", "Found data disc. Copying data.") else: utils.notify(job, "ARM Notification", "Could not identify disc. Exiting.") sys.exit() # If we have have waiting for user input enabled """if job.config.MANUAL_WAIT: logging.info("Waiting " + str(job.config.MANUAL_WAIT_TIME) + " seconds for manual override.") job.status = "waiting" db.session.commit() time.sleep(job.config.MANUAL_WAIT_TIME) db.session.refresh(job) db.session.refresh(config) job.status = "active" db.session.commit() """ # TODO: Update function that will look for the best match with most data # If we have have waiting for user input enabled if job.config.MANUAL_WAIT: logging.info( f"Waiting {job.config.MANUAL_WAIT_TIME} seconds for manual override." ) job.status = "waiting" db.session.commit() sleep_time = 0 while sleep_time < job.config.MANUAL_WAIT_TIME: time.sleep(5) sleep_time += 5 db.session.refresh(job) db.session.refresh(config) if job.title_manual: break job.status = "active" db.session.commit() # If the user has set info manually update database and hasnicetitle if job.title_manual: logging.info( "Manual override found. Overriding auto identification values.") job.updated = True # We need to let arm know we have a nice title so it can use the MEDIA folder and not the ARM folder job.hasnicetitle = True else: logging.info("No manual override found.") log_arm_params(job) check_fstab() if job.config.HASHEDKEYS: logging.info("Getting MakeMKV hashed keys for UHD rips") grabkeys() # Entry point for dvd/bluray if job.disctype in ["dvd", "bluray"]: # get filesystem in order # If we have a nice title/confirmed name use the MEDIA_DIR and not the ARM unidentified folder if job.hasnicetitle: if job.year != "0000" or job.year != "": hboutpath = os.path.join( job.config.MEDIA_DIR, str(job.title) + " (" + str(job.year) + ")") else: hboutpath = os.path.join(job.config.MEDIA_DIR, str(job.title)) else: hboutpath = os.path.join(job.config.ARMPATH, str(job.title)) # The dvd directory already exists - Lets make a new one using random numbers if (utils.make_dir(hboutpath)) is False: logging.info("Directory exist.") # Only begin ripping if we are allowed to make duplicates # Or the successful rip of the disc is not found in our database if job.config.ALLOW_DUPLICATES or not have_dupes: ts = round(time.time() * 100) # if we have a nice title, set the folder to MEDIA_DIR and not the unidentified ARMPATH if job.hasnicetitle: # Dont use the year if its 0000 if job.year != "0000" or job.year != "": hboutpath = os.path.join( job.config.MEDIA_DIR, f"{job.title} ({job.year}) {ts}") else: hboutpath = os.path.join(job.config.MEDIA_DIR, f"{job.title} {ts}") else: hboutpath = os.path.join(job.config.ARMPATH, str(job.title) + "_" + str(ts)) # We failed to make a random directory, most likely a permission issue if (utils.make_dir(hboutpath)) is False: logging.exception( "A fatal error has occurred and ARM is exiting. " "Couldn't create filesystem. Possible permission error" ) utils.notify( job, "ARM notification", "ARM encountered a fatal error processing " + str(job.title) + ". Couldn't create filesystem. Possible permission error. " ) job.status = "fail" db.session.commit() sys.exit() else: # We arent allowed to rip dupes, notify and exit logging.info("Duplicate rips are disabled.") utils.notify( job, "ARM notification", "ARM Detected a duplicate disc. For " + str(job.title) + ". Duplicate rips are disabled. You can re-enable them from your config file. " ) job.status = "fail" db.session.commit() sys.exit() logging.info("Processing files to: " + hboutpath) # entry point for bluray or dvd with MAINFEATURE off and RIPMETHOD mkv hbinpath = str(job.devpath) if job.disctype == "bluray" or (not job.config.MAINFEATURE and job.config.RIPMETHOD == "mkv"): # send to makemkv for ripping # run MakeMKV and get path to output job.status = "ripping" db.session.commit() try: mkvoutpath = makemkv.makemkv(logfile, job) except: # noqa: E722 raise if mkvoutpath is None: logging.error( "MakeMKV did not complete successfully. Exiting ARM!") job.status = "fail" db.session.commit() sys.exit() if job.config.NOTIFY_RIP: # Fixed bug line below utils.notify( job, "ARM notification", str(job.title) + " rip complete. Starting transcode. ") # point HB to the path MakeMKV ripped to hbinpath = mkvoutpath # Entry point for not transcoding if job.config.SKIP_TRANSCODE and job.config.RIPMETHOD == "mkv": logging.info("SKIP_TRANSCODE is true. Moving raw mkv files.") logging.info( "NOTE: Identified main feature may not be actual main feature" ) files = os.listdir(mkvoutpath) final_directory = hboutpath if job.video_type == "movie": logging.debug("Videotype: " + job.video_type) # if videotype is movie, then move biggest title to media_dir # move the rest of the files to the extras folder # find largest filesize logging.debug("Finding largest file") largest_file_name = "" for f in files: # initialize largest_file_name if largest_file_name == "": largest_file_name = f temp_path_f = os.path.join(hbinpath, f) temp_path_largest = os.path.join( hbinpath, largest_file_name) # os.path.join(cfg['MEDIA_DIR'] + videotitle) # if cur file size > largest_file size if (os.stat(temp_path_f).st_size > os.stat(temp_path_largest).st_size): largest_file_name = f # largest_file should be largest file logging.debug("Largest file is: " + largest_file_name) temp_path = os.path.join(hbinpath, largest_file_name) if (os.stat(temp_path).st_size > 0): # sanity check for filesize for f in files: # move main into media_dir # move others into extras folder if (f == largest_file_name): # largest movie # Encorporating Rajlaud's fix #349 utils.move_files(hbinpath, f, job, True) else: # other extras if not str(job.config.EXTRAS_SUB).lower( ) == "none": # Incorporating Rajlaud's fix #349 utils.move_files(hbinpath, f, job, False) else: logging.info("Not moving extra: " + f) # Change final path (used to set permissions) final_directory = os.path.join( job.config.MEDIA_DIR, str(job.title) + " (" + str(job.year) + ")") # Clean up # TODO: fix this so it doesnt remove everything logging.debug( "Attempting to remove extra folder in ARMPATH: " + hboutpath) if hboutpath != final_directory: try: shutil.rmtree(hboutpath) logging.debug("Removed sucessfully: " + hboutpath) except Exception: logging.debug("Failed to remove: " + hboutpath) else: # if videotype is not movie, then move everything # into 'Unidentified' folder logging.debug("Videotype: " + job.video_type) for f in files: mkvoutfile = os.path.join(mkvoutpath, f) logging.debug("Moving file: " + mkvoutfile + " to: " + mkvoutpath + f) shutil.move(mkvoutfile, hboutpath) # remove raw files, if specified in config if job.config.DELRAWFILES: logging.info("Removing raw files") shutil.rmtree(mkvoutpath) # set file to default permissions '777' if job.config.SET_MEDIA_PERMISSIONS: perm_result = utils.set_permissions(job, final_directory) logging.info("Permissions set successfully: " + str(perm_result)) utils.notify(job, "ARM notification", str(job.title) + " processing complete. ") logging.info("ARM processing complete") # WARN : might cause issues # We need to update our job before we quit # It should be safe to do this as we arent waiting for transcode job.status = "success" db.session.commit() # exit job.eject() sys.exit() job.status = "transcoding" db.session.commit() if job.disctype == "bluray" and job.config.RIPMETHOD == "mkv": handbrake.handbrake_mkv(hbinpath, hboutpath, logfile, job) elif job.disctype == "dvd" and (not job.config.MAINFEATURE and job.config.RIPMETHOD == "mkv"): handbrake.handbrake_mkv(hbinpath, hboutpath, logfile, job) elif job.video_type == "movie" and job.config.MAINFEATURE and job.hasnicetitle: handbrake.handbrake_mainfeature(hbinpath, hboutpath, logfile, job) job.eject() else: handbrake.handbrake_all(hbinpath, hboutpath, logfile, job) job.eject() # check if there is a new title and change all filenames # time.sleep(60) db.session.refresh(job) logging.debug("New Title is " + str(job.title_manual)) if job.title_manual and not job.updated: newpath = utils.rename_files(hboutpath, job) p = newpath else: p = hboutpath # move to media directory if job.video_type == "movie" and job.hasnicetitle: # tracks = job.tracks.all() tracks = job.tracks.filter_by(ripped=True) for track in tracks: logging.info("Moving Movie " + str(track.filename) + " to " + str(p)) utils.move_files(p, track.filename, job, track.main_feature) # move to media directory elif job.video_type == "series" and job.hasnicetitle: # tracks = job.tracks.all() tracks = job.tracks.filter_by(ripped=True) for track in tracks: logging.info("Moving Series " + str(track.filename) + " to " + str(p)) utils.move_files(p, track.filename, job, False) else: logging.info("job type is " + str(job.video_type) + "not movie or series, not moving.") utils.scan_emby(job) # Test for dvd fail permissions final_directory = p if job.config.SET_MEDIA_PERMISSIONS: perm_result = utils.set_permissions(job, final_directory) logging.info("Permissions set successfully: " + str(perm_result)) # remove empty directories # Same issue of removing files that have already been identified # TODO: fully fix this, this is only a temp fix if hboutpath != final_directory: try: os.rmdir(hboutpath) except OSError: logging.info(hboutpath + " directory is not empty. Skipping removal. ") pass try: newpath except NameError: logging.debug("'newpath' directory not found") else: logging.info("Found path " + newpath + ". Attempting to remove it. ") try: os.rmdir(p) except OSError: logging.info(newpath + " directory is not empty. Skipping removal. ") pass # Clean up bluray backup # if job.disctype == "bluray" and cfg["DELRAWFILES"]: if job.config.DELRAWFILES: try: shutil.rmtree(mkvoutpath) except UnboundLocalError: logging.debug("No raw files found to delete. ") except OSError: logging.debug("No raw files found to delete. ") # report errors if any if job.errors: errlist = ', '.join(job.errors) if job.config.NOTIFY_TRANSCODE: utils.notify( job, "ARM notification", str(job.title) + " processing completed with errors. Title(s) " + str(errlist) + " failed to complete. ") logging.info("Transcoding completed with errors. Title(s) " + str(errlist) + " failed to complete. ") else: if job.config.NOTIFY_TRANSCODE: utils.notify(job, "ARM notification", str(job.title) + " processing complete. ") logging.info("ARM processing complete") elif job.disctype == "music": if utils.rip_music(job, logfile): utils.notify( job, "ARM notification", "Music CD: " + str(job.label) + " processing complete. ") utils.scan_emby(job) # This shouldnt be needed. but to be safe job.status = "success" db.session.commit() else: logging.info("Music rip failed. See previous errors. Exiting. ") job.eject() job.status = "fail" db.session.commit() elif job.disctype == "data": # get filesystem in order datapath = os.path.join(job.config.ARMPATH, str(job.label)) if (utils.make_dir(datapath)) is False: ts = str(round(time.time() * 100)) datapath = os.path.join(job.config.ARMPATH, str(job.label) + "_" + ts) if (utils.make_dir(datapath)) is False: logging.info("Could not create data directory: " + str(datapath) + ". Exiting ARM. ") sys.exit() if utils.rip_data(job, datapath, logfile): utils.notify( job, "ARM notification", "Data disc: " + str(job.label) + " copying complete. ") job.eject() else: logging.info("Data rip failed. See previous errors. Exiting.") job.eject() else: logging.info( "Couldn't identify the disc type. Exiting without any action.")
else: logging.info("Job #" + str(j.job_id) + " with PID " + str(j.pid) + " has been abandoned. Updating job status to fail.") j.status = "fail" db.session.commit() log_udev_params() try: main(logfile, job) except Exception as e: logging.exception( "A fatal error has occurred and ARM is exiting. See traceback below for details." ) utils.notify( job, "ARM notification", "ARM encountered a fatal error processing " + str(job.title) + ". Check the logs for more details. " + str(e)) job.status = "fail" job.eject() else: job.status = "success" finally: job.stop_time = datetime.datetime.now() joblength = job.stop_time - job.start_time minutes, seconds = divmod(joblength.seconds + joblength.days * 86400, 60) hours, minutes = divmod(minutes, 60) total_len = '{:d}:{:02d}:{:02d}'.format(hours, minutes, seconds) job.job_length = total_len db.session.commit()
def skip_transcode(job, hb_out_path, hb_in_path, mkv_out_path, type_sub_folder): """ For when skipping transcode in enabled """ logging.info("SKIP_TRANSCODE is true. Moving raw mkv files.") logging.info( "NOTE: Identified main feature may not be actual main feature") files = os.listdir(mkv_out_path) final_directory = hb_out_path if job.video_type == "movie": logging.debug(f"Videotype: {job.video_type}") # if videotype is movie, then move biggest title to media_dir # move the rest of the files to the extras folder # find largest filesize logging.debug("Finding largest file") largest_file_name = "" for f in files: # initialize largest_file_name if largest_file_name == "": largest_file_name = f temp_path_f = os.path.join(hb_in_path, f) temp_path_largest = os.path.join(hb_in_path, largest_file_name) if os.stat(temp_path_f).st_size > os.stat( temp_path_largest).st_size: largest_file_name = f # largest_file should be largest file logging.debug(f"Largest file is: {largest_file_name}") temp_path = os.path.join(hb_in_path, largest_file_name) if os.stat(temp_path).st_size > 0: # sanity check for filesize for file in files: # move main into media_dir # move others into extras folder if file == largest_file_name: # largest movie utils.move_files(hb_in_path, file, job, True) else: # other extras if not str(cfg["EXTRAS_SUB"]).lower() == "none": utils.move_files(hb_in_path, file, job, False) else: logging.info(f"Not moving extra: {file}") # Change final path (used to set permissions) final_directory = os.path.join(cfg["COMPLETED_PATH"], str(type_sub_folder), f"{job.title} ({job.year})") # Clean up logging.debug( f"Attempting to remove extra folder in TRANSCODE_PATH: {hb_out_path}" ) if hb_out_path != final_directory: try: shutil.rmtree(hb_out_path) logging.debug(f"Removed sucessfully: {hb_out_path}") except Exception: logging.debug(f"Failed to remove: {hb_out_path}") else: # if videotype is not movie, then move everything # into 'Unidentified' folder logging.debug("Videotype: " + job.video_type) for f in files: mkvoutfile = os.path.join(mkv_out_path, f) logging.debug(f"Moving file: {mkvoutfile} to: {hb_out_path} {f}") utils.move_files(mkv_out_path, f, job, False) # remove raw files, if specified in config if cfg["DELRAWFILES"]: logging.info("Removing raw files") shutil.rmtree(mkv_out_path) utils.set_permissions(job, final_directory) utils.notify(job, NOTIFY_TITLE, str(job.title) + PROCESS_COMPLETE) logging.info("ARM processing complete") # WARN : might cause issues # We need to update our job before we quit # It should be safe to do this as we aren't waiting for transcode job.status = "success" job.path = hb_out_path db.session.commit() job.eject() sys.exit()
def main(logfile, job): """main disc processing function""" logging.info("Starting Disc identification") identify.identify(job, logfile) # Check db for entries matching the crc and successful have_dupes, crc_jobs = utils.job_dupe_check(job) logging.debug(f"Value of have_dupes: {have_dupes}") utils.notify_entry(job) # If we have have waiting for user input enabled if cfg["MANUAL_WAIT"]: logging.info( f"Waiting {cfg['MANUAL_WAIT_TIME']} seconds for manual override.") job.status = "waiting" db.session.commit() sleep_time = 0 while sleep_time < cfg["MANUAL_WAIT_TIME"]: time.sleep(5) sleep_time += 5 db.session.refresh(job) db.session.refresh(config) if job.title_manual: break job.status = "active" db.session.commit() # If the user has set info manually update database and hasnicetitle if job.title_manual: logging.info( "Manual override found. Overriding auto identification values.") job.updated = True # We need to let arm know we have a nice title so it can use the MEDIA folder and not the ARM folder job.hasnicetitle = True else: logging.info("No manual override found.") log_arm_params(job) check_fstab() grabkeys(cfg["HASHEDKEYS"]) # Entry point for dvd/bluray if job.disctype in ["dvd", "bluray"]: # get filesystem in order # If we have a nice title/confirmed name use the MEDIA_DIR and not the ARM unidentified folder # if job.hasnicetitle: type_sub_folder = utils.convert_job_type(job.video_type) if job.year and job.year != "0000" and job.year != "": hb_out_path = os.path.join( cfg["TRANSCODE_PATH"], str(type_sub_folder), str(job.title) + " (" + str(job.year) + ")") else: hb_out_path = os.path.join(cfg["TRANSCODE_PATH"], str(type_sub_folder), str(job.title)) # The dvd directory already exists - Lets make a new one using random numbers if (utils.make_dir(hb_out_path)) is False: logging.info( f"Handbrake Output directory \"{hb_out_path}\" already exists." ) # Only begin ripping if we are allowed to make duplicates # Or the successful rip of the disc is not found in our database logging.debug(f"Value of ALLOW_DUPLICATES: {0}".format( cfg["ALLOW_DUPLICATES"])) logging.debug(f"Value of have_dupes: {have_dupes}") if cfg["ALLOW_DUPLICATES"] or not have_dupes: ts = round(time.time() * 100) hb_out_path = hb_out_path + "_" + str(ts) if (utils.make_dir(hb_out_path)) is False: # We failed to make a random directory, most likely a permission issue logging.exception( "A fatal error has occurred and ARM is exiting. " "Couldn't create filesystem. Possible permission error" ) utils.notify( job, NOTIFY_TITLE, "ARM encountered a fatal error processing " + str(job.title) + ". Couldn't create filesystem. Possible permission error. " ) job.status = "fail" db.session.commit() sys.exit() else: # We arent allowed to rip dupes, notify and exit logging.info("Duplicate rips are disabled.") utils.notify( job, NOTIFY_TITLE, "ARM Detected a duplicate disc. For " + str(job.title) + ". Duplicate rips are disabled. You can re-enable them from your config file. " ) job.eject() job.status = "fail" db.session.commit() sys.exit() # Use FFMPeg to convert Large Poster if enabled in config if job.disctype == "dvd" and cfg["RIP_POSTER"]: os.system("mount " + job.devpath) if os.path.isfile(job.mountpoint + "/JACKET_P/J00___5L.MP2"): logging.info("Converting NTSC Poster Image") os.system('ffmpeg -i "' + job.mountpoint + '/JACKET_P/J00___5L.MP2" "' + hb_out_path + '/poster.png"') elif os.path.isfile(job.mountpoint + "/JACKET_P/J00___6L.MP2"): logging.info("Converting PAL Poster Image") os.system('ffmpeg -i "' + job.mountpoint + '/JACKET_P/J00___6L.MP2" "' + hb_out_path + '/poster.png"') os.system("umount " + job.devpath) logging.info(f"Processing files to: {hb_out_path}") mkvoutpath = None # entry point for bluray # or # dvd with MAINFEATURE off and RIPMETHOD mkv hb_in_path = str(job.devpath) if job.disctype == "bluray" or (not cfg["MAINFEATURE"] and cfg["RIPMETHOD"] == "mkv"): # send to makemkv for ripping # run MakeMKV and get path to output job.status = "ripping" db.session.commit() try: mkvoutpath = makemkv.makemkv(logfile, job) except: # noqa: E722 raise if mkvoutpath is None: logging.error( "MakeMKV did not complete successfully. Exiting ARM!") job.status = "fail" db.session.commit() sys.exit() if cfg["NOTIFY_RIP"]: utils.notify( job, NOTIFY_TITLE, f"{job.title} rip complete. Starting transcode. ") # point HB to the path MakeMKV ripped to hb_in_path = mkvoutpath # Entry point for not transcoding if cfg["SKIP_TRANSCODE"] and cfg["RIPMETHOD"] == "mkv": skip_transcode(job, hb_out_path, hb_in_path, mkvoutpath, type_sub_folder) job.path = hb_out_path job.status = "transcoding" db.session.commit() if job.disctype == "bluray" and cfg["RIPMETHOD"] == "mkv": handbrake.handbrake_mkv(hb_in_path, hb_out_path, logfile, job) elif job.disctype == "dvd" and (not cfg["MAINFEATURE"] and cfg["RIPMETHOD"] == "mkv"): handbrake.handbrake_mkv(hb_in_path, hb_out_path, logfile, job) elif job.video_type == "movie" and cfg[ "MAINFEATURE"] and job.hasnicetitle: handbrake.handbrake_mainfeature(hb_in_path, hb_out_path, logfile, job) job.eject() else: handbrake.handbrake_all(hb_in_path, hb_out_path, logfile, job) job.eject() # check if there is a new title and change all filenames # time.sleep(60) db.session.refresh(job) logging.debug(f"New Title is {job.title}") if job.year and job.year != "0000" and job.year != "": final_directory = os.path.join(job.config.COMPLETED_PATH, str(type_sub_folder), f'{job.title} ({job.year})') else: final_directory = os.path.join(job.config.COMPLETED_PATH, str(type_sub_folder), str(job.title)) # move to media directory tracks = job.tracks.filter_by(ripped=True) if job.video_type == "movie": for track in tracks: logging.info( f"Moving Movie {track.filename} to {final_directory}") if tracks.count() == 1: utils.move_files(hb_out_path, track.filename, job, True) else: utils.move_files(hb_out_path, track.filename, job, track.main_feature) # move to media directory elif job.video_type == "series": for track in tracks: logging.info( f"Moving Series {track.filename} to {final_directory}") utils.move_files(hb_out_path, track.filename, job, False) else: for track in tracks: logging.info( f"Type is 'unknown' or we dont have a nice title - " f"Moving {track.filename} to {final_directory}") if tracks.count() == 1: utils.move_files(hb_out_path, track.filename, job, True) else: utils.move_files(hb_out_path, track.filename, job, track.main_feature) # move movie poster src_poster = os.path.join(hb_out_path, "poster.png") dst_poster = os.path.join(final_directory, "poster.png") if os.path.isfile(src_poster): if not os.path.isfile(dst_poster): try: shutil.move(src_poster, dst_poster) except Exception as e: logging.error( f"Unable to move poster.png to '{final_directory}' - Error: {e}" ) else: logging.info("File: poster.png already exists. Not moving.") utils.scan_emby(job) utils.set_permissions(job, final_directory) # Clean up bluray backup if cfg["DELRAWFILES"]: raw_list = [mkvoutpath, hb_out_path, hb_in_path] for raw_folder in raw_list: try: logging.info(f"Removing raw path - {raw_folder}") if raw_folder != final_directory: shutil.rmtree(raw_folder) except UnboundLocalError as e: logging.debug( f"No raw files found to delete in {raw_folder}- {e}") except OSError as e: logging.debug( f"No raw files found to delete in {raw_folder} - {e}") except TypeError as e: logging.debug( f"No raw files found to delete in {raw_folder} - {e}") # report errors if any if cfg["NOTIFY_TRANSCODE"]: if job.errors: errlist = ', '.join(job.errors) utils.notify( job, NOTIFY_TITLE, f" {job.title} processing completed with errors. " f"Title(s) {errlist} failed to complete. ") logging.info( f"Transcoding completed with errors. Title(s) {errlist} failed to complete. " ) else: utils.notify(job, NOTIFY_TITLE, str(job.title) + PROCESS_COMPLETE) logging.info("ARM processing complete") elif job.disctype == "music": if utils.rip_music(job, logfile): utils.notify(job, NOTIFY_TITLE, f"Music CD: {job.label} {PROCESS_COMPLETE}") utils.scan_emby(job) # This shouldnt be needed. but to be safe job.status = "success" db.session.commit() else: logging.info("Music rip failed. See previous errors. Exiting. ") job.eject() job.status = "fail" db.session.commit() elif job.disctype == "data": # get filesystem in order datapath = os.path.join(cfg["RAW_PATH"], str(job.label)) if (utils.make_dir(datapath)) is False: ts = str(round(time.time() * 100)) datapath = os.path.join(cfg["RAW_PATH"], str(job.label) + "_" + ts) if (utils.make_dir(datapath)) is False: logging.info( f"Could not create data directory: {datapath} Exiting ARM. " ) sys.exit() if utils.rip_data(job, datapath, logfile): utils.notify(job, NOTIFY_TITLE, f"Data disc: {job.label} copying complete. ") job.eject() else: logging.info("Data rip failed. See previous errors. Exiting.") job.eject() else: logging.info( "Couldn't identify the disc type. Exiting without any action.")
job.arm_version = version logging.info(("Python version: " + sys.version).replace('\n', "")) logging.info(f"User is: {getpass.getuser()}") logger.clean_up_logs(cfg["LOGPATH"], cfg["LOGLIFE"]) logging.info(f"Job: {job.label}") utils.clean_old_jobs() log_udev_params(devpath) try: main(logfile, job) except Exception as e: logging.exception( "A fatal error has occurred and ARM is exiting. See traceback below for details." ) utils.notify( job, NOTIFY_TITLE, "ARM encountered a fatal error processing " f"{job.title}. Check the logs for more details. {e}") job.status = "fail" job.eject() else: job.status = "success" finally: job.stop_time = datetime.datetime.now() joblength = job.stop_time - job.start_time minutes, seconds = divmod(joblength.seconds + joblength.days * 86400, 60) hours, minutes = divmod(minutes, 60) total_len = '{:d}:{:02d}:{:02d}'.format(hours, minutes, seconds) job.job_length = total_len db.session.commit()
def main(logfile, job): """main dvd processing function""" logging.info("Starting Disc identification") identify.identify(job, logfile) if job.disctype in ["dvd", "bluray"]: utils.notify( job, "ARM notification", "Found disc: " + str(job.title) + ". Video type is " + str(job.video_type) + ". Main Feature is " + str(job.config.MAINFEATURE) + ". Edit entry here: http://" + job.config.WEBSERVER_IP + ":" + str(job.config.WEBSERVER_PORT)) elif job.disctype == "music": utils.notify(job, "ARM notification", "Found music CD: " + job.label + ". Ripping all tracks") elif job.disctype == "data": utils.notify(job, "ARM notification", "Found data disc. Copying data.") else: utils.notify(job, "ARM Notification", "Could not identify disc. Exiting.") sys.exit() if job.config.MANUAL_WAIT: logging.info("Waiting " + str(job.config.MANUAL_WAIT_TIME) + " seconds for manual override.") job.status = "waiting" db.session.commit() time.sleep(job.config.MANUAL_WAIT_TIME) db.session.refresh(job) db.session.refresh(config) job.status = "active" db.session.commit() if job.title_manual: logging.info( "Manual override found. Overriding auto identification values.") job.updated = True job.hasnicetitle = True else: logging.info("No manual override found.") log_arm_params(job) check_fstab() if job.config.HASHEDKEYS: logging.info("Getting MakeMKV hashed keys for UHD rips") grabkeys() if job.disctype in ["dvd", "bluray"]: # get filesystem in order hboutpath = os.path.join(job.config.ARMPATH, str(job.title)) if (utils.make_dir(hboutpath)) is False: ts = round(time.time() * 100) hboutpath = os.path.join(job.config.ARMPATH, str(job.title) + "_" + str(ts)) if (utils.make_dir(hboutpath)) is False: logging.info("Failed to create base directory. Exiting ARM.") sys.exit() logging.info("Processing files to: " + hboutpath) # Do the work! hbinpath = str(job.devpath) if job.disctype == "bluray" or (not job.config.MAINFEATURE and job.config.RIPMETHOD == "mkv"): # send to makemkv for ripping # run MakeMKV and get path to ouput job.status = "ripping" db.session.commit() try: mkvoutpath = makemkv.makemkv(logfile, job) except: # noqa: E772 raise if mkvoutpath is None: logging.error( "MakeMKV did not complete successfully. Exiting ARM!") sys.exit() if job.config.NOTIFY_RIP: utils.notify( job, "ARM notification", str(job.title + " rip complete. Starting transcode.")) # point HB to the path MakeMKV ripped to hbinpath = mkvoutpath if job.config.SKIP_TRANSCODE and job.config.RIPMETHOD == "mkv": logging.info("SKIP_TRANSCODE is true. Moving raw mkv files.") logging.info( "NOTE: Identified main feature may not be actual main feature" ) files = os.listdir(mkvoutpath) final_directory = hboutpath if job.video_type == "movie": logging.debug("Videotype: " + job.video_type) # if videotype is movie, then move biggest title to media_dir # move the rest of the files to the extras folder # find largest filesize logging.debug("Finding largest file") largest_file_name = "" for f in files: # initialize largest_file_name if largest_file_name == "": largest_file_name = f temp_path_f = os.path.join(hbinpath, f) temp_path_largest = os.path.join( hbinpath, largest_file_name) # os.path.join(cfg['MEDIA_DIR'] + videotitle) # if cur file size > largest_file size if (os.stat(temp_path_f).st_size > os.stat(temp_path_largest).st_size): largest_file_name = f # largest_file should be largest file logging.debug("Largest file is: " + largest_file_name) temp_path = os.path.join(hbinpath, largest_file_name) if (os.stat(temp_path).st_size > 0): # sanity check for filesize for f in files: # move main into media_dir # move others into extras folder if (f == largest_file_name): # largest movie utils.move_files(hbinpath, f, job.hasnicetitle, job, True) else: # other extras if not str(job.config.EXTRAS_SUB).lower( ) == "none": utils.move_files(hbinpath, f, job.hasnicetitle, job, False) else: logging.info("Not moving extra: " + f) # Change final path (used to set permissions) final_directory = os.path.join( job.config.MEDIA_DIR, job.title + " (" + str(job.year) + ")") # Clean up logging.debug( "Attempting to remove extra folder in ARMPATH: " + hboutpath) try: shutil.rmtree(hboutpath) logging.debug("Removed sucessfully: " + hboutpath) except Exception: logging.debug("Failed to remove: " + hboutpath) else: # if videotype is not movie, then move everything # into 'Unidentified' folder logging.debug("Videotype: " + job.video_type) for f in files: mkvoutfile = os.path.join(mkvoutpath, f) logging.debug("Moving file: " + mkvoutfile + " to: " + mkvoutpath + f) shutil.move(mkvoutfile, hboutpath) # remove raw files, if specified in config if job.config.DELRAWFILES: logging.info("Removing raw files") shutil.rmtree(mkvoutpath) # set file to default permissions '777' if job.config.SET_MEDIA_PERMISSIONS: perm_result = utils.set_permissions(job, final_directory) logging.info("Permissions set successfully: " + str(perm_result)) utils.notify(job, "ARM notification", str(job.title) + " processing complete.") logging.info("ARM processing complete") # exit sys.exit() job.status = "transcoding" db.session.commit() if job.disctype == "bluray" and job.config.RIPMETHOD == "mkv": handbrake.handbrake_mkv(hbinpath, hboutpath, logfile, job) elif job.disctype == "dvd" and (not job.config.MAINFEATURE and job.config.RIPMETHOD == "mkv"): handbrake.handbrake_mkv(hbinpath, hboutpath, logfile, job) elif job.video_type == "movie" and job.config.MAINFEATURE and job.hasnicetitle: handbrake.handbrake_mainfeature(hbinpath, hboutpath, logfile, job) job.eject() else: handbrake.handbrake_all(hbinpath, hboutpath, logfile, job) job.eject() # get rid of this # if not titles_in_out: # pass # check if there is a new title and change all filenames # time.sleep(60) db.session.refresh(job) logging.debug("New Title is " + str(job.title_manual)) if job.title_manual and not job.updated: newpath = utils.rename_files(hboutpath, job) p = newpath else: p = hboutpath # move to media directory if job.video_type == "movie" and job.hasnicetitle: # tracks = job.tracks.all() tracks = job.tracks.filter_by(ripped=True) for track in tracks: utils.move_files(p, track.filename, job, track.main_feature) utils.scan_emby(job) # remove empty directories try: os.rmdir(hboutpath) except OSError: logging.info(hboutpath + " directory is not empty. Skipping removal.") pass try: newpath except NameError: logging.debug("'newpath' directory not found") else: logging.info("Found path " + newpath + ". Attempting to remove it.") try: os.rmdir(p) except OSError: logging.info(newpath + " directory is not empty. Skipping removal.") pass # Clean up bluray backup # if job.disctype == "bluray" and cfg["DELRAWFILES"]: if job.config.DELRAWFILES: try: shutil.rmtree(mkvoutpath) except UnboundLocalError: logging.debug("No raw files found to delete.") except OSError: logging.debug("No raw files found to delete.") # report errors if any if job.errors: errlist = ', '.join(job.errors) if job.config.NOTIFY_TRANSCODE: utils.notify( job, "ARM notification", str(job.title) + " processing completed with errors. Title(s) " + errlist + " failed to complete.") logging.info("Transcoding completed with errors. Title(s) " + errlist + " failed to complete.") else: if job.config.NOTIFY_TRANSCODE: utils.notify(job, "ARM notification", str(job.title) + " processing complete.") logging.info("ARM processing complete") elif job.disctype == "music": if utils.rip_music(job, logfile): utils.notify(job, "ARM notification", "Music CD: " + job.label + " processing complete.") utils.scan_emby(job) else: logging.info("Music rip failed. See previous errors. Exiting.") elif job.disctype == "data": # get filesystem in order datapath = os.path.join(job.config.ARMPATH, str(job.label)) if (utils.make_dir(datapath)) is False: ts = round(time.time() * 100) datapath = os.path.join(job.config.ARMPATH, str(job.label) + "_" + str(ts)) if (utils.make_dir(datapath)) is False: logging.info("Could not create data directory: " + datapath + ". Exiting ARM.") sys.exit() if utils.rip_data(job, datapath, logfile): utils.notify(job, "ARM notification", "Data disc: " + job.label + " copying complete.") job.eject() else: logging.info("Data rip failed. See previous errors. Exiting.") job.eject() else: logging.info( "Couldn't identify the disc type. Exiting without any action.")