checkpoint

master
voussoir 2016-11-27 01:06:11 -08:00
parent df028c2354
commit 45a8a8ccc5
11 changed files with 134 additions and 70 deletions

View File

@ -3,6 +3,7 @@ from flask import request
import functools import functools
import time import time
import uuid import uuid
import warnings
def _generate_session_token(): def _generate_session_token():
token = str(uuid.uuid4()) token = str(uuid.uuid4())
@ -38,7 +39,7 @@ def not_implemented(function):
def time_me(function): def time_me(function):
''' '''
Decorator. After the function is run, print the elapsed time. After the function is run, print the elapsed time.
''' '''
@functools.wraps(function) @functools.wraps(function)
def timed_function(*args, **kwargs): def timed_function(*args, **kwargs):

View File

@ -194,6 +194,7 @@ def get_album_html(albumid):
'album.html', 'album.html',
album=album, album=album,
photos=album['photos'], photos=album['photos'],
view=request.args.get('view', 'grid'),
) )
return response return response
@ -403,6 +404,9 @@ def get_search_core():
view = request.args.get('view', 'grid') view = request.args.get('view', 'grid')
search_kwargs['view'] = view search_kwargs['view'] = view
search_kwargs['extension'] = extension_string
search_kwargs['extension_not'] = extension_not_string
search_kwargs['mimetype'] = mimetype_string
final_results = { final_results = {
'next_page_url': next_page_url, 'next_page_url': next_page_url,
@ -604,4 +608,5 @@ def post_edit_tags():
if __name__ == '__main__': if __name__ == '__main__':
site.run(threaded=True) #site.run(threaded=True)
pass

View File

@ -1,5 +1,5 @@
from gevent import monkey import gevent.monkey
monkey.patch_all() gevent.monkey.patch_all()
import etiquette import etiquette
import gevent.pywsgi import gevent.pywsgi
@ -13,13 +13,17 @@ else:
if port == 443: if port == 443:
http = gevent.pywsgi.WSGIServer( http = gevent.pywsgi.WSGIServer(
('', port), listener=('', port),
etiquette.site, application=etiquette.site,
keyfile='https\\etiquette.key', keyfile='C:\\git\\etiquette\\etiquette\\https\\etiquette.key',
certfile='https\\etiquette.crt', certfile='C:\\git\\etiquette\\etiquette\\https\\etiquette.crt',
) )
else: else:
http = gevent.wsgi.WSGIServer(('', port), etiquette.site) http = gevent.pywsgi.WSGIServer(
listener=('', port),
application=etiquette.site,
)
print('Starting server') print('Starting server')
http.serve_forever() http.serve_forever()

View File

@ -44,7 +44,7 @@ except converter.ffmpeg.FFMpegError:
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
logging.getLogger("PIL.PngImagePlugin").setLevel(logging.WARNING) logging.getLogger('PIL.PngImagePlugin').setLevel(logging.WARNING)
SQL_LASTID_COLUMNS = [ SQL_LASTID_COLUMNS = [
'table', 'table',
@ -55,7 +55,7 @@ SQL_ALBUM_COLUMNS = [
'id', 'id',
'title', 'title',
'description', 'description',
'associated_directory' 'associated_directory',
] ]
SQL_PHOTO_COLUMNS = [ SQL_PHOTO_COLUMNS = [
'id', 'id',
@ -1576,14 +1576,18 @@ class Album(ObjectBase, GroupableMixin):
log.debug('Committing - add photo to album') log.debug('Committing - add photo to album')
self.photodb.commit() self.photodb.commit()
def add_tag_to_all(self, tag, nested_children=True): def add_tag_to_all(self, tag, nested_children=True, commit=True):
tag = self.photodb.get_tag(tag) tag = self.photodb.get_tag(tag)
if nested_children: if nested_children:
photos = self.walk_photos() photos = self.walk_photos()
else: else:
photos = self.photos() photos = self.photos()
for photo in photos: for photo in photos:
photo.add_tag(tag) photo.add_tag(tag, commit=False)
if commit:
log.debug('Committing - add tag to all')
self.photodb.commit()
def delete(self, delete_children=False, commit=True): def delete(self, delete_children=False, commit=True):
log.debug('Deleting album {album:r}'.format(album=self)) log.debug('Deleting album {album:r}'.format(album=self))
@ -1673,8 +1677,12 @@ class Photo(ObjectBase):
self.duration = row_tuple[SQL_PHOTO['duration']] self.duration = row_tuple[SQL_PHOTO['duration']]
self.created = row_tuple[SQL_PHOTO['created']] self.created = row_tuple[SQL_PHOTO['created']]
self.thumbnail = row_tuple[SQL_PHOTO['thumbnail']] self.thumbnail = row_tuple[SQL_PHOTO['thumbnail']]
self.real_path = pathclass.Path(self.real_filepath)
def __reinit__(self): def __reinit__(self):
'''
Reload the row from the database and do __init__ with them.
'''
self.photodb.cur.execute('SELECT * FROM photos WHERE id == ?', [self.id]) self.photodb.cur.execute('SELECT * FROM photos WHERE id == ?', [self.id])
row = self.photodb.cur.fetchone() row = self.photodb.cur.fetchone()
self.__init__(self.photodb, row) self.__init__(self.photodb, row)
@ -1915,45 +1923,51 @@ class Photo(ObjectBase):
If `move` is True, allow this operation to move the file. If `move` is True, allow this operation to move the file.
Otherwise, slashes will be considered an error. Otherwise, slashes will be considered an error.
''' '''
current_dir = os.path.normcase(os.path.dirname(self.real_filepath)) old_path = self.real_path
old_path.correct_case()
new_filename = normalize_filepath(new_filename) new_filename = normalize_filepath(new_filename)
new_dir = os.path.normcase(os.path.dirname(new_filename)) if os.path.dirname(new_filename) == '':
if new_dir == '': new_path = old_path.parent.with_child(new_filename)
new_dir = current_dir
new_abspath = os.path.join(new_dir, new_filename)
else: else:
new_abspath = os.path.abspath(new_filename) new_path = pathclass.Path(new_filename)
new_dir = os.path.normcase(os.path.dirname(new_abspath)) new_path.correct_case()
if (new_dir != current_dir) and not move:
log.debug(old_path)
log.debug(new_path)
if (new_path.parent != old_path.parent) and not move:
raise ValueError('Cannot move the file without param move=True') raise ValueError('Cannot move the file without param move=True')
os.makedirs(new_dir, exist_ok=True) if new_path.absolute_path == old_path.absolute_path:
new_basename = os.path.basename(new_abspath) raise ValueError('The new and old names are the same')
new_abs_norm = os.path.normcase(new_abspath) os.makedirs(new_path.parent.absolute_path, exist_ok=True)
current_norm = os.path.normcase(self.real_filepath)
if new_abs_norm != current_norm: if new_path != old_path:
# This is different than the absolute == absolute check above, because this normalizes
# the paths. It's possible on case-insensitive systems to have the paths point to the
# same place while being differently cased, thus we couldn't make the intermediate link.
try: try:
os.link(self.real_filepath, new_abspath) os.link(old_path.absolute_path, new_path.absolute_path)
except OSError: except OSError:
# Happens when trying to hardlink across disks spinal.copy_file(old_path, new_path)
spinal.copy_file(self.real_filepath, new_abspath)
self.photodb.cur.execute( self.photodb.cur.execute(
'UPDATE photos SET filepath = ? WHERE filepath == ?', 'UPDATE photos SET filepath = ? WHERE filepath == ?',
[new_abspath, self.real_filepath] [new_path.absolute_path, old_path.absolute_path]
) )
if commit: if commit:
if new_abs_norm != current_norm: if new_path == old_path:
os.remove(self.real_filepath) # If they are equivalent but differently cased paths, just rename.
os.rename(old_path.absolute_path, new_path.absolute_path)
else: else:
os.rename(self.real_filepath, new_abspath) # Delete the original hardlink or copy.
os.remove(old_path.absolute_path)
log.debug('Committing - rename file') log.debug('Committing - rename file')
self.photodb.commit() self.photodb.commit()
else: else:
queue_action = {'action': os.remove, 'args': [self.real_filepath]} queue_action = {'action': os.remove, 'args': [old_path.absolute_path]}
self.photodb.on_commit_queue.append(queue_action) self.photodb.on_commit_queue.append(queue_action)
self.__reinit__() self.__reinit__()

View File

@ -6,7 +6,7 @@
<title>Album {{album["title"]}}</title> <title>Album {{album["title"]}}</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" href="/static/common.css"> <link rel="stylesheet" href="/static/common.css">
</head>
<style> <style>
#content_body #content_body
{ {
@ -14,6 +14,8 @@
display: block; display: block;
} }
</style> </style>
</head>
<body> <body>
{{header.make_header()}} {{header.make_header()}}
@ -44,14 +46,13 @@
<h3>Photos</h3> <h3>Photos</h3>
<ul> <ul>
{% for photo in photos %} {% for photo in photos %}
{{photo_card.create_photo_card(photo)}} {{photo_card.create_photo_card(photo, view=view)}}
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
</div> </div>
</body> </body>
</html>
<script type="text/javascript"> <script type="text/javascript">
function submit_tag(callback) function submit_tag(callback)
@ -60,3 +61,4 @@ function submit_tag(callback)
add_tag_box.value = ""; add_tag_box.value = "";
} }
</script> </script>
</html>

View File

@ -5,13 +5,15 @@
<title>Albums</title> <title>Albums</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" href="/static/common.css"> <link rel="stylesheet" href="/static/common.css">
</head>
<style> <style>
#content_body #content_body
{ {
flex-direction: column; flex-direction: column;
} }
</style> </style>
</head>
<body> <body>
{{header.make_header()}} {{header.make_header()}}
@ -26,8 +28,8 @@
{% endfor %} {% endfor %}
</div> </div>
</body> </body>
</html>
<script type="text/javascript"> <script type="text/javascript">
</script> </script>
</html>

View File

@ -9,7 +9,7 @@
{% set filename = photo["id"] + "." + photo["extension"] %} {% set filename = photo["id"] + "." + photo["extension"] %}
{% set link = "/file/" + filename %} {% set link = "/file/" + filename %}
{% set mimetype=photo["mimetype"] %} {% set mimetype=photo["mimetype"] %}
</head>
<style> <style>
#content_body #content_body
{ {
@ -83,6 +83,8 @@
width: 100%; width: 100%;
} }
</style> </style>
</head>
<body> <body>
{{header.make_header()}} {{header.make_header()}}
@ -150,7 +152,7 @@
</div> </div>
</div> </div>
</body> </body>
</html>
<script type="text/javascript"> <script type="text/javascript">
var add_tag_box = document.getElementById('add_tag_textbox'); var add_tag_box = document.getElementById('add_tag_textbox');
@ -186,6 +188,7 @@ function disable_hoverzoom()
div.style.backgroundImage = "none"; div.style.backgroundImage = "none";
div.onmousemove = null; div.onmousemove = null;
div.onclick = null; div.onclick = null;
add_tag_box.focus();
} }
function toggle_hoverzoom() function toggle_hoverzoom()
{ {
@ -199,30 +202,39 @@ function toggle_hoverzoom()
enable_hoverzoom(); enable_hoverzoom();
} }
} }
photo_img_holder = document.getElementById("photo_img_holder");
photo_img = document.getElementById("photo_img");
function move_hoverzoom(event) function move_hoverzoom(event)
{ {
div = document.getElementById("photo_img_holder");
img = document.getElementById("photo_img");
var x; var x;
var y; var y;
if (img.naturalWidth < div.offsetWidth) var mouse_x = event.offsetX;
mouse_x -= (photo_img_holder.offsetWidth / 2);
mouse_x *= 1.05;
mouse_x += (photo_img_holder.offsetWidth / 2);
var mouse_y = event.offsetY;
mouse_y -= (photo_img_holder.offsetHeight / 2);
mouse_y *= 1.05;
mouse_y += (photo_img_holder.offsetHeight / 2);
if (photo_img.naturalWidth < photo_img_holder.offsetWidth)
{ {
x = (img.naturalWidth - div.offsetWidth) / 2; x = (photo_img.naturalWidth - photo_img_holder.offsetWidth) / 2;
} }
else else
{ {
x = (img.naturalWidth - div.offsetWidth) * (event.offsetX / div.offsetWidth); x = (photo_img.naturalWidth - photo_img_holder.offsetWidth) * (mouse_x / photo_img_holder.offsetWidth);
} }
if (img.naturalHeight < div.offsetHeight) if (photo_img.naturalHeight < photo_img_holder.offsetHeight)
{ {
y = (img.naturalHeight - div.offsetHeight) / 2; y = (photo_img.naturalHeight - photo_img_holder.offsetHeight) / 2;
} }
else else
{ {
y = (img.naturalHeight - div.offsetHeight) * (event.offsetY / div.offsetHeight); y = (photo_img.naturalHeight - photo_img_holder.offsetHeight) * (mouse_y / photo_img_holder.offsetHeight);
} }
//console.log(x); //console.log(x);
div.style.backgroundPosition=(-x)+"px "+(-y)+"px"; photo_img_holder.style.backgroundPosition=(-x)+"px "+(-y)+"px";
} }
function receive_callback(response) function receive_callback(response)
{ {
@ -253,3 +265,4 @@ function submit_tag(callback)
add_tag_box.value = ""; add_tag_box.value = "";
} }
</script> </script>
</html>

