Beispiel #1
0
    def test_changingFromMailToName(self):
        p = Person(email=self.email)
        p.name = self.name
        p.email = None

        assert p.name == self.name
        assert p.email is None
    def populate(self, show) -> None:
        self._set_if_false(show, 'description',
                           self.settings.get('description'))

        default_category = Category(
            **self.settings['category']) if self.settings.get(
                'category') else None
        self._set_if_false(show, 'category', default_category)

        self._set_if_false(show, 'language', self.settings.get('language'))
        self._set_if_false(show, 'website', self.settings.get('website'))
        self._set_if_false(
            show, 'authors',
            [Person(**author) for author in self.settings['authors']]
            if self.settings.get('authors') else [])

        default_webmaster = Person(
            **self.settings['web_master']) if self.settings.get(
                'web_master') else None
        self._set_if_false(show, 'web_master', default_webmaster)

        self._set_if_none(show, 'explicit', self.settings.get('explicit'))

        default_owner = Person(
            **self.settings['owner']) if self.settings.get('owner') else None
        self._set_if_false(show, 'owner', default_owner)

        if show.owner:
            self._set_if_false(show, 'copyright', show.owner.name)

        self._set_if_false(show, 'image', self.settings.get('image'))
Beispiel #3
0
    def test_changingFromNameToMail(self):
        p = Person(name=self.name)
        p.email = self.email
        p.name = None

        assert p.email == self.email
        assert p.name is None
Beispiel #4
0
    def test_changingFromMailToName(self):
        p = Person(email=self.email)
        p.name = self.name
        p.email = None

        assert p.name == self.name
        assert p.email is None
Beispiel #5
0
    def test_multipleAuthors(self):
        person1 = Person("John Doe", "*****@*****.**")
        person2 = Person("Mary Sue", "*****@*****.**")

        self.fe.authors = [person1, person2]
        author_elements = \
            self.fe.rss_entry().findall("{%s}creator" % self.dublin_ns)
        author_texts = [e.text for e in author_elements]

        # Test that both authors are included, in the same order they were added
        assert person1.name in author_texts[0]
        assert person1.email in author_texts[0]
        assert person2.name in author_texts[1]
        assert person2.email in author_texts[1]

        # Test that itunes:author includes all authors' name, but not email
        itunes_author = \
            self.fe.rss_entry().find("{%s}author" % self.itunes_ns).text
        assert person1.name in itunes_author
        assert person1.email not in itunes_author
        assert person2.name in itunes_author
        assert person2.email not in itunes_author

        # Test that the regular rss tag is not used, per the RSS recommendations
        assert self.fe.rss_entry().find("author") is None
Beispiel #6
0
    def test_multipleAuthors(self):
        # Multiple authors - use itunes:author and dc:creator, not
        # managingEditor.

        person1 = Person("Multiple", "*****@*****.**")
        person2 = Person("Are", "*****@*****.**")
        self.fg.authors = [person1, person2]
        channel = self.fg._create_rss().find("channel")

        # Test dc:creator
        author_elements = \
            channel.findall("{%s}creator" % self.nsDc)
        author_texts = [e.text for e in author_elements]

        assert len(author_texts) == 2
        assert person1.name in author_texts[0]
        assert person1.email in author_texts[0]
        assert person2.name in author_texts[1]
        assert person2.email in author_texts[1]

        # Test itunes:author
        itunes_author = channel.find("{%s}author" % self.nsItunes)
        assert itunes_author is not None
        itunes_author_text = itunes_author.text
        assert person1.name in itunes_author_text
        assert person1.email not in itunes_author_text
        assert person2.name in itunes_author_text
        assert person2.email not in itunes_author_text

        # Test that managingEditor is not used
        assert channel.find("managingEditor") is None
Beispiel #7
0
    def album(self):
        page = requests.get(self.url, headers=self.header)
        soup = BeautifulSoup(page.content, "lxml")

        # 初始化
        self.podcast = Podcast()
        self.podcast.name = soup.find('div', 'detailContent_title').get_text()
        self.podcast.authors.append(Person("Powered by forecho", '*****@*****.**'))
        self.podcast.website = self.url
        self.podcast.copyright = 'cc-by'
        self.podcast.description = soup.find('div', 'mid_intro').get_text()
        self.podcast.language = 'cn'
        self.podcast.image = soup.find('a', 'albumface180').find('img').get('src').split('!')[0]
        self.podcast.feed_url = 'http://podcast.forecho.com/ximalaya/%s.rss' % self.album_id
        self.podcast.category = Category('Technology', 'Podcasting')
        self.podcast.explicit = False
        self.podcast.complete = False
        self.podcast.owner = Person("forecho", '*****@*****.**')

        sound_ids = soup.find('div', class_='personal_body').get('sound_ids').split(',')

        for sound_id in sound_ids:
            date = soup.find('li', sound_id=sound_id).find('div', class_='operate').get_text().strip()
            self.detail(sound_id, date)
        # 生成文件
        # print self.podcast.rss_str()
        self.podcast.rss_file('ximalaya/%s.rss' % self.album_id, minimize=True)
