Merge branch 'master' of mara.ddp.net:photoassistant

This commit is contained in:
2021-01-11 11:31:21 +11:00
5 changed files with 95 additions and 42 deletions

View File

@@ -23,6 +23,15 @@ from settings import Settings
################################################################################
# Utility Functions for Files
################################################################################
# Converts linux paths into windows paths
# HACK: assumes c:, might be best to just look for [a-z]: ?
def FixPath(p):
if p.startswith('c:'):
p = p.replace('/', '\\')
return p
# Returns an md5 hash of the fnames' contents
def md5(fname):
hash_md5 = hashlib.md5()
with open(fname, "rb") as f:
@@ -62,46 +71,33 @@ def getExif(file):
return fthumbnail
################################################################################
# Class describing Photos in the database, and via sqlalchemy, connected to the DB as well
################################################################################
class FileData():
def __init__(self):
self.view_path=''
self.view_list=[]
self.symlink=''
# photos might not be the best name... more than just photos live in this class currently
class Photos(db.Model):
id = db.Column(db.Integer, db.Sequence('photos_id_seq'), primary_key=True )
name = db.Column(db.String, unique=True, nullable=False )
type = db.Column(db.String, unique=False, nullable=False)
size_mb = db.Column(db.Integer, unique=False, nullable=False)
# hash might not be unique, this could be the source of dupe problems
hash = db.Column(db.Integer, unique=True, nullable=True)
thumbnail = db.Column(db.LargeBinary, unique=False, nullable=True)
def __repr__(self):
return "<id: {}, name: {}>".format(self.id, self.name )
################################################################################
# /photos -> show photos from import_path(s)
################################################################################
@app.route("/photos", methods=["GET"])
def photos():
#
# HACK: At present this only handles one path (need to re-factor if we have
# multiple valid paths in import_path)
#
def GenerateFileData():
sets = Settings.query.filter(Settings.name=="import_path").all()
paths= sets[0].value.split("#")
file_list=[]
view_list=[]
view_path=""
fdata = FileData()
for p in paths:
if p.startswith('c:'):
p = p.replace('/', '\\')
if( os.path.exists( p ) ):
view_path = p
p = FixPath(p)
if os.path.exists( p ):
if p.startswith('c:'):
symlink = 'static\\{}'.format( os.path.basename(p[0:-1]))
else:
symlink = 'static/{}'.format( os.path.basename(p[0:-1]))
if not os.path.exists(symlink):
os.symlink(p, symlink)
file_list.append(glob.glob(view_path + '**', recursive=True))
fdata.view_path = p
# to serve static content of the images, we create a symlink
# from inside the static subdir of each import_path that exists
fdata.symlink = FixPath('static/{}'.format( os.path.basename(p[0:-1])))
if not os.path.exists(fdata.symlink):
os.symlink(p, fdata.symlink)
file_list.append(glob.glob(fdata.view_path + '**', recursive=True))
for file in file_list[0]:
fthumbnail = None
if file == p:
@@ -123,13 +119,43 @@ def photos():
fsize = round(os.stat(file).st_size/(1024*1024))
fname=file.replace(p, "")
# tmp_photo=Photos( name=fname, type=ftype, size_mb=fsize, hash=fhash )
# db.session.add(tmp_photo)
view_list.append( Photos( name=fname, type=ftype, size_mb=fsize, hash=fhash, thumbnail=fthumbnail ))
view_list.append( Files( name=fname, type=ftype, size_mb=fsize, hash=fhash, thumbnail=fthumbnail ))
fdata.view_list = view_list
return fdata
# db.session.commit()
################################################################################
# Class describing Files in the database, and via sqlalchemy, connected to the DB as well
# This has to match one-for-one the DB table
################################################################################
class Files(db.Model):
id = db.Column(db.Integer, db.Sequence('files_id_seq'), primary_key=True )
name = db.Column(db.String, unique=True, nullable=False )
type = db.Column(db.String, unique=False, nullable=False)
size_mb = db.Column(db.Integer, unique=False, nullable=False)
# hash might not be unique, this could be the source of dupe problems
hash = db.Column(db.Integer, unique=True, nullable=True)
thumbnail = db.Column(db.LargeBinary, unique=False, nullable=True)
def __repr__(self):
return "<id: {}, name: {}>".format(self.id, self.name )
################################################################################
# /file_list -> show detailed file list of files from import_path(s)
################################################################################
@app.route("/file_list", methods=["GET"])
def file_list():
file_data=GenerateFileData()
return render_template("file_list.html", page_title='View Files (details)', file_data=file_data, alert=st.GetAlert(), message=st.GetMessage() )
################################################################################
# /files -> show thumbnail view of files from import_path(s)
################################################################################
@app.route("/files", methods=["GET"])
def files():
file_data=GenerateFileData()
return render_template("files.html", page_title='View Files', file_data=file_data, alert=st.GetAlert(), message=st.GetMessage() )
return render_template("photos.html", page_title='View Photos', view_path=view_path, file_list=view_list, symlink=symlink, alert=st.GetAlert(), message=st.GetMessage() )
@app.route("/static/<filename>")
def custom_static(filename):

View File

@@ -28,7 +28,7 @@ Bootstrap(app)
################################# Now, import non-book classes ###################################
from settings import Settings
from photos import Photos
from files import Files
####################################### GLOBALS #######################################
# allow jinja2 to call these python functions directly

View File

@@ -43,9 +43,9 @@
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav mr-auto">
<div class="nav-item dropdown">
<a class="nav-item dropdown nav-link dropdown-toggle" href="#" id="PhotoMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Photos</a>
<div class="dropdown-menu" aria-labelledby="PhotoMenu">
<a class="dropdown-item" href="{{url_for('photos')}}">View...</a>
<a class="nav-item dropdown nav-link dropdown-toggle" href="#" id="FileMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Files</a>
<div class="dropdown-menu" aria-labelledby="FileMenu">
<a class="dropdown-item" href="{{url_for('file_list')}}">View Details</a>
</div>
</div class="nav-item dropdown">
<div class="nav-item dropdown">

27
templates/file_list.html Normal file
View File

@@ -0,0 +1,27 @@
{% extends "base.html" %} {% block main_content %}
<div class="container">
<h3 class="offset-lg-2">{{page_title}} -- {{file_data.view_path}}</h3>
<div class="row">
<table class="table table table-sm col-xl-12">
<thead><tr class="thead-light"><th>Name</th><th>Size (MB)</th><th>Hash</th></tr></thead><tbody>
{% for obj in file_data.view_list %}
<tr><td>
{% if obj.type=="Directory" %}
<i class="fas fa-folder"></i>
{% elif obj.type=="Image" %}
<i class="fas fa-file-image"></i>
{% elif obj.type=="Video" %}
<i class="fas fa-file-video"></i>
{% else %}
<i class="fas fa-question-circle"></i>
{% endif %}
{% if obj.type=="Image" %}
<a href="{{file_data.symlink}}/{{obj.name}}"><img width="128" height="128" src="data:image/jpeg;base64,{{obj.thumbnail}}"></img></a>
{% endif %}
{{obj.name}}
</td></td><td>{{obj.size_mb}}</td><td>{{obj.hash}}</tr>
{% endfor %}
</tbody></table>
</div class="row">
</div class="container">
{% endblock main_content %}