Compare commits

...

138 Commits

Author SHA1 Message Date
JonnyWong16
05e485b55e Merge branch 'dev' 2016-01-23 13:23:45 -08:00
JonnyWong16
c62e0e4e99 v1.3.0 2016-01-23 13:21:51 -08:00
JonnyWong16
3c6a1a02b8 Merge pull request #462 from jackwilsdon/fix-restart-dev
Use os.execv instead of subprocess.Popen to restart the process
2016-01-23 13:16:13 -08:00
JonnyWong16
cc287607cd Allow custom search query to update metadata 2016-01-23 12:40:41 -08:00
JonnyWong16
b24e9a2185 Allow custom redirect uri with Facebook notifier 2016-01-23 08:12:41 -08:00
JonnyWong16
01791eac52 Fix rating_key on sync table 2016-01-23 08:05:04 -08:00
JonnyWong16
651b57a93f Add datestamp and timestamp notification options 2016-01-22 19:16:15 -08:00
JonnyWong16
cc857364f4 Fix typos in Notifiers logger 2016-01-22 18:01:32 -08:00
JonnyWong16
f29d7c8cfb Fix stream info modal on Users and Libraries pages 2016-01-22 17:59:20 -08:00
JonnyWong16
af4d0248d9 Revert https cert and key to custom directory 2016-01-22 10:17:17 -08:00
JonnyWong16
2990664b2b Fix section_id for plexwatch import 2016-01-22 09:09:37 -08:00
Jack Wilsdon
ed52038bc4 Use os.execv instead of subprocess.Popen to restart the process
This fixes #460.
2016-01-22 13:19:27 +00:00
JonnyWong16
ee125dfadc Forgot 'not' in 2dcae5e219 2016-01-19 08:31:49 -08:00
JonnyWong16
196048cf38 Work around for iOS web app links opening in Safari 2016-01-19 00:06:14 -08:00
JonnyWong16
5faf357045 Disable logging while library update in progress 2016-01-18 23:48:31 -08:00
JonnyWong16
4e0f06f24d Remove unique constraint for section_id and username 2016-01-18 22:20:14 -08:00
JonnyWong16
717530fff7 Fix Users list not sorting alphabetically 2016-01-18 19:55:10 -08:00
JonnyWong16
4a5e38dc1e Fix error refreshing library counts when XML fails
* Also increase http request timeout to 20 seconds
2016-01-18 19:27:58 -08:00
JonnyWong16
419f8dadad Fix another typo 2016-01-18 19:03:55 -08:00
JonnyWong16
2dcae5e219 Fix folders not created in the data directory 2016-01-18 18:52:01 -08:00
JonnyWong16
36a99f70a3 Fix error when script directory doesn't exist 2016-01-18 18:30:22 -08:00
JonnyWong16
c98cf858c1 Fix typo on edit library and edit user modals 2016-01-18 18:24:07 -08:00
JonnyWong16
dd463f00a7 Fix Facebook authorization not working 2016-01-18 18:22:48 -08:00
JonnyWong16
2459340c6f Fix user duplicated in Library user stats 2016-01-18 12:59:26 -08:00
JonnyWong16
76db5ffa3a Use font awesome for star rating 2016-01-17 22:16:12 -08:00
JonnyWong16
2db0e9c280 Add all media flags 2016-01-17 22:14:16 -08:00
JonnyWong16
db6dbe6c19 Fix refresh media info table doubling rows 2016-01-17 22:14:12 -08:00
JonnyWong16
ecedd4d231 Merge pull request #263 from drzoidberg33/library-id-changes
Library id changes
2016-01-17 16:43:46 -08:00
JonnyWong16
1809b95e2d Add setting to enable calculating total file sizes
* Setting is disabled by default
2016-01-17 16:15:28 -08:00
JonnyWong16
0d7e261bd1 Improved caching and fixed tables 2016-01-17 12:34:23 -08:00
JonnyWong16
908941fb82 Prettier thumbnail popovers 2016-01-17 01:10:25 -08:00
JonnyWong16
fbacc4f789 Add media info icons to info page 2016-01-16 23:17:04 -08:00
Jonathan Wong
3c1290e8fd Some more minor changes 2016-01-16 19:27:40 -08:00
Jonathan Wong
35528ef602 Get file sizes for media info table 2016-01-16 18:23:08 -08:00
Jonathan Wong
c0f0cb0d9e Don't cache last watched or play count 2016-01-16 04:10:21 -08:00
Jonathan Wong
4a65dc1d6e Start database section id update on its own thread 2016-01-16 03:31:00 -08:00
Jonathan Wong
b4a25e33bb Fix websocket log spam
* Bug where websocket reports a session playing while /status/sessions
reports nothing.
2016-01-16 03:28:39 -08:00
Jonathan Wong
7f1a08dd04 Final clean up 2016-01-16 01:51:50 -08:00
Jonathan Wong
6152a1e913 Fix bugs with media info table 2016-01-15 22:15:45 -08:00
Jonathan Wong
002cb93187 Clean up for welcome page 2016-01-15 20:59:14 -08:00
Jonathan Wong
381c3da31c Add media info table to library page 2016-01-15 20:59:02 -08:00
Jonathan Wong
10e4d562ab Clean up graphs.py 2016-01-15 20:58:57 -08:00
Jonathan Wong
2a85e11ad9 Add library recently added 2016-01-15 20:58:55 -08:00
Jonathan Wong
95b55760ad Add sortable homepage cards 2016-01-15 20:58:53 -08:00
Jonathan Wong
636f898da8 Massive code cleanup
* Finish up library pages (toggles and notifications)
* Update user pages to match library pages
* Fix no current activity bif thumbnail at the start of a stream
* Improved logging throughout PlexPy
2016-01-15 20:58:44 -08:00
Jonathan Wong
5fedac691d Add individual library page 2016-01-15 20:50:18 -08:00
Jonathan Wong
979d68957e Clean up users page to match libraries page 2016-01-15 20:49:59 -08:00
Jonathan Wong
a5b0837cf5 Add libraries page 2016-01-15 20:49:41 -08:00
Jonathan Wong
8ba68dcfcf Change home cards config to list type 2016-01-15 20:49:22 -08:00
Jonathan Wong
8f367d140f Add item counts to database
* Add schedule task to refresh libraries list
* Update library stats to use library_sections table
2016-01-15 20:49:04 -08:00
Jonathan Wong
771885f27f Add update metadata feature
* Use rating_key instead of item_id for history info
2016-01-15 20:48:47 -08:00
Jonathan Wong
09aac22909 Initial library_id changes
* Give the library sections their own db table.
2016-01-15 20:48:29 -08:00
Jonathan Wong
1de3c0d559 Fixes for testing script notifications 2016-01-15 00:33:40 -08:00
JonnyWong16
0988b68c8c Merge pull request #391 from PHoSawyer/dev
CentOS 6.X startup script
2016-01-13 00:24:31 -08:00
Jonathan Wong
325ad4094e Clean up Web Apps 2016-01-13 00:16:50 -08:00
JonnyWong16
16a09407e4 Merge pull request #436 from zobe123/dev
Web Apps
2016-01-13 00:12:12 -08:00
JonnyWong16
84256f42c6 Merge pull request #419 from JonnyWong16/facebook-agent
Add Facebook notification agent
2016-01-12 23:28:03 -08:00
JonnyWong16
7befbef6ec Add Facebook notification agent 2016-01-12 23:22:54 -08:00
Jonathan Wong
754df5bea7 Fix to get new pms identifier on server change 2016-01-12 22:39:32 -08:00
Jonathan Wong
78ee646558 Fix for empty most concurrent stat 2016-01-12 22:06:21 -08:00
Jonathan Wong
3d6f89d309 Clean up scripts 2016-01-12 21:38:47 -08:00
JonnyWong16
e321479712 Merge pull request #373 from Hellowlol/scripts
Scripts
2016-01-12 21:05:26 -08:00
Hellowlol
9328b7e586 Add scripts 2016-01-12 22:12:48 +01:00
zobe123
50ace54cd0 improvements 2016-01-12 20:59:32 +01:00
Hellowlol
ad365c7dd0 fix conflicts 2016-01-11 22:24:13 +01:00
zobe123
11427dbecd added commits how JonnyWong16 wanted
* added iOS WebAPP Icons/Splashscreens
* added android WebAPP Icons/Splashscreens
* added IE10 Icons
* Updated plexpy.css - prevents the text is larger than the box on small
screens.
2016-01-11 21:31:46 +01:00
Jonathan Wong
b490831a50 More concurrent stream stats
* Also fix graph queries
2016-01-08 22:49:04 -08:00
JonnyWong16
af76017a79 Fix datatable paging visual bug in Firefox 2016-01-08 17:58:04 -08:00
JonnyWong16
43409b3089 Fix month name localization on play totals graph
#423
2016-01-07 20:37:00 -08:00
Jonathan Wong
bfad769f93 Return message for missing changelog file 2016-01-06 18:54:30 -08:00
Jonathan Wong
7e5dce1c14 Fix regression for grouped recently added metadata 2016-01-03 23:49:58 -08:00
JonnyWong16
8ba4bebe01 Merge pull request #401 from Hellowlol/patch-4
Enable webapp for mobile devices
2015-12-31 20:16:39 -08:00
JonnyWong16
78a87db017 Merge pull request #414 from JonnyWong16/miscellaneous-fixes
Allow SSL when verifying server in settings and test notifications
2015-12-31 20:14:12 -08:00
JonnyWong16
b73a259f68 Clean up Slack agent 2015-12-31 20:13:54 -08:00
JonnyWong16
65f27ee605 Add Email from name option 2015-12-31 20:06:31 -08:00
JonnyWong16
6d5b5e15d5 Remove PlexPy Pushover API token
* User's own API token is now required
2015-12-31 20:06:29 -08:00
JonnyWong16
f31c4dcccd Add test notification for all agents 2015-12-31 20:04:08 -08:00
JonnyWong16
1e616fa585 Allow SSL when verifying server in settings 2015-12-31 20:02:54 -08:00
JonnyWong16
0d2666f7d3 Merge pull request #418 from richipargo/slack-agent
Add slack as a notification agent
2015-12-31 19:58:57 -08:00
Ricardo Tapia
0dd8970668 added url icon validation 2015-12-31 21:13:20 -06:00
Ricardo Tapia
89cda3dcff typo for telegram agent 2015-12-31 21:08:24 -06:00
Ricardo Tapia
1d48688518 finished slack integration 2015-12-31 21:04:33 -06:00
richipargo
0b59f5e29c Slack notification config 2015-12-31 16:26:10 -06:00
Ricardo Tapia
5aebc8d191 slack config options 2015-12-31 15:34:53 -06:00
richipargo
6e00c5da04 Return Settings 2015-12-31 15:21:01 -06:00
Ricardo Tapia
50b06e041c initial agent settings 2015-12-31 13:22:27 -06:00
JonnyWong16
1c539f00dd Fix duration for grouped home stats 2015-12-27 19:46:29 -08:00
JonnyWong16
87ca432ec8 Fix get server friendly name after wizard 2015-12-26 19:55:36 -08:00
Hellowlol
ca33f4a2a5 webapp
https://github.com/drzoidberg33/plexpy/issues/398
2015-12-27 01:07:31 +01:00
Jonathan Wong
9409303f24 Merge branch 'dev' 2015-12-22 19:36:10 -08:00
Jonathan Wong
94a3d35c90 v1.2.16 2015-12-22 19:35:11 -08:00
Jonathan Wong
851de4934b Change logs to 50 line default 2015-12-22 19:31:59 -08:00
JonnyWong16
2942640eb9 Fix most concurrent stat for empty database 2015-12-22 10:21:55 -08:00
PHoSawyer
1cef037db5 CentOS 6.X startup script
Init file for CentOS 6.X systems, variables exist for different install directorys. Please note, current version of Python is 2.6 and PlexPy requires 2.7. A variable exists to point to this path.

