mirror of
https://github.com/aquatix/digimarks.git
synced 2025-12-06 22:05:09 +01:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| abf9141019 | |||
|
|
8ca54bf364 | ||
| 0be05d07e9 | |||
| a66360a0e3 | |||
| 1545c17472 | |||
| dd0a9d8283 | |||
| 652e3a89af | |||
| 133a139b79 | |||
| b556978640 | |||
| 8bb9e11088 | |||
| 85e94b71e5 | |||
| a895774001 | |||
| 7598ba6a61 | |||
| c5dcf579d3 | |||
| 590095659e | |||
| d5d71b4f51 | |||
| 7f2da49d26 | |||
| 0f0e4e03c3 | |||
| 044f507aa2 | |||
| b0da3a4454 | |||
| 17e1db12bf | |||
| 480f27797f | |||
| 1729ecd540 | |||
| d54b26dafb | |||
| 2c76ffaf12 | |||
| e54a033984 | |||
| 4e0d89c25e | |||
| 30e4f74ed9 | |||
| 1beadb676c | |||
| eea63398ba | |||
| d5021fd7c4 | |||
| c03d0c2458 | |||
| ff08ea4930 | |||
| 2e9457ee1a | |||
| 63dd636c25 | |||
| 412b4a93c7 | |||
| abdc11361a | |||
|
|
7a98de4b3f | ||
|
|
59f5365edc | ||
|
|
b0aedcd6e4 | ||
| 6b61e43c5d | |||
|
|
570af2d62e | ||
|
|
8a19df2741 | ||
|
|
9e6d67a0ff |
39
CHANGELOG.md
39
CHANGELOG.md
@@ -1,3 +1,10 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
|
||||
## TODO
|
||||
|
||||
- Sorting of bookmarks
|
||||
@@ -10,9 +17,29 @@
|
||||
- Look into compatibility with del.icio.us, so we can make use of existing browser integration
|
||||
|
||||
|
||||
## v1.0.0
|
||||
## [Unreleased]
|
||||
|
||||
2016-12-29
|
||||
|
||||
## [1.1.0] - 2017-07-22
|
||||
|
||||
### Added
|
||||
- Show 404 page if bookmark is not found when editing
|
||||
- Cache buster to force loading of the latest styling
|
||||
- Theming support, default is 'green'
|
||||
- Themes need an extra `theme` field in the User table
|
||||
|
||||
### Changed
|
||||
- Make running in a virtualenv optional
|
||||
- Fix for misalignment and size of hamburger icon
|
||||
- Updated Python (pip) dependencies
|
||||
- Updated MaterializeCSS and jQuery
|
||||
|
||||
### Removed
|
||||
- Removed dependency on more_itertools
|
||||
- Removed dependency on utilkit
|
||||
|
||||
|
||||
## [1.0.0] - 2016-12-29
|
||||
|
||||
- json view of public tag pages, returns all items
|
||||
- feed (rss/atom) view of public tag pages, returns latest 15
|
||||
@@ -47,9 +74,7 @@
|
||||
- Updated MaterializeCSS and jQuery
|
||||
|
||||
|
||||
## v0.2.0
|
||||
|
||||
2016-08-02
|
||||
## [0.2.0] - 2016-08-02
|
||||
|
||||
- Favicon courtesy Freepik on flaticon.com
|
||||
- Tag tags for easy adding of tags
|
||||
@@ -60,9 +85,7 @@
|
||||
- Option to strip parameters from url (like '?utm_source=social')
|
||||
|
||||
|
||||
## v0.1.0
|
||||
|
||||
2016-07-26
|
||||
## [0.1.0] - 2016-07-26
|
||||
|
||||
- Initial release
|
||||
- Flask application with functionality to add users, add and edit bookmarks,
|
||||
|
||||
129
digimarks.py
129
digimarks.py
@@ -7,17 +7,72 @@ import sys
|
||||
import requests
|
||||
import shutil
|
||||
import bs4
|
||||
from more_itertools import unique_everseen
|
||||
from urlparse import urlparse, urlunparse, urljoin
|
||||
|
||||
from utilkit import datetimeutil
|
||||
|
||||
from flask import Flask, abort, redirect, render_template, request, url_for, jsonify
|
||||
from werkzeug.contrib.atom import AtomFeed
|
||||
from flask_peewee.db import Database
|
||||
#from flask_peewee.utils import get_object_or_404
|
||||
from peewee import * # noqa
|
||||
|
||||
DEFAULT_THEME = 'green'
|
||||
themes = {
|
||||
'green': {
|
||||
'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',
|
||||
'CARD_BACKGROUND': 'green darken-3',
|
||||
'CARD_TEXT': 'white-text',
|
||||
'FAB': 'red',
|
||||
|
||||
'STAR': 'yellow-text',
|
||||
'PROBLEM': 'red-text',
|
||||
'COMMENT': '',
|
||||
},
|
||||
'freshgreen': {
|
||||
'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',
|
||||
'CARD_BACKGROUND': 'green darken-1',
|
||||
'CARD_TEXT': 'white-text',
|
||||
'FAB': 'red',
|
||||
|
||||
'STAR': 'yellow-text',
|
||||
'PROBLEM': 'red-text',
|
||||
'COMMENT': '',
|
||||
},
|
||||
'dark': {
|
||||
'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',
|
||||
'CARD_BACKGROUND': 'grey darken-3',
|
||||
'CARD_TEXT': 'grey-text lighten-1',
|
||||
'FAB': 'red',
|
||||
|
||||
'STAR': 'yellow-text',
|
||||
'PROBLEM': 'red-text',
|
||||
'COMMENT': '',
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
import settings
|
||||
except ImportError:
|
||||
@@ -48,8 +103,35 @@ except AttributeError:
|
||||
|
||||
# Cache the tags
|
||||
all_tags = {}
|
||||
settings = {}
|
||||
|
||||
|
||||
def ifilterfalse(predicate, iterable):
|
||||
# ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
|
||||
if predicate is None:
|
||||
predicate = bool
|
||||
for x in iterable:
|
||||
if not predicate(x):
|
||||
yield x
|
||||
|
||||
|
||||
def unique_everseen(iterable, key=None):
|
||||
"List unique elements, preserving order. Remember all elements ever seen."
|
||||
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
|
||||
# unique_everseen('ABBCcAD', str.lower) --> A B C D
|
||||
seen = set()
|
||||
seen_add = seen.add
|
||||
if key is None:
|
||||
for element in ifilterfalse(seen.__contains__, iterable):
|
||||
seen_add(element)
|
||||
yield element
|
||||
else:
|
||||
for element in iterable:
|
||||
k = key(element)
|
||||
if k not in seen:
|
||||
seen_add(k)
|
||||
yield element
|
||||
|
||||
def clean_tags(tags_list):
|
||||
tags_res = [x.strip() for x in tags_list]
|
||||
tags_res = list(unique_everseen(tags_res))
|
||||
@@ -80,6 +162,7 @@ class User(db.Model):
|
||||
""" User account """
|
||||
username = CharField()
|
||||
key = CharField()
|
||||
theme = CharField(default=DEFAULT_THEME)
|
||||
created_date = DateTimeField(default=datetime.datetime.now)
|
||||
|
||||
def generate_key(self):
|
||||
@@ -233,7 +316,7 @@ class Bookmark(db.Model):
|
||||
result = {
|
||||
'title': self.title,
|
||||
'url': self.url,
|
||||
'created': datetimeutil.datetime_to_string(self.created_date),
|
||||
'created': self.created_date.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'url_hash': self.url_hash,
|
||||
'tags': self.tags,
|
||||
}
|
||||
@@ -269,6 +352,14 @@ def get_cached_tags(userkey):
|
||||
return []
|
||||
|
||||
|
||||
def get_theme(userkey):
|
||||
try:
|
||||
usertheme = settings[userkey]['theme']
|
||||
return themes[usertheme]
|
||||
except KeyError:
|
||||
return themes[DEFAULT_THEME] # default
|
||||
|
||||
|
||||
def make_external(url):
|
||||
return urljoin(request.url_root, url)
|
||||
|
||||
@@ -281,7 +372,8 @@ def page_not_found(e):
|
||||
@app.route('/')
|
||||
def index():
|
||||
""" Homepage, point visitors to project page """
|
||||
return render_template('index.html')
|
||||
theme = themes[DEFAULT_THEME]
|
||||
return render_template('index.html', theme=theme)
|
||||
|
||||
|
||||
@app.route('/<userkey>', methods=['GET', 'POST'])
|
||||
@@ -330,7 +422,8 @@ def bookmarks(userkey, filtermethod = None, sortmethod = None):
|
||||
else:
|
||||
bookmarks = Bookmark.select().where(Bookmark.userkey == userkey, Bookmark.status == Bookmark.VISIBLE).order_by(Bookmark.created_date.desc())
|
||||
|
||||
return render_template('bookmarks.html', bookmarks=bookmarks, userkey=userkey, tags=tags, filter_text=filter_text, message=message)
|
||||
theme = get_theme(userkey)
|
||||
return render_template('bookmarks.html', bookmarks=bookmarks, userkey=userkey, tags=tags, filter_text=filter_text, message=message, theme=theme)
|
||||
|
||||
|
||||
|
||||
@@ -353,13 +446,17 @@ def viewbookmarkjson(userkey, urlhash):
|
||||
def editbookmark(userkey, urlhash):
|
||||
""" Bookmark edit form """
|
||||
# bookmark = getbyurlhash()
|
||||
try:
|
||||
bookmark = Bookmark.get(Bookmark.url_hash == urlhash, Bookmark.userkey == userkey)
|
||||
except Bookmark.DoesNotExist:
|
||||
abort(404)
|
||||
message = request.args.get('message')
|
||||
tags = get_cached_tags(userkey)
|
||||
if not bookmark.note:
|
||||
# Workaround for when an existing bookmark has a null note
|
||||
bookmark.note = ''
|
||||
return render_template('edit.html', action='Edit bookmark', userkey=userkey, bookmark=bookmark, message=message, formaction='edit', tags=tags)
|
||||
theme = get_theme(userkey)
|
||||
return render_template('edit.html', action='Edit bookmark', userkey=userkey, bookmark=bookmark, message=message, formaction='edit', tags=tags, theme=theme)
|
||||
|
||||
|
||||
@app.route('/<userkey>/add')
|
||||
@@ -373,7 +470,8 @@ def addbookmark(userkey):
|
||||
bookmark = Bookmark(title='', url=url, tags='')
|
||||
message = request.args.get('message')
|
||||
tags = get_cached_tags(userkey)
|
||||
return render_template('edit.html', action='Add bookmark', userkey=userkey, bookmark=bookmark, tags=tags, message=message)
|
||||
theme = get_theme(userkey)
|
||||
return render_template('edit.html', action='Add bookmark', userkey=userkey, bookmark=bookmark, tags=tags, message=message, theme=theme)
|
||||
|
||||
|
||||
def updatebookmark(userkey, request, urlhash = None):
|
||||
@@ -420,7 +518,11 @@ def updatebookmark(userkey, request, urlhash = None):
|
||||
bookmark.set_status_code()
|
||||
|
||||
if bookmark.http_status == 200:
|
||||
try:
|
||||
bookmark.set_favicon()
|
||||
except IOError:
|
||||
# Icon file could not be saved possibly, don't bail completely
|
||||
pass
|
||||
|
||||
bookmark.save()
|
||||
return bookmark
|
||||
@@ -497,9 +599,10 @@ def tags(userkey):
|
||||
totaldeleted = Bookmark.select().where(Bookmark.userkey == userkey, Bookmark.status == Bookmark.DELETED).count()
|
||||
totalnotes = Bookmark.select().where(Bookmark.userkey == userkey, Bookmark.note != '').count()
|
||||
totalhttperrorstatus = Bookmark.select().where(Bookmark.userkey == userkey, Bookmark.http_status != 200).count()
|
||||
theme = get_theme(userkey)
|
||||
return render_template('tags.html', tags=alltags, totaltags=totaltags, totalpublic=totalpublic, totalbookmarks=totalbookmarks,
|
||||
totaldeleted=totaldeleted, totalstarred=totalstarred, totalhttperrorstatus=totalhttperrorstatus,
|
||||
totalnotes=totalnotes, userkey=userkey)
|
||||
totalnotes=totalnotes, userkey=userkey, theme=theme)
|
||||
|
||||
|
||||
@app.route('/<userkey>/tag/<tag>')
|
||||
@@ -515,7 +618,9 @@ def tag(userkey, tag):
|
||||
except PublicTag.DoesNotExist:
|
||||
publictag = None
|
||||
|
||||
return render_template('bookmarks.html', bookmarks=bookmarks, userkey=userkey, tags=tags, tag=tag, publictag=publictag, action=pageheader, message=message)
|
||||
theme = get_theme(userkey)
|
||||
return render_template('bookmarks.html', bookmarks=bookmarks, userkey=userkey, tags=tags, tag=tag, publictag=publictag, action=pageheader,
|
||||
message=message, theme=theme)
|
||||
|
||||
|
||||
@app.route('/pub/<tagkey>')
|
||||
@@ -525,7 +630,8 @@ def publictag(tagkey):
|
||||
try:
|
||||
this_tag = PublicTag.get(PublicTag.tagkey == tagkey)
|
||||
bookmarks = Bookmark.select().where(Bookmark.userkey == this_tag.userkey, Bookmark.tags.contains(this_tag.tag), Bookmark.status == Bookmark.VISIBLE).order_by(Bookmark.created_date.desc())
|
||||
return render_template('publicbookmarks.html', bookmarks=bookmarks, tag=tag, action=this_tag.tag, tagkey=tagkey)
|
||||
theme = themes[DEFAULT_THEME]
|
||||
return render_template('publicbookmarks.html', bookmarks=bookmarks, tag=tag, action=this_tag.tag, tagkey=tagkey, theme=theme)
|
||||
except PublicTag.DoesNotExist:
|
||||
abort(404)
|
||||
|
||||
@@ -640,6 +746,7 @@ users = User.select()
|
||||
print('Current user keys:')
|
||||
for user in users:
|
||||
all_tags[user.key] = get_tags_for_user(user.key)
|
||||
settings[user.key] = {'theme': user.theme}
|
||||
print(user.key)
|
||||
|
||||
# Run when called standalone
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Virtualenv to use with the wsgi file
|
||||
# Virtualenv to use with the wsgi file (optional)
|
||||
VENV = '/srv/marks.example.com/venv/bin/activate_this.py'
|
||||
|
||||
PORT = 8086
|
||||
|
||||
7
requirements.in
Normal file
7
requirements.in
Normal file
@@ -0,0 +1,7 @@
|
||||
pkg-resources==0.0.0
|
||||
|
||||
flask
|
||||
peewee
|
||||
flask-peewee
|
||||
bs4
|
||||
requests
|
||||
@@ -1,7 +1,24 @@
|
||||
flask
|
||||
peewee
|
||||
flask-peewee
|
||||
bs4
|
||||
more_itertools
|
||||
requests
|
||||
utilkit
|
||||
#
|
||||
# This file is autogenerated by pip-compile
|
||||
# To update, run:
|
||||
#
|
||||
# pip-compile --output-file requirements.txt requirements.in
|
||||
#
|
||||
beautifulsoup4==4.6.0 # via bs4
|
||||
bs4==0.0.1
|
||||
certifi==2017.4.17 # via requests
|
||||
chardet==3.0.4 # via requests
|
||||
click==6.7 # via flask
|
||||
flask-peewee==0.6.7
|
||||
flask==0.12.2
|
||||
idna==2.5 # via requests
|
||||
itsdangerous==0.24 # via flask
|
||||
jinja2==2.9.6 # via flask, flask-peewee
|
||||
markupsafe==1.0 # via jinja2
|
||||
peewee==2.10.1
|
||||
pkg-resources==0.0.0
|
||||
requests==2.18.1
|
||||
urllib3==1.21.1 # via requests
|
||||
werkzeug==0.12.2 # via flask, flask-peewee
|
||||
wtf-peewee==0.2.6 # via flask-peewee
|
||||
wtforms==2.1 # via flask-peewee, wtf-peewee
|
||||
|
||||
4
setup.py
4
setup.py
@@ -26,7 +26,7 @@ setup(
|
||||
# third part for minor release
|
||||
# second when api changes
|
||||
# first when it becomes stable someday
|
||||
version='1.0.0',
|
||||
version='1.1.0',
|
||||
author='Michiel Scholten',
|
||||
author_email='michiel@diginaut.net',
|
||||
|
||||
@@ -35,7 +35,7 @@ setup(
|
||||
|
||||
# as a practice no need to hard code version unless you know program wont
|
||||
# work unless the specific versions are used
|
||||
install_requires=['Flask', 'Peewee', 'Flask-Peewee', 'requests', 'utilkit'],
|
||||
install_requires=['Flask', 'Peewee', 'Flask-Peewee', 'requests'],
|
||||
|
||||
py_modules=['digimarks'],
|
||||
|
||||
|
||||
@@ -1,32 +1,48 @@
|
||||
/**
|
||||
* digimarks styling
|
||||
*/
|
||||
|
||||
/* label color */
|
||||
.input-field label {
|
||||
color: #000;
|
||||
/** Navigation **/
|
||||
|
||||
nav .button-collapse
|
||||
{
|
||||
/* Fix for misalignment of hamburger icon */
|
||||
margin: 0;
|
||||
}
|
||||
/* label focus color */
|
||||
.input-field input[type=text]:focus + label {
|
||||
color: #000;
|
||||
|
||||
nav .button-collapse i
|
||||
{
|
||||
/* Make the hamburger icon great again */
|
||||
font-size: 2.7rem;
|
||||
}
|
||||
|
||||
/** Form input fields **/
|
||||
|
||||
/* label underline focus color */
|
||||
.input-field input[type=text]:focus {
|
||||
.input-field input[type=text]:focus
|
||||
{
|
||||
border-bottom: 1px solid #000;
|
||||
box-shadow: 0 1px 0 0 #000;
|
||||
}
|
||||
/* valid color */
|
||||
.input-field input[type=text].valid {
|
||||
.input-field input[type=text].valid
|
||||
{
|
||||
border-bottom: 1px solid #000;
|
||||
box-shadow: 0 1px 0 0 #000;
|
||||
}
|
||||
/* invalid color */
|
||||
.input-field input[type=text].invalid {
|
||||
.input-field input[type=text].invalid
|
||||
{
|
||||
border-bottom: 1px solid #000;
|
||||
box-shadow: 0 1px 0 0 #000;
|
||||
}
|
||||
/* icon prefix focus color */
|
||||
.input-field .prefix.active {
|
||||
.input-field .prefix.active
|
||||
{
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/** Cards and tags **/
|
||||
|
||||
/* Card title anchor colour */
|
||||
.white-text .card-title a,
|
||||
|
||||
@@ -17,12 +17,24 @@
|
||||
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto+Mono&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css" type="text/css" rel="stylesheet" media="screen,projection"/>
|
||||
<link href="{{ url_for('static', filename='css/digimarks.css') }}" type="text/css" rel="stylesheet" media="screen,projection"/>
|
||||
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.1/css/materialize.min.css" type="text/css" rel="stylesheet" media="screen,projection"/>
|
||||
<style>
|
||||
/* label color */
|
||||
.input-field label
|
||||
{
|
||||
color: {{ theme.TEXTHEX }};
|
||||
}
|
||||
/* label focus color */
|
||||
.input-field input[type=text]:focus + label
|
||||
{
|
||||
color: {{ theme.TEXTHEX }};
|
||||
}
|
||||
</style>
|
||||
<link href="{{ url_for('static', filename='css/digimarks.css') }}?20170722" type="text/css" rel="stylesheet" media="screen,projection"/>
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
|
||||
</head>
|
||||
<body class="grey lighten-4">
|
||||
<nav class="green darken-3" role="navigation">
|
||||
<body class="{{ theme.BODY }} {{ theme.TEXT }}">
|
||||
<nav class="{{ theme.NAV }}" role="navigation">
|
||||
<div class="nav-wrapper container"><a id="logo-container" href="{% if userkey %}{{ url_for('bookmarks', userkey=userkey) }}{% else %}{{ url_for('index') }}{% endif %}" class="brand-logo">digimarks</a>
|
||||
<ul class="right hide-on-med-and-down">
|
||||
{% if userkey %}
|
||||
@@ -43,7 +55,7 @@
|
||||
</nav>
|
||||
<div class="section no-pad-bot" id="index-banner">
|
||||
<div class="container">
|
||||
<div class="header grey-text lighten-5">
|
||||
<div class="header {{ theme.PAGEHEADER }}">
|
||||
<h1>{% block pageheader %}Bookmarks{% endblock %}</h1>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,7 +68,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.1/js/materialize.min.js"></script>
|
||||
<script src="{{ url_for('static', filename='js/init.js') }}"></script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
{% if message %}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card-panel orange lighten-2">
|
||||
<span class="white-text">
|
||||
<div class="card-panel {{ theme.MESSAGE_BACKGROUND }}">
|
||||
<span class="{{ theme.MESSAGE_TEXT }}">
|
||||
{{ message|safe }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -52,13 +52,13 @@
|
||||
<div class="collapsible-header"><i class="material-icons">label</i>Filter on star/problem/comment/tag</div>
|
||||
<div class="collapsible-body" style="padding: 10px;">
|
||||
<div class="chip">
|
||||
<a href="{{ url_for('bookmarks', userkey=userkey, filtermethod='starred') }}"><i class="tiny material-icons yellow-text">star</i></a>
|
||||
<a href="{{ url_for('bookmarks', userkey=userkey, filtermethod='starred') }}"><i class="tiny material-icons {{ theme.STAR }}">star</i></a>
|
||||
</div>
|
||||
<div class="chip">
|
||||
<a href="{{ url_for('bookmarks', userkey=userkey, filtermethod='broken') }}"><i class="tiny material-icons red-text">report_problem</i></a>
|
||||
<a href="{{ url_for('bookmarks', userkey=userkey, filtermethod='broken') }}"><i class="tiny material-icons {{ theme.PROBLEM }}">report_problem</i></a>
|
||||
</div>
|
||||
<div class="chip">
|
||||
<a href="{{ url_for('bookmarks', userkey=userkey, filtermethod='note') }}"><i class="tiny material-icons">comment</i></a>
|
||||
<a href="{{ url_for('bookmarks', userkey=userkey, filtermethod='note') }}"><i class="tiny material-icons {{ theme.COMMENT }}">comment</i></a>
|
||||
</div>
|
||||
{% for tag in tags %}
|
||||
<div class="chip">
|
||||
@@ -83,29 +83,31 @@
|
||||
<p>{{ bookmark.created_date.strftime("%m/%d/%Y %H:%M") }}</p>
|
||||
</div>
|
||||
#}
|
||||
<div class="card horizontal tiny green darken-3">
|
||||
<div class="card horizontal tiny {{ theme.CARD_BACKGROUND }}">
|
||||
<div class="card-image">
|
||||
{% if bookmark.favicon %}
|
||||
<div><img src="{{ url_for('static', filename='favicons/' + bookmark.favicon) }}" class="favicon" /></div>
|
||||
{% endif %}
|
||||
{% if bookmark.http_status != 200 and bookmark.http_status != 304 %}
|
||||
<div><i class="small material-icons red-text" title="HTTP status {{ bookmark.http_status }}">report_problem</i></div>
|
||||
<div><i class="small material-icons {{ theme.PROBLEM }}" title="HTTP status {{ bookmark.http_status }}">report_problem</i></div>
|
||||
{% endif %}
|
||||
{% if bookmark.starred == True %}
|
||||
<div><i class="small material-icons yellow-text">star</i></div>
|
||||
<div><i class="small material-icons {{ theme.STAR }}">star</i></div>
|
||||
{% endif %}
|
||||
{% if bookmark.note %}
|
||||
<div><i class="small material-icons white-text" title="{{ bookmark.note|truncate(100) }}">comment</i></div>
|
||||
<div><i class="small material-icons {{ theme.CARD_TEXT }}" title="{{ bookmark.note|truncate(100) }}">comment</i></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-stacked">
|
||||
<div class="card-content white-text">
|
||||
<div class="card-content {{ theme.CARD_TEXT }}">
|
||||
<span class="digimark-card-header activator">
|
||||
<span class="digimark-card-header-tags">
|
||||
{% for tag in bookmark.tags_list %}
|
||||
<div class="chip">
|
||||
<a href="{{ url_for('tag', userkey=userkey, tag=tag) }}">{{ tag }}</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</span>
|
||||
<i class="material-icons right">more_vert</i>
|
||||
</span>
|
||||
<div class="digimark-card-content">
|
||||
@@ -119,9 +121,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-reveal green darken-3">
|
||||
<span class="card-title white-text">Added @ {{ bookmark.created_date.strftime('%Y-%m-%d %H:%M') }}<i class="material-icons right">close</i></span>
|
||||
<div class="white-text" style="padding-top: 10px;">
|
||||
<div class="card-reveal {{ theme.CARD_BACKGROUND }}">
|
||||
<span class="card-title {{ theme.CARD_TEXT }}">Added @ {{ bookmark.created_date.strftime('%Y-%m-%d %H:%M') }}<i class="material-icons right">close</i></span>
|
||||
<div class="{{ theme.CARD_TEXT }}" style="padding-top: 10px;">
|
||||
<a href="{{ url_for('editbookmark', userkey=userkey, urlhash=bookmark.url_hash) }}" style="padding: 3px"><i class="tiny material-icons">mode_edit</i> EDIT</a>
|
||||
<a href="{{ url_for('deletingbookmark', userkey=userkey, urlhash=bookmark.url_hash) }}" style="padding: 3px" class="red-text"><i class="tiny material-icons">delete</i> DELETE</a>
|
||||
</div>
|
||||
@@ -139,7 +141,7 @@
|
||||
</div>
|
||||
|
||||
<div class="fixed-action-btn" style="bottom: 20px; right: 20px;">
|
||||
<a class="btn-floating btn-large red" href="{{ url_for('addbookmark', userkey=userkey) }}">
|
||||
<a class="btn-floating btn-large {{ theme.FAB }}" href="{{ url_for('addbookmark', userkey=userkey) }}">
|
||||
<i class="large material-icons">add</i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
{% if bookmark.http_status != 200 and bookmark.http_status != 304 %}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card-panel red darken-1">
|
||||
<span class="white-text">
|
||||
<div class="card-panel {{ theme.ERRORMESSAGE_BACKGROUND }}">
|
||||
<span class="{{ theme.ERRORMESSAGE_TEXT }}">
|
||||
{% if bookmark.http_status == 404 %}
|
||||
<i class="material-icons">report_problem</i> URL not found (404), broken/outdated link?
|
||||
{% elif bookmark.http_status == 302 %}
|
||||
@@ -26,8 +26,8 @@
|
||||
{% if message %}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card-panel orange lighten-2">
|
||||
<span class="white-text">
|
||||
<div class="card-panel {{ theme.MESSAGE_BACKGROUND }}">
|
||||
<span class="{{ theme.MESSAGE_TEXT }}">
|
||||
{{ message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user