示例#1
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)
示例#2
0
    def test_immutable(self):
        c = Category("Arts", "Food")
        self.assertRaises(AttributeError, setattr, c, "category", "Technology")
        self.assertEqual(c.category, "Arts")

        self.assertRaises(AttributeError, setattr, c, "subcategory", "Design")
        self.assertEqual(c.subcategory, "Food")
示例#3
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)
    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'))
示例#5
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)
示例#6
0
    def test_immutable(self):
        c = Category("Arts", "Food")
        self.assertRaises(AttributeError, setattr, c, "category", "Fiction")
        self.assertEqual(c.category, "Arts")

        self.assertRaises(AttributeError, setattr, c, "subcategory",
                          "Science Fiction")
        self.assertEqual(c.subcategory, "Food")
示例#7
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)
示例#8
0
 def test_categoryWithSubcategory(self):
     c = Category("Arts", "Food")
     self.fg.category = c
     channel = self.fg._create_rss().find("channel")
     itunes_category = channel.find("{%s}category" % self.nsItunes)
     assert itunes_category is not None
     itunes_subcategory = itunes_category\
         .find("{%s}category" % self.nsItunes)
     assert itunes_subcategory is not None
     self.assertEqual(itunes_subcategory.get("text"), c.subcategory)
示例#9
0
    def test_oldCategoryIsAcceptedWithWarning(self):
        # Replacement of assertWarns in Python 2.7
        with warnings.catch_warnings(record=True) as w:
            # Replacement of assertWarns in Python 2.7
            warnings.simplefilter("always", LegacyCategoryWarning)

            c = Category("Government & Organizations")
            self.assertEqual(c.category, "Government & Organizations")

            # Replacement of assertWarns in Python 2.7
            self.assertEqual(len(w), 1)
            self.assertIsInstance(w[0].message, LegacyCategoryWarning)
示例#10
0
def rssfeed(request, programid):
    """ Builds the rss feed for a program identified by it's id. (int)

    1. Fetches all episodes of the program from the digas db.
    2. gets the programinfo from the app db
    3. Uses podgen to do the actual XML-generation.
    """
    podcasts = DigasPodcast.objects.using('digas').filter(
        softdel=0,
        program=int(programid)).only('program', 'title', 'remark', 'author',
                                     'createdate', 'broadcastdate', 'filename',
                                     'filesize', 'duration',
                                     'softdel').order_by('-createdate')
    programinfo = ProgramInfo.objects.get(programid=int(programid))

    # loading globalsettings here, and not at the module_level
    # This way django won't explode because of missing
    # constance_config table when we start on scratch
    # or set up in a new environment.
    from .models import globalsettings

    p = Podcast(
        name=programinfo.name,
        subtitle=programinfo.subtitle,
        description=programinfo.description,
        website=feed_url(programid),  # programinfo.website,
        explicit=programinfo.explicit,
        category=Category(programinfo.category),
        authors=[globalsettings.owner],
        language=programinfo.language,
        owner=globalsettings.owner,
        feed_url=feed_url(programid),
        new_feed_url=feed_url(programid),
        image=programinfo.image_url,
    )

    for episode in podcasts:
        # Get pubdate from createdate or broadcastdate
        pubdate = digas2pubdate(episode.createdate, episode.broadcastdate)
        # Add the episode to the list
        p.episodes.append(
            Episode(
                title=episode.title,
                media=Media(mp3url(episode.filename), episode.filesize),
                link=mp3url(episode.filename),  # multifeedreader uses this.
                id=guid(episode.filename),
                summary=episode.remark,
                publication_date=pubdate))

    # send it as unicode
    rss = u'%s' % p
    return HttpResponse(rss, content_type='application/xml')
示例#11
0
    def test_oldSubcategoryIsAcceptedWithWarnings(self):
        # Replacement of assertWarns in Python 2.7
        with warnings.catch_warnings(record=True) as w:
            # Replacement of assertWarns in Python 2.7
            warnings.simplefilter("always", LegacyCategoryWarning)

            c = Category("Technology", "Podcasting")
            self.assertEqual(c.category, "Technology")
            self.assertEqual(c.subcategory, "Podcasting")

            # Replacement of assertWarns in Python 2.7
            self.assertEqual(len(w), 1)
            self.assertIsInstance(w[0].message, LegacyCategoryWarning)