Beispiel #8
0
    def album(self):
        album_info_content = requests.get(self.album_info_api).content
        album_info_data = json.loads(album_info_content)
        album_list_content = requests.get(self.album_list_api).content
        album_list_data = json.loads(album_list_content)

        self.podcast = Podcast()
        self.podcast.name = album_info_data['data']['title']
        self.podcast.authors.append(Person("Powered by maijver", '*****@*****.**'))
        self.podcast.website = self.url
        self.podcast.copyright = 'cc-by'
        self.podcast.description = album_info_data['data']['description']
        self.podcast.language = 'cn'
        self.podcast.image = album_info_data['data']['thumbs']['small_thumb'].replace('!200', '')
        self.podcast.feed_url = 'http://podcast.forecho.com/qingting/%s.rss' % self.album_id
        self.podcast.category = Category('Technology', 'Podcasting')
        self.podcast.explicit = False
        self.podcast.complete = False
        self.podcast.owner = Person("maijver", '*****@*****.**')

        for each in album_list_data['data']:
            episode = self.podcast.add_episode()
            episode.id = str(each['id'])
            episode.title = each['title']
            print(self.podcast.name + '=====' + each['title'])
            episode.image = album_info_data['data']['thumbs']['small_thumb'].replace('!200', '')
            episode.summary = each['title']
            episode.link = 'http://www.qingting.fm/channels/{}/programs/{}'.format(self.album_id, each['id'])
            episode.authors = [Person("forecho", '*****@*****.**')]
            episode.publication_date = self.reduction_time(each['update_time'])
            episode.media = Media("http://od.qingting.fm/{}".format(each['mediainfo']['bitrates_url'][0]['file_path']),
                                  each['duration'])

        self.podcast.rss_file('qingting/{}.rss'.format(self.album_id), minimize=True)
Beispiel #9
0
    def test_changingFromNameToMail(self):
        p = Person(name=self.name)
        p.email = self.email
        p.name = None

        assert p.email == self.email
        assert p.name is None
Beispiel #10
0
def main():
    """Create an example podcast and print it or save it to a file."""
    # There must be exactly one argument, and it is must end with rss
    if len(sys.argv) != 2 or not (
            sys.argv[1].endswith('rss')):
        # Invalid usage, print help message
        # print_enc is just a custom function which functions like print,
        # except it deals with byte arrays properly.
        print_enc ('Usage: %s ( <file>.rss | rss )' % \
                'python -m podgen')
        print_enc ('')
        print_enc ('  rss              -- Generate RSS test output and print it to stdout.')
        print_enc ('  <file>.rss       -- Generate RSS test teed and write it to file.rss.')
        print_enc ('')
        exit()

    # Remember what type of feed the user wants
    arg = sys.argv[1]

    from podgen import Podcast, Person, Media, Category, htmlencode
    # Initialize the feed
    p = Podcast()
    p.name = 'Testfeed'
    p.authors.append(Person("Lars Kiesow", "*****@*****.**"))
    p.website = 'http://example.com'
    p.copyright = 'cc-by'
    p.description = 'This is a cool feed!'
    p.language = 'de'
    p.feed_url = 'http://example.com/feeds/myfeed.rss'
    p.category = Category('Technology', 'Podcasting')
    p.explicit = False
    p.complete = False
    p.new_feed_url = 'http://example.com/new-feed.rss'
    p.owner = Person('John Doe', '*****@*****.**')
    p.xslt = "http://example.com/stylesheet.xsl"

    e1 = p.add_episode()
    e1.id = 'http://lernfunk.de/_MEDIAID_123#1'
    e1.title = 'First Element'
    e1.summary = htmlencode('''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Tamen
            aberramus a proposito, et, ne longius, prorsus, inquam, Piso, si ista
            mala sunt, placet. Aut etiam, ut vestitum, sic sententiam habeas aliam
            domesticam, aliam forensem, ut in fronte ostentatio sit, intus veritas
            occultetur? Cum id fugiunt, re eadem defendunt, quae Peripatetici,
            verba <3.''')
    e1.link = 'http://example.com'
    e1.authors = [Person('Lars Kiesow', '*****@*****.**')]
    e1.publication_date = datetime.datetime(2014, 5, 17, 13, 37, 10, tzinfo=pytz.utc)
    e1.media = Media("http://example.com/episodes/loremipsum.mp3", 454599964,
                     duration=
                     datetime.timedelta(hours=1, minutes=32, seconds=19))

    # Should we just print out, or write to file?
    if arg == 'rss':
        # Print
        print_enc(p.rss_str())
    elif arg.endswith('rss'):
        # Write to file
        p.rss_file(arg, minimize=True)
