file manager and config updates, css changes, etc

This commit is contained in:
maximstewart 2021-02-07 00:43:36 -06:00
parent 840ffc8255
commit f6f7cfda58
14 changed files with 124 additions and 80 deletions

2
.gitignore vendored
View File

@ -1,7 +1,5 @@
*.db *.db
*.pyc *.pyc
client_secrets.json
webfm_config.json
app.pid app.pid

View File

@ -3,11 +3,13 @@ WebFM is a media and file viewer aspiring to become a full fledged file manager
# Usage # Usage
1. Install python, sqlite3, and ffmpeg on the system this will be on. 1. Install python, sqlite3, and ffmpeg on the system this will be on.
3. Use ufw or gufw to open the port on your computer to the network. 3. Use ufw or gufw to open the port on your computer to the local network.
4. Place files or start uploading some to the folders. 4. Use hosts file (or other methods) to redirect webfm.com and ssoapps.com to local app.
5. Place an image such as a jpg, png, or gif labeled "000.itsExtension" in a directory and the viewer will use it as the background image for that folder/directory. 5. Update client_secrets.json > 'client_secret' field with your Keycloak key. (Current one is local to me and not public)
9. Password protect folder based on core/webfm_config.json file settings. 6. Place files or start uploading some to the folders.
10. Save paths to favorites list for quick access. 7. Place an image such as a jpg, png, or gif labeled "000.itsExtension" in a directory and the viewer will use it as the background image for that folder/directory.
7. Password protect folder based on core/utils/shellfm/windows/webfm_config.json file settings.
8. Save paths to favorites list for quick access.
Notes: Notes:
n/a n/a

View File

@ -3,10 +3,10 @@
"auth_uri": "https://www.ssoapps.com/auth/realms/apps/protocol/openid-connect/auth", "auth_uri": "https://www.ssoapps.com/auth/realms/apps/protocol/openid-connect/auth",
"client_id": "apps", "client_id": "apps",
"issuer": "https://www.ssoapps.com/auth/realms/apps", "issuer": "https://www.ssoapps.com/auth/realms/apps",
"client_secret": "[Add your secret key here]", "client_secret": "ce6fdb7d-fdcb-46ea-bc80-b5df9649d50b",
"redirect_uris": [ "redirect_uris": [
"http://www.webfm.com/home", "https://www.webfm.com/home",
"https://www.webfm.com/home" "http://www.webfm.com/home"
], ],
"userinfo_uri": "https://www.ssoapps.com/auth/realms/apps/protocol/openid-connect/userinfo", "userinfo_uri": "https://www.ssoapps.com/auth/realms/apps/protocol/openid-connect/userinfo",
"token_uri": "https://www.ssoapps.com/auth/realms/apps/protocol/openid-connect/token", "token_uri": "https://www.ssoapps.com/auth/realms/apps/protocol/openid-connect/token",

View File

@ -1,5 +1,5 @@
# System import # System import
import os, secrets, json import os, secrets
from datetime import timedelta from datetime import timedelta
@ -12,19 +12,9 @@ from datetime import timedelta
APP_NAME = 'WebFM' APP_NAME = 'WebFM'
# Configs # Configs
ROOT_FILE_PTH = os.path.dirname(os.path.realpath(__file__)) ROOT_FILE_PTH = os.path.dirname(os.path.realpath(__file__))
CONFIG_FILE = ROOT_FILE_PTH + "/webfm_config.json"
# This path is submitted as the redirect URI in certain code flows. # This path is submitted as the redirect URI in certain code flows.
REDIRECT_LINK = "https%3A%2F%2Fwww.webfm.com%2F" REDIRECT_LINK = "https%3A%2F%2Fwww.webfm.com%2F"
# Settings data
def retrieveSettings():
returnData = []
with open(CONFIG_FILE) as infile:
try:
return json.load(infile)
except Exception as e:
print(repr(e))
return ['', 'mplayer', 'xdg-open']
@ -50,10 +40,14 @@ class Config(object):
'https://localhost:443/auth/realms/apps' 'https://localhost:443/auth/realms/apps'
] ]
WEBFM_CONFIG = retrieveSettings()
STATIC_FPTH = ROOT_FILE_PTH + "/static" STATIC_FPTH = ROOT_FILE_PTH + "/static"
REMUX_FOLDER = STATIC_FPTH + "/remuxs" REMUX_FOLDER = STATIC_FPTH + "/remuxs" # Remuxed files folder
FFMPG_THUMBNLR = STATIC_FPTH + "/ffmpegthumbnailer" FFMPG_THUMBNLR = STATIC_FPTH + "/ffmpegthumbnailer" # Thumbnail generator binary
ABS_THUMBS_PTH = STATIC_FPTH + "/imgs/thumbnails" # Used for thumbnail generation
REL_THUMBS_PTH = "static/imgs/thumbnails" # Used for flask thumbnail return
class ProductionConfig(Config): class ProductionConfig(Config):

