#!/usr/local/bin/python
from MythTV import MythDB, MythLog, MythTV, MythVideo, Program, Job
from socket import gethostname
import sys, getopt, re, os, time, logging

#Usage: mythvidexport.py <--chanid <channel id>> <--starttime <start time>> [options]
#		--format <see directory/file name options>
#	moves a single file over to MythVideo with optional directory format, format is discarded after use

#Usage: mythvidexport.py <job id>
#		WARNING: for internal use by job queue only!
#	moves a single file, grabbing necessary information from job queue table

#Usage: mythvidexport.py <options>
#		--setformat <see directory/file name options>
#			stored directory format in database for future use
#		--help
#		--helpformat
#			lengthy discription of directory formatting


class VIDEO:
	mythdb = None
	dbconn = None
	job = None
	jobhost = None
	chanid = None
	rtime = None
	source = None
	srchost = None
	srcdb = None
	dest = None
	desthost = None
	destdb = None
	prog = None
	season= None
	episode = None
	fmt = None
	log = None
	

	def __init__(self, *inp):
		if len(inp) == 1:
			self.job = Job(inp[0]);
			self.chanid = self.job.chanid
			self.rtime = "%04d%02d%02d%02d%02d%02d" % self.job.starttime.timetuple()[0:6]
			self.jobhost = self.job.host
			self.job.setStatus(3)
		elif len(inp) == 2:
			self.chanid = inp[0]
			self.rtime = inp[1]
		else:
			sys.exit(2)
		self.get_source()
		self.log = MythLog(logging.CRITICAL, '#%(levelname)s - %(message)s', 'MythTV')

	def dbconnect(self):
		self.mythdb = MythDB()
		self.dbconn = self.mythdb.db

	def get_source(self):
		if not self.dbconn:
			self.dbconnect()
		if not self.jobhost:
			self.jobhost = gethostname()

		mythinst = MythTV()
		self.prog = mythinst.getRecording(self.chanid,int(self.rtime))

		self.srcdb = self.prog.filename
		self.srchost = self.prog.hostname

		self.source = mythinst.getCheckfile(self.prog)

	def get_dest(self):
		#process self.fmt and generate self.dest
		#not programmed yet... just use my own naming scheme
		path = self.mythdb.getSetting("VideoStartupDir",hostname=self.jobhost)
		self.desthost = self.jobhost
		self.get_ttvdb()

		ext = self.source[self.source.rfind('.'):]
		subpath = "TV/%s/Season %d/%dx%02d - %s%s" % (self.prog.title,self.season,self.season,self.episode,self.prog.subtitle,ext)
		self.dest = path+'/'+subpath

		tmppath = self.dest[0:self.dest.rfind('/')] 
		if not os.access(tmppath,os.F_OK):
			os.makedirs(tmppath)

		cursor = self.dbconn.cursor()
		reslen = cursor.execute("SELECT dirname FROM storagegroup WHERE hostname='%s' and groupname='Videos'" % self.desthost)
		if reslen:
			self.destdb = subpath
		else:
			self.destdb = self.dest

	def get_ttvdb(self):
		regex = re.compile('S(?P<season>[0-9]*)E(?P<episode>[0-9]*)')
		if os.access('/usr/local/share/mythtv/mythvideo/scripts/ttvdb.py',os.F_OK):
			path = '/usr/local/share/mythtv/mythvideo/scripts/ttvdb.py'
		elif os.access('/usr/share/mythtv/mythvideo/scripts/ttvdb.py',os.F_OK):
			path = '/usr/local/share/mythtv/mythvideo/scripts/ttvdb.py'
		
		fp = os.popen("%s -N \"%s\" \"%s\"" % (path,self.prog.title,self.prog.subtitle),"r")
		match = regex.search(fp.read())
		fp.close()
		if match is None:
			if self.job:
				self.job.setComment("TTVDB.py failed to get season/episode numbers")
				self.job.setStatus(304)
				self.log.Msg(logging.CRITICAL, "TTVDB.py failed to get season/episode numbers")
			else:
				print("TTVDB.py failed to get season/episode numbers")
			sys.exit(2)
		self.season = int(match.group('season'))
		self.episode = int(match.group('episode'))

	def set_fmt(self, fmt):
		self.fmt = fmt

	def get_fmt(self):
		self.fmt = self.mythdb.getSetting('mythvideo.exportfmt')

	def copy(self):
		cursor = None
		fp = None
		srcsize = None
		dtime = None
		if self.fmt is None:
			self.get_fmt()
		self.get_dest()
		if self.desthost != self.jobhost:
			if self.job:
				self.job.setComment("Job must be run on destination host")
				self.log.Msg(logging.CRITICAL, 'MythVidExport failed - must be run on destination host')
				self.job.setStatus(304)
			else:
				print("ERROR: job must be run on destionation host")
			sys.exit(2)

		stime = time.time()
		fp = os.popen("cp \"%s\" \"%s\"" % (self.source,self.dest))
