Giter VIP home page Giter VIP logo

youtube-podcast-gateway's Introduction

YouTube Podcast Gateway

❗ This project is not maintained anymore. I haven't been using it myself since 2018 and thus can't test issues or fixes myself. If you want to take over the project, I'll gladly transfer it to you. Hit me up by email!

Transforms a YouTube playlist or a user's uploads into a Podcast.

Description

This Python application can be used to subscribe to a YouTube channel or a playlist using a podcast client.

Requirements

You will need the following, if you want to use this application:

  • Python >= 3.2
  • A Google account
  • A podcast client

Setup

To use the application, you will have to install it using pip either into a virtualenv or globally. The instructions below are for installing into a virtualenv.

Setting up the virtualenv

To set up a virtualenv with the necessary requirements, run th following commands:

$ python3 -m venv venv
$ . venv/bin/activate
$ pip install git+https://github.com/Feuermurmel/youtube-podcast-gateway.git
[...]
Successfully installed google-api-python-client-1.6.4 httplib2-0.10.3 isodate-0.5.4 oauth2client-4.1.2 pyasn1-0.3.6 pyasn1-modules-0.1.4 pytz-2017.2 rsa-3.4.2 six-1.11.0 uritemplate-3.0.0 youtube-dl-2017.9.24 youtube-podcast-gateway-0.1

If the last two lines look like the example above, the setup was successful.

Creating a YouTube API key and access token.

Next, you will need to create a client_secrets.json file containing your API key, which is used to access the YouTube API. You will need a Google account for this.

