<s> import random , urllib , email <EOL> from lxml import etree <EOL> from datetime import datetime , timedelta <EOL> from molly . conf . provider import task <EOL> import dateutil . parser <EOL> from molly . apps . podcasts . providers import BasePodcastsProvider <EOL> from molly . apps . podcasts . models import Podcast , PodcastItem , PodcastEnclosure <EOL> class Namespace ( object ) : <EOL> def __init__ ( self , ns ) : <EOL> self . ns = ns <EOL> def __call__ ( self , local ) : <EOL> return '<STR_LIT>' % ( self . ns , local ) <EOL> class RSSPodcastsProvider ( BasePodcastsProvider ) : <EOL> @ property <EOL> def PODCAST_ATTRS ( self ) : <EOL> atom = self . atom <EOL> return ( <EOL> ( '<STR_LIT>' , ( '<STR_LIT>' , atom ( '<STR_LIT:id>' ) , ) ) , <EOL> ( '<STR_LIT:title>' , ( '<STR_LIT:title>' , atom ( '<STR_LIT:title>' ) , ) ) , <EOL> ( '<STR_LIT>' , ( '<STR_LIT>' , ) ) , <EOL> ( '<STR_LIT>' , ( '<STR_LIT>' , ) ) , <EOL> ( '<STR_LIT>' , ( '<STR_LIT>' , atom ( '<STR_LIT>' ) , ) ) , <EOL> ( '<STR_LIT:description>' , ( '<STR_LIT:description>' , atom ( '<STR_LIT>' ) , ) ) , <EOL> ) <EOL> def __init__ ( self , podcasts , medium = None ) : <EOL> self . podcasts = podcasts <EOL> self . medium = medium <EOL> @ property <EOL> def atom ( self ) : <EOL> return Namespace ( '<STR_LIT>' ) <EOL> @ task ( run_every = timedelta ( minutes = <NUM_LIT> ) ) <EOL> def import_data ( self , ** metadata ) : <EOL> for slug , url in self . podcasts : <EOL> podcast , url = Podcast . objects . get_or_create ( <EOL> provider = self . class_path , <EOL> rss_url = url , <EOL> defaults = { '<STR_LIT>' : slug } ) <EOL> if self . medium : <EOL> podcast . medium = self . medium <EOL> podcast . slug = slug <EOL> self . update_podcast . delay ( podcast ) <EOL> def determine_license ( self , o ) : <EOL> license = o . find ( '<STR_LIT>' ) or o . find ( '<STR_LIT>' ) <EOL> return getattr ( license , '<STR_LIT:text>' , None ) <EOL> @ task ( ) <EOL> def update_podcast ( self , podcast ) : <EOL> atom = self . atom <EOL> def gct ( node , names ) : <EOL> for name in names : <EOL> if node . find ( name ) is None : <EOL> continue <EOL> value = node . find ( name ) . text <EOL> if name == '<STR_LIT>' : <EOL> value = datetime . fromtimestamp ( <EOL> email . utils . mktime_tz ( <EOL> email . utils . parsedate_tz ( value ) ) ) <EOL> elif name == atom ( '<STR_LIT>' ) : <EOL> value = dateutil . parser . parse ( value ) <EOL> elif name == '<STR_LIT>' : <EOL> value = int ( value ) <EOL> return value <EOL> return None <EOL> xml = etree . parse ( urllib . urlopen ( podcast . rss_url ) ) . getroot ( ) <EOL> try : <EOL> podcast . title = xml . find ( '<STR_LIT>' ) . text <EOL> podcast . description = xml . find ( '<STR_LIT>' ) . text <EOL> except AttributeError : <EOL> podcast . title = xml . find ( atom ( '<STR_LIT:title>' ) ) . text <EOL> podcast . description = xml . find ( atom ( '<STR_LIT>' ) ) . text <EOL> podcast . license = self . determine_license ( xml . find ( '<STR_LIT>' ) ) <EOL> if self . medium is not None : <EOL> podcast . medium = self . medium <EOL> logo = xml . find ( '<STR_LIT>' ) <EOL> podcast . logo = logo . text if logo is not None else None <EOL> ids = [ ] <EOL> for item in xml . findall ( '<STR_LIT>' ) or xml . findall ( atom ( '<STR_LIT>' ) ) : <EOL> id = gct ( item , ( '<STR_LIT>' , atom ( '<STR_LIT:id>' ) , ) ) <EOL> if not id : <EOL> continue <EOL> try : <EOL> podcast_item , created = PodcastItem . objects . get_or_create ( podcast = podcast , guid = id ) <EOL> except PodcastItem . MultipleObjectsReturned : <EOL> PodcastItem . objects . filter ( podcast = podcast , guid = id ) . delete ( ) <EOL> podcast_item , created = PodcastItem . objects . get_or_create ( podcast = podcast , guid = id ) <EOL> old_order = podcast_item . order <EOL> try : <EOL> podcast_item . order = int ( item . find ( '<STR_LIT>' ) . text ) <EOL> except ( AttributeError , TypeError ) : <EOL> pass <EOL> require_save = old_order != podcast_item . order <EOL> for attr , x_attrs in self . PODCAST_ATTRS : <EOL> if getattr ( podcast_item , attr ) != gct ( item , x_attrs ) : <EOL> setattr ( podcast_item , attr , gct ( item , x_attrs ) ) <EOL> require_save = True <EOL> license = self . determine_license ( item ) <EOL> if require_save or podcast_item . license != license : <EOL> podcast_item . license = license <EOL> podcast_item . save ( ) <EOL> enc_urls = [ ] <EOL> for enc in item . findall ( '<STR_LIT>' ) or item . findall ( atom ( '<STR_LIT>' ) ) : <EOL> attrib = enc . attrib <EOL> url = attrib . get ( '<STR_LIT:url>' , attrib . get ( '<STR_LIT>' ) ) <EOL> podcast_enc , updated = PodcastEnclosure . objects . get_or_create ( podcast_item = podcast_item , url = url ) <EOL> try : <EOL> podcast_enc . length = int ( attrib [ '<STR_LIT>' ] ) <EOL> except ValueError : <EOL> podcast_enc . length = None <EOL> podcast_enc . mimetype = attrib [ '<STR_LIT:type>' ] <EOL> podcast_enc . save ( ) <EOL> enc_urls . append ( url ) <EOL> encs = PodcastEnclosure . objects . filter ( podcast_item = podcast_item ) <EOL> for enc in encs : <EOL> if not enc . url in enc_urls : <EOL> enc . delete ( ) <EOL> ids . append ( id ) <EOL> for podcast_item in PodcastItem . objects . filter ( podcast = podcast ) : <EOL> if not podcast_item . guid in ids : <EOL> podcast_item . podcastenclosure_set . all ( ) . delete ( ) <EOL> podcast_item . delete ( ) <EOL> podcast . save ( ) </s>
