def callwebservice(job, omdb_api_key, dvd_title, year=""): """ Queries OMDbapi.org for title information and parses type, imdb, and poster info """ if job.config.VIDEOTYPE == "auto": strurl = "http://www.omdbapi.com/?t={1}&y={2}&plot=short&r=json&apikey={0}".format( omdb_api_key, dvd_title, year) logging.debug( "http://www.omdbapi.com/?t={1}&y={2}&plot=short&r=json&apikey={0}". format("key_hidden", dvd_title, year)) else: strurl = "http://www.omdbapi.com/?t={1}&y={2}&" \ "type={3}&plot=short&r=json&apikey={0}".format(omdb_api_key, dvd_title, year, job.config.VIDEOTYPE) logging.debug( "http://www.omdbapi.com/?t={1}&y={2}&type={3}&plot=short&r=json&apikey={0}" .format("key_hidden", dvd_title, year, job.config.VIDEOTYPE)) logging.debug("***Calling webservice with Title: " + str(dvd_title) + " and Year: " + str(year)) try: # strurl = "http://www.omdbapi.com/?t={1}&y={2}&plot=short& # r=json&apikey={0}".format(omdb_api_key, dvd_title, year) # # logging.debug("http://www.omdbapi.com/?t={1}&y={2}&plot=short& # r=json&apikey={0}".format("key_hidden", dvd_title, year)) dvd_title_info_json = urllib.request.urlopen(strurl).read() except Exception: logging.debug("Webservice failed") return "fail" else: doc = json.loads(dvd_title_info_json.decode()) if doc['Response'] == "False": logging.debug("Webservice failed with error: " + doc['Error']) return "fail" else: # global new_year new_year = doc['Year'] # new_year = job.year_auto = job.year = str(doc['Year']) title = clean_for_filename(doc['Title']) logging.debug("Webservice successful. New title is " + title + ". New Year is: " + new_year) args = { 'year_auto': str(new_year), 'year': str(new_year), 'title_auto': title, 'title': title, 'video_type_auto': doc['Type'], 'video_type': doc['Type'], 'imdb_id_auto': doc['imdbID'], 'imdb_id': doc['imdbID'], 'poster_url_auto': doc['Poster'], 'poster_url': doc['Poster'], 'hasnicetitle': True } utils.database_updater(args, job) # db.session.commit() return doc['Response']
def get_track_info(mdisc, job): """Use MakeMKV to get track info and update Track class\n mdisc = MakeMKV disc number\n job = Job instance\n """ logging.info("Using MakeMKV to get information on all the tracks on the disc. This will take a few minutes...") cmd = f'makemkvcon -r --cache=1 info disc:{mdisc}' logging.debug(f"Sending command: {cmd}") try: mkv = subprocess.check_output( cmd, stderr=subprocess.STDOUT, shell=True ).decode("utf-8").splitlines() except subprocess.CalledProcessError as mdisc_error: raise MakeMkvRuntimeError(mdisc_error) track = 0 fps = float(0) aspect = "" seconds = 0 filename = "" for line in mkv: if line.split(":")[0] in ("MSG", "TCOUNT", "CINFO", "TINFO", "SINFO"): line_split = line.split(":", 1) msg_type = line_split[0] msg = line_split[1].split(",") line_track = int(msg[0]) if msg_type == "TCOUNT": titles = int(line_split[1].strip()) logging.info(f"Found {titles} titles") utils.database_updater({'no_of_titles': titles}, job) if msg_type == "TINFO": if track != line_track: if line_track == int(0): pass else: utils.put_track(job, track, seconds, aspect, fps, False, "makemkv", filename) track = line_track if msg[1] == "27": filename = msg[3].replace('"', '').strip() if msg_type == "TINFO" and msg[1] == "9": len_hms = msg[3].replace('"', '').strip() h, m, s = len_hms.split(':') seconds = int(h) * 3600 + int(m) * 60 + int(s) if msg_type == "SINFO" and msg[1] == "0": if msg[2] == "20": aspect = msg[4].replace('"', '').strip() elif msg[2] == "21": fps = msg[4].split()[0] fps = fps.replace('"', '').strip() fps = float(fps) utils.put_track(job, track, seconds, aspect, fps, False, "makemkv", filename)
def get_track_info(mdisc, job): """Use MakeMKV to get track info and updatte Track class\n mdisc = MakeMKV disc number\n job = Job instance\n """ logging.info( "Using MakeMKV to get information on all the tracks on the disc. This will take a few minutes..." ) cmd = 'makemkvcon -r --cache=1 info disc:{0}'.format(mdisc) logging.debug("Sending command: %s", cmd) try: mkv = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).decode("utf-8").splitlines() except subprocess.CalledProcessError as mdisc_error: err = "Call to MakeMKV failed with code: " + str( mdisc_error.returncode) + "(" + str(mdisc_error.output) + ")" logging.error(err) return None track = 0 fps = float(0) aspect = "" seconds = 0 filename = "" for line in mkv: if line.split(":")[0] in ("MSG", "TCOUNT", "CINFO", "TINFO", "SINFO"): # print(line.rstrip()) line_split = line.split(":", 1) msg_type = line_split[0] msg = line_split[1].split(",") line_track = int(msg[0]) if msg_type == "MSG": if msg[0] == "5055": # job.errors = "MakeMKV evaluation period has expired. " \ # "DVD processing will continue. Bluray processing will exit." arm_error = "MakeMKV evaluation period has expired." \ "DVD processing will continue. Bluray processing will exit." if job.disctype == "bluray": err = "MakeMKV evaluation period has expired. Disc is a Bluray so ARM is exiting" logging.error(err) raise ValueError(err, "makemkv") else: logging.error( "MakeMKV evaluation period has expired. Disc is dvd so ARM will continue" ) utils.database_updater({'errors': arm_error}, job) # db.session.commit() if msg_type == "TCOUNT": titles = int(line_split[1].strip()) logging.info("Found " + str(titles) + " titles") # job.no_of_titles = titles # db.session.commit() utils.database_updater({'no_of_titles': titles}, job) if msg_type == "TINFO": if track != line_track: if line_track == int(0): pass else: utils.put_track(job, track, seconds, aspect, fps, False, "makemkv", filename) track = line_track if msg[1] == "27": filename = msg[3].replace('"', '').strip() if msg_type == "TINFO" and msg[1] == "9": len_hms = msg[3].replace('"', '').strip() h, m, s = len_hms.split(':') seconds = int(h) * 3600 + int(m) * 60 + int(s) if msg_type == "SINFO" and msg[1] == "0": if msg[2] == "20": aspect = msg[4].replace('"', '').strip() elif msg[2] == "21": fps = msg[4].split()[0] fps = fps.replace('"', '').strip() fps = float(fps) utils.put_track(job, track, seconds, aspect, fps, False, "makemkv", filename)
def handbrake_mainfeature(srcpath, basepath, logfile, job): """process dvd with mainfeature enabled.\n srcpath = Path to source for HB (dvd or files)\n basepath = Path where HB will save trancoded files\n logfile = Logfile for HB to redirect output to\n job = Job object\n Returns nothing """ logging.info("Starting DVD Movie Mainfeature processing") logging.debug("Handbrake starting: ") logging.debug("\n\r" + job.pretty_table()) utils.database_updater({'status': "waiting_transcode"}, job) # TODO: send a notification that jobs are waiting ? utils.sleep_check_process("HandBrakeCLI", int(cfg["MAX_CONCURRENT_TRANSCODES"])) logging.debug("Setting job status to 'transcoding'") utils.database_updater({'status': "transcoding"}, job) filename = os.path.join(basepath, job.title + "." + cfg["DEST_EXT"]) filepathname = os.path.join(basepath, filename) logging.info(f"Ripping title Mainfeature to {shlex.quote(filepathname)}") get_track_info(srcpath, job) track = job.tracks.filter_by(main_feature=True).first() if track is None: msg = "No main feature found by Handbrake. Turn MAINFEATURE to false in arm.yml and try again." logging.error(msg) raise RuntimeError(msg) track.filename = track.orig_filename = filename db.session.commit() if job.disctype == "dvd": hb_args = cfg["HB_ARGS_DVD"] hb_preset = cfg["HB_PRESET_DVD"] elif job.disctype == "bluray": hb_args = cfg["HB_ARGS_BD"] hb_preset = cfg["HB_PRESET_BD"] cmd = 'nice {0} -i {1} -o {2} --main-feature --preset "{3}" {4} >> {5} 2>&1'.format( cfg["HANDBRAKE_CLI"], shlex.quote(srcpath), shlex.quote(filepathname), hb_preset, hb_args, logfile ) logging.debug(f"Sending command: {cmd}") try: subprocess.check_output(cmd, shell=True).decode("utf-8") logging.info("Handbrake call successful") track.status = "success" except subprocess.CalledProcessError as hb_error: err = f"Call to handbrake failed with code: {hb_error.returncode}({hb_error.output})" logging.error(err) track.status = "fail" track.error = err job.status = "fail" db.session.commit() sys.exit(err) logging.info(PROCESS_COMPLETE) logging.debug("\n\r" + job.pretty_table()) track.ripped = True db.session.commit()
def call_tmdb_service(job, tmdb_api_key, dvd_title, year=""): """ Queries api.themoviedb.org for movies close to the query """ # Movies and TV shows # https://api.themoviedb.org/3/search/multi?api_key=<<api_key>>&query=aa # Movie with tons of extra details # https://api.themoviedb.org/3/movie/78?api_key= # &append_to_response=alternative_titles,changes,credits,images,keywords,lists,releases,reviews,similar,videos if year: url = f"https://api.themoviedb.org/3/search/movie?api_key={tmdb_api_key}&query={dvd_title}&year={year}" clean_url = f"https://api.themoviedb.org/3/search/movie?api_key=hidden&query={dvd_title}&year={year}" else: url = f"https://api.themoviedb.org/3/search/movie?api_key={tmdb_api_key}&query={dvd_title}" clean_url = f"https://api.themoviedb.org/3/search/movie?api_key=hidden&query={dvd_title}" poster_size = "original" poster_base = f"http://image.tmdb.org/t/p/{poster_size}" # Making a get request logging.debug(f"url = {clean_url}") response = requests.get(url) p = json.loads(response.text) x = {} # Check for movies if p['total_results'] > 0: logging.debug(p['total_results']) for s in p['results']: s['poster_path'] = s['poster_path'] if s[ 'poster_path'] is not None else None s['release_date'] = '0000-00-00' if 'release_date' not in s else s[ 'release_date'] s['imdbID'] = tmdb_get_imdb(s['id'], tmdb_api_key) s['Year'] = re.sub("-[0-9]{0,2}-[0-9]{0,2}", "", s['release_date']) s['Title'] = s['title'] s['Type'] = "movie" logging.debug( f"{s['title']} ({s['Year']})- {poster_base}{s['poster_path']}") s['Poster'] = f"{poster_base}{s['poster_path']}" # print(poster_url) s['background_url'] = f"{poster_base}{s['backdrop_path']}" logging.debug(s['background_url']) dvd_title_pretty = re.sub(r"\+", " ", dvd_title) logging.debug( f"trying {dvd_title.capitalize()} == {s['title'].capitalize()}" ) if dvd_title_pretty.capitalize() == s['title'].capitalize(): s['Search'] = s logging.debug("x=" + str(x)) s['Response'] = True # global new_year new_year = s['Year'] # new_year = job.year_auto = job.year = str(x['Year']) title = clean_for_filename(s['Title']) logging.debug("Webservice successful. New title is " + title + ". New Year is: " + new_year) args = { 'year_auto': str(new_year), 'year': str(new_year), 'title_auto': title, 'title': title, 'video_type_auto': s['Type'], 'video_type': s['Type'], 'imdb_id_auto': s['imdbID'], 'imdb_id': s['imdbID'], 'poster_url_auto': s['Poster'], 'poster_url': s['Poster'], 'hasnicetitle': True } utils.database_updater(args, job) return s x['Search'] = p['results'] return x else: # Movies have failed check for tv series url = f"https://api.themoviedb.org/3/search/tv?api_key={tmdb_api_key}&query={dvd_title}" response = requests.get(url) p = json.loads(response.text) # v = json.dumps(response.json(), indent=4, sort_keys=True) # logging.debug(v) x = {} if p['total_results'] > 0: logging.debug(p['total_results']) for s in p['results']: logging.debug(s) s['poster_path'] = s['poster_path'] if s[ 'poster_path'] is not None else None s['release_date'] = '0000-00-00' if 'release_date' not in s else s[ 'release_date'] s['imdbID'] = tmdb_get_imdb(s['id'], tmdb_api_key) reg = "-[0-9]{0,2}-[0-9]{0,2}" s['Year'] = re.sub(reg, "", s['first_air_date']) if 'first_air_date' in s else \ re.sub(reg, "", s['release_date']) s['Title'] = s['title'] if 'title' in s else s[ 'name'] # This isnt great s['Type'] = "series" logging.debug( f"{s['Title']} ({s['Year']})- {poster_base}{s['poster_path']}" ) s['Poster'] = f"{poster_base}{s['poster_path']}" # print(poster_url) s['background_url'] = f"{poster_base}{s['backdrop_path']}" logging.debug(s['background_url']) dvd_title_pretty = re.sub(r"\+", " ", dvd_title) logging.debug( f"trying {dvd_title.capitalize()} == {s['Title'].capitalize()}" ) if dvd_title_pretty.capitalize() == s['Title'].capitalize(): s['Search'] = s logging.debug("x=" + str(x)) s['Response'] = True # global new_year new_year = s['Year'] # new_year = job.year_auto = job.year = str(x['Year']) title = clean_for_filename(s['Title']) logging.debug("Webservice successful. New title is " + title + ". New Year is: " + new_year) args = { 'year_auto': str(new_year), 'year': str(new_year), 'title_auto': title, 'title': title, 'video_type_auto': s['Type'], 'video_type': s['Type'], 'imdb_id_auto': s['imdbID'], 'imdb_id': s['imdbID'], 'poster_url_auto': s['Poster'], 'poster_url': s['Poster'], 'hasnicetitle': True } utils.database_updater(args, job) return s x['Search'] = p['results'] return x logging.debug("no results found") return "fail"