Go to the (Google Developer Console)[https://console.developers.google.com] and create a new project. Under APIs & Auth > APIs, enable the YouTube Data API v3 for the new project. Then, under APIs & Auth > Consent screen, choose an Email address [1] and set a Product name [2].

Then, go to APIs & Auth > Credentials and create an OAuth 2.0 Client ID. For the Application type, choose Installed application and for Installed application type, choose Other. After creating the key, click Download JSON. This will download a JSON file. Rename the file to client_secrets.json and put it in the root directory of the application.

Now you can run the application for the first time using youtube-podcast-gateway. It should ask you to visit an web site.

$ youtube-podcast-gateway
Go to the following link in your browser:

    https://accounts.google.com/[...]

Enter verification code: 

Navigate to the displayed URL. It should give you the option to log in and ask you whether you want to allow the application read access to your youtube account. You will need allow this [3]. You can of course use the same Google account for logging into the Developer Console as well as YouTube.

After accepting, the page will give you the verification code as string, which you can paste back into the console where the URL was displayed. Then it should say that authentication was successful and the the HTTP server is started:

Enter verification code: [...]
Authentication successful.
Starting server on port 8080 ...

From now on, the application will use the saved access token when it is started.

[1]: God knows why …

[2]: The name of the project as well as the product name are not important, you will only see the product name when authorizing the application to access your account.

[3]: The main benefit is that this way, you can subscribe to private playlists you created [4].

[4]: Or e.g. the "Watch Later" playlist, which also private.

Subscribing to Channels and playlists

To subscribe to a YouTube channel or playlist, URLs of the following form have to be assembled:

  • http://localhost:8080/uploads/<channel-id>
  • http://localhost:8080/playlist/<playlist-id>

In both cases, the assembled URI (possibly with localhost replaced by the host name of your server) can be used in a podcast client to subscribe to the channel or playlist [5].

[5]: I've successfully tested iTunes, Apple's Podcasts app for iOS and Downcast for iOS. Please open an issue if you have trouble with your podcast client.

Subscribing to a channel

<channel-id> is either the use name of the channel's owner or the channel ID. YouTube currently uses both to refer to channels, depending on context. For example:

https://www.youtube.com/channel/UCOGeU-1Fig3rrDjhm9Zs_wg
https://www.youtube.com/user/CGPGrey

Here, UCOGeU-1Fig3rrDjhm9Zs_wg is the channel ID of a channel and CGPGrey is the username of another channel. Either can be used in place of <channel-id>

Subscribing to a playlist

is the ID of the playlist to subscribe to. For example:

https://www.youtube.com/playlist?list=PLbQ-gSLYQEc4Ah-5yF3IH29er13oJs_Xy

Here, PLbQ-gSLYQEc4Ah-5yF3IH29er13oJs_Xy is the ID of a playlist.

Configuration

Some settings can be configured using the -o command line option. For example:

$ youtube-podcast-gateway -o max_episode_count=100

This is a list of available settings:

http_listen_address: Host name or IP address to listen on. Defaults to listening all interfaces. Defaults to 0.0.0.0.

http_listen_port: Local port to listen on. Defaults to 8080.

max_episode_count: Maximum number of episodes to fetch for a single feed. Defaults to no limit.

client_secrets_path: Path to the client_secrets.json file downloaded from the Google Developer Console. Defaults to client_secrets.json.

oauth2_token_path: Path to the oauth2_token.json file which stores the OAuth 2 authorization tokes. Defaults to oauth2_token.json.

canonical_base_url: Base URL of the application which is used to generate URLs to the media files embedded in the feeds. This URL should point to the / path of the HTTP server run by the application. By default the base URI is guessed from the Host: header sent by a client and the port the HTTP server is listening on.

youtube-podcast-gateway's People

Contributors

feuermurmel avatar phistep avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

youtube-podcast-gateway's Issues

HttpError - OAUTH-related failure accessing playlists

After working flawlessly for a couple of years, all requests to retrieve playlists have recently stopped working for me - possibly an OAUTH-related failure?

Reinstalling the virtualenv/dependencies, and redoing the API keys / oauth setup seem to have no effect.

Are you/anyone else seeing anything similar?

$ ./run.sh
Starting server on port 58181 ...
[1]: Handling request for /uploads/UC6cMYsKMx6XicFcFm7mTsmA ...
Requesting https://www.googleapis.com/youtube/v3/channels?alt=json&part=snippet&id=UC6cMYsKMx6XicFcFm7mTsmA&maxResults=50 ...
Traceback (most recent call last):
  File "./lib/gateway.py", line 230, in do_GET
    self._handle_feed_request(type, rest[0], audio_only)
  File "./lib/gateway.py", line 273, in _handle_feed_request
    feed = feed_type(id, audio_only)
  File "./lib/gateway.py", line 304, in _create_uploads_feed
    channel = self._gateway.service.get_channel_by_id_or_username(channel_id, 'snippet')
  File "./lib/youtube.py", line 54, in get_channel_by_id_or_username
    channel = self.get_channels(channel_id_or_username, part)
  File "./lib/youtube.py", line 72, in get_channels
    return self._get(self._service.channels(), part, id = channel_id)
  File "./lib/youtube.py", line 103, in _get
    items = self._get_raw(resource, part, id = id, **kwargs)
  File "./lib/youtube.py", line 132, in _get_raw
    response = request.execute()
  File "/opt/youtube-podcast-gateway/venv/lib/python3.5/site-packages/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/opt/youtube-podcast-gateway/venv/lib/python3.5/site-packages/googleapiclient/http.py", line 844, in execute
    raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <exception str() failed>

(The same error repeats for every request)

Issues with channels with hundreds of videos

I was trying to generate a RSS feed of uploads from the RoosterTeeth channel and ran into issues. It looks like the application was pulling multiple, 50 results pages and eventually things broke. Is there a way to limit things to just 50 results and not have multiple pages?

I saw in youtube.py there is _max_results = 50, but that appears to limit the number of results per page. If I change the setting to something like 15, multiple pages are still requested.

URL: http://localhost:8080/uploads/UCzH3iADRIq1IJlIXjfNgTpA

tony@ubuntuv2:~/yt5/youtube-podcast-gateway-master$ ./run.sh 
Starting server on port 8080 ...
[1]: Handling request for /uploads/UCzH3iADRIq1IJlIXjfNgTpA ...
Requesting https://www.googleapis.com/youtube/v3/channels?alt=json&maxResults=50&part=contentDetails%2Csnippet&id=UCzH3iADRIq1IJlIXjfNgTpA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CDIQAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CGQQAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJYBEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMgBEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPoBEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKwCEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CN4CEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJADEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMIDEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPQDEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKYEEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNgEEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIoFEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLwFEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CO4FEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKAGEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNIGEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIQHEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLYHEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=COgHEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJoIEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMwIEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CP4IEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLAJEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=COIJEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJQKEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMYKEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPgKEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKoLEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNwLEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CI4MEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMAMEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPIMEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKQNEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNYNEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIgOEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLoOEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=COwOEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJ4PEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNAPEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIIQEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLQQEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=COYQEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJgREAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMoREAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPwREAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CK4SEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=COASEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJITEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMQTEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPYTEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKgUEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNoUEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIwVEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CL4VEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPAVEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKIWEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNQWEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIYXEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLgXEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=COoXEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJwYEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CM4YEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIAZEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLIZEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=COQZEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJYaEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMgaEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPoaEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKwbEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CN4bEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJAcEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMIcEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CPQcEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKYdEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNgdEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIoeEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLweEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CO4eEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CKAfEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CNIfEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CIQgEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CLYgEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=COggEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CJohEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CMwhEAA ...
Requesting https://www.googleapis.com/youtube/v3/playlistItems?maxResults=50&playlistId=UUzH3iADRIq1IJlIXjfNgTpA&part=contentDetails&alt=json&pageToken=CP4hEAA ...
Traceback (most recent call last):
  File "./lib/gateway.py", line 230, in _handle_request
    self._handle_feed_request(handler, type, rest[0], audio_only)
  File "./lib/gateway.py", line 267, in _handle_feed_request
    feed = feed_type(id, audio_only)
  File "./lib/gateway.py", line 299, in _create_uploads_feed
    playlist_items = self._gateway.service.get_playlist_items(channel.contentDetails.relatedPlaylists.uploads, 'contentDetails')
  File "./lib/youtube.py", line 77, in get_playlist_items
    return self._get(self._service.playlistItems(), part = part, playlistId = playlist_id)
  File "./lib/youtube.py", line 92, in _get
    items = cls._get_raw(resource, part, **kwargs)
  File "./lib/youtube.py", line 126, in _get_raw
    return [_Item.wrap_json(i) for i in iter_items()]
  File "./lib/youtube.py", line 126, in <listcomp>
    return [_Item.wrap_json(i) for i in iter_items()]
  File "./lib/youtube.py", line 120, in iter_items
    response = request.execute()
  File "/home/tony/yt5/youtube-podcast-gateway-master/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/home/tony/yt5/youtube-podcast-gateway-master/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 729, in execute
    raise HttpError(resp, content, uri=self.uri)

I am running this on a Ubuntu 14.04 x64 virtual machine with 2GB of memory (this is a test system before I move it to a larger home server). Here is the output from installing.

tony@ubuntuv2:~/yt5/youtube-podcast-gateway-master$ ls
client_secrets.json  lib  __main__.py  oauth2_token.json  run.sh  setup-venv.sh
tony@ubuntuv2:~/yt5/youtube-podcast-gateway-master$ ./setup-venv.sh 
Running virtualenv with interpreter /usr/bin/python3.4
Using base prefix '/usr'
New python executable in venv/bin/python3.4
Also creating executable in venv/bin/python
Installing setuptools, pip...done.
Downloading/unpacking google-api-python-client
  Downloading google-api-python-client-1.4.0.tar.gz (40kB): 40kB downloaded
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/google-api-python-client/setup.py) egg_info for package google-api-python-client

    warning: no files found matching '*.json' under directory 'apiclient'
    warning: no files found matching 'README'
    warning: no files found matching 'FAQ'
    warning: no files found matching 'setpath.sh'
