mirror of
https://github.com/aquatix/digimarks.git
synced 2025-12-06 22:05:09 +01:00
Refactoring to FastAPI
This commit is contained in:
@@ -23,9 +23,8 @@ dependencies = [
|
|||||||
"fastapi[all]",
|
"fastapi[all]",
|
||||||
"pydantic>2.0",
|
"pydantic>2.0",
|
||||||
"requests",
|
"requests",
|
||||||
"strictyaml",
|
"bs4",
|
||||||
"gitpython",
|
"feedgen"
|
||||||
"rq"
|
|
||||||
]
|
]
|
||||||
# dynamic = ["version"]
|
# dynamic = ["version"]
|
||||||
|
|
||||||
@@ -36,6 +35,9 @@ my-script = "digimarks:app"
|
|||||||
"Homepage" = "https://github.com/aquatix/digimarks"
|
"Homepage" = "https://github.com/aquatix/digimarks"
|
||||||
"Bug Tracker" = "https://github.com/aquatix/digimarks/issues"
|
"Bug Tracker" = "https://github.com/aquatix/digimarks/issues"
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
line-length = 120
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
exclude = [
|
exclude = [
|
||||||
".git",
|
".git",
|
||||||
|
|||||||
@@ -13,139 +13,22 @@ from dateutil import tz
|
|||||||
#from flask import (Flask, abort, jsonify, make_response, redirect,
|
#from flask import (Flask, abort, jsonify, make_response, redirect,
|
||||||
# render_template, request, url_for)
|
# render_template, request, url_for)
|
||||||
from fastapi import Depends, FastAPI, HTTPException, Request, Response
|
from fastapi import Depends, FastAPI, HTTPException, Request, Response
|
||||||
|
from fastapi.responses import RedirectResponse
|
||||||
|
from fastapi.responses import HTMLResponse
|
||||||
|
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from fastapi.templating import Jinja2Templates
|
||||||
from feedgen.feed import FeedGenerator
|
from feedgen.feed import FeedGenerator
|
||||||
from pydantic import BaseModel, DirectoryPath, FilePath, validator
|
from pydantic import DirectoryPath, FilePath, validator
|
||||||
from pydantic_settings import BaseSettings
|
from pydantic_settings import BaseSettings
|
||||||
from sqlalchemy import VARCHAR, Boolean, Column, DateTime, ForeignKey, Integer, String, Text, create_engine
|
from sqlalchemy import VARCHAR, Boolean, Column, DateTime, ForeignKey, Integer, String, Text, create_engine
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
|
|
||||||
DIGIMARKS_USER_AGENT = 'digimarks/2.0.0-dev'
|
DIGIMARKS_USER_AGENT = 'digimarks/2.0.0-dev'
|
||||||
|
|
||||||
DEFAULT_THEME = 'freshgreen'
|
DEFAULT_THEME = 'freshgreen'
|
||||||
themes = {
|
|
||||||
'green': {
|
|
||||||
'BROWSERCHROME': '#2e7d32', # green darken-2
|
|
||||||
'BODY': 'grey lighten-4',
|
|
||||||
'TEXT': 'black-text',
|
|
||||||
'TEXTHEX': '#000',
|
|
||||||
'NAV': 'green darken-3',
|
|
||||||
'PAGEHEADER': 'grey-text lighten-5',
|
|
||||||
'MESSAGE_BACKGROUND': 'orange lighten-2',
|
|
||||||
'MESSAGE_TEXT': 'white-text',
|
|
||||||
'ERRORMESSAGE_BACKGROUND': 'red darken-1',
|
|
||||||
'ERRORMESSAGE_TEXT': 'white-text',
|
|
||||||
'BUTTON': '#1b5e20', # green darken-4
|
|
||||||
'BUTTON_ACTIVE': '#43a047', # green darken-1
|
|
||||||
'LINK_TEXT': '#1b5e20', # green darken-4
|
|
||||||
'CARD_BACKGROUND': 'green darken-3',
|
|
||||||
'CARD_TEXT': 'white-text',
|
|
||||||
'CARD_LINK': '#FFF', # white-text
|
|
||||||
'CHIP_TEXT': '#1b5e20', # green darken-4
|
|
||||||
'FAB': 'red',
|
|
||||||
|
|
||||||
'STAR': 'yellow-text',
|
|
||||||
'PROBLEM': 'red-text',
|
|
||||||
'COMMENT': '',
|
|
||||||
},
|
|
||||||
'freshgreen': {
|
|
||||||
'BROWSERCHROME': '#43a047', # green darken-1
|
|
||||||
'BODY': 'grey lighten-5',
|
|
||||||
'TEXT': 'black-text',
|
|
||||||
'TEXTHEX': '#000',
|
|
||||||
'NAV': 'green darken-1',
|
|
||||||
'PAGEHEADER': 'grey-text lighten-5',
|
|
||||||
'MESSAGE_BACKGROUND': 'orange lighten-2',
|
|
||||||
'MESSAGE_TEXT': 'white-text',
|
|
||||||
'ERRORMESSAGE_BACKGROUND': 'red darken-1',
|
|
||||||
'ERRORMESSAGE_TEXT': 'white-text',
|
|
||||||
'BUTTON': '#1b5e20', # green darken-4
|
|
||||||
'BUTTON_ACTIVE': '#43a047', # green darken-1
|
|
||||||
'LINK_TEXT': '#1b5e20', # green darken-4
|
|
||||||
'CARD_BACKGROUND': 'green darken-1',
|
|
||||||
'CARD_TEXT': 'white-text',
|
|
||||||
'CARD_LINK': '#FFF', # white-text
|
|
||||||
'CHIP_TEXT': '#1b5e20', # green darken-4
|
|
||||||
'FAB': 'red',
|
|
||||||
|
|
||||||
'STAR': 'yellow-text',
|
|
||||||
'PROBLEM': 'red-text',
|
|
||||||
'COMMENT': '',
|
|
||||||
},
|
|
||||||
'lightblue': {
|
|
||||||
'BROWSERCHROME': '#0288d1', # light-blue darken-2
|
|
||||||
'BODY': 'white',
|
|
||||||
'TEXT': 'black-text',
|
|
||||||
'TEXTHEX': '#000',
|
|
||||||
'NAV': 'light-blue darken-2',
|
|
||||||
'PAGEHEADER': 'grey-text lighten-5',
|
|
||||||
'MESSAGE_BACKGROUND': 'orange lighten-2',
|
|
||||||
'MESSAGE_TEXT': 'white-text',
|
|
||||||
'ERRORMESSAGE_BACKGROUND': 'red darken-1',
|
|
||||||
'ERRORMESSAGE_TEXT': 'white-text',
|
|
||||||
'BUTTON': '#fb8c00', # orange darken-1
|
|
||||||
'BUTTON_ACTIVE': '#ffa726', # orange lighten-1
|
|
||||||
'LINK_TEXT': '#FFF', # white
|
|
||||||
'CARD_BACKGROUND': 'light-blue lighten-2',
|
|
||||||
'CARD_TEXT': 'black-text',
|
|
||||||
'CARD_LINK': '#263238', # blue-grey-text darken-4
|
|
||||||
'CHIP_TEXT': '#FFF', # white
|
|
||||||
'FAB': 'light-blue darken-4',
|
|
||||||
|
|
||||||
'STAR': 'yellow-text',
|
|
||||||
'PROBLEM': 'red-text',
|
|
||||||
'COMMENT': '',
|
|
||||||
},
|
|
||||||
'dark': {
|
|
||||||
'BROWSERCHROME': '#212121', # grey darken-4
|
|
||||||
'BODY': 'grey darken-4',
|
|
||||||
'TEXT': 'grey-text lighten-1',
|
|
||||||
'TEXTHEX': '#bdbdbd',
|
|
||||||
'NAV': 'grey darken-3',
|
|
||||||
'PAGEHEADER': 'grey-text lighten-1',
|
|
||||||
'MESSAGE_BACKGROUND': 'orange lighten-2',
|
|
||||||
'MESSAGE_TEXT': 'white-text',
|
|
||||||
'ERRORMESSAGE_BACKGROUND': 'red darken-1',
|
|
||||||
'ERRORMESSAGE_TEXT': 'white-text',
|
|
||||||
'BUTTON': '#fb8c00', # orange darken-1
|
|
||||||
'BUTTON_ACTIVE': '#ffa726', # orange lighten-1
|
|
||||||
'LINK_TEXT': '#fb8c00', # orange-text darken-1
|
|
||||||
'CARD_BACKGROUND': 'grey darken-3',
|
|
||||||
'CARD_TEXT': 'grey-text lighten-1',
|
|
||||||
'CARD_LINK': '#fb8c00', # orange-text darken-1
|
|
||||||
'CHIP_TEXT': '#fb8c00', # orange-text darken-1
|
|
||||||
'FAB': 'red',
|
|
||||||
|
|
||||||
'STAR': 'yellow-text',
|
|
||||||
'PROBLEM': 'red-text',
|
|
||||||
'COMMENT': '',
|
|
||||||
},
|
|
||||||
'amoled': {
|
|
||||||
'BROWSERCHROME': '#000', # grey darken-4
|
|
||||||
'BODY': 'black',
|
|
||||||
'TEXT': 'grey-text lighten-1',
|
|
||||||
'TEXTHEX': '#bdbdbd',
|
|
||||||
'NAV': 'grey darken-3',
|
|
||||||
'PAGEHEADER': 'grey-text lighten-1',
|
|
||||||
'MESSAGE_BACKGROUND': 'orange lighten-2',
|
|
||||||
'MESSAGE_TEXT': 'white-text',
|
|
||||||
'ERRORMESSAGE_BACKGROUND': 'red darken-1',
|
|
||||||
'ERRORMESSAGE_TEXT': 'white-text',
|
|
||||||
'BUTTON': '#fb8c00', # orange darken-1
|
|
||||||
'BUTTON_ACTIVE': '#ffa726', # orange lighten-1
|
|
||||||
'LINK_TEXT': '#fb8c00', # orange-text darken-1
|
|
||||||
'CARD_BACKGROUND': 'grey darken-3',
|
|
||||||
'CARD_TEXT': 'grey-text lighten-1',
|
|
||||||
'CARD_LINK': '#fb8c00', # orange-text darken-1
|
|
||||||
'CHIP_TEXT': '#fb8c00', # orange-text darken-1
|
|
||||||
'FAB': 'red',
|
|
||||||
|
|
||||||
'STAR': 'yellow-text',
|
|
||||||
'PROBLEM': 'red-text',
|
|
||||||
'COMMENT': '',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
@@ -171,6 +54,8 @@ Base = declarative_base()
|
|||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
|
||||||
logger = logging.getLogger('digimarks')
|
logger = logging.getLogger('digimarks')
|
||||||
if settings.debug:
|
if settings.debug:
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
@@ -185,6 +70,7 @@ app.add_middleware(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Temporary
|
||||||
all_tags = {}
|
all_tags = {}
|
||||||
usersettings = {}
|
usersettings = {}
|
||||||
|
|
||||||
@@ -246,6 +132,9 @@ def file_type(filename):
|
|||||||
|
|
||||||
class User(Base):
|
class User(Base):
|
||||||
""" User account """
|
""" User account """
|
||||||
|
__tablename__ = 'user'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
username = Column(VARCHAR(255))
|
username = Column(VARCHAR(255))
|
||||||
key = Column(VARCHAR(255))
|
key = Column(VARCHAR(255))
|
||||||
# theme = CharField(default=DEFAULT_THEME)
|
# theme = CharField(default=DEFAULT_THEME)
|
||||||
@@ -260,6 +149,9 @@ class User(Base):
|
|||||||
|
|
||||||
class Bookmark(Base):
|
class Bookmark(Base):
|
||||||
""" Bookmark instance, connected to User """
|
""" Bookmark instance, connected to User """
|
||||||
|
__tablename__ = 'bookmark'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
# Foreign key to User
|
# Foreign key to User
|
||||||
userkey = Column(VARCHAR(255))
|
userkey = Column(VARCHAR(255))
|
||||||
|
|
||||||
@@ -301,7 +193,7 @@ class Bookmark(Base):
|
|||||||
""" Generate hash """
|
""" Generate hash """
|
||||||
self.url_hash = hashlib.md5(self.url.encode('utf-8')).hexdigest()
|
self.url_hash = hashlib.md5(self.url.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
def set_title_from_source(self):
|
def set_title_from_source(self) -> str:
|
||||||
""" Request the title by requesting the source url """
|
""" Request the title by requesting the source url """
|
||||||
try:
|
try:
|
||||||
result = requests.get(self.url, headers={'User-Agent': DIGIMARKS_USER_AGENT})
|
result = requests.get(self.url, headers={'User-Agent': DIGIMARKS_USER_AGENT})
|
||||||
@@ -317,10 +209,10 @@ class Bookmark(Base):
|
|||||||
self.title = ''
|
self.title = ''
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
def set_status_code(self):
|
def set_status_code(self) -> int:
|
||||||
""" Check the HTTP status of the url, as it might not exist for example """
|
""" Check the HTTP status of the url, as it might not exist for example """
|
||||||
try:
|
try:
|
||||||
result = requests.head(self.url, headers={'User-Agent': DIGIMARKS_USER_AGENT})
|
result = requests.head(self.url, headers={'User-Agent': DIGIMARKS_USER_AGENT}, timeout=30)
|
||||||
self.http_status = result.status_code
|
self.http_status = result.status_code
|
||||||
except requests.ConnectionError:
|
except requests.ConnectionError:
|
||||||
self.http_status = self.HTTP_CONNECTIONERROR
|
self.http_status = self.HTTP_CONNECTIONERROR
|
||||||
@@ -332,14 +224,16 @@ class Bookmark(Base):
|
|||||||
meta = requests.head(
|
meta = requests.head(
|
||||||
'http://icons.better-idea.org/icon?size=60&url=' + domain,
|
'http://icons.better-idea.org/icon?size=60&url=' + domain,
|
||||||
allow_redirects=True,
|
allow_redirects=True,
|
||||||
headers={'User-Agent': DIGIMARKS_USER_AGENT}
|
headers={'User-Agent': DIGIMARKS_USER_AGENT},
|
||||||
|
timeout=15
|
||||||
)
|
)
|
||||||
if meta.url[-3:].lower() == 'ico':
|
if meta.url[-3:].lower() == 'ico':
|
||||||
fileextension = '.ico'
|
fileextension = '.ico'
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
'http://icons.better-idea.org/icon?size=60&url=' + domain,
|
'http://icons.better-idea.org/icon?size=60&url=' + domain,
|
||||||
stream=True,
|
stream=True,
|
||||||
headers={'User-Agent': DIGIMARKS_USER_AGENT}
|
headers={'User-Agent': DIGIMARKS_USER_AGENT},
|
||||||
|
timeout=15
|
||||||
)
|
)
|
||||||
filename = os.path.join(settings.media_dir, 'favicons/', domain + fileextension)
|
filename = os.path.join(settings.media_dir, 'favicons/', domain + fileextension)
|
||||||
with open(filename, 'wb') as out_file:
|
with open(filename, 'wb') as out_file:
|
||||||
@@ -445,7 +339,7 @@ class Bookmark(Base):
|
|||||||
return self.tags.split(',')
|
return self.tags.split(',')
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self) -> dict:
|
||||||
result = {
|
result = {
|
||||||
'title': self.title,
|
'title': self.title,
|
||||||
'url': self.url,
|
'url': self.url,
|
||||||
@@ -456,12 +350,15 @@ class Bookmark(Base):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def serialize(self):
|
def serialize(self) -> dict:
|
||||||
return self.to_dict()
|
return self.to_dict()
|
||||||
|
|
||||||
|
|
||||||
class PublicTag(BaseModel):
|
class PublicTag(Base):
|
||||||
""" Publicly shared tag """
|
""" Publicly shared tag """
|
||||||
|
__tablename__ = 'publictag'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
tagkey = Column(VARCHAR(255))
|
tagkey = Column(VARCHAR(255))
|
||||||
userkey = Column(VARCHAR(255))
|
userkey = Column(VARCHAR(255))
|
||||||
tag = Column(VARCHAR(255))
|
tag = Column(VARCHAR(255))
|
||||||
@@ -490,6 +387,7 @@ def get_cached_tags(userkey):
|
|||||||
|
|
||||||
|
|
||||||
def get_theme(userkey):
|
def get_theme(userkey):
|
||||||
|
themes = {DEFAULT_THEME: {}}
|
||||||
try:
|
try:
|
||||||
usertheme = usersettings[userkey]['theme']
|
usertheme = usersettings[userkey]['theme']
|
||||||
return themes[usertheme]
|
return themes[usertheme]
|
||||||
@@ -497,11 +395,12 @@ def get_theme(userkey):
|
|||||||
return themes[DEFAULT_THEME] # default
|
return themes[DEFAULT_THEME] # default
|
||||||
|
|
||||||
|
|
||||||
def make_external(url):
|
def make_external(request: Request, url):
|
||||||
return urljoin(request.url_root, url)
|
return urljoin(request.url_root, url)
|
||||||
|
|
||||||
|
|
||||||
def _find_bookmarks(userkey, filter_text):
|
def _find_bookmarks(userkey, filter_text) -> list[Bookmark]:
|
||||||
|
"""Look up bookmark for `userkey` which contains `filter_text` in its properties"""
|
||||||
return Bookmark.select().where(
|
return Bookmark.select().where(
|
||||||
Bookmark.userkey == userkey,
|
Bookmark.userkey == userkey,
|
||||||
(
|
(
|
||||||
@@ -513,20 +412,21 @@ def _find_bookmarks(userkey, filter_text):
|
|||||||
).order_by(Bookmark.created_date.desc())
|
).order_by(Bookmark.created_date.desc())
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(404)
|
# @app.errorhandler(404)
|
||||||
def page_not_found(e):
|
# def page_not_found(e):
|
||||||
theme = themes[DEFAULT_THEME]
|
# theme = themes[DEFAULT_THEME]
|
||||||
return render_template('404.html', error=e, theme=theme), 404
|
# return render_template('404.html', error=e, theme=theme), 404
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
@app.get('/')
|
||||||
def index():
|
def index():
|
||||||
""" Homepage, point visitors to project page """
|
""" Homepage, point visitors to project page """
|
||||||
theme = themes[DEFAULT_THEME]
|
# theme = themes[DEFAULT_THEME]
|
||||||
return render_template('index.html', theme=theme)
|
# return render_template('index.html', theme=theme)
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def get_bookmarks(userkey, filtermethod=None, sortmethod=None):
|
def get_bookmarks(request: Request, userkey, filtermethod=None, sortmethod=None):
|
||||||
""" User homepage, list their bookmarks, optionally filtered and/or sorted """
|
""" User homepage, list their bookmarks, optionally filtered and/or sorted """
|
||||||
#return object_list('bookmarks.html', Bookmark.select())
|
#return object_list('bookmarks.html', Bookmark.select())
|
||||||
#user = User.select(key=userkey)
|
#user = User.select(key=userkey)
|
||||||
@@ -574,16 +474,17 @@ def get_bookmarks(userkey, filtermethod=None, sortmethod=None):
|
|||||||
return bookmarks, bookmarktags, filter_text, message
|
return bookmarks, bookmarktags, filter_text, message
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>', methods=['GET', 'POST'])
|
@app.get('/<userkey>', response_class=HTMLResponse)
|
||||||
|
@app.post('/<userkey>', response_class=HTMLResponse)
|
||||||
@app.route('/<userkey>/filter/<filtermethod>', methods=['GET', 'POST'])
|
@app.route('/<userkey>/filter/<filtermethod>', methods=['GET', 'POST'])
|
||||||
@app.route('/<userkey>/sort/<sortmethod>', methods=['GET', 'POST'])
|
@app.route('/<userkey>/sort/<sortmethod>', methods=['GET', 'POST'])
|
||||||
@app.route('/<userkey>/<show_as>', methods=['GET', 'POST'])
|
@app.route('/<userkey>/<show_as>', methods=['GET', 'POST'])
|
||||||
@app.route('/<userkey>/<show_as>/filter/<filtermethod>', methods=['GET', 'POST'])
|
@app.route('/<userkey>/<show_as>/filter/<filtermethod>', methods=['GET', 'POST'])
|
||||||
@app.route('/<userkey>/<show_as>/sort/<sortmethod>', methods=['GET', 'POST'])
|
@app.route('/<userkey>/<show_as>/sort/<sortmethod>', methods=['GET', 'POST'])
|
||||||
def bookmarks_page(userkey, filtermethod=None, sortmethod=None, show_as='cards'):
|
def bookmarks_page(request: Request, userkey, filtermethod=None, sortmethod=None, show_as='cards'):
|
||||||
bookmarks, bookmarktags, filter_text, message = get_bookmarks(userkey, filtermethod, sortmethod)
|
bookmarks, bookmarktags, filter_text, message = get_bookmarks(request, userkey, filtermethod, sortmethod)
|
||||||
theme = get_theme(userkey)
|
theme = get_theme(userkey)
|
||||||
return render_template(
|
return templates.TemplateResponse(
|
||||||
'bookmarks.html',
|
'bookmarks.html',
|
||||||
bookmarks=bookmarks,
|
bookmarks=bookmarks,
|
||||||
userkey=userkey,
|
userkey=userkey,
|
||||||
@@ -599,22 +500,26 @@ def bookmarks_page(userkey, filtermethod=None, sortmethod=None, show_as='cards')
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/js')
|
@app.get('/<userkey>/js')
|
||||||
def bookmarks_js(userkey):
|
def bookmarks_js(userkey):
|
||||||
""" Return list of bookmarks with their favicons, to be used for autocompletion """
|
""" Return list of bookmarks with their favicons, to be used for autocompletion """
|
||||||
bookmarks = Bookmark.select().where(
|
bookmarks = Bookmark.select().where(
|
||||||
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(
|
result = []
|
||||||
'bookmarks.js',
|
for bookmark in bookmarks:
|
||||||
bookmarks=bookmarks
|
result.append({'title': bookmark.title})
|
||||||
))
|
# resp = make_response(render_template(
|
||||||
resp.headers['Content-type'] = 'text/javascript; charset=utf-8'
|
# 'bookmarks.js',
|
||||||
return resp
|
# bookmarks=bookmarks
|
||||||
|
# ))
|
||||||
|
# resp.headers['Content-type'] = 'text/javascript; charset=utf-8'
|
||||||
|
# return resp
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@app.route('/r/<userkey>/<urlhash>')
|
@app.get('/r/<userkey>/<urlhash>', response_class=HTMLResponse)
|
||||||
def bookmark_redirect(userkey, urlhash):
|
def bookmark_redirect(userkey, urlhash):
|
||||||
""" Securely redirect a bookmark to its url, stripping referrer (if browser plays nice) """
|
""" Securely redirect a bookmark to its url, stripping referrer (if browser plays nice) """
|
||||||
# @TODO: add counter to this bookmark
|
# @TODO: add counter to this bookmark
|
||||||
@@ -625,15 +530,15 @@ def bookmark_redirect(userkey, urlhash):
|
|||||||
Bookmark.status == Bookmark.VISIBLE
|
Bookmark.status == Bookmark.VISIBLE
|
||||||
)
|
)
|
||||||
except Bookmark.DoesNotExist:
|
except Bookmark.DoesNotExist:
|
||||||
abort(404)
|
raise HTTPException(status_code=404, detail='Bookmark not found')
|
||||||
return render_template('redirect.html', url=bookmark.url)
|
return templates.TemplateResponse('redirect.html', url=bookmark.url)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/v1/<userkey>', methods=['GET', 'POST'])
|
@app.route('/api/v1/<userkey>', methods=['GET', 'POST'])
|
||||||
@app.route('/api/v1/<userkey>/filter/<filtermethod>', methods=['GET', 'POST'])
|
@app.route('/api/v1/<userkey>/filter/<filtermethod>', methods=['GET', 'POST'])
|
||||||
@app.route('/api/v1/<userkey>/sort/<sortmethod>', methods=['GET', 'POST'])
|
@app.route('/api/v1/<userkey>/sort/<sortmethod>', methods=['GET', 'POST'])
|
||||||
def bookmarks_json(userkey, filtermethod=None, sortmethod=None):
|
def bookmarks_json(request: Request, userkey, filtermethod=None, sortmethod=None):
|
||||||
bookmarks, bookmarktags, filter_text, message = get_bookmarks(userkey, filtermethod, sortmethod)
|
bookmarks, bookmarktags, filter_text, message = get_bookmarks(request, userkey, filtermethod, sortmethod)
|
||||||
|
|
||||||
bookmarkslist = [i.serialize for i in bookmarks]
|
bookmarkslist = [i.serialize for i in bookmarks]
|
||||||
|
|
||||||
@@ -644,7 +549,7 @@ def bookmarks_json(userkey, filtermethod=None, sortmethod=None):
|
|||||||
'message': message,
|
'message': message,
|
||||||
'userkey': userkey,
|
'userkey': userkey,
|
||||||
}
|
}
|
||||||
return jsonify(the_data)
|
return the_data
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/v1/<userkey>/<urlhash>')
|
@app.route('/api/v1/<userkey>/<urlhash>')
|
||||||
@@ -656,10 +561,9 @@ def bookmark_json(userkey, urlhash):
|
|||||||
Bookmark.userkey == userkey,
|
Bookmark.userkey == userkey,
|
||||||
Bookmark.status == Bookmark.VISIBLE
|
Bookmark.status == Bookmark.VISIBLE
|
||||||
)
|
)
|
||||||
return jsonify(bookmark.to_dict())
|
return bookmark.to_dict()
|
||||||
except Bookmark.DoesNotExist:
|
except Bookmark.DoesNotExist:
|
||||||
return jsonify({'message': 'Bookmark not found', 'status': 'error 404'})
|
raise HTTPException(status_code=404, detail='Bookmark not found')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/v1/<userkey>/search/<filter_text>')
|
@app.route('/api/v1/<userkey>/search/<filter_text>')
|
||||||
def search_bookmark_titles_json(userkey, filter_text):
|
def search_bookmark_titles_json(userkey, filter_text):
|
||||||
@@ -668,25 +572,25 @@ def search_bookmark_titles_json(userkey, filter_text):
|
|||||||
result = []
|
result = []
|
||||||
for bookmark in bookmarks:
|
for bookmark in bookmarks:
|
||||||
result.append(bookmark.to_dict())
|
result.append(bookmark.to_dict())
|
||||||
return jsonify(result)
|
return result
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/<urlhash>')
|
@app.get('/<userkey>/<urlhash>', response_class=HTMLResponse)
|
||||||
@app.route('/<userkey>/<urlhash>/edit')
|
@app.get('/<userkey>/<urlhash>/edit', response_class=HTMLResponse)
|
||||||
def editbookmark(userkey, urlhash):
|
def editbookmark(request: Request, userkey, urlhash):
|
||||||
""" Bookmark edit form """
|
""" Bookmark edit form """
|
||||||
# bookmark = getbyurlhash()
|
# bookmark = getbyurlhash()
|
||||||
try:
|
try:
|
||||||
bookmark = Bookmark.get(Bookmark.url_hash == urlhash, Bookmark.userkey == userkey)
|
bookmark = Bookmark.get(Bookmark.url_hash == urlhash, Bookmark.userkey == userkey)
|
||||||
except Bookmark.DoesNotExist:
|
except Bookmark.DoesNotExist:
|
||||||
abort(404)
|
raise HTTPException(status_code=404, detail='Bookmark not found')
|
||||||
message = request.args.get('message')
|
message = request.args.get('message')
|
||||||
tags = get_cached_tags(userkey)
|
tags = get_cached_tags(userkey)
|
||||||
if not bookmark.note:
|
if not bookmark.note:
|
||||||
# Workaround for when an existing bookmark has a null note
|
# Workaround for when an existing bookmark has a null note
|
||||||
bookmark.note = ''
|
bookmark.note = ''
|
||||||
theme = get_theme(userkey)
|
theme = get_theme(userkey)
|
||||||
return render_template(
|
return templates.TemplateResponse(
|
||||||
'edit.html',
|
'edit.html',
|
||||||
action='Edit bookmark',
|
action='Edit bookmark',
|
||||||
userkey=userkey,
|
userkey=userkey,
|
||||||
@@ -698,8 +602,8 @@ def editbookmark(userkey, urlhash):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/add')
|
@app.get('/<userkey>/add', response_class=HTMLResponse)
|
||||||
def addbookmark(userkey):
|
def addbookmark(request: Request, userkey):
|
||||||
""" Bookmark add form """
|
""" Bookmark add form """
|
||||||
url = request.args.get('url')
|
url = request.args.get('url')
|
||||||
if not url:
|
if not url:
|
||||||
@@ -710,7 +614,7 @@ def addbookmark(userkey):
|
|||||||
message = request.args.get('message')
|
message = request.args.get('message')
|
||||||
tags = get_cached_tags(userkey)
|
tags = get_cached_tags(userkey)
|
||||||
theme = get_theme(userkey)
|
theme = get_theme(userkey)
|
||||||
return render_template(
|
return templates.TemplateResponse(
|
||||||
'edit.html',
|
'edit.html',
|
||||||
action='Add bookmark',
|
action='Add bookmark',
|
||||||
userkey=userkey,
|
userkey=userkey,
|
||||||
@@ -721,7 +625,7 @@ def addbookmark(userkey):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def updatebookmark(userkey, urlhash=None):
|
def updatebookmark(request: Request, userkey, urlhash=None):
|
||||||
""" Add (no urlhash) or edit (urlhash is set) a bookmark """
|
""" Add (no urlhash) or edit (urlhash is set) a bookmark """
|
||||||
title = request.form.get('title')
|
title = request.form.get('title')
|
||||||
url = request.form.get('url')
|
url = request.form.get('url')
|
||||||
@@ -739,7 +643,7 @@ def updatebookmark(userkey, urlhash=None):
|
|||||||
bookmark, created = Bookmark.get_or_create(url=url, userkey=userkey)
|
bookmark, created = Bookmark.get_or_create(url=url, userkey=userkey)
|
||||||
if not created:
|
if not created:
|
||||||
message = 'Existing bookmark, did not overwrite with new values'
|
message = 'Existing bookmark, did not overwrite with new values'
|
||||||
return redirect(url_for('editbookmark', userkey=userkey, urlhash=bookmark.url_hash, message=message))
|
return RedirectResponse(request.url_for('editbookmark', userkey=userkey, urlhash=bookmark.url_hash, message=message))
|
||||||
elif url:
|
elif url:
|
||||||
# Existing bookmark, get from DB
|
# Existing bookmark, get from DB
|
||||||
bookmark = Bookmark.get(Bookmark.userkey == userkey, Bookmark.url_hash == urlhash)
|
bookmark = Bookmark.get(Bookmark.userkey == userkey, Bookmark.url_hash == urlhash)
|
||||||
@@ -777,34 +681,34 @@ def updatebookmark(userkey, urlhash=None):
|
|||||||
|
|
||||||
@app.route('/<userkey>/adding', methods=['GET', 'POST'])
|
@app.route('/<userkey>/adding', methods=['GET', 'POST'])
|
||||||
#@app.route('/<userkey>/adding')
|
#@app.route('/<userkey>/adding')
|
||||||
def addingbookmark(userkey):
|
def addingbookmark(request: Request, userkey):
|
||||||
""" Add the bookmark from form submit by /add """
|
""" Add the bookmark from form submit by /add """
|
||||||
tags = get_cached_tags(userkey)
|
tags = get_cached_tags(userkey)
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
bookmark = updatebookmark(userkey)
|
bookmark = updatebookmark(request, userkey)
|
||||||
if not bookmark:
|
if not bookmark:
|
||||||
return redirect(url_for('addbookmark', userkey=userkey, message='No url provided', tags=tags))
|
return RedirectResponse(request.url_for('addbookmark', userkey=userkey, message='No url provided', tags=tags))
|
||||||
if type(bookmark).__name__ == 'Response':
|
if type(bookmark).__name__ == 'Response':
|
||||||
return bookmark
|
return bookmark
|
||||||
all_tags[userkey] = get_tags_for_user(userkey)
|
all_tags[userkey] = get_tags_for_user(userkey)
|
||||||
return redirect(url_for('editbookmark', userkey=userkey, urlhash=bookmark.url_hash))
|
return RedirectResponse(request.url_for('editbookmark', userkey=userkey, urlhash=bookmark.url_hash))
|
||||||
return redirect(url_for('addbookmark', userkey=userkey, tags=tags))
|
return RedirectResponse(request.url_for('addbookmark', userkey=userkey, tags=tags))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/<urlhash>/editing', methods=['GET', 'POST'])
|
@app.route('/<userkey>/<urlhash>/editing', methods=['GET', 'POST'])
|
||||||
def editingbookmark(userkey, urlhash):
|
def editingbookmark(request: Request, userkey, urlhash):
|
||||||
""" Edit the bookmark from form submit """
|
""" Edit the bookmark from form submit """
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
bookmark = updatebookmark(userkey, urlhash=urlhash)
|
bookmark = updatebookmark(request, userkey, urlhash=urlhash)
|
||||||
all_tags[userkey] = get_tags_for_user(userkey)
|
all_tags[userkey] = get_tags_for_user(userkey)
|
||||||
return redirect(url_for('editbookmark', userkey=userkey, urlhash=bookmark.url_hash))
|
return RedirectResponse(request.url_for('editbookmark', userkey=userkey, urlhash=bookmark.url_hash))
|
||||||
return redirect(url_for('editbookmark', userkey=userkey, urlhash=urlhash))
|
return RedirectResponse(request.url_for('editbookmark', userkey=userkey, urlhash=urlhash))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/<urlhash>/delete', methods=['GET', 'POST'])
|
@app.route('/<userkey>/<urlhash>/delete', methods=['GET', 'POST'])
|
||||||
def deletingbookmark(userkey, urlhash):
|
def deletingbookmark(request: Request, userkey, urlhash):
|
||||||
""" Delete the bookmark from form submit by <urlhash>/delete """
|
""" Delete the bookmark from form submit by <urlhash>/delete """
|
||||||
query = Bookmark.update(status=Bookmark.DELETED).where(Bookmark.userkey == userkey, Bookmark.url_hash == urlhash)
|
query = Bookmark.update(status=Bookmark.DELETED).where(Bookmark.userkey == userkey, Bookmark.url_hash == urlhash)
|
||||||
query.execute()
|
query.execute()
|
||||||
@@ -813,26 +717,26 @@ def deletingbookmark(userkey, urlhash):
|
|||||||
Bookmark.url_hash == urlhash
|
Bookmark.url_hash == urlhash
|
||||||
)
|
)
|
||||||
query.execute()
|
query.execute()
|
||||||
message = 'Bookmark deleted. <a href="{}">Undo deletion</a>'.format(url_for(
|
message = 'Bookmark deleted. <a href="{}">Undo deletion</a>'.format(request.url_for(
|
||||||
'undeletebookmark',
|
'undeletebookmark',
|
||||||
userkey=userkey,
|
userkey=userkey,
|
||||||
urlhash=urlhash
|
urlhash=urlhash
|
||||||
))
|
))
|
||||||
all_tags[userkey] = get_tags_for_user(userkey)
|
all_tags[userkey] = get_tags_for_user(userkey)
|
||||||
return redirect(url_for('bookmarks_page', userkey=userkey, message=message))
|
return RedirectResponse(request.url_for('bookmarks_page', userkey=userkey, message=message))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/<urlhash>/undelete')
|
@app.get('/<userkey>/<urlhash>/undelete')
|
||||||
def undeletebookmark(userkey, urlhash):
|
def undeletebookmark(request: Request, userkey, urlhash):
|
||||||
""" Undo deletion of the bookmark identified by urlhash """
|
""" Undo deletion of the bookmark identified by urlhash """
|
||||||
query = Bookmark.update(status=Bookmark.VISIBLE).where(Bookmark.userkey == userkey, Bookmark.url_hash == urlhash)
|
query = Bookmark.update(status=Bookmark.VISIBLE).where(Bookmark.userkey == userkey, Bookmark.url_hash == urlhash)
|
||||||
query.execute()
|
query.execute()
|
||||||
message = 'Bookmark restored'
|
message = 'Bookmark restored'
|
||||||
all_tags[userkey] = get_tags_for_user(userkey)
|
all_tags[userkey] = get_tags_for_user(userkey)
|
||||||
return redirect(url_for('bookmarks_page', userkey=userkey, message=message))
|
return RedirectResponse(request.url_for('bookmarks_page', userkey=userkey, message=message))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/tags')
|
@app.get('/<userkey>/tags', response_class=HTMLResponse)
|
||||||
def tags_page(userkey):
|
def tags_page(userkey):
|
||||||
""" Overview of all tags used by user """
|
""" Overview of all tags used by user """
|
||||||
tags = get_cached_tags(userkey)
|
tags = get_cached_tags(userkey)
|
||||||
@@ -858,7 +762,7 @@ def tags_page(userkey):
|
|||||||
totalnotes = Bookmark.select().where(Bookmark.userkey == userkey, Bookmark.note != '').count()
|
totalnotes = Bookmark.select().where(Bookmark.userkey == userkey, Bookmark.note != '').count()
|
||||||
totalhttperrorstatus = Bookmark.select().where(Bookmark.userkey == userkey, Bookmark.http_status != 200).count()
|
totalhttperrorstatus = Bookmark.select().where(Bookmark.userkey == userkey, Bookmark.http_status != 200).count()
|
||||||
theme = get_theme(userkey)
|
theme = get_theme(userkey)
|
||||||
return render_template(
|
return templates.TemplateResponse(
|
||||||
'tags.html',
|
'tags.html',
|
||||||
tags=alltags,
|
tags=alltags,
|
||||||
totaltags=totaltags,
|
totaltags=totaltags,
|
||||||
@@ -873,8 +777,8 @@ def tags_page(userkey):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/tag/<tag>')
|
@app.get('/<userkey>/tag/<tag>', response_class=HTMLResponse)
|
||||||
def tag_page(userkey, tag):
|
def tag_page(request: Request, userkey, tag):
|
||||||
""" Overview of all bookmarks with a certain tag """
|
""" Overview of all bookmarks with a certain tag """
|
||||||
bookmarks = Bookmark.select().where(
|
bookmarks = Bookmark.select().where(
|
||||||
Bookmark.userkey == userkey,
|
Bookmark.userkey == userkey,
|
||||||
@@ -891,7 +795,7 @@ def tag_page(userkey, tag):
|
|||||||
publictag = None
|
publictag = None
|
||||||
|
|
||||||
theme = get_theme(userkey)
|
theme = get_theme(userkey)
|
||||||
return render_template(
|
return templates.TemplateResponse(
|
||||||
'bookmarks.html',
|
'bookmarks.html',
|
||||||
bookmarks=bookmarks,
|
bookmarks=bookmarks,
|
||||||
userkey=userkey,
|
userkey=userkey,
|
||||||
@@ -917,14 +821,15 @@ def get_publictag(tagkey):
|
|||||||
return this_tag, bookmarks
|
return this_tag, bookmarks
|
||||||
|
|
||||||
|
|
||||||
@app.route('/pub/<tagkey>')
|
@app.get('/pub/<tagkey>', response_class=HTMLResponse)
|
||||||
def publictag_page(tagkey):
|
def publictag_page(tagkey):
|
||||||
""" Read-only overview of the bookmarks in the userkey/tag of this PublicTag """
|
""" Read-only overview of the bookmarks in the userkey/tag of this PublicTag """
|
||||||
#this_tag = get_object_or_404(PublicTag.select().where(PublicTag.tagkey == tagkey))
|
#this_tag = get_object_or_404(PublicTag.select().where(PublicTag.tagkey == tagkey))
|
||||||
try:
|
try:
|
||||||
this_tag, bookmarks = get_publictag(tagkey)
|
this_tag, bookmarks = get_publictag(tagkey)
|
||||||
theme = themes[DEFAULT_THEME]
|
# theme = themes[DEFAULT_THEME]
|
||||||
return render_template(
|
theme = {}
|
||||||
|
return templates.TemplateResponse(
|
||||||
'publicbookmarks.html',
|
'publicbookmarks.html',
|
||||||
bookmarks=bookmarks,
|
bookmarks=bookmarks,
|
||||||
tag=this_tag.tag,
|
tag=this_tag.tag,
|
||||||
@@ -933,7 +838,7 @@ def publictag_page(tagkey):
|
|||||||
theme=theme
|
theme=theme
|
||||||
)
|
)
|
||||||
except PublicTag.DoesNotExist:
|
except PublicTag.DoesNotExist:
|
||||||
abort(404)
|
raise HTTPException(status_code=404, detail='Public tag not found')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/api/v1/pub/<tagkey>')
|
@app.route('/api/v1/pub/<tagkey>')
|
||||||
@@ -949,9 +854,9 @@ def publictag_json(tagkey):
|
|||||||
}
|
}
|
||||||
for bookmark in bookmarks:
|
for bookmark in bookmarks:
|
||||||
result['items'].append(bookmark.to_dict())
|
result['items'].append(bookmark.to_dict())
|
||||||
return jsonify(result)
|
return result
|
||||||
except PublicTag.DoesNotExist:
|
except PublicTag.DoesNotExist:
|
||||||
abort(404)
|
raise HTTPException(status_code=404, detail='Public tag not found')
|
||||||
|
|
||||||
|
|
||||||
@app.get('/pub/<tagkey>/feed')
|
@app.get('/pub/<tagkey>/feed')
|
||||||
@@ -969,7 +874,7 @@ async def publictag_feed(request: Request, tagkey: str):
|
|||||||
feed.title(this_tag.tag)
|
feed.title(this_tag.tag)
|
||||||
feed.id(request.url)
|
feed.id(request.url)
|
||||||
feed.link(href=request.url, rel='self')
|
feed.link(href=request.url, rel='self')
|
||||||
feed.link(href=make_external(app.url_path_for('publictag_page', tagkey=tagkey)))
|
feed.link(href=make_external(request, app.url_path_for('publictag_page', tagkey=tagkey)))
|
||||||
|
|
||||||
for bookmark in bookmarks:
|
for bookmark in bookmarks:
|
||||||
entry = feed.add_entry()
|
entry = feed.add_entry()
|
||||||
@@ -1027,11 +932,12 @@ async def addpublictag(userkey: str, tag: str):
|
|||||||
|
|
||||||
|
|
||||||
@app.route('/<userkey>/<tag>/removepublic/<tagkey>', methods=['GET', 'POST'])
|
@app.route('/<userkey>/<tag>/removepublic/<tagkey>', methods=['GET', 'POST'])
|
||||||
def removepublictag(userkey, tag, tagkey):
|
def removepublictag(request: Request, userkey, tag, tagkey):
|
||||||
q = PublicTag.delete().where(PublicTag.userkey == userkey, PublicTag.tag == tag, PublicTag.tagkey == tagkey)
|
q = PublicTag.delete().where(PublicTag.userkey == userkey, PublicTag.tag == tag, PublicTag.tagkey == tagkey)
|
||||||
q.execute()
|
q.execute()
|
||||||
message = 'Public link deleted'
|
message = f'Public link {tagkey} has been deleted'
|
||||||
return redirect(url_for('tag_page', userkey=userkey, tag=tag, message=message))
|
url = request.url_for('tag_page', userkey=userkey, tag=tag)
|
||||||
|
return {'message': message, 'url': url}
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<systemkey>/adduser')
|
@app.route('/<systemkey>/adduser')
|
||||||
@@ -1043,9 +949,9 @@ def adduser(systemkey):
|
|||||||
newuser.username = 'Nomen Nescio'
|
newuser.username = 'Nomen Nescio'
|
||||||
newuser.save()
|
newuser.save()
|
||||||
all_tags[newuser.key] = []
|
all_tags[newuser.key] = []
|
||||||
return redirect('/{}'.format(newuser.key.decode("utf-8")), code=302)
|
return {'user': f'/{newuser.key.decode("utf-8")}'}
|
||||||
else:
|
else:
|
||||||
abort(404)
|
raise HTTPException(status_code=404, detail='I can''t let you do that Dave')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<systemkey>/refreshfavicons')
|
@app.route('/<systemkey>/refreshfavicons')
|
||||||
@@ -1056,14 +962,14 @@ def refreshfavicons(systemkey):
|
|||||||
for bookmark in bookmarks:
|
for bookmark in bookmarks:
|
||||||
if bookmark.favicon:
|
if bookmark.favicon:
|
||||||
try:
|
try:
|
||||||
filename = os.path.join(MEDIA_ROOT, 'favicons/' + bookmark.favicon)
|
filename = os.path.join(settings.media_dir, 'favicons', bookmark.favicon)
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
print(e)
|
print(e)
|
||||||
bookmark.set_favicon()
|
bookmark.set_favicon()
|
||||||
return redirect('/')
|
return {'message': 'Done refreshing icons'}
|
||||||
else:
|
else:
|
||||||
abort(404)
|
raise HTTPException(status_code=404, detail='I can''t let you do that Dave')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<systemkey>/findmissingfavicons')
|
@app.route('/<systemkey>/findmissingfavicons')
|
||||||
@@ -1073,7 +979,7 @@ def findmissingfavicons(systemkey):
|
|||||||
bookmarks = Bookmark.select()
|
bookmarks = Bookmark.select()
|
||||||
for bookmark in bookmarks:
|
for bookmark in bookmarks:
|
||||||
try:
|
try:
|
||||||
if not bookmark.favicon or not os.path.isfile(os.path.join(MEDIA_ROOT, 'favicons/' + bookmark.favicon)):
|
if not bookmark.favicon or not os.path.isfile(os.path.join(settings.media_dir, 'favicons', bookmark.favicon)):
|
||||||
# This favicon is missing
|
# This favicon is missing
|
||||||
# Clear favicon, so fallback can be used instead of showing a broken image
|
# Clear favicon, so fallback can be used instead of showing a broken image
|
||||||
bookmark.favicon = None
|
bookmark.favicon = None
|
||||||
@@ -1083,9 +989,9 @@ def findmissingfavicons(systemkey):
|
|||||||
bookmark.save()
|
bookmark.save()
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
print(e)
|
print(e)
|
||||||
return redirect('/')
|
return {'message': 'Done finding missing icons'}
|
||||||
else:
|
else:
|
||||||
abort(404)
|
raise HTTPException(status_code=404, detail='I can''t let you do that Dave')
|
||||||
|
|
||||||
|
|
||||||
# Initialisation == create the bookmark, user and public tag tables if they do not exist
|
# Initialisation == create the bookmark, user and public tag tables if they do not exist
|
||||||
|
|||||||
Reference in New Issue
Block a user