#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
 Copyright (C) 2004 jan gerber <j@reboot.fm>

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Library General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
'''

# last_week - stream of last week, just plays back the program of 
#             last week from the archive. this is the fallack in
#            	switch.py

import os,string
from sys import exit,stdout
from ogg import OggSyncState, vorbis
from shout import Shout,ShoutException
from types import NoneType
from urllib2 import urlopen,HTTPError
import socket
from math import *

# installed by hand right now. might put it in one package. python-pdi
from pdi.icalendar import VCalendar,ICalendar
import pdi.parser

# installed by hand right now. might put it in one package. python-dateutil
from dateutil.parser import *
import time
import datetime

class switchogg :
	def __init__(self) :
		#some variables mostly urls
		# replaced with local file. update should go in thread
		#self.ics_url='http://www.reboot.fm/vcal/current.ics'
		self.ics_url='file:///tmp/reboot.fm_current.ics'
		self.fallback_url='http://localhost:8000/line-in.ogg'
		self.fallback=0
		self.default_stream='http://10.0.0.5:8000/line-in.ogg'
		self.calendar=None
		self.url=None
		# some stuff to handle the shout to the icecast server
		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 = '/lastweek.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):
	try:
		read = f.read(4096)
		length=len(read)
	except socket.error, msg:  ### non blocking
		print "fill buffer: timeout"
		return (0,0)
	return (read,length)

def print_log(string):
	print time.strftime("%Y-%m-%d %H:%M:%S"),"\t:",string
	stdout.flush()

def status_log(item,value):
	try:
		if item =='url':
			stat=open("/tmp/lastweek.status","w")
			stat.write(value)
			stat.close()
	except:
		print_log("could not update status")


def get_last_week():
	# just find the show that was running last week
	return url_to_last_week
#seeks in oggfile to now-one_week
def seek_to_now_last_week(f):


def switch_loop():
	dto = socket.getdefaulttimeout()
	socket.setdefaulttimeout(1.0)
	#initalize some variables,
	now=0
	f_tmp=0
	
	print_log("starting up Ogg last week switch.")
	while 1:
		try:
			so=switchogg()
		except:
			print_log("couldn't connect to icecast server.")
			# what is a cood timeout here? to not try too often
			time.sleep(1)
			continue
		# open show from last week and seek to current time.
		# using functions from recordings2archive
		filename_lastweek=get_last_week()
		f=urlopen(filename_lastweek)
		seek_to_now_last_week(f)
		print_log("open show from last week: %s" % filename_lastweek)
		while 1:
			(read,length) = fillbuffer(f)
			# open next file in recordings here
			if length == 0:
				f.close()
				try:
					filename_lastweek=get_last_week()
					f= urlopen(filename_lastweek)
					seek_to_now_last_week(f)
					status_log('url',filename_lastweek):
				except:
					f.close()
					f= urlopen(so.fallback_url)
					print_log("fallback, open: %s" % so.fallback_url)
					so.fallback=1
			try:
				so(read)
			except ShoutException:
			# so the connection to the icecast server is down.
			# clean up some open filehandles and reconnect
				print_log("ShoutException")
				f.close()
				break
		f.close()
		# restore default
		socket.setdefaulttimeout(dto)

if __name__ == '__main__':
	switch_loop()
