Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
29c7853380 | ||
![]() |
cd417aaf44 | ||
![]() |
428a5cc0ff | ||
![]() |
d128d7c8e6 | ||
![]() |
8027199bd5 | ||
![]() |
099a887cc7 | ||
![]() |
ea41d06023 | ||
![]() |
5147baab05 | ||
![]() |
1c50e615cf | ||
![]() |
ed2d34e979 | ||
![]() |
c404016700 | ||
![]() |
14b0353ba4 | ||
![]() |
fbe136a350 | ||
![]() |
4fcfea943e | ||
![]() |
279d27d081 | ||
![]() |
651125ef2c | ||
![]() |
a5eb0e7faa |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,5 +1,26 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.4.20 (2017-06-24)
|
||||||
|
|
||||||
|
* New: Added platform image for the PlexTogether player.
|
||||||
|
* Fix: Corrected math used to calculate human duration. (Thanks @senepa)
|
||||||
|
* Fix: Sorting of 4k in media info tables.
|
||||||
|
* Fix: Update file sizes when refreshing media info tables.
|
||||||
|
* Fix: Support a custom port for Mattermost (Slack) notifications.
|
||||||
|
|
||||||
|
|
||||||
|
## v1.4.19 (2017-05-31)
|
||||||
|
|
||||||
|
* Fix: Video resolution not showing up for transcoded streams on PMS 1.7.x.
|
||||||
|
|
||||||
|
|
||||||
|
## v1.4.18 (2017-04-22)
|
||||||
|
|
||||||
|
* New: Added some new Arnold quotes. (Thanks @senepa)
|
||||||
|
* Fix: Text wrapping in datatable footers.
|
||||||
|
* Fix: API command get_apikey. (Thanks @Hellowlol)
|
||||||
|
|
||||||
|
|
||||||
## v1.4.17 (2017-03-04)
|
## v1.4.17 (2017-03-04)
|
||||||
|
|
||||||
* New: Configurable month range for the Plays by month graph. (Thanks @Pbaboe)
|
* New: Configurable month range for the Plays by month graph. (Thanks @Pbaboe)
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
# PlexPy
|
# PlexPy
|
||||||
|
|
||||||
[](https://gitter.im/plexpy/general?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://discord.gg/36ggawe)
|
||||||
|
[](https://gitter.im/plexpy/general)
|
||||||
|
[](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program)
|
||||||
|
|
||||||
A python based web application for monitoring, analytics and notifications for [Plex Media Server](https://plex.tv).
|
A python based web application for monitoring, analytics and notifications for [Plex Media Server](https://plex.tv).
|
||||||
|
|
||||||
This project is based on code from [Headphones](https://github.com/rembo10/headphones) and [PlexWatchWeb](https://github.com/ecleese/plexWatchWeb).
|
This project is based on code from [Headphones](https://github.com/rembo10/headphones) and [PlexWatchWeb](https://github.com/ecleese/plexWatchWeb).
|
||||||
|
|
||||||
* [Plex forum thread](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program)
|
|
||||||
* [Gitter chat](https://gitter.im/plexpy/general)
|
|
||||||
* [/r/Plex Discord server](https://discord.gg/011TFFWSuNFI02EKr) | [PlexPy Discord server](https://discord.gg/36ggawe)
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Responsive web design viewable on desktop, tablet and mobile web browsers.
|
* Responsive web design viewable on desktop, tablet and mobile web browsers.
|
||||||
|
@@ -223,7 +223,7 @@
|
|||||||
<li><a href="${anon_url('https://github.com/%s/plexpy/wiki/Frequently-Asked-Questions-(FAQ)' % plexpy.CONFIG.GIT_USER)}" target="_blank"><i class="fa fa-fw fa-question-circle"></i> FAQ</a></li>
|
<li><a href="${anon_url('https://github.com/%s/plexpy/wiki/Frequently-Asked-Questions-(FAQ)' % plexpy.CONFIG.GIT_USER)}" target="_blank"><i class="fa fa-fw fa-question-circle"></i> FAQ</a></li>
|
||||||
<li><a href="settings?support=true"><i class="fa fa-fw fa-comment"></i> Support</a></li>
|
<li><a href="settings?support=true"><i class="fa fa-fw fa-comment"></i> Support</a></li>
|
||||||
<li role="separator" class="divider"></li>
|
<li role="separator" class="divider"></li>
|
||||||
<li><a href="${anon_url('https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DG783BMSCU3V4')}" target="_blank"><i class="fa fa-fw fa-paypal"></i> Paypal</a></li>
|
<li><a href="${anon_url('https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=6XPPKTDSX9QFL&lc=US&item_name=PlexPy¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted')}" target="_blank"><i class="fa fa-fw fa-paypal"></i> Paypal</a></li>
|
||||||
<li><a href="${anon_url('https://www.coinbase.com/JonnyWong16')}" target="_blank"><i class="fa fa-fw fa-btc"></i> Bitcoin</a></li>
|
<li><a href="${anon_url('https://www.coinbase.com/JonnyWong16')}" target="_blank"><i class="fa fa-fw fa-btc"></i> Bitcoin</a></li>
|
||||||
<li role="separator" class="divider"></li>
|
<li role="separator" class="divider"></li>
|
||||||
% if plexpy.CONFIG.CHECK_GITHUB:
|
% if plexpy.CONFIG.CHECK_GITHUB:
|
||||||
|
@@ -2491,6 +2491,9 @@ a .home-platforms-list-cover-face:hover
|
|||||||
.dataTables_paginate li {
|
.dataTables_paginate li {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
div.dataTables_info {
|
||||||
|
white-space: normal !important;
|
||||||
|
}
|
||||||
.tooltip.top .tooltip-arrow {
|
.tooltip.top .tooltip-arrow {
|
||||||
border-top-color: #fff;
|
border-top-color: #fff;
|
||||||
}
|
}
|
||||||
|
BIN
data/interfaces/default/images/platforms/plextogether.png
Normal file
BIN
data/interfaces/default/images/platforms/plextogether.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
@@ -256,6 +256,8 @@ function getPlatformImagePath(platformName) {
|
|||||||
return 'images/platforms/wp.png';
|
return 'images/platforms/wp.png';
|
||||||
} else if (platformName.indexOf("Plex Media Player") > -1) {
|
} else if (platformName.indexOf("Plex Media Player") > -1) {
|
||||||
return 'images/platforms/pmp.png';
|
return 'images/platforms/pmp.png';
|
||||||
|
} else if (platformName.indexOf("PlexTogether") > -1) {
|
||||||
|
return 'images/platforms/plextogether.png';
|
||||||
} else {
|
} else {
|
||||||
return 'images/platforms/default.png';
|
return 'images/platforms/default.png';
|
||||||
}
|
}
|
||||||
|
@@ -407,7 +407,7 @@ General optional parameters:
|
|||||||
data = None
|
data = None
|
||||||
apikey = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[0:32]
|
apikey = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[0:32]
|
||||||
if plexpy.CONFIG.HTTP_USERNAME and plexpy.CONFIG.HTTP_PASSWORD:
|
if plexpy.CONFIG.HTTP_USERNAME and plexpy.CONFIG.HTTP_PASSWORD:
|
||||||
if username == plexpy.HTTP_USERNAME and password == plexpy.CONFIG.HTTP_PASSWORD:
|
if username == plexpy.CONFIG.HTTP_USERNAME and password == plexpy.CONFIG.HTTP_PASSWORD:
|
||||||
if plexpy.CONFIG.API_KEY:
|
if plexpy.CONFIG.API_KEY:
|
||||||
data = plexpy.CONFIG.API_KEY
|
data = plexpy.CONFIG.API_KEY
|
||||||
else:
|
else:
|
||||||
|
@@ -204,10 +204,10 @@ def human_duration(s, sig='dhms'):
|
|||||||
hd = ''
|
hd = ''
|
||||||
|
|
||||||
if str(s).isdigit() and s > 0:
|
if str(s).isdigit() and s > 0:
|
||||||
d = int(s / 84600)
|
d = int(s / 86400)
|
||||||
h = int((s % 84600) / 3600)
|
h = int((s % 86400) / 3600)
|
||||||
m = int(((s % 84600) % 3600) / 60)
|
m = int(((s % 86400) % 3600) / 60)
|
||||||
s = int(((s % 84600) % 3600) % 60)
|
s = int(((s % 86400) % 3600) % 60)
|
||||||
|
|
||||||
hd_list = []
|
hd_list = []
|
||||||
if sig >= 'd' and d > 0:
|
if sig >= 'd' and d > 0:
|
||||||
|
@@ -382,7 +382,7 @@ class Libraries(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# If no cache was imported, get all library children items
|
# If no cache was imported, get all library children items
|
||||||
cached_items = {d['rating_key']: d['file_size'] for d in rows}
|
cached_items = {d['rating_key']: d['file_size'] for d in rows} if not refresh else {}
|
||||||
|
|
||||||
if refresh or not rows:
|
if refresh or not rows:
|
||||||
pms_connect = pmsconnect.PmsConnect()
|
pms_connect = pmsconnect.PmsConnect()
|
||||||
@@ -491,6 +491,8 @@ class Libraries(object):
|
|||||||
results = sorted(results, key=lambda k: helpers.cast_to_int(k['media_index']), reverse=reverse)
|
results = sorted(results, key=lambda k: helpers.cast_to_int(k['media_index']), reverse=reverse)
|
||||||
elif sort_key == 'file_size' or sort_key == 'bitrate':
|
elif sort_key == 'file_size' or sort_key == 'bitrate':
|
||||||
results = sorted(results, key=lambda k: helpers.cast_to_int(k[sort_key]), reverse=reverse)
|
results = sorted(results, key=lambda k: helpers.cast_to_int(k[sort_key]), reverse=reverse)
|
||||||
|
elif sort_key == 'video_resolution':
|
||||||
|
results = sorted(results, key=lambda k: helpers.cast_to_int(k[sort_key].replace('4k', '2160p').rstrip('p')), reverse=reverse)
|
||||||
else:
|
else:
|
||||||
results = sorted(results, key=lambda k: k[sort_key], reverse=reverse)
|
results = sorted(results, key=lambda k: k[sort_key], reverse=reverse)
|
||||||
|
|
||||||
|
@@ -2062,9 +2062,10 @@ class SLACK(object):
|
|||||||
data['attachments'] = [attachment]
|
data['attachments'] = [attachment]
|
||||||
|
|
||||||
slackhost = urlparse(self.slack_hook).hostname
|
slackhost = urlparse(self.slack_hook).hostname
|
||||||
|
slackport = urlparse(self.slack_hook).port
|
||||||
slackpath = urlparse(self.slack_hook).path
|
slackpath = urlparse(self.slack_hook).path
|
||||||
|
|
||||||
http_handler = HTTPSConnection(slackhost)
|
http_handler = HTTPSConnection(slackhost, slackport)
|
||||||
http_handler.request("POST",
|
http_handler.request("POST",
|
||||||
slackpath,
|
slackpath,
|
||||||
headers={'Content-type': "application/json"},
|
headers={'Content-type': "application/json"},
|
||||||
|
@@ -1186,8 +1186,8 @@ class PmsConnect(object):
|
|||||||
transcode_audio_codec = helpers.get_xml_attr(transcode_session, 'audioCodec')
|
transcode_audio_codec = helpers.get_xml_attr(transcode_session, 'audioCodec')
|
||||||
video_decision = helpers.get_xml_attr(transcode_session, 'videoDecision')
|
video_decision = helpers.get_xml_attr(transcode_session, 'videoDecision')
|
||||||
transcode_video_codec = helpers.get_xml_attr(transcode_session, 'videoCodec')
|
transcode_video_codec = helpers.get_xml_attr(transcode_session, 'videoCodec')
|
||||||
transcode_width = helpers.get_xml_attr(transcode_session, 'width')
|
transcode_width = helpers.get_xml_attr(transcode_session, 'width') or width
|
||||||
transcode_height = helpers.get_xml_attr(transcode_session, 'height')
|
transcode_height = helpers.get_xml_attr(transcode_session, 'height') or height
|
||||||
transcode_container = helpers.get_xml_attr(transcode_session, 'container')
|
transcode_container = helpers.get_xml_attr(transcode_session, 'container')
|
||||||
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
||||||
else:
|
else:
|
||||||
@@ -1443,8 +1443,8 @@ class PmsConnect(object):
|
|||||||
transcode_speed = helpers.get_xml_attr(transcode_session, 'speed')
|
transcode_speed = helpers.get_xml_attr(transcode_session, 'speed')
|
||||||
video_decision = helpers.get_xml_attr(transcode_session, 'videoDecision')
|
video_decision = helpers.get_xml_attr(transcode_session, 'videoDecision')
|
||||||
transcode_video_codec = helpers.get_xml_attr(transcode_session, 'videoCodec')
|
transcode_video_codec = helpers.get_xml_attr(transcode_session, 'videoCodec')
|
||||||
transcode_width = helpers.get_xml_attr(transcode_session, 'width')
|
transcode_width = helpers.get_xml_attr(transcode_session, 'width') or width
|
||||||
transcode_height = helpers.get_xml_attr(transcode_session, 'height')
|
transcode_height = helpers.get_xml_attr(transcode_session, 'height') or height
|
||||||
transcode_container = helpers.get_xml_attr(transcode_session, 'container')
|
transcode_container = helpers.get_xml_attr(transcode_session, 'container')
|
||||||
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
||||||
else:
|
else:
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
PLEXPY_VERSION = "master"
|
PLEXPY_VERSION = "master"
|
||||||
PLEXPY_RELEASE_VERSION = "1.4.17"
|
PLEXPY_RELEASE_VERSION = "1.4.20"
|
||||||
|
@@ -4312,13 +4312,18 @@ class WebInterface(object):
|
|||||||
'Come with me if you want to live.',
|
'Come with me if you want to live.',
|
||||||
'Who is your daddy and what does he do?',
|
'Who is your daddy and what does he do?',
|
||||||
'Oh, cookies! I can\'t wait to toss them.',
|
'Oh, cookies! I can\'t wait to toss them.',
|
||||||
'Can you hurry up. My horse is getting tired.',
|
'Make it quick because my horse is getting tired.',
|
||||||
'What killed the dinosaurs? The Ice Age!',
|
'What killed the dinosaurs? The Ice Age!',
|
||||||
'That\'s for sleeping with my wife!',
|
'That\'s for sleeping with my wife!',
|
||||||
'Remember when I said I\'d kill you last... I lied!',
|
'Remember when I said I\'d kill you last... I lied!',
|
||||||
'You want to be a farmer? Here\'s a couple of acres',
|
'You want to be a farmer? Here\'s a couple of acres',
|
||||||
'Now, this is the plan. Get your ass to Mars.',
|
'Now, this is the plan. Get your ass to Mars.',
|
||||||
'I just had a terrible thought... What if this is a dream?'
|
'I just had a terrible thought... What if this is a dream?',
|
||||||
|
'Well, listen to this one: Rubber baby buggy bumpers!',
|
||||||
|
'Take your toy back to the carpet!',
|
||||||
|
'My name is John Kimble... And I love my car.',
|
||||||
|
'I eat Green Berets for breakfast.',
|
||||||
|
'Put that cookie down! NOW!'
|
||||||
]
|
]
|
||||||
|
|
||||||
random_number = randint(0, len(quote_list) - 1)
|
random_number = randint(0, len(quote_list) - 1)
|
||||||
|
Reference in New Issue
Block a user