예제 #1
0
 def testAGetChannel(self):
     _log.info("Get channel metadata and content ------------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     feeds = ["http://www.rtvslo.si/podcasts/zapisi_iz_mocvirja.xml",
              "http://downloads.bbc.co.uk/podcasts/radio4/today/rss.xml"]
     for f in feeds:
         channel = Channel.getContentSource(f)
         feed = feedparser.parse(f)
         self.assertTrue(channel.metadata != None)
         self.assertTrue(channel.cstype == settings.CS_TYPE_CHANNEL)
         self.assertTrue(channel.sourceMeta == None)
         self.assertTrue(channel.name != None)
         self.assertTrue(channel.identifier != None)
         self.assertTrue(channel.location == f)
         self.assertTrue(os.path.isdir(channel.storage))
         self.assertTrue(os.path.exists(os.path.join(channel.storage, channel.metaFile)))
         self.assertTrue(os.path.exists(os.path.join(channel.storage, settings.CONTENT_SOURCE_PROPERTIES)))
         self.assertTrue(len(channel.items) == len(feed.entries))
         for i, v in channel.items.items():
             self.assertTrue(v.name != None)
             self.assertTrue(v.cutype == settings.CONTENT_VOD)
             self.assertTrue(v.identifier != None and v.identifier == i)
             self.assertTrue(v.metadata != None)
             self.assertTrue(channel.storage == v.feedStore)
             self.assertTrue(v.stored)
             self.assertTrue(v.acquire == channel.acquire)
             self.assertTrue(os.path.exists(os.path.join(channel.storage, v.contentFile)))
             self.assertTrue(os.path.exists(os.path.join(channel.storage, v.metaFile)))
         restored = channel.restore(channel.storage)
         self.assertTrue(restored == channel)
         new = Channel.getContentSource(f)
         self.assertTrue(new == channel)
         channel.remove()
예제 #2
0
 def testDCheckUpdate(self):
     _log.info("Check update from source ------------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     feeds = ["http://www.rtvslo.si/podcasts/zapisi_iz_mocvirja.xml",
              "http://downloads.bbc.co.uk/podcasts/radio4/today/rss.xml"]
     for f in feeds:
         channel = Channel.getContentSource(f)
         for i, v in channel.items.items():
             self.assertTrue(os.path.exists(os.path.join(channel.storage, v.contentFile)))
             self.assertTrue(os.path.exists(os.path.join(channel.storage, v.metaFile)))
         random.random()
         r = random.randint(1, len(channel.items))
         n = 0
         meta = None 
         cont = None
         for i, v in channel.items.items():
             n += 1
             if n == r:
                 meta = os.path.join(channel.storage, v.contentFile)
                 cont = os.path.join(channel.storage, v.metaFile)
                 os.remove(meta)
                 os.remove(cont)
         self.assertTrue(not os.path.exists(meta))
         self.assertTrue(not os.path.exists(cont))
         # update
         channel = Channel.getContentSource(f)
         self.assertTrue(os.path.exists(meta))
         self.assertTrue(os.path.exists(cont))
