Skip to content

Commit

Permalink
Improve bookmarklet and backend to upload bookmarks with direct html (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzay-G committed Feb 13, 2022
1 parent 440ed1a commit fa389e7
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 8 deletions.
13 changes: 8 additions & 5 deletions archivy/models.py
Expand Up @@ -89,7 +89,7 @@ class DataObj:
fullpath: Optional[str] = attrib(validator=optional(instance_of(str)), default=None)
error: Optional[str] = attrib(validator=optional(instance_of(str)), default=None)

def process_bookmark_url(self):
def process_bookmark_url(self, raw_html=None):
"""Process url to get content for bookmark"""
if self.type not in ("bookmark", "pocket_bookmark") or not validators.url(
self.url
Expand All @@ -107,17 +107,20 @@ def process_bookmark_url(self):
return

try:
url_request = requests.get(
self.url,
headers={"User-agent": f"Archivy/v{require('archivy')[0].version}"},
page_html = (
raw_html
or requests.get(
self.url,
headers={"User-agent": f"Archivy/v{require('archivy')[0].version}"},
).text
)
except Exception:
self.error = f"Could not retrieve {self.url}\n"
self.wipe()
return

try:
document = Document(url_request.text)
document = Document(page_html)
self.title = document.short_title() or self.url
parsed_html = BeautifulSoup(document.summary(), features="html.parser")
except Exception:
Expand Down
23 changes: 22 additions & 1 deletion archivy/routes.py
Expand Up @@ -18,7 +18,7 @@
from werkzeug.security import check_password_hash, generate_password_hash

from archivy.models import DataObj, User
from archivy import data, app, forms
from archivy import data, app, forms, csrf
from archivy.helpers import get_db, write_config
from archivy.tags import get_all_tags
from archivy.search import search, search_frontmatter_tags
Expand Down Expand Up @@ -396,3 +396,24 @@ def update_config_value(key, val, dictionary):
return render_template(
"config.html", conf=form, default=default, title="Edit Config"
)


@csrf.exempt # exempt from CSRF to be able to submit info directly from bookmarklet
@app.route("/save_from_bookmarklet", methods=["POST"])
def save_raw_url():
"""
Used in the bookmarklet - Saves a URL by taking its raw HTML.
POST parameters:
- html
- url
"""
html = request.form.get("html")
if not html:
return "No HTML provided", 400
bookmark = DataObj(url=request.form.get("url"), type="bookmark")
bookmark.process_bookmark_url(html)
if bookmark.insert():
return redirect(f"/dataobj/{bookmark.id}")
else:
return "Could not save bookmark", 500
14 changes: 13 additions & 1 deletion archivy/templates/bookmarklet.html
Expand Up @@ -7,6 +7,18 @@ <h2>Bookmarklet</h2>

All you need to do is drage the link below to your browser toolbar. Then, when you find an interesting link, just click the button on your toolbar named "Add to archivy".

<h3><a href="javascript:window.location = `{{ request.host_url | safe }}bookmarks/new?url=${window.location}`;">Add to {{ config.SITE_TITLE }}</a></h3>
<h3><a href="javascript: (async function() {
document.body.insertAdjacentHTML('beforeend', `
<form style='display: none' method='post' target='_blank' id='archivy_bookmarklet' action='{{ request.host_url | safe }}/save_from_bookmarklet'>
<input type='hidden' name='url'>
<input type='text' name='html'>
</form>
`);
const form = document.getElementById('archivy_bookmarklet');
form.querySelector('input[name=url]').value = window.location.href;
form.querySelector('input[name=html]').value = document.documentElement.outerHTML;
form.submit();})();">
Add to {{ config.SITE_TITLE }}
</a></h3>

{% endblock %}
15 changes: 15 additions & 0 deletions tests/functional/test_routes.py
Expand Up @@ -398,3 +398,18 @@ def test_getting_matches_for_specific_tag(test_app, client, bookmark_fixture):
assert resp.status_code == 200
assert bookmark_fixture.title in str(resp.data)
assert str(bookmark_fixture.id) in str(resp.data)


def test_bookmarklet_upload(test_app, client):
title = "bookmarklet bookmark"
resp = client.post(
"/save_from_bookmarklet",
data={
"url": "https://example.com",
"html": f"<html><title>{title}</title><html>",
},
follow_redirects=True,
)
assert resp.status_code == 200
assert title in str(resp.data)
assert "/dataobj/" in request.path
2 changes: 1 addition & 1 deletion tests/integration/test_api.py
Expand Up @@ -5,7 +5,7 @@
from flask import Flask
from flask.testing import FlaskClient
from tinydb import Query
from archivy.data import create_dir, get_items, create_dir
from archivy.data import create_dir, get_items, create_dir, get_item
from archivy.models import DataObj
from archivy.helpers import get_db

Expand Down

0 comments on commit fa389e7

Please sign in to comment.