Since PlexPy is based on Headphones, I just copied the init script for Headphones and changed the paths and added the Python2.7 path
2015-12-21 15:20:35 +00:00
Jonathan Wong
a00d43092d Merge branch 'dev' 2015-12-20 09:34:38 -08:00
Jonathan Wong
45c2f50018 v1.2.15 2015-12-20 09:33:04 -08:00
JonnyWong16
ef8c6e82e6 Merge pull request #381 from JonnyWong16/miscellaneous-fixes
Group watch statistics history
2015-12-20 03:22:39 -08:00
Jonathan Wong
3eebb58da5 Fix most concurrent count with duplicate time entires 2015-12-20 03:14:39 -08:00
Jonathan Wong
447c50fd03 Group watch statistics history 2015-12-19 20:40:30 -08:00
Jonathan Wong
0620ebebcf Touch up current activity status bar hover effect 2015-12-17 23:26:26 -08:00
JonnyWong16
cf081ee291 Merge pull request #380 from zobe123/patch-1
Added Statusbar hover effect with percentage
2015-12-17 23:18:22 -08:00
zobe123
3c29b8e9c5 Update plexpy.css
Added Statusbar hover effect with percentage
2015-12-17 23:33:53 +01:00
zobe123
6143da5a6a Update pmsconnect.py
some additions to Show readable transcode progress
2015-12-17 23:25:29 +01:00
JonnyWong16
664f71575c Merge pull request #370 from JonnyWong16/miscellaneous-fixes
Miscellaneous fixes
2015-12-16 19:52:07 -08:00
Jonathan Wong
9ae111b8a1 Fix Growl notifications 2015-12-16 19:42:51 -08:00
Jonathan Wong
18682c7a2e Add logger info for Boxcar2 notification sent 2015-12-15 19:56:14 -08:00
Jonathan Wong
b21c50dfcf Fix typo on settings page 2015-12-13 23:53:22 -08:00
Jonathan Wong
49b6965e8e Add CC and BCC and multiple email recipients 2015-12-13 15:08:43 -08:00
Jonathan Wong
c6cc2b8831 Save graph type/days/tab to config file
* Change input for graph days range
2015-12-13 11:35:33 -08:00
Jonathan Wong
f9f65eae53 Add duration to history table footer 2015-12-13 09:36:54 -08:00
Jonathan Wong
b51d442673 Add notification for remote access/server back up 2015-12-13 09:31:11 -08:00
Jonathan Wong
5863b62ccf Add notifier name to modal title 2015-12-12 17:32:32 -08:00
Jonathan Wong
66bb922012 Add stream details to notification options
* Also beautify modal
2015-12-12 17:31:52 -08:00
Jonathan Wong
53876e8f0d Add time range to most concurrent stat
* Reorder cards
2015-12-12 16:21:54 -08:00
Jonathan Wong
cb7ba7fdde Clean up if statement in current activity header 2015-12-12 14:36:57 -08:00
Jonathan Wong
9cf6793b24 Add most concurrent streams home statistic 2015-12-12 14:34:42 -08:00
Jonathan Wong
6e62ffdd22 Get Pushbullet devices automatically using API 2015-12-12 14:34:11 -08:00
Jonathan Wong
c042d9e39a Fix metadata for grouped recently added notifications 2015-12-12 14:31:04 -08:00
Jonathan Wong
1262de2ae2 Clean up notifiers 2015-12-12 14:30:42 -08:00
JonnyWong16
307230cec8 Merge pull request #365 from zobe123/patch-1
Update current_activity_header.html
2015-12-12 14:10:27 -08:00
drzoidberg33
4fa2711e78 Merge pull request #367 from drzoidberg33/frontend-tweaks
Fix greedy search bar.
2015-12-12 16:20:44 +02:00
Tim
5c9c2f9ab8 Fix greedy search bar. 2015-12-12 16:19:30 +02:00
zobe123
604155b41b Update current_activity_header.html
remove "no"
2015-12-11 22:23:14 +01:00
zobe123
6e4198e7be Update current_activity_header.html
dynamic "s" at the word stream/streams
added "no" before Activity when their is no activity
2015-12-10 23:56:02 +01:00
drzoidberg33
14d4940d05 Merge pull request #363 from InAnimaTe/dev
add .pem cert to ignore list
2015-12-09 18:47:22 +02:00
Mario Loria
a6b0cdef97 add .pem cert to ignore list 2015-12-09 11:00:53 -05:00
Tim
6265943607 Merge branch 'dev' 2015-12-07 22:32:00 +02:00
Tim
de39f7691c v1.2.14 2015-12-07 22:31:00 +02:00
drzoidberg33
921a219beb Merge pull request #352 from drzoidberg33/security-fixes
Fix regression on select_single queries Resolves #350
2015-12-07 22:26:33 +02:00
Tim
b9c95d49a6 Fix regression on select_single queries. 2015-12-07 22:22:47 +02:00
Jonathan Wong
fc0be6bce2 Merge branch 'dev' 2015-12-06 11:41:08 -08:00
Jonathan Wong
8db891cfe6 v1.2.13 2015-12-06 11:40:17 -08:00
JonnyWong16
f6e77cc578 Merge pull request #346 from JonnyWong16/miscellaneous-fixes
Fix current activity
2015-12-06 11:36:05 -08:00
Jonathan Wong
a3782f9150 Fix dict key for IP address in current activity 2015-12-06 11:30:33 -08:00
drzoidberg33
7546c7ef42 Merge pull request #345 from drzoidberg33/security-fixes
Security fixes
2015-12-06 21:23:43 +02:00
Jonathan Wong
53de8cda30 Match newline between tags for notification text 2015-12-06 11:13:46 -08:00
Tim
1fb7473dc5 Sanitize sync row items. 2015-12-06 21:04:33 +02:00
Tim
cc9d09bd54 Allow HTML encoded content to be displayed in notification setting descriptions. 2015-12-06 20:49:00 +02:00
818 changed files with 10658 additions and 4509 deletions

1
.gitignore vendored
View File