View File

@ -30,7 +30,7 @@ def home():
if request.method == 'GET': if request.method == 'GET':
view = get_window_controller().get_window(1).get_view(0) view = get_window_controller().get_window(1).get_view(0)
_path = view.get_path() _path = view.get_path()
_files = view.get_files() _files = view.get_files_formatted()
return render_template('pages/index.html', path=_path, files=_files) return render_template('pages/index.html', path=_path, files=_files)
return render_template('error.html', return render_template('error.html',

View File

@ -5,6 +5,7 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: -999; z-index: -999;
object-fit: cover;
} }
#bg img { #bg img {
@ -19,7 +20,7 @@
} }
#master-container { #master-container {
height: 85vh; height: 90vh;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
} }
@ -47,9 +48,9 @@
.dir-style, .video-style, .image-style, .file-style { .dir-style, .video-style, .image-style, .file-style {
height: auto; /* max-width: 24vw; */
width: 24vw; /* height: auto;
position: relative; position: relative; */
max-width: 20em; max-width: 20em;
} }

View File

@ -11,8 +11,8 @@
<li class="nav-item"> <li class="nav-item">
<div class="input-group input-group-sm justify-content-center"> <div class="input-group input-group-sm justify-content-center">
<button title="Other Options..." class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#options-modal"></button> <button title="Other Options..." class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#options-modal"></button>
<button title="Refresh..." id="refresh-btn" class="btn btn-sm btn-secondary" hash="{{files[0][1]}}"></button> <button title="Refresh..." id="refresh-btn" class="btn btn-sm btn-secondary" hash="{{files['files'][0][1]}}"></button>
<button title="Back..." id="back-btn" class="btn btn-sm btn-secondary" hash="{{files[1][1]}}"></button> <button title="Back..." id="back-btn" class="btn btn-sm btn-secondary" hash="{{files['files'][1][1]}}"></button>
<input id="search-files-field" type="text" class="form-control" aria-label="Search..." placeholder="Search..." style="max-width: 260px"> <input id="search-files-field" type="text" class="form-control" aria-label="Search..." placeholder="Search..." style="max-width: 260px">
<div class="input-group-prepend"> <div class="input-group-prepend">

View File

@ -15,7 +15,7 @@
{% block body_content_additional %} {% block body_content_additional %}
<div id="files" class="row"> <div id="files" class="row">
{% for file in files %} {% for file in files['files'] %}
<div class="col-sm-12 col-md-6 col-lg-4"> <div class="col-sm-12 col-md-6 col-lg-4">
<div class="card"> <div class="card">
<div class="card-header">{{file[0]}}</div> <div class="card-header">{{file[0]}}</div>

View File

@ -1,9 +0,0 @@
class Filters:
fvideos = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
foffice = ('.doc', '.docx', '.xls', '.xlsx', '.xlt', '.xltx', '.xlm', '.ppt', 'pptx', '.pps', '.ppsx', '.odt', '.rtf')
fimages = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
ftext = ('.txt', '.text', '.sh', '.cfg', '.conf')
fmusic = ('.psf', '.mp3', '.ogg', '.flac', '.m4a')
fpdf = ('.pdf')
subpath = "/LazyShare/Synced Backup/222_Photos/Backgrounds/HD-Wallpapers"

View File

