diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css index 0c261421..ebbc2489 100644 --- a/data/interfaces/default/css/plexpy.css +++ b/data/interfaces/default/css/plexpy.css @@ -1,7 +1,8 @@ body { font-family: 'Open Sans', sans-serif; color: #fff; - padding-top: 50px; + margin-top: 50px; + overflow: hidden; } a { color: #eee; @@ -454,29 +455,10 @@ input[type="color"], a .poster-face:hover, a .cover-face:hover, a .users-poster-face:hover { - -webkit-box-shadow: inset 0 0 0 2px #e9a049; + webkit-box-shadow: inset 0 0 0 2px #e9a049; -moz-box-shadow: inset 0 0 0 2px #e9a049; box-shadow: inset 0 0 0 2px #e9a049; } -.users-poster-face img { - bottom: 0; - overflow: hidden; - float: left; - background-color: #323232; - background-position: center; - background-size: cover; - -webkit-border-radius: 1000px; - -moz-border-radius: 1000px; - border-radius: 1000px; - -webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); - box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); - width: 40px; - height: 40px; -} -.users-poster-face img:hover{ - -webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 2px #F9AA03; - box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 2px #F9AA03; -} .users-name { position: relative; } @@ -521,6 +503,8 @@ a .users-poster-face:hover { text-align: center; } .dashboard-activity-cover-face-bg { +} +.dashboard-activity-poster-music-bg { background-position: center; background-size: cover; background-repeat: no-repeat; @@ -743,8 +727,8 @@ a .users-poster-face:hover { float: left; min-height: 340px; } -.dashboard-recent-media-metacontainer{ - width: 153px; +.dashboard-recent-media-metacontainer { + width: 150px; font-size: 13px; margin-bottom: 20px; clear: both; @@ -759,7 +743,7 @@ a .users-poster-face:hover { margin: 0; line-height: 15px; font-weight: normal; - width: 153px; + width: 150px; white-space: nowrap; text-align: left; clear: both; @@ -774,244 +758,212 @@ a .users-poster-face:hover { } .art-face { background-repeat: no-repeat; - background-position: 50% 0%; - background-size: 100%; - height: 540px; - overflow: hidden; - min-width: 280px; - position: relative; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - -webkit-box-shadow: 0 0 0px rgba(0,0,0,0.75); - -moz-box-shadow: 0 0 0px rgba(0,0,0,0.75); - box-shadow: 0 0 0px rgba(0,0,0,0.75); - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - -webkit-transform-style: preserve-3d; - -moz-transform-style: preserve-3d; - -ms-transform-style: preserve-3d; - -o-transform-style: preserve-3d; - transform-style: preserve-3d; - -webkit-perspective: 1000; - -moz-perspective: 1000; - -ms-perspective: 1000; - -o-perspective: 1000; - perspective: 1000; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - -ms-backface-visibility: hidden; - -o-backface-visibility: hidden; - backface-visibility: hidden; - clear: both; -} -.art-face img { - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - border-color: #1d1d1d; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.75); - -moz-box-shadow: 0 0 10px rgba(0,0,0,0.75); - box-shadow: 0 0 10px rgba(0,0,0,0.75); - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - -webkit-transform-style: preserve-3d; - -moz-transform-style: preserve-3d; - -ms-transform-style: preserve-3d; - -o-transform-style: preserve-3d; - transform-style: preserve-3d; - -webkit-perspective: 1000; - -moz-perspective: 1000; - -ms-perspective: 1000; - -o-perspective: 1000; - perspective: 1000; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - -ms-backface-visibility: hidden; - -o-backface-visibility: hidden; - backface-visibility: hidden; + background-position: center center; + background-attachment: scroll; + background-size: cover; + opacity: 0; + position: absolute; + top: 0; + bottom: 0; + width: 100%; } .art-music-face { background-repeat: no-repeat; - background-position: 50% 50%; - background-size: 100%; + background-position: center; + background-size: cover; width: 250px; - height: 141px; - overflow: hidden; position: relative; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - -webkit-box-shadow: 0 0 0px rgba(0,0,0,0.75); - -moz-box-shadow: 0 0 0px rgba(0,0,0,0.75); - box-shadow: 0 0 0px rgba(0,0,0,0.75); - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - -webkit-transform-style: preserve-3d; - -moz-transform-style: preserve-3d; - -ms-transform-style: preserve-3d; - -o-transform-style: preserve-3d; - transform-style: preserve-3d; - -webkit-perspective: 1000; - -moz-perspective: 1000; - -ms-perspective: 1000; - -o-perspective: 1000; - perspective: 1000; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - -ms-backface-visibility: hidden; - -o-backface-visibility: hidden; - backface-visibility: hidden; - clear: both; + top: 0; + bottom: 0; } -.summary-wrapper { - height: auto; - width: 100%; +.summary-container { position: absolute; + top: 0; + right: 0; bottom: 0; + left: 0; + overflow-x: hidden; + overflow-y: auto; } -.summary-overlay { - background-color: rgba(0,0,0,0.85); - color: #fff; - font-size: 14px; - height: auto; - position: relative; - top: 0px; - border-color: #1d1d1d; - border: 2px solid #191919; +.summary-container .table-card-header, +.summary-container .table-card-back { + opacity: 0.90; } -.summary-content-wrapper { - margin-left: auto; - margin-right: auto; - width: 960px; -} -.summary-content-poster { - position: relative; - top: -10px; - float: left; - margin-left: 25px; - width: 150px; - height: 225px; -} -.summary-content-poster img { - bottom: 0; +.summary-navbar { + background-color: rgba(255,255,255,.03); + height: 50px; + line-height: 50px; + max-height: 50px; overflow: hidden; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.75); - -moz-box-shadow: 0 0 10px rgba(0,0,0,0.75); - box-shadow: 0 0 10px rgba(0,0,0,0.75); - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - -webkit-transform-style: preserve-3d; - -moz-transform-style: preserve-3d; - -ms-transform-style: preserve-3d; - -o-transform-style: preserve-3d; - transform-style: preserve-3d; - -webkit-perspective: 1000; - -moz-perspective: 1000; - -ms-perspective: 1000; - -o-perspective: 1000; - perspective: 1000; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - -ms-backface-visibility: hidden; - -o-backface-visibility: hidden; - backface-visibility: hidden; } -.summary-content { - position: relative; - top: 0px; - left: 20px; +.summary-navbar-list { + padding: 0 25px; color: #999; - height: auto; - overflow: hidden; - margin-right: 20px; - margin-bottom: 20px; } -.summary-content-title h1{ - margin-top: 15px; - margin-bottom: 15px; - color: #F9AA03; - font-size: 24px; - line-height: 32px; +.summary-navbar-list span { float: left; + margin-right: 20px; } -.summary-content-title h1 a{ +.summary-navbar-list span a { + color: #999; +} +.summary-navbar-list span a:hover { color: #F9AA03; } -.summary-content-title h1 a:hover{ +.summary-content-title-wrapper { + height: 150px; + padding-top: 50px; +} +.summary-content-title { + overflow: hidden; + position: relative; + max-height: 100px; +} +.summary-content-title h1 { + margin-top: 0; + margin-bottom: 10px; + color: #F9AA03; + font-size: 28px; + line-height: 40px; + float: left; + clear: left; +} +.summary-content-title h1 a { + color: #F9AA03; +} +.summary-content-title h1 a:hover { color: #F9AA03; text-decoration: underline; } +.summary-content-title h2 { + margin-top: 0; + margin-bottom: 10px; + color: #fff; + font-size: 28px; + line-height: 40px; + float: left; + clear: left; +} +.summary-content-title h3 { + margin-top: 0; + margin-bottom: 10px; + color: #999; + font-size: 28px; + line-height: 40px; + float: right; +} +.summary-content-title h3 a:hover { + text-decoration: underline; +} +.summary-content-title h3 a { + color: #999; +} +.summary-content-wrapper { + background-image: linear-gradient(rgba(0,0,0,.4),rgba(19,19,19,.4) 50%,rgba(26,26,26,.4)); + background-clip: content-box; + min-height: calc(100% - 200px); + position: inherit; +} +.summary-content-poster { + float: left; + width: 250px; + margin: 0 40px 0 25px; + height: 100px; + overflow: visible; +} +.summary-poster-face { + background-position: center; + background-size: cover; + height: 375px; + width: 250px; + position: relative; + webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); + -moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); + box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); + overflow: hidden; + z-index: 1; +} +.summary-poster-face-episode { + background-position: center; + background-size: cover; + height: 140px; + width: 250px; + position: relative; + webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); + -moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); + box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); + overflow: hidden; + z-index: 1; +} +a .summary-poster-face:hover, +a .summary-poster-face-episode:hover { + webkit-box-shadow: inset 0 0 0 2px #e9a049; + -moz-box-shadow: inset 0 0 0 2px #e9a049; + box-shadow: inset 0 0 0 2px #e9a049; +} +.summary-content-padding { + float: left; + width: 250px; + height: 1px; + margin: 0 40px 20px 25px; +} +.summary-content { + position: relative; + color: #999; + overflow: hidden; + padding-right: 10px; + margin-bottom: 20px; +} .summary-content-details-wrapper { width: 100%; - padding-bottom: 15px; - margin-top: -10px; - clear: both; + padding: 10px 0 15px 0; position: relative; - top: -15px; + float: left; } .summary-content-director { float: left; - margin-right: 10px; line-height: 24px; } .summary-content-director strong { color: #fff; margin-left: 2px; + margin-right: 10px; } .summary-content-studio { float: left; - margin-right: 10px; line-height: 24px; } .summary-content-studio strong { color: #fff; margin-left: 2px; + margin-right: 10px; } .summary-content-airdate { float: left; - margin-right: 10px; line-height: 24px; } .summary-content-airdate strong { color: #fff; margin-left: 2px; + margin-right: 10px; } .summary-content-duration { float: left; - margin-right: 10px; line-height: 24px; } .summary-content-duration strong { color: #fff; margin-left: 2px; + margin-right: 10px; } .summary-content-content-rating { float: left; line-height: 24px; - margin-right: 10px; } .summary-content-content-rating strong { color: #fff; margin-left: 2px; + margin-right: 10px; } .summary-content-summary { overflow: hidden; @@ -1019,14 +971,12 @@ a .users-poster-face:hover { float: left; position: relative; clear: both; - padding-right: 10px; height: auto; max-height: 160px; padding-bottom: 0px; } .summary-content-people-wrapper { - margin-top: 25px; - margin-right: 25px; + margin-right: 20px; float: left; } .summary-content-people-wrapper hidden-phone hidden-tablet { @@ -1035,9 +985,7 @@ a .users-poster-face:hover { min-height: 0px; } .summary-content-actors { - margin-top: 0px; - margin-left: 0px; - margin-right: 15px; + margin-top: 13px; font-size: 12px; line-height: 18px; color: #999; @@ -1045,6 +993,7 @@ a .users-poster-face:hover { } .summary-content-actors ul { padding-left:20px; + margin-bottom: 0; } .summary-content-actors li { list-style: none; @@ -1055,9 +1004,7 @@ a .users-poster-face:hover { color: #fff; } .summary-content-genres { - margin-top: 0px; - margin-left: 0px; - margin-right: 15px; + margin-top: 13px; font-size: 12px; line-height: 18px; color: #999; @@ -1065,6 +1012,7 @@ a .users-poster-face:hover { } .summary-content-genres ul { padding-left:20px; + margin-bottom: 0; } .summary-content-genres li { list-style: none; @@ -1075,9 +1023,7 @@ a .users-poster-face:hover { color: #fff; } .summary-content-writers { - margin-top: 0px; - margin-left: 0px; - margin-right: 15px; + margin-top: 13px; font-size: 12px; line-height: 18px; color: #999; @@ -1085,6 +1031,7 @@ a .users-poster-face:hover { } .summary-content-writers ul { padding-left: 20px; + margin-bottom: 0; } .summary-content-writers li { list-style: none; @@ -1097,7 +1044,6 @@ a .users-poster-face:hover { .rateit { display: -moz-inline-box; display: inline-block; - position: relative; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; @@ -1105,30 +1051,118 @@ a .users-poster-face:hover { -ms-user-select: none; user-select: none; -webkit-touch-callout: none; - float: right; - margin-top: 23px; - margin-right: 20px; overflow: hidden; white-space: nowrap; + float: right; + margin-top: 3px; + height: 21px; } .rateit .rateit-range { - background: url(../images/star-gray-16.png); + background: url(../images/star-gray-32.png); + background-size: contain; height: 16px; } .rateit .rateit-selected { - background: url(../images/star-16.png); + background: url(../images/star-32.png); + background-size: contain; + height: 16px; +} +.show-seasons-wrapper { +} +.show-seasons-instance { + list-style: none; + margin: 0; +} +.show-seasons-instance li { + float: left; + position: relative; + left: 0px; + margin-right: 25px; + margin-bottom: 25px; +} +a .show-seasons-card-overlay:hover { + webkit-box-shadow: inset 0 0 0 2px #e9a049; + -moz-box-shadow: inset 0 0 0 2px #e9a049; + box-shadow: inset 0 0 0 2px #e9a049; +} +.show-seasons-poster { + float: left; + position: relative; + left: 0px; +} +.show-seasons-card-overlay { + position: absolute; + left: 0; + right: 0; + bottom: 0; + text-align: left; + background: -moz-linear-gradient(top, rgba(0,0,0,0) 30%, rgba(0,0,0,1) 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(30%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,1))); + background: -webkit-linear-gradient(top, rgba(0,0,0,0) 30%,rgba(0,0,0,1) 100%); + background: -o-linear-gradient(top, rgba(0,0,0,0) 30%,rgba(0,0,0,1) 100%); + background: -ms-linear-gradient(top, rgba(0,0,0,0) 30%,rgba(0,0,0,1) 100%); + background: linear-gradient(to bottom, rgba(0,0,0,0) 30%,rgba(0,0,0,1) 100%); + height: 225px; +} +.show-seasons-overlay-text { + color: #aaa; + font-size: 12px; + float: left; + position: absolute; + left: 8px; + bottom: 5px; +} +.show-seasons-instance-text-wrapper { + width: 150px; + font-size: 13px; + margin-bottom: 20px; + clear: both; +} +.show-seasons-instance-text-wrapper h3 { + padding: 5px 3px 0 3px; + color: #fff; + text-overflow: ellipsis; + overflow: hidden; + position: relative; + font-size: 13px; + margin: 0; + line-height: 15px; + font-weight: normal; + width: 250px; + white-space: nowrap; + text-align: left; + clear: both; +} +.show-seasons-title a { + text-decoration: none; + font-size: 14px; + font-weight: normal; + color: #fff; + float: left; + text-overflow: ellipsis; + overflow: hidden; + position: relative; + white-space: nowrap; + width: 205px; + margin-top: 2px; + margin-left: 0px; + margin-bottom: 20px; +} +.show-seasons a:hover { + color: #F9AA03; } .season-episodes-wrapper { } .season-episodes-instance { list-style: none; - margin: 0 0 0px 0px; + margin: 0; } .season-episodes-instance li { float: left; position: relative; left: 0px; margin-right: 25px; + margin-bottom: 25px; } a .season-episodes-card-overlay:hover { -webkit-box-shadow: inset 0 0 0 2px #e9a049; @@ -1180,11 +1214,13 @@ a .season-episodes-card-overlay:hover { font-size: 11px; text-shadow: 0 1px 5px rgba(0,0,0,0.2); } -.season-episodes-instance-text-wrapper { - width: 250px; - font-size: 13px; - margin-bottom: 20px; - clear: both; +.season-episodes-overlay-text { + color: #aaa; + font-size: 12px; + float: left; + position: absolute; + left: 8px; + bottom: 5px; } .season-episodes-instance-text-wrapper h3 { padding: 5px 3px 0 3px; @@ -1272,20 +1308,6 @@ a .season-episodes-card-overlay:hover { -moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); } -.user-info-poster-face img { - bottom: 0; - margin-right: 15px; - overflow: hidden; - float: left; - background-color: #323232; - background-position: center; - background-size: cover; - -webkit-border-radius: 1000px; - -moz-border-radius: 1000px; - border-radius: 1000px; - -webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); - box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1); -} .user-info-username { font-size: 24px; color: #fff; @@ -2150,4 +2172,4 @@ a .home-platforms-instance-list-oval:hover, border: 3px solid transparent; border-radius: 8px; background-clip: padding-box; -} \ No newline at end of file +} diff --git a/data/interfaces/default/info.html b/data/interfaces/default/info.html index 5dfc51dc..c2cacf2a 100644 --- a/data/interfaces/default/info.html +++ b/data/interfaces/default/info.html @@ -47,211 +47,217 @@ DOCUMENTATION :: END % if data:
-
-
-
-
-
-
- -
-
- % if data['type'] == 'movie': -

${data['title']}

- % elif data['type'] == 'season': -

${data['parent_title']} (${data['title']})

- % elif data['type'] == 'episode': -

${data['grandparent_title']} - ${data['title']} - (Season ${data['parent_index']}, Episode ${data['index']})

- % else: -

${data['title']}

- % endif -
- % if (data['type'] == 'movie' or data['type'] == 'show' or data['type'] == 'episode') and data['rating']: - - % endif -
-
- % if (data['type'] == 'episode' or data['type'] == 'movie') and data['directors']: - Directed by ${data['directors'][0]} - % endif -
-
- % if (data['type'] == 'show' or data['type'] == 'movie') and data['studio']: - Studio ${data['studio']} - % endif -
-
- % if data['type'] == 'movie': - Year ${data['year']} - % elif data['type'] == 'show': - Aired ${data['year']} - % elif data['type'] == 'episode': - Aired ${data['originally_available_at']} - % endif -
-
- Runtime ${data['duration']} mins -
-
- % if (data['type'] == 'episode' or data['type'] == 'movie' or data['type'] == 'show') and data['content_rating']: - Rated ${data['content_rating']} - % endif -
-
-
-

${data['summary']}

-
-
-
-
- - -
-
+
+
+
+
+
+ % if data['type'] == 'movie': + Movies + + ${data['title']} + % elif data['type'] == 'show': + TV Shows + + ${data['title']} + % elif data['type'] == 'season': + TV Shows + + ${data['parent_title']} + + Season ${data['index']} + % elif data['type'] == 'episode': + TV Shows + + ${data['grandparent_title']} + + Season ${data['parent_index']} + + ${data['title']} + % endif
-
-
-
-% if data['type'] == 'movie' or data['type'] == 'episode' or data['type'] == 'show': -
-
-
-
-
- Watch History for ${data['title']} -
-
- -   - - -
-
-
- - - - - - - - - - - - - - - - - - -
DeleteTimeUserIP AddressPlatformTitleStartedPausedStoppedDuration
-
- - - -% elif data['type'] == 'season': -
-
-
-
-
- Episode List for ${data['title']} +
+
+ % if data['type'] == 'movie' or data['type'] == 'show' or data['type'] == 'season': + + % else: + + % endif +
+
+ % if (data['type'] == 'movie' or data['type'] == 'show' or data['type'] == 'episode') and data['rating']: + + % endif +
+ % if (data['type'] == 'episode' or data['type'] == 'movie') and data['directors']: + Directed by ${data['directors'][0]} + % endif +
+
+ % if (data['type'] == 'show' or data['type'] == 'movie') and data['studio']: + Studio ${data['studio']} + % endif +
+
+ % if data['type'] == 'movie': + Year ${data['year']} + % elif data['type'] == 'show': + Aired ${data['year']} + % elif data['type'] == 'episode': + Aired ${data['originally_available_at']} + % endif +
+
+ Runtime ${data['duration']} mins +
+
+ % if (data['type'] == 'episode' or data['type'] == 'movie' or data['type'] == 'show') and data['content_rating']: + Rated ${data['content_rating']} + % endif +
+
+
+

${data['summary']}

+
+
+
+ + +
+ % if data['type'] == 'show': +
+
+
+ Season List for ${data['title']} +
+
+
+
+
+
+ % elif data['type'] == 'season': +
+
+
+ Episode List for ${data['title']} +
+
+
+
+
+
+ % endif + % if data['type'] == 'movie' or data['type'] == 'episode' or data['type'] == 'show' or data['type'] == 'season': +
+
+
+ Watch History for ${data['title']} +
+
+   + +
+
+
+ + + + + + + + + + + + + + + + + +
DeleteTimeUserIP AddressPlatformTitleStartedPausedStoppedDuration
+
+ + +
+ % endif
-
-
-
- % endif
@@ -259,8 +265,10 @@ DOCUMENTATION :: END
-

Error retrieving item data. This media may not be available in the Plex Media Server database - anymore.

+

+ Error retrieving item data. This media may not be available in the Plex Media Server database + anymore. +

@@ -292,47 +300,22 @@ DOCUMENTATION :: END type: 'post', data: function ( d ) { return { 'json_data': JSON.stringify( d ), - 'rating_key': ${data['rating_key']} - }; + 'rating_key': ${data['rating_key']} }; } } history_table = $('#history_table').DataTable(history_table_options); var colvis = new $.fn.dataTable.ColVis(history_table, { buttonText: ' Select columns', buttonClass: 'btn btn-dark', exclude: [0, 10] }); $(colvis.button()).appendTo('div.colvis-button-bar'); - + clearSearchButton('history_table', history_table); - $('#row-edit-mode').on('click', function() { - $('#delete-message').popover(); - + $('#row-edit-mode').click(function() { if ($(this).hasClass('active')) { - if (history_to_delete.length > 0) { - $('#deleteCount').text(history_to_delete.length); - $('#confirm-modal').modal(); - $('#confirm-modal').one('click', '#confirm-delete', function () { - for (var i = 0; i < history_to_delete.length; i++) { - $.ajax({ - url: 'delete_history_rows', - data: { row_id: history_to_delete[i] }, - async: true, - success: function (data) { - var msg = "User history purged"; - showMsg(msg, false, true, 2000); - } - }); - } - history_table.draw(); - }); - } - - $('.delete-control').each(function () { - $(this).find('button.btn-danger').toggleClass('btn-warning').toggleClass('btn-danger'); + $('.delete-control').each(function() { $(this).addClass('hidden'); }); - } else { - history_to_delete = []; $('.delete-control').each(function() { $(this).removeClass('hidden'); }); @@ -349,8 +332,7 @@ DOCUMENTATION :: END type: 'post', data: function ( d ) { return { 'json_data': JSON.stringify( d ), - 'grandparent_rating_key': ${data['rating_key']} - }; + 'grandparent_rating_key': ${data['rating_key']} }; } } history_table = $('#history_table').DataTable(history_table_options); @@ -371,19 +353,54 @@ DOCUMENTATION :: END } }); }); - -% endif - -% if data['type'] == 'season': - +% endif +% if data['type'] == 'season': + + % endif @@ -392,4 +409,7 @@ DOCUMENTATION :: END $("#runtime").html(millisecondsToMinutes($("#runtime").text(), true)); % endif + diff --git a/data/interfaces/default/info_episode_list.html b/data/interfaces/default/info_episode_list.html index ef02c42c..11651969 100644 --- a/data/interfaces/default/info_episode_list.html +++ b/data/interfaces/default/info_episode_list.html @@ -34,7 +34,7 @@ DOCUMENTATION :: END
-
+
Episode ${a['index']}
diff --git a/data/interfaces/default/info_season_list.html b/data/interfaces/default/info_season_list.html new file mode 100644 index 00000000..6da68e0e --- /dev/null +++ b/data/interfaces/default/info_season_list.html @@ -0,0 +1,55 @@ +<%doc> +USAGE DOCUMENTATION :: PLEASE LEAVE THIS AT THE TOP OF THIS FILE + +For Mako templating syntax documentation please visit: http://docs.makotemplates.org/en/latest/ + +Filename: info_season_list.html +Version: 0.1 +Variable names: data [list] + +data :: Usable parameters + +== Global keys == +season_count Returns the number of seasons in the array. +season_list Returns an array of seasons. + +data['season_list'] :: Usable paramaters + +== Global keys == +rating_key Returns the unique identifier for the media item. +thumb Returns the location of the item's thumbnail. Use with pms_image_proxy. +title Returns the name of the season. +index Returns the season number. + +DOCUMENTATION :: END + + +% if data != None: +% if data['season_count'] > 0: +
+ +
+% endif +% endif \ No newline at end of file diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index 5257f5ae..c7fed0d7 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -55,6 +55,7 @@ class DataFactory(object): (CASE WHEN session_history_metadata.duration IS NULL THEN 1.0 ELSE \ session_history_metadata.duration * 1.0 END) * 100) as percent_complete', 'session_history.grandparent_rating_key as grandparent_rating_key', + 'session_history.parent_rating_key as parent_rating_key', 'session_history.rating_key as rating_key', 'session_history.user', 'session_history_metadata.media_type', @@ -112,6 +113,7 @@ class DataFactory(object): "duration": item["duration"], "percent_complete": item["percent_complete"], "grandparent_rating_key": item["grandparent_rating_key"], + "parent_rating_key": item["parent_rating_key"], "rating_key": item["rating_key"], "user": item["user"], "media_type": item["media_type"], diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py index 7fb15618..dba5b0b8 100644 --- a/plexpy/pmsconnect.py +++ b/plexpy/pmsconnect.py @@ -89,6 +89,23 @@ class PmsConnect(object): return request + """ + Return list of seasons in requested show. + + Parameters required: rating_key { ratingKey of parent } + Optional parameters: output_format { dict, json } + + Output: array + """ + def get_season_list(self, rating_key='', output_format=''): + uri = '/library/metadata/' + rating_key + '/children' + request = self.request_handler.make_request(uri=uri, + proto=self.protocol, + request_type='GET', + output_format=output_format) + + return request + """ Return list of episodes in requested season. @@ -103,7 +120,7 @@ class PmsConnect(object): proto=self.protocol, request_type='GET', output_format=output_format) - + return request """ @@ -798,6 +815,49 @@ class PmsConnect(object): return session_output + """ + Return processed and validated season list. + + Output: array + """ + def get_show_children(self, rating_key=''): + season_data = self.get_season_list(rating_key, output_format='xml') + + try: + xml_head = season_data.getElementsByTagName('MediaContainer') + except: + logger.warn("Unable to parse XML for get_season_list.") + return [] + + season_list = [] + + for a in xml_head: + if a.getAttribute('size'): + if a.getAttribute('size') == '0': + logger.debug(u"No season data.") + episode_list = {'season_count': '0', + 'season_list': [] + } + return season_list + + if a.getElementsByTagName('Directory'): + result_data = a.getElementsByTagName('Directory') + for result in result_data: + season_output = {'rating_key': helpers.get_xml_attr(result, 'ratingKey'), + 'index': helpers.get_xml_attr(result, 'index'), + 'title': helpers.get_xml_attr(result, 'title'), + 'thumb': helpers.get_xml_attr(result, 'thumb'), + 'parent_thumb': helpers.get_xml_attr(a, 'thumb') + } + season_list.append(season_output) + + output = {'season_count': helpers.get_xml_attr(xml_head[0], 'size'), + 'title': helpers.get_xml_attr(xml_head[0], 'title2'), + 'season_list': season_list + } + + return output + """ Return processed and validated episode list. diff --git a/plexpy/webserve.py b/plexpy/webserve.py index ee62f960..f2b6067b 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -569,6 +569,9 @@ class WebInterface(object): if 'rating_key' in kwargs: rating_key = kwargs.get('rating_key', "") custom_where = [['rating_key', rating_key]] + if 'parent_rating_key' in kwargs: + rating_key = kwargs.get('parent_rating_key', "") + custom_where = [['parent_rating_key', rating_key]] if 'grandparent_rating_key' in kwargs: rating_key = kwargs.get('grandparent_rating_key', "") custom_where = [['grandparent_rating_key', rating_key]] @@ -806,7 +809,19 @@ class WebInterface(object): return serve_template(templatename="user_platform_stats.html", data=None, title="Platform Stats") @cherrypy.expose - def get_children(self, rating_key='', **kwargs): + def get_show_children(self, rating_key='', **kwargs): + + pms_connect = pmsconnect.PmsConnect() + result = pms_connect.get_show_children(rating_key) + + if result: + return serve_template(templatename="info_season_list.html", data=result, title="Season List") + else: + logger.warn('Unable to retrieve data.') + return serve_template(templatename="info_season_list.html", data=None, title="Season List") + + @cherrypy.expose + def get_season_children(self, rating_key='', **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_season_children(rating_key)