from wtforms import SubmitField, StringField, HiddenField, validators, Form from flask_wtf import FlaskForm from flask import request, render_template, redirect from main import db, app, ma from sqlalchemy import Sequence from sqlalchemy.exc import SQLAlchemyError from status import st, Status import os import glob from PIL import Image from pymediainfo import MediaInfo import hashlib import exifread import base64 import numpy ################################################################################ # Local Class imports ################################################################################ from settings import Settings ################################################################################ # Utility Functions for Files ################################################################################ def md5(fname): hash_md5 = hashlib.md5() with open(fname, "rb") as f: for chunk in iter(lambda: f.read(4096), b""): hash_md5.update(chunk) return hash_md5.hexdigest() ################################################################################ # Class describing Photos in the database, and via sqlalchemy, connected to the DB as well ################################################################################ # 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 "".format(self.id, self.name ) ################################################################################ # /photos -> show photos from import_path(s) ################################################################################ @app.route("/photos", methods=["GET"]) def photos(): sets = Settings.query.filter(Settings.name=="import_path").all() paths= sets[0].value.split("#") file_list=[] view_list=[] view_path="" for p in paths: if p.startswith('c:'): p = p.replace('/', '\\') if( os.path.exists( p ) ): view_path = p file_list.append(glob.glob(view_path + '**', recursive=True)) for file in file_list[0]: fthumbnail = None if file == p: continue if os.path.isdir(file): ftype = 'Directory' elif isImage(file): ftype = 'Image' fthumbnail = getExif(file) elif isVideo(file): ftype = 'Video' else: ftype = 'File' if ftype != "Directory": fhash=md5(file) else: fhash=None fsize = round(os.stat(file).st_size/(1024*1024)) view_list.append( Photos( name=file, type=ftype, size_MB=fsize, hash=fhash, thumbnail=fthumbnail )) return render_template("photos.html", page_title='View Photos', view_path=view_path, file_list=view_list, alert=st.GetAlert(), message=st.GetMessage() ) def isImage(file): try: img = Image.open(file) return True except: return False def isVideo(file): try: fileInfo = MediaInfo.parse(file) for track in fileInfo.tracks: if track.track_type == "Video": return True return False except Exception as e: return False def getExif(file): f = open(file, 'rb') try: tags = exifread.process_file(f) except: print('NO EXIF TAGS?!?!?!?') f.close() raise f.close() fthumbnail = base64.b64encode(tags['JPEGThumbnail']) fthumbnail = str(fthumbnail)[2:-1] return fthumbnail