@ -1,29 +1,39 @@
# System import
import os, subprocess, threading
# Lib imports
# Apoplication imports
class Launcher: class Launcher:
def openFilelocally(self, file): def openFilelocally(self, file):
lowerName = file.lower() lowerName = file.lower()
command = [] command = []
if lowerName.endswith(self.VEXTENSION): if lowerName.endswith(self.fvideos):
player = config["settings"]["media_app"] player = self.fm_config["settings"]["media_app"]
options = config["settings"]["mplayer_options"].split() options = self.fm_config["settings"]["mplayer_options"].split()
command = [player] command = [player]
if "mplayer" in player: if "mplayer" in player:
command += options command += options
command += [file] command += [file]
elif lowerName.endswith(self.IEXTENSION): elif lowerName.endswith(self.fimages):
command = [config["settings"]["image_app"], file] command = [self.fm_config["settings"]["image_app"], file]
elif lowerName.endswith(self.MEXTENSION): elif lowerName.endswith(self.fmusic):
command = [config["settings"]["music_app"], file] command = [self.fm_config["settings"]["music_app"], file]
elif lowerName.endswith(self.OEXTENSION): elif lowerName.endswith(self.foffice):
command = [config["settings"]["office_app"], file] command = [self.fm_config["settings"]["office_app"], file]
elif lowerName.endswith(self.TEXTENSION): elif lowerName.endswith(self.ftext):
command = [config["settings"]["text_app"], file] command = [self.fm_config["settings"]["text_app"], file]
elif lowerName.endswith(self.PEXTENSION): elif lowerName.endswith(self.fpdf):
command = [config["settings"]["pdf_app"], file] command = [self.fm_config["settings"]["pdf_app"], file]
else: else:
command = [config["settings"]["file_manager_app"], file] command = [self.fm_config["settings"]["file_manager_app"], file]
self.logging.debug(command) self.logging.debug(command)
DEVNULL = open(os.devnull, 'w') DEVNULL = open(os.devnull, 'w')
@ -32,25 +42,10 @@ class Launcher:
def remuxVideo(self, hash, file): def remuxVideo(self, hash, file):
remux_vid_pth = self.REMUX_FOLDER + "/" + hash + ".mp4" remux_vid_pth = self.REMUX_FOLDER + "/" + hash + ".mp4"
message = '{"path":"static/remuxs/' + hash + '.mp4"}'
self.logging.debug(remux_vid_pth) self.logging.debug(remux_vid_pth)
self.logging.debug(message)
if not os.path.isfile(remux_vid_pth): if not os.path.isfile(remux_vid_pth):
limit = config["settings"]["remux_folder_max_disk_usage"] self.check_remux_space()
try:
limit = int(limit)
except Exception as e:
self.logging.debug(e)
return
usage = self.getRemuxFolderUsage(self.REMUX_FOLDER)
if usage > limit:
files = os.listdir(self.REMUX_FOLDER)
for file in files:
fp = os.path.join(self.REMUX_FOLDER, file)
os.unlink(fp)
command = ["ffmpeg", "-i", file, "-hide_banner", "-movflags", "+faststart"] command = ["ffmpeg", "-i", file, "-hide_banner", "-movflags", "+faststart"]
if file.endswith("mkv"): if file.endswith("mkv"):
@ -67,11 +62,11 @@ class Launcher:
proc = subprocess.Popen(command) proc = subprocess.Popen(command)
proc.wait() proc.wait()
except Exception as e: except Exception as e:
message = '{"message": {"type": "danger", "text":"' + str( repr(e) ) + '"}}'
self.logging.debug(message) self.logging.debug(message)
self.logging.debug(e) self.logging.debug(e)
return False
return message return True
def generateVideoThumbnail(self, fullPath, hashImgPth): def generateVideoThumbnail(self, fullPath, hashImgPth):
@ -81,13 +76,29 @@ class Launcher:
except Exception as e: except Exception as e:
self.logging.debug(repr(e)) self.logging.debug(repr(e))
def check_remux_space(self):
limit = self.fm_config["settings"]["remux_folder_max_disk_usage"]
try:
limit = int(limit)
except Exception as e:
self.logging.debug(e)
return
usage = self.getRemuxFolderUsage(self.REMUX_FOLDER)
if usage > limit:
files = os.listdir(self.REMUX_FOLDER)
for file in files:
fp = os.path.join(self.REMUX_FOLDER, file)
os.unlink(fp)
def getRemuxFolderUsage(self, start_path = "."): def getRemuxFolderUsage(self, start_path = "."):
total_size = 0 total_size = 0
for dirpath, dirnames, filenames in os.walk(start_path): for dirpath, dirnames, filenames in os.walk(start_path):
for f in filenames: for f in filenames:
fp = os.path.join(dirpath, f) fp = os.path.join(dirpath, f)
# skip if it is symbolic link if not os.path.islink(fp): # Skip if it is symbolic link
if not os.path.islink(fp):
total_size += os.path.getsize(fp) total_size += os.path.getsize(fp)
return total_size return total_size

