Beispiel #1
0
def web_archive_import_playlist(id):
    """Imports playlist to archive.

    Imports entire playlist to the first available archive. Creates new archive
        if all are full.

    Args:
        id (str): YouTube playlist ID.
    """

    db = get_db()
    user_id = flask.session['user']['id']

    for item in yt_get_playlist_items(id):
        video_id = item['snippet']['resourceId']['videoId']
        video = yt_get_video(video_id)
        channel_id = video['snippet']['channelId']

        archive = None
        for playlist in db_get_archives():
            if playlist['contentDetails']['itemCount'] < 5000:
                archive = playlist
                break

        if archive is None:
            archive = yt_create_playlist()

        if yt_insert_to_playlist(video_id, archive['id']):
            if channel_id not in db[user_id]:
                db[user_id][channel_id] = {'played': {}, 'archived': {}}
            db[user_id][channel_id]['archived'][video_id] = archive['id']
            update_db(db)
Beispiel #2
0
def web_channels_update_tracks(tracks):
    """Handles channel tracking using connected account.

    Tracks or untracks YouTube channels using connected account.

    Args:
        tracks (string): URL encoded JSON data (``channel_id``: ``tracked?``).
    """

    db = get_db()
    user_id = flask.session['user']['id']

    for channel_id, tracked in json.loads(
            urllib.parse.unquote(tracks)).items():
        if tracked:
            if channel_id not in db[user_id]:
                db[user_id][channel_id] = {'played': {}, 'archived': {}}
        else:
            if channel_id in db[user_id]:
                channel = db[user_id][channel_id]
                for video_id, archive_id in channel['archived'].items():
                    yt_remove_from_playlist(video_id, archive_id)
                db[user_id].pop(channel_id)

    update_db(db)
Beispiel #3
0
def web_channels_update_query(query):
    """Handles channel tracking by user query.

    Tracks or untracks YouTube channels by user query.

    Args:
        query (string): URL encoded JSON data (``type``: ``url`` or ``id``,
            ``value``: ``value``).
    """

    db = get_db()
    query_data = json.loads(urllib.parse.unquote(query))
    user_id = flask.session['user']['id']

    if query_data['type'] == 'url':
        url = query_data['value']
        if '/user/' in url:
            user = re.search('^.+\/user\/([^\/]+)(\/.*|$)', url,
                             re.IGNORECASE).group(1)
            channel = yt_get_channel('snippet', user=user)
            db[user_id][channel['id']] = {'played': {}, 'archived': {}}
        elif '/channel/' in url:
            channel_id = url.rsplit('/', 1)[-1]
            channel = yt_get_channel('snippet', channel_id=channel_id)
            db[user_id][channel['id']] = {'played': {}, 'archived': {}}
        else:
            raise
    elif query_data['type'] == 'user':
        channel = yt_get_channel('snippet', user=query_data['value'])
        db[user_id][channel['id']] = {'played': {}, 'archived': {}}
    elif query_data['type'] == 'id':
        channel = yt_get_channel('snippet', id=query_data['value'])
        db[user_id][channel['id']] = {'played': {}, 'archived': {}}

    update_db(db)
Beispiel #4
0
def api_video_unplay(channel=None, video=None):
    """API video unplay route handler.

    Handles marking video as unplayed.

    Args:
        channel (Optional[str]): YouTube channel ID.
        video (Optional[str]): YouTube video ID.

    Returns:
        flask.Response: Whether operation has succeeded (bool in JSON).
    """

    try:
        auth_check()
    except Exception as e:
        return flask.jsonify(False)

    if channel is not None and video is not None:
        db = get_db()
        if video in db[flask.session['user']['id']][channel]['played']:
            db[flask.session['user']['id']][channel]['played'].pop(video)
            update_db(db)

        return flask.jsonify(True)
Beispiel #5
0
def api_video_play(channel=None, video=None):
    """API video play route handler.

    Handles marking video as played.

    Args:
        channel (Optional[str]): YouTube channel ID.
        video (Optional[str]): YouTube video ID.

    Returns:
        flask.Response: Whether operation has succeeded (bool in JSON).
    """

    try:
        auth_check()
    except Exception as e:
        return flask.jsonify(False)

    if channel is not None and video is not None:
        db = get_db()
        user_id = flask.session['user']['id']

        if video not in db[user_id][channel]['played']:
            db[user_id][channel]['played'][video] = (
                datetime.datetime.utcnow().replace(
                    microsecond=0, tzinfo=datetime.timezone.utc).isoformat())
            update_db(db)

        return flask.jsonify(True)
Beispiel #6
0
def api_video_unarchive(channel=None, video=None):
    """API video unarchive route handler.

    Handles video unarchiving.

    Args:
        channel (Optional[str]): YouTube channel ID.
        video (Optional[str]): YouTube video ID.

    Returns:
        flask.Response: Whether operation has succeeded (bool in JSON).
    """

    try:
        auth_check()
    except Exception as e:
        return flask.jsonify(False)

    if channel is not None and video is not None:
        db = get_db()
        user_id = flask.session['user']['id']
        if video in db[user_id][channel]['archived']:
            if yt_remove_from_playlist(
                    video, db[user_id][channel]['archived'][video]):
                db[user_id][channel]['archived'].pop(video)
                update_db(db)
            else:
                return flask.jsonify(False)

        return flask.jsonify(True)
Beispiel #7
0
def auth_oauth2callback():
    """OAuth 2.0 callback route handler.

    Completes authorization process (stores obtained credentials, gets user
        information and registers him if needed) and redirects to index.

    Returns:
        flask.Response: Index page.
    """
    state = flask.session['state']

    flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
        CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
    flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

    authorization_response = flask.request.url
    flow.fetch_token(authorization_response=authorization_response)

    credentials = flow.credentials
    flask.session['credentials'] = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret,
        'scopes': credentials.scopes
    }
    flask.session['user'] = yt_get_user()

    db = get_db()
    if flask.session['user']['id'] not in db:
        db[flask.session['user']['id']] = {}
    update_db(db)

    return flask.redirect(flask.url_for('index'))
Beispiel #8
0
def test_update_db():
    db = json.load(open(DB_FIXTURE_PATH))
    storage = io.StringIO()

    flexmock(builtins, open=storage)
    flexmock(storage, close=True)

    db['user_id']['channel_id']['played']['video_id'] = 'modified'
    update_db(db)

    assert json.loads(storage.getvalue()) == {
        'user_id': {
            'channel_id': {
                'archived': {
                    'video_id': 'playlist_id'
                },
                'played': {
                    'video_id': 'modified'
                }
            }
        }
    }
    storage.close()
Beispiel #9
0
def api_video_archive(channel=None, video=None):
    """API video archive route handler.

    Handles video archiving.

    Args:
        channel (Optional[str]): YouTube channel ID.
        video (Optional[str]): YouTube video ID.

    Returns:
        flask.Response: Whether operation has succeeded (bool in JSON).
    """

    try:
        auth_check()
    except Exception as e:
        return flask.jsonify(False)

    if channel is not None and video is not None:
        db = get_db()
        archive = None
        for playlist in db_get_archives():
            if playlist['contentDetails']['itemCount'] < 5000:
                archive = playlist
                break

        if archive is None:
            archive = yt_create_playlist()

        if yt_insert_to_playlist(video, archive['id']):
            db[flask.session['user']
               ['id']][channel]['archived'][video] = archive['id']
            update_db(db)
            return flask.jsonify(True)
        else:
            return flask.jsonify(False)