Beispiel #11
0
    def album(self):
        page = requests.get(self.album_url, headers=self.header)
        soup = BeautifulSoup(page.content, "lxml")

        # 初始化
        self.podcast = Podcast()
        self.podcast.name = soup.find('h1', 'title').get_text()
        self.podcast.authors.append(Person("Powered by forecho", '*****@*****.**'))
        self.podcast.website = self.album_url
        self.podcast.copyright = 'cc-by'
        if soup.find('div', 'album-intro') and soup.find('div', 'album-intro').get_text():
            self.podcast.description = soup.find('div', 'album-intro').get_text()
        else:
            self.podcast.description = self.podcast.name
        self.podcast.language = 'cn'
        self.podcast.image = soup.find('div', 'album-info').find('img').get('src').split('!')[0]
        self.podcast.feed_url = 'http://podcast.forecho.com/ximalaya/%s.rss' % self.album_id
        self.podcast.category = Category('Technology', 'Podcasting')
        self.podcast.explicit = False
        self.podcast.complete = False
        self.podcast.owner = Person("forecho", '*****@*****.**')

        album_list_content = requests.get(self.album_list_api, headers=self.header).content
        album_list_data = json.loads(album_list_content.decode('utf-8'))
        count = len(album_list_data['data']['tracksAudioPlay'])
        for each in album_list_data['data']['tracksAudioPlay']:
            try:
                detail_url = 'http://www.ximalaya.com/tracks/%s.json' % each['trackId']
                response = requests.get(detail_url, headers=self.header)
                item = json.loads(response.content)

                episode = self.podcast.add_episode()
                episode.id = str(each['index'])
                episode.title = each['trackName']
                print(self.podcast.name + '=====' + each['trackName'])
                image = each['trackCoverPath'].split('!')[0]
                if (image[-4:] == '.gif' or image[-4:] == '.bmp'):
                    episode.image = self.podcast.image
                else:
                    episode.image = image
                if item['intro']:
                    episode.summary = item['intro'].replace('\r\n', '')
                else:
                    episode.summary = each['trackName']
                episode.link = 'http://www.ximalaya.com%s' % each['albumUrl']
                episode.authors = [Person("forecho", '*****@*****.**')]
                episode.publication_date = self.reduction_time(item['time_until_now'], item['formatted_created_at'])
                episode.media = Media(each['src'], each['duration'])
                episode.position = count - each['index'] + 1
            except Exception as e:
                print('异常:', e)
                print('异常 URL:', 'http://www.ximalaya.com%s' % each['trackUrl'])
                traceback.print_exc()
            
        # 生成文件
        # print self.podcast.rss_str()
        self.podcast.rss_file('ximalaya/%s.rss' % self.album_id, minimize=True)
Beispiel #12
0
    def test_webMaster(self):
        self.fg.web_master = Person(None, "*****@*****.**")
        channel = self.fg._create_rss().find("channel")
        assert channel.find("webMaster").text == self.fg.web_master.email

        self.assertRaises(ValueError, setattr, self.fg, "web_master",
                          Person("Mr. No Email Address"))

        self.fg.web_master = Person("Both a name", "*****@*****.**")
        channel = self.fg._create_rss().find("channel")
        # Does webMaster follow the pattern "email (name)"?
        self.assertEqual(
            self.fg.web_master.email + " (" + self.fg.web_master.name + ")",
            channel.find("webMaster").text)
