1
0
mirror of https://github.com/aquatix/digimarks.git synced 2025-12-07 00:15:10 +01:00

4 Commits

7 changed files with 70 additions and 153 deletions

View File

@@ -39,8 +39,6 @@ Usage / example configuration
Copy ``settings.py`` from example_config to the parent directory and Copy ``settings.py`` from example_config to the parent directory and
configure to your needs (*at the least* change the value of `SYSTEMKEY`). configure to your needs (*at the least* change the value of `SYSTEMKEY`).
Do not forget to fill in the `MASHAPE_API_KEY` value, which you [can request on the RapidAPI website](https://rapidapi.com/realfavicongenerator/api/realfavicongenerator).
Run digimarks as a service under nginx or apache and call the appropriate Run digimarks as a service under nginx or apache and call the appropriate
url's when wanted. url's when wanted.

View File

@@ -10,11 +10,10 @@ import sys
import bs4 import bs4
import requests import requests
from dateutil import tz from flask import (Flask, abort, jsonify, redirect, render_template, request,
from feedgen.feed import FeedGenerator url_for)
from flask import (Flask, abort, jsonify, make_response, redirect,
render_template, request, url_for)
from peewee import * # noqa from peewee import * # noqa
from werkzeug.contrib.atom import AtomFeed
try: try:
# Python 3 # Python 3
@@ -358,14 +357,14 @@ class Bookmark(BaseModel):
def _set_favicon_with_realfavicongenerator(self, domain): def _set_favicon_with_realfavicongenerator(self, domain):
""" Fetch favicon for the domain """ """ Fetch favicon for the domain """
response = requests.get( response = requests.get(
'https://realfavicongenerator.p.rapidapi.com/favicon/icon?platform=android_chrome&site=' + domain, 'https://realfavicongenerator.p.mashape.com/favicon/icon?platform=android_chrome&site=' + domain,
stream=True, stream=True,
headers={'User-Agent': DIGIMARKS_USER_AGENT, 'X-Mashape-Key': settings.MASHAPE_API_KEY} headers={'User-Agent': DIGIMARKS_USER_AGENT, 'X-Mashape-Key': settings.MASHAPE_API_KEY}
) )
if response.status_code == 404: if response.status_code == 404:
# Fall back to desktop favicon # Fall back to desktop favicon
response = requests.get( response = requests.get(
'https://realfavicongenerator.p.rapidapi.com/favicon/icon?platform=desktop&site=' + domain, 'https://realfavicongenerator.p.mashape.com/favicon/icon?platform=desktop&site=' + domain,
stream=True, stream=True,
headers={'User-Agent': DIGIMARKS_USER_AGENT, 'X-Mashape-Key': settings.MASHAPE_API_KEY} headers={'User-Agent': DIGIMARKS_USER_AGENT, 'X-Mashape-Key': settings.MASHAPE_API_KEY}
) )
@@ -450,7 +449,10 @@ class Bookmark(BaseModel):
'url': self.url, 'url': self.url,
'created': self.created_date.strftime('%Y-%m-%d %H:%M:%S'), 'created': self.created_date.strftime('%Y-%m-%d %H:%M:%S'),
'url_hash': self.url_hash, 'url_hash': self.url_hash,
'tags': self.tags, 'tags': self.tags.split(','),
'favicon': self.favicon,
'http_status': self.http_status,
'redirect_uri': self.redirect_uri,
} }
return result return result
@@ -605,12 +607,10 @@ def bookmarks_js(userkey):
Bookmark.userkey == userkey, Bookmark.userkey == userkey,
Bookmark.status == Bookmark.VISIBLE Bookmark.status == Bookmark.VISIBLE
).order_by(Bookmark.created_date.desc()) ).order_by(Bookmark.created_date.desc())
resp = make_response(render_template( return render_template(
'bookmarks.js', 'bookmarks.js',
bookmarks=bookmarks bookmarks=bookmarks
)) )
resp.headers['Content-type'] = 'text/javascript; charset=utf-8'
return resp
@app.route('/r/<userkey>/<urlhash>') @app.route('/r/<userkey>/<urlhash>')
@@ -963,34 +963,23 @@ def publictag_feed(tagkey):
Bookmark.tags.contains(this_tag.tag), Bookmark.tags.contains(this_tag.tag),
Bookmark.status == Bookmark.VISIBLE Bookmark.status == Bookmark.VISIBLE
) )
feed = AtomFeed(this_tag.tag, feed_url=request.url, url=make_external(url_for('publictag_page', tagkey=tagkey)))
feed = FeedGenerator()
feed.title(this_tag.tag)
feed.id(request.url)
feed.link(href=request.url, rel='self')
feed.link(href=make_external(url_for('publictag_page', tagkey=tagkey)))
for bookmark in bookmarks: for bookmark in bookmarks:
entry = feed.add_entry()
updated_date = bookmark.modified_date updated_date = bookmark.modified_date
if not bookmark.modified_date: if not bookmark.modified_date:
updated_date = bookmark.created_date updated_date = bookmark.created_date
bookmarktitle = '{} (no title)'.format(bookmark.url) bookmarktitle = '{} (no title)'.format(bookmark.url)
if bookmark.title: if bookmark.title:
bookmarktitle = bookmark.title bookmarktitle = bookmark.title
feed.add(
entry.id(bookmark.url) bookmarktitle,
entry.title(bookmarktitle) content_type='html',
entry.link(href=bookmark.url) author='digimarks',
entry.author(name='digimarks') url=bookmark.url,
entry.pubdate(bookmark.created_date.replace(tzinfo=tz.tzlocal())) updated=updated_date,
entry.published(bookmark.created_date.replace(tzinfo=tz.tzlocal())) published=bookmark.created_date
entry.updated(updated_date.replace(tzinfo=tz.tzlocal())) )
return feed.get_response()
response = make_response(feed.atom_str(pretty=True))
response.headers.set('Content-Type', 'application/atom+xml')
return response
except PublicTag.DoesNotExist: except PublicTag.DoesNotExist:
abort(404) abort(404)

