[kupfer] Alternative ranking for Actions
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [kupfer] Alternative ranking for Actions
- Date: Wed, 13 Jan 2010 14:50:49 +0000 (UTC)
commit ebe59610c2cbdd15fcfda1af9aa1f31daed6b7a9
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Wed Jan 13 15:46:22 2010 +0100
Alternative ranking for Actions
This adjusts the rank for actions, *without query* (no search text),
to be more rigid. Basically, we honor all rank_adjust actions, so
default actions are almost always on top, and negatively adjusted
actions are always at the bottom.
This is the only way we can get sane and predictable results right
now, what is needed for the future is:
* Object-specific action memory
* Action configuration: which actions to use, which rank to give them
With a search query in the action pane, it behaves exactly as before,
with the old ranking mechanism.
kupfer/core/data.py | 48 ++++++++++++++++++++++++++++++++++--------------
kupfer/core/search.py | 16 ++++++++++++++++
2 files changed, 50 insertions(+), 14 deletions(-)
---
diff --git a/kupfer/core/data.py b/kupfer/core/data.py
index 5af1bca..0bfef35 100644
--- a/kupfer/core/data.py
+++ b/kupfer/core/data.py
@@ -5,7 +5,7 @@ import os
import gobject
from kupfer.obj import base, sources, compose
-from kupfer import pretty, scheduler, task
+from kupfer import pretty, scheduler
from kupfer import commandexec
from kupfer import datatools
from kupfer.core import search, learn
@@ -31,6 +31,17 @@ def dress_leaves(seq, action):
sc.decorate_object(itm.object, action=action)
yield itm
+def peekfirst(seq):
+ """This function will return (firstitem, iter)
+ where firstitem is the first item of @seq or None if empty,
+ and iter an equivalent copy of @seq
+ """
+ seq = iter(seq)
+ for itm in seq:
+ old_iter = itertools.chain((itm, ), seq)
+ return (itm, old_iter)
+ return (None, seq)
+
class Searcher (object):
"""
This class searches KupferObjects efficiently, and
@@ -115,23 +126,33 @@ class Searcher (object):
if (not hasattr(obj, "is_valid")) or obj.is_valid():
yield itm
- def peekfirst(seq):
- """This function will return (firstitem, iter)
- where firstitem is the first item of @seq or None if empty,
- and iter an equivalent copy of @seq
- """
- seq = iter(seq)
- for itm in seq:
- old_iter = itertools.chain((itm, ), seq)
- return (itm, old_iter)
- return (None, seq)
-
# Check if the items are valid as the search
# results are accessed through the iterators
unique_matches = as_set_iter(matches)
match, match_iter = peekfirst(decorator(valid_check(unique_matches)))
return match, match_iter
+ def rank_actions(self, objects, key, item_check=None, decorator=None):
+ """
+ rank @objects, which should be a sequence of KupferObjects,
+ for @key, with the action ranker algorithm.
+
+ Filters and return value like .score().
+ """
+ if not item_check: item_check = identity
+ if not decorator: decorator = identity
+
+ rankables = search.make_rankables(item_check(objects))
+ if key:
+ rankables = search.score_objects(rankables, key)
+ matches = search.bonus_objects(rankables, key)
+ else:
+ matches = search.score_actions(rankables)
+ matches = sorted(matches, key=operator.attrgetter("rank"), reverse=True)
+
+ match, match_iter = peekfirst(decorator(matches))
+ return match, match_iter
+
class Pane (gobject.GObject):
"""
signals:
@@ -306,8 +327,7 @@ class PrimaryActionPane (Pane):
if is_valid_cached(obj.object):
yield obj
- sources = (actions, )
- match, match_iter = self.searcher.search(sources, key,
+ match, match_iter = self.searcher.rank_actions(actions, key,
decorator=valid_decorator)
self.emit_search_result(match, match_iter, context)
diff --git a/kupfer/core/search.py b/kupfer/core/search.py
index 1a93fcd..2c5d4a3 100644
--- a/kupfer/core/search.py
+++ b/kupfer/core/search.py
@@ -74,3 +74,19 @@ def score_objects(rankables, key):
rb.rank = rank
yield rb
+
+def score_actions(rankables):
+ """Alternative (rigid) scoring mechanism for objects,
+ putting much more weight in rank_adjust
+ """
+ get_record_score = learn.get_record_score
+ for obj in rankables:
+ ra = obj.object.rank_adjust
+ if ra > 0:
+ obj.rank = 50 + ra + get_record_score(obj.object)/2
+ elif ra == 0:
+ obj.rank = get_record_score(obj.object)
+ else:
+ obj.rank = -50 + ra + get_record_score(obj.object)
+ yield obj
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]