Beispiel #13
0
def main(event, context):
    dynamodb = boto3.resource('dynamodb', region_name='sa-east-1')

    table = dynamodb.Table('semservidor-dev')

    podcasts = table.scan()

    author = Person("Evandro Pires da Silva", "*****@*****.**")
    p = Podcast(
        name="Sem Servidor",
        description=
        "Podcast dedicado a arquitetura serverless, com conteúdo de qualidade em português.",
        website="https://semservidor.com.br",
        explicit=False,
        copyright="2020 Evandro Pires da Silva",
        language="pr-BR",
        authors=[author],
        feed_url=
        "https://3tz8r90j0d.execute-api.sa-east-1.amazonaws.com/dev/podcasts/rss",
        category=Category("Music", "Music History"),
        owner=author,
        image="http://d30gvsirhz3ono.cloudfront.net/logo_semservidor_teste.jpg",
        web_master=Person(None, "*****@*****.**"))

    items = podcasts['Items']
    for item in items:
        base_url = "http://d30gvsirhz3ono.cloudfront.net/"
        file_path = base_url + item['info']['arquivo']['nome']
        p.episodes += [
            Episode(title=item['info']['episodio'],
                    media=Media(file_path,
                                int(item['info']['arquivo']['tamanho'])),
                    summary=item['info']['descricao'],
                    position=int(item['id']))
        ]

    p.apply_episode_order()
    rss = p.rss_str()

    response = {
        "statusCode": 200,
        "headers": {
            "content-type": "application/xml"
        },
        "body": rss
    }

    return response
    def populate(self, episode) -> None:
        metadata = self.data[self._get_key(episode)]

        for attribute, value in metadata.items():
            if hasattr(episode, attribute):
                if attribute == "publication_date":
                    try:
                        episode.publication_date = datetime.strptime(metadata['publication_date'], "%Y-%m-%d %H:%M:%S %z")
                    except ValueError:
                        logger.warning("Date %s in file %s could not be parsed, so it was ignored. "
                            "Make sure it's on the following form (±HHMM being timezone offset): "
                            "YYYY-MM-DD HH:MM:SS ±HHMM", metadata['date'], self._config_file)
                elif attribute == "authors":
                    authors = [Person(p.get('name'), p.get('email')) for p in value]
                    episode.authors = authors
                elif attribute.startswith("media."):
                    media_attribute = attribute[6:]
                    if media_attribute == "duration":
                        # Convert to datetime.timedelta
                        splitted = value.split(":")
                        if len(splitted) == 3:
                            duration = timedelta(hours=splitted[0],
                                minutes=splitted[1], seconds=splitted[2])
                        else:
                            duration = timedelta(minutes=splitted[0],
                                                 seconds=splitted[1])
                        episode.media.duration = duration
                    else:
                        setattr(episode.media, media_attribute, value)
                else:
                    setattr(episode, attribute, value)
            else:
                logger.warning("WARNING %s: Attribute %s for %s was not recognized.",
                      self._source_name, attribute, episode.media.url)
    def episode(self, show, episode_dict):
        # Find the publication date
        publication_datetime_str = str(episode_dict['dato']) + " 00:00:00"
        publication_datetime_format = "%Y%m%d %H:%M:%S"
        # Start out with midnight
        publication_date = datetime.datetime.strptime(
            publication_datetime_str, publication_datetime_format)
        # Then go to the specified time
        publication_datetime_naive = \
            publication_date + datetime.timedelta(seconds=episode_dict['time'])
        # And associate a timezone with that datetime
        timezone = pytz.timezone("Europe/Oslo")
        publication_datetime_aware = \
            timezone.localize(publication_datetime_naive)

        # Create our episode object
        return Episode(
            show=show,
            media=Media(episode_dict['url'], episode_dict['filesize'], None,
                        datetime.timedelta(seconds=episode_dict['duration'])),
            id="radiorevolt.no/podkast/episode/" + str(episode_dict['id']),
            deprecated_url=episode_dict['deprecated_url'],
            title=episode_dict['title'],
            long_summary=linkify(htmlencode(episode_dict['comment'])).replace(
                "\n", "<br/>\n"),
            publication_date=publication_datetime_aware,
            authors=[Person(name=episode_dict['author'])]
            if episode_dict['author'] else [],
        )
Beispiel #16
0
    def test_constructor(self):
        title = "A constructed episode"
        subtitle = "We're using the constructor!"
        summary = "In this week's episode, we try using the constructor to " \
                  "create a new Episode object."
        long_summary = "In this week's episode, we try to use the constructor " \
                       "to create a new Episode object. Additionally, we'll " \
                       "check whether it actually worked or not. Hold your " \
                       "fingers crossed!"
        media = Media("http://example.com/episodes/1.mp3", 1425345346,
                      "audio/mpeg",
                      datetime.timedelta(hours=1, minutes=2, seconds=22))
        publication_date = datetime.datetime(2016,
                                             6,
                                             7,
                                             13,
                                             37,
                                             0,
                                             tzinfo=pytz.utc)
        link = "http://example.com/blog/?i=1"
        authors = [Person("John Doe", "*****@*****.**")]
        image = "http://example.com/static/1.png"
        explicit = True
        is_closed_captioned = False
        position = 3
        withhold_from_itunes = True

        ep = Episode(
            title=title,
            subtitle=subtitle,
            summary=summary,
            long_summary=long_summary,
            media=media,
            publication_date=publication_date,
            link=link,
            authors=authors,
            image=image,
            explicit=explicit,
            is_closed_captioned=is_closed_captioned,
            position=position,
            withhold_from_itunes=withhold_from_itunes,
        )

        # Time to check if this works
        self.assertEqual(ep.title, title)
        self.assertEqual(ep.subtitle, subtitle)
        self.assertEqual(ep.summary, summary)
        self.assertEqual(ep.long_summary, long_summary)
        self.assertEqual(ep.media, media)
        self.assertEqual(ep.publication_date, publication_date)
        self.assertEqual(ep.link, link)
        self.assertEqual(ep.authors, authors)
        self.assertEqual(ep.image, image)
        self.assertEqual(ep.explicit, explicit)
        self.assertEqual(ep.is_closed_captioned, is_closed_captioned)
        self.assertEqual(ep.position, position)
        self.assertEqual(ep.withhold_from_itunes, withhold_from_itunes)