예제 #3
0
 def testHRestoreStoredProperties(self):
     _log.info("Restore stored properties -----------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     feed = "http://www.rtvslo.si/podcasts/zapisi_iz_mocvirja.xml"
     publish = "http://stream.e5.ijs.si/vod"
     feedLink = "http://stream.e5.ijs.si/feeds/zapisi_iz_mocvirja.xml"
     cuci = "RTVVoDContent"
     exportLink = "http://web.server.of.your.choice/relative"
     guid = "xyz"
     image = "http://stream.e5.ijs.si/image/kuku.jpg"
     didfile = "did-base-test.xml"
     rmg = RichMetadataGenerator.getInstance()
     meta = rmg.getRichMetadata(None, metadata.MPEG_21_BASE)
     meta.setRelatedIdentifier("urn:rtv-slo:slo1-xyz") 
     meta.setPaymentReference("URI to additional MPEG_21 data (payment)") 
     meta.setAdvertisementReference("URI to additional MPEG_21 data (advertising)") 
     meta.setScalabilityReference("URI to additional MPEG_21 data (scalability)")
     meta.setLimoReference("URI to additional MPEG_21 data (limo)")
     f = open(didfile, 'w')
     f.write(rmg.build(meta))
     f.close()
     channel = Channel.getContentSource(feed, publish, RTVVoDContent(), feedLink, didfile)
     feed1_xml = channel.exportFeed(guid, image)
     test = ContentSource.getContentSource(feed)
     test.storage = channel.storage
     test.restoreAttributes()
     self.assertTrue(channel.storage == test.storage)
     self.assertTrue(channel.cstype == test.cstype)
     self.assertTrue(channel.location == test.location)
     self.assertTrue(channel.publish == test.publish)
     self.assertTrue(channel.image == test.image)
     self.assertTrue(channel.contentUnitClassInstance == test.contentUnitClassInstance)
     self.assertTrue(channel.exportFeedLink == test.exportFeedLink)
     self.assertTrue(channel.didbaseFile == test.didbaseFile)
     self.assertTrue(channel.guid == test.guid)
     channel = Channel.getContentSource(feed)
     feed2_xml = channel.exportFeed()
     # Cannot compare directly xmls since the updated can change
     feed1_meta = Feed.getMetadata(StringIO(feed1_xml), False)
     feed2_meta = Feed.getMetadata(StringIO(feed2_xml), False)
     self.assertTrue(feed1_meta.id == feed2_meta.id)
     self.assertTrue(feed1_meta.p2pnext_img_src == feed2_meta.p2pnext_img_src)
     self.assertTrue(feed1_meta.links_href == feed2_meta.links_href)
     count = 0
     for i in feed1_meta._items:
         self.assertTrue(i.links_href == feed2_meta._items[count].links_href)
         self.assertTrue(i.id == feed2_meta._items[count].id)
         self.assertTrue(i.p2pnext_image_src == feed2_meta._items[count].p2pnext_image_src)
         count += 1
예제 #4
0
 def testEDefaultsExportFeed(self):
     _log.info("Defaults export feed ------------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     feeds = ["http://www.rtvslo.si/podcasts/zapisi_iz_mocvirja.xml",
              "http://downloads.bbc.co.uk/podcasts/radio4/today/rss.xml"]
     rmg = RichMetadataGenerator.getInstance()
     publish = "http://web.server.of.your.choice/relative"
     for f in feeds:
         channel = Channel.getContentSource(f, publish)
         _log.debug(rmg.prettyPrint(channel.exportFeed(), 'utf-8'))
         # Get meta, don't identify media, since we can't (yet?)
         meta = Feed.getMetadata(StringIO(channel.exportFeed()), False)
         self.assertTrue(meta.title == channel.name)
         self.assertTrue(meta.links_href == publish + "/" + textify(channel.name) + settings.METADATA_EXT)
         self.assertTrue(meta.language == channel.metadata.getLanguage())
         self.assertTrue(meta.author == channel.metadata.getPublisher())
         self.assertTrue(meta.id == channel.getExportFeedLink())
         self.assertTrue(meta.p2pnext_image_src == channel.image)
         for i, v in channel.items.items():
             # Find according to link
             rmi = None
             for i in meta._items:
                 if i.links_href == publish + "/" + v.publish:
                     rmi = i
             self.assertTrue(rmi != None)
             self.assertTrue(rmi.title == v.name)
             self.assertTrue(rmi.links_type == "application/x-bittorrent")
             # Id not tested
             self.assertTrue(rmi.p2pnext_image_src == channel.image)
             self.assertTrue(rmi.title == v.metadata.getTitleEpisodeTitle())
예제 #5
0
 def run(self):
     """
     Runs the feed tool and creates a feed according to specified
     options
     """
     if not options.title:
         options.title = self.default_title
     if not options.exporturl:
         self.exitOnInputError("Export url must be defined")
     if not options.publisher:
         options.publisher = self.default_publisher
     if not options.id:
         options.id = options.exporturl
     if not options.image:
         options.image = self.default_image
     df = P2PNextAtomFeed(title=options.title,
                          feed_url=options.exporturl,
                          author_name=options.publisher,
                          feed_guid=options.id,
                          image=options.image)
     storage = settings.MEDIA_ROOT
     if options.mediaroot:
         if os.path.isdir(options.mediaroot):
             storage = options.mediaroot
         else:
             self.exitOnInputError("Specified media root is not a directory")
     for e in os.listdir(storage):
         fdir = os.path.join(storage, e)
         _log.debug(fdir)
         if os.path.isdir(fdir):
             if os.path.exists(os.path.join(fdir, settings.CONTENT_SOURCE_PROPERTIES)):
                 _log.debug(fdir)
                 # Will need to adapt when live streams are supported
                 cs = Channel.getContentSource(fdir)
                 _log.debug(cs.toString())
                 image = options.image
                 if cs.image:
                     image = cs.image
                 fid = settings.URN + settings.P2P_NEXT + settings.COLON + cs.identifier
                 if cs.guid:
                     fid = cs.guid
                 video = False
                 for i, v in cs.items.items():
                     if v.metadata:
                         if v.metadata.getVideoCoding():
                             video = True
                             break
                 if video:
                     cat = [(settings.CATEGORY_TV, settings.CATEGORY_SCHEME_ST)]
                 else:
                     cat = [(settings.CATEGORY_RADIO, settings.CATEGORY_SCHEME_ST)]
                 df.add_item(title=cs.name, 
                             link=cs.exportFeedLink,
                             link_type="application/atom+xml",
                             unique_id=fid,
                             description=cs.metadata.getTitleSeriesTitle(),
                             image=image,
                             categories=cat)
     print self.rmg.prettyPrint(df.writeString(), 'utf-8')
예제 #6
0
 def testJLoadFromDir(self):
     _log.info("Loading from directory -----------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     feeds = ["http://www.rtvslo.si/podcasts/zapisi_iz_mocvirja.xml",
              "http://downloads.bbc.co.uk/podcasts/radio4/today/rss.xml"]  
     netch = []
     for f in feeds:
         netch.append(Channel.getContentSource(f))
     dirch = []
     for c in netch:
         dirch.append(Channel.getContentSource(c.storage))
     i = 0
     for c in netch:
         self.assertTrue(c == dirch[i])
         i += 1
예제 #7
0
 def testFCostumizedExportFeed(self):
     _log.info("Customized export feed -----------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     feeds = ["http://www.rtvslo.si/podcasts/zapisi_iz_mocvirja.xml",
              "http://downloads.bbc.co.uk/podcasts/radio4/today/rss.xml"]  
     rmg = RichMetadataGenerator.getInstance()
     publish = "http://stream.e5.ijs.si/vod"
     for f in feeds:
         url = urlparse.urlparse(f)
         if url.netloc == "www.rtvslo.si":
             channel = Channel.getContentSource(f, publish, RTVVoDContent())
             for i, v in channel.items.items():
                 self.assertTrue(type(v) == type(RTVVoDContent()))
         else:
             channel = Channel.getContentSource(f, publish)
             for i, v in channel.items.items():
                 self.assertTrue(type(v) == type(ContentUnit()))
         _log.debug(rmg.prettyPrint(channel.exportFeed(), 'utf-8'))
예제 #8
0
 def testIWindow(self):
     _log.info("Window test -----------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     feed = "http://downloads.bbc.co.uk/podcasts/radio4/today/rss.xml"
     channel = Channel.getContentSource(feed)
     fp = feedparser.parse(feed)
     osw = len(fp.entries)
     channel = Channel.getContentSource(feed, None, None, None, None, osw)
     self.assertTrue(len(channel.items) == osw)
     channel = Channel.getContentSource(feed, None, None, None, None, osw-1)
     self.assertTrue(len(channel.items) == osw-1)
     channel.window = 10
     channel.checkWindow()
     self.assertTrue(len(channel.items) == 10)
     channel.store(True)
     channel = Channel.getContentSource(feed)
     self.assertTrue(len(channel.items) == 10)
     # Negative value for window restores default - None
     channel = Channel.getContentSource(feed, None, None, None, None, -1)
     self.assertTrue(len(channel.items) == osw)
예제 #9
0
 def testGExportFeedLink(self):
     _log.info("Export feed link -----------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     feeds = ["http://www.rtvslo.si/podcasts/zapisi_iz_mocvirja.xml"]
     rmg = RichMetadataGenerator.getInstance()
     publish = "http://stream.e5.ijs.si/vod"
     feedLink = "http://stream.e5.ijs.si/feeds/zapisi_iz_mocvirja.xml"
     for f in feeds:
         channel = Channel.getContentSource(f, publish, RTVVoDContent(), feedLink)
         meta = Feed.getMetadata(StringIO(channel.exportFeed()), False)
         self.assertTrue(meta.links_href == feedLink)
예제 #10
0
파일: getfeed.py 프로젝트: Swizec/IJS-stuff
 def run(self):
     """
     Runs the getfeed tool, fetches the content, generate torrents
     and provides P2P-Next compliant feed on std out
     """
     if options.location != None:
         template = None
         if options.template:
             if self.mapper.get(options.template):
                 template = self.mapper[options.template]
         channel = Channel.getContentSource(options.location, 
                                            options.publish,
                                            template,
                                            options.feedexport,
                                            options.didbaseFile,
                                            options.window)
         _log.info("Feed is stored in path: %s",
                   channel.storage)
         _log.info("Resulting torrent files reside in path: %s",
                   settings.EXPORT_TORRENT_DIR)
         _log.info("DID Base used path: %s", options.didbaseFile)
         _log.info("Resulting feed should be published at location: %s",
                   channel.getExportFeedLink())
         print self.rmg.prettyPrint(channel.exportFeed(options.guid, options.image), 'utf-8')
     elif options.directory != None:
         if os.path.isdir(options.directory):
             if os.path.exists(os.path.join(options.directory, settings.CONTENT_SOURCE_PROPERTIES)):
                 channel = Channel.getContentSource(options.directory)
                 if channel.location.startswith("file"):
                     _log.debug("Mannually created feed in the directory %s, won't update", options.directory)
                 else:
                     channel.update()
                 print self.rmg.prettyPrint(channel.exportFeed(), 'utf-8')
             else:
                 self.exitOnInputError("Directory " + options.directory + " specified but does not hold a feed.")
         else:
             self.exitOnInputError("Specified path '" + options.directory + "' is not a directory")
     else:
         self.exitOnInputError("Neither location (-l) nor update directory (-u)\n                    were specified.")
예제 #11
0
 def testBExportTorrents(self):
     _log.info("Export torrents ------------")
     if not TestContentSource.run_test:
         _log.debug("Test avoided.")
         return
     channel = Channel.getContentSource("http://www.rtvslo.si/podcasts/zapisi_iz_mocvirja.xml")
     channel.exportTorrent()
     for i, v in channel.items.items():
         (b, e) = os.path.splitext(v.contentFile)
         tp = os.path.join(settings.EXPORT_TORRENT_DIR, b + '.tstream')
         self.assertTrue(os.path.exists(tp))
     channel.update()
     for i, v in channel.items.items():
         self.assertTrue(not v.fresh)
     channel.remove()
     shutil.rmtree(settings.EXPORT_TORRENT_DIR)
예제 #12
0
 def run(self):
     """
     Runs the managefeed tool and creates a feed according to specified
     options or modifies feed content (items)
     """
     core = None
     rmg = RichMetadataGenerator.getInstance()
     if options.coremetafile:
         core = rmg.getRichMetadata(options.coremetafile)                
         if core:
             if core.metadataType != metadata.METADATA_CORE:
                 self.exitOnInputError("Core metadata of wrong type: " + core.metadataType)
         else:
             self.exitOnInputError("Cannot read core metadata from supplied file: " + options.coremetafile)
     # Creates a feed
     if options.feedmod:
         if not options.title and not options.coremetafile:
             self.exitOnInputError("Feed title or core metadata must be defined")
         channel = Channel()
         if core:
             if not core.getTitleMain():
                 self.exitOnInputError("Feed title or core metadata title mainmust be defined")
             channel.name = core.getTitleMain()
             channel.metadata = core
         else:
             channel.name = options.title
         channel.storage = settings.MEDIA_ROOT + os.path.sep + textify(channel.name)
         channel.location = "file://" + channel.storage
         channel.identifier = channel.identify(channel.location)
         if options.cuci:
             cuci = classImport(classpath, options.cuci)
             if cuci:
                 channel.contentUnitClassInstance = cuci.__class.__name__
                 channel.cuci = cuci
         if os.path.isdir(channel.storage):
             channel = channel.restore(channel.storage, channel)
             if core: # core metadata supplied on command line, prevail
                 channel.metadata = core
         if options.publish:
             channel.publish = options.publish
         if options.exporturl:
             channel.exportFeedLink = options.exporturl
         if options.didbase:
             channel.setDIDBaseFile(options.didbase)
         if options.image:
             channel.image = options.image
         if not core:
             core = rmg.getRichMetadata()
         old = core
         if options.language:
             core.setLanguage(options.language)
         if options.description:
             core.setTitleSeriesTitle(options.description)
         if options.publisher:
             core.setPublisher(options.publisher)
         if options.originator:
             core.setOriginator(options.originator)
         if options.title:
             core.setTitleMain(options.title)
         if core != old or not channel.metadata:
             channel.metadata = core
         channel.store(True)
     # Adds an item to the feed
     elif options.additem:
         if not options.feeddir:
             self.exitOnInputError("For adding the feed item feed directory needs\n                    to be specified! (-d option)")
         if not os.path.exists(os.path.join(options.feeddir, settings.CONTENT_SOURCE_PROPERTIES)):
             self.exitOnInputError("Feed directory specified seems not to be populated.\n                    Feed properties file is missing in path: " + options.feeddir)
         c = Channel()
         channel = c.restore(options.feeddir)
         cu = channel.getContentUnitInstance()
         cu.acquire = channel.acquire
         if options.content:
             if os.path.exists(options.content) and os.path.isfile(options.content):
                 cu.contentFile = os.path.basename(options.content)
             else:
                 self.exitOnInputError("Content file is missing in path or is not a file:\n                    " + options.content)
         else:
             self.exitOnInputError("Content file should be specified while adding an item")
         item = Item()
         item._items.append(Media.getMetadata(options.content))
         if not core: 
             core = rmg.getRichMetadata()
         if options.title:
             core.setTitleEpisodeTitle(options.title)
         if options.synopsis:
             core.setSynopsis(options.synopsis)
         # Problem turned round. From RM set the item attributes
         for k, v in settings.MMM_ITEM.items():
             if v:
                 m = "get" + v.lstrip("set")
                 f = getattr(core, m)
                 setattr(item, k, f())
         if options.coremetafile:
             cu.metadata = item.getRichMetadata(core)
         else:
             cu.metadata = item.getRichMetadata(channel.metadata)
         cu.name = cu.metadata.getTitleEpisodeTitle()
         cu.identifier = cu.identify()
         if cu.identifier in channel.items:
             self.exitOnInputError("You are trying to add the content " + options.content + " with metadata that seems already added to the feed with name " + channel.name)
         cu.feedStore = channel.storage
         (b, e) = os.path.splitext(cu.contentFile)
         cu.storeMeta(os.path.join(channel.storage, b))
         if channel.storage != os.path.basename(options.content):
             if os.path.exists(os.path.join(channel.storage, cu.contentFile)):
                 self.exitOnInputError("You are trying to add the content " + cu.contentFile + "\n                    to the feed with name '" + channel.name + "' that already\n                    exists in the feed.")     
             os.symlink(options.content, os.path.join(channel.storage, cu.contentFile))
         cu.fresh = True
         channel.items[cu.identifier] = cu
         channel.exportTorrent()
     # Removes the item
     elif options.removeitem:
         if not options.feeddir:
             self.exitOnInputError("For removing the feed item feed directory needs to be\n                        specified (-d option)!")
         if os.path.exists(options.feeddir) and os.path.isdir(options.feeddir):
             c = Channel()
             channel = c.restore(options.feeddir)
             if channel.items.has_key(options.removeitem):
                 channel.removeContentUnit(options.removeitem)
             else:
                 self.exitOnInputError("Cannot remove nonexistent content unit, identifier " + options.removeitem + " not registred")
         else:
             self.exitOnInputError("Feed directory is missing in path or is not a directory:\n                    " + options.feeddir)                
     # List the feed
     elif options.list:
         if os.path.exists(options.list) and os.path.isdir(options.list):
             c = Channel()
             channel = c.getCSFromDir(options.list)
             if options.listlong:
                 print channel.toString()
             else:
                 print "'" + channel.name + "', stored in " + channel.storage
                 print "Location: " + channel.location
                 i = 1
                 sitems = channel.timesort.sort()
                 sitems.reverse()
                 for k in sitems:
                     if channel.items.get(k):
                         v = channel.items[k]
                         print '{0:>3}'.format(i) + ") " + v.name 
                         print "     Identifier: " + v.identifier
                         print "     Content:    " + v.contentFile
                         print "     Metadata:   " + v.metaFile
                         print "     Torrent:    " + str(v.findTorrentFile())
                         i += 1
                     else:
                         _log.warn("Programmable error: identifier in sorter that does not exists in source")
         else:
             self.exitOnInputError("Feed directory is missing in path or is not a directory:\n                    " + options.list)                
     else:
         self.exitOnInputError("None of the main options -c, -a, -r or -l specified!")