You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.7 KiB
85 lines
2.7 KiB
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: str = '' |
|
rel_path: str = '' # NOTE: fs path relative to config['MOVIE_DIR'] |
|
file_extension: str = '' |
|
is_dir: bool = False |
|
in_db: bool = False |
|
|
|
|
|
@bp.route('/file_listing/') |
|
def getBaseFolderContents(): |
|
return render_template('file_listing/file_listing.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('/file_listing_json/') |
|
@bp.route('/file_listing_json/<path:subpath>') |
|
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: {}, subpath: {}, full_path: {}'.format(video_path, subpath, 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=sorted(paths, key=lambda k: str.lower(k['base_name']))) |
|
|
|
|
|
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 path_cache WHERE path = ?', |
|
(pe.rel_path, ) |
|
) |
|
pe.in_db = cur.fetchone()[0] > 0 |
|
else: |
|
return None |
|
return pe |
|
return None |
|
|
|
|