示例#12
0
    def test_constructorWithSubcategory(self):
        # Replacement of assertWarns in Python 2.7
        with warnings.catch_warnings(record=True) as w:
            # Replacement of assertWarns in Python 2.7
            warnings.simplefilter("always", LegacyCategoryWarning)

            c = Category("Arts", "Food")
            self.assertEqual(c.category, "Arts")
            self.assertEqual(c.subcategory, "Food")

            # No warning should be given
            # Replacement of assertWarns in Python 2.7
            self.assertEqual(len(w), 0)
示例#13
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
                    })
示例#15
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
示例#16
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
示例#17
0
 def test_escapedIsAccepted(self):
     c = Category("Sports &amp; Recreation", "College &amp; High School")
     self.assertEqual(c.category, "Sports & Recreation")
     self.assertEqual(c.subcategory, "College & High School")
示例#18
0
def create_rss(type, download):
    """Create an example podcast and print it or save it to a file."""
    
    # Create the Podcast & initialize the feed
    default_channel = Channel.defaultChannel()
    
    p = Podcast()
    p.name          = default_channel.name
    p.description   = default_channel.description
    p.website       = default_channel.website
    p.explicit      = default_channel.explicit
    p.image         = default_channel.image

    p.copyright     = default_channel.copyright
    p.language      = default_channel.language
    p.feed_url      = default_channel.feed_url
    p.category      = Category(default_channel.category)
    # p.category = Category('Technology', 'Podcasting')
    # p.xslt      = "https://example.com/feed/stylesheet.xsl"  # URL of XSLT stylesheet

    p.authors   = [Person(default_channel.authors, default_channel.authors_email)]
    p.owner     = Person(default_channel.owner, default_channel.owner_email)

    # Other Attributes
    p.generator = " "
    
    # Others for iTunes
    # p.complete = False
    # p.new_feed_url = 'http://example.com/new-feed.rss'

    # 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))
    # e1.media = Media("http://example.com/episodes/loremipsum.mp3", 454599964)

    # Add some episodes
    p.episodes += [
       Episode(title = download.title, 
            subtitle = download.subtitle,
            # id=str(uuid.uuid4()),
            position =2,
            media = Media(download.media_url, size=download.media_size, duration=timedelta(seconds=download.media_duration)),
            image = download.image_url,
            publication_date = datetime(year=2021, month=1, day=8, hour=10, minute=0, tzinfo=pytz.utc),
            summary = download.summary)
    ,
       Episode(title="Episode 2 - The Crazy Ones",
            subtitle="this is a cool episode, this is for th crazy ones",
            position=1,
            image="https://github.com/oliverbarreto/PersonalPodcast/raw/main/site-logo-1400x1400.png",
            media=Media("https://github.com/oliverbarreto/PersonalPodcast/raw/main/downloaded_with_pytube_Apple%20Steve%20Jobs%20Heres%20To%20The%20Crazy%20Ones.mp4", type="audio/mpeg", size=989, duration=timedelta(hours=0, minutes=1, seconds=1)),
            publication_date = datetime(year=2021, month=1, day=6, hour=10, minute=0, tzinfo=pytz.utc),
            summary=htmlencode("wow wow wow summary"))
    ,
        Episode(title="Episode 3 - The Super Crazy",
            subtitle="crazy ones revisited",
            position=0,
            image="https://github.com/oliverbarreto/PersonalPodcast/raw/main/site-logo-1400x1400.png",
            media=Media("https://drive.google.com/file/d/1X5Mwa8V0Su1IDqhcQL7LdzEY0VaMC1Nn", type="audio/mpeg", size=989, duration=timedelta(hours=0, minutes=1, seconds=1)),
            publication_date = datetime(year=2021, month=1, day=10, hour=10, minute=0, tzinfo=pytz.utc),
            summary=download.summary)
    ]

    # Should we just print out, or write to file?
    if type == 'print':
        # Print
        print_enc(p.rss_str())
    elif type== 'feed.xml':
        # Write to file
        p.rss_file(type, minimize=False)
        print("\n")
        print("feed.xml created !!!")
示例#19
0
 def test_constructorCaseInsensitive(self):
     c = Category("arTS", "FOOD")
     self.assertEqual(c.category, "Arts")
     self.assertEqual(c.subcategory, "Food")
示例#20
0
 def test_constructorWithoutSubcategory(self):
     c = Category("Arts")
     self.assertEqual(c.category, "Arts")
     self.assertTrue(c.subcategory is None)