Beispiel #17
0
 def test_AuthorEmail(self):
     # Just email - so use managingEditor, not dc:creator or itunes:author
     # This is per the RSS best practices, see the section about dc:creator
     self.fg.authors = [Person(None, "*****@*****.**")]
     channel = self.fg._create_rss().find("channel")
     # managingEditor uses email?
     assert channel.find("managingEditor").text == self.fg.authors[0].email
     # No dc:creator?
     assert channel.find("{%s}creator" % self.nsDc) is None
     # No itunes:author?
     assert channel.find("{%s}author" % self.nsItunes) is None
Beispiel #18
0
    def test_oneAuthorWithoutName(self):
        email = "*****@*****.**"
        self.fe.authors.extend([Person(email=email)])
        entry = self.fe.rss_entry()

        # Test that rss author is the email
        assert entry.find("author").text == email
        # Test that itunes:author is not used, since it requires name
        assert entry.find("{%s}author" % self.itunes_ns) is None
        # Test that dc:creator is not used, since it would duplicate rss author
        assert entry.find("{%s}creator" % self.dublin_ns) is None
Beispiel #19
0
    def test_oneAuthorWithoutEmail(self):
        name = "John Doe"
        self.fe.authors.append(Person(name))
        entry = self.fe.rss_entry()

        # Test that author is not used, since it requires email
        assert entry.find("author") is None
        # Test that itunes:author is still the name
        assert entry.find("{%s}author" % self.itunes_ns).text == name
        # Test that dc:creator is used in rss author's place (since dc:creator
        # doesn't require email)
        assert entry.find("{%s}creator" % self.dublin_ns).text == name
Beispiel #20
0
 def test_AuthorName(self):
     # Just name - use dc:creator and itunes:author, not managingEditor
     self.fg.authors = [Person("Just a. Name")]
     channel = self.fg._create_rss().find("channel")
     # No managingEditor?
     assert channel.find("managingEditor") is None
     # dc:creator equals name?
     assert channel.find("{%s}creator" % self.nsDc).text == \
            self.fg.authors[0].name
     # itunes:author equals name?
     assert channel.find("{%s}author" % self.nsItunes).text == \
         self.fg.authors[0].name
Beispiel #21
0
    def test_oneAuthor(self):
        name = "John Doe"
        email = "*****@*****.**"
        self.fe.authors = [Person(name, email)]
        author_text = self.fe.rss_entry().find("author").text
        assert name in author_text
        assert email in author_text

        # Test that itunes:author is the name
        assert self.fe.rss_entry().find("{%s}author" % self.itunes_ns).text\
            == name
        # Test that dc:creator is not used when rss author does the same job
        assert self.fe.rss_entry().find("{%s}creator" % self.dublin_ns) is None
Beispiel #22
0
def create_podcast(name, desc, website):
    p = Podcast()
    #if not res:
    p.name = name
    p.description = desc
    p.authors = [Person("Dawn News", "*****@*****.**")]
    p.website = website
    p.image = "http://3.15.38.214/zarahatkay/cover_art.png"
    p.language = "en-US"
    p.feed_url = "http://3.15.38.214/zarahatkay"
    p.category = Category("News &amp; Politics")
    p.explicit = False
    return p
    def populate(self, show) -> None:
        metadata = self.data[self._get_key(show)]

        for attribute, value in metadata.items():
            if hasattr(show, attribute):
                if attribute in ("publication_date", "last_updated"):
                    try:
                        setattr(show, attribute,
                                strptime(value, "%Y-%m-%d %H:%M:%S %z"))
                    except ValueError:
                        logger.warning(
                            "Date %(date)s in file %(file)s could not be parsed, so it was ignored.\n"
                            "Make sure it's on the following form (±HHMM being timezone offset):\n"
                            "    YYYY-MM-DD HH:MM:SS ±HHMM", {
                                "date": metadata['date'],
                                "file": self._config_file
                            })
                elif attribute == "authors":
                    authors = [
                        Person(p.get('name'), p.get('email')) for p in value
                    ]
                    show.authors = authors
                elif attribute == "web_master":
                    show.web_master = Person(value.get('name'),
                                             value.get('email'))
                elif attribute == "category":
                    if len(value) == 2:
                        show.category = Category(value[0], value[1])
                    else:
                        show.category = Category(value[0])
                else:
                    setattr(show, attribute, value)
            else:
                logger.warning(
                    "Attribute %(keys)s for %(id)s was not recognized.", {
                        "id": show.id,
                        "keys": attribute
                    })