Downloading/unpacking isodate
  Downloading isodate-0.5.1.tar.gz
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/isodate/setup.py) egg_info for package isodate

Downloading/unpacking pytz
  Downloading pytz-2015.2-py2.py3-none-any.whl (476kB): 476kB downloaded
Downloading/unpacking httplib2>=0.8 (from google-api-python-client)
  Downloading httplib2-0.9.1.tar.gz (205kB): 205kB downloaded
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/httplib2/setup.py) egg_info for package httplib2

Downloading/unpacking oauth2client>=1.4.6 (from google-api-python-client)
  Downloading oauth2client-1.4.7.tar.gz (48kB): 48kB downloaded
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/oauth2client/setup.py) egg_info for package oauth2client

Downloading/unpacking six>=1.6.1 (from google-api-python-client)
  Downloading six-1.9.0-py2.py3-none-any.whl
Downloading/unpacking uritemplate>=0.6 (from google-api-python-client)
  Downloading uritemplate-0.6.tar.gz
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/uritemplate/setup.py) egg_info for package uritemplate

Downloading/unpacking pyasn1==0.1.7 (from oauth2client>=1.4.6->google-api-python-client)
  Downloading pyasn1-0.1.7.tar.gz (68kB): 68kB downloaded
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/pyasn1/setup.py) egg_info for package pyasn1

Downloading/unpacking pyasn1-modules==0.0.5 (from oauth2client>=1.4.6->google-api-python-client)
  Downloading pyasn1-modules-0.0.5.tar.gz
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/pyasn1-modules/setup.py) egg_info for package pyasn1-modules

Downloading/unpacking rsa==3.1.4 (from oauth2client>=1.4.6->google-api-python-client)
  Downloading rsa-3.1.4.tar.gz
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/rsa/setup.py) egg_info for package rsa

    warning: no files found matching 'README'
Downloading/unpacking simplejson>=2.5.0 (from uritemplate>=0.6->google-api-python-client)
  Downloading simplejson-3.6.5.tar.gz (73kB): 73kB downloaded
  Running setup.py (path:/home/tony/yt5/youtube-podcast-gateway-master/venv/build/simplejson/setup.py) egg_info for package simplejson

Installing collected packages: google-api-python-client, isodate, pytz, httplib2, oauth2client, six, uritemplate, pyasn1, pyasn1-modules, rsa, simplejson
  Running setup.py install for google-api-python-client

    warning: no files found matching '*.json' under directory 'apiclient'
    warning: no files found matching 'README'
    warning: no files found matching 'FAQ'
    warning: no files found matching 'setpath.sh'
  Running setup.py install for isodate
    Fixing build/lib/isodate/__init__.py build/lib/isodate/isodates.py build/lib/isodate/isotime.py build/lib/isodate/duration.py build/lib/isodate/isotzinfo.py build/lib/isodate/tzinfo.py build/lib/isodate/isoerror.py build/lib/isodate/isoduration.py build/lib/isodate/isodatetime.py build/lib/isodate/isostrf.py build/lib/isodate/tests/test_date.py build/lib/isodate/tests/test_duration.py build/lib/isodate/tests/__init__.py build/lib/isodate/tests/test_pickle.py build/lib/isodate/tests/test_time.py build/lib/isodate/tests/test_strf.py build/lib/isodate/tests/test_datetime.py
    Skipping implicit fixer: buffer
    Skipping implicit fixer: idioms
    Skipping implicit fixer: set_literal
    Skipping implicit fixer: ws_comma
    Fixing build/lib/isodate/__init__.py build/lib/isodate/isodates.py build/lib/isodate/isotime.py build/lib/isodate/duration.py build/lib/isodate/isotzinfo.py build/lib/isodate/tzinfo.py build/lib/isodate/isoerror.py build/lib/isodate/isoduration.py build/lib/isodate/isodatetime.py build/lib/isodate/isostrf.py build/lib/isodate/tests/test_date.py build/lib/isodate/tests/test_duration.py build/lib/isodate/tests/__init__.py build/lib/isodate/tests/test_pickle.py build/lib/isodate/tests/test_time.py build/lib/isodate/tests/test_strf.py build/lib/isodate/tests/test_datetime.py
    Skipping implicit fixer: buffer
    Skipping implicit fixer: idioms
    Skipping implicit fixer: set_literal
    Skipping implicit fixer: ws_comma

  Running setup.py install for httplib2

  Running setup.py install for oauth2client

  Running setup.py install for uritemplate

  Running setup.py install for pyasn1

  Running setup.py install for pyasn1-modules

  Running setup.py install for rsa

    warning: no files found matching 'README'
    Installing pyrsa-keygen script to /home/tony/yt5/youtube-podcast-gateway-master/venv/bin
    Installing pyrsa-priv2pub script to /home/tony/yt5/youtube-podcast-gateway-master/venv/bin
    Installing pyrsa-decrypt-bigfile script to /home/tony/yt5/youtube-podcast-gateway-master/venv/bin
    Installing pyrsa-sign script to /home/tony/yt5/youtube-podcast-gateway-master/venv/bin
    Installing pyrsa-encrypt script to /home/tony/yt5/youtube-podcast-gateway-master/venv/bin
    Installing pyrsa-decrypt script to /home/tony/yt5/youtube-podcast-gateway-master/venv/bin
    Installing pyrsa-verify script to /home/tony/yt5/youtube-podcast-gateway-master/venv/bin
    Installing pyrsa-encrypt-bigfile script to /home/tony/yt5/youtube-podcast-gateway-master/venv/bin
  Running setup.py install for simplejson
    building 'simplejson._speedups' extension
    x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.4m -I/home/tony/yt5/youtube-podcast-gateway-master/venv/include/python3.4m -c simplejson/_speedups.c -o build/temp.linux-x86_64-3.4/simplejson/_speedups.o
    simplejson/_speedups.c:2:20: fatal error: Python.h: No such file or directory
     #include "Python.h"
                        ^
    compilation terminated.
    ***************************************************************************
    WARNING: The C extension could not be compiled, speedups are not enabled.
    Failure information, if any, is above.
    I'm retrying the build without the C extension now.
    ***************************************************************************

    ***************************************************************************
    WARNING: The C extension could not be compiled, speedups are not enabled.
    Plain-Python installation succeeded.
    ***************************************************************************
