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 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 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 action(self, query, args=None): with db_lock: if query == None: return sqlResult = None attempt = 0 while attempt < 5: try: if args == None: logger.debug("{0}: {1}".format(self.filename, query)) #print query sqlResult = self.connection.execute(query) else: logger.debug("{0}: {1} with args {2}".format(self.filename, query, args)) #print query, args sqlResult = self.connection.execute(query, args) self.connection.commit() # get out of the connection attempt loop since we were successful break except sqlite3.OperationalError, e: if "unable to open database file" in e.message or "database is locked" in e.message: logger.warning(u"DB error: ".format(ex(e))) #print "error(e)" attempt += 1 time.sleep(1) else: logger.error(u"DB error: ".format(ex(e))) #print "error(e)" raise except sqlite3.DatabaseError, e: logger.error(u"Fatal error executing query: ".format(ex(e))) #print "error(e)" raise
def _sendBoxcar(self, msg, title, email, subscribe=False): msg = msg.strip() curUrl = API_URL data = urllib.urlencode({ 'email': email, 'notification[from_screen_name]': title, 'notification[message]': msg.encode('utf-8'), 'notification[from_remote_service_id]': int(time.time()) }) if subscribe: # subscription notification data = urllib.urlencode({'email': email}) curUrl = curUrl + "/subscribe" req = urllib2.Request(curUrl) try: handle = urllib2.urlopen(req, data) handle.close() except urllib2.URLError, e: if not hasattr(e, 'code'): logger.error("Boxcar notification failed. {0}".format(ex(e))) return False else: logger.warning("Boxcar notification failed. Error code: {0}".format(str(e.code))) if e.code == 404: #HTTP status 404 if the provided email address isn't a Boxcar user. logger.warning("Username is wrong/not a boxcar email. Boxcar will send an email to it") return False elif e.code == 401: #For HTTP status code 401's, it is because you are passing in either an invalid token, or the user has not added your service. if subscribe: #If the user has already added your service, we'll return an HTTP status code of 401. logger.error("Already subscribed to service") # i dont know if this is true or false ... its neither but i also dont know how we got here in the first place return False else: #HTTP status 401 if the user doesn't have the service added subscribeNote = self._sendBoxcar(msg, title, email, True) if subscribeNote: logger.debug("Subscription send") return True else: logger.error("Subscription could not be send") return False elif e.code == 400: #If you receive an HTTP status code of 400, it is because you failed to send the proper parameters logger.error("Wrong data send to boxcar") return False
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 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
# Root path path = os.path.dirname(os.path.abspath( __file__ )) # Insert local directories into path sys.path.insert(0, os.path.join(path, 'lib')) #TODO: cleanup! #check if debugmode is acitvated try: debugfile = open('/var/packages/MediaServer/etc/dmsinfo.conf') filelines = debugfile.readlines() debugfile.close() value = filelines[-1].replace("loglevel_mediaservice=\"","").replace("\"\n","") if int(value) < 3: logger.error(u"MediaServer not running in Debugmode!") sys.exit(u"Please enable Debugmode for MediaServer first!") else: logger.debug(u"MediaServer running in Debugmode") except: logger.error(u"Can't check if your MeidaServer runs in Debugmode or not...") def getDurationFromLog(theid): dates = idtimes[theid] startdate = dates[0] try: enddate = dates[-1] except: enddate = startdate