Browse Source

add new endpoints for async file listing

master
cinnaboot 7 years ago
parent
commit
c4590c4789
  1. 7
      video_metadata/templates/base.html
  2. 21
      video_metadata/templates/file_listing/folder_contents.html
  3. 62
      video_metadata/views/file_listing.py

7
video_metadata/templates/base.html

@ -1,15 +1,16 @@
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
<title>{% block title %}{% endblock %} - video_metadata</title> <title>{% block title %}{% endblock %} - pvdb</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head> </head>
<body> <body>
<nav> <nav>
<h1>video_metadata</h1> <h1>pvdb</h1>
<ul> <ul>
<li><a href="{{ url_for('index') }}">Home</a> <li><a href="{{ url_for('index') }}">Home</a>
<li><a href="{{ url_for('file_listing.index') }}">File Listing</a> <li><a href="{{ url_for('file_listing.index') }}">File Listing Slow</a>
<li><a href="{{ url_for('file_listing.getBaseFolderContents') }}">File Listing_Async</a>
<li><a href="{{ url_for('tmdb.query_movie') }}">Query</a> <li><a href="{{ url_for('tmdb.query_movie') }}">Query</a>
</ul> </ul>
</nav> </nav>

21
video_metadata/templates/file_listing/folder_contents.html

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}File Listing{% endblock %}</h1>
{% endblock %}
{% block content %}
<ul>
{% for path in paths%}
<li>
{% if path.is_dir %}
<a href="{{ url_for('file_listing.getFolderJSON', subpath=path.rel_path) }}">
{{ path.base_name }}</a>
{% else %}
<a href="{{ url_for('tmdb.query_movie', query=path.base_name, rel_path=path.rel_path) }}">
{{ path.base_name }}</a>
{% endif %}
</li>
{% endfor %}
</ul>
{% endblock %}

62
video_metadata/views/file_listing.py

@ -1,16 +1,18 @@
import os import os
import re import re
import yaml
from flask import Blueprint, current_app, render_template from flask import Blueprint, current_app, escape, flash, render_template
from flask import jsonify
from .. import util
VIDEO_EXTENSIONS = ['.avi', '.m4v', '.mkv', '.mp4', '.mpg'] VIDEO_EXTENSIONS = ['.avi', '.m4v', '.mkv', '.mp4', '.mpg']
MAX_RECURSE_DEPTH = 5 MAX_RECURSE_DEPTH = 5
bp = Blueprint('file_listing', __name__) bp = Blueprint('file_listing', __name__, url_prefix='/file_listing')
class path_entry: class path_entry(object):
def __init__(self): def __init__(self):
self.base_name = '' self.base_name = ''
self.rel_path = '' # NOTE: fs path relative to config['MOVIE_DIR'] self.rel_path = '' # NOTE: fs path relative to config['MOVIE_DIR']
@ -20,7 +22,7 @@ class path_entry:
self.contents = [] self.contents = []
@bp.route('/file_listing') @bp.route('/')
def index(): def index():
# construct tree of path_entry objects # construct tree of path_entry objects
video_path = current_app.config['MOVIE_DIR'] video_path = current_app.config['MOVIE_DIR']
@ -34,9 +36,57 @@ def index():
return render_template( return render_template(
'file_listing/index.html', 'file_listing/index.html',
paths=paths, paths=paths,
debug_str=yaml.dump(paths) debug_str=util.dumpObject(paths)
)
@bp.route('/folder_contents/')
def getBaseFolderContents():
full_path = current_app.config['MOVIE_DIR']
paths = []
# validate input
if not os.path.exists(full_path):
flash('invalid path')
else:
for entry in os.scandir(full_path):
paths.append(getPathInfo(entry, MAX_RECURSE_DEPTH))
return render_template(
'file_listing/folder_contents.html',
paths=paths,
debug_str=util.dumpObject(paths)
) )
# 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/<path:subpath>')
def getFolderJSON(subpath = ''):
video_path = current_app.config['MOVIE_DIR']
full_path = os.path.join(video_path, subpath)
paths = []
# validate input
if re.search('\.\.', subpath) or not os.path.exists(full_path):
flash('invalid path')
else:
for entry in os.scandir(full_path):
# TODO: remove 'getPathInfo()' when finished with async file listing
# make sure to continue to test for '.' and symlinks
logger.info(entry)
pe = getPathInfo(entry, MAX_RECURSE_DEPTH)
if pe:
paths.append({
'base_name': pe.base_name,
'rel_path': pe.rel_path,
'file_extension': pe.file_extension,
'is_dir': pe.is_dir,
})
return jsonify(paths)
def getPathInfo(entry, depth=0): def getPathInfo(entry, depth=0):
if not entry.name.startswith('.') and not entry.is_symlink(): if not entry.name.startswith('.') and not entry.is_symlink():
video_path = current_app.config['MOVIE_DIR'] video_path = current_app.config['MOVIE_DIR']

Loading…
Cancel
Save