Beispiel #24
0
 def test_AuthorNameAndEmail(self):
     # Both name and email - use managingEditor and itunes:author,
     # not dc:creator
     self.fg.authors = [Person("Both a name", "*****@*****.**")]
     channel = self.fg._create_rss().find("channel")
     # Does managingEditor follow the pattern "email (name)"?
     self.assertEqual(
         self.fg.authors[0].email + " (" + self.fg.authors[0].name + ")",
         channel.find("managingEditor").text)
     # No dc:creator?
     assert channel.find("{%s}creator" % self.nsDc) is None
     # itunes:author uses name only?
     assert channel.find("{%s}author" % self.nsItunes).text == \
         self.fg.authors[0].name
Beispiel #25
0
def generate_rss_from_articles(feed_settings, articles):
    """
    Creates a FeedGenerator feed from a set of feed_entries.

    :param feed_settings: a feed_settings object containing
    :param articles:
    :return:
    """
    # Initialize the feed
    podcast = Podcast()
    podcast.name = feed_settings.title
    author = Person(feed_settings.author['name'], feed_settings.author['email'])
    podcast.authors.append(author)
    podcast.website = feed_settings.source_page_url
    podcast.copyright = feed_settings.copyright
    podcast.description = feed_settings.subtitle
    podcast.summary = feed_settings.subtitle
    podcast.subtitle = feed_settings.subtitle
    podcast.language = 'vi'
    podcast.feed_url = feed_settings.output_url
    podcast.image = feed_settings.img_url
    podcast.category = Category('Music', 'Music Commentary')
    podcast.explicit = False
    # p.complete = False
    # p.new_feed_url = 'http://example.com/new-feed.rss'
    podcast.owner = author
    # p.xslt = "http://example.com/stylesheet.xsl"

    vt_tz = pytz.timezone('Asia/Ho_Chi_Minh')
    pastdate = datetime.datetime(2000, 1, 1, 0, 0).astimezone(vt_tz)
    # podcast.last_updated = datetime.datetime.now(vt_tz)

    for article in articles:
        episode = podcast.add_episode()
        episode.id = article.link
        episode.title = article.title
        episode.summary = article.description
        episode.link = article.link
        # episode.authors = [Person('Lars Kiesow', '*****@*****.**')]
        episode.publication_date = article.pub_date
        pastdate = max(pastdate, article.pub_date)
        # episode.media = Media.create_from_server_response(article.media, size=None, duration=None)
        episode.media = Media(article.media, size=None, duration=None, type=article.type)

    podcast.last_updated = pastdate
    podcast.publication_date = pastdate

    return podcast
Beispiel #26
0
    def detail(self, sound_id, date):
        detail_url = 'http://www.ximalaya.com/tracks/%s.json' % sound_id
        response = requests.get(detail_url, headers=self.header)
        item = json.loads(response.content)

        episode = self.podcast.add_episode()
        episode.id = str(item['id'])
        episode.title = item['title']
        episode.image = item['cover_url_142'].split('?')[0]
        episode.summary = (item['intro'].replace('\n', '') if item['intro'] else '')
        episode.link = 'http://www.ximalaya.com/sound/%d' % item['id']
        episode.authors = [Person("forecho", '*****@*****.**')]
        episode.publication_date = self.reduction_time(
            date, item['formatted_created_at'])
        episode.media = Media(item['play_path_64'], 454599964)
        print self.podcast.name + '=====' + item['title']