示例#21
0
 def test_constructorWithSubcategory(self):
     c = Category("Arts", "Food")
     self.assertEqual(c.category, "Arts")
     self.assertEqual(c.subcategory, "Food")
示例#22
0
                'filename': file_local_path,
                'name': video.title
            })
        except HTTPError as err:
            print('Can not parse this video bacause of HTTPError.')

# Create Podcast object and fill it with episodes
podcast_object = Podcast(
    name=CONFIG['podcast_name'],
    description=CONFIG['podcast_description'],
    website=CONFIG['podcast_website'],
    explicit=False,
    image=CONFIG['podcast_image'],
    language=CONFIG['podcast_language'],
    authors=[Person(CONFIG['podcast_author'], CONFIG['podcast_author_email'])],
    owner=Person(CONFIG['podcast_owner'], CONFIG['podcast_owner_email']),
    category=Category(CONFIG['podcast_category'],
                      CONFIG['podcast_subcategory']))

for item in db:
    web_media_path = "%s/podcast_%s.mp4" % (CONFIG['podcast_media_server'],
                                            item['link'][9:])
    podcast_object.add_episode(
        Episode(title=item['name'],
                media=Media(web_media_path,
                            os.stat(item['filename']).st_size,
                            type="audio/mpeg")))

# Generating RSS
podcast_object.rss_file(('%s/rss.xml' % CONFIG['data_path']), minimize=True)
示例#23
0
def generate(name, description, website, explicit, image, author_name,
             author_email, feed_path, copyright, language, category, blog,
             blog_path, verbose, folder):
    """Generate a podcast from mp3 files located in the provided FOLDER"""
    if verbose:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    attrs = locals()
    logging.debug('Processing input: %s' % (attrs))
    del attrs['folder']
    del attrs['author_name']
    del attrs['author_email']
    del attrs['verbose']
    del attrs['feed_path']
    del attrs['blog']
    del attrs['blog_path']

    attrs['authors'] = [Person(author_name, author_email)]
    attrs['owner'] = attrs['authors'][0]

    attrs['category'] = Category(category)

    feed_name = name.lower().replace(' ', '_') + '.rss'
    feed_base = '%s/%s' % (website, feed_path)
    feed_url = '%s/%s' % (feed_base, feed_name)
    attrs['feed_url'] = feed_url

    logging.info('Creating podcast %s, feed %s' % (name, feed_url))
    p = Podcast(**attrs)

    for fpath in sorted(glob.glob('%s*.mp3' % (folder))):
        logging.info('Adding episode %s' % (fpath))
        fname = os.path.basename(fpath)
        size = os.path.getsize(fpath)
        logging.debug('Filename: %s, size %i' % (fname, size))
        try:
            tag = ID3(fpath)
        except ID3NoHeaderError:
            logging.error('%s is not a valid mp3 file, ignoring it' % (fpath))
            continue
        logging.debug('Read tag: %s' % (tag))
        e = Episode()
        if 'TPE1' in tag:
            e.authors = [Person(tag['TPE1'][0])]
        else:
            e.authors = attrs['authors']
        e.title = tag['TIT2'][0]
        e.subtitle = e.title
        if 'COMM::eng' in tag:
            e.summary = tag['COMM::eng'][0]
        else:
            e.summary = description
        episode_url = '%s/%s' % (feed_base, fname)
        logging.debug('Episode url: %s' % (episode_url))
        e.media = Media(episode_url, size, type='audio/mpeg')
        e.media.populate_duration_from(fpath)
        pubdate = datetime.strptime(tag['TDRC'][0].text[:10], '%Y-%m-%d')
        pubdate = pubdate.replace(tzinfo=pytz.utc)
        e.publication_date = pubdate
        if blog:
            blog_post = ''
            short_name = re.search('[a-z]*_-_([a-z_]*[#0-9]*)', fname)
            if short_name:
                blog_post = short_name.group(1).replace('_', '-').\
                    replace('#', '') + '.html'
                e.link = '%s/%s/%s' % (website, blog_path, blog_post)
        p.episodes.append(e)

    feed_local_path = '%s%s' % (folder, feed_name)
    logging.info('Generating feed in %s' % (feed_local_path))
    p.rss_file(feed_local_path, minimize=False)