View File

@ -1,5 +1,9 @@
<!DOCTYPE html5> <!DOCTYPE html5>
<html> <html>
<head>
<title>Etiquette</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/common.css">
<style> <style>
body, a body, a
@ -21,13 +25,9 @@ a:hover
background-color: #ffffd4; background-color: #ffffd4;
} }
</style> </style>
<head>
<title>Etiquette</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/common.css">
</head> </head>
<body> <body>
<span>{{motd}}</span> <span>{{motd}}</span>
<a href="/search">Search</a> <a href="/search">Search</a>
@ -35,10 +35,7 @@ a:hover
<a href="/albums">Browse albums</a> <a href="/albums">Browse albums</a>
</body> </body>
</html>
<script type="text/javascript"> <script type="text/javascript">
</script> </script>
</html>

View File

@ -7,7 +7,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" href="/static/common.css"> <link rel="stylesheet" href="/static/common.css">
<script src="/static/common.js"></script> <script src="/static/common.js"></script>
</head>
<style> <style>
form form
{ {
@ -114,6 +114,8 @@ form
<button class="remove_tag_button_perm" onclick="orderby_remove_hook(this);"></button> <button class="remove_tag_button_perm" onclick="orderby_remove_hook(this);"></button>
</li> </li>
{% endmacro %} {% endmacro %}
</head>
<body> <body>
{{header.make_header()}} {{header.make_header()}}
@ -244,7 +246,6 @@ form
</div> </div>
</div> </div>
</body> </body>
</html>
<script type="text/javascript"> <script type="text/javascript">
@ -526,3 +527,4 @@ input_mays.onkeydown = function(){tag_input_hook(this, inputted_mays, "search_bu
input_forbids.onkeydown = function(){tag_input_hook(this, inputted_forbids, "search_builder_forbids_inputted")}; input_forbids.onkeydown = function(){tag_input_hook(this, inputted_forbids, "search_builder_forbids_inputted")};
bind_box_to_button(input_expression, document.getElementById("search_go_button")); bind_box_to_button(input_expression, document.getElementById("search_go_button"));
</script> </script>
</html>

View File

@ -6,7 +6,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" href="/static/common.css"> <link rel="stylesheet" href="/static/common.css">
<script src="/static/common.js"></script> <script src="/static/common.js"></script>
</head>
<style> <style>
body body
{ {
@ -55,6 +55,8 @@ body
align-items: center; align-items: center;
} }
</style> </style>
</head>
<body> <body>
{{header.make_header()}} {{header.make_header()}}
@ -84,8 +86,6 @@ body
</div> </div>
</body> </body>
</html>
<script type="text/javascript"> <script type="text/javascript">
var box = document.getElementById('add_tag_textbox'); var box = document.getElementById('add_tag_textbox');
@ -143,3 +143,4 @@ function submit_tag(callback)
box.value = ""; box.value = "";
} }
</script> </script>
</html>

View File

@ -0,0 +1,23 @@
<!DOCTYPE html5>
<html>
<head>
{% import "header.html" as header %}
<title>Flasksite</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/common.css">
<style>
</style>
</head>
<body>
<div id="content_body">
<p>test</p>
</div>
</body>
<script type="text/javascript">
</script>
</html>