start of torrent-move,-options,-files

This commit is contained in:
Martijn Voncken 2008-02-15 18:11:34 +00:00
parent e03a516cb5
commit c1b8d6e880
18 changed files with 391 additions and 104 deletions

View file

@ -133,6 +133,8 @@ class ServerFolder(newforms.CharField):
newforms.CharField.__init__(self, label=label,**kwargs)
def clean(self, value):
if value == None:
value = ""
value = value.rstrip('/').rstrip('\\')
self.validate(value)
return newforms.CharField.clean(self, value)

View file

@ -38,6 +38,8 @@ import page_decorators as deco
import config_tabs_webui #auto registers
import config_tabs_deluge #auto registers
from config import config_page
import torrent_options
from torrent_move import torrent_move
#import forms
#
from debugerror import deluge_debugerror
@ -68,6 +70,7 @@ urls = (
"/torrent/reannounce/(.*)", "torrent_reannounce",
"/torrent/add(.*)", "torrent_add",
"/torrent/delete/(.*)", "torrent_delete",
"/torrent/move/(.*)", "torrent_move",
"/torrent/queue/up/(.*)", "torrent_queue_up",
"/torrent/queue/down/(.*)", "torrent_queue_down",
"/pause_all", "pause_all",
@ -155,9 +158,15 @@ class torrent_info:
class torrent_info_inner:
@deco.deluge_page
def GET(self, torrent_ids):
vars = web.input(tab = None)
if vars.tab:
active_tab = vars.tab
else:
active_tab = getcookie("torrent_info_tab") or "details"
setcookie("torrent_info_tab", active_tab)
torrent_ids = torrent_ids.split(',')
info = get_torrent_status(torrent_ids[0])
return render.torrent_info_inner(info)
return render.torrent_info_inner(info, active_tab)
class torrent_start:
@deco.check_session
@ -219,6 +228,7 @@ class torrent_delete:
ws.proxy.remove_torrent(torrent_ids, torrent_also, data_also)
do_redirect()
class torrent_queue_up:
@deco.check_session
def POST(self, name):

View file

@ -89,7 +89,7 @@ def template_crop(text, end):
return "[ERROR NOT A STRING:(%s)]" % text
return text
def template_crop_right(text, maxlen):
def template_crop_left(text, maxlen):
try:
if len(text) > maxlen:
return "..." + text[-(maxlen + 3):]
@ -145,7 +145,7 @@ template.Template.globals.update({
'part_stats':template_part_stats,
'category_tabs':category_tabs,
'crop': template_crop,
'crop_right': template_crop_right,
'crop_left': template_crop_left,
'_': _ , #gettext/translations
'str': str, #because % in templetor is broken.
'int':int,
@ -162,7 +162,10 @@ template.Template.globals.update({
'version': VERSION,
'getcookie':getcookie,
'get': lambda (var): getattr(web.input(**{var:None}), var), # unreadable :-(
'env':ws.env
'env':ws.env,
'forms':web.Storage(),
'enumerate':enumerate
})
#/template-defs

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

View file

@ -120,4 +120,8 @@ th {
background-color:none;
}
h3 {
background-color:#68a;
text-align:left;
}
/* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */

View file

@ -50,6 +50,12 @@ $for t in torrent_list:
title='$_("Details")'><img class='toolbar_btn'
src='/static/images/tango/details.png'></a>
<a class='toolbar_btn' href="#"
onclick='toolbar_get("/torrent/move/",2)'
title='$_("Move")'><img class='toolbar_btn'
src='/static/images/tango/move.png'></a>
$:category_tabs(all_torrents)
</div>

View file

@ -332,6 +332,32 @@ th.newforms {
text-align:right;
color:#FFFFFF;
}
a.tab_button {
color:#FFFFFF;
text-decoration:none;
}
a.tab_button:visited {
color:#FFFFFF;
}
a.tab_button:hover {
background-color:#68a;
}
a.tab_button_active {
background-color:#900;
text-decoration:none;
color:#FFFFFF;
}
a.tab_button_active:visited {
background-color:#900;
color:#FFFFFF;
}
h3 {
background-color:#68a;
text-align:left;
}
/* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */

View file

@ -1,15 +1,22 @@
$def with (torrent)
$def with (torrent, active_tab)
<!--for iframe in javascript mode.-->
<html><head>
<html>
<head>
<title>Deluge:$torrent.name</title>
<link rel="icon" href="/static/images/deluge_icon.gif" type="image/gif" />
<link rel="shortcut icon" href="/static/images/deluge_icon.gif" type="image/gif" />
<link rel="stylesheet" type="text/css" href="/static/simple_site_style.css" />
<link rel="stylesheet" type="text/css" href="/template/static/advanced.css" />
</head>
<body class="inner">
<!--[Tab :Details] [Tab : Files] [Tab : Peers]-->
$:render.tab_meta(torrent)
$:render.footer()
$:render.part_tab_button('details', _("Details"), active_tab)
$:render.part_tab_button('files', _("Files"), active_tab)
$:render.part_tab_button('options', _("Options"), active_tab)
$if active_tab == 'details':
$:render.tab_meta(torrent)
$if active_tab == 'files':
$:render.tab_files(torrent)
$if active_tab == 'options':
$:render.tab_options(torrent)
</body>
</html>

View file

@ -4,6 +4,17 @@ $def with (torrent)
<table width="100%">
$altrow(True)
<tr class="tab_$altrow()"><th>$_("File")</th><th>$_("Size")</th></tr>
$for file in torrent.files:
<tr class="tab_$altrow()" title="$file["path"]"><td>$(crop_right(file["path"], 70))</td><td>$fsize(file["size"])</td></tr>
$for i, file in enumerate(torrent.files):
<tr class="tab_$altrow()" >
<td title="$file['path']">
<input type="checkbox"
$if (torrent.file_priorities[i]):
checked
>
$(crop_left(file["path"], 70))
</td>
<td>$fsize(file["size"])</td></tr>
</table>
<div class="error">Save/update: Todo</div>

View file

@ -27,8 +27,13 @@ $def with (torrent)
<td class="info_value">$torrent.num_pieces x $fsize(torrent.piece_length) </td>
</tr>
<tr><td class="info_label">&nbsp;</td>
<td class="info_value">&nbsp; </td>
<tr><td class="info_label">$_('Allocation'):</td>
<td class="info_value">
$if torrent.compact:
$_('Compact')
$else:
$_('Full')
</td>
</table>
@ -50,10 +55,11 @@ $fspeed(torrent.download_rate)</td></td></tr>
<tr><td class="info_label">$_('Availability'):</td>
<td class="info_value">$("%.3f" % torrent.distributed_copies)</td></td></tr>
<tr><td class="info_label">&nbsp;</td>
<td class="info_value">&nbsp; </td>
</tr>
<tr><td class="info_label">$_('Queue Position'):</td>
<td class="info_value">$torrent.queue_pos </td>
</tr>
</table>
@ -68,17 +74,16 @@ $fspeed(torrent.download_rate)</td></td></tr>
<td class="info_value">$torrent.num_files</td></tr>
<tr><td class="info_label">$_('Tracker'):</td>
<td class="info_value" title="$torrent.tracker">$(crop(torrent.tracker, 30))</td></tr>
<td class="info_value" title="$torrent.tracker">$(crop(torrent.tracker, 25))</td></tr>
<tr><td class="info_label">$_('Tracker Status'):</td>
<td class="info_value" title="$torrent.tracker_status">$(crop(torrent.tracker_status, 30)) </td></tr>
<td class="info_value" title="$torrent.tracker_status">$(crop(torrent.tracker_status, 25)) </td></tr>
<tr><td class="info_label">$_('Next Announce'):</td>
<td class="info_value">$torrent.next_announce </td></tr>
<tr><td class="info_label">$_('Queue Position'):</td>
<td class="info_value">$torrent.queue_pos </td>
<tr><td class="info_label">$('Save Path'):</td>
<td class="info_value" title="$torrent.save_path">$crop_left(torrent.save_path, 25)</td>
</tr>
</table>

View file

@ -0,0 +1,19 @@
$def with (torrent)
<form>
<table><tr><td valign="top">
<table>
$:(forms.torrent_options(torrent).as_table(["max_download_speed", "max_upload_speed", "max_connections", "max_upload_slots"]))
<!--<tr><td></td><td><input type="submit" value="$_('Update')"></td></tr>-->
</table>
</td><td valign="top">
<table>
$:(forms.torrent_options(torrent).as_table(["prioritize_first_last", "private"]))
</table>
</tr></table>
<div class="error">Save/update: Todo</div>
</form>

View file

@ -3,9 +3,6 @@ $def with (torrent)
$:(render.header(torrent.message + '/' + torrent.name))
<div class="panel">
<h3>$_('Details')</h3>
$:render.tab_meta(torrent)
$if (torrent.action == 'start'):
$:render.part_button('POST', '/torrent/start/' + str(torrent.id), _('Resume'), 'tango/start.png')
$else:
@ -18,9 +15,20 @@ $:render.part_button('POST', '/torrent/reannounce/' + str(torrent.id), _('Reanno
$:render.part_button('POST', '/torrent/queue/up/' + str(torrent.id), _('Queue Up'), 'tango/queue-up.png')
$:render.part_button('POST', '/torrent/queue/down/' + str(torrent.id), _('Queue Down'), 'tango/queue-down.png')
<br>
$:render.part_button('GET', '/torrent/move/' + str(torrent.id), _('Move'), 'tango/move.png')
<h3>$_('Details')</h3>
$:render.tab_meta(torrent)
<h3>$_('Files')</h3>
$:render.tab_files(torrent)
<h3>$_('Options')</h3>
$:render.tab_options(torrent)
<br>
<!--
[<a onclick="javascript:toggle_dump()">$_('Debug:Data Dump')</a>]

View file

@ -0,0 +1,23 @@
$def with (torrent_ids, torrent_list, form, error)
$:render.header(_("Remove torrent"))
<div class="panel">
<form method="POST" action='/torrent/move/$torrent_ids'>
<div id="del_torrent">
<h2>$_("Move torrent")</h2>
<ul>
$for torrent in torrent_list:
<li>$torrent.name ($torrent.save_path)</li>
</ul>
<!--
$if error:
<div class="error">$error</div>
-->
<div class="error">not working yet, but close..</div>
$:form.as_table()
<input type="submit" name="submit" value="$_('Move')" class="form_input">
</form>
</div>
$:render.footer()

View file

@ -7,82 +7,100 @@ from WebUi.webserver_common import ws
ws.init_06()
async_proxy = ws.async_proxy
#
#A: translate this into 1 multicall:
start = time.time()
stats = {
'download_rate':ws.proxy.get_download_rate(),
'upload_rate':ws.proxy.get_upload_rate(),
'max_download':ws.proxy.get_config_value('max_download_speed'),
'max_upload':ws.proxy.get_config_value('max_upload_speed'),
'num_connections':ws.proxy.get_num_connections(),
'max_num_connections':ws.proxy.get_config_value('max_connections_global')
}
print "sync-stats:",time.time() - start
print stats
#
#map callback to a a dict-setter
def dict_cb(key,d):
def callback(result):
d[key] = result
return callback
start = time.time()
d = {}
async_proxy.get_download_rate(dict_cb('download_rate',d))
async_proxy.get_upload_rate(dict_cb('upload_rate',d))
async_proxy.get_config_value(dict_cb('max_download',d),"max_download_speed")
async_proxy.get_config_value(dict_cb('max_upload',d),"max_upload_speed")
async_proxy.get_num_connections(dict_cb("num_connections",d))
async_proxy.get_config_value(dict_cb('max_num_connections',d),"max_connections_global")
async_proxy.force_call(block=True)
print "Async-stats:",time.time() - start
print d
#
#B: translate this to multicall:
#
#old-sync:
start = time.time()
torrent_list = [ws.proxy.get_torrent_status(id,[])
for id in ws.proxy.get_session_state()
TORRENT_KEYS = ['name', 'total_size', 'num_files', 'num_pieces', 'piece_length',
'eta', 'ratio', 'file_progress', 'distributed_copies', 'total_done',
'total_uploaded', 'state', 'paused', 'progress', 'next_announce',
'total_payload_download', 'total_payload_upload', 'download_payload_rate',
'upload_payload_rate', 'num_peers', 'num_seeds', 'total_peers', 'total_seeds',
'total_wanted', 'tracker', 'trackers', 'tracker_status', 'save_path',
'files', 'file_priorities', 'compact', 'max_connections',
'max_upload_slots', 'max_download_speed', 'prioritize_first_last', 'private'
]
print "sync-list:",time.time() - start
print torrent_list
#new async:
start = time.time()
torrent_ids = ws.proxy.get_session_state() #Syc-api.
torrent_dict = {}
for id in torrent_ids:
async_proxy.get_torrent_status(dict_cb(id,torrent_dict), id, [])
async_proxy.force_call(block=True)
print "Async-list:",time.time() - start
print "\n".join(torrent_dict[torrent_ids[0]].keys())
print torrent_dict[torrent_ids[0]]["files"]
if False:
#
#A: translate this into 1 multicall:
start = time.time()
stats = {
'download_rate':ws.proxy.get_download_rate(),
'upload_rate':ws.proxy.get_upload_rate(),
'max_download':ws.proxy.get_config_value('max_download_speed'),
'max_upload':ws.proxy.get_config_value('max_upload_speed'),
'num_connections':ws.proxy.get_num_connections(),
'max_num_connections':ws.proxy.get_config_value('max_connections_global')
}
print "sync-stats:",time.time() - start
print stats
#
#map callback to a a dict-setter
def dict_cb(key,d):
def callback(result):
d[key] = result
return callback
start = time.time()
d = {}
async_proxy.get_download_rate(dict_cb('download_rate',d))
async_proxy.get_upload_rate(dict_cb('upload_rate',d))
async_proxy.get_config_value(dict_cb('max_download',d),"max_download_speed")
async_proxy.get_config_value(dict_cb('max_upload',d),"max_upload_speed")
async_proxy.get_num_connections(dict_cb("num_connections",d))
async_proxy.get_config_value(dict_cb('max_num_connections',d),"max_connections_global")
async_proxy.force_call(block=True)
print "Async-stats:",time.time() - start
print d
#
#B: translate this to multicall:
#
#old-sync:
start = time.time()
torrent_list = [ws.proxy.get_torrent_status(id, TORRENT_KEYS )
for id in ws.proxy.get_session_state()
]
print "sync-list:",time.time() - start
print torrent_list[0]
#new async:
"""
torrent.compact,
torrent.max_connections,
torrent.max_upload_slots,
torrent.max_upload_speed,
torrent.max_download_speed,
torrent.prioritize_first_last,
torrent.private
"""
start = time.time()
torrent_ids = ws.proxy.get_session_state() #Syc-api.
torrent_dict = {}
for id in torrent_ids:
async_proxy.get_torrent_status(dict_cb(id,torrent_dict), id, TORRENT_KEYS )
async_proxy.force_call(block=True)
print "Async-list:",time.time() - start
print "\n".join(torrent_dict[torrent_ids[0]].keys())
print torrent_dict[torrent_ids[0]]
if False:
print ws.proxy.get_config_value('download_location')
if True:
torrent_id = ws.proxy.get_session_state()[0]
print torrent_id
ws.proxy.move_torrent([torrent_id],"/media/sdb1/test")

View file

@ -70,7 +70,12 @@ class AddForm(forms.Form):
class torrent_add:
def add_page(self,error = None):
form_data = utils.get_newforms_data(AddForm)
#form_data = utils.get_newforms_data(AddForm)
#TODO: CLEANUP!!!
vars = web.input(url = None)
form_data = {'url':vars.url}
options_data = None
if error:
options_data = utils.get_newforms_data(OptionsForm)

View file

@ -0,0 +1,74 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) Martijn Voncken 2008 <mvoncken@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# exception, you may extend this exception to your version of the file(s),
# but you are not obligated to do so. If you do not wish to do so, delete
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
from webserver_common import ws
import utils
from render import render
import page_decorators as deco
import lib.newforms_plus as forms
import lib.webpy022 as web
#Too much boilerplate code here, todo : fix it.
class MoveForm(forms.Form):
save_path = forms.ServerFolder(_("Move To"))
def initial_data(self):
return {'save_path':ws.proxy.get_config_value('download_location')}
class torrent_move:
def move_page(self, name, error = None):
torrent_ids = name.split(',')
torrent_list = [utils.get_torrent_status(id) for id in torrent_ids]
data = None
if error:
data = utils.get_newforms_data(MoveForm)
form = MoveForm(data)
return render.torrent_move(name, torrent_list , form, error)
@deco.deluge_page
def GET(self, name):
return self.move_page(name)
@deco.check_session
def POST(self, name):
torrent_ids = name.split(',')
form = MoveForm(utils.get_newforms_data(MoveForm))
if not form.is_valid():
print self.move_page(name, error = _("Error in Path."))
return
save_path = form.clean_data["save_path"]
ws.proxy.move_torrent(torrent_ids, save_path)
utils.do_redirect()

View file

@ -0,0 +1,54 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) Martijn Voncken 2008 <mvoncken@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# exception, you may extend this exception to your version of the file(s),
# but you are not obligated to do so. If you do not wish to do so, delete
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
from webserver_common import ws
import utils
from render import template
import page_decorators as deco
import lib.newforms_plus as forms
import lib.webpy022 as web
class TorrentOptionsForm(forms.Form):
#download
max_download_speed = forms.DelugeFloat(
_("Maximum Down Speed"))
max_upload_speed = forms.DelugeFloat(
_("Maximum Up Speed"))
max_connections = forms.DelugeInt(_("Maximum Connections"))
max_upload_slots = forms.DelugeInt(_("Maximum Upload Slots"))
#general
prioritize_first_last = forms.CheckBox(
_('Prioritize first and last pieces'))
private = forms.CheckBox(_('Private Flag'))
template.Template.globals["forms"].torrent_options = lambda torrent : TorrentOptionsForm(torrent)

View file

@ -64,14 +64,26 @@ try:
except:
VERSION = '<unknown:bzr-branch?>'
TORRENT_KEYS = ['distributed_copies', 'download_payload_rate',
'eta', 'is_seed', 'name', 'next_announce',
'num_files', 'num_peers', 'num_pieces', 'num_seeds', 'paused',
'piece_length','progress', 'ratio', 'total_done', 'total_download',
'total_payload_download', 'total_payload_upload', 'total_peers',
'total_seeds', 'total_size', 'total_upload', 'total_wanted',
'tracker_status', 'upload_payload_rate',
'uploaded_memory','tracker','state','queue_pos','user_paused','files']
TORRENT_KEYS = ['name', 'total_size', 'num_files', 'num_pieces', 'piece_length',
'eta', 'ratio', 'file_progress', 'distributed_copies', 'total_done',
'total_uploaded', 'state', 'paused', 'progress', 'next_announce',
'total_payload_download', 'total_payload_upload', 'download_payload_rate',
'upload_payload_rate', 'num_peers', 'num_seeds', 'total_peers', 'total_seeds',
'total_wanted', 'tracker', 'trackers', 'tracker_status', 'save_path',
'files', 'file_priorities', 'compact', 'max_connections',
'max_upload_slots', 'max_download_speed', 'prioritize_first_last',
'private','max_upload_speed',
#REMOVE:
"is_seed","total_download","total_upload","uploaded_memory","queue_pos",
"user_paused"
]
"""
NOT:is_seed,total_download,total_upload,uploaded_memory,queue_pos,user_paused
"""
STATE_MESSAGES = (_("Queued"),
_("Checking"),