View File

@@ -10,10 +10,6 @@ DEBUG = False
# echo -n "yourstring" | sha1sum # echo -n "yourstring" | sha1sum
SYSTEMKEY = 'S3kr1t' SYSTEMKEY = 'S3kr1t'
# RapidAPI key for favicons
# https://rapidapi.com/realfavicongenerator/api/realfavicongenerator
MASHAPE_API_KEY = 'your_MASHAPE_key'
LOG_LOCATION = 'digimarks.log' LOG_LOCATION = 'digimarks.log'
#LOG_LOCATION = '/var/log/digimarks/digimarks.log' #LOG_LOCATION = '/var/log/digimarks/digimarks.log'
# How many logs to keep in log rotation: # How many logs to keep in log rotation:

View File

@@ -1,61 +1,28 @@
# This file was autogenerated by uv via the following command: #
# uv pip compile requirements-dev.in # This file is autogenerated by pip-compile
astroid==3.3.11 # To update, run:
# via pylint #
beautifulsoup4==4.13.5 # pip-compile --output-file requirements-dev.txt requirements-dev.in
# via bs4 #
blinker==1.9.0 astroid==2.0.4 # via pylint
# via flask beautifulsoup4==4.6.3 # via bs4
bs4==0.0.2 bs4==0.0.1
# via -r requirements.in certifi==2018.8.24 # via requests
certifi==2025.8.3 chardet==3.0.4 # via requests
# via requests click==7.0 # via flask
charset-normalizer==3.4.3 flask==1.0.2
# via requests idna==2.7 # via requests
click==8.2.1 isort==4.3.4 # via pylint
# via flask itsdangerous==0.24 # via flask
dill==0.4.0 jinja2==2.10 # via flask
# via pylint lazy-object-proxy==1.3.1 # via astroid
feedgen==1.0.0 markupsafe==1.0 # via jinja2
# via -r requirements.in mccabe==0.6.1 # via pylint
flask==3.1.2 peewee==3.7.0
# via -r requirements.in pylint==2.1.1
idna==3.10 requests==2.19.1
# via requests six==1.11.0 # via astroid
isort==6.0.1 typed-ast==1.1.0 # via astroid
# via pylint urllib3==1.23 # via requests
itsdangerous==2.2.0 werkzeug==0.14.1 # via flask
# via flask wrapt==1.10.11 # via astroid
jinja2==3.1.6
# via flask
lxml==6.0.1
# via feedgen
markupsafe==3.0.2
# via
# flask
# jinja2
# werkzeug
mccabe==0.7.0
# via pylint
peewee==3.18.2
# via -r requirements.in
platformdirs==4.4.0
# via pylint
pylint==3.3.8
# via -r requirements-dev.in
python-dateutil==2.9.0.post0
# via feedgen
requests==2.32.5
# via -r requirements.in
six==1.17.0
# via python-dateutil
soupsieve==2.8
# via beautifulsoup4
tomlkit==0.13.3
# via pylint
typing-extensions==4.15.0
# via beautifulsoup4
urllib3==2.5.0
# via requests
werkzeug==3.1.3
# via flask

