#!/usr/bin/env python
# Copyright 2009 John-Mark Gurney <jmg@funkthat.com>
'''MPEG-TS clip'''

__version__ = '$Change: 1308 $'
# $Id: //depot/python/pymeds/main/shoutcast.py#22 $

import bisect
import email
import os.path

from DIDLLite import VideoItem, Resource
from FSStorage import registerklassfun

from twisted.web import static

class ClipProxyFile:
	def __init__(self, f, p):
		self.fp = open(f)
		self.p = p
		self.pos = 0
		lp = p[-1]
		self.size = lp[0] + lp[1]

	def read(self, s=None):
		if s is None:
			s = self.size - self.pos

		p = bisect.bisect_right(self.p, (self.pos,))
		if p > 0:
			p -= 1
		# We might be able to do this with proper construction of
		# self.p, but this is easier.
		r = []
		fp = self.fp
		records = iter(self.p[p:])
		while s:
			rec = records.next()
			diff = self.pos - rec[0]
			rlen = min(s, rec[1] - diff)
			fp.seek(rec[2] + diff)
			r.append(fp.read(rlen))
			s -= rlen
			self.pos += rlen

		return ''.join(r)

	def close(self):
		self.fp.close()

	def seek(self, p, d=0):
		assert d == 0
		self.pos = p
		if self.pos > self.size:
			self.pos = self.size

	def tell(self):
		return self.pos

class ClipProxy(static.File):
	isLeaf = True

	synchronized = [ 'parsefile', 'getsize', 'open' ]

	def __init__(self, f, *args):
		self.__mtime = None
		static.File.__init__(self, f, *args)
		self.parsefile(self.path)

	def parsefile(self, f):
		if self.getModificationTime() == self.__mtime:
			return

		self.__mtime = self.getModificationTime()
		i = email.message_from_file(open(f))
		self.origfile = i['file']
		self.date = eval(i['datetuple'], { '__builtins__': {} })
		# date is UTC
		p = [ map(int, x.split()) for x in i.get_payload().split('\n') if x ]
		pos = 0
		self.pos = par = []
		for j in p:
			l = j[1] - j[0] + 188
			par.append((pos, l, j[0]))
			pos += l
		self.__size = pos

	def getsize(self):
		return self.__size

	def open(self):
		return ClipProxyFile(self.origfile, self.pos)

	def restat(self):
		static.File.restat(self)
		self.parsefile(self.path)

class ClipFile(VideoItem):
	def __init__(self, *args, **kwargs):
		file = kwargs.pop('file')
		mimetype = 'video/mpeg'
		kwargs['content'] = ClipProxy(file, mimetype)
		VideoItem.__init__(self, *args, **kwargs)
		self.url = '%s/%s' % (self.cd.urlbase, self.id)
		self.res = Resource(self.url, 'http-get:*:%s:*' % mimetype)

def detectclipfile(origpath, fobj):
	path = os.path.basename(origpath)
	ext = os.path.splitext(path)[1]
	if ext == '.clip':
		return ClipFile, { 'file': origpath }

	return None, None

registerklassfun(detectclipfile)