#		if self.srchost == self.jobhost:
#			fp = os.popen("cp '%s' '%s'" % (self.source,self.dest))
#		else:
#			fp = os.popen("scp '%s:%s' '%s'" % (self.srchost, self.source, self.dest))
		srcsize = self.prog.filesize
		destsize = [0,0,0,0,0,0,0,0,0,0]
		if self.job:
			self.job.setStatus(4)
		while srcsize > destsize[9]:
			time.sleep(4)
			destsize.append(os.stat(self.dest)[6])
			rem = srcsize-destsize[10]
			if destsize[0]:
				dtime = 40
			else:
				dtime = int(time.time()-stime)
			rate = (destsize[10]-destsize.pop(0))/dtime
			remt = rem/rate
			if self.job:
				self.job.setComment("%02d%% complete - %s seconds remaining" % (destsize[9]*100/srcsize, remt))
		fp.close()
		if self.job:
			self.job.setComment("Complete - %d seconds elapsed" % (int(time.time()-stime)))
			self.job.setStatus(256)


	def write_meta(self):
		mythvid = MythVideo()
		mythtv = MythTV()
		director = self.mythdb.getCast(self.chanid, int(self.rtime), roles='director')
		if len(director) == 0:
			director = 'NULL'
		else:
			director = director[0]
		viddata = {'title': '%s - %dx%02d - %s' % (self.prog.title, self.season, self.episode, self.prog.subtitle),
			'director': director,
			'plot': self.prog.description,
			'year': self.prog.airdate.split('-')[0],
			'length': str(int((self.prog.recendts-self.prog.recstartts).seconds/60)),
			'filename': self.destdb,
			'host': self.desthost,
			'showlevel': 1,
			'rating': 'NR',
			'inetref': '00000000',
			'coverfile': 'No Cover'}
		intid = mythvid.getMetadataId(self.destdb)
		if intid:
			mythvid.setMetadata(viddata,intid)
		else:
			intid = mythvid.setMetadata(viddata)

		cast = self.mythdb.getCast(self.chanid, int(self.rtime), roles=('actor','guest_star','host','commentator','guest'))
		for name in cast:
			mythvid.setCast(name, intid)
		if self.job:
			self.job.setStatus(272)

def usage():
	print("bleg")

def usage_format():
	print("more bleg")

def main():
	format = None
	jobid = None
	chanid = None
	rtime = None
	skip = False
	try:
		opts, args = getopt.getopt(sys.argv[1:], "hf", ["help","helpformat","format=","chanid=","starttime=","skipcopy"])
	except getopt.GetoptError, err:
		print(str(err))
		usage()
		sys.exit(2)
	for opt, arg in opts:
		if opt in ("-h", "--help"):
			usage()
			sys.exit()
		elif opt in ('-f', '--helpformat'):
			usage_format()
			sys.exit()
		elif opt == '--format':
			format = arg
		elif opt == '--chanid':
			chanid = int(arg)
		elif opt == '--starttime':
			rtime = int(arg)
		elif opt == '--skipcopy':
			skip = True
		
	if len(args):
		jobid = int(args[0])

	if chanid and rtime:
		export = VIDEO(chanid,rtime)
	elif jobid:
		export = VIDEO(jobid)
	elif format:
		# store format to database
		sys.exit()
	else:
		usage()
		sys.exit(2)

	if format:
		export.set_fmt(format)
	if skip:
		export.get_fmt()
		export.get_dest()
	else:
		export.copy()
	export.write_meta()

if __name__ == "__main__":
	main()

