From 6534294c48df5cb89cfff278e4040c0b8f718659 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Wed, 11 May 2011 20:09:27 +0200 Subject: whites filemanager --- module/database/UserDatabase.py | 1 + module/web/json_app.py | 126 ++++++++- module/web/media/default/css/window.css | 21 +- module/web/media/default/img/add_folder.png | Bin 0 -> 571 bytes module/web/pyload_app.py | 98 ++++++- module/web/templates/default/admin.html | 4 + module/web/templates/default/base.html | 28 +- module/web/templates/default/collector.html | 28 +- module/web/templates/default/downloads.html | 21 -- module/web/templates/default/filemanager.html | 80 ++++++ module/web/templates/default/filemanager_ui.js | 296 +++++++++++++++++++++ module/web/templates/default/folder.html | 15 ++ module/web/templates/default/home.html | 24 ++ module/web/templates/default/info.html | 7 + module/web/templates/default/logs.html | 20 -- module/web/templates/default/queue.html | 30 +-- module/web/templates/default/rename_directory.html | 28 ++ module/web/templates/default/settings.html | 25 -- module/web/utils.py | 4 + 19 files changed, 716 insertions(+), 140 deletions(-) create mode 100644 module/web/media/default/img/add_folder.png create mode 100644 module/web/templates/default/filemanager.html create mode 100644 module/web/templates/default/filemanager_ui.js create mode 100644 module/web/templates/default/folder.html create mode 100644 module/web/templates/default/rename_directory.html diff --git a/module/database/UserDatabase.py b/module/database/UserDatabase.py index 4367b1292..11bdbabc0 100644 --- a/module/database/UserDatabase.py +++ b/module/database/UserDatabase.py @@ -29,6 +29,7 @@ class PERMS: SEE_DOWNLOADS = 16 # see queue and collector DOWNLOAD = 32 # can download from webinterface SETTINGS = 64 # can access settings + FILEMANAGER = 128 # can manage files and folders trough webinterface class ROLE: ADMIN = 0 #admin has all permissions implicit diff --git a/module/web/json_app.py b/module/web/json_app.py index df58238ec..5b3b9f1fd 100644 --- a/module/web/json_app.py +++ b/module/web/json_app.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import base64 -from os.path import join +#from os.path import join, exists from traceback import print_exc from shutil import copyfileobj @@ -14,6 +14,10 @@ from utils import login_required, render_to_response from module.utils import decode +import os +import shutil +import os.path + def format_time(seconds): seconds = int(seconds) @@ -384,3 +388,123 @@ def update_accounts(): elif action == "delete" and value: PYLOAD.remove_account(plugin, user) +@route("/json/filemanager/rename", method="POST") +@login_required('filemanager') +def rename_dir(): + try: + path = request.forms.get("path").decode("utf8", "ignore") + old_name = path + "/" + request.forms.get("old_name").decode("utf8", "ignore") + new_name = path + "/" + request.forms.get("new_name").decode("utf8", "ignore") + + try: + #check if file exists + os.rename(old_name, new_name); + except Exception as (errno, strerror): + return { "response": "fail", "error" : strerror + "\n" + old_name + " => " + new_name } + + return {"response" : "success"} + + except: + return HTTPError() + +@route("/json/filemanager/delete", method="POST") +@login_required('filemanager') +def rename_dir(): + try: + + try: + path = request.forms.get("path").decode("utf8", "ignore") + name = request.forms.get("name").decode("utf8", "ignore") + + shutil.rmtree(path + "/" + name) + except Exception as (errno, strerror): + return { "response": "fail", "error": strerror + "\n" + path + "/" + name } + + return {"response" : "success"} + + except: + return HTTPError() + +@route("/json/filemanager/mkdir", method="POST") +@login_required('filemanager') +def make_dir(): + try: + path = request.forms.get("path").decode("utf8", "ignore") + name = request.forms.get("name").decode("utf8", "ignore") + try: + #i = 1 + #full_name = path + "/" + name + #while os.path.exists(full_name) + # full_name = full_name + i + # i = i + 1 + # + #os.mkdir(full_name) + + os.mkdir(path + "/" + name) + except Exception as (errno, strerror): + return { "response": "fail", "error": strerror + "\nUnable to create directory: " + path + "/" + name } + + return {"response" : "success", "path": path, "name": name} + + except: + return HTTPError() +@route("/json/filemanager/rename", method="POST") +@login_required('filemanager') +def rename_dir(): + try: + path = request.forms.get("path").decode("utf8", "ignore") + old_name = path + "/" + request.forms.get("old_name").decode("utf8", "ignore") + new_name = path + "/" + request.forms.get("new_name").decode("utf8", "ignore") + + try: + #check if file exists + os.rename(old_name, new_name); + except Exception as (errno, strerror): + return { "response": "fail", "error" : strerror + "\n" + old_name + " => " + new_name } + + return {"response" : "success"} + + except: + return HTTPError() + +@route("/json/filemanager/delete", method="POST") +@login_required('filemanager') +def rename_dir(): + try: + + try: + path = request.forms.get("path").decode("utf8", "ignore") + name = request.forms.get("name").decode("utf8", "ignore") + + shutil.rmtree(path + "/" + name) + except Exception as (errno, strerror): + return { "response": "fail", "error": strerror + "\n" + path + "/" + name } + + return {"response" : "success"} + + except: + return HTTPError() + +@route("/json/filemanager/mkdir", method="POST") +@login_required('filemanager') +def make_dir(): + try: + path = request.forms.get("path").decode("utf8", "ignore") + name = request.forms.get("name").decode("utf8", "ignore") + try: + #i = 1 + #full_name = path + "/" + name + #while os.path.exists(full_name) + # full_name = full_name + i + # i = i + 1 + # + #os.mkdir(full_name) + + os.mkdir(path + "/" + name) + except Exception as (errno, strerror): + return { "response": "fail", "error": strerror + "\nUnable to create directory: " + path + "/" + name } + + return {"response" : "success", "path": path, "name": name} + + except: + return HTTPError() \ No newline at end of file diff --git a/module/web/media/default/css/window.css b/module/web/media/default/css/window.css index a2f2dcef5..6841c5315 100644 --- a/module/web/media/default/css/window.css +++ b/module/web/media/default/css/window.css @@ -86,4 +86,23 @@ .styled_button { margin-left: 15px; -} \ No newline at end of file +} +#directories-list { + padding-left:5px; + margin-top:-30px; +} +#directories-list ul { + padding-left:0px; + margin-left:0; +} + +#directories-list li { + list-style:none; +} + +#directories-list li.folder { background:url(../img/folder.png) no-repeat top left; padding-left:22px;} +#directories-list li.file { background:url(../img/images.png) no-repeat top left; padding-left:22px;} + +#directories-list li.folder span { cursor:pointer; } + +/*#directories-list li span input { width:200px; float:left; }*/ diff --git a/module/web/media/default/img/add_folder.png b/module/web/media/default/img/add_folder.png new file mode 100644 index 000000000..8acbc411b Binary files /dev/null and b/module/web/media/default/img/add_folder.png differ diff --git a/module/web/pyload_app.py b/module/web/pyload_app.py index fc2302809..693d08d06 100644 --- a/module/web/pyload_app.py +++ b/module/web/pyload_app.py @@ -20,12 +20,11 @@ from copy import deepcopy from datetime import datetime from operator import itemgetter - import time import os import sys from os import listdir -from os.path import isdir, isfile, join ,abspath +from os.path import isdir, isfile, join, abspath from sys import getfilesystemencoding from hashlib import sha1 from urllib import unquote @@ -54,7 +53,8 @@ def pre_processor(): return {"user": user, 'status': status, 'captcha': captcha, - 'perms': perms} + 'perms': perms, + 'url': request.url} def get_sort_key(item): @@ -68,11 +68,10 @@ def base(messages): ## Views @error(500) def error500(error): - print "An error occured while processing the request." if error.traceback: print error.traceback - + return base(["An Error occured, please enable debug mode to get more details.", error, error.traceback.replace("\n", "
") if error.traceback else "No Traceback"]) @@ -84,10 +83,12 @@ def server_static(path): response.headers['Cache-control'] = "public" return static_file(path, root=join(PROJECT_DIR, "media")) + @route('/favicon.ico') def favicon(): return static_file("favicon.ico", root=join(PROJECT_DIR, "media", "img")) + @route('/login', method="GET") def login(): if not PYLOAD and SETUP: @@ -95,10 +96,12 @@ def login(): else: return render_to_response("login.html", proc=[pre_processor]) + @route('/nopermission') def nopermission(): return base([_("You dont have permission to access this page.")]) + @route("/login", method="POST") def login_post(): user = request.forms.get("username") @@ -120,6 +123,7 @@ def login_post(): return redirect("/") + @route("/logout") def logout(): s = request.environ.get('beaker.session') @@ -155,6 +159,7 @@ def queue(): return render_to_response('queue.html', {'content': data}, [pre_processor]) + @route("/collector") @login_required('see_downloads') def collector(): @@ -165,6 +170,7 @@ def collector(): return render_to_response('collector.html', {'content': data}, [pre_processor]) + @route("/downloads") @login_required('download') def downloads(): @@ -197,6 +203,7 @@ def downloads(): return render_to_response('downloads.html', {'files': data}, [pre_processor]) + @route("/downloads/get/:path#.+#") @login_required("download") def get_download(path): @@ -213,6 +220,63 @@ def get_download(path): print e return HTTPError(404, "File not Found.") + +@route("/filemanager") +@login_required('filemanager') +def filemanager(): + root = PYLOAD.get_conf_val("general", "download_folder") + + if not isdir(root): + return base([_('Download directory not found.')]) + + root_node = {'name': '/', + 'path': root, + 'files': [], + 'folders': [] + } + + for item in sorted(listdir(root)): + if isdir(join(root, item)): + root_node['folders'].append(iterate_over_dir(root, item)) + elif isfile(join(root, item)): + f = { + 'name': decode(item), + 'path': root + } + root_node['files'].append(f) + + return render_to_response('filemanager.html', {'root': root_node}, [pre_processor]) + + +def iterate_over_dir(root, dir): + out = { + 'name': decode(dir), + 'path': root, + 'files': [], + 'folders': [] + } + for item in sorted(listdir(join(root, dir))): + subroot = join(root, dir) + if isdir(join(subroot, item)): + out['folders'].append(iterate_over_dir(subroot, item)) + elif isfile(join(subroot, item)): + f = { + 'name': decode(item), + 'path': subroot + } + out['files'].append(f) + + return out + + +@route("/filemanager/get_dir", "POST") +@login_required('filemanager') +def folder(): + path = request.forms.get("path").decode("utf8", "ignore") + name = request.forms.get("name").decode("utf8", "ignore") + return render_to_response('folder.html', {'path': path, 'name': name}, [pre_processor]) + + @route("/settings") @login_required('settings') def config(): @@ -257,6 +321,7 @@ def config(): {'conf': {'plugin': plugin_menu, 'general': conf_menu, 'accs': accs}}, [pre_processor]) + @route("/package_ui.js") @login_required('see_downloads') def package_ui(): @@ -266,6 +331,15 @@ def package_ui(): return render_to_response('package_ui.js') +@route("/filemanager_ui.js") +@login_required('see_downloads') +def package_ui(): + response.headers['Expires'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", + time.gmtime(time.time() + 60 * 60 * 24 * 7)) + response.headers['Cache-control'] = "public" + return render_to_response('filemanager_ui.js') + + @route("/filechooser") @route("/pathchooser") @route("/filechooser/:file#.+#") @@ -357,6 +431,7 @@ def path(file="", path=""): {'cwd': cwd, 'files': files, 'parentdir': parentdir, 'type': type, 'oldfile': oldfile, 'absolute': abs}, []) + @route("/logs") @route("/logs", method="POST") @route("/logs/:item") @@ -443,11 +518,11 @@ def logs(item=-1): 'inext': (item + perpage) if item + perpage < len(log) else item}, [pre_processor]) + @route("/admin") @route("/admin", method="POST") @login_required("is_admin") def admin(): - user = PYLOAD.get_user_data() for data in user.itervalues(): data["perms"] = {} @@ -494,13 +569,16 @@ def admin(): else: user[name]["perms"]["settings"] = False + if request.POST.get("%s|filemanager" % name, False): + user[name]["perms"]["filemanager"] = True + else: + user[name]["perms"]["filemanager"] = False user[name]["permission"] = set_permission(user[name]["perms"]) PYLOAD.set_user_permission(name, user[name]["permission"], user[name]["role"]) - - return render_to_response("admin.html", {"users": user} ,[pre_processor]) + return render_to_response("admin.html", {"users": user}, [pre_processor]) @route("/setup") @@ -508,11 +586,11 @@ def setup(): if PYLOAD or not SETUP: return base([_("Run pyLoadCore.py -s to access the setup.")]) - return render_to_response('setup.html', {"user" : False, "perms": False}) + return render_to_response('setup.html', {"user": False, "perms": False}) + @route("/info") def info(): - conf = PYLOAD.get_config() data = {"python": sys.version, diff --git a/module/web/templates/default/admin.html b/module/web/templates/default/admin.html index 5be649de7..365e9b7bc 100644 --- a/module/web/templates/default/admin.html +++ b/module/web/templates/default/admin.html @@ -36,6 +36,9 @@ {{ _("Change settings") }} + + {{ _("Filemanager") }} + {% for name, data in users.iteritems() %} @@ -48,6 +51,7 @@ + {% endfor %} diff --git a/module/web/templates/default/base.html b/module/web/templates/default/base.html index 7f7db2610..fd22abbd4 100644 --- a/module/web/templates/default/base.html +++ b/module/web/templates/default/base.html @@ -245,24 +245,33 @@ function AddBox()