from dataclasses import dataclass import os import re from flask import Blueprint, current_app, escape, flash, render_template from flask import jsonify from .. import db, util VIDEO_EXTENSIONS = ['.avi', '.m4v', '.mkv', '.mp4', '.mpg'] bp = Blueprint('file_listing', __name__, url_prefix='/file_listing') @dataclass class path_entry: base_name = '' rel_path = '' # NOTE: fs path relative to config['MOVIE_DIR'] file_extension = '' is_dir = False in_db = False @bp.route('/folder_contents/') def getBaseFolderContents(): return render_template('file_listing/folder_contents.html') # NOTE: return a listing of files and directories in a sub_directory as JSON # @param subpath a path relative to config['MOVIE_DIR'] @bp.route('/folder_contents_json/') @bp.route('/folder_contents_json/') def getFolderJSON(subpath = ''): video_path = current_app.config['MOVIE_DIR'] full_path = os.path.join(video_path, subpath) errors, paths = [], [] current_app.logger.debug('video_path: {}'.format(video_path)) current_app.logger.debug('subpath: {}'.format(subpath)) current_app.logger.debug('full_path: {}'.format(full_path)) # validate input if re.search('\.\.', subpath) or not os.path.exists(full_path): errors.append('invalid path: {}'.format(full_path)) elif not os.path.isdir(full_path): errors.append('path is not a directory: {}'.format(full_path)) else: for entry in os.scandir(full_path): pe = getPathInfo(entry) if pe: paths.append({ 'base_name': pe.base_name, 'rel_path': pe.rel_path, 'file_extension': pe.file_extension, 'is_dir': pe.is_dir, 'in_db': pe.in_db, }) return jsonify(errors=errors, paths=paths) def getPathInfo(entry): if not entry.name.startswith('.') and not entry.is_symlink(): video_path = current_app.config['MOVIE_DIR'] pe = path_entry() pe.base_name = entry.name pe.rel_path = re.sub(video_path, '', entry.path) pe.is_dir = entry.is_dir() if entry.is_file(): ext = os.path.splitext(entry)[1] if ext in VIDEO_EXTENSIONS: pe.file_extension = ext # check if the path is already stored in db cur = db.get_db().cursor() cur.execute('SELECT COUNT(*) FROM movie_paths WHERE movie_path = ?', (pe.rel_path, ) ) pe.in_db = cur.fetchone()[0] > 0 else: return None return pe return None