Skip to content

Commit

Permalink
Allow loading custom css from USER_DIR/css (#235)
Browse files Browse the repository at this point in the history
* Allow loading custom css from USER_DIR/css
* DOC + change name of config option
* ADD test

Co-authored-by: Uzay-G <uzgirit@gmail.com>
  • Loading branch information
edditler and Uzay-G committed May 22, 2021
1 parent 58c22f6 commit 5154ad1
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 7 deletions.
3 changes: 3 additions & 0 deletions archivy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ def __init__(self):

self.PANDOC_HIGHLIGHT_THEME = "pygments"
self.SCRAPING_CONF = {"save_images": False}

self.THEME_CONF = {"use_custom_css": False, "custom_css_file": ""}

self.SEARCH_CONF = {
"enabled": 0,
"url": "http://localhost:9200",
Expand Down
5 changes: 3 additions & 2 deletions archivy/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,8 @@ def save_image(image: FileStorage):

def image_exists(filename: str):
sanitized = secure_filename(filename)
image_path = Path(current_app.config["USER_DIR"]) / "images" / sanitized
if image_path.exists():
images_dir = Path(current_app.config["USER_DIR"]) / "images"
image_path = images_dir / sanitized
if image_path.exists() and is_relative_to(image_path, images_dir):
return str(image_path)
return 0
20 changes: 19 additions & 1 deletion archivy/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@
from os.path import sep

import frontmatter
from flask import render_template, flash, redirect, request, url_for, send_file
from flask import (
render_template,
flash,
redirect,
request,
url_for,
send_file,
send_from_directory,
)
from flask_login import login_user, current_user, logout_user
from tinydb import Query
from werkzeug.security import check_password_hash, generate_password_hash
Expand Down Expand Up @@ -273,3 +281,13 @@ def serve_image(filename):
return "Image not found", 404
else:
return "Invalid file request", 413


@app.route("/static/custom.css")
def custom_css():
if not app.config["THEME_CONF"]["use_custom_css"]:
return ""
return send_from_directory(
Path(app.config["USER_DIR"]) / "css",
app.config["THEME_CONF"]["custom_css_file"],
)
8 changes: 6 additions & 2 deletions archivy/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
{% if config.THEME_CONF['use_custom_css'] %}
<link rel="stylesheet" href="/static/custom.css">
{% endif %}

<link rel="icon" href="{{ url_for('static', filename='archivy.svg')}}" type="image/svg+xml">
<style>

Expand All @@ -25,7 +29,7 @@
<svg class="octicon open" style="display: none;" width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M12.78 6.22a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06 0L3.22 7.28a.75.75 0 011.06-1.06L8 9.94l3.72-3.72a.75.75 0 011.06 0z"></path></svg>
</button>
<a href="/?path={{ SEP.join(path) + SEP }}"><h3>
{{ dir.name }}
{{ dir.name }}
</h3></a>
</div>
{% if dir.child_files | length %}
Expand Down Expand Up @@ -114,7 +118,7 @@ <h3>Bookmarklet</h3>
<script>
const SCRIPT_ROOT = {{ request.script_root|tojson|safe }} + "/api";
let max_folder_id = document.querySelectorAll(".folder-cont").length;
function createInteractive(btn, id)
function createInteractive(btn, id)
{
// expand
let parentDiv = btn.parentNode;
Expand Down
17 changes: 17 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ SCRAPING_CONF:
|-------------------------|-----------------------------|---------------------------------------|
| `save_images` | False | If true, whenever you save a bookmark, every linked image will also be downloaded locally. |

### Theming

Configure the way your Archivy install looks.

These configuration options are children of the `THEME_CONF` object, like this:

```yaml
THEME_CONF:
use_custom_css:
custom_css_file:
```

| Variable | Default | Description |
|------|-------|----|
| `use_custom_css` | false | Whether or not to load custom css from `custom_css_file` |
| `custom_css_file` | "" | Name of file to load in the `css/` subdirectory of your user directory (the one with your data or hooks). Create `css/` if it doesn't exist. |


### Search

Expand Down
22 changes: 20 additions & 2 deletions tests/functional/test_routes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from os import pathconf
import os

from flask.testing import FlaskClient
from flask import request
Expand All @@ -15,6 +15,24 @@ def test_get_index(test_app, client: FlaskClient):
assert response.status_code == 200


def test_get_custom_css(test_app, client: FlaskClient):
test_app.config["THEME_CONF"]["use_custom_css"] = True
css_file = "custom.css"
css_contents = """
body {
color: red
}
"""

os.mkdir(f"{test_app.config['USER_DIR']}/css/")
with open(f"{test_app.config['USER_DIR']}/css/{css_file}", "w") as f:
f.write(css_contents)
test_app.config["THEME_CONF"]["custom_css_file"] = css_file
resp = client.get("/static/custom.css")
assert css_contents.encode("utf-8") in resp.data
test_app.config["THEME_CONF"]["use_custom_css"] = False


def test_get_new_bookmark(test_app, client: FlaskClient):
response = client.get("/bookmarks/new")
assert response.status_code == 200
Expand Down Expand Up @@ -253,7 +271,7 @@ def test_bookmark_with_long_title_gets_truncated(test_app, client, mocked_respon
long_title = "a" * 300
# check that our mock title is indeed longer than the limit
# and would cause an error, without our truncating
assert pathconf("/", "PC_NAME_MAX") < len(long_title)
assert os.pathconf("/", "PC_NAME_MAX") < len(long_title)
mocked_responses.add(GET, "https://example.com", f"<title>{long_title}</title>")
bookmark_data = {
"url": "https://example.com",
Expand Down

0 comments on commit 5154ad1

Please sign in to comment.