Skip to content

Commit

Permalink
Merge pull request #35 from pganssle/adjust_resources
Browse files Browse the repository at this point in the history
By default pull default resources from the package data
  • Loading branch information
pganssle authored Nov 27, 2022
2 parents 9b8d586 + 55af972 commit c2ba9a2
Show file tree
Hide file tree
Showing 12 changed files with 302 additions and 124 deletions.
8 changes: 8 additions & 0 deletions src/audio_feeder/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from . import cache_utils
from . import database_handler as dh
from . import resources
from .config import read_from_config
from .pages import root


Expand Down Expand Up @@ -57,6 +59,12 @@ def create_app(load_db=True, populate_qr_cache=True, progressbar=False, block=Fa
for warning in warnings:
log.warning(*warning)

log.info("Refreshing fonts on disk")
static_media_path = read_from_config("static_media_path")
resources.update_resource(
"audio_feeder.data.site.fonts", static_media_path / "fonts"
)

log.info("Creating Flask application")
app = Flask(__name__)
app.register_blueprint(root)
Expand Down
56 changes: 5 additions & 51 deletions src/audio_feeder/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,34 +137,10 @@ def install(config_dir, config_name):
Installs the feeder configuration and populates the initial file structures
with the default package data.
"""
import importlib
import os
import warnings
from importlib import resources

from . import config

def _copy_resource(
resource: importlib.abc.Traversable, target_dir: pathlib.Path
) -> None:
if resource.is_file():
if not target_dir.exists():
target_dir.mkdir(parents=True)

target_loc = target_dir / resource.name
target_loc.write_bytes(resource.read_bytes())
else:
for child in resource.iterdir():
if (
child.name.endswith(".py")
or child.name.endswith(".pyc")
or child.name == "__pycache__"
):
continue
if child.is_dir():
_copy_resource(child, target_dir / child.name)
else:
_copy_resource(child, target_dir)
from . import config, resources

# Assign a configuration directory
if config_dir is None:
Expand Down Expand Up @@ -195,21 +171,13 @@ def _copy_resource(
config_obj.to_file(config_loc)

# Create the directories that need to exist, if they don't already
make_dir_entries = (
"templates_base_loc",
"entry_templates_loc",
"pages_templates_loc",
"rss_templates_loc",
"rss_entry_templates_loc",
"static_media_path",
) # Absolute paths
make_dir_entries = ("static_media_path",) # Absolute paths

make_dir_directories = [config_obj[x] for x in make_dir_entries]
static_paths = [
os.path.join(config_obj.static_media_path, config_obj[x])
for x in (
"site_images_loc",
"css_loc",
"cover_cache_path",
"qr_cache_path",
"media_cache_path",
Expand Down Expand Up @@ -242,23 +210,9 @@ def _copy_resource(
raise

# Copy all package data as appropriate
site = resources.files("audio_feeder.data.site")
templates = resources.files("audio_feeder.data.templates")

_copy_resource(site, pathlib.Path(config_obj["static_media_path"]))

# Directories
pkg_dir_map = {
"entry_templates_loc": "entry_types",
"pages_templates_loc": "pages",
"rss_templates_loc": "rss",
"rss_entry_templates_loc": "entry_types",
}

pkg_dir_map = {config_obj[k]: v for k, v in pkg_dir_map.items()}

for target_loc, resource_loc in pkg_dir_map.items():
_copy_resource(templates / resource_loc, pathlib.Path(target_loc))
resources.update_resource(
"audio_feeder.data.site", pathlib.Path(config_obj["static_media_path"])
)


@cli.group()
Expand Down
6 changes: 5 additions & 1 deletion src/audio_feeder/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ class Configuration:

static_media_url: str = TemplateStr("{{URL}}/static")

# If true, this will not inject the default CSS files.
disable_default_css: bool = False

# Relative to static
media_path: str = "media"
site_images_loc: str = "images/site-images"
Expand All @@ -132,7 +135,8 @@ class Configuration:
rss_feed_urls: str = "rss/{id}.xml"

# Relative to others
main_css_files: typing.Sequence[str] = ("main.css", "fontawesome-subset.css") # CSS
main_css_files: typing.Sequence[str] = () # Deprecated, no longer used
extra_css_files: typing.Sequence[str] = ()
thumb_max: typing.Tuple[int, int] = (200, 400) # width, height
base_protocol: str = "http"
base_host: str = "localhost"
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ div.topnav-icons {

.modal-window {
display: inline-block;
position: absolute;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
Expand Down
44 changes: 27 additions & 17 deletions src/audio_feeder/page_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from jinja2 import Template

from . import resources
from .config import read_from_config
from .html_utils import TagStripper
from .media_renderer import RenderModes
Expand Down Expand Up @@ -132,27 +133,36 @@ def truncation_point(self, description):

return orig_pos

def _get_template(self, loc, name, resource_default):
template_loc = os.path.join(loc, name)

if not os.path.exists(template_loc):
# Load from resource
return Template(resources.get_text_resource(resource_default, name))
else:
with open(template_loc, "rt") as f:
return Template(f.read())

def load_type(self, type_name):
type_cache = getattr(self, "_load_type_cache", {})
if type_name not in type_cache:
et_loc = self.entry_templates_loc
if not os.path.exists(et_loc):
raise IOError("Entry templates directory does not exist.")

type_dir = os.path.join(et_loc, type_name)
if not os.path.exists(type_dir):
raise IOError(f"Type directory templates do not exist: {type_dir}")

type_dir = self.entry_templates_loc / type_name
type_dict = {}
for fname in os.listdir(type_dir):
fpath = os.path.join(type_dir, fname)
if not (os.path.isfile(fpath) and fpath.endswith(".tpl")):
continue

tname = os.path.splitext(fname)[0]

with open(fpath, "r") as f:
type_dict[tname] = Template(f.read())
if type_dir.exists():
for fpath in type_dir.glob("*.tpl"):
type_dict[fpath.stem] = Template(fpath.read_text())
else:
resource = f"audio_feeder.data.templates.entry_types.{type_name}"
for child in resources.get_children(resource):
if child.is_dir() or not child.name.endswith(".tpl"):
continue
fname = os.path.splitext(child.name)[0]
type_dict[fname] = Template(child.read_text())

if not type_dict:
raise FileNotFounderror(
f"No entry templates found for type {type_name}"
)

type_cache[type_name] = type_dict

Expand Down
69 changes: 45 additions & 24 deletions src/audio_feeder/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from audio_feeder import media_renderer as mr
from audio_feeder import object_handler as oh
from audio_feeder import page_generator as pg
from audio_feeder import resources
from audio_feeder import rss_feeds as rf
from audio_feeder.config import read_from_config
from audio_feeder.file_location import FileLocation
Expand Down Expand Up @@ -511,32 +512,37 @@ def get_sortable_args(args):
return args


def get_list_template():
template = getattr(get_list_template, "_template", None)
if template is None:
template = _get_template("pages_templates_loc", "list.tpl")
get_list_template._template = template
@functools.cache
def get_list_template() -> Template:
template = _get_template(
"pages_templates_loc",
"list.tpl",
resource_default="audio_feeder.data.templates.pages",
)

return template


def get_feed_template():
template = getattr(get_feed_template, "_template", None)
if template is None:
template = _get_template("rss_templates_loc", "rss_feed.tpl")
get_feed_template._template = template

return get_feed_template._template

@functools.cache
def get_feed_template() -> Template:
return _get_template(
"rss_templates_loc",
"rss_feed.tpl",
resource_default="audio_feeder.data.templates.rss",
)

def _get_template(loc_entry, template_name):
template_loc = read_from_config(loc_entry)
template_loc = os.path.join(template_loc, template_name)

with open(template_loc, "r") as f:
template = Template(f.read())
def _get_template(
loc_entry: str, template_name: str, resource_default: typing.Optional[str] = None
) -> Template:
template_loc = read_from_config(loc_entry) / template_name

return template
if template_loc.exists():
return Template(template_loc.read_text())
elif resource_default is not None:
return Template(resources.get_text_resource(resource_default, template_name))
else:
raise FileNotFoundError(f"Could not find template: {template_loc}")


def get_renderer(rss_renderer=False):
Expand All @@ -555,13 +561,28 @@ def get_renderer(rss_renderer=False):
return renderer[rss_renderer]


def get_css_links():
@functools.cache
def get_css_links() -> typing.Sequence[str]:
resolver = get_resolver()
css_loc = read_from_config("css_loc")
css_locs = [
os.path.join(css_loc, css_file)
for css_file in read_from_config("main_css_files")
]
css_locs: typing.MutableSequence[str] = []
if not read_from_config("disable_default_css"):
static_path = read_from_config("static_media_path")
default_loc = resolver.resolve_static(css_loc)
default_path = default_loc.path
assert default_path is not None
resources.update_resource("audio_feeder.data.css", default_path)
css_locs.extend(
os.fspath(fpath.relative_to(static_path))
for fpath in default_path.rglob("*.css")
)

css_locs.extend(
(
os.path.join(css_loc, css_file)
for css_file in read_from_config("extra_css_files")
)
)

css_paths = [resolver.resolve_static(css_relpath).url for css_relpath in css_locs]

Expand Down
Loading

0 comments on commit c2ba9a2

Please sign in to comment.