|
|
@ -29,7 +29,7 @@ app.after_request(after_request)
|
|
|
|
|
|
|
|
|
|
|
|
MAX_TITLE_LENGTH = 100 # Youtube only allows 100-character titles
|
|
|
|
MAX_TITLE_LENGTH = 100 # Youtube only allows 100-character titles
|
|
|
|
MAX_DESCRIPTION_LENGTH = 5000 # Youtube only allows 5000-character descriptions
|
|
|
|
MAX_DESCRIPTION_LENGTH = 5000 # Youtube only allows 5000-character descriptions
|
|
|
|
|
|
|
|
DESCRIPTION_PLAYLISTS_HEADER = "This video is part of the following playlists:"
|
|
|
|
|
|
|
|
|
|
|
|
def cors(app):
|
|
|
|
def cors(app):
|
|
|
|
"""WSGI middleware that sets CORS headers"""
|
|
|
|
"""WSGI middleware that sets CORS headers"""
|
|
|
@ -194,19 +194,20 @@ def get_row(ident):
|
|
|
|
response['thumbnail_time'] = start
|
|
|
|
response['thumbnail_time'] = start
|
|
|
|
|
|
|
|
|
|
|
|
# remove any added headers or footers so round-tripping is a no-op
|
|
|
|
# remove any added headers or footers so round-tripping is a no-op
|
|
|
|
# TODO make work with playlist links in description
|
|
|
|
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
app.title_header
|
|
|
|
app.title_header
|
|
|
|
and response["video_title"] is not None
|
|
|
|
and response["video_title"] is not None
|
|
|
|
and response["video_title"].startswith(app.title_header)
|
|
|
|
and response["video_title"].startswith(app.title_header)
|
|
|
|
):
|
|
|
|
):
|
|
|
|
response["video_title"] = response["video_title"][len(app.title_header):]
|
|
|
|
response["video_title"] = response["video_title"][len(app.title_header):]
|
|
|
|
if (
|
|
|
|
description_playlist_re = re.compile(r"({}\n(- .* \[https://youtube.com/playlist\?list=[A-Za-z0-9_-]+\n)+)?{}$".format(
|
|
|
|
app.description_footer
|
|
|
|
re.escape(DESCRIPTION_PLAYLISTS_HEADER),
|
|
|
|
and response["video_description"] is not None
|
|
|
|
re.escape(app.description_footer),
|
|
|
|
and response["video_description"].endswith(app.description_footer)
|
|
|
|
))
|
|
|
|
):
|
|
|
|
if response["video_description"] is not None:
|
|
|
|
response["video_description"] = response["video_description"][:-len(app.description_footer)]
|
|
|
|
match = description_playlist_re.search(response["video_description"])
|
|
|
|
|
|
|
|
if match:
|
|
|
|
|
|
|
|
response["video_description"] = response["video_description"][:match.start()]
|
|
|
|
|
|
|
|
|
|
|
|
logging.info('Row {} fetched'.format(ident))
|
|
|
|
logging.info('Row {} fetched'.format(ident))
|
|
|
|
|
|
|
|
|
|
|
@ -275,7 +276,7 @@ def update_row(ident, editor=None):
|
|
|
|
return 'Row {} not found'.format(ident), 404
|
|
|
|
return 'Row {} not found'.format(ident), 404
|
|
|
|
assert old_row['id'] == ident
|
|
|
|
assert old_row['id'] == ident
|
|
|
|
|
|
|
|
|
|
|
|
playlists = query(conn, """
|
|
|
|
playlists = database.query(conn, """
|
|
|
|
SELECT playlist_id, name, tags
|
|
|
|
SELECT playlist_id, name, tags
|
|
|
|
FROM playlists
|
|
|
|
FROM playlists
|
|
|
|
WHERE show_in_description
|
|
|
|
WHERE show_in_description
|
|
|
@ -290,12 +291,12 @@ def update_row(ident, editor=None):
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# Include headers and footers
|
|
|
|
# Include headers and footers
|
|
|
|
playlist_info = get_playlist_info(conn)
|
|
|
|
|
|
|
|
new_row['video_title'] = app.title_header + new_row['video_title']
|
|
|
|
new_row['video_title'] = app.title_header + new_row['video_title']
|
|
|
|
description_lines = ["This video is part of the following playlists:"]
|
|
|
|
# NOTE: If you change this format, you need to also change the regex that matches this
|
|
|
|
|
|
|
|
# on the GET handler.
|
|
|
|
|
|
|
|
description_lines = [DESCRIPTION_PLAYLISTS_HEADER]
|
|
|
|
description_lines += [
|
|
|
|
description_lines += [
|
|
|
|
# TODO check this url
|
|
|
|
"- {} [https://youtube.com/playlist?list={}]".format(playlist.name, playlist.playlist_id)
|
|
|
|
"{} [https://youtube.com/playlist/{}]".format(playlist.name, playlist.playlist_id)
|
|
|
|
|
|
|
|
for playlist in playlists
|
|
|
|
for playlist in playlists
|
|
|
|
]
|
|
|
|
]
|
|
|
|
description_lines.append(app.description_footer)
|
|
|
|
description_lines.append(app.description_footer)
|
|
|
|