Beispiel #27
0
    def generate_podcast(self, feed_name: str) -> str:
        """
        Create podcast XML based on the files found in podcastDir. Taken from
        https://podgen.readthedocs.io/en/latest/usage_guide/podcasts.html

        :param self: PodcastService class
        :param feed_name: name of the feed and the sub-directory for files
        :return:  string of the podcast
        """
        # Initialize the feed
        p = Podcast()

        # Required fields
        p.name = f'{feed_name} Archive'
        p.description = 'Stuff to listen to later'
        p.website = self.base_url
        p.complete = False

        # Optional
        p.language = 'en-US'
        p.feed_url = f'{p.website}/feeds/{feed_name}/rss'
        p.explicit = False
        p.authors.append(Person("Anthology"))

        # for filepath in glob.iglob(f'{self.search_dir}/{feed_name}/*.mp3'):
        for path in Path(f'{self.search_dir}/{feed_name}').glob('**/*.mp3'):
            filepath = str(path)
            episode = p.add_episode()

            # Attempt to load saved metadata
            metadata_file_name = filepath.replace('.mp3', '.json')
            try:
                with open(metadata_file_name) as metadata_file:
                    metadata = json.load(metadata_file)
            except FileNotFoundError:
                metadata = {}
            except JSONDecodeError:
                metadata = {}
                self.logger.error(f'Failed to read {metadata_file_name}')

            # Build the episode based on either the saved metadata or the file details
            episode.title = metadata.get(
                'title',
                filepath.split('/')[-1].rstrip('.mp3'))
            episode.summary = metadata.get('summary',
                                           htmlencode('Some Summary'))
            if 'link' in metadata:
                episode.link = metadata.get('link')
            if 'authors' in metadata:
                episode.authors = [
                    Person(author) for author in metadata.get('authors')
                ]
            episode.publication_date = \
                isoparse(metadata.get('publication_date')) if 'publication_date' in metadata \
                else datetime.fromtimestamp(os.path.getmtime(filepath), tz=pytz.utc)
            episode.media = Media(
                f'{p.website}/{filepath.lstrip(self.search_dir)}'.replace(
                    ' ', '+'), os.path.getsize(filepath))
            episode.media.populate_duration_from(filepath)

            if "image" in metadata:
                episode.image = metadata.get('image')
            else:
                for ext in ['.jpg', '.png']:
                    image_file_name = filepath.replace('.mp3', ext)
                    if os.path.isfile(image_file_name):
                        episode.image = f'{p.website}/{image_file_name.lstrip(self.search_dir)}'.replace(
                            ' ', '+')
                        break

            # Save the metadata for future editing
            if not os.path.exists(metadata_file_name):
                metadata = {
                    'title': episode.title,
                    'summary': episode.summary,
                    'publication_date': episode.publication_date,
                    'authors': episode.authors
                }
                with open(metadata_file_name, 'w') as outFile:
                    json.dump(metadata, outFile, indent=2, default=str)

        return p.rss_str()
Beispiel #28
0
    def album(self):
        album_info = requests.get(self.album_info_url.format(self.album_id),
                                  headers=self.header).content
        album_info_content = json.loads(album_info.decode('utf-8'))
        if album_info_content['ret'] == 200:
            album_info_data = album_info_content['data']

            # 初始化
            self.podcast = Podcast()
            self.podcast.name = album_info_data['mainInfo']['albumTitle']
            self.podcast.authors.append(
                Person("Powered by forecho", '*****@*****.**'))
            self.podcast.website = self.album_url.format(self.album_id)
            self.podcast.copyright = 'cc-by'
            if album_info_data['mainInfo']['richIntro']:
                self.podcast.description = album_info_data['mainInfo'][
                    'richIntro']
            else:
                self.podcast.description = self.podcast.name
            self.podcast.language = 'cn'
            self.podcast.image = 'https:' + album_info_data['mainInfo'][
                'cover'].split('!')[0]
            self.podcast.feed_url = 'http://podcast.forecho.com/ximalaya/%s.rss' % self.album_id
            self.podcast.category = Category('Technology', 'Podcasting')
            self.podcast.explicit = False
            self.podcast.complete = False
            self.podcast.owner = Person("forecho", '*****@*****.**')
            page_num = 1
            # py2 +1
            track_total_count = math.ceil(
                album_info_data['tracksInfo']['trackTotalCount'] /
                self.page_size) + 1
            while page_num <= track_total_count:
                album_list = requests.get(self.album_list_url.format(
                    self.album_id, page_num, self.page_size),
                                          headers=self.header).content
                album_list_content = json.loads(album_list.decode('utf-8'))
                count = len(album_list_content['data']['tracksAudioPlay'])
                for each in album_list_content['data']['tracksAudioPlay']:
                    try:
                        detail = requests.get(self.detail_url.format(
                            each['trackId']),
                                              headers=self.header).content
                        detail_content = json.loads(detail.decode('utf-8'))
                        episode = self.podcast.add_episode()
                        episode.id = str(each['index'])
                        episode.title = each['trackName']
                        print(self.podcast.name + '=====' + each['trackName'])
                        image = each['trackCoverPath'].split('!')[0]
                        if image[-4:] == '.png' or image[-4:] == '.jpg':
                            episode.image = 'https:' + image
                        else:
                            episode.image = self.podcast.image
                        if 'intro' in detail_content:
                            episode.summary = detail_content['intro'].replace(
                                '\r\n', '')
                        else:
                            episode.summary = each['trackName']
                        episode.link = 'http://www.ximalaya.com%s' % each[
                            'albumUrl']
                        episode.authors = [
                            Person("forecho", '*****@*****.**')
                        ]
                        episode.publication_date = self.reduction_time(
                            detail_content['createdAt'])
                        episode.media = Media(each['src'], each['duration'])
                        episode.position = count - each['index'] + 1
                    except Exception as e:
                        print('异常:', e)
                        print('异常 URL:',
                              'https://www.ximalaya.com%s' % each['trackUrl'])
                        traceback.print_exc()
                # 生成文件
                # print self.podcast.rss_str()
                page_num = page_num + 1
            self.podcast.rss_file('ximalaya/%s.rss' % self.album_id,
                                  minimize=True)
