Example #1
0
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")
Example #2
0
def getProcess(length, viewed):
	length = durationStamps(length)
	viewed = durationStamps(viewed)
	try:
		percent = int(viewed) / (int(length) / 100)
	except:
		percent = 0
	logger.debug(u"Duration: {0}s, Viewed: {1}s = {2}% watched".format(length, viewed, percent))
	if percent > 100:
		percent=100
	return percent
Example #3
0
def durationStamps(time):
	try:
		h, m, s = time.split(":")
		timestamp = int(h*60)
		timestamp = (timestamp + int(m))*60
		timestamp = (timestamp + int(s))
		logger.debug(u"timestamp for: {0} is {1}".format(time, timestamp))
	except:
		timestamp = time
		logger.debug(u"{0} seems to be a timestamp already".format(time))
	return timestamp
Example #4
0
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
Example #5
0
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
Example #6
0
    def _notifyBoxcar(self, title, message=None, username=None, force=False):
        if not config.use_boxcar and not force:
            logger.debug("Notification for Boxcar not enabled, skipping this notification")
            return False

        if not username:
            username = config.boxcar_username

        logger.debug("Sending notification for {0}".format(message))

        self._sendBoxcar(message, title, username)
        return True
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
Example #8
0
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]}
Example #9
0
    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
Example #10
0
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
Example #11
0
def getDurationFromLog(id):
	dates = idtimes[id]
	startdate = dates[1]
	enddade = dates[-1]

	duration = enddade - startdate
	
	logger.debug(u"Fileid: " + str(id))
	logger.debug(u"Duration: " + str(duration))
	h, m, s = str(duration).split(":")
	time = int(h)*60
	time = (time + int(m))*60
	time = (time + int(s))
	logger.debug(u"Duration Timestamp: {0}".format(time))
	logger.debug(u"Last viewed: {0}, for: {1}".format(enddade, duration))
	return time, enddade
Example #12
0
	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 getDurationFromLog(theid):
	dates = idtimes[theid]
	
	startdate = dates[0]
	try:
		enddate = dates[-1]
	except:
		enddate = startdate

	duration = enddate - startdate
	
	logger.debug(u"Fileid: " + str(theid))
	logger.debug(u"Viewed: " + str(duration))
	h, m, s = str(duration).split(":")
	time = int(h)*60
	time = (time + int(m))*60
	time = (time + int(s))
	logger.debug(u"Viewed Timestamp: {0}".format(time))
	logger.debug(u"Last viewed: {0}, for: {1}".format(enddate, duration))
	return time, enddate
Example #14
0
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
# 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

	duration = enddate - startdate
	
	logger.debug(u"Fileid: " + str(theid))
Example #16
0
                    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
        else:# 200
            logger.debug("Boxcar notification successful.")
            return True


    def _notifyBoxcar(self, title, message=None, username=None, force=False):
        if not config.use_boxcar and not force:
            logger.debug("Notification for Boxcar not enabled, skipping this notification")
            return False

        if not username:
            username = config.boxcar_username

        logger.debug("Sending notification for {0}".format(message))

        self._sendBoxcar(message, title, username)
        return True
Example #17
0
		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]}
		#return None
	except urllib2.URLError, e:
		response = {'status' : 'failure', 'error' : e.reason[0]}
		#return None
	logger.debug("response: {0}".format(response))
	if response['status'] == 'success':
		#create an nfo file for later use...
		# if not mediaelement["hasnfo"]:
		# 	helper.makeNFO(mediaelement)
			
		#marking the id as scrobbled inside the database...
		if not action.split("/")[-1] == "watching":
			if config.use_database:
				helper.markScrobbled(mediaelement["id"])
		return True
	else:
		return None
Example #18
0
def getSeries(filepath, curdir):
	myfilestring = filepath.replace(curdir,'')
	series, season, filename = myfilestring.split('/')
	logger.debug(u"Splitting {0} -> Series: {1}, Season: {2}, Filename: {3}".format(filepath, series, season, filename))