diff options
author | RaNaN <Mast3rRaNaN@hotmail.de> | 2011-05-11 20:09:27 +0200 |
---|---|---|
committer | RaNaN <Mast3rRaNaN@hotmail.de> | 2011-05-11 20:09:27 +0200 |
commit | 6534294c48df5cb89cfff278e4040c0b8f718659 (patch) | |
tree | 370e7b9e5f9d4d331c55a713396dee47672a67eb /module | |
parent | fix cli (diff) | |
download | pyload-6534294c48df5cb89cfff278e4040c0b8f718659.tar.xz |
whites filemanager
Diffstat (limited to 'module')
-rw-r--r-- | module/database/UserDatabase.py | 1 | ||||
-rw-r--r-- | module/web/json_app.py | 126 | ||||
-rw-r--r-- | module/web/media/default/css/window.css | 21 | ||||
-rw-r--r-- | module/web/media/default/img/add_folder.png | bin | 0 -> 571 bytes | |||
-rw-r--r-- | module/web/pyload_app.py | 98 | ||||
-rw-r--r-- | module/web/templates/default/admin.html | 4 | ||||
-rw-r--r-- | module/web/templates/default/base.html | 28 | ||||
-rw-r--r-- | module/web/templates/default/collector.html | 28 | ||||
-rw-r--r-- | module/web/templates/default/downloads.html | 21 | ||||
-rw-r--r-- | module/web/templates/default/filemanager.html | 80 | ||||
-rw-r--r-- | module/web/templates/default/filemanager_ui.js | 296 | ||||
-rw-r--r-- | module/web/templates/default/folder.html | 15 | ||||
-rw-r--r-- | module/web/templates/default/home.html | 24 | ||||
-rw-r--r-- | module/web/templates/default/info.html | 7 | ||||
-rw-r--r-- | module/web/templates/default/logs.html | 20 | ||||
-rw-r--r-- | module/web/templates/default/queue.html | 30 | ||||
-rw-r--r-- | module/web/templates/default/rename_directory.html | 28 | ||||
-rw-r--r-- | module/web/templates/default/settings.html | 25 | ||||
-rw-r--r-- | module/web/utils.py | 4 |
19 files changed, 716 insertions, 140 deletions
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 Binary files differnew file mode 100644 index 000000000..8acbc411b --- /dev/null +++ b/module/web/media/default/img/add_folder.png 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", "<br>") 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 @@ <th> {{ _("Change settings") }} </th> + <th> + {{ _("Filemanager") }} + </th> </thead> {% for name, data in users.iteritems() %} @@ -48,6 +51,7 @@ <td><input name="{{ name }}|see_downloads" type="checkbox" {% if data.perms.see_downloads %} checked="True" {% endif %}"></td> <td><input name="{{ name }}|download" type="checkbox" {% if data.perms.download %} checked="True" {% endif %}"></td> <td><input name="{{ name }}|settings" type="checkbox" {% if data.perms.settings %} checked="True" {% endif %}"></td> + <td><input name="{{ name }}|filemanager" type="checkbox" {% if data.perms.filemanager %} checked="True" {% endif %}"></td> </tr> {% 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() <div id="head-menu">
<ul>
-
+
+ {% macro selected(name, right=False) -%}
+ {% if name in url -%}class="{% if right -%}right {% endif %}selected"{%- endif %}
+ {% if not name in url and right -%}class="right"{%- endif %}
+ {%- endmacro %}
+
+
{% block menu %}
- <li class="selected">
+ <li>
<a href="/" title=""><img src="/media/default/img/head-menu-home.png" alt="" /> {{_("Home")}}</a>
</li>
- <li>
+ <li {{ selected('queue') }}>
<a href="/queue/" title=""><img src="/media/default/img/head-menu-queue.png" alt="" /> {{_("Queue")}}</a>
</li>
- <li>
+ <li {{ selected('collector') }}>
<a href="/collector/" title=""><img src="/media/default/img/head-menu-collector.png" alt="" /> {{_("Collector")}}</a>
</li>
- <li>
+ <li {{ selected('downloads') }}>
<a href="/downloads/" title=""><img src="/media/default/img/head-menu-development.png" alt="" /> {{_("Downloads")}}</a>
</li>
- <li class="right">
+ <li {{ selected('filemanager') }}>
+ <a href="/filemanager/" title=""><img src="/media/default/img/head-menu-download.png" alt="" /> {{_("FileManager")}}</a>
+ </li>
+ <li {{ selected('logs', True) }}>
<a href="/logs/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-index.png" alt="" />{{_("Logs")}}</a>
</li>
- <li class="right">
+ <li {{ selected('settings', True) }}>
<a href="/settings/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-config.png" alt="" />{{_("Config")}}</a>
</li>
{% endblock %}
@@ -316,6 +325,11 @@ function AddBox() <b><p>{{message}}</p></b>
{% endfor %}
+<div id="load-indicator" style="opacity: 0; float: right; margin-top: -10px;">
+ <img src="/media/default/img/ajax-loader.gif" alt="" style="padding-right: 5px"/>
+ {{_("loading")}}
+</div>
+
{% block content %}
{% endblock content %}
diff --git a/module/web/templates/default/collector.html b/module/web/templates/default/collector.html index 3e6b47234..2683d8ee5 100644 --- a/module/web/templates/default/collector.html +++ b/module/web/templates/default/collector.html @@ -14,26 +14,6 @@ document.addEvent("domready", function(){ {% block title %}{{_("Collector")}} - {{super()}} {% endblock %}
{% block subtitle %}{{_("Collector")}}{% endblock %}
-{% block menu %}
-<li>
- <a href="/" title=""><img src="/media/default/img/head-menu-home.png" alt="" /> {{_("Home")}}</a>
-</li>
-<li>
- <a href="/queue/" title=""><img src="/media/default/img/head-menu-queue.png" alt="" /> {{_("Queue")}}</a>
-</li>
-<li class="selected">
- <a href="/collector/" title=""><img src="/media/default/img/head-menu-collector.png" alt="" /> {{_("Collector")}}</a>
-</li>
-<li>
- <a href="/downloads/" title=""><img src="/media/default/img/head-menu-development.png" alt="" /> {{_("Downloads")}}</a>
-</li>
-<li class="right">
- <a href="/logs/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-index.png" alt="" />{{_("Logs")}}</a>
-</li>
-<li class="right">
- <a href="/settings/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-config.png" alt="" />{{_("Config")}}</a>
-</li>{% endblock %}
-
{% block pageactions %}
<ul id="page-actions-more">
<li id="del_finished"><a style="padding: 0; font-weight: bold;" href="#">{{_("Delete Finished")}}</a></li>
@@ -42,12 +22,6 @@ document.addEvent("domready", function(){ {% endblock %}
{% block content %}
-<div id="load-success" style="opacity: 0; float: right; color: white; background-color: #90ee90; padding: 4px; -moz-border-radius: 5px; border-radius: 5px; font-weight: bold; margin-left: -100%; margin-top: -10px;">{{_("success")}}</div>
-<div id="load-failure" style="opacity: 0; float: right; color: white; background-color: #f08080; padding: 4px; -moz-border-radius: 5px; border-radius: 5px; font-weight: bold; margin-left: -100%; margin-top: -10px;">{{_("failure")}}</div>
-<div id="load-indicator" style="opacity: 0; float: right; margin-top: -10px;">
- <img src="/media/default/img/ajax-loader.gif" alt="" style="padding-right: 5px"/>
- {{_("loading")}}
-</div>
<ul id="package-list" style="list-style: none; padding-left: 0; margin-top: -10px;">
{% for id, package in content %}
@@ -81,4 +55,4 @@ document.addEvent("domready", function(){ {% include "default/edit_package.html" %}
-{% endblock %}
\ No newline at end of file +{% endblock %}
diff --git a/module/web/templates/default/downloads.html b/module/web/templates/default/downloads.html index 813dc8d06..450b8a102 100644 --- a/module/web/templates/default/downloads.html +++ b/module/web/templates/default/downloads.html @@ -2,27 +2,6 @@ {% block title %}Downloads - {{super()}} {% endblock %} -{% block menu %} -<li> - <a href="/" title=""><img src="/media/default/img/head-menu-home.png" alt="" /> {{_("Home")}}</a> -</li> -<li> - <a href="/queue/" title=""><img src="/media/default/img/head-menu-queue.png" alt="" /> {{_("Queue")}}</a> -</li> -<li> - <a href="/collector/" title=""><img src="/media/default/img/head-menu-collector.png" alt="" /> {{_("Collector")}}</a> -</li> -<li class="selected"> - <a href="/downloads/" title=""><img src="/media/default/img/head-menu-development.png" alt="" /> {{_("Downloads")}}</a> -</li> -<li class="right"> - <a href="/logs/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-index.png" alt="" />{{_("Logs")}}</a> -</li> -<li class="right"> - <a href="/settings/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-config.png" alt="" />{{_("Config")}}</a> -</li> -{% endblock %} - {% block subtitle %} {{_("Downloads")}} {% endblock %} diff --git a/module/web/templates/default/filemanager.html b/module/web/templates/default/filemanager.html new file mode 100644 index 000000000..97095c13e --- /dev/null +++ b/module/web/templates/default/filemanager.html @@ -0,0 +1,80 @@ +{% extends 'default/base.html' %} + +{% block head %} + +<script type="text/javascript" src="/filemanager_ui.js"></script> + +<script type="text/javascript"> + +document.addEvent("domready", function(){ + var fmUI = new FilemanagerUI("url",1); +}); +</script> +{% endblock %} + +{% block title %}Downloads - {{super()}} {% endblock %} + + +{% block subtitle %} +{{_("FileManager")}} +{% endblock %} + +{% macro display_file(file) %} + <li class="file"> + <input type="hidden" name="path" class="path" value="{{ file.path }}" /> + <input type="hidden" name="name" class="name" value="{{ file.name }}" /> + <span> + <b>{{ file.name }}</b> + <span class="buttons" style="opacity:0"> + <img title="{{_("Rename Directory")}}" class="rename" style="cursor: pointer" height="12px" src="/media/default/img/pencil.png" /> + + <img title="{{_("Delete Directory")}}" class="delete" style="margin-left: -10px; cursor: pointer" width="12px" height="12px" src="/media/default/img/delete.png" /> + </span> + </span> + </li> +{%- endmacro %} + +{% macro display_folder(fld, open = false) -%} + <li class="folder"> + <input type="hidden" name="path" class="path" value="{{ fld.path }}" /> + <input type="hidden" name="name" class="name" value="{{ fld.name }}" /> + <span> + <b>{{ fld.name }}</b> + <span class="buttons" style="opacity:0"> + <img title="{{_("Rename Directory")}}" class="rename" style="cursor: pointer" height="12px" src="/media/default/img/pencil.png" /> + + <img title="{{_("Delete Directory")}}" class="delete" style="margin-left: -10px; cursor: pointer" width="12px" height="12px" src="/media/default/img/delete.png" /> + + <img title="{{_("Add subdirectory")}}" class="mkdir" style="margin-left: -10px; cursor: pointer" width="12px" height="12px" src="/media/default/img/add_folder.png" /> + </span> + </span> + {% if (fld.folders|length + fld.files|length) > 0 %} + {% if open %} + <ul> + {% else %} + <ul style="display:none"> + {% endif %} + {% for child in fld.folders %} + {{ display_folder(child) }} + {% endfor %} + {% for child in fld.files %} + {{ display_file(child) }} + {% endfor %} + </ul> + {% else %} + <div style="display:none">{{ _("Folder is empty") }}</div> + {% endif %} + </li> +{%- endmacro %} + +{% block content %} + +<div style="clear:both"><!-- --></div> + +<ul id="directories-list"> +{{ display_folder(root, true) }} +</ul> + +{% include "default/rename_directory.html" %} + +{% endblock %} diff --git a/module/web/templates/default/filemanager_ui.js b/module/web/templates/default/filemanager_ui.js new file mode 100644 index 000000000..2808317be --- /dev/null +++ b/module/web/templates/default/filemanager_ui.js @@ -0,0 +1,296 @@ +var load, success, fail, rename_box, confirm_box; + +document.addEvent("domready", function() { + load = new Fx.Tween($("load-indicator"), {link: "cancel"}); + success = new Fx.Tween($("load-success"), {link: "chain"}); + fail = new Fx.Tween($("load-failure"), {link: "chain"}); + + [load,success,fail].each(function(fx) { + fx.set("opacity", 0) + }); + + rename_box = new Fx.Tween($('rename_box')); + confirm_box = new Fx.Tween($('confirm_box')); + $('rename_reset').addEvent('click', function() { + hide_rename_box() + }); + $('delete_reset').addEvent('click', function() { + hide_confirm_box() + }); + + /*$('filemanager_actions_list').getChildren("li").each(function(action) { + var action_name = action.className; + if(functions[action.className] != undefined) + { + action.addEvent('click', functions[action.className]); + } + });*/ +}); + +function indicateLoad() { + //$("load-indicator").reveal(); + load.start("opacity", 1) +} + +function indicateFinish() { + load.start("opacity", 0) +} + +function indicateSuccess() { + indicateFinish(); + notify.alert('{{_("Success")}}.', { + 'className': 'success' + }); +} + +function indicateFail() { + indicateFinish(); + notify.alert('{{_("Failed")}}.', { + 'className': 'error' + }); +} + +function show_rename_box() { + bg_show(); + $("rename_box").setStyle('display', 'block'); + rename_box.start('opacity', 1) +} + +function hide_rename_box() { + bg_hide(); + rename_box.start('opacity', 0).chain(function() { + $('rename_box').setStyle('display', 'none'); + }); +} + +function show_confirm_box() { + bg_show(); + $("confirm_box").setStyle('display', 'block'); + confirm_box.start('opacity', 1) +} + +function hide_confirm_box() { + bg_hide(); + confirm_box.start('opacity', 0).chain(function() { + $('confirm_box').setStyle('display', 'none'); + }); +} + +var FilemanagerUI = new Class({ + initialize: function(url, type) { + this.url = url; + this.type = type; + this.directories = []; + this.files = []; + this.parseChildren(); + }, + + parseChildren: function() { + $("directories-list").getChildren("li.folder").each(function(ele) { + var path = ele.getElements("input.path")[0].get("value"); + var name = ele.getElements("input.name")[0].get("value"); + this.directories.push(new Item(this, path, name, ele)) + }.bind(this)); + + $("directories-list").getChildren("li.file").each(function(ele) { + var path = ele.getElements("input.path")[0].get("value"); + var name = ele.getElements("input.name")[0].get("value"); + this.files.push(new Item(this, path, name, ele)) + }.bind(this)); + } +}); + +var Item = new Class({ + initialize: function(ui, path, name, ele) { + this.ui = ui; + this.path = path; + this.name = name; + this.ele = ele; + this.directories = []; + this.files = []; + this.actions = new Array(); + this.actions["delete"] = this.delete; + this.actions["rename"] = this.rename; + this.actions["mkdir"] = this.mkdir; + this.parseElement(); + + var pname = this.ele.getElements("span")[0]; + this.buttons = new Fx.Tween(this.ele.getElements(".buttons")[0], {link: "cancel"}); + this.buttons.set("opacity", 0); + + pname.addEvent("mouseenter", function(e) { + this.buttons.start("opacity", 1) + }.bind(this)); + + pname.addEvent("mouseleave", function(e) { + this.buttons.start("opacity", 0) + }.bind(this)); + + }, + + parseElement: function() { + this.ele.getChildren('span span.buttons img').each(function(img) { + img.addEvent('click', this.actions[img.className].bind(this)); + }, this); + + //click on the directory name must open the directory itself + this.ele.getElements('b')[0].addEvent('click', this.toggle.bind(this)); + + //iterate over child directories + var uls = this.ele.getElements('ul'); + if(uls.length > 0) + { + uls[0].getChildren("li.folder").each(function(fld) { + var path = fld.getElements("input.path")[0].get("value"); + var name = fld.getElements("input.name")[0].get("value"); + this.directories.push(new Item(this, path, name, fld)); + }.bind(this)); + uls[0].getChildren("li.file").each(function(fld) { + var path = fld.getElements("input.path")[0].get("value"); + var name = fld.getElements("input.name")[0].get("value"); + this.files.push(new Item(this, path, name, fld)); + }.bind(this)); + } + }, + + reorderElements: function() { + //TODO sort the main ul again (to keep data ordered after renaming something) + }, + + delete: function(event) { + $("confirm_form").removeEvents("submit"); + $("confirm_form").addEvent("submit", this.deleteDirectory.bind(this)); + + $$("#confirm_form p").set('html', '{{_(("Are you sure you want to delete the selected item?"))}}'); + + show_confirm_box(); + event.stop(); + }, + + deleteDirectory: function(event) { + hide_confirm_box(); + new Request.JSON({ + method: 'POST', + url: "/json/filemanager/delete", + data: {"path": this.path, "name": this.name}, + onSuccess: function(data) { + if(data.response == "success") + { + new Fx.Tween(this.ele).start('opacity', 0); + var ul = this.ele.parentNode; + this.ele.dispose(); + //if this was the only child, add a "empty folder" div + if(!ul.getChildren('li')[0]) + { + var div = new Element("div", { 'html': '{{ _("Folder is empty") }}' }); + div.replaces(ul); + } + + indicateSuccess(); + } else + { + //error from json code... + indicateFail(); + } + }.bind(this), + onFailure: indicateFail + }).send(); + + event.stop(); + }, + + rename: function(event) { + $("rename_form").removeEvents("submit"); + $("rename_form").addEvent("submit", this.renameDirectory.bind(this)); + + $("path").set("value", this.path); + $("old_name").set("value", this.name); + $("new_name").set("value", this.name); + + show_rename_box(); + event.stop(); + }, + + renameDirectory: function(event) { + hide_rename_box(); + new Request.JSON({ + method: 'POST', + url: "/json/filemanager/rename", + onSuccess: function(data) { + if(data.response == "success") + { + this.name = $("new_name").get("value"); + this.ele.getElements("b")[0].set('html', $("new_name").get("value")); + this.reorderElements(); + indicateSuccess(); + } else + { + //error from json code... + indicateFail(); + } + }.bind(this), + onFailure: indicateFail + }).send($("rename_form").toQueryString()); + + event.stop(); + }, + + mkdir: function(event) { + new Request.JSON({ + method: 'POST', + url: "/json/filemanager/mkdir", + data: {"path": this.path + "/" + this.name, "name": '{{_("New folder")}}'}, + onSuccess: function(data) { + if(data.response == "success") + { + new Request.HTML({ + method: 'POST', + url: "/filemanager/get_dir", + data: {"path": data.path, "name": data.name}, + onSuccess: function(li) { + //add node as first child of ul + var ul = this.ele.getChildren('ul')[0]; + if(!ul) + { + //remove the "Folder Empty" div + this.ele.getChildren('div').dispose(); + + //create new ul to contain subfolder + ul = new Element("ul"); + ul.inject(this.ele, 'bottom'); + } + li[0].inject(ul, 'top'); + + //add directory as a subdirectory of the current item + this.directories.push(new Item(this.ui, data.path, data.name, ul.firstChild)); + }.bind(this), + onFailure: indicateFail + }).send(); + indicateSuccess(); + } else + { + //error from json code... + indicateFail(); + } + }.bind(this), + onFailure: indicateFail + }).send(); + + event.stop(); + }, + + toggle: function() { + var child = this.ele.getElement('ul'); + if(child == null) + child = this.ele.getElement('div'); + + if(child != null) + { + if (child.getStyle('display') == "block") { + child.dissolve(); + } else { + child.reveal(); + } + } + } +}); diff --git a/module/web/templates/default/folder.html b/module/web/templates/default/folder.html new file mode 100644 index 000000000..b385e80cb --- /dev/null +++ b/module/web/templates/default/folder.html @@ -0,0 +1,15 @@ +<li class="folder"> + <input type="hidden" name="path" class="path" value="{{ path }}" /> + <input type="hidden" name="name" class="name" value="{{ name }}" /> + <span> + <b>{{ name }}</b> + <span class="buttons" style="opacity:0"> + <img title="{{_("Rename Directory")}}" class="rename" style="cursor: pointer" height="12px" src="/media/default/img/pencil.png" /> + + <img title="{{_("Delete Directory")}}" class="delete" style="margin-left: -10px; cursor: pointer" width="12px" height="12px" src="/media/default/img/delete.png" /> + + <img title="{{_("Add subdirectory")}}" class="mkdir" style="margin-left: -10px; cursor: pointer" width="12px" height="12px" src="/media/default/img/add_folder.png" /> + </span> + </span> + <div style="display:none">{{ _("Folder is empty") }}</div> +</li>
\ No newline at end of file diff --git a/module/web/templates/default/home.html b/module/web/templates/default/home.html index b2cef2cb7..927287dfc 100644 --- a/module/web/templates/default/home.html +++ b/module/web/templates/default/home.html @@ -205,6 +205,30 @@ var LinkEntry = new Class({ {{_("Active Downloads")}}
{% endblock %}
+{% block menu %}
+<li class="selected">
+ <a href="/" title=""><img src="/media/default/img/head-menu-home.png" alt="" /> {{_("Home")}}</a>
+</li>
+<li>
+ <a href="/queue/" title=""><img src="/media/default/img/head-menu-queue.png" alt="" /> {{_("Queue")}}</a>
+</li>
+<li>
+ <a href="/collector/" title=""><img src="/media/default/img/head-menu-collector.png" alt="" /> {{_("Collector")}}</a>
+</li>
+<li>
+ <a href="/downloads/" title=""><img src="/media/default/img/head-menu-development.png" alt="" /> {{_("Downloads")}}</a>
+</li>
+<li>
+ <a href="/filemanager/" title=""><img src="/media/default/img/head-menu-download.png" alt="" /> {{_("FileManager")}}</a>
+</li>
+<li class="right">
+ <a href="/logs/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-index.png" alt="" />{{_("Logs")}}</a>
+</li>
+<li class="right">
+ <a href="/settings/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-config.png" alt="" />{{_("Config")}}</a>
+</li>
+{% endblock %}
+
{% block content %}
<table width="100%" class="queue">
<thead>
diff --git a/module/web/templates/default/info.html b/module/web/templates/default/info.html index b9ee3b1bd..fabe7aea1 100644 --- a/module/web/templates/default/info.html +++ b/module/web/templates/default/info.html @@ -18,6 +18,13 @@ <h3>{{ _("News") }}</h3> <div id="twitter"></div> + <h3>{{ _("Support") }}</h3> + + <ul> + <li style="font-weight:bold;"><a href="http://forum.pyload.org/" target="_blank">Forum</a></li> + <li style="font-weight:bold;"><a href="http://pyload.org/irc/" target="_blank">Chat</a></li> + </ul> + <h3>{{ _("System") }}</h3> <table class="system"> <tr> diff --git a/module/web/templates/default/logs.html b/module/web/templates/default/logs.html index 7a95b4364..d6288df0e 100644 --- a/module/web/templates/default/logs.html +++ b/module/web/templates/default/logs.html @@ -5,26 +5,6 @@ {% block head %} <link rel="stylesheet" type="text/css" href="/media/default/css/log.css"/> {% endblock %} -{% block menu %} -<li> - <a href="/" title=""><img src="/media/default/img/head-menu-home.png" alt="" /> {{_("Home")}}</a> -</li> -<li> - <a href="/queue/" title=""><img src="/media/default/img/head-menu-queue.png" alt="" /> {{_("Queue")}}</a> -</li> -<li> - <a href="/collector/" title=""><img src="/media/default/img/head-menu-collector.png" alt="" /> {{_("Collector")}}</a> -</li> -<li> - <a href="/downloads/" title=""><img src="/media/default/img/head-menu-development.png" alt="" /> {{_("Downloads")}}</a> -</li> -<li class="right selected"> - <a href="/logs/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-index.png" alt="" />{{_("Logs")}}</a> -</li> -<li class="right"> - <a href="/settings/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-config.png" alt="" />{{_("Config")}}</a> -</li> -{% endblock %} {% block content %} <div style="clear: both;"></div> diff --git a/module/web/templates/default/queue.html b/module/web/templates/default/queue.html index e72871873..104369c11 100644 --- a/module/web/templates/default/queue.html +++ b/module/web/templates/default/queue.html @@ -14,27 +14,6 @@ document.addEvent("domready", function(){ {% block title %}{{_("Queue")}} - {{super()}} {% endblock %}
{% block subtitle %}{{_("Queue")}}{% endblock %}
-{% block menu %}
-<li>
- <a href="/" title=""><img src="/media/default/img/head-menu-home.png" alt="" /> {{_("Home")}}</a>
-</li>
-<li class="selected">
- <a href="/queue/" title=""><img src="/media/default/img/head-menu-queue.png" alt="" /> {{_("Queue")}}</a>
-</li>
-<li>
- <a href="/collector/" title=""><img src="/media/default/img/head-menu-collector.png" alt="" /> {{_("Collector")}}</a>
-</li>
-<li>
- <a href="/downloads/" title=""><img src="/media/default/img/head-menu-development.png" alt="" /> {{_("Downloads")}}</a>
-</li>
-<li class="right">
- <a href="/logs/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-index.png" alt="" />{{_("Logs")}}</a>
-</li>
-<li class="right">
- <a href="/settings/" class="action index" accesskey="x" rel="nofollow"><img src="/media/default/img/head-menu-config.png" alt="" />{{_("Config")}}</a>
-</li>
-{% endblock %}
-
{% block pageactions %}
<ul id="page-actions-more">
<li id="del_finished"><a style="padding: 0; font-weight: bold;" href="#">{{_("Delete Finished")}}</a></li>
@@ -43,12 +22,7 @@ document.addEvent("domready", function(){ {% endblock %}
{% block content %}
-<div id="load-success" style="opacity: 0; float: right; color: white; background-color: #90ee90; padding: 4px; -moz-border-radius: 5px; border-radius: 5px; font-weight: bold; margin-left: -100%; margin-top: -10px;">{{_("success")}}</div>
-<div id="load-failure" style="opacity: 0; float: right; color: white; background-color: #f08080; padding: 4px; -moz-border-radius: 5px; border-radius: 5px; font-weight: bold; margin-left: -100%; margin-top: -10px;">{{_("failure")}}</div>
-<div id="load-indicator" style="opacity: 0; float: right; margin-top: -10px;">
- <img src="/media/default/img/ajax-loader.gif" alt="" style="padding-right: 5px"/>
- {{_("loading")}}
-</div>
+
<ul id="package-list" style="list-style: none; padding-left: 0; margin-top: -10px;">
{% for id, package in content %}
@@ -82,4 +56,4 @@ document.addEvent("domready", function(){ {% include "default/edit_package.html" %}
-{% endblock %}
\ No newline at end of file +{% endblock %}
diff --git a/module/web/templates/default/rename_directory.html b/module/web/templates/default/rename_directory.html new file mode 100644 index 000000000..606573554 --- /dev/null +++ b/module/web/templates/default/rename_directory.html @@ -0,0 +1,28 @@ +<div id="rename_box" class="myform window_box" style="z-index: 2"> + <form id="rename_form" action="/json/filemanager/rename" method="POST" enctype="multipart/form-data"> + <h1>{{_("Rename directory")}}</h1> + <input name="path" id="path" type="hidden" value=""/> + <input name="old_name" id="old_name" type="hidden" value=""/> + + <label for="new_name">{{_("New Name")}} + <span class="small">{{_("Name the selected item must be renamed to.")}}</span> + </label> + <input id="new_name" name="new_name" type="text" size="20" /> + + <button type="submit">{{_("Submit")}}</button> + <button id="rename_reset" style="margin-left: 0" type="reset">{{_("Reset")}}</button> + <div class="spacer"></div> + </form> +</div> + +<div id="confirm_box" class="myform window_box" style="z-index: 2"> + <form id="confirm_form" action="/json/filemanager/delete" method="POST" enctype="multipart/form-data"> + <h1>{{_("Delete directory")}}</h1> + + <p>{{_(("Are you sure?"))}}</p> + + <button type="submit">{{_("Yes")}}</button> + <button id="delete_reset" style="margin-left: 0" type="reset">{{_("No")}}</button> + <div class="spacer"></div> + </form> +</div>
\ No newline at end of file diff --git a/module/web/templates/default/settings.html b/module/web/templates/default/settings.html index df6616e42..fc33ca64a 100644 --- a/module/web/templates/default/settings.html +++ b/module/web/templates/default/settings.html @@ -41,31 +41,6 @@ {% endblock %} -{% block menu %} - <li> - <a href="/" title=""><img src="/media/default/img/head-menu-home.png" alt=""/> {{ _("Home") }}</a> - </li> - <li> - <a href="/queue/" title=""><img src="/media/default/img/head-menu-queue.png" alt=""/> {{ _("Queue") }}</a> - </li> - <li> - <a href="/collector/" title=""><img src="/media/default/img/head-menu-collector.png" - alt=""/> {{ _("Collector") }}</a> - </li> - <li> - <a href="/downloads/" title=""><img src="/media/default/img/head-menu-development.png" - alt=""/> {{ _("Downloads") }}</a> - </li> - <li class="right"> - <a href="/logs/" class="action index" accesskey="x" rel="nofollow"><img - src="/media/default/img/head-menu-index.png" alt=""/>{{ _("Logs") }}</a> - </li> - <li class="right selected"> - <a href="/settings/" class="action index" accesskey="x" rel="nofollow"><img - src="/media/default/img/head-menu-config.png" alt=""/>{{ _("Config") }}</a> - </li> -{% endblock %} - {% block content %} <ul id="toptabs" class="tabs"> diff --git a/module/web/utils.py b/module/web/utils.py index afe5ac60c..fccfb78d6 100644 --- a/module/web/utils.py +++ b/module/web/utils.py @@ -35,6 +35,7 @@ def parse_permissions(session): "status": False, "see_downloads": False, "download" : False, + "filemanager" : False, "settings": False, "is_admin": False} @@ -58,6 +59,7 @@ def get_permission(perms, p): perms["see_downloads"] = has_permission(p, PERMS.SEE_DOWNLOADS) perms["download"] = has_permission(p, PERMS.DOWNLOAD) perms["settings"] = has_permission(p, PERMS.SETTINGS) + perms["filemanager"] = has_permission(p, PERMS.FILEMANAGER) def set_permission(perms): permission = 0 @@ -73,6 +75,8 @@ def set_permission(perms): permission |= PERMS.DOWNLOAD if perms["settings"]: permission |= PERMS.SETTINGS + if perms["filemanager"]: + permission |= PERMS.FILEMANAGER return permission |