summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO8
-rw-r--r--PKGBUILD10
-rw-r--r--ps-dl-ui-find_all.patch43
-rw-r--r--ui_pyroscope.cc111
-rw-r--r--ui_pyroscope.h1
5 files changed, 142 insertions, 31 deletions
diff --git a/.SRCINFO b/.SRCINFO
index c8eb043b6fd4..6c96c08974ec 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,6 +1,6 @@
pkgbase = rtorrent-ps
pkgdesc = Extended rTorrent distribution with UI enhancements, colorization, and some added features
- pkgver = 1.1.r15.g56057fc
+ pkgver = 1.1.r29.g78a68a0
pkgrel = 1
url = https://github.com/pyroscope/rtorrent-ps
arch = any
@@ -14,6 +14,7 @@ pkgbase = rtorrent-ps
source = https://github.com/rakshasa/rtorrent/archive/0.9.6.tar.gz
source = backport_0.9.6_algorithm_median.patch
source = command_pyroscope.cc
+ source = ps-dl-ui-find_all.patch
source = ps-event-view_all.patch
source = ps-fix-double-slash-319_all.patch
source = ps-fix-log-xmlrpc-close_all.patch
@@ -40,6 +41,7 @@ pkgbase = rtorrent-ps
md5sums = b8b4009f95f8543244ae1d23b1810d7c
md5sums = b49903d3fa25a66c72db69570dfe8b47
md5sums = e7f737e4b2c4db9659faf2609a17732e
+ md5sums = 27e2b4099fa2b943812d80d9306dab79
md5sums = fbe511a1dfe89fe0510a077e61ae6ec7
md5sums = 22fae392c6e281dc438b39a5019e7e1b
md5sums = 1b4f82e6123c5baa0cd07056e368064e
@@ -60,8 +62,8 @@ pkgbase = rtorrent-ps
md5sums = 26faff00b306b6ef276a7d9e6d964994
md5sums = bd04a0699b80c8042e1cf63a7e0e4222
md5sums = d0a956f0eb4b53b66d83df2a8a4d16dc
- md5sums = 88c3520c6ba51a31ea29903b5ee6c484
- md5sums = a572a0fd087c89d8f50f16544bb1ec69
+ md5sums = d6eb433a0516d987ac1054e8b14e8129
+ md5sums = a4528366d1839ee400e51abc793446f5
md5sums = 0a2bbaf74c7160ba33876dcc2f050f14
pkgname = rtorrent-ps
diff --git a/PKGBUILD b/PKGBUILD
index 900f76d8095a..607978feddc2 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -3,7 +3,7 @@
_pkgname=rtorrent
pkgname=rtorrent-ps
_pkgver=0.9.6
-pkgver=1.1.r15.g56057fc
+pkgver=1.1.r29.g78a68a0
pkgrel=1
pkgdesc='Extended rTorrent distribution with UI enhancements, colorization, and some added features'
url='https://github.com/pyroscope/rtorrent-ps'
@@ -15,6 +15,7 @@ conflicts=('rtorrent')
source=("https://github.com/rakshasa/$_pkgname/archive/$_pkgver.tar.gz"
'backport_0.9.6_algorithm_median.patch'
'command_pyroscope.cc'
+ 'ps-dl-ui-find_all.patch'
'ps-event-view_all.patch'
'ps-fix-double-slash-319_all.patch'
'ps-fix-log-xmlrpc-close_all.patch'
@@ -41,6 +42,7 @@ source=("https://github.com/rakshasa/$_pkgname/archive/$_pkgver.tar.gz"
md5sums=('b8b4009f95f8543244ae1d23b1810d7c'
'b49903d3fa25a66c72db69570dfe8b47'
'e7f737e4b2c4db9659faf2609a17732e'
+ '27e2b4099fa2b943812d80d9306dab79'
'fbe511a1dfe89fe0510a077e61ae6ec7'
'22fae392c6e281dc438b39a5019e7e1b'
'1b4f82e6123c5baa0cd07056e368064e'
@@ -61,8 +63,8 @@ md5sums=('b8b4009f95f8543244ae1d23b1810d7c'
'26faff00b306b6ef276a7d9e6d964994'
'bd04a0699b80c8042e1cf63a7e0e4222'
'd0a956f0eb4b53b66d83df2a8a4d16dc'
- '88c3520c6ba51a31ea29903b5ee6c484'
- 'a572a0fd087c89d8f50f16544bb1ec69'
+ 'd6eb433a0516d987ac1054e8b14e8129'
+ 'a4528366d1839ee400e51abc793446f5'
'0a2bbaf74c7160ba33876dcc2f050f14')
prepare() {
@@ -115,7 +117,7 @@ package() {
make DESTDIR="$pkgdir" install
- install -Dm644 "doc/faq.xml" "$pkgdir/usr/share/doc/$_pkgname/faq.xml"
+ install -Dm644 "doc/faq.xml" "$pkgdir/usr/share/doc/$_pkgname/faq.xml"
install -Dm644 "doc/old/rtorrent.1" "$pkgdir/usr/share/man/man1/$_pkgname.1"
install -Dm644 "doc/rtorrent.rc" "$pkgdir/usr/share/doc/$_pkgname/rtorrent.rc"
install -Dm644 "doc/rtorrent_fast_resume.pl" "$pkgdir/usr/share/doc/$_pkgname/rtorrent_fast_resume.pl"
diff --git a/ps-dl-ui-find_all.patch b/ps-dl-ui-find_all.patch
new file mode 100644
index 000000000000..8392ce212593
--- /dev/null
+++ b/ps-dl-ui-find_all.patch
@@ -0,0 +1,43 @@
+--- a/src/ui/download_list.cc
++++ b/src/ui/download_list.cc
+@@ -259,6 +259,10 @@ DownloadList::receive_view_input(Input type) {
+ title = "command";
+ break;
+
++ case INPUT_FIND:
++ title = "find";
++ break;
++
+ default:
+ throw torrent::internal_error("DownloadList::receive_view_input(...) Invalid input type.");
+ }
+@@ -322,6 +326,11 @@ DownloadList::receive_exit_input(Input type) {
+ input->str());
+ break;
+
++ case INPUT_FIND:
++ rpc::call_command("ui.find.term.set", rak::trim(input->str()), rpc::make_target());
++ rpc::call_command("ui.find.next", torrent::Object(), rpc::make_target());
++ break;
++
+ default:
+ throw torrent::internal_error("DownloadList::receive_exit_input(...) Invalid input type.");
+ }
+@@ -353,2 +362,5 @@ DownloadList::setup_keys() {
+ m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['l'] = std::bind(&DownloadList::activate_display, this, DISPLAY_LOG);
++
++ // Replace Ctrl-F binding for setting 'ui.find.term'
++ m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['F' - '@'] = std::bind(&DownloadList::receive_view_input, this, INPUT_FIND);
+ }
+--- a/src/ui/download_list.h
++++ b/src/ui/download_list.h
+@@ -86,7 +86,8 @@ public:
+ INPUT_LOAD_DEFAULT,
+ INPUT_LOAD_MODIFIED,
+ INPUT_CHANGE_DIRECTORY,
+- INPUT_COMMAND
++ INPUT_COMMAND,
++ INPUT_FIND
+ } Input;
+
+ DownloadList();
diff --git a/ui_pyroscope.cc b/ui_pyroscope.cc
index 06db8c6725c7..d9dd1edd00a8 100644
--- a/ui_pyroscope.cc
+++ b/ui_pyroscope.cc
@@ -385,35 +385,38 @@ torrent::Object ui_canvas_color_set(const torrent::Object::string_type& arg) {
int64_t cmd_d_message_alert(core::Download* d) {
int64_t alert = ps::ALERT_NORMAL;
+ const std::string& msg = d->message();
- if (!d->message().empty()) {
+ if (!msg.empty()) {
alert = ps::ALERT_GENERIC;
- if (d->message().find("Tried all trackers") != std::string::npos)
+ if (msg.find("Tried all trackers") != std::string::npos)
alert = ps::ALERT_NORMAL_CYCLING;
- else if (d->message().find("Timeout was reached") != std::string::npos
- || d->message().find("Timed out") != std::string::npos)
+ else if (msg.find("no data") != std::string::npos)
+ alert = ps::ALERT_NORMAL_GHOST;
+ else if (msg.find("Timeout was reached") != std::string::npos
+ || msg.find("Timed out") != std::string::npos)
alert = ps::ALERT_TIMEOUT;
- else if (d->message().find("Connecting to") != std::string::npos)
+ else if (msg.find("Connecting to") != std::string::npos)
alert = ps::ALERT_CONNECT;
- else if (d->message().find("Could not parse bencoded data") != std::string::npos
- || d->message().find("Failed sending data") != std::string::npos
- || d->message().find("Server returned nothing") != std::string::npos
- || d->message().find("Couldn't connect to server") != std::string::npos)
+ else if (msg.find("Could not parse bencoded data") != std::string::npos
+ || msg.find("Failed sending data") != std::string::npos
+ || msg.find("Server returned nothing") != std::string::npos
+ || msg.find("Couldn't connect to server") != std::string::npos)
alert = ps::ALERT_REQUEST;
- else if (d->message().find("not registered") != std::string::npos
- || d->message().find("torrent cannot be found") != std::string::npos
- || d->message().find("nregistered") != std::string::npos)
+ else if (msg.find("not registered") != std::string::npos
+ || msg.find("torrent cannot be found") != std::string::npos
+ || msg.find("nregistered") != std::string::npos)
alert = ps::ALERT_GONE;
- else if (d->message().find("not authorized") != std::string::npos
- || d->message().find("blocked from") != std::string::npos
- || d->message().find("denied") != std::string::npos
- || d->message().find("limit exceeded") != std::string::npos
- || d->message().find("active torrents are enough") != std::string::npos)
+ else if (msg.find("not authorized") != std::string::npos
+ || msg.find("blocked from") != std::string::npos
+ || msg.find("denied") != std::string::npos
+ || msg.find("limit exceeded") != std::string::npos
+ || msg.find("active torrents are enough") != std::string::npos)
alert = ps::ALERT_PERMS;
- else if (d->message().find("tracker is down") != std::string::npos)
+ else if (msg.find("tracker is down") != std::string::npos)
alert = ps::ALERT_DOWN;
- else if (d->message().find("n't resolve host name") != std::string::npos)
+ else if (msg.find("n't resolve host name") != std::string::npos)
alert = ps::ALERT_DNS;
}
@@ -438,7 +441,7 @@ torrent::Object cmd_d_tracker_alias(core::Download* download) {
static void decorate_download_title(Window* window, display::Canvas* canvas, core::View* view,
- int pos, Range& range, int x_title) {
+ int pos, Range& range, int x_title, size_t hilite, size_t hilen) {
int offset = row_offset(view, range);
core::Download* item = *range.first;
bool active = item->is_open() && item->is_active();
@@ -455,6 +458,10 @@ static void decorate_download_title(Window* window, display::Canvas* canvas, cor
title_col = (active ? D_INFO(item)->down_rate()->rate() ?
ps::COL_LEECHING : ps::COL_INCOMPLETE : ps::COL_QUEUED) + offset;
canvas->set_attr(x_title, pos, -1, attr_map[title_col] | focus_attr, title_col);
+ if (hilen && hilite != std::string::npos && x_title + hilite < int(canvas->width())) {
+ canvas->set_attr(x_title + hilite, pos, std::min(hilen, int(canvas->width()) - x_title - hilite),
+ (attr_map[title_col] | focus_attr | A_REVERSE) ^ A_BOLD, title_col);
+ }
// show label for active tracker (a/k/a in focus tracker)
if (int(canvas->width()) <= x_title + NAME_RESERVED_WIDTH + 3) return;
@@ -505,7 +512,7 @@ void ui_pyroscope_download_list_redraw_item(Window* window, display::Canvas* can
}
}
- decorate_download_title(window, canvas, view, pos, range, 2);
+ decorate_download_title(window, canvas, view, pos, range, 2, -1, 0);
// better handling for trail of line 2 (ratio etc.)
int status_pos = 91;
@@ -763,7 +770,8 @@ int render_columns(bool headers, bool narrow, rpc::target_type target, core::Dow
case ps::COL_ALERT: // COL_ALARM is the actual color, this is the dynamic one
bool has_alert = !item->message().empty()
&& item->message().find("Tried all trackers") == std::string::npos;
- attr_idx = has_alert ? ps::COL_ALARM : ps::COL_INFO;
+ bool no_data = item->message().find("no data") != std::string::npos;
+ attr_idx = no_data ? ps::COL_PROGRESS0 : has_alert ? ps::COL_ALARM : ps::COL_INFO;
break;
}
}
@@ -810,6 +818,8 @@ bool ui_pyroscope_download_list_redraw(Window* window, display::Canvas* canvas,
const torrent::Object::map_type& column_defs = control->object_storage()->get_str("ui.column.render").as_map();
int pos = 1, x_base = 2, column = x_base;
bool narrow = false;
+ std::string find_term = rpc::call_command_string("ui.find.term");
+ std::transform(find_term.begin(), find_term.end(), find_term.begin(), ::tolower);
// Render header line
canvas->print(0, pos, "⇳ ");
@@ -864,7 +874,13 @@ bool ui_pyroscope_download_list_redraw(Window* window, display::Canvas* canvas,
canvas->print(column, pos, " %s",
u8_chop(displayname.empty() ? d->info()->name() : displayname.c_str(),
canvas->width() - column - 1).c_str());
- decorate_download_title(window, canvas, view, pos, range, column + 1);
+ size_t hilite = std::string::npos;
+ if (!find_term.empty()) {
+ if (displayname.empty()) displayname = d->info()->name();
+ std::transform(displayname.begin(), displayname.end(), displayname.begin(), ::tolower);
+ hilite = displayname.find(find_term);
+ }
+ decorate_download_title(window, canvas, view, pos, range, column + 1, hilite, find_term.length());
}
// Colorize focus marker
@@ -1054,6 +1070,46 @@ torrent::Object apply_magnitude(const torrent::Object::list_type& args) {
}
+torrent::Object ui_find_next() {
+ std::string term = rpc::call_command_string("ui.find.term");
+ if (term.empty())
+ return torrent::Object(); // no current search term set
+ std::transform(term.begin(), term.end(), term.begin(), ::tolower);
+
+ ui::DownloadList* dl_list = control->ui()->download_list();
+ core::View* dl_view = dl_list->current_view();
+
+ if (dl_view->empty_visible()) {
+ control->core()->push_log("This view is empty, nothing to find!");
+ } else {
+ core::View::iterator itr = dl_view->focus() == dl_view->end_visible() ?
+ dl_view->begin_visible() : dl_view->focus();
+ bool found = false;
+
+ do {
+ if (++itr == dl_view->end_visible())
+ itr = dl_view->begin_visible();
+
+ // In C++11, this can be done more efficiently using std::search;
+ // we only use this interactively, so meh.
+ std::string name = get_custom_string(*itr, "displayname");
+ if (name.empty()) name = (*itr)->info()->name();
+ std::transform(name.begin(), name.end(), name.begin(), ::tolower);
+ found = name.find(term) != std::string::npos;
+ } while (!found && itr != dl_view->focus());
+
+ if (!found) {
+ control->core()->push_log(("Cannot find anything matching '" + term + "'").c_str());
+ } else if (itr != dl_view->focus()) {
+ dl_view->set_focus(itr);
+ dl_view->set_last_changed();
+ }
+ }
+
+ return torrent::Object();
+}
+
+
// register our commands
void initialize_command_ui_pyroscope() {
#define PS_VARIABLE_COLOR(key, value) \
@@ -1091,6 +1147,9 @@ void initialize_command_ui_pyroscope() {
CMD2_ANY("ui.column.sacrificial.list", _cxxstd_::bind(&display::ui_column_sacrificial_list));
CMD2_VAR_VALUE("ui.column.sacrificed", 0);
+ CMD2_ANY ("ui.find.next", _cxxstd_::bind(&ui_find_next));
+ CMD2_VAR_STRING("ui.find.term", "");
+
PS_VARIABLE_COLOR("ui.color.progress0", "red");
PS_VARIABLE_COLOR("ui.color.progress20", "bold bright red");
PS_VARIABLE_COLOR("ui.color.progress40", "bold bright magenta");
@@ -1162,6 +1221,10 @@ void initialize_command_ui_pyroscope() {
"schedule2 = collapsed_view_toggle, 0, 0, ((ui.bind_key, download_list, *, \""
"view.collapsed.toggle= ; ui.current_view.set = (ui.current_view)\"))\n"
+ // Bind 'F' / F3 to find the next item for 'ui.find.term'
+ "schedule2 = ui_find_next_f, 0, 0, ((ui.bind_key, download_list, F, \"ui.find.next=\"))\n"
+ "schedule2 = ui_find_next_f3, 0, 0, ((ui.bind_key, download_list, 0413, \"ui.find.next=\"))\n"
+
// Collapse built-in views
"view.collapsed.toggle = main\n"
"view.collapsed.toggle = name\n"
@@ -1213,7 +1276,7 @@ void initialize_command_ui_pyroscope() {
// Status flags (❢ ☢ ☍ ⌘)
"method.set_key = ui.column.render, \"100:3C95/2:❢ \","
- " ((array.at, {\" \", \"♺ \", \"⚠ \", \"◔ \", \"⚡ \", \"↯ \", \"¿?\","
+ " ((array.at, {\" \", \"♺ \", \"ʘ \", \"⚠ \", \"◔ \", \"⚡ \", \"↯ \", \"¿?\","
" \"⨂ \", \"⋫ \", \"☡ \"}, ((d.message.alert)) ))\n"
"method.set_key = ui.column.render, \"110:2C92/2:☢ \","
" ((string.map, ((cat, ((d.is_open)), ((d.is_active)))), {00, \"▪ \"}, {01, \"▪ \"}, {10, \"╍ \"}, {11, \"▹ \"}))\n"
diff --git a/ui_pyroscope.h b/ui_pyroscope.h
index aee5ada5afde..042d73c44366 100644
--- a/ui_pyroscope.h
+++ b/ui_pyroscope.h
@@ -11,6 +11,7 @@ namespace ps {
enum AlertKind {
ALERT_NORMAL,
ALERT_NORMAL_CYCLING, // Tried all trackers
+ ALERT_NORMAL_GHOST, // no data
ALERT_GENERIC,
ALERT_TIMEOUT,
ALERT_CONNECT,