Beispiel #29
0
 def do_authorsInvalidAssignment(self):
     self.fe.authors = Person("Oh No", "*****@*****.**")
print('>>> wrote fresh sessions.json file')

# write the new rss file
p = Podcast()

p.name = "The Objectivism Seminar"
p.category = Category("Society &amp; Culture", "Philosophy")
p.language = "en-US"
p.explicit = True
p.description = (
    "A weekly online conference call to systematically study " +
    "the philosophy of Objectivism via the works of prominent Rand scholars.")
p.website = "https://www.ObjectivismSeminar.com"
p.image = "https://www.ObjectivismSeminar.com/assets/images/atlas-square.jpg"
p.feed_url = "https://www.ObjectivismSeminar.com/archives/rss"
p.authors = [Person("Greg Perkins, Host", "*****@*****.**")]
p.owner = Person("Greg Perkins", "*****@*****.**")

p.episodes += [
    Episode(title=x['title'],
            media=Media(x['link'], type="audio/mpeg", size=x['length']),
            id=x['GUID'],
            publication_date=x['pubDate'],
            summary=x['description']) for x in updated_session_items
]

p.rss_file(rss_filename)

print('>>> wrote fresh rss.xml file')
Beispiel #31
0
    def setUp(self):
        self.existing_locale = locale.setlocale(locale.LC_ALL, None)
        locale.setlocale(locale.LC_ALL, 'C')

        fg = Podcast()

        self.nsContent = "http://purl.org/rss/1.0/modules/content/"
        self.nsDc = "http://purl.org/dc/elements/1.1/"
        self.nsItunes = "http://www.itunes.com/dtds/podcast-1.0.dtd"
        self.feed_url = "http://example.com/feeds/myfeed.rss"

        self.name = 'Some Testfeed'

        # Use character not in ASCII to catch encoding errors
        self.author = Person('Jon Døll', '*****@*****.**')

        self.website = 'http://example.com'
        self.description = 'This is a cool feed!'
        self.subtitle = 'Coolest of all'

        self.language = 'en'

        self.cloudDomain = 'example.com'
        self.cloudPort = '4711'
        self.cloudPath = '/ws/example'
        self.cloudRegisterProcedure = 'registerProcedure'
        self.cloudProtocol = 'SOAP 1.1'

        self.pubsubhubbub = "http://pubsubhubbub.example.com/"

        self.contributor = {
            'name': "Contributor Name",
            'email': 'Contributor email'
        }
        self.copyright = "The copyright notice"
        self.docs = 'http://www.rssboard.org/rss-specification'
        self.skip_days = set(['Tuesday'])
        self.skip_hours = set([23])

        self.explicit = False

        self.programname = podgen.version.name

        self.web_master = Person(email='*****@*****.**')
        self.image = "http://example.com/static/podcast.png"
        self.owner = self.author
        self.complete = True
        self.new_feed_url = "https://example.com/feeds/myfeed2.rss"
        self.xslt = "http://example.com/feed/stylesheet.xsl"

        fg.name = self.name
        fg.website = self.website
        fg.description = self.description
        fg.subtitle = self.subtitle
        fg.language = self.language
        fg.cloud = (self.cloudDomain, self.cloudPort, self.cloudPath,
                    self.cloudRegisterProcedure, self.cloudProtocol)
        fg.pubsubhubbub = self.pubsubhubbub
        fg.copyright = self.copyright
        fg.authors.append(self.author)
        fg.skip_days = self.skip_days
        fg.skip_hours = self.skip_hours
        fg.web_master = self.web_master
        fg.feed_url = self.feed_url
        fg.explicit = self.explicit
        fg.image = self.image
        fg.owner = self.owner
        fg.complete = self.complete
        fg.new_feed_url = self.new_feed_url
        fg.xslt = self.xslt

        self.fg = fg

        warnings.simplefilter("always")

        def noop(*args, **kwargs):
            pass

        warnings.showwarning = noop
Beispiel #32
0
 def do_authorsInvalidValue(self):
     self.fg.authors = Person("Opsie", "*****@*****.**")