View File

@@ -1,10 +1,4 @@
# Core application
flask flask
peewee peewee
# Fetch title etc from links
bs4 bs4
requests requests
# Generate (atom) feeds for tags and such
feedgen

View File

@@ -1,47 +1,20 @@
# This file was autogenerated by uv via the following command: #
# uv pip compile requirements.in # This file is autogenerated by pip-compile
beautifulsoup4==4.13.5 # To update, run:
# via bs4 #
blinker==1.9.0 # pip-compile --output-file requirements.txt requirements.in
# via flask #
bs4==0.0.2 beautifulsoup4==4.6.3 # via bs4
# via -r requirements.in bs4==0.0.1
certifi==2025.8.3 certifi==2018.8.24 # via requests
# via requests chardet==3.0.4 # via requests
charset-normalizer==3.4.3 click==7.0 # via flask
# via requests flask==1.0.2
click==8.2.1 idna==2.7 # via requests
# via flask itsdangerous==0.24 # via flask
feedgen==1.0.0 jinja2==2.10 # via flask
# via -r requirements.in markupsafe==1.0 # via jinja2
flask==3.1.2 peewee==3.7.0
# via -r requirements.in requests==2.19.1
idna==3.10 urllib3==1.23 # via requests
# via requests werkzeug==0.14.1 # via flask
itsdangerous==2.2.0
# via flask
jinja2==3.1.6
# via flask
lxml==6.0.1
# via feedgen
markupsafe==3.0.2
# via
# flask
# jinja2
# werkzeug
peewee==3.18.2
# via -r requirements.in
python-dateutil==2.9.0.post0
# via feedgen
requests==2.32.5
# via -r requirements.in
six==1.17.0
# via python-dateutil
soupsieve==2.8
# via beautifulsoup4
typing-extensions==4.15.0
# via beautifulsoup4
urllib3==2.5.0
# via requests
werkzeug==3.1.4
# via flask

View File

@@ -9,7 +9,7 @@
{% if tag and not publictag %} {% if tag and not publictag %}
<div class="row"> <div class="row">
<div class="col s12"> <div class="col s12">
<a href="{{ url_for('addpublictag', userkey=userkey, tag=tag) }}">Create public page <i class="material-icons right">tag</i></a> <a href="{{ url_for('addpublictag', userkey=userkey, tag=tag) }}">Create public page <i class="material-icons left">tag</i></a>
</div> </div>
</div> </div>
{% endif %} {% endif %}