@@ -21,6 +21,7 @@ cache/*
*.crt
*.key
*.csr
*.pem
# OS generated files #
######################

View File

@@ -1,5 +1,74 @@
# Changelog
## v1.3.0 (2016-01-23)
* Add: Brand new Libraries section.
* Add: Lots of new library statistics.
* Add: Media info table for libraries.
* Add: Web app for Android and iOS. (Thanks @zobe123)
* Add: Slack notification agent. (Thanks @richipargo)
* Add: Facebook notification agent.
* Add: Custom script notification agent. (Thanks @Hellowlol)
* Add: Custom "From Name" to email notification agent.
* Add: Ability to test notifications / send custom one-off notifications.
* Add: 'datestamp' and 'timestamp' notification options.
* Add: More concurrent stream statistics.
* Add: Media info flags on the info pages.
* Add: Ability to fix broken metadata if the item has been moved in Plex.
* Add: Ability to rearrange the homepage statistics cards.
* Add: CentOS startup script (Thanks @PHoSawyer)
* Fix: Server name blank after first run wizard.
* Fix: Incorrect duration for grouped home stats.
* Fix: Allow SSL when verifying server in settings.
* Fix: Metadata for grouped recently added notifications.
* Fix: Unable to access settings with missing changelog file.
* Fix: Month name localization on play totals graphs.
* Fix: Get new PMS identifier when changing servers.
* Fix: Websocket log spam when there is no active session.
* Fix: Logs and cache folder not created in the data directory.
* Fix: Title links on sync table.
* Fix: Other various minor bugs and graphical glitches.
* Change: Prettier thumbnail popovers on tables.
* Change: Star ratings to use css/font-awesome.
* Change: More detailed logging info to warnings and errors.
* Change: Better PlexPy process restart handling (Thanks @jackwilsdon)
* Change: Massive behind the scenes code cleanup.
* Remove: Built in Pushover API token (User's own API token is now required).
## v1.2.16 (2015-12-22)
* Fix Most Concurrent stream stat for emtpy databases
* Change logs to 50 lines by default
## v1.2.15 (2015-12-20)
* Fix navbar covering current activity on smaller screens.
* Fix metadata for grouped recently added notifications.
* Fix Growl notification agent not working.
* Change graph days selection.
* Change watch statistics to match table history grouping.
* Add automatic discovery of Pushbullet devices.
* Add Most Concurrent Streams watch statistic.
* Add precentage to current activity progress bars.
* Add a bunch of stream details to notification options.
* Add notification for Plex Remote Access/Plex Media Server back up.
* Add CC/BCC and multiple recipients to email notification agent.
* Add total watch time to history table footer.
## v1.2.14 (2015-12-07)
* Fix regression with PlexWatch db importer and buffer warnings.
## v1.2.13 (2015-12-06)
* Fix match newlines between tags in notification text.
* Fix current activity not showing on PMS 0.9.12.
## v1.2.12 (2015-12-06)
* Fix for "too many open files" error.

View File

@@ -18,12 +18,117 @@ from plexpy import version
${next.headIncludes()}
<link rel="icon" type="image/x-icon" href="interfaces/default/images/favicon.ico"/>
<!-- touch icons -->
<link rel="shortcut icon" href="interfaces/default/images/favicon.png">
<link rel="apple-touch-icon" href="interfaces/default/images/icon_iphone.png">
<link rel="apple-touch-icon" sizes="72x72" href="interfaces/default/images/icon_ipad.png">
<link rel="apple-touch-icon" sizes="114x114" href="interfaces/default/images/icon_iphone@2x.png">
<link rel="apple-touch-icon" sizes="144x144" href="interfaces/default/images/icon_ipad@2x.png">
<!-- Allow web app to be run in full-screen mode. -->
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- Configure the status bar. -->
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- Set the viewport. -->
<meta name="viewport" content="initial-scale=1">
<!-- Disable automatic phone number detection. -->
<meta name="format-detection" content="telephone=no">
<!-- ICONS -->
<!-- IE10 icon -->
<meta name="application-name" content="PlexPy" />
<meta name="msapplication-config" content="interfaces/default/xml/IEconfig.xml"/>
<!-- Android >M39 icon -->
<link rel="manifest" href="interfaces/default/json/Android-manifest.json">
<!-- iPad retina icon -->
<link href="interfaces/default/images/res/ios/icon-76@2x.png" sizes="152x152" rel="apple-touch-icon-precomposed">
<!-- iPad retina icon (iOS < 7) -->
<link href="interfaces/default/images/res/ios/icon-72@2x.png" sizes="144x144" rel="apple-touch-icon-precomposed">
<!-- iPad non-retina icon -->
<link href="interfaces/default/images/res/ios/icon-76.png" sizes="76x76" rel="apple-touch-icon-precomposed">
<!-- iPad non-retina icon (iOS < 7) -->
<link href="interfaces/default/images/res/ios/icon-72.png" sizes="72x72" rel="apple-touch-icon-precomposed">
<!-- iPhone 6 Plus icon -->
<link href="interfaces/default/images/res/ios/icon-60@2x.png" sizes="120x120" rel="apple-touch-icon-precomposed">
<!-- iPhone retina icon (iOS < 7) -->
<link href="interfaces/default/images/res/ios/icon@2x.png" sizes="114x114" rel="apple-touch-icon-precomposed">
<!-- iPhone non-retina icon (iOS < 7) -->
<link href="interfaces/default/images/res/ios/icon.png" sizes="57x57" rel="apple-touch-icon-precomposed">
<!-- iPhone / iPod Touch -->
<link href="interfaces/default/images/res/ios/icon-60@3x.png" sizes="180x180" rel="apple-touch-icon-precomposed">
<link href="interfaces/default/images/res/ios/icon-60.png" sizes="60x60" rel="apple-touch-icon-precomposed">
<!-- Spotlight Icon -->
<link href="interfaces/default/images/res/ios/icon-40.png" sizes="40x40" rel="apple-touch-icon-precomposed">
<link href="interfaces/default/images/res/ios/icon-40@2x.png" sizes="80x80" rel="apple-touch-icon-precomposed">
<!-- iPhone Spotlight and Settings Icon -->
<link href="interfaces/default/images/res/ios/icon-small.png" sizes="29x29" rel="apple-touch-icon-precomposed">
<link href="interfaces/default/images/res/ios/icon-small@2x.png" sizes="58x58" rel="apple-touch-icon-precomposed">
<!-- iPad Spotlight and Settings Icon -->
<link href="interfaces/default/images/res/ios/icon-50.png" sizes="50x50" rel="apple-touch-icon-precomposed">
<link href="interfaces/default/images/res/ios/icon-50@2x.png" sizes="100x100" rel="apple-touch-icon-precomposed">
<!-- STARTUP IMAGES -->
<!-- iPad retina portrait startup image -->
<link href="interfaces/default/images/res/screen/ios/Default-Portrait@2x~ipad.png"
media="(device-width: 768px) and (device-height: 1024px)
and (-webkit-device-pixel-ratio: 2)
and (orientation: portrait)"
rel="apple-touch-startup-image">
<!-- iPad retina landscape startup image -->
<link href="interfaces/default/images/res/screen/ios/Default-Landscape@2x~ipad.png"
media="(device-width: 768px) and (device-height: 1024px)
and (-webkit-device-pixel-ratio: 2)
and (orientation: landscape)"
rel="apple-touch-startup-image">
<!-- iPad non-retina portrait startup image -->
<link href="interfaces/default/images/res/screen/ios/Default-Portrait~ipad.png"
media="(device-width: 768px) and (device-height: 1024px)
and (-webkit-device-pixel-ratio: 1)
and (orientation: portrait)"
rel="apple-touch-startup-image">
<!-- iPad non-retina landscape startup image -->
<link href="interfaces/default/images/res/screen/ios/Default-Landscape~ipad.png"
media="(device-width: 768px) and (device-height: 1024px)
and (-webkit-device-pixel-ratio: 1)
and (orientation: landscape)"
rel="apple-touch-startup-image">
<!-- iPhone 6 Plus portrait startup image -->
<link href="interfaces/default/images/res/screen/ios/Default-736h.png"
media="(device-width: 414px) and (device-height: 736px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: portrait)"
rel="apple-touch-startup-image">
<!-- iPhone 6 Plus landscape startup image -->
<link href="interfaces/default/images/res/screen/ios/Default-Landscape-736h.png"
media="(device-width: 414px) and (device-height: 736px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: landscape)"
rel="apple-touch-startup-image">
<!-- iPhone 6 startup image -->
<link href="interfaces/default/images/res/screen/ios/Default-667h.png"
media="(device-width: 375px) and (device-height: 667px)
and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image">
<!-- iPhone 5 startup image -->
<link href="interfaces/default/images/res/screen/ios/Default-568h@2x~iphone5.jpg"
media="(device-width: 320px) and (device-height: 568px)
and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image">
<!-- iPhone < 5 retina startup image -->
<link href="interfaces/default/images/res/screen/ios/Default@2x~iphone.png"
media="(device-width: 320px) and (device-height: 480px)
and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image">
<!-- iPhone < 5 non-retina startup image -->
<link href="interfaces/default/images/res/screen/ios/Default~iphone.png"
media="(device-width: 320px) and (device-height: 480px)
and (-webkit-device-pixel-ratio: 1)"
rel="apple-touch-startup-image">
</head>
<body class="content">
@@ -57,7 +162,7 @@ from plexpy import version
</div>
<div class="collapse navbar-collapse navbar-right" id="navbar-collapse-1">
<ul class="nav navbar-nav">
<li>
<li class="hidden-sm hidden-xs">
<form action="search" method="post" class="form" id="search_form">
<div class="input-group">
<span class="input-textbox">
@@ -69,37 +174,42 @@ from plexpy import version
</div>
</form>
</li>
% if title=="Home":
% if title == "Home":
<li class="active"><a href="home"><i class="fa fa-lg fa-home"></i></a></li>
% else:
<li><a href="home"><i class="fa fa-lg fa-home"></i></a></li>
% endif
% if title=="Users" or title=="User":
% if title == "Libraries" or title == "Library" or title == "Info":
<li class="active"><a href="libraries">Libraries</a></li>
% else:
<li><a href="libraries">Libraries</a></li>
% endif
% if title == "Users" or title == "User":
<li class="active"><a href="users">Users</a></li>
% else:
<li><a href="users">Users</a></li>
% endif
% if title=="History":
% if title == "History":
<li class="active"><a href="history">History</a></li>
% else:
<li><a href="history">History</a></li>
% endif
% if title=="Graphs":
% if title == "Graphs":
<li class="active"><a href="graphs">Graphs</a></li>
% else:
<li><a href="graphs">Graphs</a></li>
% endif
% if title=="Synced Items":
% if title == "Synced Items":
<li class="active"><a href="sync">Synced Items</a></li>
% else:
<li><a href="sync">Synced Items</a></li>
% endif
% if title=="Log":
% if title == "Log":
<li class="active"><a href="logs">Logs</a></li>
% else:
<li><a href="logs">Logs</a></li>
% endif
% if title=="Settings":
% if title == "Settings":
<li class="active"><a href="settings">Settings</a></li>
% else:
<li><a href="settings">Settings</a></li>
@@ -135,22 +245,37 @@ ${next.headerIncludes()}
$.ajax({
type: 'post',
url: 'search',
data: { 'query': $('#query').val() }
data: { query: $('#query').val() }
})
} else {
e.preventDefault();
$('#search_button').removeClass('btn-inactive');
$('#query').clearQueue().val('').animate({ right: '0', width: '250px' }).addClass('active').focus();
$('#query').clearQueue().val('').animate({ right: '0', width: '200px' }).addClass('active').focus();
}
})
$('#query').on('blur', function (e) {
if ($(this).val().trim() == '') {
$(this).delay(200).animate({ right: '-250px', width: '0' }, function () {
$(this).delay(200).animate({ right: '-200px', width: '0' }, function () {
$('#search_button').addClass('btn-inactive');
}).removeClass('active');
}
});
</script>
<script>
// Work around for iOS web app links opening in Safari
$(document).ready(function () {
if (("standalone" in window.navigator) && window.navigator.standalone) {
// For iOS Apps
$('a').on('click', function (e) {
e.preventDefault();
var new_location = $(this).attr('href');
if (new_location != undefined && new_location.substr(0, 1) != '#' && $(this).attr('data-method') == undefined) {
window.location = new_location;
}
});
}
});
</script>
${next.javascriptIncludes()}
</body>
</html>

View File

@@ -235,8 +235,8 @@ fieldset[disabled] .btn-bright:active,
.btn-bright.disabled.active,
.btn-bright[disabled].active,
fieldset[disabled] .btn-bright.active {
background-color: #5cb85c;
border-color: #4cae4c;
background-color: #c9302c;
border-color: #ac2925;
}
.btn-bright .badge {
color: #fff;
@@ -487,7 +487,8 @@ textarea.form-control:focus {
.users-poster-face {
overflow: hidden;
float: left;
background-size: contain;
background-size: cover;
background-position: center;
height: 40px;
width: 40px;
-webkit-border-radius: 50%;
@@ -497,6 +498,16 @@ textarea.form-control:focus {
-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);
}
.libraries-poster-face {
overflow: hidden;
float: left;
background-size: contain;
height: 40px;
width: 40px;
/*-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);*/
}
a .poster-face:hover,
a .cover-face:hover,
a .users-poster-face:hover {
@@ -737,14 +748,20 @@ a:hover .dashboard-activity-poster {
transition: all 0s;
}
.dashboard-activity-progress .bufferbar {
padding-top: 6px;
padding-right: 3px;
font-size: x-small;
text-align: right;
color: rgba(255, 255, 255, 0);
background-color: #444;
position: absolute;
height: 6px;
overflow: hidden;
}
.dashboard-activity-progress .bar {
padding-top: 6px;
padding-right: 3px;
font-size: x-small;
text-align: right;
color: rgba(255, 255, 255, 0);
background-color: #faa732;
background-image: -moz-linear-gradient(top, #fbb450, #f89406);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
@@ -757,6 +774,37 @@ a:hover .dashboard-activity-poster {
height: 6px;
overflow: hidden;
}
.dashboard-instance.hover .dashboard-activity-progress-bar {
height: 14px;
transform-origin: top;
transition: all .2s ease;
border-radius: 0px 0px 3px 3px;
}
.dashboard-instance.hover .bar {
height: 14px;
transform-origin: top;
transition: all .2s ease;
border-radius: 0px 0px 3px 3px;
color: rgba(255, 255, 255, 1);
background-image: -webkit-linear-gradient(left,rgba(0,0,0,0.25),0%,rgba(0,0,0,0),50px);
background-image: -moz-linear-gradient(left,rgba(0,0,0,0.25) 0%,rgba(0,0,0,0) 50px);
background-image: linear-gradient(to left,rgba(0,0,0,0.25) 0%,rgba(0,0,0,0) 50px);
}
.dashboard-instance.hover .bufferbar {
height: 14px;
transform-origin: top;
transition: all .2s ease;
border-radius: 0px 0px 3px 3px;
color: rgba(255, 255, 255, 1);
background-image: -webkit-linear-gradient(left,rgba(0,0,0,0.25),0%,rgba(0,0,0,0),50px);
background-image: -moz-linear-gradient(left,rgba(0,0,0,0.25) 0%,rgba(0,0,0,0) 50px);
background-image: linear-gradient(to left,rgba(0,0,0,0.25) 0%,rgba(0,0,0,0) 50px);
}
.dashboard-instance.hover .dashboard-activity-metadata-wrapper {
margin-top: 11px;
transform-origin: top;
transition: all .2s ease;
}
.dashboard-activity-metadata-wrapper {
position: relative;
width: 100%;
@@ -1157,6 +1205,7 @@ a:hover .summary-poster-face-track .summary-poster-face-overlay span {
width: 250px;
height: 1px;
margin: 0 40px 20px 25px;
position: relative;
}
.summary-content {
position: relative;
@@ -1180,6 +1229,20 @@ a:hover .summary-poster-face-track .summary-poster-face-overlay span {
margin-left: 2px;
margin-right: 10px;
}
.summary-content-media-info-wrapper {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
text-align: center;
}
.summary-content-media-flag {
width: auto;
height: auto;
max-width: 75pt;
max-height: 15px;
margin: 0 5px;
}
.summary-content-summary {
overflow: hidden;
color: #fff;
@@ -1256,31 +1319,25 @@ a:hover .summary-poster-face-track .summary-poster-face-overlay span {
line-height: 18px;
color: #fff;
}
.rateit {
display: -moz-inline-box;
.star-rating {
display: inline-block;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
font-size: 15px;
overflow: hidden;
white-space: nowrap;
float: right;
margin-top: 3px;
height: 21px;
position: absolute;
right: 0;
}
.rateit .rateit-range {
background: url(../images/star-gray-32.png);
background-size: contain;
height: 16px;
.star-rating .star-icon {
width: auto;
margin-left: 2px;
color: #F9AA03;
}
.rateit .rateit-selected {
background: url(../images/star-32.png);
background-size: contain;
height: 16px;
.star-rating .star-icon-o {
width: auto;
margin-left: 2px;
color: #999;
}
#children-list, #search-results-list {
position: relative;
@@ -1500,7 +1557,8 @@ a:hover .item-children-poster {
float: left;
margin-top: 15px;
margin-right: 15px;
background-size: contain;
background-size: cover;
background-position: center;
height: 80px;
width: 80px;
-webkit-border-radius: 50%;
@@ -1615,7 +1673,6 @@ a:hover .item-children-poster {
}
.user-player-instance-box {
float: left;
width: 75px;
border-radius: 3px;
-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);
@@ -1637,6 +1694,7 @@ a:hover .item-children-poster {
font-weight: normal;
width: 140px;
margin-left: 10px;
margin-bottom: 10px;
}
.user-player-instance-playcount h3 {
font-size: 30px;
@@ -1656,6 +1714,35 @@ a:hover .item-children-poster {
top: 15px;
left: 0px;
}
.library-info-poster-face {
float: left;
margin-top: 15px;
margin-right: 15px;
background-size: contain;
height: 80px;
width: 80px;
/*-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);*/
}
.library-user-instance-box {
float: left;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
-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);
background-size: contain;
position: relative;
height: 80px;
width: 80px;
}
.library-user-instance-box: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;
}
.home-platforms {
}
.home-platforms ul {
@@ -1686,6 +1773,7 @@ a:hover .item-children-poster {
padding-left: 80px;
width: 100%;
height: 120px;
overflow: hidden;
}
.home-platforms-instance-name {
color: #fff;
@@ -2087,7 +2175,8 @@ a .home-platforms-instance-list-oval:hover,
float: right;
}
.colvis-button-bar,
.refresh-users-button {
.refresh-users-button,
.refresh-libraries-button {
float: right;
}
.nav-settings,
@@ -2286,6 +2375,9 @@ a .home-platforms-instance-list-oval:hover,
width: 250px;
z-index: 9999;
}
.dataTables_paginate li {
margin: 0;
}
.tooltip.top .tooltip-arrow {
border-top-color: #fff;
}
@@ -2303,42 +2395,52 @@ a .home-platforms-instance-list-oval:hover,
background: #fff;
border: 0;
font-weight: bold;
border-radius: 2px;
}
.history-title .popover.right {
margin-left: 12px;
z-index: 5;
.history-thumbnail-popover {
z-index: 2;
padding: 0;
border: 0;
}
.history-title .popover.right .popover-content {
padding: 5px 8px;
.history-thumbnail-popover.popover.right {
margin-left: 15px;
}
.history-thumbnail-popover .popover-content {
color: #000;
padding: 0;
}
.history-thumbnail {
background-position: center;
background-size: cover;
width: 80px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
-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);
}
.edit-user-toggles {
.edit-user-toggles,
.edit-library-toggles {
padding-right: 10px;
}
.edit-user-toggles > input[type='checkbox'] {
.edit-user-toggles > input[type='checkbox'],
.edit-library-toggles > input[type='checkbox'] {
display: none;
}
.edit-user-toggles > input[type='checkbox'] + label {
.edit-user-toggles > input[type='checkbox'] + label,
.edit-library-toggles > input[type='checkbox'] + label {
color: #444;
cursor: pointer;
}
.edit-user-toggles > input[type='checkbox']:checked + label {
.edit-user-toggles > input[type='checkbox']:checked + label,
.edit-library-toggles > input[type='checkbox']:checked + label {
color: #fff;
cursor: pointer;
}
.edit-user-name > input[type='text'] {
margin: 0;
}
.popover {
z-index: 2;
}
.popover .popover-content {
color: #000;
}
.noTransition
{
-moz-transition: none !important;
@@ -2375,7 +2477,9 @@ a .home-platforms-instance-list-oval:hover,
left: 12px;
}
#users-to-delete > li,
#users-to-purge > li {
#users-to-purge > li,
#libraries-to-delete > li,
#libraries-to-purge > li {
color: #e9a049;
}
#updatebar {
@@ -2425,9 +2529,8 @@ a .home-platforms-instance-list-oval:hover,
right: 0;
bottom: 0;
left: 0;
overflow-x: hidden;
overflow-y: auto;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
::-webkit-scrollbar {
width: 15px;
@@ -2453,12 +2556,19 @@ a .home-platforms-instance-list-oval:hover,
width: 100%;
}
}
table.display,
table.display tr.shown + tr table[id^='history_child'],
table.display tr.shown + tr table[id^='media_info_child'],
table.display tr.shown + tr table[id^='media_info_child'] tr.shown + tr table[id^='media_info_child'] {
table-layout: auto;
}
table.display tr.shown + tr div.slider {
display: none;
}
table.display tr.shown + tr > td {
padding-top: 0;
padding-bottom: 0;
padding-left: 0;
}
table.display tr.shown + tr:hover {
background-color: rgba(255,255,255,0);
@@ -2469,7 +2579,9 @@ table.display tr.shown + tr .pagination > .active > a,
table.display tr.shown + tr .pagination > .active > a:hover {
color: #fff;
}
table.display tr.shown + tr table[id^='history_child'] td:hover a {
table.display tr.shown + tr table[id^='history_child'] td:hover a,
table.display tr.shown + tr table[id^='media_info_child'] > tr > td:hover a,
table.display tr.shown + tr table[id^='media_info_child'] tr.shown + tr table[id^='media_info_child'] td:hover a {
color: #F9AA03;
}
table.display tr.shown + tr .pagination > .disabled > a {
@@ -2480,21 +2592,29 @@ table.display tr.shown + tr .pagination > li > a:hover {
}
table[id^='history_child'] {
margin-top: 0;
margin-left: -4px;
opacity: .6;
}
table[id^='history_child'] thead th {
table[id^='media_info_child'] {
margin-top: 0;
}
table[id^='history_child'] thead th,
table[id^='media_info_child'] thead th {
line-height: 0;
height: 0 !important;
overflow: hidden;
}
table[id^='media_info_child'] table[id^='media_info_child'] thead th {
line-height: 25px;
height: 35px !important;
overflow: hidden;
}
#search_form {
width: 350px;
width: 300px;
padding: 8px 15px;
}
#search_form span.input-textbox {
overflow: hidden;
width: 250px;
width: 200px;
height: 34px;
display: inline-flex;
float: right;
@@ -2505,11 +2625,11 @@ table[id^='history_child'] thead th {
margin-top: 0;
float: right;
position: relative;
right: -250px;
right: -200px;
border-radius: 3px 0 0 3px;
}
#search_form #query.active {
width: 250px;
width: 200px;
right: 0px;
}
#search_form #search_button.btn-inactive {
@@ -2520,4 +2640,77 @@ table[id^='history_child'] thead th {
-ms-transition: background 0.3s;
-o-transition: background 0.3s;
transition: background 0.3s;
}
#update_search_form div.input-group {
display: inline-table;
vertical-align: middle;
max-width: 250px;
}
#update_search_form #update_query {
margin: 5px 0 0 0.5em;
}
.notification-params {
margin-top: 10px;
background-color: #282828;
}
.notification-params th {
padding-left: 10px;
height: 30px;
}
.notification-params td {
height: 25px;
}
.notification-params td:first-child {
padding-left: 10px;
width: 200px;
}
.notification-params td:not(:first-child) {
padding-right: 10px;
}
.notification-params tr:nth-child(odd) td {
background-color: rgba(255,255,255,0.035);
}
.notification-params tr:nth-child(even) td {
background-color: rgba(255,255,255,0.010);
}
#days-selection label {
margin-bottom: 0;
}
#graph-days {
margin: 0;
width: 75px;
height: 34px;
}
.card-sortable {
height: 36px;
padding: 0 20px 0 0;
line-height: 34px;
cursor: move;
cursor: -webkit-grab;
cursor: grab;
border-bottom: 1px solid #232323;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.card {
position: relative;
background-color: #282828;
border-top: 1px solid #2d2d2d;
}
.card label {
font-weight: normal;
}
.card-handle {
display: inline-block;
width: 30px;
margin-right: 10px;
color: #444;
text-align: center;
background-color: #2f2f2f;
}
.selectize-input input[type='text'] {
height: 20px;
}

View File

@@ -69,12 +69,12 @@ DOCUMENTATION :: END
% for a in data['sessions']:
<div class="dashboard-instance" id="instance-${a['session_key']}">
% if a['media_type'] == 'movie' or a['media_type'] == 'episode' or a['media_type'] == 'track':
<a href="info?item_id=${a['rating_key']}">
<a href="info?rating_key=${a['rating_key']}">
% endif
<div class="dashboard-activity-poster">
% if a['media_type'] == 'movie' and not a['indexes']:
% if (a['media_type'] == 'movie' and not a['indexes']) or (a['indexes'] and not a['view_offset']):
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${a['art']}&width=500&height=280);"></div>
% elif a['media_type'] == 'episode' and not a['indexes']:
% elif (a['media_type'] == 'episode' and not a['indexes']) or (a['indexes'] and not a['view_offset']):
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${a['art']}&width=500&height=280);"></div>
% elif a['indexes']:
<div class="dashboard-activity-poster-face bif" style="background-image: url(pms_image_proxy?img=${a['bif_thumb']}&width=500&height=280); display: none;"></div>
@@ -227,13 +227,13 @@ DOCUMENTATION :: END
<i class="fa fa-spinner"></i>&nbsp;
% endif
% if a['media_type'] == 'episode':
<a href="info?item_id=${a['rating_key']}" title="${a['grandparent_title']} - ${a['title']}">${a['grandparent_title']} - ${a['title']}</a>
<a href="info?rating_key=${a['rating_key']}" title="${a['grandparent_title']} - ${a['title']}">${a['grandparent_title']} - ${a['title']}</a>
% elif a['media_type'] == 'movie':
<a href="info?item_id=${a['rating_key']}" title="${a['title']}">${a['title']}</a>
<a href="info?rating_key=${a['rating_key']}" title="${a['title']}">${a['title']}</a>
% elif a['media_type'] == 'clip':
<span title="${a['title']}">${a['title']}</span>
% elif a['media_type'] == 'track':
<a href="info?item_id=${a['rating_key']}" title="${a['grandparent_title']} - ${a['title']}">${a['grandparent_title']} - ${a['title']}</a>
<a href="info?rating_key=${a['rating_key']}" title="${a['grandparent_title']} - ${a['title']}">${a['grandparent_title']} - ${a['title']}</a>
% elif a['media_type'] == 'photo':
<span title="${a['parent_title']}">${a['parent_title']}</span>
% else:
@@ -246,7 +246,7 @@ DOCUMENTATION :: END
% elif a['media_type'] == 'movie':
<span title="${a['year']}">${a['year']}</span>
% elif a['media_type'] == 'track':
<a href="info?item_id=${a['parent_rating_key']}" title="${a['parent_title']}">${a['parent_title']}</a>
<a href="info?rating_key=${a['parent_rating_key']}" title="${a['parent_title']}">${a['parent_title']}</a>
% elif a['media_type'] == 'photo':
<span title="${a['title']}">${a['title']}</span>
% else:
@@ -280,6 +280,13 @@ DOCUMENTATION :: END
e.preventDefault();
$($(this).attr('data-target')).toggle();
});
// Add hover class to dashboard-instance
$('.dashboard-activity-poster').hover(function() {
$(this).closest('.dashboard-instance').addClass('hover');
}, function() {
$(this).closest('.dashboard-instance').removeClass('hover');
});
</script>
% else:
<div class="text-muted">Nothing is currently being watched.</div><br>

View File

@@ -15,11 +15,13 @@ DOCUMENTATION :: END
</%doc>
% if data != None:
% if data == '0':
<h3>Activity</h3>
% if data == '0':
<h3>Activity</h3>
% elif data == '1':
<h3>Activity <small>${data} stream</small></h3>
% else:
<h3>Activity <small>${data} streams</small></h3>
% endif
% else:
<h3>Activity <small>${data} stream(s)</small></h3>
<h3>Activity</h3>
% endif
% else:
<h3>Activity</h3>
% endif

View File

@@ -0,0 +1,179 @@
<%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: edit_library.html
Version: 0.1
Variable names: data [list]
data :: Usable parameters
== Global keys ==
section_id Returns the library id of the library.
section_name Returns the name of the library.
section_type Returns the type of the library.
library_thumb Returns the thumbnail for the library.
custom_thumb Returns the custom thumbnail for the library.
library_art Returns the artwork for the library.
count Returns the item count for the library.
parent_count Returns the parent item count for the library.
child_count Returns the child item count for the library.
do_notify Returns bool value for whether to send notifications for the library.
keep_history Returns bool value for whether to keep history for the library.
DOCUMENTATION :: END
</%doc>
<%!
from plexpy import helpers
%>
% if data != None:
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
<h4 class="modal-title">Edit library <strong>${data['section_name']}</strong></h4>
</div>
<div class="modal-body" id="modal-text">
<fieldset>
<div class="form-group">
<label for="profile_url">Library Picture URL</label>
<div class="row">
<div class="col-md-8">
<input type="text" class="form-control" id="custom_thumb_url" name="custom_thumb_url" value="${data['library_thumb']}">
</div>
</div>
<p class="help-block">Change the library's picture in PlexPy. To reset to default, leave this field empty and save.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="do_notify" name="do_notify" value="1" ${helpers.checked(data['do_notify'])}> Enable notifications
</label>
<p class="help-block">Uncheck this if you do not want to receive notifications for this library's activity.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="keep_history" name="keep_history" value="1" ${helpers.checked(data['keep_history'])}> Keep history
</label>
<p class="help-block">Uncheck this if you do not want to keep any history on this library's activity.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="do_notify_created" name="do_notify_created" value="1" ${helpers.checked(data['do_notify_created'])}> Enable recently added notifications
</label>
<p class="help-block">Uncheck this if you do not want to receive recently added notifications for this library.</p>
</div>
% if data['section_id']:
<div class="form-group">
<button class="btn btn-danger" id="delete-all-history">Purge</button>
<p class="help-block">DANGER ZONE! Click the purge button to remove all history logged for this library. This is permanent!</p>
</div>
% endif
</fieldset>
</div>
<div class="modal-footer">
<div>
<span id="edit-library-status-message"></span>
<input type="button" id="save_library" class="btn btn-bright" value="Save">
</div>
</div>
</div>
</div>
<div id="confirm-modal-purge" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal-purge">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
<h4 class="modal-title" id="myModalLabel">Confirm Purge</h4>
</div>
<div class="modal-body" style="text-align: center;">
<p>Are you REALLY sure you want to purge all history for this library?</p>
<p>This is permanent and cannot be undone!</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-purge">Purge</button>
</div>
</div>
</div>
</div>
<script>
// Save library options
$("#save_library").on('click', function () {
var custom_thumb = $("#custom_thumb_url").val();
var do_notify = 0;
var do_notify_created = 0;
var keep_history = 0;
if ($("#do_notify").is(":checked")) {
do_notify = 1;
}
if ($("#do_notify_created").is(":checked")) {
do_notify_created = 1;
}
if ($("#keep_history").is(":checked")) {
keep_history = 1;
}
$.ajax({
url: 'edit_library',
data: {
section_id: '${data["section_id"]}',
custom_thumb: custom_thumb,
do_notify: do_notify,
do_notify_created: do_notify_created,
keep_history: keep_history
},
cache: false,
async: true,
success: function (data) {
location.reload();
}
});
});
$("#delete-all-history").on('click', function() {
$('#confirm-modal-purge').modal();
$('#confirm-modal-purge').one('click', '#confirm-purge', function () {
$.ajax({
url: 'delete_all_library_history',
data: { section_id: '${data["section_id"]}' },
cache: false,
async: true,
success: function(data) {
location.reload();
}
});
});
});
$(document).ready(function() {
// Move #confirm-modal to parent container
if (!($('#edit-library-modal').next().is('#confirm-modal-purge'))) {
$('#confirm-modal-purge').appendTo($('#edit-library-modal').parent());
}
$('#edit-library-modal > #confirm-modal-purge').remove();
$('#edit-library-modal').css('z-index', '1050');
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1049');
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
$('#confirm-modal-purge').on('show.bs.modal', function () {
// Fix position to match parent modal
var currentPadding = parseInt($('body').css('padding-right'));
$(this).children('.modal-dialog').css('left', -currentPadding/2);
$('#edit-library-modal').css('overflow-y', 'hidden');
});
$('#confirm-modal-purge').on('shown.bs.modal', function () {
$(this).css('z-index', '1060');
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1059');
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
});
$('#confirm-modal-purge').on('hidden.bs.modal', function () {
$('body').addClass('modal-open');
$('#edit-library-modal').css('overflow-y', 'auto');
});
});
</script>
% endif

View File

@@ -10,21 +10,30 @@ Variable names: data [list]
data :: Usable parameters
== Global keys ==
user Return the real Plex username
user_id Return the Plex user_id
friendly_name Returns the friendly edited Plex username
do_notify Returns bool value for whether the user should trigger notifications
keep_history Returns bool value for whether the user's activity should be logged
user_id Returns the user id of the user.
username Returns the user's username.
friendly_name Returns the friendly name of the user.
email Returns the user's email address.
user_thumb Returns the thumbnail for the user.
is_home_user Returns bool value for whether the user is part of a Plex Home.
is_allow_sync Returns bool value for whether the user has sync rights.
is_restricted Returns bool value for whether the user account is restricted.
do_notify Returns bool value for whether to send notifications for the user.
keep_history Returns bool value for whether to keep history for the user.
DOCUMENTATION :: END
</%doc>
% if data is not None:
<%!
from plexpy import helpers
%>
% if data != None:
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
<h4 class="modal-title">Edit user <strong>${data['user']}</strong></h4>
<h4 class="modal-title">Edit user <strong>${data['username']}</strong></h4>
</div>
<div class="modal-body" id="modal-text">
<fieldset>
@@ -41,22 +50,22 @@ DOCUMENTATION :: END
<label for="profile_url">Profile Picture URL</label>
<div class="row">
<div class="col-md-8">
<input type="text" class="form-control" id="profile_url" name="profile_url" value="${data['thumb']}">
<input type="text" class="form-control" id="custom_avatar_url" name="custom_avatar_url" value="${data['user_thumb']}">
</div>
</div>
<p class="help-block">Change the users profile picture in PlexPy. To reset to default, leave this field empty and save then perform a user refresh.</p>
<p class="help-block">Change the users profile picture in PlexPy. To reset to default, leave this field empty and save.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="do_notify" name="do_notify" value="1" ${data['do_notify']}> Enable notifications
<input type="checkbox" id="do_notify" name="do_notify" value="1" ${helpers.checked(data['do_notify'])}> Enable notifications
</label>
<p class="help-block">Uncheck this if you do not want to receive notifications for this user's activity.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="keep_history" name="keep_history" value="1" ${data['keep_history']}> Keep history
<input type="checkbox" id="keep_history" name="keep_history" value="1" ${helpers.checked(data['keep_history'])}> Keep history
</label>
<p class="help-block">Uncheck this if you do not want this keep any history on this user's activity.</p>
<p class="help-block">Uncheck this if you do not want to keep any history on this user's activity.</p>
</div>
% if data['user_id']:
<div class="form-group">
@@ -69,7 +78,7 @@ DOCUMENTATION :: END
<div class="modal-footer">
<div>
<span id="edit-user-status-message"></span>
<input type="button" id="save_user_name" class="btn btn-bright" value="Save">
<input type="button" id="save_user" class="btn btn-bright" value="Save">
</div>
</div>
</div>
@@ -93,10 +102,10 @@ DOCUMENTATION :: END
</div>
</div>
<script>
// Set new friendly name
$("#save_user_name").click(function() {
// Set user options
$("#save_user").on('click', function () {
var friendly_name = $("#friendly_name").val();
var thumb = $("#profile_url").val();
var custom_thumb = $("#custom_avatar_url").val();
var do_notify = 0;
var keep_history = 0;
if ($("#do_notify").is(":checked")) {
@@ -106,35 +115,21 @@ DOCUMENTATION :: END
keep_history = 1;
}
% if data['user_id']:
$.ajax({
url: 'edit_user',
data: {user_id: '${data['user_id']}', friendly_name: friendly_name, do_notify: do_notify, keep_history: keep_history, thumb: thumb},
cache: false,
async: true,
success: function(data) {
$("#edit-user-status-message").html(data);
if ($.trim(friendly_name) !== '') {
$('.set-username').html(document.createTextNode(friendly_name));
}
$("#user-profile-thumb").attr('src', thumb);
}
});
% else:
$.ajax({
url: 'edit_user',
data: {user: '${data['user']}', friendly_name: friendly_name, do_notify: do_notify, keep_history: keep_history, thumb: thumb},
cache: false,
async: true,
success: function(data) {
$("#edit-user-status-message").html(data);
if ($.trim(friendly_name) !== '') {
$(".set-username").html(friendly_name);
}
$("#user-profile-thumb").attr('src', thumb);
}
});
% endif
$.ajax({
url: 'edit_user',
data: {
user_id: '${data["user_id"]}',
friendly_name: friendly_name,
custom_thumb: custom_thumb,
do_notify: do_notify,
keep_history: keep_history
},
cache: false,
async: true,
success: function(data) {
location.reload();
}
});
});
$("#delete-all-history").on('click', function() {
@@ -142,7 +137,7 @@ DOCUMENTATION :: END
$('#confirm-modal').one('click', '#confirm-purge', function () {
$.ajax({
url: 'delete_all_user_history',
data: {user_id: '${data['user_id']}'},
data: { user_id: '${data["user_id"]}' },
cache: false,
async: true,
success: function(data) {
@@ -155,7 +150,8 @@ DOCUMENTATION :: END
$(document).ready(function() {
// Move #confirm-modal to parent container
if(!($('#edit-user-modal').next().is('#confirm-modal'))) {
$('#confirm-modal').appendTo($('#edit-user-modal').parent()); }
$('#confirm-modal').appendTo($('#edit-user-modal').parent());
}
$('#edit-user-modal > #confirm-modal').remove();
$('#edit-user-modal').css('z-index', '1050');
@@ -179,5 +175,4 @@ DOCUMENTATION :: END
});
});
</script>
% endif

View File

@@ -13,110 +13,132 @@
</div>
<div class="button-bar hidden-xs">
<div class="btn-group" data-toggle="buttons" id="yaxis-selection">
% if config['graph_type'] == 'duration':
<label class="btn btn-dark">
<input type="radio" name="yaxis-options" id="yaxis-count" value="plays" autocomplete="off"> Play Count
</label>
<label class="btn btn-dark active">
<input type="radio" name="yaxis-options" id="yaxis-duration" value="duration" autocomplete="off" checked> Play Duration
</label>
% else:
<label class="btn btn-dark active">
<input type="radio" name="yaxis-options" id="yaxis-count" value="plays" autocomplete="off" checked> Play Count
</label>
<label class="btn btn-dark">
<input type="radio" name="yaxis-options" id="yaxis-duration" value="duration" autocomplete="off"> Play Duration
</label>
% endif
</div>
<div class="btn-group" data-toggle="buttons" id="days-selection">
<label class="btn btn-dark">
<input type="radio" name="date-options" id="graph-7" value="7" autocomplete="off"> 7 days
</label>
<label class="btn btn-dark active">
<input type="radio" name="date-options" id="graph-30" value="30" autocomplete="off" checked> 30 days
</label>
<label class="btn btn-dark">
<input type="radio" name="date-options" id="graph-90" value="90" autocomplete="off"> 90 days
</label>
<label class="btn btn-dark">
<input type="radio" name="date-options" id="graph-365" value="365" autocomplete="off"> 1 year
<div class="btn-group" id="days-selection">
<label>
<input type="number" name="graph-days" id="graph-days" value="${config['graph_days']}" min="1" /> days
</label>
</div>
</div>
</div>
<div class='table-card-back'>
<ul class="nav nav-pills" role="tablist" id="graph-tabs">
% if config['graph_tab'] == 'tabs-3':
<li role="presentation"><a href="#tabs-1" aria-controls="tabs-1" data-toggle="tab" role="tab">Plays by period</a></li>
<li role="presentation"><a href="#tabs-2" aria-controls="tabs-2" data-toggle="tab" role="tab">Stream Info</a></li>
<li role="presentation" class="active"><a href="#tabs-3" aria-controls="tabs-3" data-toggle="tab" role="tab">Play Totals</a></li>
% elif config['graph_tab'] == 'tabs-2':
<li role="presentation"><a href="#tabs-1" aria-controls="tabs-1" data-toggle="tab" role="tab">Plays by period</a></li>
<li role="presentation" class="active"><a href="#tabs-2" aria-controls="tabs-2" data-toggle="tab" role="tab">Stream Info</a></li>
<li role="presentation"><a href="#tabs-3" aria-controls="tabs-3" data-toggle="tab" role="tab">Play Totals</a></li>
% else:
<li role="presentation" class="active"><a href="#tabs-1" aria-controls="tabs-1" data-toggle="tab" role="tab">Plays by period</a></li>
<li role="presentation"><a href="#tabs-2" aria-controls="tabs-2" data-toggle="tab" role="tab">Stream Info</a></li>
<li role="presentation"><a href="#tabs-3" aria-controls="tabs-3" data-toggle="tab" role="tab">Play Totals</a></li>
% endif
</ul>
<div class="tab-content">
% if config['graph_tab'] != 'tabs-2' and config['graph_tab'] != 'tabs-3':
<div role="tabpanel" class="tab-pane active" id="tabs-1">
<div class="row">
<div class="col-md-12">
<h4><i class="fa fa-history"></i> Daily <span class="yaxis-text">Play count</span> <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The total play count or duration of tv, movies, and music played per day. Click a graph point to open up a list of items played for that specific date.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_day">
<div class="graphs-load"><i class="fa fa-refresh fa-spin"></i> Loading chart...</div>
<br>
% else:
<div role="tabpanel" class="tab-pane" id="tabs-1">
% endif
<div class="row">
<div class="col-md-12">
<h4><i class="fa fa-history"></i> Daily <span class="yaxis-text">Play count</span> <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The total play count or duration of tv, movies, and music played per day. Click a graph point to open up a list of items played for that specific date.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_day">
<div class="graphs-load"><i class="fa fa-refresh fa-spin"></i> Loading chart...</div>
<br>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h4><i class="fa fa-calendar"></i> <span class="yaxis-text">Play count</span> by day of week <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The combined total of tv, movies, and music played per day of the week.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_dayofweek" style="float: left;">
<div class="graphs-load">
<i class="fa fa-refresh fa-spin"></i> Loading chart...
</div>
<br>
</div>
</div>
</div>
<div class="col-md-6">
<h4><i class="fa fa-clock-o"></i> <span class="yaxis-text">Play count</span> by hour of day <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The combined total of tv, movies, and music played per hour of the day.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_hourofday">
<div class="graphs-load">
<i class="fa fa-refresh fa-spin"></i> Loading chart...
</div>
<br>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h4><i class="fa fa-television"></i> <span class="yaxis-text">Play count</span> by top 10 platforms <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The combined total of tv, movies, and music played by top 10 most active platforms.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_platform" style="float: left;">
<div class="graphs-load">
<i class="fa fa-refresh fa-spin"></i> Loading chart...
</div>
<br>
</div>
</div>
</div>
<div class="col-md-6">
<h4><i class="fa fa-user"></i> <span class="yaxis-text">Play count</span> by top 10 users <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The combined total of tv, movies, and music played by top 10 most active users.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_user">
<div class="graphs-load">
<i class="fa fa-refresh fa-spin"></i> Loading chart...
</div>
<br>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h4><i class="fa fa-calendar"></i> <span class="yaxis-text">Play count</span> by day of week <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The combined total of tv, movies, and music played per day of the week.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_dayofweek" style="float: left;">
<div class="graphs-load"><i class="fa fa-refresh fa-spin"></i> Loading chart...
</div>
<br>
</div>
</div>
</div>
<div class="col-md-6">
<h4><i class="fa fa-clock-o"></i> <span class="yaxis-text">Play count</span> by hour of day <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The combined total of tv, movies, and music played per hour of the day.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_hourofday">
<div class="graphs-load"><i class="fa fa-refresh fa-spin"></i> Loading chart...
</div>
<br>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h4><i class="fa fa-television"></i> <span class="yaxis-text">Play count</span> by top 10 platforms <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The combined total of tv, movies, and music played by top 10 most active platforms.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_platform" style="float: left;">
<div class="graphs-load"><i class="fa fa-refresh fa-spin"></i> Loading chart...
</div>
<br>
</div>
</div>
</div>
<div class="col-md-6">
<h4><i class="fa fa-user"></i> <span class="yaxis-text">Play count</span> by top 10 users <small>Last <span class="days">30</span> days</small></h4>
<p class="help-block">
The combined total of tv, movies, and music played by top 10 most active users.
</p>
<div class="graphs-instance">
<div class="watch-chart" id="chart_div_plays_by_user">
<div class="graphs-load"><i class="fa fa-refresh fa-spin"></i> Loading chart...
</div>
<br>
</div>
</div>
</div>
</div>
</div>
% if config['graph_tab'] == 'tabs-2':
<div role="tabpanel" class="tab-pane active" id="tabs-2">
% else:
<div role="tabpanel" class="tab-pane" id="tabs-2">
% endif
<div class="row">
<div class="col-md-12">
<h4><i class="fa fa-video-camera"></i> Daily Stream type breakdown <small>Last <span class="days">30</span> days</small></h4>
@@ -189,7 +211,11 @@
</div>
</div>
% if config['graph_tab'] == 'tabs-3':
<div role="tabpanel" class="tab-pane active" id="tabs-3">
% else:
<div role="tabpanel" class="tab-pane" id="tabs-3">
% endif
<div class="row">
<div class="col-md-12">
<h4><i class="fa fa-calendar"></i> Plays by Month <small>Last 12 months</small></h4>
@@ -263,36 +289,12 @@
<script>
$(document).ready(function () {
// Save graph state to cookies
$('input[name=yaxis-options]').change(function() {
setCookie('graphType', $(this).val(), 365, '/');
});
$('input[name=date-options]').change(function() {
setCookie('graphDate', $(this).val(), 365, '/');
});
$('a[data-toggle=tab]').click(function() {
setCookie('graphTab', $(this).attr('href'), 365, '/');
});
// Initial values for graph from config
var yaxis = "${config['graph_type']}";
var current_range = ${config['graph_days']};
var current_tab = "${'#' + config['graph_tab']}";
// Initial values for graph if no saved state
var yaxis = 'plays';
var current_range = 30;
var current_tab = '#tabs-1';
// Read saved graph state from cookies and set initial values
if(getCookie('graphType')) {
var yaxis = getCookie('graphType');
$('input[name=yaxis-options][value=' + yaxis + ']').prop('checked', true).trigger('click');
}
if(getCookie('graphDate')) {
var current_range = getCookie('graphDate');
$('input[name=date-options][value=' + current_range + ']').prop('checked', true).trigger('click');
$('.days').html(current_range);
}
if(getCookie('graphTab')) {
var current_tab = getCookie('graphTab');
$('a[data-toggle=tab][href=' + current_tab + ']').trigger('click');
}
$('.days').html(current_range);
var music_visible = (${config['music_logging_enable']} == 1 ? true : false);
@@ -476,40 +478,61 @@
}
// Set initial state
loadGraphsTab1(current_range, yaxis);
if (current_tab == '#tabs-1') { loadGraphsTab1(current_range, yaxis); }
if (current_tab == '#tabs-2') { loadGraphsTab2(current_range, yaxis); }
if (current_tab == '#tabs-3') { loadGraphsTab3(yaxis); }
// Tab1 opened
$('#graph-tabs a[href="#tabs-1"]').on('shown.bs.tab', function (e) {
e.preventDefault();
current_tab = $(this).attr('href');
$('#days-selection').show();
loadGraphsTab1(current_range, yaxis);
$.ajax({
url: 'set_graph_config',
data: { graph_tab: current_tab.replace('#','') },
async: true
});
})
// Tab2 opened
$('#graph-tabs a[href="#tabs-2"]').on('shown.bs.tab', function (e) {
e.preventDefault();
current_tab = $(this).attr('href');
$('#days-selection').show();
loadGraphsTab2(current_range, yaxis);
$.ajax({
url: 'set_graph_config',
data: { graph_tab: current_tab.replace('#','') },
async: true
});
})
// Tab3 opened
$('#graph-tabs a[href="#tabs-3"]').on('shown.bs.tab', function (e) {
e.preventDefault();
current_tab = $(this).attr('href');
$('#days-selection').hide();
console.log('loading....');
loadGraphsTab3(yaxis);
$.ajax({
url: 'set_graph_config',
data: { graph_tab: current_tab.replace('#','') },
async: true
});
})
// Date range changed
$('#days-selection').on('change', function() {
current_range = $('input[name=date-options]:checked', '#days-selection').val();
$('#graph-days').on('change', function() {
current_range = $(this).val();
if (current_range < 1) {
$(this).val(7);
current_range = 7;
}
if (current_tab == '#tabs-1') { loadGraphsTab1(current_range, yaxis); }
if (current_tab == '#tabs-2') { loadGraphsTab2(current_range, yaxis); }
$('.days').html(current_range);
$.ajax({
url: 'set_graph_config',
data: { graph_days: current_range},
async: true
});
});
// Y-axis changed
@@ -518,6 +541,11 @@
if (current_tab == '#tabs-1') { loadGraphsTab1(current_range, yaxis); }
if (current_tab == '#tabs-2') { loadGraphsTab2(current_range, yaxis); }
if (current_tab == '#tabs-3') { loadGraphsTab3(yaxis); }
$.ajax({
url: 'set_graph_config',
data: { graph_type: yaxis},
async: true
});
});
function setGraphFormat(type) {

View File

@@ -25,18 +25,18 @@
<table class="display" id="history_table" width="100%">
<thead>
<tr>
<th align='left' id="delete_row">Delete</th>
<th align='left' id="time">Time</th>
<th align='left' id="friendly_name">User</th>
<th align='left' id="ip_address">IP Address</th>
<th align='left' id="platform">Platform</th>
<th align='left' id="device">Player</th>
<th align='left' id="title">Title</th>
<th align='left' id="started">Started</th>
<th align='left' id="paused_counter">Paused</th>
<th align='left' id="stopped">Stopped</th>
<th align='left' id="duration">Duration</th>
<th align='left' id="percent_complete"></th>
<th align="left" id="delete_row">Delete</th>
<th align="left" id="time">Time</th>
<th align="left" id="friendly_name">User</th>
<th align="left" id="ip_address">IP Address</th>
<th align="left" id="platform">Platform</th>
<th align="left" id="device">Player</th>
<th align="left" id="title">Title</th>
<th align="left" id="started">Started</th>
<th align="left" id="paused_counter">Paused</th>
<th align="left" id="stopped">Stopped</th>
<th align="left" id="duration">Duration</th>
<th align="left" id="percent_complete"></th>
</tr>
</thead>
<tbody>
@@ -83,8 +83,8 @@
type: 'post',
data: function (d) {
return {
'json_data': JSON.stringify(d),
'media_type': media_type
json_data: JSON.stringify(d),
media_type: media_type
};
}
}

View File

@@ -13,11 +13,11 @@
<table class="display" id="history_table" width="100%">
<thead>
<tr>
<th align='left' id="started">Started</th>
<th align='left' id="stopped">Stopped</th>
<th align='left' id="friendly_name">User</th>
<th align='left' id="player">Player</th>
<th align='left' id="title">Title</th>
<th align="left" id="started">Started</th>
<th align="left" id="stopped">Stopped</th>
<th align="left" id="friendly_name">User</th>
<th align="left" id="player">Player</th>
<th align="left" id="title">Title</th>
</tr>
</thead>
<tbody>
@@ -34,13 +34,14 @@
$(document).ready(function() {
$('#date-header').html(moment('${data}','YYYY-MM-DD').format('ddd MMM Do YYYY'));
history_table_modal_options.ajax = {
"url": "get_history",
type: "post",
url: 'get_history',
type: 'post',
data: function ( d ) {
return { 'json_data': JSON.stringify( d ),
'grouping': false,
'start_date': '${data}'
};
return {
json_data: JSON.stringify(d),
grouping: false,
start_date: '${data}'
};
}
}

View File

@@ -44,6 +44,11 @@ player Returns the player name for the associated stat.
== Only if 'stat_id' is 'last_watched' ==
last_watch Returns the time the media item was last watched.
== Only if 'stat_id' is 'most_concurrent' ==
count Returns the count of the most concurrent streams.
started Returns the start time of the most concurrent streams.
stopped Returns the stop time of the most concurrent streams.
DOCUMENTATION :: END
</%doc>
@@ -65,8 +70,8 @@ DOCUMENTATION :: END
%>
% if data:
% if data[0]['stat_id']:
<ul class="list-unstyled">
% if any(top_stat['rows'] for top_stat in data):
% for top_stat in data:
% if top_stat['stat_id'] == 'top_tv' and top_stat['rows']:
<div class="home-platforms-instance">
@@ -77,7 +82,7 @@ DOCUMENTATION :: END
</div>
<div class="home-platforms-instance-playcount">
<h4>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
${top_stat['rows'][0]['title']}
</a>
</h4>
@@ -89,7 +94,7 @@ DOCUMENTATION :: END
% endif
</div>
</div>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
% if top_stat['rows'][0]['grandparent_thumb']:
<div class="home-platforms-instance-poster">
<div class="home-platforms-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][0]['grandparent_thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -100,18 +105,18 @@ DOCUMENTATION :: END
</div>
% endif
</a>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
<h5>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
${top_stat['rows'][loop.index]['title']}
</a>
</h5>
@@ -125,7 +130,7 @@ DOCUMENTATION :: END
% endif
</div>
</div>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
% if top_stat['rows'][loop.index]['grandparent_thumb']:
<div class="home-platforms-instance-list-poster">
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['grandparent_thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -157,7 +162,7 @@ DOCUMENTATION :: END
</div>
<div class="home-platforms-instance-playcount">
<h4>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
${top_stat['rows'][0]['title']}
</a>
</h4>
@@ -165,7 +170,7 @@ DOCUMENTATION :: END
<p> users</p>
</div>
</div>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
% if top_stat['rows'][0]['grandparent_thumb'] != '':
<div class="home-platforms-instance-poster">
<div class="home-platforms-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][0]['grandparent_thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -176,18 +181,18 @@ DOCUMENTATION :: END
</div>
% endif
</a>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
<h5>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
${top_stat['rows'][loop.index]['title']}
</a>
</h5>
@@ -197,7 +202,7 @@ DOCUMENTATION :: END
<p> users</p>
</div>
</div>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
% if top_stat['rows'][loop.index]['grandparent_thumb']:
<div class="home-platforms-instance-list-poster">
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['grandparent_thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -229,7 +234,7 @@ DOCUMENTATION :: END
</div>
<div class="home-platforms-instance-playcount">
<h4>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
${top_stat['rows'][0]['title']}
</a>
</h4>
@@ -241,7 +246,7 @@ DOCUMENTATION :: END
% endif
</div>
</div>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
% if top_stat['rows'][0]['thumb']:
<div class="home-platforms-instance-poster">
<div class="home-platforms-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][0]['thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -252,18 +257,18 @@ DOCUMENTATION :: END
</div>
% endif
</a>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
<h5>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
${top_stat['rows'][loop.index]['title']}
</a>
</h5>
@@ -277,7 +282,7 @@ DOCUMENTATION :: END
% endif
</div>
</div>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
% if top_stat['rows'][loop.index]['thumb']:
<div class="home-platforms-instance-list-poster">
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -309,7 +314,7 @@ DOCUMENTATION :: END
</div>
<div class="home-platforms-instance-playcount">
<h4>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
${top_stat['rows'][0]['title']}
</a>
</h4>
@@ -317,7 +322,7 @@ DOCUMENTATION :: END
<p> users</p>
</div>
</div>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
% if top_stat['rows'][0]['thumb']:
<div class="home-platforms-instance-poster">
<div class="home-platforms-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][0]['thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -328,18 +333,18 @@ DOCUMENTATION :: END
</div>
% endif
</a>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
<h5>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
${top_stat['rows'][loop.index]['title']}
</a>
</h5>
@@ -349,7 +354,7 @@ DOCUMENTATION :: END
<p> users</p>
</div>
</div>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
% if top_stat['rows'][loop.index]['thumb']:
<div class="home-platforms-instance-list-poster">
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -381,7 +386,7 @@ DOCUMENTATION :: END
</div>
<div class="home-platforms-instance-playcount">
<h4>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
${top_stat['rows'][0]['title']}
</a>
</h4>
@@ -393,7 +398,7 @@ DOCUMENTATION :: END
% endif
</div>
</div>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
% if top_stat['rows'][0]['grandparent_thumb']:
<div class="home-platforms-instance-poster">
<div class="home-platforms-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][0]['grandparent_thumb']}&width=300&height=300&fallback=poster);"></div>
@@ -404,18 +409,18 @@ DOCUMENTATION :: END
</div>
% endif
</a>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
<h5>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
${top_stat['rows'][loop.index]['title']}
</a>
</h5>
@@ -429,7 +434,7 @@ DOCUMENTATION :: END
% endif
</div>
</div>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
% if top_stat['rows'][loop.index]['grandparent_thumb']:
<div class="home-platforms-instance-list-poster">
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['grandparent_thumb']}&width=300&height=300&fallback=poster);"></div>
@@ -461,7 +466,7 @@ DOCUMENTATION :: END
</div>
<div class="home-platforms-instance-playcount">
<h4>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
${top_stat['rows'][0]['title']}
</a>
</h4>
@@ -469,7 +474,7 @@ DOCUMENTATION :: END
<p> users</p>
</div>
</div>
<a href="info?item_id=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
<a href="info?rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
% if top_stat['rows'][0]['grandparent_thumb'] != '':
<div class="home-platforms-instance-poster">
<div class="home-platforms-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][0]['grandparent_thumb']}&width=300&height=300&fallback=poster);"></div>
@@ -480,18 +485,18 @@ DOCUMENTATION :: END
</div>
% endif
</a>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
<h5>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
${top_stat['rows'][loop.index]['title']}
</a>
</h5>
@@ -501,7 +506,7 @@ DOCUMENTATION :: END
<p> users</p>
</div>
</div>
<a href="info?item_id=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
% if top_stat['rows'][loop.index]['grandparent_thumb']:
<div class="home-platforms-instance-list-poster">
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['grandparent_thumb']}&width=300&height=300&fallback=poster);"></div>
@@ -564,13 +569,13 @@ DOCUMENTATION :: END
</div>
% endif
</a>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
@@ -642,13 +647,13 @@ DOCUMENTATION :: END
$("#platform-stat").html("<div class='home-platforms-instance-box' style='background-image: url(" + getPlatformImagePath('${top_stat['rows'][0]['platform_type']}') + ");'>");
</script>
</div>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
@@ -691,7 +696,7 @@ DOCUMENTATION :: END
</div>
<div class="home-platforms-instance-last-user">
<h4>
<a href="info?source=history&item_id=${top_stat['rows'][0]['row_id']}" title="${top_stat['rows'][0]['title']}">
<a href="info?source=history&rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
${top_stat['rows'][0]['title']}
</a>
</h4>
@@ -713,7 +718,7 @@ DOCUMENTATION :: END
</p>
</div>
</div>
<a href="info?source=history&item_id=${top_stat['rows'][0]['row_id']}" title="${top_stat['rows'][0]['title']}">
<a href="info?source=history&rating_key=${top_stat['rows'][0]['rating_key']}" title="${top_stat['rows'][0]['title']}">
% if top_stat['rows'][0]['thumb']:
<div class="home-platforms-instance-poster">
<div class="home-platforms-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][0]['thumb']}&width=300&height=450&fallback=poster);"></div>
@@ -724,18 +729,18 @@ DOCUMENTATION :: END
</div>
% endif
</a>
%if len(top_stat['rows']) > 1:
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
%if loop.index > 0:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
<h5>
<a href="info?source=history&item_id=${top_stat['rows'][loop.index]['row_id']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?source=history&rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
${top_stat['rows'][loop.index]['title']}
</a>
</h5>
@@ -759,13 +764,13 @@ DOCUMENTATION :: END
</p>
</div>
</div>
<a href="info?source=history&item_id=${top_stat['rows'][loop.index]['row_id']}" title="${top_stat['rows'][loop.index]['title']}">
<a href="info?source=history&rating_key=${top_stat['rows'][loop.index]['rating_key']}" title="${top_stat['rows'][loop.index]['title']}">
% if top_stat['rows'][loop.index]['thumb']:
<div class="home-platforms-instance-list-poster">
<div class="home-platforms-list-poster-face" style="background-image: url(pms_image_proxy?img=${top_stat['rows'][loop.index]['thumb']}&width=300&height=450&fallback=poster);"></div>
</div>
% else:
<div class="home-platforms-instance-poster2">
<div class="home-platforms-instance-list-poster">
<div class="home-platforms-list-poster-face" style="background-image: url(interfaces/default/images/poster.png);"></div>
</div>
% endif
@@ -782,8 +787,74 @@ DOCUMENTATION :: END
% endif
</li>
</div>
% elif top_stat['stat_id'] == 'most_concurrent' and top_stat['rows']:
<div class="home-platforms-instance">
<li>
<div class="home-platforms-instance-info">
<div class="home-platforms-instance-name">
<h4>Most Concurrent Streams</h4>
</div>
<div class="home-platforms-instance-playcount">
<h4>
<span id="most-concurrent-start">
<script>
$('#most-concurrent-start').text(moment(${top_stat['rows'][0]['started']},"X").format(date_format + ' ' + time_format));
</script>
</span>
</h4>
<h3>${top_stat['rows'][0]['count']}</h3>
<p> streams</p>
</div>
</div>
<div class="home-platforms-instance-poster">
<div class="home-platforms-instance-box" style="background-image: url(interfaces/default/images/home-stat_most-concurrent.png);"></div>
</div>
% if len(top_stat['rows']) > 1:
<div class="home-platforms-instance-list-chevron"><i class="fa fa-chevron-down"></i></div>
<ul class="list-unstyled">
<div class="slider">
<div class="home-platforms-instance-list">
% for row in top_stat['rows']:
% if loop.index > 0:
<li>
<div class="home-platforms-instance-list-info">
<div class="home-platforms-instance-list-name">
<h5>
${top_stat['rows'][loop.index]['title']}
</h5>
</div>
<div class="home-platforms-instance-list-playcount">
<h3>${top_stat['rows'][loop.index]['count']}</h3>
<p> streams
% if top_stat['rows'][loop.index]['started']:
- <span id="most-concurrent-start-${loop.index + 1}">
<script>
$('#most-concurrent-start-${loop.index + 1}').text(moment(${top_stat['rows'][loop.index]['started']},"X").format(date_format + ' ' + time_format));
</script>
</span>
% else:
- N/A
% endif
</p>
</div>
</div>
<div class="home-platforms-instance-poster">
<div class="home-platforms-instance-list-box" style="background-image: url(interfaces/default/images/home-stat_most-concurrent.png);"></div>
</div>
</li>
% endif
% endfor
</div>
</div>
</ul>
% endif
</li>
</div>
% endif
% endfor
% else:
<div class="text-muted">No stats to show for the selected period.</div><br>
% endif
</ul>
<script>
var topZIndex = 2;
@@ -799,9 +870,5 @@ DOCUMENTATION :: END
});
</script>
% else:
<div class="text-muted">No stats for selected period.</div><br>
% endif
% else:
<div class="text-muted">Unable to retrieve data from database. Please check your <a href="settings">settings</a>.
</div><br>
<div class="text-muted">No stats to show for the selected period.</div><br>
% endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 827 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More