#!/usr/bin/env python
#
# restream - parses a ics (ical) file and switches
#            to another ogg stream if nessessary
#            ogg streams are provided by 
#							- live encoders (studioA,..)
#							- an archive (preproduced shows, repetitions)
#	
# (c) 2004 <j@reboot.fm>

import os
import string
from time import *
from sys import exit
from ogg import OggSyncState, vorbis
from shout import Shout
from types import NoneType
from urllib2 import urlopen
from xmlrpclib import ServerProxy
from math import *
from pdi.icalendar import VCalendar
import pdi.parser







class restreamogg :
	def __init__(self) :
		#some variables mostly urls
		self.xmlrpcurl="http://localhost:8070"
		#self.ics_url='http://meta.b.lab.net:9000/vcal/current.ics'
		self.ics_url='http://localhost/current.ics'
		self.next_url='http://localhost/ogg/bios.ogg'
		self.fallback_url='http://localhost/ogg/os.ogg'

		self.ogg = OggSyncState()
		self.page = 0
		self.serial = 1
		self.shout = Shout()
		self.shout.host = '127.0.0.1'
		self.shout.port = 8000
		self.shout.user = 'source'
		self.shout.password = 'hack4me'
		self.shout.mount = '/j_stream.ogg'
		self.shout.format = 'vorbis'
		self.shout.protocol = 'http'
		self.shout.open()
	def __call__(self, data) :
		self.ogg.bytesin(data)
		while 1:
				newpage = self.ogg.pageseek()
				if newpage == None :
					break
				if self.page == 0 :
				   	self.page = newpage
				   	continue
				if self.page.serialno != newpage.serialno : self.page.eos = 1
				if newpage.pageno==0 : self.page.eos = 1
				self.page.serialno=self.serial
				if self.page.eos == 1 :
				   if self.serial<65536 : self.serial = self.serial + 1
				   else : self.serial = 0
				self.shout.sync()
				out=self.page.header+self.page.body
				self.shout.send(out)
				self.page=newpage
		return

def fillbuffer(f):
	read = f.read(4096)
	length=len(read)
	return (read,length)

def print_log(string):
	print time(),"\t:",string

def upcoming_show():
	global ics_url
	# needs to read file from schedular and parse
	#
	#ics_f=open()
	#upcoming_ics=ics_f.read()
	#ics_f.close()
	ics_fh=urlopen(ics_url)
	calendar = pdi.parser.fromFileObject(ics_fh, VCalendar())
	ics_fh.close
	#<year><month><day>T<hour><minute<second><type designator>
	icaltimeformat="%Y%m%dT%H%M%SZ"
	for show in calendar.components:
		next_show=strptime(show.properties['DTSTART'].getContent(), icaltimeformat)
		print next_show

	#return server.upcoming_show();
	return (0,"/dev/null")

while 1:
	try:
		so=restreamogg()
	except:
		print_log("could not connect to icecast server.")
		sleep(5)
		continue

	server = ServerProxy(xmlrpcurl)
	f=urlopen(next_url)
	ftotal = 0
	timestamp=0
	f_tmp=0

	print_log("starting up oggstreamer.")
	while 1 :
		while 1:
			length = 0
			while length == 0 :
				if timestamp < floor(time()):
					timestamp = floor(time())
					next_t = upcoming_show()
					try:
						next_t = upcoming_show()
					except:
						print_log("getting upcoming_show faild: %s" % xmlrpcurl)
					else:
						(next_start, next_url) =  next_t
						if timestamp <= next_start <= ceil(time()):
							try:
								f_tmp = urlopen(next_url)
							except:
								print_log("could not open ogg stream: %s" % next_url)
						else:
							f.close()
							f=f_tmp
							f_tmp=0
				(read,length) = fillbuffer(f)
				if length == 0:
					f.close()
					f= urlopen(fallback_url)
			ftotal = ftotal + len(read)
			so(read)
		print 'Track end, total %d bytes' % ftotal
		f.close()
