def makeNFO(mediaelement): nfopath = os.path.splitext(mediaelement["thepath"])[0] + ".nfo" doc = Document() synodlnatrakt = doc.createElement("SynoDLNAtrakt") doc.appendChild(synodlnatrakt) #the id id = doc.createElement("id") idtext = doc.createTextNode(mediaelement["imdb_id"]) id.appendChild(idtext) #the title of the movie title = doc.createElement("title") titletext = doc.createTextNode(mediaelement["name"]) title.append(titletext) year = doc.createElement("year") yeartext = doc.createTextNode(mediaelement["year"]) year.append(yeartext) synodlnatrakt.append(id) synodlnatrakt.append(title) synodlnatrakt.append(year) try: f = open(nfopath,"w") f.write(doc.toprettyxml(indent=" ")) f.close() logger.info(u"nfo file for {0} created".format(mediaelement["name"])) except: logger.error(u"unable to create nfo for {0}".format(mediaelement["name"]))
def checkIMDB(filename): filename = filename + ".imdb" if os.path.exists(filename): f = open(filename, "r") imdb_id = f.read() f.close() logger.info(u"found a imdb file with the ID: {0}".format(imdb_id)) return imdb_id else: logger.debug(u"no imdb file found for: {0}".format(filename)) return None
def sendRequest(mediaelement): if mediaelement["process"] < config.min_progress and mediaelement["process"] > 7: response = watching(mediaelement) elif mediaelement["process"] < 7: logger.info(u"not scrobbleing because progress is lower than 7%") response = "not scrobbleing because progress is lower than 7%" else: response = scrobble(mediaelement) if not response: logger.debug(u"Scrobble failed, trying to mark as seen manually...") response = seen(mediaelement) return response
def buildMediaElement(mediaelement, theid): #check if given id is already in Database and get the lastviewed value to compare if its the same entry. if mediaelement: logger.info(u"processing file: {0}".format(mediaelement["thepath"])) logger.debug(u"mediatype: {0}, directory: {1}".format(mediaelement["type"], mediaelement["directory"])) mediaelement["id"] = theid mediaelement["duration"] = helper.getVideoDuration(theid) mediaelement["viewed"], mediaelement["lastviewed"] = getDurationFromLog(theid) mediaelement["process"] = helper.getProcess(mediaelement["duration"], mediaelement["viewed"]) #quit here if process is not enough... (saves time) # if int(mediaelement["process"]) < int(config.min_progress): # logger.error(u"File with the ID: {0}, has been viewed {1}% we need at least {2}%... skipping it".format(mediaelement["id"], mediaelement["process"], config.min_progress)) # return None # else: #currently only used for movies... idk if its possible to scrobble this for series. #mediaelement["lastviewedstamp"] = calendar.timegm(mediaelement["lastviewed"].timetuple()) mediaelement["lastviewedstamp"] = time.mktime(mediaelement["lastviewed"].timetuple()) #generate timestamp from lastviewed (datetime obj) #d = datetime.datetime.now() #calendar.timegm(d.timetuple()) #timestamp is needed for scrobbling last viewed date and to save it in database... #generate datetime from timestamp #datetime.datetime.utcfromtimestamp(1341237828) #handling for mediatype series if mediaelement["type"] == "series": try: mediaelement["tvdb_id"], mediaelement["name"] = helper.checkNFO(mediaelement["thepath"], "series") mediaelement["season"], mediaelement["episode"] = helper.checkNFO(mediaelement["thepath"], "episode") except: logger.error(u"Could not create {0} MediaElement".format(mediaelement["type"])) return None #handling for mediatype movies if mediaelement["type"] == "movie": try: mediaelement["name"], mediaelement["imdb_id"], mediaelement["year"], mediaelement["hasnfo"] = helper.checkNFO(mediaelement["thepath"], "movie") except: logger.error(u"Could not create {0} MediaElement".format(mediaelement["type"])) return None #log the created mediaobject in debug mode logger.debug(u"MediaElement successfully created: {0}".format(mediaelement)) #insert created infos in database if activated if config.use_database: helper.mediaelementToDatabase(mediaelement) return mediaelement else: logger.error(u"File with the ID: {0} seems not to be a media file that i currently support") return None
def processWatched(mediaelement): '''INFO: synoindex -N doesn't seem to work here, i wasnt able to figure out why, but it seems like -N is just a shortcut for -d and -a. So the id in the database gets updated to, and this is kinda useless... may just delete it and re add it manually?''' if config.delete_from_index: check = subprocess.call(['synoindex','-d', '{0}'.format(mediaelement["thepath"])]) if check == 0: logger.info(u"Deleted {0} from the synoindex database".format(mediaelement["thepath"])) else: logger.error(u"Cant delete from synoindex... exit code: {0}".format(check)) if mediaelement["type"] == "movie" and config.move_watched_movies and mediaelement["process"] > 80: dirname = os.path.dirname(mediaelement["thepath"]) path, filename = os.path.split(dirname) #newpath = os.path.join(config.move_movies_to_dir, foldername) #os.rename(dirname, newpath) newfullpath = os.path.join(config.move_movies_to_dir, filename) if os.path.exists(mediaelement["thepath"]) and not os.path.exists(newfullpath): shutil.move(dirname, config.move_movies_to_dir) logger.info(u"Moved {0} to {1}".format(mediaelement["thepath"], newfullpath)) if config.update_synoindex: try: subprocess.call(['synoindex','-N', '{0}', '{1}'.format(newfullpath, mediaelement["thepath"])]) except: subprocess.call(['synoindex','-d', '{0}'.format(mediaelement["thepath"])]) logger.info(u"Updated synoindex for {0} with {1}".format(mediaelement["thepath"], newfullpath)) else: logger.info(u"Directory already exists") if mediaelement["type"] == "series" and config.move_watched_series: pass
def send(action, postdata, mediaelement): url = "http://api.trakt.tv/{0}/{1}".format(action, config.trakt_key) try: logger.info(u"Sending infos for {0} \"{1}\" to trakt".format(mediaelement["type"], mediaelement["name"])) except: logger.info(u"Sending infos to trakt") logger.debug(u"Sending infos to trakt: URL: {0}, Data: {1}".format(url, postdata)) try: request = urllib2.Request(url, json.dumps(postdata)) response = urllib2.urlopen(request) response = response.read() response = json.loads(response) except urllib2.HTTPError, e: response = {'status' : 'failure', 'error' : responses[e.code][1]}
def cleanDB(): if config.use_database: logger.info(u"Cleaning database...") db.checkDB() myDB = db.DBConnection() if config.clean_uncomplete_only: reslut = myDB.select("SELECT * from scrobble where process < {0}".format(config.min_progress)) else: reslut = myDB.select("SELECT * from scrobble") if reslut: counter=0 for item in reslut: filename = os.path.split(item["thepath"])[1] thedate = datetime.datetime.fromtimestamp(float(item["lastviewed"])) timedelta = thedate + datetime.timedelta(weeks=8) if timedelta < datetime.datetime.now(): counter=counter+1 logger.debug(u"Deleting {0} from database because lastviewed more than 8 weeks ago".format(filename)) myDB.action("DELETE from scrobble where id = {0}".format(item["id"])) logger.info(u"removed {0} old entrys from databse".format(counter)) else: logger.info(u"no need to clean database for now")
def tmdbsearch(searchstring): logger.debug(u"searchstring: {0}".format(searchstring)) if searchstring[:2] == "tt": movieinfo = tmdb.getMovieInfo('{0}'.format(searchstring)) else: results = tmdb.search(searchstring) if results: firstresult = results[0] movieinfo = firstresult.info() else: #search again for movie without the year searchstring = re.sub(" \([0-9]{4}\)", "", searchstring) results = tmdb.search(searchstring) if results: firstresult = results[0] movieinfo = firstresult.info() else: logger.error(u"Can't find any matches for {0}: {1}".format(nfotype, searchstring)) imdb_id = movieinfo["imdb_id"] title = movieinfo["original_name"] logger.info(u"Found result for {0} -> Fullname: {1} imdb_id: {2}".format(searchstring, title, imdb_id)) return title, imdb_id
def checkNFO(filepath, nfotype): hasnfo = False #check the nfo for the needed id stuff... #check if there is an nfo file... if not, f**k it and try to get infos from tvdb... if nfotype == "series": directory = os.path.dirname(filepath) directory = re.sub(r'Staffel \d{2}|Season \d{2}', '', directory) nfofile = os.path.join(directory, "tvshow.nfo") try: dom = parse(nfofile) seriesidTag = dom.getElementsByTagName('id')[0].toxml() seriesid=seriesidTag.replace('<id>','').replace('</id>','') try: nameTag = dom.getElementsByTagName('showtitle')[0].toxml() name=nameTag.replace('<showtitle>','').replace('</showtitle>','') except: nameTag = dom.getElementsByTagName('title')[0].toxml() name=nameTag.replace('<title>','').replace('</title>','') logger.debug(u"SeriesID for {0} is: {1}".format(name, seriesid)) return seriesid, name except: #TODO: fix some unicode errors here... logger.error(u"cant find/open file: {0}".format(nfofile)) if config.try_guessing: logger.info(u"Trying to guess infos from Filename...") seriesname = os.path.basename(filepath) p = re.match(seriesregex, seriesname) name = p.group("name").replace(".", " ").strip() season = p.group("season") episode = p.group("episode") logger.debug(u"Type: {3}, Name: {0}, Season: {1}, Episode: {2}".format(name, season, episode, nfotype)) t = tvdb_api.Tvdb() showinfo = t[name] tvdb_id = showinfo["id"] realname = showinfo["seriesname"] year = showinfo["firstaired"] #logger.debug("tvdb gave the following keys: {0}".format(showinfo.data.keys())) logger.info(u"Found result for {0} -> Fullname: {1}, tvdb_id: {2}, Year: {3}".format(seriesname, realname, tvdb_id, year)) return tvdb_id, realname else: logger.error(u"Please enable try_guessing in settings or create an tvshow.nfo for: {0}".format(directory)) return 0 if nfotype == "episode": filename, extension = os.path.splitext(filepath) nfofile = filename + ".nfo" try: dom = parse(nfofile) episodeTag = dom.getElementsByTagName('episode')[0].toxml() episode=episodeTag.replace('<episode>','').replace('</episode>','') seasonTag = dom.getElementsByTagName('season')[0].toxml() season=seasonTag.replace('<season>','').replace('</season>','') episodeTag = dom.getElementsByTagName('episode')[0].toxml() episode=episodeTag.replace('<episode>','').replace('</episode>','') logger.info(u'TVSHOW info -> Season: {0}, Episode: {1}'.format(season, episode)) return season, episode except: logger.error(u"Cant find/open/parse file: {0}".format(nfofile)) if config.try_guessing: logger.info(u"try to guess infos from Filename...") seriesname = os.path.basename(filepath) p = re.match(seriesregex, seriesname) name = p.group("name").replace(".", " ").strip() season = p.group("season") episode = p.group("episode") logger.debug(u"Type: {3}, Series: {0}, Season: {1}, Episode: {2}".format(seriesname, season, episode, nfotype)) return season, episode else: logger.error(u"Please enable try_guessing in settings or create an .nfo for: {0}".format(directory)) return 0 if nfotype == "movie": #order of use: .nfo, .imdb, try_guessing filename, extension = os.path.splitext(filepath) nfofile = filename + ".nfo" if os.path.exists(nfofile): hasnfo = True try: dom = parse(nfofile) tvdb_idtag = dom.getElementsByTagName('id')[0].toxml() tvdb_id=tvdb_idtag.replace('<id>','').replace('</id>','') nametag = dom.getElementsByTagName('title')[0].toxml() name=nametag.replace('<title>','').replace('</title>','') if name[:4].lower() in config.the_srings: name = name[4:] + ', ' + name[:4].strip() yeartag = dom.getElementsByTagName('year')[0].toxml() year=yeartag.replace('<year>','').replace('</year>','') logger.info(u'Movie info -> Name: {0}, Year: {1}, imdb_id: {2}'.format(name, year, tvdb_id)) return name, tvdb_id, year except: logger.error(u"Cant find/open file: {0}".format(nfofile)) imdbcheck = checkIMDB(filename) if imdbcheck: searchstring = imdbcheck else: searchstring = None #only use try_guessing if there was no imdb file... if config.try_guessing and not searchstring: logger.info(u"try to guess infos from Filename...") try: moviename = os.path.basename(filepath) for junk in config.removejunk: moviename = moviename.replace(junk,'') p = re.match(movieregex, moviename) name = p.group("name").replace("."," ").replace("-"," ").strip() if name[:4].lower() in config.the_srings: name = name[4:] + ', ' + name[:4].strip() year = p.group("year") searchstring = "{0} ({1})".format(name, year) except: moviename = os.path.dirname(filepath) for junk in config.removejunk: moviename = moviename.replace(junk,'') directory, moviename = os.path.split(moviename) p = re.match(movieregex, moviename) name = p.group("name").replace("."," ").strip() year = p.group("year") searchstring = "{0} ({1})".format(name, year) logger.debug(u"Type: {3}, Name: {0}, Year: {1}, Searchstring: {2}".format(name, year, searchstring, nfotype)) #we need imdb id for scrobbleing to trakt, so lets make a moviedb lookup here to get these infos (especially if there is no year in the name....) #this ALWAYS uses the first resault that comes from tmdb... else: logger.error(u"Please enable try_guessing in settings or create an .nfo for: {0}".format(filepath)) return 0 if searchstring: title, imdb_id = tmdbsearch(searchstring) return title, imdb_id, year, hasnfo else: logger.error(u"Something went terrible wrong here...") return 0
logger.error(u"Could not create {0} MediaElement".format(mediaelement["type"])) return None #log the created mediaobject in debug mode logger.debug(u"MediaElement successfully created: {0}".format(mediaelement)) #insert created infos in database if activated if config.use_database: helper.mediaelementToDatabase(mediaelement) return mediaelement else: logger.error(u"File with the ID: {0} seems not to be a media file that i currently support") return None logger.info(u"Starting SynoDLNAtrakt...") #helper.cleanDB() #check for accesslog and exit if not found if not os.path.exists(config.accesslog): logger.info(u"{0} doesn't exist please check your settings and make sure you enabled MediaServers Debug mode".format(config.accesslog)) sys.exit(1) #this may should be moved to helper.py too if os.path.getsize(config.accesslog) > 0: logger.info(u"Parsing MediaServer log file from: {0}".format(config.accesslog)) for line in open(config.accesslog): try: data = p.parse(line)