View File

@ -0,0 +1,26 @@
# System import
import json
from os import path
# Lib imports
# Apoplication imports
class Settings:
ABS_THUMBS_PTH = None # Used for thumbnail generation and is set by passing in
REMUX_FOLDER = None # Used for Remuxed files and is set by passing in
FFMPG_THUMBNLR = None # Used for thumbnail generator binary and is set by passing in
CONFIG_FILE = path.dirname(__file__) + '/webfm_config.json'
subpath = "/LazyShare" # modify 'home' folder path
fvideos = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
foffice = ('.doc', '.docx', '.xls', '.xlsx', '.xlt', '.xltx', '.xlm', '.ppt', 'pptx', '.pps', '.ppsx', '.odt', '.rtf')
fimages = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
ftext = ('.txt', '.text', '.sh', '.cfg', '.conf')
fmusic = ('.psf', '.mp3', '.ogg', '.flac', '.m4a')
fpdf = ('.pdf')

View File

@ -8,10 +8,10 @@ from os.path import isdir, isfile, join
# Application imports # Application imports
from . import Path, Filters, Launcher from . import Path, Settings, Launcher
class View(Filters, Path, Launcher): class View(Settings, Launcher, Path):
def __init__(self): def __init__(self):
self.hideHiddenFiles = True self.hideHiddenFiles = True
self.files = [] self.files = []
@ -20,8 +20,20 @@ class View(Filters, Path, Launcher):
self.images = [] self.images = []
self.desktop = [] self.desktop = []
self.ungrouped = [] self.ungrouped = []
self.fm_config = self.getFileManagerSettings()
self.set_to_home() self.set_to_home()
# Settings data
def getFileManagerSettings(self):
returnData = []
with open(self.CONFIG_FILE) as infile:
try:
return json.load(infile)
except Exception as e:
print(repr(e))
return ['', 'mplayer', 'xdg-open']
def load_directory(self): def load_directory(self):
path = self.get_path() path = self.get_path()
self.dirs = ['.', '..'] self.dirs = ['.', '..']
@ -78,6 +90,16 @@ class View(Filters, Path, Launcher):
return file[0] return file[0]
return None return None
def get_files_formatted(self):
return {
'files': self.hashSet(self.files),
'dirs': self.hashSet(self.dirs),
'videos': self.hashSet(self.vids),
'images': self.hashSet(self.images),
'desktops': self.hashSet(self.desktop),
'ungrouped': self.hashSet(self.ungrouped)
}
def get_files(self): def get_files(self):
return self.hashSet(self.files) return self.hashSet(self.files)

View File

@ -1,5 +1,5 @@
from .Settings import Settings
from .Launcher import Launcher from .Launcher import Launcher
from .Filters import Filters
from .Path import Path from .Path import Path
from .View import View from .View import View
from .Window import Window from .Window import Window

View File

@ -8,10 +8,9 @@
"pdf_app": "evince", "pdf_app": "evince",
"text_app": "leafpad", "text_app": "leafpad",
"file_manager_app": "spacefm", "file_manager_app": "spacefm",
"locked_folder_password": "toor",
"do_refresh": "no", "do_refresh": "no",
"remux_folder_max_disk_usage": "8589934592", "remux_folder_max_disk_usage": "8589934592",
"locked_folders": "venv::::flasks", "locked_folders": "Synced Backup::::venv::::flasks",
"folders_locked": "true" "folders_locked": "true"
} }
} }