示例#24
0
 def test_escapedIsAccepted(self):
     c = Category("Kids &amp; Family", "Pets &amp; Animals")
     self.assertEqual(c.category, "Kids & Family")
     self.assertEqual(c.subcategory, "Pets & Animals")
示例#25
0
# write the new sessions json file
updated_session_items = new_items + session_items

for item in updated_session_items:
    item['link'] = f'{ipfs_prefix}{item["CID"]}{ipfs_suffix}'

with open(sessions_filename, 'w') as outfile:
    json.dump(updated_session_items, outfile, indent=2)

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'],
示例#26
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)
def lambda_handler(event, context):
    print('Starting cccRssBuilder Lambda function')
    # Get episodes from DynamoDB
    episodes = query_episodes()
    episodes.sort(key=lambda x: x['episode-num'])

    # Create the podcast feed
    # Main podcast info comes from "episode 0"
    episodeInfo = episodes[0]
    separator = ', '
    p = Podcast()
    p.name = episodeInfo['name']
    p.description = episodeInfo['description']
    p.website = episodeInfo['website']
    p.explicit = episodeInfo['explicit']
    p.image = episodeInfo['image']
    p.feed_url = episodeInfo['feed-url']
    p.language = episodeInfo['language']
    p.category = Category(episodeInfo['category'], episodeInfo['subcategory'])
    p.owner = Person(episodeInfo['owner-name'], episodeInfo['owner-email'])
    p.authors = [Person(episodeInfo['owner-name'], episodeInfo['owner-email'])]

    # Process each episode
    for episode in episodes:
        # Skip "Episode 0"
        if episode['episode-num'] == 0:
            continue
        # Check if episode contains media file info (name, duration, size).  If not, add it to db and episode object.
        if 'media-file' not in episode:
            episodeNum = episode['episode-num']
            print('Analyzing media file for episode', episodeNum)
            mediaFile = 'ccc-{:03d}-{}.mp3'.format(int(episodeNum),
                                                   episode['pub-date'])
            print('Media file:', mediaFile)
            localMediaFile = '/tmp/' + mediaFile
            s3 = boto3.client('s3')
            s3.download_file('kwksolutions.com', 'ccc/media/' + mediaFile,
                             localMediaFile)

            # Try to analyze the mp3 file - looking for duration and file size
            try:
                audio = MP3(localMediaFile)
            except:
                print('Not an MP3 file!')
                return
            duration = round(audio.info.length)
            hours = int(duration / 3600)
            minutes = int((duration % 3600) / 60)
            seconds = duration % 60
            if hours == 0:
                durationStr = '{:02d}:{:02d}'.format(minutes, seconds)
            else:
                durationStr = '{:02d}:{:02d}:{:02d}'.format(
                    hours, minutes, seconds)
            size = str(os.path.getsize(localMediaFile))
            update_episode(episodeNum, mediaFile, size, durationStr)
            episode['media-file'] = mediaFile
            episode['size'] = size
            episode['duration'] = durationStr

        # Figure out all the info needed for the episode object
        mediaURL = 'https://www.kwksolutions.com/ccc/media/' + episode[
            'media-file']
        durationList = episode['duration'].split(':')
        secs = int(durationList[-1])
        mins = int(durationList[-2])
        try:
            h = int(durationList[-3])
        except:
            h = 0
        pubdateList = episode['pub-date'].split('-')
        year = int(pubdateList[0])
        month = int(pubdateList[1])
        day = int(pubdateList[2])

        # Build the episode object
        e = p.add_episode()
        e.id = mediaURL
        e.title = 'Episode ' + str(episode['episode-num'])
        e.summary = episode['description']
        e.link = 'http://christcommunitycarmel.org/get-involved/podcasts'
        e.publication_date = datetime.datetime(year,
                                               month,
                                               day,
                                               12,
                                               00,
                                               00,
                                               tzinfo=pytz.timezone('EST'))
        e.media = Media(mediaURL,
                        episode['size'],
                        duration=datetime.timedelta(hours=h,
                                                    minutes=mins,
                                                    seconds=secs))

    # Write the rss file
    print('Writing RSS file to S3')
    rssLocalFile = '/tmp/podcast.rss'
    rssS3File = 'ccc/podcast.rss'
    p.rss_file(rssLocalFile)
    s3 = boto3.client('s3')
    s3.upload_file(rssLocalFile,
                   'kwksolutions.com',
                   rssS3File,
                   ExtraArgs={'ContentType': 'text/xml'})

    return