#! /usr/bin/python

# Cupid Receiver, a command-line podcatcher in Python
# (c) 2007, Jason Lefkowitz (jason@jasonlefkowitz.net)
# 
__license__ = """(c) 2007, Jason Lefkowitz (jason@jasonlefkowitz.net)
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 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."""
__author__ = "Jason Lefkowitz <jason@jasonlefkowitz.net>"
__version__ = "0.1"


import feedparser
import urllib
import os
import sys
import re
import cPickle
from datetime import date

BASE_DIR = u'/media/My Book/Audio/'
MEDIA_DEVICE_DIR = u'/media/JUKEBOX/'
FILE_DIR = u'Podcasts/'
PODCAST_LIST = u'podcasts.db'
PICKLE_FILE = u'cupid.db'

def cleanUpFeedItems(item):
	""" Often times feed items will contain characters in their names that don't work with a standard filesystem.  This function strips out the most egregious offenders, replaces others with alternatives, and returns the cleaned up name as a Unicode string."""
	
	regex = re.compile('\s*[:|\|]\s*')
	item = re.sub(regex, ' -- ', item)
	item = item.replace('\\','')
	item = item.replace('/','')
	item = item.replace('*','Star')
#	item = item.replace(':','--')
#	item = item.replace('|', '--')
	item = item.replace('?', '')
	return unicode(item)
 
def getPodcastList():
	
	podcastDict = {}
	
	if os.path.exists(PICKLE_FILE):
		podcastDb = open(PICKLE_FILE, 'r')
		podcastDictPickled = cPickle.load(podcastDb)
	else:
		podcastDictPickled = {}
	
	if os.path.exists(PODCAST_LIST):
		print "Found podcast list"
		podcastListFile = open(PODCAST_LIST, 'r')	
	else:
		sys.exit("No feeds specified, dingbat!")
		
	podcastList = []	
	for line in podcastListFile:
		line = line.rstrip('\n')
		podcastList.append(line)
		
	for podcastKey in podcastDictPickled.keys():
		if podcastList.count(podcastKey) == 0:
			print "Removing " + podcastKey + "from pickled file"
			del podcastDictPickled[podcastKey]
		
	for line in podcastList:
		if line.split():
			if podcastDictPickled.has_key(line):
				podcastDict[line] = {'etag':podcastDictPickled[line]['etag'], 'last_modified':podcastDictPickled[line]['last_modified']}
			else:
				podcastDict[line] = {'etag':'', 'last_modified':''}
		
	podcastListFile.close()
	return podcastDict
	
		
def updatePickledPodcastList(podcastList):
	podcastDb = open(PICKLE_FILE, 'w')
	cPickle.dump(podcastList, podcastDb)
	podcastDb.close()
	
def syncWithRemoteStorage(mediaDevicePath):
	print "Syncing with remote device..."
	for directory in os.listdir(BASE_DIR + FILE_DIR):
		print directory	
	
	
	
if __name__ == '__main__':
	 
	downloadDir = BASE_DIR + FILE_DIR
			 
	podcastList = getPodcastList()
	for podcast in podcastList.keys():
		if podcastList[podcast]['etag']:
			d = feedparser.parse(podcast, etag=podcastList[podcast]['etag'])
		elif podcastList[podcast]['last_modified']:
			d = feedparser.parse(podcast, modified=podcastList[podcast]['last_modified'])
		else:
			d = feedparser.parse(podcast)
			
		print podcast + ' : ' + str(d['status'])

		if d['status'] == 200 or d['status'] == 302:
			if d.has_key('etag'):
				podcastList[podcast]['etag'] = d.etag
			if d.has_key('modified'):
				podcastList[podcast]['last_modified'] = d.modified
			feedDir = unicode(downloadDir + cleanUpFeedItems(d['feed']['title']))
			if os.path.isdir(feedDir) == False:
				os.mkdir(feedDir)
			for entry in d['entries']:
				if entry.has_key('enclosures'):
					lastUpdated = date(entry['updated_parsed'][0], entry['updated_parsed'][1], entry['updated_parsed'][2])
					lastUpdated = str(lastUpdated)
					lastUpdated = unicode(lastUpdated)
					for enclosure in entry['enclosures']:
						fileNameToWriteTo = feedDir + u'/(' + lastUpdated + u') ' + cleanUpFeedItems(entry['title']) + u'.mp3'
						if os.path.isfile(fileNameToWriteTo) == False:	
							print "Retrieving " + fileNameToWriteTo + "..."
							urllib.urlretrieve(enclosure.href, fileNameToWriteTo)
						else:
							print str(fileNameToWriteTo) + " already exists"
			
		
#	syncWithRemoteStorage(MEDIA_DEVICE_DIR)
		
	updatePickledPodcastList(podcastList)