mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 06:00:51 -07:00
Cleanup image caching and logs
* Prettier confirm modal dialogues * Setting to disable image caching
This commit is contained in:
parent
baf44a97b4
commit
e79f6d5617
10 changed files with 505 additions and 352 deletions
549
API.md
549
API.md
|
@ -70,6 +70,10 @@ Returns:
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### delete_cache
|
||||||
|
Delete and recreate the cache directory.
|
||||||
|
|
||||||
|
|
||||||
### delete_datatable_media_info_cache
|
### delete_datatable_media_info_cache
|
||||||
Delete the media info table cache for a specific library.
|
Delete the media info table cache for a specific library.
|
||||||
|
|
||||||
|
@ -85,6 +89,10 @@ Returns:
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### delete_image_cache
|
||||||
|
Delete and recreate the image cache directory.
|
||||||
|
|
||||||
|
|
||||||
### delete_library
|
### delete_library
|
||||||
Delete a library section from PlexPy. Also erases all history for the library.
|
Delete a library section from PlexPy. Also erases all history for the library.
|
||||||
|
|
||||||
|
@ -138,6 +146,10 @@ Return the api docs as a dict where commands are keys, docstring are value.
|
||||||
Return the api docs formatted with markdown.
|
Return the api docs formatted with markdown.
|
||||||
|
|
||||||
|
|
||||||
|
### download_log
|
||||||
|
Download the PlexPy log file.
|
||||||
|
|
||||||
|
|
||||||
### edit_library
|
### edit_library
|
||||||
Update a library section on PlexPy.
|
Update a library section on PlexPy.
|
||||||
|
|
||||||
|
@ -189,60 +201,60 @@ Returns:
|
||||||
json:
|
json:
|
||||||
{"stream_count": 3,
|
{"stream_count": 3,
|
||||||
"session":
|
"session":
|
||||||
[{"art": "/library/metadata/1219/art/1462175063",
|
[{"art": "/library/metadata/1219/art/1462175063",
|
||||||
"aspect_ratio": "1.78",
|
"aspect_ratio": "1.78",
|
||||||
"audio_channels": "6",
|
"audio_channels": "6",
|
||||||
"audio_codec": "ac3",
|
"audio_codec": "ac3",
|
||||||
"audio_decision": "transcode",
|
"audio_decision": "transcode",
|
||||||
"bif_thumb": "/library/parts/274169/indexes/sd/",
|
"bif_thumb": "/library/parts/274169/indexes/sd/",
|
||||||
"bitrate": "10617",
|
"bitrate": "10617",
|
||||||
"container": "mkv",
|
"container": "mkv",
|
||||||
"content_rating": "TV-MA",
|
"content_rating": "TV-MA",
|
||||||
"duration": "2998290",
|
"duration": "2998290",
|
||||||
"friendly_name": "Mother of Dragons",
|
"friendly_name": "Mother of Dragons",
|
||||||
"grandparent_rating_key": "1219",
|
"grandparent_rating_key": "1219",
|
||||||
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
||||||
"grandparent_title": "Game of Thrones",
|
"grandparent_title": "Game of Thrones",
|
||||||
"height": "1078",
|
"height": "1078",
|
||||||
"indexes": 1,
|
"indexes": 1,
|
||||||
"ip_address": "xxx.xxx.xxx.xxx",
|
"ip_address": "xxx.xxx.xxx.xxx",
|
||||||
"labels": [],
|
"labels": [],
|
||||||
"machine_id": "83f189w617623ccs6a1lqpby",
|
"machine_id": "83f189w617623ccs6a1lqpby",
|
||||||
"media_index": "1",
|
"media_index": "1",
|
||||||
"media_type": "episode",
|
"media_type": "episode",
|
||||||
"parent_media_index": "6",
|
"parent_media_index": "6",
|
||||||
"parent_rating_key": "153036",
|
"parent_rating_key": "153036",
|
||||||
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
|
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
|
||||||
"parent_title": "",
|
"parent_title": "",
|
||||||
"platform": "Chrome",
|
"platform": "Chrome",
|
||||||
"player": "Plex Web (Chrome)",
|
"player": "Plex Web (Chrome)",
|
||||||
"progress_percent": "0",
|
"progress_percent": "0",
|
||||||
"rating_key": "153037",
|
"rating_key": "153037",
|
||||||
"section_id": "2",
|
"section_id": "2",
|
||||||
"session_key": "291",
|
"session_key": "291",
|
||||||
"state": "playing",
|
"state": "playing",
|
||||||
"throttled": "1",
|
"throttled": "1",
|
||||||
"thumb": "/library/metadata/153037/thumb/1462175060",
|
"thumb": "/library/metadata/153037/thumb/1462175060",
|
||||||
"title": "The Red Woman",
|
"title": "The Red Woman",
|
||||||
"transcode_audio_channels": "2",
|
"transcode_audio_channels": "2",
|
||||||
"transcode_audio_codec": "aac",
|
"transcode_audio_codec": "aac",
|
||||||
"transcode_container": "mkv",
|
"transcode_container": "mkv",
|
||||||
"transcode_height": "1078",
|
"transcode_height": "1078",
|
||||||
"transcode_key": "tiv5p524wcupe8nxegc26s9k9",
|
"transcode_key": "tiv5p524wcupe8nxegc26s9k9",
|
||||||
"transcode_progress": 2,
|
"transcode_progress": 2,
|
||||||
"transcode_protocol": "http",
|
"transcode_protocol": "http",
|
||||||
"transcode_speed": "0.0",
|
"transcode_speed": "0.0",
|
||||||
"transcode_video_codec": "h264",
|
"transcode_video_codec": "h264",
|
||||||
"transcode_width": "1920",
|
"transcode_width": "1920",
|
||||||
"user": "DanyKhaleesi69",
|
"user": "DanyKhaleesi69",
|
||||||
"user_id": 8008135,
|
"user_id": 8008135,
|
||||||
"user_thumb": "https://plex.tv/users/568gwwoib5t98a3a/avatar",
|
"user_thumb": "https://plex.tv/users/568gwwoib5t98a3a/avatar",
|
||||||
"video_codec": "h264",
|
"video_codec": "h264",
|
||||||
"video_decision": "copy",
|
"video_decision": "copy",
|
||||||
"video_framerate": "24p",
|
"video_framerate": "24p",
|
||||||
"video_resolution": "1080",
|
"video_resolution": "1080",
|
||||||
"view_offset": "",
|
"view_offset": "",
|
||||||
"width": "1920",
|
"width": "1920",
|
||||||
"year": "2016"
|
"year": "2016"
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -381,22 +393,22 @@ Returns:
|
||||||
{"stat_id": "top_tv",
|
{"stat_id": "top_tv",
|
||||||
"stat_type": "total_plays",
|
"stat_type": "total_plays",
|
||||||
"rows":
|
"rows":
|
||||||
[{"content_rating": "TV-MA",
|
[{"content_rating": "TV-MA",
|
||||||
"friendly_name": "",
|
"friendly_name": "",
|
||||||
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
||||||
"labels": [],
|
"labels": [],
|
||||||
"last_play": 1462380698,
|
"last_play": 1462380698,
|
||||||
"media_type": "episode",
|
"media_type": "episode",
|
||||||
"platform": "",
|
"platform": "",
|
||||||
"platform_type": "",
|
"platform_type": "",
|
||||||
"rating_key": 1219,
|
"rating_key": 1219,
|
||||||
"row_id": 1116,
|
"row_id": 1116,
|
||||||
"section_id": 2,
|
"section_id": 2,
|
||||||
"thumb": "",
|
"thumb": "",
|
||||||
"title": "Game of Thrones",
|
"title": "Game of Thrones",
|
||||||
"total_duration": 213302,
|
"total_duration": 213302,
|
||||||
"total_plays": 69,
|
"total_plays": 69,
|
||||||
"user": "",
|
"user": "",
|
||||||
"users_watched": ""
|
"users_watched": ""
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -443,13 +455,13 @@ Optional parameters:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
json:
|
json:
|
||||||
[{"art": "/:/resources/show-fanart.jpg",
|
[{"art": "/:/resources/show-fanart.jpg",
|
||||||
"child_count": "3745",
|
"child_count": "3745",
|
||||||
"count": "62",
|
"count": "62",
|
||||||
"parent_count": "240",
|
"parent_count": "240",
|
||||||
"section_id": "2",
|
"section_id": "2",
|
||||||
"section_name": "TV Shows",
|
"section_name": "TV Shows",
|
||||||
"section_type": "show",
|
"section_type": "show",
|
||||||
"thumb": "/:/resources/show.png"
|
"thumb": "/:/resources/show.png"
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -479,30 +491,30 @@ Returns:
|
||||||
"recordsTotal": 10,
|
"recordsTotal": 10,
|
||||||
"recordsFiltered": 10,
|
"recordsFiltered": 10,
|
||||||
"data":
|
"data":
|
||||||
[{"child_count": 3745,
|
[{"child_count": 3745,
|
||||||
"content_rating": "TV-MA",
|
"content_rating": "TV-MA",
|
||||||
"count": 62,
|
"count": 62,
|
||||||
"do_notify": "Checked",
|
"do_notify": "Checked",
|
||||||
"do_notify_created": "Checked",
|
"do_notify_created": "Checked",
|
||||||
"duration": 1578037,
|
"duration": 1578037,
|
||||||
"id": 1128,
|
"id": 1128,
|
||||||
"keep_history": "Checked",
|
"keep_history": "Checked",
|
||||||
"labels": [],
|
"labels": [],
|
||||||
"last_accessed": 1462693216,
|
"last_accessed": 1462693216,
|
||||||
"last_played": "Game of Thrones - The Red Woman",
|
"last_played": "Game of Thrones - The Red Woman",
|
||||||
"library_art": "/:/resources/show-fanart.jpg",
|
"library_art": "/:/resources/show-fanart.jpg",
|
||||||
"library_thumb": "",
|
"library_thumb": "",
|
||||||
"media_index": 1,
|
"media_index": 1,
|
||||||
"media_type": "episode",
|
"media_type": "episode",
|
||||||
"parent_count": 240,
|
"parent_count": 240,
|
||||||
"parent_media_index": 6,
|
"parent_media_index": 6,
|
||||||
"parent_title": "",
|
"parent_title": "",
|
||||||
"plays": 772,
|
"plays": 772,
|
||||||
"rating_key": 153037,
|
"rating_key": 153037,
|
||||||
"section_id": 2,
|
"section_id": 2,
|
||||||
"section_name": "TV Shows",
|
"section_name": "TV Shows",
|
||||||
"section_type": "Show",
|
"section_type": "Show",
|
||||||
"thumb": "/library/metadata/153036/thumb/1462175062",
|
"thumb": "/library/metadata/153036/thumb/1462175062",
|
||||||
"year": 2016
|
"year": 2016
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -538,27 +550,27 @@ Returns:
|
||||||
"filtered_file_size": 2616760056742,
|
"filtered_file_size": 2616760056742,
|
||||||
"total_file_size": 2616760056742,
|
"total_file_size": 2616760056742,
|
||||||
"data":
|
"data":
|
||||||
[{"added_at": "1403553078",
|
[{"added_at": "1403553078",
|
||||||
"audio_channels": "",
|
"audio_channels": "",
|
||||||
"audio_codec": "",
|
"audio_codec": "",
|
||||||
"bitrate": "",
|
"bitrate": "",
|
||||||
"container": "",
|
"container": "",
|
||||||
"file_size": 253660175293,
|
"file_size": 253660175293,
|
||||||
"grandparent_rating_key": "",
|
"grandparent_rating_key": "",
|
||||||
"last_played": 1462380698,
|
"last_played": 1462380698,
|
||||||
"media_index": "1",
|
"media_index": "1",
|
||||||
"media_type": "show",
|
"media_type": "show",
|
||||||
"parent_media_index": "",
|
"parent_media_index": "",
|
||||||
"parent_rating_key": "",
|
"parent_rating_key": "",
|
||||||
"play_count": 15,
|
"play_count": 15,
|
||||||
"rating_key": "1219",
|
"rating_key": "1219",
|
||||||
"section_id": 2,
|
"section_id": 2,
|
||||||
"section_type": "show",
|
"section_type": "show",
|
||||||
"thumb": "/library/metadata/1219/thumb/1436265995",
|
"thumb": "/library/metadata/1219/thumb/1436265995",
|
||||||
"title": "Game of Thrones",
|
"title": "Game of Thrones",
|
||||||
"video_codec": "",
|
"video_codec": "",
|
||||||
"video_framerate": "",
|
"video_framerate": "",
|
||||||
"video_resolution": "",
|
"video_resolution": "",
|
||||||
"year": "2011"
|
"year": "2011"
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -631,51 +643,51 @@ Returns:
|
||||||
json:
|
json:
|
||||||
{"metadata":
|
{"metadata":
|
||||||
{"actors": [
|
{"actors": [
|
||||||
"Kit Harington",
|
"Kit Harington",
|
||||||
"Emilia Clarke",
|
"Emilia Clarke",
|
||||||
"Isaac Hempstead-Wright",
|
"Isaac Hempstead-Wright",
|
||||||
"Maisie Williams",
|
"Maisie Williams",
|
||||||
"Liam Cunningham",
|
"Liam Cunningham",
|
||||||
],
|
],
|
||||||
"added_at": "1461572396",
|
"added_at": "1461572396",
|
||||||
"art": "/library/metadata/1219/art/1462175063",
|
"art": "/library/metadata/1219/art/1462175063",
|
||||||
"content_rating": "TV-MA",
|
"content_rating": "TV-MA",
|
||||||
"directors": [
|
"directors": [
|
||||||
"Jeremy Podeswa"
|
"Jeremy Podeswa"
|
||||||
],
|
],
|
||||||
"duration": "2998290",
|
"duration": "2998290",
|
||||||
"genres": [
|
"genres": [
|
||||||
"Adventure",
|
"Adventure",
|
||||||
"Drama",
|
"Drama",
|
||||||
"Fantasy"
|
"Fantasy"
|
||||||
],
|
],
|
||||||
"grandparent_rating_key": "1219",
|
"grandparent_rating_key": "1219",
|
||||||
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
||||||
"grandparent_title": "Game of Thrones",
|
"grandparent_title": "Game of Thrones",
|
||||||
"guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
|
"guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
|
||||||
"labels": [],
|
"labels": [],
|
||||||
"last_viewed_at": "1462165717",
|
"last_viewed_at": "1462165717",
|
||||||
"library_name": "TV Shows",
|
"library_name": "TV Shows",
|
||||||
"media_index": "1",
|
"media_index": "1",
|
||||||
"media_type": "episode",
|
"media_type": "episode",
|
||||||
"originally_available_at": "2016-04-24",
|
"originally_available_at": "2016-04-24",
|
||||||
"parent_media_index": "6",
|
"parent_media_index": "6",
|
||||||
"parent_rating_key": "153036",
|
"parent_rating_key": "153036",
|
||||||
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
|
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
|
||||||
"parent_title": "",
|
"parent_title": "",
|
||||||
"rating": "7.8",
|
"rating": "7.8",
|
||||||
"rating_key": "153037",
|
"rating_key": "153037",
|
||||||
"section_id": "2",
|
"section_id": "2",
|
||||||
"studio": "HBO",
|
"studio": "HBO",
|
||||||
"summary": "Jon Snow is dead. Daenerys meets a strong man. Cersei sees her daughter again.",
|
"summary": "Jon Snow is dead. Daenerys meets a strong man. Cersei sees her daughter again.",
|
||||||
"tagline": "",
|
"tagline": "",
|
||||||
"thumb": "/library/metadata/153037/thumb/1462175060",
|
"thumb": "/library/metadata/153037/thumb/1462175060",
|
||||||
"title": "The Red Woman",
|
"title": "The Red Woman",
|
||||||
"updated_at": "1462175060",
|
"updated_at": "1462175060",
|
||||||
"writers": [
|
"writers": [
|
||||||
"David Benioff",
|
"David Benioff",
|
||||||
"D. B. Weiss"
|
"D. B. Weiss"
|
||||||
],
|
],
|
||||||
"year": "2016"
|
"year": "2016"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,20 +732,20 @@ Returns:
|
||||||
"recordsTotal": 1039,
|
"recordsTotal": 1039,
|
||||||
"recordsFiltered": 163,
|
"recordsFiltered": 163,
|
||||||
"data":
|
"data":
|
||||||
[{"agent_id": 13,
|
[{"agent_id": 13,
|
||||||
"agent_name": "Telegram",
|
"agent_name": "Telegram",
|
||||||
"body_text": "Game of Thrones - S06E01 - The Red Woman [Transcode].",
|
"body_text": "Game of Thrones - S06E01 - The Red Woman [Transcode].",
|
||||||
"id": 1000,
|
"id": 1000,
|
||||||
"notify_action": "play",
|
"notify_action": "play",
|
||||||
"poster_url": "http://i.imgur.com/ZSqS8Ri.jpg",
|
"poster_url": "http://i.imgur.com/ZSqS8Ri.jpg",
|
||||||
"rating_key": 153037,
|
"rating_key": 153037,
|
||||||
"script_args": "[]",
|
"script_args": "[]",
|
||||||
"session_key": 147,
|
"session_key": 147,
|
||||||
"subject_text": "PlexPy (Winterfell-Server)",
|
"subject_text": "PlexPy (Winterfell-Server)",
|
||||||
"timestamp": 1462253821,
|
"timestamp": 1462253821,
|
||||||
"user": "DanyKhaleesi69",
|
"user": "DanyKhaleesi69",
|
||||||
"user_id": 8008135
|
"user_id": 8008135
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
{...}
|
{...}
|
||||||
]
|
]
|
||||||
|
@ -996,8 +1008,8 @@ Optional parameters:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
json:
|
json:
|
||||||
[["May 08, 2016 09:35:37",
|
[["May 08, 2016 09:35:37",
|
||||||
"DEBUG",
|
"DEBUG",
|
||||||
"Auth: Came in with a super-token, authorization succeeded."
|
"Auth: Came in with a super-token, authorization succeeded."
|
||||||
],
|
],
|
||||||
[...],
|
[...],
|
||||||
|
@ -1019,21 +1031,21 @@ Optional parameters:
|
||||||
Returns:
|
Returns:
|
||||||
json:
|
json:
|
||||||
{"recently_added":
|
{"recently_added":
|
||||||
[{"added_at": "1461572396",
|
[{"added_at": "1461572396",
|
||||||
"grandparent_rating_key": "1219",
|
"grandparent_rating_key": "1219",
|
||||||
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
||||||
"grandparent_title": "Game of Thrones",
|
"grandparent_title": "Game of Thrones",
|
||||||
"library_name": "",
|
"library_name": "",
|
||||||
"media_index": "1",
|
"media_index": "1",
|
||||||
"media_type": "episode",
|
"media_type": "episode",
|
||||||
"parent_media_index": "6",
|
"parent_media_index": "6",
|
||||||
"parent_rating_key": "153036",
|
"parent_rating_key": "153036",
|
||||||
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
|
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
|
||||||
"parent_title": "",
|
"parent_title": "",
|
||||||
"rating_key": "153037",
|
"rating_key": "153037",
|
||||||
"section_id": "2",
|
"section_id": "2",
|
||||||
"thumb": "/library/metadata/153037/thumb/1462175060",
|
"thumb": "/library/metadata/153037/thumb/1462175060",
|
||||||
"title": "The Red Woman",
|
"title": "The Red Woman",
|
||||||
"year": "2016"
|
"year": "2016"
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -1108,12 +1120,12 @@ Optional parameters:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
json:
|
json:
|
||||||
[{"clientIdentifier": "ds48g4r354a8v9byrrtr697g3g79w",
|
[{"clientIdentifier": "ds48g4r354a8v9byrrtr697g3g79w",
|
||||||
"httpsRequired": "0",
|
"httpsRequired": "0",
|
||||||
"ip": "xxx.xxx.xxx.xxx",
|
"ip": "xxx.xxx.xxx.xxx",
|
||||||
"label": "Winterfell-Server",
|
"label": "Winterfell-Server",
|
||||||
"local": "1",
|
"local": "1",
|
||||||
"port": "32400",
|
"port": "32400",
|
||||||
"value": "xxx.xxx.xxx.xxx"
|
"value": "xxx.xxx.xxx.xxx"
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -1237,26 +1249,26 @@ Optional parameters:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
json:
|
json:
|
||||||
[{"content_type": "video",
|
[{"content_type": "video",
|
||||||
"device_name": "Tyrion's iPad",
|
"device_name": "Tyrion's iPad",
|
||||||
"failure": "",
|
"failure": "",
|
||||||
"friendly_name": "Tyrion Lannister",
|
"friendly_name": "Tyrion Lannister",
|
||||||
"item_complete_count": "0",
|
"item_complete_count": "0",
|
||||||
"item_count": "1",
|
"item_count": "1",
|
||||||
"item_downloaded_count": "0",
|
"item_downloaded_count": "0",
|
||||||
"item_downloaded_percent_complete": 0,
|
"item_downloaded_percent_complete": 0,
|
||||||
"metadata_type": "movie",
|
"metadata_type": "movie",
|
||||||
"music_bitrate": "192",
|
"music_bitrate": "192",
|
||||||
"photo_quality": "74",
|
"photo_quality": "74",
|
||||||
"platform": "iOS",
|
"platform": "iOS",
|
||||||
"rating_key": "154092",
|
"rating_key": "154092",
|
||||||
"root_title": "Deadpool",
|
"root_title": "Deadpool",
|
||||||
"state": "pending",
|
"state": "pending",
|
||||||
"sync_id": "11617019",
|
"sync_id": "11617019",
|
||||||
"title": "Deadpool",
|
"title": "Deadpool",
|
||||||
"total_size": "0",
|
"total_size": "0",
|
||||||
"user_id": "328871",
|
"user_id": "328871",
|
||||||
"username": "DrukenDwarfMan",
|
"username": "DrukenDwarfMan",
|
||||||
"video_quality": "60"
|
"video_quality": "60"
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -1286,24 +1298,24 @@ Returns:
|
||||||
"recordsTotal": 2344,
|
"recordsTotal": 2344,
|
||||||
"recordsFiltered": 10,
|
"recordsFiltered": 10,
|
||||||
"data":
|
"data":
|
||||||
[{"friendly_name": "Jon Snow",
|
[{"friendly_name": "Jon Snow",
|
||||||
"id": 1121,
|
"id": 1121,
|
||||||
"ip_address": "xxx.xxx.xxx.xxx",
|
"ip_address": "xxx.xxx.xxx.xxx",
|
||||||
"last_played": "Game of Thrones - The Red Woman",
|
"last_played": "Game of Thrones - The Red Woman",
|
||||||
"last_seen": 1462591869,
|
"last_seen": 1462591869,
|
||||||
"media_index": 1,
|
"media_index": 1,
|
||||||
"media_type": "episode",
|
"media_type": "episode",
|
||||||
"parent_media_index": 6,
|
"parent_media_index": 6,
|
||||||
"parent_title": "",
|
"parent_title": "",
|
||||||
"platform": "Chrome",
|
"platform": "Chrome",
|
||||||
"play_count": 149,
|
"play_count": 149,
|
||||||
"player": "Plex Web (Chrome)",
|
"player": "Plex Web (Chrome)",
|
||||||
"rating_key": 153037,
|
"rating_key": 153037,
|
||||||
"thumb": "/library/metadata/153036/thumb/1462175062",
|
"thumb": "/library/metadata/153036/thumb/1462175062",
|
||||||
"transcode_decision": "transcode",
|
"transcode_decision": "transcode",
|
||||||
"user_id": 328871,
|
"user_id": 328871,
|
||||||
"year": 2016
|
"year": 2016
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
{...}
|
{...}
|
||||||
]
|
]
|
||||||
|
@ -1343,17 +1355,17 @@ Optional parameters:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
json:
|
json:
|
||||||
[{"email": "Jon.Snow.1337@CastleBlack.com",
|
[{"email": "Jon.Snow.1337@CastleBlack.com",
|
||||||
"filter_all": "",
|
"filter_all": "",
|
||||||
"filter_movies": "",
|
"filter_movies": "",
|
||||||
"filter_music": "",
|
"filter_music": "",
|
||||||
"filter_photos": "",
|
"filter_photos": "",
|
||||||
"filter_tv": "",
|
"filter_tv": "",
|
||||||
"is_allow_sync": null,
|
"is_allow_sync": null,
|
||||||
"is_home_user": "1",
|
"is_home_user": "1",
|
||||||
"is_restricted": "0",
|
"is_restricted": "0",
|
||||||
"thumb": "https://plex.tv/users/k10w42309cynaopq/avatar",
|
"thumb": "https://plex.tv/users/k10w42309cynaopq/avatar",
|
||||||
"user_id": "328871",
|
"user_id": "328871",
|
||||||
"username": "Jon Snow"
|
"username": "Jon Snow"
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
|
@ -1383,29 +1395,29 @@ Returns:
|
||||||
"recordsTotal": 10,
|
"recordsTotal": 10,
|
||||||
"recordsFiltered": 10,
|
"recordsFiltered": 10,
|
||||||
"data":
|
"data":
|
||||||
[{"allow_guest": "Checked",
|
[{"allow_guest": "Checked",
|
||||||
"do_notify": "Checked",
|
"do_notify": "Checked",
|
||||||
"duration": 2998290,
|
"duration": 2998290,
|
||||||
"friendly_name": "Jon Snow",
|
"friendly_name": "Jon Snow",
|
||||||
"id": 1121,
|
"id": 1121,
|
||||||
"ip_address": "xxx.xxx.xxx.xxx",
|
"ip_address": "xxx.xxx.xxx.xxx",
|
||||||
"keep_history": "Checked",
|
"keep_history": "Checked",
|
||||||
"last_played": "Game of Thrones - The Red Woman",
|
"last_played": "Game of Thrones - The Red Woman",
|
||||||
"last_seen": 1462591869,
|
"last_seen": 1462591869,
|
||||||
"media_index": 1,
|
"media_index": 1,
|
||||||
"media_type": "episode",
|
"media_type": "episode",
|
||||||
"parent_media_index": 6,
|
"parent_media_index": 6,
|
||||||
"parent_title": "",
|
"parent_title": "",
|
||||||
"platform": "Chrome",
|
"platform": "Chrome",
|
||||||
"player": "Plex Web (Chrome)",
|
"player": "Plex Web (Chrome)",
|
||||||
"plays": 487,
|
"plays": 487,
|
||||||
"rating_key": 153037,
|
"rating_key": 153037,
|
||||||
"thumb": "/library/metadata/153036/thumb/1462175062",
|
"thumb": "/library/metadata/153036/thumb/1462175062",
|
||||||
"transcode_decision": "transcode",
|
"transcode_decision": "transcode",
|
||||||
"user_id": 328871,
|
"user_id": 328871,
|
||||||
"user_thumb": "https://plex.tv/users/568gwwoib5t98a3a/avatar",
|
"user_thumb": "https://plex.tv/users/568gwwoib5t98a3a/avatar",
|
||||||
"year": 2016
|
"year": 2016
|
||||||
},
|
},
|
||||||
{...},
|
{...},
|
||||||
{...}
|
{...}
|
||||||
]
|
]
|
||||||
|
@ -1467,7 +1479,7 @@ Required parameters:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
json:
|
json:
|
||||||
{"results_count": 69,
|
{"results_count": 69,
|
||||||
"results_list":
|
"results_list":
|
||||||
{"movie":
|
{"movie":
|
||||||
[{...},
|
[{...},
|
||||||
|
@ -1553,4 +1565,5 @@ Optional parameters:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None
|
None
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,25 @@
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="confirm-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal">
|
||||||
|
<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">Confirm</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div id="confirm-message" style="text-align: center; margin-top: 20px; margin-bottom: 20px;">
|
||||||
|
</div>
|
||||||
|
</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-button">Confirm</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
% if _session['user_group'] != 'admin':
|
% if _session['user_group'] != 'admin':
|
||||||
<div id="admin-login-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="admin-login-modal">
|
<div id="admin-login-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="admin-login-modal">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
|
@ -310,18 +329,20 @@ ${next.headerIncludes()}
|
||||||
$('#updatebar').show();
|
$('#updatebar').show();
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#nav-shutdown").click(function () {
|
$("#nav-shutdown").click(function() {
|
||||||
var r = confirm("Are you sure you want to shutdown PlexPy?");
|
$("#confirm-message").text("Are you sure you want to shutdown PlexPy?");
|
||||||
if (r == true) {
|
$('#confirm-modal').modal();
|
||||||
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
window.location.href = "shutdown";
|
window.location.href = "shutdown";
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#nav-restart").click(function () {
|
$("#nav-restart").click(function() {
|
||||||
var r = confirm("Are you sure you want to restart PlexPy?");
|
$("#confirm-message").text("Are you sure you want to restart PlexPy?");
|
||||||
if (r == true) {
|
$('#confirm-modal').modal();
|
||||||
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
window.location.href = "restart";
|
window.location.href = "restart";
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#nav-update").first().one("click", function () {
|
$("#nav-update").first().one("click", function () {
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="button-bar">
|
<div class="button-bar">
|
||||||
<button class="btn btn-dark" id="download-plexpylog"><i class="fa fa-download"></i> Download log</button>
|
<button class="btn btn-dark" id="download-plexpylog"><i class="fa fa-download"></i> Download log</button>
|
||||||
<button class="btn btn-dark" id="clear-logs"><i class="fa fa-trash-o"></i> Clear log</button>
|
<button class="btn btn-dark" id="clear-logs"><i class="fa fa-trash-o"></i> Clear logs</button>
|
||||||
<button class="btn btn-dark" id="clear-notify-logs" style="display: none;"><i class="fa fa-trash-o"></i> Clear log</button>
|
<button class="btn btn-dark" id="clear-notify-logs" style="display: none;"><i class="fa fa-trash-o"></i> Clear logs</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='table-card-back'>
|
<div class='table-card-back'>
|
||||||
|
@ -189,10 +189,24 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#clear-logs").click(function () {
|
$("#clear-logs").click(function () {
|
||||||
var r = confirm("Are you sure you want to clear the PlexPy log?");
|
$("#confirm-message").text("Are you sure you want to clear the PlexPy logs?");
|
||||||
if (r == true) {
|
$('#confirm-modal').modal();
|
||||||
window.location.href = "clearLogs";
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
}
|
$.ajax({
|
||||||
|
url: 'delete_logs',
|
||||||
|
type: 'POST',
|
||||||
|
complete: function (xhr, status) {
|
||||||
|
result = $.parseJSON(xhr.responseText);
|
||||||
|
msg = result.message;
|
||||||
|
if (result.result == 'success') {
|
||||||
|
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
|
||||||
|
} else {
|
||||||
|
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
|
||||||
|
}
|
||||||
|
log_table.draw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#download-plexpylog").click(function () {
|
$("#download-plexpylog").click(function () {
|
||||||
|
@ -201,16 +215,24 @@
|
||||||
|
|
||||||
|
|
||||||
$("#clear-notify-logs").click(function () {
|
$("#clear-notify-logs").click(function () {
|
||||||
var r = confirm("Are you sure you want to clear the PlexPy notification log?");
|
$("#confirm-message").text("Are you sure you want to clear the PlexPy notification logs?");
|
||||||
if (r == true) {
|
$('#confirm-modal').modal();
|
||||||
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'delete_notification_log',
|
url: 'delete_notification_log',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
success: function (data) {
|
complete: function (xhr, status) {
|
||||||
|
result = $.parseJSON(xhr.responseText);
|
||||||
|
msg = result.message;
|
||||||
|
if (result.result == 'success') {
|
||||||
|
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
|
||||||
|
} else {
|
||||||
|
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
|
||||||
|
}
|
||||||
notification_log_table.draw();
|
notification_log_table.draw();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var timer;
|
var timer;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import plexpy
|
import plexpy
|
||||||
from plexpy import common, notifiers, versioncheck
|
from plexpy import common, logger, notifiers, versioncheck
|
||||||
from plexpy.helpers import anon_url
|
from plexpy.helpers import anon_url
|
||||||
|
|
||||||
available_notification_agents = sorted(notifiers.available_notification_agents(), key=lambda k: k['name'])
|
available_notification_agents = sorted(notifiers.available_notification_agents(), key=lambda k: k['name'])
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Log File:</td>
|
<td>Log File:</td>
|
||||||
<td><a class="no-highlight" href="logFile" target="_blank">${os.path.join(config['log_dir'],'plexpy.log')}</a></td>
|
<td><a class="no-highlight" href="logFile" target="_blank">${os.path.join(config['log_dir'], logger.FILENAME)}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Backup Directory:</td>
|
<td>Backup Directory:</td>
|
||||||
|
@ -198,24 +198,39 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="backup_dir">Backup Directory</label>
|
<label for="backup_dir">Backup Directory</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-8">
|
||||||
<input type="text" class="form-control directory-settings" id="backup_dir" name="backup_dir" value="${config['backup_dir']}">
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control directory-settings" id="backup_dir" name="backup_dir" value="${config['backup_dir']}">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-form" type="button" id="backup_database">Backup Database</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="cache_dir">Cache Directory</label>
|
<label for="cache_dir">Cache Directory</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-8">
|
||||||
<input type="text" class="form-control directory-settings" id="cache_dir" name="cache_dir" value="${config['cache_dir']}">
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control directory-settings" id="cache_dir" name="cache_dir" value="${config['cache_dir']}">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-form" type="button" id="clear_cache">Clear Cache</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="log_dir">Log Directory</label>
|
<label for="log_dir">Log Directory</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-8">
|
||||||
<input type="text" class="form-control directory-settings" id="log_dir" name="log_dir" value="${config['log_dir']}">
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control directory-settings" id="log_dir" name="log_dir" value="${config['log_dir']}">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-form" type="button" id="clear_logs">Clear Logs</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -724,6 +739,14 @@
|
||||||
Note: Only logs from the time this setting is enabled will be masked. Do not post your logs publically without masking sensitive information!
|
Note: Only logs from the time this setting is enabled will be masked. Do not post your logs publically without masking sensitive information!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="cache_images" name="cache_images" value="1" ${config['cache_images']}> Cache Plex Images
|
||||||
|
</label>
|
||||||
|
<p class="help-block">
|
||||||
|
Enable to cache images from Plex to reduce API calls and improve loading times.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="anon_redirect">Anonymous Redirect</label>
|
<label for="anon_redirect">Anonymous Redirect</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -2056,7 +2079,7 @@ $(document).ready(function() {
|
||||||
postSaveChecks();
|
postSaveChecks();
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
showMsg('<i class="fa fa-exclamation-circle"></i> Please verify your settings.', false, true, 2000, true)
|
showMsg('<i class="fa fa-exclamation-circle"></i> Please verify your settings.', false, true, 5000, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2069,17 +2092,19 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#menu_link_shutdown").click(function() {
|
$("#menu_link_shutdown").click(function() {
|
||||||
var r = confirm("Are you sure you want to shutdown PlexPy?");
|
$("#confirm-message").text("Are you sure you want to shutdown PlexPy?");
|
||||||
if (r == true) {
|
$('#confirm-modal').modal();
|
||||||
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
window.location.href = "shutdown";
|
window.location.href = "shutdown";
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#menu_link_restart").click(function() {
|
$("#menu_link_restart").click(function() {
|
||||||
var r = confirm("Are you sure you want to restart PlexPy?");
|
$("#confirm-message").text("Are you sure you want to restart PlexPy?");
|
||||||
if (r == true) {
|
$('#confirm-modal').modal();
|
||||||
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
window.location.href = "restart";
|
window.location.href = "restart";
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#menu_link_update_check").click(function() {
|
$("#menu_link_update_check").click(function() {
|
||||||
|
@ -2094,6 +2119,66 @@ $(document).ready(function() {
|
||||||
window.location.href = "restart";
|
window.location.href = "restart";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#backup_database").click(function () {
|
||||||
|
$("#confirm-message").text("Are you sure you want to create a backup of the PlexPy database?");
|
||||||
|
$('#confirm-modal').modal();
|
||||||
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
|
$.ajax({
|
||||||
|
url: 'backup_db',
|
||||||
|
type: 'POST',
|
||||||
|
complete: function (xhr, status) {
|
||||||
|
result = $.parseJSON(xhr.responseText);
|
||||||
|
msg = result.message;
|
||||||
|
if (result.result == 'success') {
|
||||||
|
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
|
||||||
|
} else {
|
||||||
|
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#clear_cache").click(function () {
|
||||||
|
$("#confirm-message").text("Are you sure you want to clear the PlexPy cache?");
|
||||||
|
$('#confirm-modal').modal();
|
||||||
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
|
$.ajax({
|
||||||
|
url: 'delete_cache',
|
||||||
|
type: 'POST',
|
||||||
|
complete: function (xhr, status) {
|
||||||
|
result = $.parseJSON(xhr.responseText);
|
||||||
|
msg = result.message;
|
||||||
|
if (result.result == 'success') {
|
||||||
|
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
|
||||||
|
} else {
|
||||||
|
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#clear_logs").click(function () {
|
||||||
|
$("#confirm-message").text("Are you sure you want to clear the PlexPy logs?");
|
||||||
|
$('#confirm-modal').modal();
|
||||||
|
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||||
|
$.ajax({
|
||||||
|
url: 'delete_logs',
|
||||||
|
type: 'POST',
|
||||||
|
complete: function (xhr, status) {
|
||||||
|
result = $.parseJSON(xhr.responseText);
|
||||||
|
msg = result.message;
|
||||||
|
if (result.result == 'success') {
|
||||||
|
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000)
|
||||||
|
} else {
|
||||||
|
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if ($("#api_enabled").is(":checked")) {
|
if ($("#api_enabled").is(":checked")) {
|
||||||
$("#apioptions").show();
|
$("#apioptions").show();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2235,7 +2320,7 @@ $(document).ready(function() {
|
||||||
$("#pms-verify").html('<i class="fa fa-close"></i>');
|
$("#pms-verify").html('<i class="fa fa-close"></i>');
|
||||||
$('#pms-verify').fadeIn('fast');
|
$('#pms-verify').fadeIn('fast');
|
||||||
$("#pms-ip-group").addClass("has-error");
|
$("#pms-ip-group").addClass("has-error");
|
||||||
showMsg('<i class="fa fa-exclamation-circle"></i> Could not verify your server.', false, true, 2000, true)
|
showMsg('<i class="fa fa-exclamation-circle"></i> Could not verify your server.', false, true, 5000, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2243,7 +2328,7 @@ $(document).ready(function() {
|
||||||
$("#pms-verify").html('<i class="fa fa-close"></i>');
|
$("#pms-verify").html('<i class="fa fa-close"></i>');
|
||||||
$('#pms-verify').fadeIn('fast');
|
$('#pms-verify').fadeIn('fast');
|
||||||
$("#pms-ip-group").addClass("has-error");
|
$("#pms-ip-group").addClass("has-error");
|
||||||
showMsg('<i class="fa fa-exclamation-circle"></i> Could not verify your server.', false, true, 2000, true)
|
showMsg('<i class="fa fa-exclamation-circle"></i> Could not verify your server.', false, true, 5000, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2326,7 +2411,7 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$('#osxnotifyregister').click(function () {
|
$('#osxnotifyregister').click(function () {
|
||||||
var osx_notify_app = $("#osx_notify_reg").val();
|
var osx_notify_app = $("#osx_notify_reg").val();
|
||||||
$.get("/osxnotifyregister", { 'app': osx_notify_app }, function (data) { showMsg("<div class='msg'><span class='ui-icon ui-icon-check'></span>" + data + "</div>", false, true, 3000); });
|
$.get("/osxnotifyregister", { 'app': osx_notify_app }, function (data) { showMsg("<div class='msg'><span class='fa fa-check'></span>" + data + "</div>", false, true, 3000); });
|
||||||
})
|
})
|
||||||
|
|
||||||
pms_version = false;
|
pms_version = false;
|
||||||
|
|
|
@ -214,7 +214,7 @@ class Api(object):
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
logfile = os.path.join(plexpy.CONFIG.LOG_DIR, 'plexpy.log')
|
logfile = os.path.join(plexpy.CONFIG.LOG_DIR, logger.FILENAME)
|
||||||
templog = []
|
templog = []
|
||||||
start = int(kwargs.get('start', 0))
|
start = int(kwargs.get('start', 0))
|
||||||
end = int(kwargs.get('end', 0))
|
end = int(kwargs.get('end', 0))
|
||||||
|
|
|
@ -148,7 +148,7 @@ class API2:
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logfile = os.path.join(plexpy.CONFIG.LOG_DIR, 'plexpy.log')
|
logfile = os.path.join(plexpy.CONFIG.LOG_DIR, logger.FILENAME)
|
||||||
templog = []
|
templog = []
|
||||||
start = int(kwargs.get('start', 0))
|
start = int(kwargs.get('start', 0))
|
||||||
end = int(kwargs.get('end', 0))
|
end = int(kwargs.get('end', 0))
|
||||||
|
|
|
@ -86,6 +86,7 @@ _CONFIG_DEFINITIONS = {
|
||||||
'BUFFER_WAIT': (int, 'Monitoring', 900),
|
'BUFFER_WAIT': (int, 'Monitoring', 900),
|
||||||
'BACKUP_DIR': (str, 'General', ''),
|
'BACKUP_DIR': (str, 'General', ''),
|
||||||
'CACHE_DIR': (str, 'General', ''),
|
'CACHE_DIR': (str, 'General', ''),
|
||||||
|
'CACHE_IMAGES': (int, 'General', 1),
|
||||||
'CACHE_SIZEMB': (int, 'Advanced', 32),
|
'CACHE_SIZEMB': (int, 'Advanced', 32),
|
||||||
'CHECK_GITHUB': (int, 'General', 1),
|
'CHECK_GITHUB': (int, 'General', 1),
|
||||||
'CHECK_GITHUB_INTERVAL': (int, 'General', 360),
|
'CHECK_GITHUB_INTERVAL': (int, 'General', 360),
|
||||||
|
|
|
@ -1301,7 +1301,7 @@ class DataFactory(object):
|
||||||
logger.info(u"PlexPy DataFactory :: Clearing notification logs from database.")
|
logger.info(u"PlexPy DataFactory :: Clearing notification logs from database.")
|
||||||
monitor_db.action('DELETE FROM notify_log')
|
monitor_db.action('DELETE FROM notify_log')
|
||||||
monitor_db.action('VACUUM')
|
monitor_db.action('VACUUM')
|
||||||
return 'Cleared notification logs.'
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for delete_notification_log: %s." % e)
|
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for delete_notification_log: %s." % e)
|
||||||
return 'Unable to clear notification logs.'
|
return False
|
|
@ -1917,7 +1917,7 @@ class PmsConnect(object):
|
||||||
return result[0], result[1]
|
return result[0], result[1]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.error(u"PlexPy Pmsconnect :: Image proxy queries but no input received.")
|
logger.error(u"PlexPy Pmsconnect :: Image proxy queried but no input received.")
|
||||||
|
|
||||||
def get_search_results(self, query=''):
|
def get_search_results(self, query=''):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1948,17 +1948,9 @@ class WebInterface(object):
|
||||||
if 'search[regex]' in kwargs:
|
if 'search[regex]' in kwargs:
|
||||||
search_regex = kwargs.get('search[regex]', "")
|
search_regex = kwargs.get('search[regex]', "")
|
||||||
|
|
||||||
def oh_i_feel_so_dirty(s):
|
|
||||||
""" Really inefficient helper to only allow one pre tag,
|
|
||||||
atleast it better then regex..
|
|
||||||
"""
|
|
||||||
s = s.encode('utf-8').replace('<pre>', '').replace('</pre>', '')
|
|
||||||
s = '<pre>%s</pre>' % s
|
|
||||||
return s
|
|
||||||
|
|
||||||
filt = []
|
filt = []
|
||||||
fa = filt.append
|
fa = filt.append
|
||||||
with open(os.path.join(plexpy.CONFIG.LOG_DIR, 'plexpy.log')) as f:
|
with open(os.path.join(plexpy.CONFIG.LOG_DIR, logger.FILENAME)) as f:
|
||||||
for l in f.readlines():
|
for l in f.readlines():
|
||||||
try:
|
try:
|
||||||
temp_loglevel_and_time = l.split('- ')
|
temp_loglevel_and_time = l.split('- ')
|
||||||
|
@ -1966,11 +1958,11 @@ class WebInterface(object):
|
||||||
msg = l.split(' : ')[1].replace('\n', '')
|
msg = l.split(' : ')[1].replace('\n', '')
|
||||||
fa([temp_loglevel_and_time[0], loglvl, msg])
|
fa([temp_loglevel_and_time[0], loglvl, msg])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
# Add traceback message to previous msg..
|
# Add traceback message to previous msg.
|
||||||
tl = (len(filt) - 1)
|
tl = (len(filt) - 1)
|
||||||
filt[tl][2] += ' ' + l
|
n = len(l) - len(l.lstrip(' '))
|
||||||
# Inject the pre tag since we only want it on tracebacks
|
l = ' ' * (2*n) + l[n:]
|
||||||
filt[tl][2] = oh_i_feel_so_dirty(filt[tl][2])
|
filt[tl][2] += '<br>' + l
|
||||||
continue
|
continue
|
||||||
|
|
||||||
filtered = []
|
filtered = []
|
||||||
|
@ -2112,20 +2104,27 @@ class WebInterface(object):
|
||||||
"""
|
"""
|
||||||
data_factory = datafactory.DataFactory()
|
data_factory = datafactory.DataFactory()
|
||||||
result = data_factory.delete_notification_log()
|
result = data_factory.delete_notification_log()
|
||||||
result = result if result else 'no data received'
|
res = 'success' if result else 'error'
|
||||||
|
msg = 'Cleared notification logs.' if result else 'Failed to clear notification logs.'
|
||||||
|
|
||||||
return {'message': result}
|
return {'result': res, 'message': msg}
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
|
@cherrypy.tools.json_out()
|
||||||
@requireAuth(member_of("admin"))
|
@requireAuth(member_of("admin"))
|
||||||
def clearLogs(self):
|
def delete_logs(self):
|
||||||
|
log_file = logger.FILENAME
|
||||||
try:
|
try:
|
||||||
open(os.path.join(plexpy.CONFIG.LOG_DIR, 'plexpy.log'), 'w').close()
|
open(os.path.join(plexpy.CONFIG.LOG_DIR, log_file), 'w').close()
|
||||||
|
result = 'success'
|
||||||
|
msg = 'Cleared the %s file.' % log_file
|
||||||
|
logger.info(msg)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(u'Failed to delete plexpy.log %s' % e)
|
result = 'error'
|
||||||
|
msg = 'Failed to clear the %s file.' % log_file
|
||||||
|
logger.exception(u'Failed to clear the %s file: %s.' % (log_file, e))
|
||||||
|
|
||||||
logger.info(u'plexpy.log cleared')
|
return {'result': result, 'message': msg}
|
||||||
raise cherrypy.HTTPRedirect("logs")
|
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@requireAuth(member_of("admin"))
|
@requireAuth(member_of("admin"))
|
||||||
|
@ -2151,7 +2150,7 @@ class WebInterface(object):
|
||||||
@requireAuth(member_of("admin"))
|
@requireAuth(member_of("admin"))
|
||||||
def logFile(self):
|
def logFile(self):
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(plexpy.CONFIG.LOG_DIR, 'plexpy.log'), 'r') as f:
|
with open(os.path.join(plexpy.CONFIG.LOG_DIR, logger.FILENAME), 'r') as f:
|
||||||
return '<pre>%s</pre>' % f.read()
|
return '<pre>%s</pre>' % f.read()
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
return "Log file not found."
|
return "Log file not found."
|
||||||
|
@ -2282,7 +2281,8 @@ class WebInterface(object):
|
||||||
"buffer_wait": plexpy.CONFIG.BUFFER_WAIT,
|
"buffer_wait": plexpy.CONFIG.BUFFER_WAIT,
|
||||||
"group_history_tables": checked(plexpy.CONFIG.GROUP_HISTORY_TABLES),
|
"group_history_tables": checked(plexpy.CONFIG.GROUP_HISTORY_TABLES),
|
||||||
"git_token": plexpy.CONFIG.GIT_TOKEN,
|
"git_token": plexpy.CONFIG.GIT_TOKEN,
|
||||||
"imgur_client_id": plexpy.CONFIG.IMGUR_CLIENT_ID
|
"imgur_client_id": plexpy.CONFIG.IMGUR_CLIENT_ID,
|
||||||
|
"cache_images": checked(plexpy.CONFIG.CACHE_IMAGES)
|
||||||
}
|
}
|
||||||
|
|
||||||
return serve_template(templatename="settings.html", title="Settings", config=config)
|
return serve_template(templatename="settings.html", title="Settings", config=config)
|
||||||
|
@ -2304,7 +2304,7 @@ class WebInterface(object):
|
||||||
"ip_logging_enable", "movie_logging_enable", "tv_logging_enable", "music_logging_enable",
|
"ip_logging_enable", "movie_logging_enable", "tv_logging_enable", "music_logging_enable",
|
||||||
"notify_consecutive", "notify_upload_posters", "notify_recently_added", "notify_recently_added_grandparent",
|
"notify_consecutive", "notify_upload_posters", "notify_recently_added", "notify_recently_added_grandparent",
|
||||||
"monitor_pms_updates", "monitor_remote_access", "get_file_sizes", "log_blacklist", "http_hash_password",
|
"monitor_pms_updates", "monitor_remote_access", "get_file_sizes", "log_blacklist", "http_hash_password",
|
||||||
"allow_guest_access"
|
"allow_guest_access", "cache_images"
|
||||||
]
|
]
|
||||||
for checked_config in checked_configs:
|
for checked_config in checked_configs:
|
||||||
if checked_config not in kwargs:
|
if checked_config not in kwargs:
|
||||||
|
@ -2443,9 +2443,9 @@ class WebInterface(object):
|
||||||
result = database.make_backup()
|
result = database.make_backup()
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
return {'message': 'Database backup successful.'}
|
return {'result': 'success', 'message': 'Database backup successful.'}
|
||||||
else:
|
else:
|
||||||
return {'message': 'Database backup failed.'}
|
return {'result': 'error', 'message': 'Database backup failed.'}
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@requireAuth(member_of("admin"))
|
@requireAuth(member_of("admin"))
|
||||||
|
@ -2834,15 +2834,15 @@ class WebInterface(object):
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@requireAuth()
|
@requireAuth()
|
||||||
def pms_image_proxy(self, img='', ratingkey=None, width='0', height='0', fallback=None, **kwargs):
|
def pms_image_proxy(self, img='', rating_key=None, width='0', height='0', fallback=None, **kwargs):
|
||||||
""" Grabs the images from pms and saved them to disk """
|
""" Gets an image from the PMS and saves it to the image cache directory. """
|
||||||
|
|
||||||
if not img and not ratingkey:
|
if not img and not rating_key:
|
||||||
logger.debug('No image input received')
|
logger.error('No image input received.')
|
||||||
return
|
return
|
||||||
|
|
||||||
if ratingkey and not img:
|
if rating_key and not img:
|
||||||
img = '/library/metadata/%s/thumb/1337' % ratingkey
|
img = '/library/metadata/%s/thumb/1337' % rating_key
|
||||||
|
|
||||||
img_string = img.rsplit('/', 1)[0]
|
img_string = img.rsplit('/', 1)[0]
|
||||||
img_string += '%s%s' % (width, height)
|
img_string += '%s%s' % (width, height)
|
||||||
|
@ -2867,7 +2867,7 @@ class WebInterface(object):
|
||||||
|
|
||||||
if result and result[0]:
|
if result and result[0]:
|
||||||
cherrypy.response.headers['Content-type'] = result[1]
|
cherrypy.response.headers['Content-type'] = result[1]
|
||||||
if 'indexes' not in img:
|
if plexpy.CONFIG.CACHE_IMAGES and 'indexes' not in img:
|
||||||
with open(ffp, 'wb') as f:
|
with open(ffp, 'wb') as f:
|
||||||
f.write(result[0])
|
f.write(result[0])
|
||||||
|
|
||||||
|
@ -2876,7 +2876,7 @@ class WebInterface(object):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug('Failed to get image %s file %s falling back to %s' % (img, fp, e))
|
logger.exception(u'Failed to get image %s, falling back to %s.' % (img, fallback))
|
||||||
fbi = None
|
fbi = None
|
||||||
if fallback == 'poster':
|
if fallback == 'poster':
|
||||||
fbi = common.DEFAULT_POSTER_THUMB
|
fbi = common.DEFAULT_POSTER_THUMB
|
||||||
|
@ -2894,38 +2894,49 @@ class WebInterface(object):
|
||||||
@requireAuth(member_of("admin"))
|
@requireAuth(member_of("admin"))
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def download_log(self):
|
def download_log(self):
|
||||||
|
""" Download the PlexPy log file. """
|
||||||
|
log_file = logger.FILENAME
|
||||||
try:
|
try:
|
||||||
logger.logger.flush()
|
logger.logger.flush()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return serve_download(os.path.join(plexpy.CONFIG.LOG_DIR, 'plexpy.log'), name='plexpy.log')
|
return serve_download(os.path.join(plexpy.CONFIG.LOG_DIR, log_file), name=log_file)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@cherrypy.tools.json_out()
|
@cherrypy.tools.json_out()
|
||||||
@requireAuth(member_of("admin"))
|
@requireAuth(member_of("admin"))
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def delete_image_cache(self):
|
def delete_image_cache(self):
|
||||||
""" Deletes the image cache dir and recreates it """
|
""" Delete and recreate the image cache directory. """
|
||||||
cache_dir = os.path.join(plexpy.CONFIG.CACHE_DIR, 'images')
|
return self.delete_cache(folder='images')
|
||||||
|
|
||||||
|
@cherrypy.expose
|
||||||
|
@cherrypy.tools.json_out()
|
||||||
|
@requireAuth(member_of("admin"))
|
||||||
|
@addtoapi()
|
||||||
|
def delete_cache(self, folder=''):
|
||||||
|
""" Delete and recreate the cache directory. """
|
||||||
|
cache_dir = os.path.join(plexpy.CONFIG.CACHE_DIR, folder)
|
||||||
result = 'success'
|
result = 'success'
|
||||||
msg = 'Deleted your cache images'
|
msg = 'Cleared the %scache.' % (folder + ' ' if folder else '')
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(cache_dir, ignore_errors=True)
|
shutil.rmtree(cache_dir, ignore_errors=True)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
result = 'error'
|
result = 'error'
|
||||||
msg = 'Failed to delete %s %s' % (cache_dir, e)
|
msg = 'Failed to delete %s.' % cache_dir
|
||||||
logger.exception(msg)
|
logger.exception(u'Failed to delete %s: %s.' % (cache_dir, e))
|
||||||
return
|
return {'result': result, 'message': msg}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.makedirs(cache_dir)
|
os.makedirs(cache_dir)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
result = 'error'
|
result = 'error'
|
||||||
msg = 'Failed to make %s %s' % (cache_dir, e)
|
msg = 'Failed to make %s.' % cache_dir
|
||||||
logger.exception(msg)
|
logger.exception(u'Failed to create %s: %s.' % (cache_dir, e))
|
||||||
return
|
return {'result': result, 'message': msg}
|
||||||
|
|
||||||
|
logger.info(msg)
|
||||||
return {'result': result, 'message': msg}
|
return {'result': result, 'message': msg}
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue