Skip to content
This repository has been archived by the owner on Oct 13, 2024. It is now read-only.

Commit

Permalink
fix(ui): improve speed of dashboard by caching data (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
ReenigneArcher authored Nov 17, 2023
1 parent 4f9ffa3 commit dfda394
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 26 deletions.
1 change: 1 addition & 0 deletions Contents/Code/default_prefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
bool_update_collection_metadata_plex_movie='False',
bool_update_collection_metadata_legacy='True',
int_update_themes_interval='60',
int_update_database_cache_interval='60',
int_plexapi_plexapi_timeout='180',
int_plexapi_upload_retries_max='3',
int_plexapi_upload_threads='3',
Expand Down
5 changes: 5 additions & 0 deletions Contents/Code/scheduled_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# local imports
from constants import plugin_identifier
from plex_api_helper import scheduled_update
from webapp import cache_data

# setup logging for schedule
Log.Info('Adding schedule log handlers to plex plugin logger')
Expand Down Expand Up @@ -112,5 +113,9 @@ def setup_scheduling():
job_func=run_threaded,
target=scheduled_update
)
schedule.every(max(15, int(Prefs['int_update_database_cache_interval']))).minutes.do(
job_func=run_threaded,
target=cache_data
)

run_threaded(target=schedule_loop, daemon=True) # start the schedule loop in a thread
77 changes: 52 additions & 25 deletions Contents/Code/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import json
import logging
import os
from threading import Thread
from threading import Lock, Thread

# plex debugging
try:
Expand All @@ -16,6 +16,7 @@
pass
else: # the code is running outside of Plex
from plexhints.constant_kit import CACHE_1DAY # constant kit
from plexhints.core_kit import Core # core kit
from plexhints.log_kit import Log # log kit
from plexhints.parse_kit import JSON # parse kit
from plexhints.prefs_kit import Prefs # prefs kit
Expand All @@ -28,7 +29,7 @@
from werkzeug.utils import secure_filename

# local imports
from constants import contributes_to, issue_urls, plugin_directory, plugin_identifier
from constants import contributes_to, issue_urls, plugin_directory, plugin_identifier, themerr_data_directory
import general_helper
from plex_api_helper import get_database_info, setup_plexapi
import themerr_db_helper
Expand Down Expand Up @@ -100,6 +101,10 @@
'svg': 'image/svg+xml',
}

# where the database cache is stored
database_cache_file = os.path.join(themerr_data_directory, 'database_cache.json')
database_cache_lock = Lock()


@babel.localeselector
def get_locale():
Expand Down Expand Up @@ -182,30 +187,14 @@ def stop_server():
return False


@app.route('/', methods=["GET"])
@app.route('/home', methods=["GET"])
def home():
# type: () -> render_template
def cache_data():
# type: () -> None
"""
Serve the webapp home page.
This page serves the Themerr completion report for supported Plex libraries.
Returns
-------
render_template
The rendered page.
Cache data for use in the Web UI dashboard.
Notes
-----
The following routes trigger this function.
- `/`
- `/home`
Examples
--------
>>> home()
Because there are many http requests that must be made to gather the data for the dashboard, it can be
time-consuming to populate; therefore, this is performed within this caching function, which runs on a schedule.
This function will create a json file that can be loaded by other functions.
"""
# get all Plex items from supported metadata agents
plex_server = setup_plexapi()
Expand Down Expand Up @@ -368,7 +357,45 @@ def home():
year=year,
))

return render_template('home.html', title='Home', items=items)
with database_cache_lock:
Core.storage.save(filename=database_cache_file, data=json.dumps(items), binary=False)


@app.route('/', methods=["GET"])
@app.route('/home', methods=["GET"])
def home():
# type: () -> render_template
"""
Serve the webapp home page.
This page serves the Themerr completion report for supported Plex libraries.
Returns
-------
render_template
The rendered page.
Notes
-----
The following routes trigger this function.
- `/`
- `/home`
Examples
--------
>>> home()
"""
items = []
try:
items = json.loads(Core.storage.load(filename=database_cache_file, binary=False))
except IOError:
pass

if items:
return render_template('home.html', title='Home', items=items)
else:
return render_template('home_db_not_cached.html', title='Home')


@app.route("/<path:img>", methods=["GET"])
Expand Down
7 changes: 7 additions & 0 deletions Contents/DefaultPrefs.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@
"default": "60",
"secure": "false"
},
{
"id": "int_update_database_cache_interval",
"type": "text",
"label": "Interval for database cache update task, in minutes (min: 15)",
"default": "60",
"secure": "false"
},
{
"id": "int_plexapi_plexapi_timeout",
"type": "text",
Expand Down
16 changes: 16 additions & 0 deletions Contents/Resources/web/templates/home_db_not_cached.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends 'base.html' %}
{% block modals %}
{% endblock modals %}

{% block content %}
<div class="container px-auto my-5">
<div class="col-lg-12 mx-auto" id="themerr-container" style="min-width: 335px">

<h2 class="text-center text-white">{{ _('Database is being cached, please try again soon.') }}</h2>

</div>
</div>
{% endblock content %}

{% block scripts %}
{% endblock scripts %}
14 changes: 13 additions & 1 deletion docs/source/about/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ Default
Minimum
``15``

Interval for database cache update task
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Description
The interval (in minutes) to run the database cache update task. This data is used to display the Web UI dashboard.

Default
``60``

Minimum
``15``

PlexAPI Timeout
^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -234,7 +246,7 @@ YouTube Cookies
^^^^^^^^^^^^^^^^

Description
The cookies to use for the requests to YouTube. Should be in Chromium JSON export format.
The cookies to use for the requests to YouTube. Should be in Chromium JSON export format.
`Example exporter <https://chrome.google.com/webstore/detail/get-cookiestxt/bgaddhkoddajcdgocldbbfleckgcbcid>`__.

Default
Expand Down
18 changes: 18 additions & 0 deletions tests/unit/test_webapp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-

# standard imports
import json
import os

# local imports
from Code import webapp


def test_cache_data():
webapp.cache_data()
assert os.path.isfile(webapp.database_cache_file), "Database cache file not found"

with open(webapp.database_cache_file, 'r') as f:
data = json.load(f)

assert data, "Database cache file is empty"

0 comments on commit dfda394

Please sign in to comment.