Successfully installed google-api-python-client isodate pytz httplib2 oauth2client six uritemplate pyasn1 pyasn1-modules rsa simplejson
Cleaning up...```

Server becomes unreachable when i close connection to remote server

Hi, i'm using your solution to get podcast from one specific youtube channel. When i connect to my digital ocean droplet and run ./run.sh & command, i'm able to load podcasts from iPhone. But as soon as i close connection to my remote server, podcast cannot load new podcasts any more and i can't reach the server by the address i was able to connect when my connection to remote server was alive. I see in your code that you use server.run_forever(), so in theory it should run ok. What am i missing ?

Thanks.

Daily Limit for Unauthenticated Use Exceeded.

Hello. I'm getting this error (reported by google apis). How to fix it? Thank you!

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "dailyLimitExceededUnreg",
    "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
    "extendedHelp": "https://code.google.com/apis/console"
   }
  ],
  "code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }
}

Stack trace:

    uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)         
  File "./lib/youtube.py", line 80, in get_channel_videos       
    return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)                                                             
  File "./lib/youtube.py", line 97, in _get                     
    items = cls._get_raw(resource, part, max_results, **kwargs) 
  File "./lib/youtube.py", line 131, in _get_raw                
    response = request.execute()                                
  File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper                                                            
    return wrapped(*args, **kwargs)                             
  File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute    
    raise HttpError(resp, content, uri=self.uri)                
googleapiclient.errors.HttpError[236]: Handling request for /uploads/independentinstitute ...                                   
Requesting https://www.googleapis.com/youtube/v3/channels?part=snippet&id=independentinstitute&alt=json&maxResults=50 ...       
Traceback (most recent call last):                              
  File "./lib/gateway.py", line 230, in do_GET                  
    self._handle_feed_request(type, rest[0], audio_only)        
  File "./lib/gateway.py", line 273, in _handle_feed_request    
    feed = feed_type(id, audio_only)                            
  File "./lib/gateway.py", line 314, in _create_playlist_feed   
    title = playlist.snippet.title                              
AttributeError: 'NoneType' object has no attribute 'snippet'    

Can’t make it work with OAuth credentials, need an API Key-only method

The Google authentication URL displayed by the script makes Google issue an error message like:

Error 400: invalid_request

You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure.

I tried many types of credentials from Google Console. I think things have changed and this is why it's not working anymore. You can see this by trying to follow the credentials instruction on the project page, which are completely different nowadays from what you'll find in Google API Console.

Skimming Google documentation, it says you don't need OAuth for an app that will simply browse public YouTube data. OAuth is needed when the app needs to go to places where only the authenticated user is allowed.

You will use an OAuth 2.0 client ID to submit an authorized request that retrieves information about your own YouTube channel.

Is there any way to make it work with an API key only, no OAuth?

Add a readme describing installation and usage

I have everything setup and can start the application ("Starting server on port 8080 ..."), but I don't know how to generate a RSS feed. Could you provide some guidance? I'm not very good and reading python code.

This is one of the few applications I've seen on github that works with YouTube's v3 API and I'm hoping it works with a personal project.

HTTPError

[4]: Handling request for /playlist/PLV9o5alTk7g1-q8dPcwwPj94hW2MVcAME ...
Requesting https://www.googleapis.com/youtube/v3/playlists?part=snippet&maxResults=50&id=PLV9o5alTk7g1-q8dPcwwPj94hW2MVcAME&alt=json ...
Traceback (most recent call last):
  File "/home/roman/youtube/venv/lib/python3.6/site-packages/youtube_podcast_gateway/gateway.py", line 268, in do_GET
    self._handle_feed_request(type, id, audio_only)
  File "/home/roman/youtube/venv/lib/python3.6/site-packages/youtube_podcast_gateway/gateway.py", line 323, in _handle_feed_request
    feed = feed_type(id, audio_only)
  File "/home/roman/youtube/venv/lib/python3.6/site-packages/youtube_podcast_gateway/gateway.py", line 368, in _create_playlist_feed
    playlist = self._gateway.service.get_playlists(playlist_id, 'snippet')
  File "/home/roman/youtube/venv/lib/python3.6/site-packages/youtube_podcast_gateway/youtube.py", line 89, in get_playlists
    return self._get(self._service.playlists(), part, id=playlist_id)
  File "/home/roman/youtube/venv/lib/python3.6/site-packages/youtube_podcast_gateway/youtube.py", line 137, in _get
    items = self._get_raw(resource, part, id=id, **kwargs)
  File "/home/roman/youtube/venv/lib/python3.6/site-packages/youtube_podcast_gateway/youtube.py", line 166, in _get_raw
    response = request.execute()
  File "/home/roman/youtube/venv/lib/python3.6/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/home/roman/youtube/venv/lib/python3.6/site-packages/googleapiclient/http.py", line 851, in execute
    raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <exception str() failed>

Podcast doesn't work

Audio Only

Judging from lib/gateway.py line 49 you already have support for creating audio only feeds. How do I subscribe to them? Is there any front end? If not I think it would be a good feature to implement. I would propose an optional GET argument ?audioonly=true.

I'm not that fluent in Python and struggled following the flow of your application, so I unfortunately cannot do it myself. Maybe you could offer me some help so I can prepare a pull request myself (not really sure if I'll be able to do it, though) or you could do it yourself? :)

Won't start

Traceback (most recent call last):
  File "/var/youtube/venv/bin/youtube-podcast-gateway", line 11, in <module>
    load_entry_point('youtube-podcast-gateway==0.1', 'console_scripts', 'youtube-podcast-gateway')()
  File "/var/youtube/venv/lib/python3.6/site-packages/youtube_podcast_gateway/__init__.py", line 31, in entry_point
    main(**vars(parse_args()))
  File "/var/youtube/venv/lib/python3.6/site-packages/youtube_podcast_gateway/__init__.py", line 27, in main
    gateway.Gateway(config.Configuration(dict(options))).run()
TypeError: 'NoneType' object is not iterable

Signature extraction failed

Hello! I'm getting the following error, after a fresh install, when I request a file through the Apple IOS stock podcast app:

[3]: Handling request for /video/Y0budGEwSYY.m4v ... [3]: Request for range bytes=0-1 of video Y0budGEwSYY. Getting URL for video Y0budGEwSYY ... Traceback (most recent call last): File "/home/maurizio/podcast/venv/lib/python3.7/site-packages/youtube_podcast_gateway/gateway.py", line 264, in do_GET self._gateway.file_factory.get_file(id, False)) File "/home/maurizio/podcast/venv/lib/python3.7/site-packages/youtube_podcast_gateway/gateway.py", line 343, in _handle_media_request request = urllib.request.Request(file.download_url) File "/home/maurizio/podcast/venv/lib/python3.7/site-packages/youtube_podcast_gateway/gateway.py", line 100, in download_url self._download_url = self._get_download_url() File "/home/maurizio/podcast/venv/lib/python3.7/site-packages/youtube_podcast_gateway/gateway.py", line 66, in _get_download_url url = self._get_url_for_format(i) File "/home/maurizio/podcast/venv/lib/python3.7/site-packages/youtube_podcast_gateway/gateway.py", line 91, in _get_url_for_format 'Getting the download URL failed: {}'.format(message)) Exception: Getting the download URL failed: ERROR: Signature extraction failed: Traceback (most recent call last):

The server is installed on Ubuntu Bionic Beaver (18.04 LTS). Python 3.7.3.

Any ideas on how to fix it? Thanks!

SSL: WRONG_VERSION_NUMBER

Hello!

There is an issue I found on Ubuntu ... Any ideas?

[65]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1977)
./run.sh: line 16: 19229 Segmentation fault      (core dumped) python . "${options[@]}"

Sorry to dump all this... Hope it helps. It has problem with playlists

Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Starting server on port 8080 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [1]: Handling request for /uploads/independentinstitute ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=independentinstitute&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=independentinstitute&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UCtMWEs-0VzhOboqaGomEHuQ&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UCtMWEs-0VzhOboqaGomEHuQ&alt=json&maxResults=50&pageToken=CDIQAA ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [2]: Handling request for /playlist/PLAbF6ETffGbwQuTdrleNPAZ7jRJGlmxQ8 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLAbF6ETffGbwQuTdrleNPAZ7jRJGlmxQ8&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UCtMWEs-0VzhOboqaGomEHuQ&alt=json&maxResults=50&pageToken=CGQQAA ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UCtMWEs-0VzhOboqaGomEHuQ&alt=json&maxResults=50&pageToken=CJYBEAA ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UCtMWEs-0VzhOboqaGomEHuQ&alt=json&maxResults=50&pageToken=CMgBEAA ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [2]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [1]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [3]: Handling request for /playlist/PLAbF6ETffGbwQuTdrleNPAZ7jRJGlmxQ8 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLAbF6ETffGbwQuTdrleNPAZ7jRJGlmxQ8&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [4]: Handling request for /uploads/independentinstitute ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=independentinstitute&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=UCydlo5t0YhsYr1X2ZKAykbg&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLAbF6ETffGbwQuTdrleNPAZ7jRJGlmxQ8&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/videos?id=a-DjxJ24tLU%2CPMYhItjKE9A%2CRc-zuo2b1kY%2CjqFja7l2eCQ%2CDPqQFSEYMX8%2CzeS6yEtYORI%2CNQuSt7Tn354&part=contentDetails%2Csnippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 301, in _create_uploads_feed
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:     channel = self._gateway.service.get_channel_by_id_or_username(channel_id, 'snippet')
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 53, in get_channel_by_id_or_username
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:     channel = self.get_channels(channel_id_or_username, part)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 71, in get_channels
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.channels(), part, id = channel_id)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 111, in _get
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]:     raise ValueError('Multiple items were returned.')
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: ValueError: Multiple items were returned.
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [3]: Returned status 200.
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [7]: Handling request for /uploads/corbettreport ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=corbettreport&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [5]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [6]: Handling request for /uploads/minivanjack ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [6]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [5]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [7]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [8]: Handling request for /uploads/corbettreport ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=corbettreport&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=corbettreport&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UC7TvL4GlQyMBLlUsTrN_C4Q&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [9]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [10]: Handling request for /uploads/minivanjack ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UC7TvL4GlQyMBLlUsTrN_C4Q&alt=json&maxResults=50&pageToken=CDIQAA ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UC7TvL4GlQyMBLlUsTrN_C4Q&alt=json&maxResults=50&pageToken=CGQQAA ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [9]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [10]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [8]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [11]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=UCfVttlt_w2FrSV6yP9HQNTw&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [13]: Handling request for /uploads/minivanjack ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [12]: Handling request for /uploads/corbettreport ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=corbettreport&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/videos?id=2A0mvth1-oQ%2C7qyzDnLljck%2CxG99nSvsWcU%2CaGYt5_UJWF0%2CUF_cv2y3bmo%2Ct6TmTd_0P6E&part=contentDetails%2Csnippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [12]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [13]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [11]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [14]: Handling request for /playlist/PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=UCfVttlt_w2FrSV6yP9HQNTw&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [16]: Handling request for /uploads/corbettreport ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=corbettreport&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [15]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [17]: Handling request for /uploads/minivanjack ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5&alt=json&maxResults=50 ...
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [16]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [15]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [14]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:24:38 ip-172-30-0-190 run.sh[28417]: [17]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [18]: Handling request for /playlist/PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=UCfVttlt_w2FrSV6yP9HQNTw&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5&alt=json&maxResults=50&pageToken=CDIQAA ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5&alt=json&maxResults=50&pageToken=CGQQAA ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/videos?id=UnIuhRt3D-E%2C231mKI1-OzQ%2CfFoXyFmmGBQ%2CF3_EXqJ8f-0%2C-SWdYcEUxJE%2CGFosQtEqzSE%2CRA3idjkyrBg%2CaJndeGzbubo%2CDVq_fIZeO00%2CkoM7Ng43Bts%2CkkEQ6bNU6A8%2CUyhjaPLgSzw%2C0i_cN9he4jc%2CpYCD7_OG2fU%2CyQhqZ-iWMRM%2CYxLBPA1PBzE%2CCwqiEJEzBtE%2C1_0PSyGc1A8%2CNXh50Ac1_ug%2CSQU955n6iEI%2C6rE6o6Yhr4U%2C6BPErgO8k-E%2C_R5UZQtczdI%2CtCOv7C9g7xo%2CH46FcBjOxHY%2CSAN5CKbZnD0%2C3WUsMUkIUSY%2CUTMxfAkxfQ0%2CpdNmTEjdYeo%2CF7HmFH-Wo1s%2CuWboviCLW3I%2CGvE4zEfrv0k%2C4Zlvc17iF4w%2C1DClRU4na3I%2CMptBNULyzxo%2CEtfmJBSh6mY%2CIJQnf12UQkE%2CCJgn1Y55I2s%2CfqZ1_t4bdu8%2CzJMH4hWBXlw%2C6InUaGbtw8k%2CRILDjo4EXV8%2Cs_TeACO_p5E%2C52tyPRsL3VQ%2C916aRMt8k2s%2CySnk-f2ThpE%2CQpGzpqU-b04%2CvSrf9j2pvmU%2CNX9bwYXLHso%2CpF_MoCf8FE0&part=contentDetails%2Csnippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [21]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [20]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [19]: Handling request for /uploads/corbettreport ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=corbettreport&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/videos?id=Yz9NGu9kbrU%2Ck7-ipmPk-jM%2CEQwbX0P4wLM%2CS97Juf3Xh6I%2CmuBoGayfPM4%2CKAWxhdPGJfU%2ClrZ2DJzbYYo%2ClWnkZwCum0M%2CYPS89qS0XyE%2Cq7IUuHNDiyw%2CwXtMTgk2sZo%2CCYeuvt7Eul4%2CEoYCCtBmqpg%2CMmc83shIsYA%2CZtLABW149Ss%2Cf82mHHAt6yI%2Cm7trUPRO61k%2CBBeHcstqF7k%2CTOWpQrSDc5w%2C3fJjajItnEQ%2CyMAEJgx1p-c%2CV_StcQwElGE%2Cy29LHRpO30c%2CfFxJFv_wpqw%2CYwkEH1v5T6Q%2CG0SqKfdwr0o%2COuONeUKcMxs%2CvmCn2vP-DEo%2CH6Opvlmy8i8%2CoVZX_amgLnc%2CHZfhy6DvSv0%2C_w0TOJspijA%2CSwqAa04pzZI%2CzGahZSS_T8w%2CJif0y7k-OXk%2C50-ZYCh3nBc%2CEquufg8nu4c%2CTCy_UOjEir0%2C6laN0llsMZs%2CYLqGo9d1ZbU%2CGJn2cwEmtl0%2CWNHKDJzgqJg%2CFE7L_dJBlww%2C8iLLfieGifY%2CkPy9j3vtKCs%2CN7CvEt51fz4%2CSGJ5cZnoodY%2CYZcF17jr1Tk%2CLbyuzObHEWk%2CDy1frpilnPQ&part=contentDetails%2Csnippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [19]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [20]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [21]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [18]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [25]: Handling request for /playlist/PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [23]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [23]: Connection was closed: [Errno 9] Bad file descriptor
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [22]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [22]: Connection was closed: [Errno 9] Bad file descriptor
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [24]: Handling request for /uploads/corbettreport ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=corbettreport&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=UCfVttlt_w2FrSV6yP9HQNTw&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=UCfVttlt_w2FrSV6yP9HQNTw&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/videos?id=pmbh7fdxG6E%2CmuBoGayfPM4%2CxTcQCeSb08k%2CFrFLriAXgEg&part=contentDetails%2Csnippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [26]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [27]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [24]: Returned status 200.
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [28]: Handling request for /playlist/PLyl80QTKi0gPBcb32paMvXxcq7UUeJskV ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLyl80QTKi0gPBcb32paMvXxcq7UUeJskV&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLf_n1y8cN9NZyf13qBz9IqFl-5sUgYci5&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [27]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [26]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [25]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [28]: Connection was closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1748)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [29]: Handling request for /playlist/PLyl80QTKi0gPBcb32paMvXxcq7UUeJskV ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLyl80QTKi0gPBcb32paMvXxcq7UUeJskV&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=UC82By0y-2ZdjigNu5bWY4LQ&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLyl80QTKi0gPBcb32paMvXxcq7UUeJskV&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/videos?id=FRNHdJGBATE%2CBB4BKLvH3l8%2CKvpbQlQwl0A%2CSkAzDrrKkME%2CyswqoQ-6MQY%2CbE8i-4HpKlM&part=contentDetails%2Csnippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [29]: Returned status 200.
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [31]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: [30]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:00 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[32]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: [33]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[34]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: [35]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[36]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: [37]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[38]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: [39]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:05 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[40]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: [41]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[42]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: [43]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[44]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: [45]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[46]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: [47]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:17 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[48]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: [49]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[50]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: [51]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[52]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: [53]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     items = cls._get_raw(resource, part, max_results, **kwargs)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 131, in _get_raw
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     response = request.execute()
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/oauth2client/util.py", line 137, in positional_wrapper
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     return wrapped(*args, **kwargs)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "/home/ubuntu/youtube-podcast-gateway/venv/lib/python3.4/site-packages/googleapiclient/http.py", line 838, in execute
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     raise HttpError(resp, content, uri=self.uri)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: googleapiclient.errors.HttpError[54]: Handling request for /uploads/minivanjack ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/channels?id=minivanjack&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 314, in _create_playlist_feed
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     title = playlist.snippet.title
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: AttributeError: 'NoneType' object has no attribute 'snippet'
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: [55]: Handling request for /playlist/PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/playlists?id=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&part=snippet&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Requesting https://www.googleapis.com/youtube/v3/search?part=id&type=video&order=date&channelId=PLf_n1y8cN9Navz3k7R4dVaCV8IVcjUZIH&alt=json&maxResults=50 ...
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]: Traceback (most recent call last):
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 230, in do_GET
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     self._handle_feed_request(type, rest[0], audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 273, in _handle_feed_request
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     feed = feed_type(id, audio_only)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/gateway.py", line 305, in _create_uploads_feed
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     uploads = self._gateway.service.get_channel_videos(channel.id, 'id', max_results = self._gateway.max_episode_count)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 80, in get_channel_videos
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:     return self._get(self._service.search(), part, channelId = channelId, order = order, type = 'video', max_results = max_results)
Oct 18 21:25:37 ip-172-30-0-190 run.sh[28417]:   File "./lib/youtube.py", line 97, in _get

Use Video Thumbnail as Per-Episode Cover

Since according to Apple's specification setting a different cover per episode is also supported.

The itunes:image tag is also supported at the (episode) level. For best results, Apple recommends embedding the same artwork within the metadata for that episode’s media file prior to uploading to your host server; using Garageband or another content-creation tool to edit your media file if needed.

From my experience, many major podcast clients also support this. I think it would be nice to use a thumbnail of the video as episode cover. This StackOverflow post lists an easy way to get the thumbnails of a known video ID.

https://img.youtube.com/vi/<insert-youtube-video-id-here>/0.jpg
https://img.youtube.com/vi/<insert-youtube-video-id-here>/1.jpg
https://img.youtube.com/vi/<insert-youtube-video-id-here>/2.jpg
https://img.youtube.com/vi/<insert-youtube-video-id-here>/3.jpg

I'd be happy to implement this myself, just not right now. This issue mainly serves as a reminder to myself and a survey if you'd be willing to merge this behaviour?

Not working in PocketCasts / wrong MIME-type

The gateway does not work with PocketCasts for iOS (and I assume won't do so for Android either). The MIME-type is set to application/atom+xml. The correct type seems to be application/rss+xml. When set up to use this MIME-type, the feed works in PocketCasts. I have no idea if this is still compatible with other clients.

Issues with Pocket Casts / caching

I'm trying to subscribe to a playlist with over 400 episodes, Shore, Stein, Papier, (PLpr-NGsAGodEbDePSO3wivni39lgdLQjW), and youtube-podcast-gateway needs a couple of seconds to respond to the subscription request. The Pocket Casts podcast client (I can only speak for iOS) refuses to add the feed as it thinks it is unavailable. This is in my opinion a problem on their side, but nevertheless I wanted to report it here.

Maybe you could start caching YouTube's responses to be able to handle subscription/update requests more swiftly, but I think caching and especially cache-invalidation will be pretty hard to get right.

There is also the Podlove Paged Feeds specification specification, which could be used to quicken up repsonse times as fewer data has to be assembled and sent to the user. Honestly I think this would be a little overkill.

Connection was closed: [Errno 32] Broken pipe

I have many broken pipe errors:

(venv) ~/code/youtube-podcast-gateway (master ✘)✹ ᐅ ./run.sh
Starting server on port 8080 ...
[4]: Handling request for /video/ozAPGnr-934.m4v ...
[4]: Request for video ozAPGnr-934.
Getting URL for video ozAPGnr-934 ...
[3]: Handling request for /video/oTugjssqOT0.m4v ...
[3]: Request for video oTugjssqOT0.
Getting URL for video oTugjssqOT0 ...
[7]: Handling request for /video/ozAPGnr-934.m4v ...
[7]: Request for video ozAPGnr-934.
Getting URL for video ozAPGnr-934 ...
[4]: Returned status 200.
[7]: Returned status 200.
[3]: Returned status 200.
[8]: Handling request for /video/oTugjssqOT0.m4v ...
[8]: Request for video oTugjssqOT0.
[9]: Handling request for /video/ozAPGnr-934.m4v ...
[9]: Request for video ozAPGnr-934.
[9]: Returned status 200.
[8]: Returned status 200.
[10]: Handling request for /video/oTugjssqOT0.m4v ...
[10]: Request for video oTugjssqOT0.
[10]: Returned status 200.
[11]: Handling request for /video/ozAPGnr-934.m4v ...
[11]: Request for video ozAPGnr-934.
[11]: Returned status 200.
[12]: Handling request for /video/ozAPGnr-934.m4v ...
[12]: Request for video ozAPGnr-934.
[12]: Returned status 200.
[13]: Handling request for /video/ryHotna5RSQ.m4v ...
[13]: Request for video ryHotna5RSQ.
Getting URL for video ryHotna5RSQ ...
[13]: Returned status 200.
[14]: Handling request for /video/ryHotna5RSQ.m4v ...
[14]: Request for video ryHotna5RSQ.
[14]: Returned status 200.
[14]: Connection was closed: [Errno 32] Broken pipe

From https://stackoverflow.com/questions/11866792/how-to-prevent-errno-32-broken-pipe it seems that the mobile client closes the connection for some reason and we should handle it properly.

Serve a subscription page under /

Add a small, static HTML page under /, where a YouTube page can be pasted and which then redirects the user to the URL of the feed for the of the uploads or playlist referenced in the pasted URL.

Maybe generate the URL using JavaScript and allow the URL to be copy&pasted and clicked on.

Some notes on how to successfully start the application...

First off, thank you for this great and very useful application.

After having installed from scratch:

  1. it looks like you have to have at lest an option, for example: -o max_episode_count=1000 otherwise it doesn't start

Traceback (most recent call last): File "/home/yyy/venv/bin/youtube-podcast-gateway", line 11, in <module> load_entry_point('youtube-podcast-gateway==0.1', 'console_scripts', 'youtube-podcast-gateway')() File "/home/yyy/venv/lib/python3.6/site-packages/youtube_podcast_gateway/__init__.py", line 31, in entry_point main(**vars(parse_args())) File "/home/yyy/venv/lib/python3.6/site-packages/youtube_podcast_gateway/__init__.py", line 27, in main gateway.Gateway(config.Configuration(dict(options))).run() TypeError: 'NoneType' object is not iterable

  1. you have to use the canonical_base_url=http://example.com:8080option otherwise, if you subscribe to a youtube channel or playlist with the port number, for example: 8080 , the file attached could not be retrieved because the port of subscription is added to the port of the file resources.

Example of successful command line

youtube-podcast-gateway -o max_episode_count=1000 -o canonical_base_url=http://example.com:8080

Add option to limit number of episodes

Subscribing to channels with thousands of videos will result in requests taking a very long time (multiple minutes), resulting in timeouts. Also, I wouldn't be surprised if some podcast clients choke on multi-megabyte feeds containing thousands of episodes.

This should fix the problem reported in #4.

Remove upcoming live events form feed

Output when requesting a video which is actually an upcoming live event.

[77]: Request for range None of video lqsN_4wXuRg.
Getting URL for video lqsN_4wXuRg ...
Traceback (most recent call last):
  File "./lib/gateway.py", line 226, in do_GET
    self._handle_media_request(self._gateway.file_factory.get_file(rest[0], False))
  File "./lib/gateway.py", line 288, in _handle_media_request
    request = urllib.request.Request(file.download_url)
  File "./lib/gateway.py", line 81, in download_url
    self._download_url = self._get_download_url()
  File "./lib/gateway.py", line 54, in _get_download_url
    url = self._get_url_for_format(i)
  File "./lib/gateway.py", line 72, in _get_url_for_format
    'Getting the download URL failed: {}'.format(message))
Exception: Getting the download URL failed: ERROR: uefD6LUhyUE: YouTube said: Please sign in to view this video.
Traceback (most recent call last):
  File "./lib/gateway.py", line 226, in do_GET
    self._handle_media_request(self._gateway.file_factory.get_file(rest[0], False))
  File "./lib/gateway.py", line 288, in _handle_media_request
    request = urllib.request.Request(file.download_url)
  File "./lib/gateway.py", line 81, in download_url
    self._download_url = self._get_download_url()
  File "./lib/gateway.py", line 54, in _get_download_url
    url = self._get_url_for_format(i)
  File "./lib/gateway.py", line 72, in _get_url_for_format
    'Getting the download URL failed: {}'.format(message))
Exception: Getting the download URL failed: ERROR: no conn, hlsvp or url_encoded_fmt_stream_map information found in video info; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.

Playlist sorting order

The playlist Shore, Stein, Papier, (PLpr-NGsAGodEbDePSO3wivni39lgdLQjW is sorted in a way that gets the order of episodes right in respect to episode number. I suppose you use the upload date for the <pubDate> field in feed generation. I couldn't really find that in the feed xml, but it appears to me, that several episodes have been published in the same minute. The Pocket Casts podcast player doesn't sort them alphabetically but appearingly random (my guess is it maps to their internal data structure and maybe which item was first presented in the feed and parsed into their data structure or something), which leads to a confused playlist order due to the episodes being published on the same <pubDate>. This again is a Pocket Casts problem, but apart from that: Would you be interested in creating an option [like a GET option ?keeporder=true) for playlists to keep them in order of the playlist creation and not video upload by faking the episode <pubDate> starting from 1970-01-01 00:00 and setting each episode 1 hour apart or something like that? This would also be useful for playlists which are created from videos with a broad range of upload date but that is sorted in a special way using the YouTube playlist feature.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.