From 85572c94de77f4a51d5b64e44c6b50cbe200c946 Mon Sep 17 00:00:00 2001 From: James Taylor Date: Fri, 23 Aug 2019 14:48:00 -0700 Subject: Layout: refactor item system to be more maintainable, add vertical item type --- youtube/local_playlist.py | 1 - youtube/static/shared.css | 307 +++++++++++++-------------------- youtube/templates/common_elements.html | 140 ++++----------- youtube/templates/search.html | 2 +- youtube/templates/watch.html | 5 +- youtube/watch.py | 2 - youtube/yt_data_extract.py | 4 - 7 files changed, 158 insertions(+), 303 deletions(-) (limited to 'youtube') diff --git a/youtube/local_playlist.py b/youtube/local_playlist.py index bb05d1a..4b92315 100644 --- a/youtube/local_playlist.py +++ b/youtube/local_playlist.py @@ -82,7 +82,6 @@ def get_local_playlist_videos(name, offset=0, amount=50): else: info['thumbnail'] = util.get_thumbnail_url(info['id']) missing_thumbnails.append(info['id']) - info['item_size'] = 'small' info['type'] = 'video' yt_data_extract.add_extra_html_info(info) videos.append(info) diff --git a/youtube/static/shared.css b/youtube/static/shared.css index 415296a..3624272 100644 --- a/youtube/static/shared.css +++ b/youtube/static/shared.css @@ -118,218 +118,151 @@ body{ .item-list{ display: grid; - grid-auto-rows: 138px; grid-row-gap: 10px; } - .item-list .video-thumbnail-box{ - width:246px; - } - .item-list .playlist-thumbnail-box{ - width:246px; - } .item-grid{ - display:grid; - grid-template-columns: repeat(auto-fill, 400px); - grid-auto-rows: 94px; - grid-row-gap: 10px; + display: flex; + flex-wrap: wrap; } - .item-grid .video-thumbnail-box{ - width:168px; + .item-grid > .playlist-item-box{ + margin-right: 10px; } - .item-grid .playlist-thumbnail-box{ - width:168px; + .item-grid > * { + margin-bottom: 10px; + } + .item-grid .horizontal-item-box .item{ + width:370px; + } + .item-grid .vertical-item-box .item{ } - - -.medium-item-box{ - - display:grid; - grid-template-columns: 1fr 30px; +.item-box{ + display: inline-flex; + flex-direction: row; } -.medium-item{ - background-color:#bcbcbc; - text-decoration:none; - font-size: 12px; - color: #767676; - - display: grid; - align-content: start; - grid-template-columns: auto 1fr auto; - grid-template-rows: auto auto auto auto auto 1fr; +.vertical-item-box{ } - .medium-item .title{ - grid-column:2 / span 2; - grid-row:1; - justify-self:start; - min-width: 0; - max-height:3.6em; - overflow:hidden; - - color: #333; - font-size: 16px; - font-weight: 500; - text-decoration:initial; - } - .medium-item address{ - display:inline; +.horizontal-item-box{ +} + .item{ + background-color:#bcbcbc; + text-decoration:none; + font-size: 12px; + color: #767676; } - /*.medium-item .views{ - grid-column: 3; - grid-row: 2; - justify-self:end; + + .horizontal-item-box .item { + flex-grow: 1; + display: grid; + align-content: start; + grid-template-columns: auto 1fr; + grid-template-rows: auto auto auto auto 1fr; } - .medium-item time{ - grid-column: 2; - grid-row: 3; - justify-self:start; - }*/ - .medium-item .stats{ - grid-column: 2 / span 2; - grid-row: 2; - max-height:2.4em; - overflow:hidden; + .vertical-item-box .item{ + width: 168px; } - .medium-item .stats > *::after{ - content: " | "; + .thumbnail-box{ + font-size: 0px; /* prevent newlines and blank space from creating gaps */ + position: relative; + display: block; } - .medium-item .stats > *:last-child::after{ - content: ""; + .horizontal-item-box .thumbnail-box{ + grid-row: 1 / span 5; } - - .medium-item .description{ - grid-column: 2 / span 2; - grid-row: 4; - } - .medium-item .badges{ - grid-column: 2 / span 2; - grid-row: 5; - } - /* thumbnail size */ - .medium-item img{ - /*height:138px; - width:246px;*/ - height:100%; - justify-self:center; - } - -.small-item-box{ - color: #767676; - font-size: 12px; + .no-description .thumbnail-box{ + width: 168px; + height:94px; + } + .has-description .thumbnail-box{ + width: 246px; + height:138px; + } + .video-item .thumbnail-info{ + position: absolute; + bottom: 2px; + right: 2px; + opacity: .8; + color: #ffffff; + font-size: 12px; + background-color: #000000; + } + .playlist-item .thumbnail-info{ + position: absolute; + right: 0px; + bottom: 0px; + height: 100%; + width: 50%; + text-align:center; + white-space: pre-line; + opacity: .8; + color: #cfcfcf; + font-size: 12px; + background-color: #000000; + } + .playlist-item .thumbnail-info span{ /* trick to vertically center the text */ + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + } + .thumbnail-img{ /* center it */ + margin: auto; + display: block; + max-height: 100%; + } + .horizontal-item-box .thumbnail-img{ + height: 100%; + } - display:grid; - grid-template-columns: 1fr 30px; - grid-template-rows: 94px; -} + .item .title{ + min-width: 0; + max-height:3.6em; + overflow:hidden; -.small-item{ - background-color:#bcbcbc; - align-content: start; - text-decoration:none; - - display: grid; - grid-template-columns: 168px 1fr; - grid-column-gap: 5px; - grid-template-rows: auto auto auto 1fr; -} - .small-item .title{ - grid-column:2; - grid-row:1; - margin:0; + color: #333; + font-size: 16px; + font-weight: 500; + text-decoration:initial; + } - color: #333; - font-size: 16px; - font-weight: 500; - text-decoration:initial; - min-width: 0; - justify-self:start; + .stats{ + list-style: none; + padding: 0px; + margin: 0px; + } + .horizontal-stats{ + max-height:2.4em; + overflow:hidden; + } + .horizontal-stats > li{ + display: inline; + } - overflow:hidden; - max-height: 3.3em; - line-height: 1.1em; - } - .small-item address{ - grid-column: 2; - grid-row: 2; - justify-self: start; - } - - .small-item .views{ - grid-column: 2; - grid-row: 3; - justify-self:start; - } - /* thumbnail size */ - .small-item img{ - /*height:94px; - width:168px;*/ - height:100%; - justify-self:center; - } - -.item-checkbox{ - justify-self:start; - align-self:center; - height:30px; - width:30px; - - grid-column: 2; -} + .horizontal-stats > li::after{ + content: " | "; + } + .horizontal-stats > li:last-child::after{ + content: ""; + } -/* ---Thumbnails for videos---- */ -.video-thumbnail-box{ - max-height:100%; + .vertical-stats{ + display: flex; + flex-direction: column; + } + .stats address{ + display: inline; + } - grid-column:1; - grid-row:1 / span 6; - - display:grid; - grid-template-columns: 1fr 0fr; -} - .video-thumbnail-img{ - grid-column:1 / span 2; - grid-row:1; - } - .video-duration{ - grid-column: 2; - grid-row: 1; - align-self: end; - opacity: .8; - color: #ffffff; - font-size: 12px; - background-color: #000000; + .item-checkbox{ + justify-self:start; + align-self:center; + height:30px; + width:30px; + margin: 0px; } -/* ---Thumbnails for playlists---- */ -.playlist-thumbnail-box{ - max-height:100%; - - grid-column:1; - grid-row:1 / span 6; - - display:grid; - grid-template-columns: 3fr 2fr; -} - .playlist-thumbnail-img{ - grid-column:1 / span 2; - grid-row:1; - } - .playlist-thumbnail-info{ - grid-column:2; - grid-row:1; - - display: grid; - align-items:center; - - text-align:center; - white-space: pre-line; - opacity: .8; - color: #cfcfcf; - background-color: #000000; - } .page-button-row{ justify-self:center; diff --git a/youtube/templates/common_elements.html b/youtube/templates/common_elements.html index 49e2fad..b9ceafa 100644 --- a/youtube/templates/common_elements.html +++ b/youtube/templates/common_elements.html @@ -14,121 +14,53 @@ {%- endif -%} {% endmacro %} -{% macro small_item(info, include_author=true) %} -
-
- {% if info['type'] == 'video' %} - - - {{ info['duration'] }} - - {{ info['title'] }} - -
{{ info['author'] }}
- {{ info['views'] }} - - {% elif info['type'] == 'playlist' %} - - -
- {{ info['size'] }} +{% macro item(info, description=false, horizontal=true, include_author=true) %} +
+ - {% if info['type'] == 'video' %} - - {% endif %} -
-{% endmacro %} - -{% macro get_stats(info, include_author=true) %} - {% if include_author %} - {% if 'author_url' is in(info) %} -
By {{ info['author'] }}
- {% else %} -
{{ info['author'] }}
- {% endif %} - {% endif %} - {% if 'views' is in(info) %} - {{ info['views'] }} - {% endif %} - {% if 'published' is in(info) %} - - {% endif %} -{% endmacro %} - - - -{% macro medium_item(info, include_author=true) %} -
-
- {% if info['type'] == 'video' %} - - - {{ info['duration'] }} - - - {{ info['title'] }} - -
- {{ get_stats(info, include_author) }} -
- + {% endif %} + + + {{ info['title'] }} + +
    + {% if info['type'] == 'channel' %} +
  • {{ info['subscriber_count'] }} subscribers
  • +
  • {{ info['size'] }} videos
  • + {% else %} + {% if include_author %} + {% if 'author_url' is in(info) %} +
  • By {{ info['author'] }}
  • + {% else %} +
  • {{ info['author'] }}
  • + {% endif %} + {% endif %} + {% if 'views' is in(info) %} +
  • {{ info['views'] }}
  • + {% endif %} + {% if 'published' is in(info) %} +
  • + {% endif %} + {% endif %} +
+ + {% if description %} {{ text_runs(info.get('description', '')) }} - {{ info['badges']|join(' | ') }} - {% elif info['type'] == 'playlist' %} - - -
- {{ info['size'] }} -
-
- - {{ info['title'] }} - -
- {{ get_stats(info, include_author) }} -
- {% elif info['type'] == 'channel' %} - - - - - {{ info['title'] }} - - {{ info['subscriber_count'] }} subscribers - {{ info['size'] }} videos - - {{ text_runs(info.get('description', '')) }} - {% else %} - Error: unsupported item type {% endif %} + {{ info['badges']|join(' | ') }}
{% if info['type'] == 'video' %} {% endif %}
-{% endmacro %} - -{% macro item(info, include_author=true) %} - {% if info['item_size'] == 'small' %} - {{ small_item(info, include_author) }} - {% elif info['item_size'] == 'medium' %} - {{ medium_item(info, include_author) }} - {% else %} - Error: Unknown item size - {% endif %} {% endmacro %} - - {% macro page_buttons(estimated_pages, url, parameters_dictionary) %} {% set current_page = parameters_dictionary.get('page', 1)|int %} {% set parameters_dictionary = parameters_dictionary.to_dict() %} diff --git a/youtube/templates/search.html b/youtube/templates/search.html index 782a85e..f429da0 100644 --- a/youtube/templates/search.html +++ b/youtube/templates/search.html @@ -45,7 +45,7 @@
{% for info in results %} - {{ common_elements.item(info) }} + {{ common_elements.item(info, description=true) }} {% endfor %}