diff --git a/video_metadata/templates/base.html b/video_metadata/templates/base.html
index 7fa93b1..dce219e 100644
--- a/video_metadata/templates/base.html
+++ b/video_metadata/templates/base.html
@@ -1,15 +1,16 @@
- {% block title %}{% endblock %} - video_metadata
+ {% block title %}{% endblock %} - pvdb
diff --git a/video_metadata/templates/file_listing/folder_contents.html b/video_metadata/templates/file_listing/folder_contents.html
new file mode 100644
index 0000000..7ceae6c
--- /dev/null
+++ b/video_metadata/templates/file_listing/folder_contents.html
@@ -0,0 +1,21 @@
+{% extends 'base.html' %}
+
+{% block header %}
+ {% block title %}File Listing{% endblock %}
+{% endblock %}
+
+{% block content %}
+
+{% endblock %}
diff --git a/video_metadata/views/file_listing.py b/video_metadata/views/file_listing.py
index fe3a427..5eeb23c 100644
--- a/video_metadata/views/file_listing.py
+++ b/video_metadata/views/file_listing.py
@@ -1,16 +1,18 @@
import os
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']
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):
self.base_name = ''
self.rel_path = '' # NOTE: fs path relative to config['MOVIE_DIR']
@@ -20,7 +22,7 @@ class path_entry:
self.contents = []
-@bp.route('/file_listing')
+@bp.route('/')
def index():
# construct tree of path_entry objects
video_path = current_app.config['MOVIE_DIR']
@@ -34,9 +36,57 @@ def index():
return render_template(
'file_listing/index.html',
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/')
+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):
if not entry.name.startswith('.') and not entry.is_symlink():
video_path = current_app.config['MOVIE_DIR']