gtg team mailing list archive
-
gtg team
-
Mailing list archive
-
Message #03103
[Merge] lp:~thibaultfevry/gtg/core_cleanup_and_enhancements into lp:gtg
Thibault Fevry has proposed merging lp:~thibaultfevry/gtg/core_cleanup_and_enhancements into lp:gtg.
Requested reviews:
Gtg developers (gtg): additional-test
Related bugs:
#619703 Remove unused imports, some unused functions, useless calls, useless code, pep8 fixes.
https://bugs.launchpad.net/bugs/619703
This changes many little things, but the overall structure of the programme isn't touched.
I removed:
- Some code that was useless. (Setting variable and never using them.).
- Some deprecated fuctions. (And updates other files to use the new.)
- Some useless calls. (Principaly to tas.py, where str() was called more than necessary.
Optimization:
- Better regex finder, should match the same things.
- Use of tuples when list's arn't saved, minimal space space but also more logical and better for error handling.
- Debug.sh will now print a message to not let it be executed with root privileges, as running it with root removes graphical login. (And breaks many other stuff.)
Typos, pep8, docstring, comment fixe:
- ~600 pep8 fixes in the different classes in core.
- Fix some typos in comments.
- Sometimes clarify some details.
(I won't probably have the possibility to edit code for 2 weeks, but I'll try to check my mails frequently.)
--
https://code.launchpad.net/~thibaultfevry/gtg/core_cleanup_and_enhancements/+merge/33043
Your team Gtg developers is requested to review the proposed merge of lp:~thibaultfevry/gtg/core_cleanup_and_enhancements into lp:gtg.
=== modified file 'AUTHORS'
--- AUTHORS 2010-08-15 19:12:35 +0000
+++ AUTHORS 2010-08-18 19:18:41 +0000
@@ -69,4 +69,4 @@
* Marko Kevac <marko@xxxxxxxxx>
* Volodymyr Floreskul <exufer@xxxxxxxxx>
* Jeff Oliver <kaiserfro@xxxxxxxxx>
-* Thibault Fevry <https://edge.launchpad.net/~thibaultfevry> (no email provided)
+* Thibault Fevry <thibaultfevry@xxxxxxxxx>
=== modified file 'GTG/core/__init__.py'
--- GTG/core/__init__.py 2010-08-04 00:43:25 +0000
+++ GTG/core/__init__.py 2010-08-18 19:18:41 +0000
@@ -38,7 +38,7 @@
"""
-#=== IMPORT ====================================================================
+#=== IMPORT ===================================================================
import os
from xdg.BaseDirectory import xdg_data_home, xdg_config_home
from configobj import ConfigObj
@@ -49,9 +49,7 @@
from GTG.tools.borg import Borg
-
class CoreConfig(Borg):
-
#The projects and tasks are of course DATA !
#We then use XDG_DATA for them
@@ -75,8 +73,8 @@
self.data_dir = '/tmp/GTG_TESTS/data'
self.conf_dir = '/tmp/GTG_TESTS/conf'
else:
- self.data_dir = os.path.join(xdg_data_home,'gtg/')
- self.conf_dir = os.path.join(xdg_config_home,'gtg/')
+ self.data_dir = os.path.join(xdg_data_home, 'gtg/')
+ self.conf_dir = os.path.join(xdg_config_home, 'gtg/')
if not os.path.exists(self.conf_dir):
os.makedirs(self.conf_dir)
if not os.path.exists(self.data_dir):
@@ -95,7 +93,7 @@
"cannot be read or written. Please check it")
self.conf_dict = ConfigObj(self.conf_dir + self.CONF_FILE)
self.task_conf_dict = ConfigObj(self.conf_dir + self.TASK_CONF_FILE)
-
+
def save(self):
''' Saves the configuration of CoreConfig '''
self.conf_dict.write()
=== modified file 'GTG/core/datastore.py'
--- GTG/core/datastore.py 2010-06-23 10:54:11 +0000
+++ GTG/core/datastore.py 2010-08-18 19:18:41 +0000
@@ -18,7 +18,7 @@
# -----------------------------------------------------------------------------
"""
-The DaataStore contains a list of TagSource objects, which are proxies
+The DataStore contains a list of TagSource objects, which are proxies
between a backend and the datastore itself
"""
@@ -34,7 +34,6 @@
from GTG.tools.logger import Log
from GTG.backends.genericbackend import GenericBackend
from GTG.tools import cleanxml
-from GTG.tools.keyring import Keyring
from GTG.backends.backendsignals import BackendSignals
from GTG.tools.synchronized import synchronized
from GTG.tools.borg import Borg
@@ -49,7 +48,6 @@
Requester instead (which also sends signals as you issue commands).
'''
-
def __init__(self):
'''
Initializes a DataStore object
@@ -83,7 +81,7 @@
this datastore
'''
return self.requester
-
+
def get_tasks_tree(self):
'''
Helper function to get a Tree with all the tasks contained in this
@@ -125,8 +123,8 @@
else:
Log.debug("requested non-existent task")
return None
-
- def task_factory(self, tid, newtask = False):
+
+ def task_factory(self, tid, newtask=False):
'''
Instantiates the given task id as a Task object.
@param tid: a task id. Must be unique
@@ -146,9 +144,9 @@
task = self.task_factory(uuid.uuid4(), True)
self.open_tasks.add_node(task)
return task
-
+
@synchronized
- def push_task(self, task, backend_capabilities = 'bypass for now'):
+ def push_task(self, task, backend_capabilities='bypass for now'):
'''
Adds the given task object to the task tree. In other words, registers
the given task in the GTG task set.
@@ -169,10 +167,11 @@
### Backends functions
##########################################################################
- def get_all_backends(self, disabled = False):
- """
+ def get_all_backends(self, disabled=False):
+ """
returns list of all registered backends for this DataStore.
- @param disabled: If disabled is True, attaches also the list of disabled backends
+ @param disabled: If disabled is True,
+ attaches also the list of disabled backends
@return list: a list of TaskSource objects
"""
#NOTE: consider cashing this result for speed.
@@ -211,15 +210,14 @@
if backend.get_id() in self.backends:
Log.debug("registering already registered backend")
return None
- source = TaskSource(requester = self.requester,
- backend = backend,
- datastore = self.filtered_datastore)
+ source = TaskSource(requester=self.requester, backend=backend,
+ datastore=self.filtered_datastore)
self.backends[backend.get_id()] = source
#we notify that a new backend is present
self._backend_signals.backend_added(backend.get_id())
#saving the backend in the correct dictionary (backends for enabled
# backends, disabled_backends for the disabled ones)
- #this is useful for retro-compatibility
+ #this is useful for retro-compatibility
if not GenericBackend.KEY_ENABLED in backend_dic:
source.set_parameter(GenericBackend.KEY_ENABLED, True)
if not GenericBackend.KEY_DEFAULT_BACKEND in backend_dic:
@@ -227,7 +225,7 @@
#if it's enabled, we initialize it
if source.is_enabled() and \
(self.is_default_backend_loaded or source.is_default()):
- source.initialize(connect_signals = False)
+ source.initialize(connect_signals=False)
#Filling the backend
#Doing this at start is more efficient than
#after the GUI is launched
@@ -236,7 +234,7 @@
else:
Log.debug("Tried to register a backend without a pid")
- def _activate_non_default_backends(self, sender = None):
+ def _activate_non_default_backends(self, sender=None):
'''
Non-default backends have to wait until the default loads before
being activated. This function is called after the first default
@@ -270,15 +268,14 @@
current_state = backend.is_enabled()
if current_state == True and state == False:
#we disable the backend
- backend.quit(disable = True)
+ backend.quit(disable=True)
elif current_state == False and state == True:
if self.is_default_backend_loaded == True:
backend.initialize()
self.flush_all_tasks(backend_id)
else:
#will be activated afterwards
- backend.set_parameter(GenericBackend.KEY_ENABLED,
- True)
+ backend.set_parameter(GenericBackend.KEY_ENABLED, True)
def remove_backend(self, backend_id):
'''
@@ -310,23 +307,24 @@
identified with backend_id. If tasks need to be added or removed, it
will be done here.
It has to be run after the creation of a new backend (or an alteration
- of its "attached tags"), so that the tasks which are already loaded in
+ of its "attached tags"), so that the tasks which are already loaded in
the Tree will be saved in the proper backends
@param backend_id: a backend id
'''
+
def _internal_flush_all_tasks():
backend = self.backends[backend_id]
for task_id in self.requester.get_all_tasks_list():
backend.queue_set_task(None, task_id)
- t = threading.Thread(target = _internal_flush_all_tasks).start()
+ threading.Thread(target=_internal_flush_all_tasks).start()
self.backends[backend_id].start_get_tasks()
- def save(self, quit = False):
+ def save(self, quit=False):
'''
- Saves the backends parameters.
+ Saves the backends parameters.
@param quit: If quit is true, backends are shut down
'''
- doc,xmlconfig = cleanxml.emptydoc("config")
+ doc, xmlconfig = cleanxml.emptydoc("config")
#we ask all the backends to quit first.
if quit:
for b in self.get_all_backends():
@@ -334,10 +332,10 @@
#has_quit would be faster (invernizzi)
b.quit()
#we save the parameters
- for b in self.get_all_backends(disabled = True):
+ for b in self.get_all_backends(disabled=True):
t_xml = doc.createElement("backend")
for key, value in b.get_parameters().iteritems():
- if key in ["backend", "xmlobject"]:
+ if key in ("backend", "xmlobject"):
#We don't want parameters,backend,xmlobject
continue
param_type = b.get_parameter_type(key)
@@ -345,16 +343,17 @@
t_xml.setAttribute(str(key), value)
#Saving all the projects at close
xmlconfig.appendChild(t_xml)
-
- datafile = os.path.join(CoreConfig().get_data_dir(), CoreConfig.DATA_FILE)
- cleanxml.savexml(datafile,doc,backup=True)
+
+ datafile = os.path.join(CoreConfig().get_data_dir(),
+ CoreConfig.DATA_FILE)
+ cleanxml.savexml(datafile, doc, backup=True)
#Saving the tagstore
ts = self.get_tagstore()
ts.save()
def request_task_deletion(self, tid):
- '''
+ '''
This is a proxy function to request a task deletion from a backend
@param tid: the tid of the task to remove
'''
@@ -366,6 +365,7 @@
Transparent interface between the real backend and the DataStore.
Is in charge of connecting and disconnecting to signals
'''
+
def __init__(self, requester, backend, datastore):
"""
Instantiates a TaskSource object.
@@ -382,16 +382,16 @@
if Log.is_debugging_mode():
self.timer_timestep = 5
else:
- self.timer_timestep = 1
+ self.timer_timestep = 1
self.set_task_handle = None
self.remove_task_handle = None
self.to_set_timer = None
-
+
def start_get_tasks(self):
- ''''
+ '''
Maps the TaskSource to the backend and starts threading.
'''
- threading.Thread(target = self.__start_get_tasks).start()
+ threading.Thread(target=self.__start_get_tasks).start()
def __start_get_tasks(self):
'''
@@ -407,7 +407,8 @@
'''
Fiter that checks if the task should be stored in this backend.
- @returns function: a function that accepts a task and returns True/False
+ @returns function: a function that accepts
+ a task and returns True/False
whether the task should be stored or not
'''
raw_filter = self.req.get_filter("backend_filter").get_function()
@@ -436,7 +437,7 @@
self.__try_launch_setting_thread()
else:
self.queue_remove_task(None, tid)
-
+
def launch_setting_thread(self):
'''
Operates the threads to set and remove tasks.
@@ -454,7 +455,7 @@
#NOTE: no need to lock, we're reading
if tid not in self.to_remove and \
self.should_task_id_be_stored(tid) and \
- self.req.has_task(tid):
+ self.req.has_task(tid):
task = self.req.get_task(tid)
self.backend.queue_set_task(task)
while True:
@@ -465,7 +466,7 @@
self.backend.queue_remove_task(tid)
#we release the weak lock
self.to_set_timer = None
-
+
def queue_remove_task(self, sender, tid):
'''
Queues task to be removed.
@@ -485,7 +486,7 @@
self.launch_setting_thread)
self.to_set_timer.start()
- def initialize(self, connect_signals = True):
+ def initialize(self, connect_signals=True):
'''
Initializes the backend and starts looking for signals.
@param connect_signals: if True, it starts listening for signals
@@ -531,7 +532,7 @@
pass
self.launch_setting_thread()
- def quit(self, disable = False):
+ def quit(self, disable=False):
'''
Quits the backend and disconnect the signals
@param disable: if True, the backend is disabled.
@@ -539,39 +540,33 @@
self._disconnect_signals()
self.sync()
self.backend.quit(disable)
-
+
def __getattr__(self, attr):
'''
Delegates all the functions not defined here to the real backend
(standard python function)
@param attr: attribute to get
'''
- if attr in self.__dict__:
+ if attr in self.__dict__:
return self.__dict__[attr]
else:
return getattr(self.backend, attr)
-
class FilteredDataStore(Borg):
- '''
+ '''
This class acts as an interface to the Datastore.
It is used to hide most of the methods of the Datastore.
The backends can safely use the remaining methods.
'''
-
def __init__(self, datastore):
super(FilteredDataStore, self).__init__()
self.datastore = datastore
def __getattr__(self, attr):
- if attr in ['task_factory', \
- 'push_task',
- 'get_task',
- 'has_task',
- 'request_task_deletion']:
+ if attr in ('task_factory', 'push_task', 'get_task', 'has_task',
+ 'request_task_deletion'):
return getattr(self.datastore, attr)
else:
raise AttributeError
-
=== modified file 'GTG/core/filteredtree.py'
--- GTG/core/filteredtree.py 2010-08-02 19:07:24 +0000
+++ GTG/core/filteredtree.py 2010-08-18 19:18:41 +0000
@@ -35,11 +35,11 @@
Note that the nodes are not aware that they are in a filtered tree.
Use the FilteredTree methods, not the node methods directly.
-If you believe a function would be useful in a filtered tree, don't
+If you believe a function would be useful in a filtered tree, don't
hesitate to make a proposal.
To be more efficient, a quick way to optimize the FilteredTree is to cache
-all answers in a dictionary so we don't have to compute the answer
+all answers in a dictionary so we don't have to compute the answer
all the time. This is not done yet.
B{Warning}: this is very fragile. Calls to any GTK registered view should be
@@ -78,8 +78,9 @@
from GTG.tools.logger import Log
COUNT_CACHING_ENABLED = True
-#DEBUG_TID = ['11@1','861@1','23@1','1159@1','422@1']
-DEBUG_TID = ['11@1','861@1']
+#DEBUG_TID = ('11@1','861@1','23@1','1159@1','422@1')
+DEBUG_TID = ('11@1', '861@1')
+
class FilteredTree(gobject.GObject):
@@ -90,9 +91,9 @@
'task-deleted-inview': (gobject.SIGNAL_RUN_FIRST, \
gobject.TYPE_NONE, (str, )),
'task-modified-inview': (gobject.SIGNAL_RUN_FIRST, \
- gobject.TYPE_NONE, (str, )),}
+ gobject.TYPE_NONE, (str, )), }
- def __init__(self,req,tree,maintree=False):
+ def __init__(self, req, tree, maintree=False):
"""
Construct a FilteredTree object on top of an existing task tree.
@param req: The requestor object
@@ -137,36 +138,37 @@
self.path_for_node_cache = {}
#### Standard tree functions
- def get_node(self,id):
+
+ def get_node(self, id):
"""
Retrieves the given node
@param id: The tid of the task node
@return: Node from the underlying tree
"""
return self.tree.get_node(id)
-
+
def get_root(self):
"""
returns the root node
"""
return self.tree.get_root()
-
+
def get_all_keys(self):
"""
returns list of all displayed node keys
"""
return list(self.displayed_nodes)
-
+
def get_all_nodes(self):
"""
returns list of all nodes
"""
- k = []
+ nodes = []
for n in self.get_all_nodes():
- k.append(self.get_node(n))
- return k
-
- def get_n_nodes(self,withfilters=[],countednodes=False):
+ nodes.append(self.get_node(n))
+ return nodes
+
+ def get_n_nodes(self, withfilters=[], countednodes=False):
"""
Returns quantity of nodes displayed in this tree.
@@ -205,36 +207,38 @@
else:
toreturn = len(zelist)
return toreturn
-
+
### signals functions
def __task_added(self,sender,tid):
todis = self.__is_displayed(tid)
curdis = self.is_displayed(tid)
if todis and not curdis:
self.__add_node(tid)
-
- def __task_modified(self,sender,tid):
+
+ def __task_modified(self, sender, tid):
if tid not in self.tasks_to_modify:
self.tasks_to_modify.append(tid)
node = self.get_node(tid)
if node:
inroot = self.__is_root(node)
- self.__update_node(tid,inroot)
+ self.__update_node(tid, inroot)
self.tasks_to_modify.remove(tid)
- def __task_deleted(self,sender,tid):
+ def __task_deleted(self, sender, tid):
self.__remove_node(tid)
-
+
####TreeModel functions ##############################
def print_tree(self):
- print "displayed : %s" %self.displayed_nodes
+ print "displayed : %s" % self.displayed_nodes
for rid in self.virtual_root:
r = self.req.get_task(rid)
self.__print_from_node(r)
#The path received is only for tasks that are displayed
#We have to find the good node.
+
+ #FIXME: Isn't there already this in tree.py ?
def get_node_for_path(self, path):
"""
Returns node for the given path.
@@ -247,19 +251,19 @@
n1id = self.virtual_root[p0]
n1 = self.get_node(n1id)
pa = path[1:]
- toreturn = self.__node_for_path(n1,pa)
+ toreturn = self.__node_for_path(n1, pa)
else:
toreturn = None
return toreturn
- def __node_for_path(self,basenode,path):
+ def __node_for_path(self, basenode, path):
if len(path) == 0 or self.flat:
return basenode
elif path[0] < self.node_n_children(basenode):
if len(path) == 1:
- return self.node_nth_child(basenode,path[0])
+ return self.node_nth_child(basenode, path[0])
else:
- node = self.node_nth_child(basenode,path[0])
+ node = self.node_nth_child(basenode, path[0])
path = path[1:]
return self.__node_for_path(node, path)
else:
@@ -291,19 +295,22 @@
path = (ind,)
toreturn.append(path)
else:
- print "*** Task id %s has parents but is not in virtual root" %tid
- Log.debug("*** is in node_to_add? %s" %(tid in self.node_to_add))
-
+ print """*** Task id %s has parents but
+ is not in virtual root""" % tid
+ Log.debug("""*** is in node_to_add?
+ %s""" % (tid in self.node_to_add))
# parents = self.node_parents(node)
# if len(parents) > 0:
-# print "WARNING : %s was in VRÂ with %s parents" %(tid,len(parents))
+# print """WARNING : %s was in VRÂ with %s parents
+# """ %(tid, len(parents))
#The node is not a virtual root
else:
# if len(pars) <= 0:
# #if we don't have parent, we add the task
# #to the virtual root.
# if tid in DEBUG_TID:
-# print "we should not update %s from the get_path method" %tid
+# print """we should not update %s from the get_path method
+# """ %tid
# self.__root_update(tid,True)
# ind = self.virtual_root.index(tid)
# path = (ind,)
@@ -311,17 +318,17 @@
# else:
for par in pars:
pos = 0
- max = self.node_n_children(par)
+ ze_max = self.node_n_children(par)
child = self.node_children(par)
- while pos < max and node != child:
+ while pos < ze_max and node != child:
pos += 1
- child = self.node_nth_child(par,pos)
+ child = self.node_nth_child(par, pos)
par_paths = self.get_paths_for_node(par)
for par_path in par_paths:
- path = par_path + (pos,)
+ path = par_path + (pos, )
toreturn.append(path)
if len(toreturn) == 0:
- #If we are here, it means that we have a ghost task that
+ #If we are here, it means that we have a ghost task that
#is not really displayed but still here in the tree.
#It happens sometimes when we remove a parent with children.
#If we still have a recorded path for the ghost task,
@@ -329,15 +336,15 @@
if self.path_for_node_cache.has_key(tid):
toreturn = self.path_for_node_cache[tid]
else:
- Log.debug("ghost position for %s" %tid)
- Log.debug("VR : %s " %self.virtual_root)
+ Log.debug("ghost position for %s" % tid)
+ Log.debug("VR : %s " % self.virtual_root)
Log.debug(self.path_for_node_cache)
-
+
self.path_for_node_cache[tid] = toreturn
return toreturn
#Done
- def next_node(self, node,parent):
+ def next_node(self, node, parent):
"""
Returns the next sibling node, or None if there are no other siblings
"""
@@ -354,20 +361,16 @@
else:
parents_nodes = self.node_parents(node)
if len(parents_nodes) >= 1:
- if parent in parents_nodes:
- parent_node = parent
- else:
- parent_node = parents_nodes[0]
total = self.node_n_children(parent)
c = 0
next_id = None
while c < total and not next_id:
- child = self.node_nth_child(parent,c)
+ child = self.node_nth_child(parent, c)
c += 1
if child == node:
next_id = c
if next_id < total:
- nextnode = self.node_nth_child(parent,next_id)
+ nextnode = self.node_nth_child(parent, next_id)
#check to see if our result is correct
if nextnode and not self.is_displayed(nextnode.get_id()):
nextnode = None
@@ -383,7 +386,7 @@
"""
#print "on_iter_children for parent %s" %parent.get_id()
#here, we should return only good childrens
- child = self.node_nth_child(parent,0)
+ child = self.node_nth_child(parent, 0)
return child
#Done
@@ -394,7 +397,7 @@
#print "on_iter_has_child for node %s" %node
#we should say "has_good_child"
# print "node has %s children" %self.node_n_children(node)
- if not self.flat and node and self.node_n_children(node)>0:
+ if not self.flat and node and self.node_n_children(node) > 0:
return True
else:
if not node:
@@ -409,14 +412,14 @@
#we should return the number of "good" children
if not node:
toreturn = len(self.virtual_root)
- id = 'root'
+ #id = 'root' Useless ?
elif self.flat:
toreturn = 0
else:
n = 0
for cid in node.get_children():
if self.is_displayed(cid):
- n+= 1
+ n += 1
toreturn = n
return toreturn
@@ -430,9 +433,8 @@
#we return the nth good children !
if not node:
if len(self.virtual_root) > n:
- to_id = self.virtual_root[n]
- toreturn = self.get_node(to_id)
-# print "## node_nth_child : %s" %to_id
+ toreturn = self.get_node(self_virtual_root[n])
+# print "## node_nth_child : %s" % self_virtual_root[n]
else:
toreturn = None
elif self.flat:
@@ -463,7 +465,7 @@
#Done
def node_parents(self, node):
"""
- Returns parent of the given node, or None if there is no
+ Returns parent of the given node, or None if there is no
parent (such as if the node is a child of the virtual root),
or if the parent is not displayable.
"""
@@ -472,7 +474,7 @@
if node == None:
Log.debug("requested a parent of a non-existing node")
return parents_nodes
- tid = node.get_id()
+# tid = node.get_id() Useless ?
# if node and tid in self.virtual_root:
# return parents_nodes
#we return only parents that are not root and displayed
@@ -480,21 +482,23 @@
for pid in node.get_parents():
parent = self.tree.get_node(pid)
# if pid in DEBUG_TID:
-# print "%%%%parent %s is displayed : %s" %(pid,self.is_displayed(pid))
+# print """parent %s is displayed : %s
+# """ %(pid,self.is_displayed(pid))
if self.is_displayed(pid) and parent != self.tree.get_root():
parents_nodes.append(parent)
# if len(parents_nodes) == 0:
# print "ERROR : %s has no parent and is not in VR" %tid
-# if not self.flat and tid in self.virtual_root and len(parents_nodes) > 0:
+# if not self.flat and tid in self.virtual_root \
+# and len(parents_nodes) > 0:
# self.__root_update(tid,False)
# if tid in DEBUG_TID:
-# print "%s has parents %s but return %s" %(tid,node.get_parents(),parents_nodes)
+# print """%s has parents %s but return %s
+# """ %(tid,node.get_parents(),parents_nodes)
return parents_nodes
-
####Â Filtering methods #########
-
- def is_displayed(self,tid):
+
+ def is_displayed(self, tid):
"""
This is a public method that return True if the task is
currently displayed in the tree
@@ -504,7 +508,7 @@
else:
toreturn = False
return toreturn
-
+
def __is_displayed(self, tid):
"""
This is a private method that return True if the task *should*
@@ -539,16 +543,16 @@
else:
result = False
return result
-
+
def refilter(self):
"""
- rebuilds the tree from scratch. It should be called only when
+ rebuilds the tree from scratch. It should be called only when
the filter is changed (i.e. only filters_bank should call it).
"""
self.update_count = 0
self.add_count = 0
self.remove_count = 0
- virtual_root2 = []
+ #virtual_root2 = [] Useless ?
to_add = []
self.counted_nodes = []
self.count_cache = {}
@@ -579,8 +583,8 @@
# self.print_tree()
####### Change filters #################
- def apply_filter(self,filter_name,parameters=None,\
- reset=False,imtherequester=False,refresh=True):
+ def apply_filter(self, filter_name, parameters=None, \
+ reset=False, imtherequester=False, refresh=True):
"""
Applies a new filter to the tree. Can't be called on the main tree.
@param filter_name: The name of an already registered filter to apply
@@ -589,7 +593,7 @@
@param imtherequester: If true enables adding filters to the main tree
"""
if self.is_main and not imtherequester:
- print "Error : use the requester to apply a filter to the main tree"
+ print "Error: use the requester to apply a filter to the main tree"
print "We don't do that automatically on purpose"
else:
if reset:
@@ -604,15 +608,16 @@
self.refilter()
return True
return False
-
- def unapply_filter(self,filter_name,imtherequester=False,refresh=True):
+
+ def unapply_filter(self, filter_name, imtherequester=False, refresh=True):
"""
Removes a filter from the tree. Can't be called on the main tree.
@param filter_name: The name of an already added filter to remove
- @param imtherequester: If true enables removing filters from the main tree
+ @param imtherequester: If true enables removing filters
+ from the main tree
"""
if self.is_main and not imtherequester:
- print "Error : use the requester to remove a filter to the main tree"
+ print "Error: use the requester to remove a filter from the tree."
print "We don't do that automatically on purpose"
elif filter_name in self.applied_filters:
self.applied_filters.remove(filter_name)
@@ -621,28 +626,31 @@
return True
return False
- def reset_filters(self,imtherequester=False,refresh=True):
+ def reset_filters(self, imtherequester=False, refresh=True):
"""
- Clears all filters currently set on the tree. Can't be called on
+ Clears all filters currently set on the tree. Can't be called on
the main tree.
- @param imtherequester: If true enables clearing filters from the main tree
+ @param imtherequester: If true enables clearing filters
+ from the main tree
"""
if self.is_main and not imtherequester:
- print "Error : use the requester to remove a filter to the main tree"
+ print """Error: use the requester to remove
+ a filter from the main tree"""
print "We don't do that automatically on purpose"
else:
self.applied_filters = []
if refresh:
self.refilter()
- def reset_tag_filters(self,refilter=True,imtherequester=False):
+ def reset_tag_filters(self, refilter=True, imtherequester=False):
"""
- Clears all filters currently set on the tree. Can't be called on
+ Clears all filters currently set on the tree. Can't be called on
the main tree.
- @param imtherequester: If true enables clearing filters from the main tree
+ @param imtherequester: If true enables clearing filters
+ from the main tree
"""
if self.is_main and not imtherequester:
- print "Error : use the requester to remove a filter to the main tree"
+ print "Error: use the requester to remove a filter from the tree"
print "We don't do that automatically on purpose"
else:
if "notag" in self.applied_filters:
@@ -659,18 +667,19 @@
# Return True if the node should be a virtual root node
# regardless of the current state
- def __is_root(self,n):
+
+ def __is_root(self, n):
is_root = True
if not self.flat and n and n.has_parent():
for par in n.get_parents():
if self.__is_displayed(par):
is_root = False
return is_root
-
+
# Put or remove a node from the virtual root
- def __root_update(self,tid,inroot):
+ def __root_update(self, tid, inroot):
# if tid in DEBUG_TID:
-# print "calling root update %s for %s" %(inroot,tid)
+# print "calling root update %s for %s" % (inroot,tid)
children_update = False
if inroot:
if tid not in self.virtual_root:
@@ -682,9 +691,9 @@
else:
if tid in self.virtual_root:
# if tid in DEBUG_TID:
-# print "removin %s from VR" %tid
+# print "removing %s from VR" %tid
self.virtual_root.remove(tid)
- #even if you are not a root,
+ #even if you are not a root,
#your children should not be in VR either
else:
children_update = True
@@ -696,7 +705,7 @@
# print "updating %s childrens of node %s" %(nc,tid)
i = 0
while i < nc:
- ch = self.node_nth_child(node,i)
+ ch = self.node_nth_child(node, i)
if ch:
chid = ch.get_id()
if chid in self.virtual_root:
@@ -704,14 +713,14 @@
#because its parent is in now
# if tid in DEBUG_TID:
# print "updating children %s of node %s" %(chid,tid)
- self.__update_node(chid,False)
+ self.__update_node(chid, False)
i += 1
-
- def __update_node(self,tid,inroot):
+
+ def __update_node(self, tid, inroot):
if tid not in self.node_to_remove:
# if tid in DEBUG_TID:
# print "updating inroot %s the node %s" %(inroot,tid)
- todis = self.__is_displayed(tid)
+ todis = self.__is_displayed(tid)
curdis = self.is_displayed(tid)
if todis:
#if the task was not displayed previously but now should
@@ -721,14 +730,14 @@
# print "*update_node :Â adding node %s" %tid
self.__add_node(tid)
else:
- self.__root_update(tid,inroot)
- self.update_count += 1
+ self.__root_update(tid, inroot)
+ #self.update_count += 1 Is this used ?
self.emit("task-modified-inview", tid)
#I don't remember why we have to update the children.
if not self.flat:
child_list = self.get_node(tid).get_children()
for c in child_list:
- self.__update_node(c,False)
+ self.__update_node(c, False)
else:
#if the task was displayed previously but shouldn't be anymore
#we remove it
@@ -737,18 +746,15 @@
else:
self.emit("task-deleted-inview", tid)
-
-
-
- def __add_node(self,tid,inroot=None):
- self.__adding_queue.append([tid,inroot])
+ def __add_node(self, tid, inroot=None):
+ self.__adding_queue.append((tid, inroot))
if not self.__adding_lock and len(self.__adding_queue) > 0:
self.__adding_lock = True
self.__adding_loop()
def __adding_loop(self):
while len(self.__adding_queue) > 0:
- tid,inroot = self.__adding_queue.pop(0)
+ tid, inroot = self.__adding_queue.pop(0)
if not self.is_displayed(tid):
# if tid in DEBUG_TID:
# print "adding inroot %s the node %s" %(inroot,tid)
@@ -772,7 +778,7 @@
if tid in self.node_to_add:
self.node_to_add.remove(tid)
#Should be in displayed_nodes before updating the root
- self.__root_update(tid,inroot)
+ self.__root_update(tid, inroot)
self.emit("task-added-inview", tid)
#We added a new node so we can check with those waiting
lost_nodes = []
@@ -780,13 +786,13 @@
n = self.node_to_add.pop(0)
toad = self.get_node(n)
if len(self.node_parents(toad)) > 0:
- self.__add_node(n,False)
+ self.__add_node(n, False)
else:
lost_nodes.append(n)
self.node_to_add += lost_nodes
self.__adding_lock = False
-
- def __remove_node(self,tid):
+
+ def __remove_node(self, tid):
if tid not in self.node_to_remove:
self.node_to_remove.append(tid)
isroot = False
@@ -794,8 +800,8 @@
isroot = self.__is_root(self.get_node(tid))
self.remove_count += 1
self.__nodes_count -= 1
- self.emit('task-deleted-inview',tid)
- self.__root_update(tid,False)
+ self.emit('task-deleted-inview', tid)
+ self.__root_update(tid, False)
self.displayed_nodes.remove(tid)
self.__reset_cache()
#Test if this is necessary
@@ -807,13 +813,13 @@
pid = p.get_id()
if pid not in self.__clean_list:
inroot = self.__is_root(p)
- self.__update_node(pid,inroot)
+ self.__update_node(pid, inroot)
self.node_to_remove.remove(tid)
-
+
#This function print the actual tree. Useful for debugging
def __print_from_node(self, node, prefix=""):
- print "%s%s (%s) - %s" %(prefix,node.get_id(),\
- str(self.get_paths_for_node(node)),node.get_title())
+ print "%s%s (%s) - %s" % (prefix, node.get_id(),\
+ str(self.get_paths_for_node(node)), node.get_title())
prefix = prefix + "->"
if self.node_has_child(node):
child = self.node_children(node)
@@ -821,9 +827,9 @@
n = 0
while child and n < nn:
n += 1
- self.__print_from_node(child,prefix)
- child = self.node_nth_child(node,n)
-
+ self.__print_from_node(child, prefix)
+ child = self.node_nth_child(node, n)
+
#This function removes all the nodes, leaves first.
def __clean_from_node(self, node):
nid = node.get_id()
@@ -831,10 +837,10 @@
self.__clean_list.append(nid)
if self.node_has_child(node):
n = self.node_n_children(node)
- child = self.node_nth_child(node,n-1)
+ child = self.node_nth_child(node, n-1)
while child and n > 0:
self.__clean_from_node(child)
- n = n-1
- child = self.node_nth_child(node,n-1)
+ n -= 1
+ child = self.node_nth_child(node, n-1)
self.__remove_node(nid)
self.__clean_list.remove(nid)
=== modified file 'GTG/core/filters_bank.py'
--- GTG/core/filters_bank.py 2010-08-02 19:09:17 +0000
+++ GTG/core/filters_bank.py 2010-08-18 19:18:41 +0000
@@ -15,7 +15,6 @@
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
-#
"""
filters_bank stores all of GTG's filters in centralized place
@@ -24,65 +23,66 @@
from datetime import datetime
from GTG.core.task import Task
-from GTG.tools.dates import date_today, no_date, Date
+from GTG.tools.dates import date_today, no_date
class Filter:
- def __init__(self,func,req):
+
+ def __init__(self, func, req):
self.func = func
self.dic = {}
self.req = req
- def set_parameters(self,dic):
+ def set_parameters(self, dic):
self.dic = dic
def get_function(self):
'''Returns the filtering function'''
return self.func
-
- def is_displayed(self,tid):
+
+ def is_displayed(self, tid):
task = self.req.get_task(tid)
value = True
if not task:
value = False
elif self.dic:
- value = self.func(task,parameters=self.dic)
+ value = self.func(task, parameters=self.dic)
else:
value = self.func(task)
if 'negate' in self.dic and self.dic['negate']:
value = not value
return value
-
- def get_parameters(self,param):
+
+ def get_parameters(self, param):
if self.dic.has_key(param):
return self.dic[param]
else:
return None
#return True is the filter is a flat list only
+
def is_flat(self):
if self.dic.has_key('flat'):
return self.dic['flat']
else:
return False
-
+
+
class SimpleTagFilter:
- def __init__(self,tagname,req):
+
+ def __init__(self, tagname, req):
self.req = req
self.tname = tagname
self.dic = {}
-
- def set_parameters(self,dic):
+
+ def set_parameters(self, dic):
self.dic = dic
-
- def get_parameters(self,param):
+
+ def get_parameters(self, param):
if self.dic.has_key(param):
return self.dic[param]
else:
return None
-
- def set_parameters(self,dic):
- self.dic = dic
def get_all_descendant_tags(self, tname):
tags = [tname]
@@ -94,7 +94,7 @@
tags.extend(self.get_all_descendant_tags(child_tag))
return tags
- def is_displayed(self,tid):
+ def is_displayed(self, tid):
task = self.req.get_task(tid)
value = True
if not task:
@@ -105,16 +105,17 @@
if 'negate' in self.dic and self.dic['negate']:
value = not value
return value
-
+
def is_flat(self):
return False
-
+
+
class FiltersBank:
"""
Stores filter objects in a centralized place.
"""
- def __init__(self,req,tree=None):
+ def __init__(self, req, tree=None):
"""
Create several stock filters:
@@ -128,75 +129,74 @@
self.available_filters = {}
self.custom_filters = {}
#Workview
- filt_obj = Filter(self.workview,self.req)
+ filt_obj = Filter(self.workview, self.req)
self.available_filters['workview'] = filt_obj
#Active
- filt_obj = Filter(self.active,self.req)
+ filt_obj = Filter(self.active, self.req)
self.available_filters['active'] = filt_obj
#closed
- filt_obj = Filter(self.closed,self.req)
+ filt_obj = Filter(self.closed, self.req)
param = {}
param['flat'] = True
filt_obj.set_parameters(param)
self.available_filters['closed'] = filt_obj
#notag
- filt_obj = Filter(self.notag,self.req)
+ filt_obj = Filter(self.notag, self.req)
param = {}
param['ignore_when_counting'] = True
filt_obj.set_parameters(param)
self.available_filters['notag'] = filt_obj
#workable
- filt_obj = Filter(self.is_workable,self.req)
+ filt_obj = Filter(self.is_workable, self.req)
self.available_filters['workable'] = filt_obj
#workable
- filt_obj = Filter(self.is_started,self.req)
+ filt_obj = Filter(self.is_started, self.req)
self.available_filters['started'] = filt_obj
#workdue
- filt_obj = Filter(self.workdue,self.req)
+ filt_obj = Filter(self.workdue, self.req)
self.available_filters['workdue'] = filt_obj
#workstarted
- filt_obj = Filter(self.workstarted,self.req)
+ filt_obj = Filter(self.workstarted, self.req)
self.available_filters['workstarted'] = filt_obj
#worktostart
- filt_obj = Filter(self.worktostart,self.req)
+ filt_obj = Filter(self.worktostart, self.req)
self.available_filters['worktostart'] = filt_obj
#worklate
- filt_obj = Filter(self.worklate,self.req)
+ filt_obj = Filter(self.worklate, self.req)
self.available_filters['worklate'] = filt_obj
#backend filter
filt_obj = Filter(self.backend_filter, self.req)
self.available_filters['backend_filter'] = filt_obj
#no_disabled_tag
- filt_obj = Filter(self.no_disabled_tag,self.req)
- param = {}
- param['ignore_when_counting'] = True
+ filt_obj = Filter(self.no_disabled_tag, self.req)
+ param = {'ignore_when_counting': True}
filt_obj.set_parameters(param)
self.available_filters['no_disabled_tag'] = filt_obj
######### hardcoded filters #############
- def notag(self,task,parameters=None):
+ def notag(self, task, parameters=None):
""" Filter of tasks without tags """
return task.has_tags(notag_only=True)
-
- def is_leaf(self,task,parameters=None):
+
+ def is_leaf(self, task, parameters=None):
""" Filter of tasks which have no children """
return not task.has_child()
-
- def is_workable(self,task,parameters=None):
+
+ def is_workable(self, task, parameters=None):
""" Filter of tasks that can be worked """
workable = True
for c in task.get_subtasks():
if c and c.get_status() == Task.STA_ACTIVE:
workable = False
return workable
-
- def is_started(self,task,parameters=None):
+
+ def is_started(self, task, parameters=None):
'''Filter for tasks that are already started'''
start_date = task.get_start_date()
- if start_date :
+ if start_date:
#Seems like pylint falsely assumes that subtraction always results
- #in an object of the same type. The subtraction of dates
- #results in a datetime.timedelta object
+ #in an object of the same type. The subtraction of dates
+ #results in a datetime.timedelta object
#that does have a 'days' member.
difference = date_today() - start_date
if difference.days == 0:
@@ -206,47 +206,42 @@
return difference.days > 0 #pylint: disable-msg=E1101
else:
return True
-
- def workview(self,task,parameters=None):
- wv = self.active(task) and\
- self.is_started(task) and\
+
+ def workview(self, task, parameters=None):
+ wv = self.active(task) and self.is_started(task) and\
self.is_workable(task)
return wv
-
- def workdue(self,task):
+
+ def workdue(self, task):
''' Filter for tasks due within the next day '''
- wv = self.workview(task) and \
- task.get_due_date() != no_date and \
+ wv = self.workview(task) and task.get_due_date() != no_date and \
task.get_days_left() < 2
return wv
- def worklate(self,task):
+ def worklate(self, task):
''' Filter for tasks due within the next day '''
- wv = self.workview(task) and \
- task.get_due_date() != no_date and \
+ wv = self.workview(task) and task.get_due_date() != no_date and \
task.get_days_late() > 0
return wv
- def workstarted(self,task):
+ def workstarted(self, task):
''' Filter for workable tasks with a start date specified '''
- wv = self.workview(task) and \
- task.start_date
+ wv = self.workview(task) and task.start_date
return wv
-
- def worktostart(self,task):
+
+ def worktostart(self, task):
''' Filter for workable tasks without a start date specified '''
- wv = self.workview(task) and \
- not task.start_date
+ wv = self.workview(task) and not task.start_date
return wv
-
- def active(self,task,parameters=None):
+
+ def active(self, task, parameters=None):
""" Filter of tasks which are active """
#FIXME: we should also handle unactive tags
return task.get_status() == Task.STA_ACTIVE
-
- def closed(self,task,parameters=None):
+
+ def closed(self, task, parameters=None):
""" Filter of tasks which are closed """
- ret = task.get_status() in [Task.STA_DISMISSED, Task.STA_DONE]
+ ret = task.get_status() in (Task.STA_DISMISSED, Task.STA_DONE)
return ret
def backend_filter(self, task, parameters):
@@ -265,18 +260,18 @@
return True
task_tags = set(task.get_tags_name())
return task_tags.intersection(tags_to_match_set)
-
- def no_disabled_tag(self,task,parameters=None):
+
+ def no_disabled_tag(self, task, parameters=None):
"""Filter of task that don't have any disabled/nonworkview tag"""
toreturn = True
for t in task.get_tags():
if t.get_attribute("nonworkview") == "True":
toreturn = False
return toreturn
-
+
##########################################
-
- def get_filter(self,filter_name):
+
+ def get_filter(self, filter_name):
""" Get the filter object for a given name """
if self.available_filters.has_key(filter_name):
return self.available_filters[filter_name]
@@ -284,16 +279,16 @@
return self.custom_filters[filter_name]
else:
return None
-
+
def list_filters(self):
""" List, by name, all available filters """
liste = self.available_filters.keys()
liste += self.custom_filters.keys()
return liste
-
- def add_filter(self,filter_name,filter_func):
+
+ def add_filter(self, filter_name, filter_func):
"""
- Adds a filter to the filter bank
+ Adds a filter to the filter bank
Return True if the filter was added
Return False if the filter_name was already in the bank
"""
@@ -303,18 +298,17 @@
negate = True
filter_name = filter_name[1:]
if filter_name.startswith('@'):
- filter_obj = SimpleTagFilter(filter_name,self.req)
- param = {}
- param['ignore_when_counting'] = True
+ filter_obj = SimpleTagFilter(filter_name, self.req)
+ param = {'ignore_when_counting': True}
filter_obj.set_parameters(param)
else:
- filter_obj = Filter(filter_func,self.req)
+ filter_obj = Filter(filter_func, self.req)
self.custom_filters[filter_name] = filter_obj
return True
else:
return False
-
- def remove_filter(self,filter_name):
+
+ def remove_filter(self, filter_name):
"""
Remove a filter from the bank.
Only custom filters that were added here can be removed
@@ -322,7 +316,8 @@
"""
if not self.available_filters.has_key(filter_name):
if self.custom_filters.has_key(filter_name):
- self.unapply_filter(filter_name)
+ #self.unapply_filter(filter_name) This doesn't exist, it's the
+ #todo undo fixme. Remove comments when it's done.
self.custom_filters.pop(filter_name)
return True
else:
=== modified file 'GTG/core/requester.py'
--- GTG/core/requester.py 2010-06-22 19:55:15 +0000
+++ GTG/core/requester.py 2010-08-18 19:18:41 +0000
@@ -25,11 +25,10 @@
from GTG.core.filteredtree import FilteredTree
from GTG.core.filters_bank import FiltersBank
-from GTG.core.task import Task
from GTG.core.tagstore import Tag
-from GTG.tools.dates import date_today
from GTG.tools.logger import Log
+
class Requester(gobject.GObject):
"""A view on a GTG datastore.
@@ -57,104 +56,114 @@
gobject.GObject.__init__(self)
self.ds = datastore
self.basetree = self.ds.get_tasks_tree()
- self.main_tree = FilteredTree(self,self.basetree,maintree=True)
-
- self.filters = FiltersBank(self,tree=self.main_tree)
+ self.main_tree = FilteredTree(self, self.basetree, maintree=True)
+
+ self.filters = FiltersBank(self, tree=self.main_tree)
self.counter_call = 0
############# Signals #########################
#Used by the tasks to emit the task added/modified signal
#Should NOT be used by anyone else
+
def _task_loaded(self, tid):
gobject.idle_add(self.emit, "task-added", tid)
def _task_modified(self, tid):
self.counter_call += 1
- #print "signal task_modified %s (%s modifications)" %(tid,self.counter_call)
+ #print """signal task_modified %s
+# (%s modifications)""" %(tid,self.counter_call)
gobject.idle_add(self.emit, "task-modified", tid)
def _task_deleted(self, tid):
#when this is emitted, task has *already* been deleted
gobject.idle_add(self.emit, "task-deleted", tid)
- def _tag_added(self,tagname):
+ def _tag_added(self, tagname):
gobject.idle_add(self.emit, "tag-added", tagname)
- def _tag_modified(self,tagname):
+ def _tag_modified(self, tagname):
gobject.idle_add(self.emit, "tag-modified", tagname)
def _tag_path_deleted(self, path):
gobject.idle_add(self.emit, "tag-path-deleted", path)
-
- def _tag_deleted(self,tagname):
+
+ def _tag_deleted(self, tagname):
gobject.idle_add(self.emit, "tag-deleted", tagname)
-
+
############ Tasks Tree ######################
# This is the main FilteredTree. You cannot apply filters
# directly to it, you have to pass them through the requester.
# This is the tree as it is displayed in the main window
+
def get_main_tasks_tree(self):
return self.main_tree
-
+
# This is a FilteredTree that you have to handle yourself.
# You can apply/unapply filters on it as you wish.
+
def get_custom_tasks_tree(self):
- return FilteredTree(self,self.basetree,maintree=False)
-
+ return FilteredTree(self, self.basetree, maintree=False)
+
def get_main_tasks_list(self):
return self.main_tree.get_all_keys()
-
+
def get_main_n_tasks(self):
return self.main_tree.get_n_nodes()
-
+
def get_all_tasks_list(self):
return self.basetree.get_all_keys()
-
+
# Apply a given filter to the main FilteredTree
- def apply_filter(self,filter_name,parameters=None,refresh=True):
- r = self.main_tree.apply_filter(filter_name,parameters=parameters,\
- imtherequester=True,refresh=refresh)
+ def apply_filter(self, filter_name, parameters=None, refresh=True):
+ r = self.main_tree.apply_filter(filter_name, parameters=parameters, \
+ imtherequester=True, refresh=refresh)
return r
-
+
# Unapply a filter from the main FilteredTree.
# Does nothing if the filter was not previously applied.
- def unapply_filter(self,filter_name):
- r = self.main_tree.unapply_filter(filter_name,imtherequester=True)
+
+ def unapply_filter(self, filter_name):
+ r = self.main_tree.unapply_filter(filter_name, imtherequester=True)
return r
def reset_filters(self):
self.main_tree.reset_filters(imtherequester=True)
-
- def reset_tag_filters(self,refilter=True):
- self.main_tree.reset_tag_filters(refilter=refilter,imtherequester=True)
-
- def is_displayed(self,task):
+
+ def reset_tag_filters(self, refilter=True):
+ self.main_tree.reset_tag_filters(refilter=refilter,
+ imtherequester=True)
+
+ def is_displayed(self, task):
return self.main_tree.is_displayed(task)
######### Filters bank #######################
# Get the filter object for a given name
- def get_filter(self,filter_name):
+ def get_filter(self, filter_name):
return self.filters.get_filter(filter_name)
-
+
# List, by name, all available filters
+
def list_filters(self):
return self.filters.list_filters()
-
+
# Add a filter to the filter bank
# Return True if the filter was added
# Return False if the filter_name was already in the bank
- def add_filter(self,filter_name,filter_func):
- return self.filters.add_filter(filter_name,filter_func)
-
+
+ def add_filter(self, filter_name, filter_func):
+ return self.filters.add_filter(filter_name, filter_func)
+
# Remove a filter from the bank.
# Only custom filters that were added here can be removed
# Return False if the filter was not removed
- def remove_filter(self,filter_name):
+
+ def remove_filter(self, filter_name):
return self.filters.remove_filter(filter_name)
############## Tasks ##########################
###############################################
+
def has_task(self, tid):
"""Does the task 'tid' exist?"""
return self.ds.has_task(tid)
@@ -239,7 +248,7 @@
for t in self.ds.get_tagstore().get_all_tags():
if t.is_used() and t not in l:
l.append(t)
- l.sort(cmp=lambda x, y: cmp(x.get_name().lower(),\
+ l.sort(cmp=lambda x, y: cmp(x.get_name().lower(), \
y.get_name().lower()))
return l
@@ -258,13 +267,13 @@
for t in self.ds.get_tagstore().get_all_tags():
if t.is_actively_used() and t not in l:
l.append(t.get_name())
- l.sort(cmp=lambda x, y: cmp(x.lower(),y.lower()))
+ l.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))
return l
############## Backends #######################
###############################################
- def get_all_backends(self, disabled = False):
+ def get_all_backends(self, disabled=False):
return self.ds.get_all_backends(disabled)
def register_backend(self, dic):
=== modified file 'GTG/core/tagstore.py'
--- GTG/core/tagstore.py 2010-08-03 08:01:28 +0000
+++ GTG/core/tagstore.py 2010-08-18 19:18:41 +0000
@@ -37,37 +37,37 @@
XMLROOT = "tagstore"
-# There's only one Tag store per user. It will store all the tags used
-# and their attributes.
class TagStore(Tree):
+ """
+ Class TagStore that stores all Tags. There's only one TagStore per user.
+ It will store all the tags used and their attributes.
+ """
-
- def __init__(self,requester):
+ def __init__(self, requester):
Tree.__init__(self)
self.req = requester
- self.req.connect('tag-modified',self.update_tag)
-
+ self.req.connect('tag-modified', self.update_tag)
self.loaded = False
-
+
### building the initial tags
# Build the "all tasks tag"
self.alltag_tag = self.new_tag(CoreConfig.ALLTASKS_TAG)
- self.alltag_tag.set_attribute("special","all")
- self.alltag_tag.set_attribute("label","<span weight='bold'>%s</span>"\
+ self.alltag_tag.set_attribute("special", "all")
+ self.alltag_tag.set_attribute("label", "<span weight='bold'>%s</span>"\
% _("All tasks"))
- self.alltag_tag.set_attribute("icon","gtg-tags-all")
- self.alltag_tag.set_attribute("order",0)
+ self.alltag_tag.set_attribute("icon", "gtg-tags-all")
+ self.alltag_tag.set_attribute("order", 0)
# Build the "without tag tag"
self.notag_tag = self.new_tag("gtg-tags-none")
- self.notag_tag.set_attribute("special","notag")
- self.notag_tag.set_attribute("label","<span weight='bold'>%s</span>"\
+ self.notag_tag.set_attribute("special", "notag")
+ self.notag_tag.set_attribute("label", "<span weight='bold'>%s</span>"\
% _("Tasks with no tags"))
- self.notag_tag.set_attribute("icon","gtg-tags-none")
- self.notag_tag.set_attribute("order",1)
+ self.notag_tag.set_attribute("icon", "gtg-tags-none")
+ self.notag_tag.set_attribute("order", 1)
# Build the separator
self.sep_tag = self.new_tag("gtg-tags-sep")
- self.sep_tag.set_attribute("special","sep")
- self.sep_tag.set_attribute("order",2)
+ self.sep_tag.set_attribute("special", "sep")
+ self.sep_tag.set_attribute("order", 2)
self.filename = os.path.join(CoreConfig().get_data_dir(), XMLFILE)
doc, self.xmlstore = cleanxml.openxmlfile(self.filename,
@@ -86,16 +86,16 @@
i += 1
parent = tag.get_attribute('parent')
if parent:
- pnode=self.new_tag(parent)
+ pnode = self.new_tag(parent)
tag.set_parent(pnode.get_id())
self.loaded = True
- def update_tag(self,sender,tagname):
+ def update_tag(self, sender, tagname):
tag = self.get_tag(tagname)
if tag and tag.is_removable():
self.remove_tag(tagname)
-
- def remove_tag(self,tagname):
+
+ def remove_tag(self, tagname):
self.req._tag_deleted(tagname)
self.remove_node(tagname)
@@ -109,7 +109,7 @@
tag = Tag(tname, req=self.req)
self.add_node(tag)
self.req._tag_added(tname)
- self.req.add_filter(tname,None)
+ self.req.add_filter(tname, None)
for c in tag.get_children():
self.req._tag_modified(c)
#self.tags[tname] = tag
@@ -126,10 +126,10 @@
#FIXME : also add a new filter
def rename_tag(self, oldname, newname):
if len(newname) > 0 and \
- oldname not in ['gtg-tags-none','gtg-tags-all']:
+ oldname not in ('gtg-tags-none', 'gtg-tags-all'):
if newname[0] != "@":
newname = "@" + newname
- if newname != oldname and newname != None :
+ if newname != oldname and newname != None:
otag = self.get_node(oldname)
if not self.has_node(newname):
ntag = self.new_tag(newname)
@@ -138,7 +138,7 @@
#copy attributes
for att in otag.get_all_attributes(butname=True):
if not ntag.get_attribute(att):
- ntag.set_attribute(att,otag.get_attribute(att))
+ ntag.set_attribute(att, otag.get_attribute(att))
#restore position in tree
if otag.has_parent():
opar = otag.get_parent()
@@ -149,12 +149,13 @@
#copy tasks
for tid in otag.get_tasks():
tas = self.req.get_task(tid)
- tas.rename_tag(oldname,newname)
+ tas.rename_tag(oldname, newname)
#remove the old one
self.remove_tag(oldname)
self.req._tag_modified(oldname)
-# print "tag %s has %s tasks" %(newname,self.get_node(newname).get_tasks_nbr())
-
+# print """tag %s has %s tasks
+# """ %(newname,self.get_node(newname).get_tasks_nbr())
+
def get_all_tags_name(self, attname=None, attvalue=None):
"""Return the name of all tags
Optionally, if you pass the attname and attvalue argument, it will
@@ -163,9 +164,7 @@
(except if attvalue is None)"""
l = []
for t in self.get_all_nodes():
- if not attname:
- l.append(t.get_name())
- elif t.get_attribute(attname) == attvalue:
+ if t.get_attribute(attname) == attvalue or not attname:
l.append(t.get_name())
return l
@@ -186,7 +185,7 @@
#we don't save tags with no attributes
#It saves space and allow the saved list growth to be controlled
for t in tags:
- attr = t.get_all_attributes(butname = True, withparent = True)
+ attr = t.get_all_attributes(butname=True, withparent=True)
if "special" not in attr and len(attr) > 0:
tagname = t.get_name()
if not tagname in already_saved:
@@ -209,7 +208,7 @@
return self.notag_tag
### Tag Objects ##############################################################
-#
+
class Tag(TreeNode):
"""A short name that can be applied to L{Task}s.
@@ -240,7 +239,7 @@
"""Return the name of the tag."""
return self.get_attribute("name")
- def set_save_callback(self,save):
+ def set_save_callback(self, save):
self._save = save
def set_attribute(self, att_name, att_value):
@@ -267,7 +266,8 @@
val = unicode(str(att_value), "UTF-8")
self._attributes[att_name] = val
if self._save:
-# print "saving tag : attribute %s set to %s" %(att_name,att_value)
+# print """saving tag : attribute %s set to %s
+# """ %(att_name,att_value)
self._save()
def get_attribute(self, att_name):
@@ -280,24 +280,23 @@
if self.has_parent():
parents_id = self.get_parents()
if len(parents_id) > 0:
- to_return = reduce(lambda a,b: "%s,%s" % (a, b), parents_id)
+ to_return = reduce(lambda a, b: "%s,%s" % (a, b), parents_id)
else:
to_return = self._attributes.get(att_name, None)
return to_return
-
+
def del_attribute(self, att_name):
- """Deletes the attribute C{att_name}.
- """
+ """Deletes the attribute C{att_name}."""
if not att_name in self._attributes:
return
- elif att_name in ['name','parent']:
+ elif att_name in ('name', 'parent'):
return
else:
del self._attributes[att_name]
if self._save:
self._save()
- def get_all_attributes(self, butname=False, withparent = False):
+ def get_all_attributes(self, butname=False, withparent=False):
"""Return a list of all attribute names.
@param butname: If True, exclude C{name} from the list of attribute
@@ -313,14 +312,14 @@
attributes.append("parent")
return attributes
- ### TASK relation ####
+ ### TASK relation ####
def add_task(self, tid):
if tid not in self.tasks:
- self.tasks.append(tid)
+ self.tasks.append(tid)
def remove_task(self, tid):
if tid in self.tasks:
- self.tasks.remove(tid)
+ self.tasks.remove(tid)
self.req._tag_modified(self.get_name())
def get_tasks(self):
@@ -333,40 +332,15 @@
for ti in tmplist:
if ti not in toreturn:
toreturn.append(ti)
- return toreturn
-
-# We do not need this anymore.
-# #TODO: we want to optimize this task. Really.
-# def get_tasks_nbr(self,workview=False):
-# tasks = self.get_tasks()
-# temp_list = []
-# #workview in a non workviewable tag
-# if workview and self.get_attribute("nonworkview") == "True":
-# for t in tasks:
-# ta = self.req.get_task(t)
-# if ta.is_in_workview(tag=self) and t not in temp_list:
-# temp_list.append(t)
-# #workview in a workviewable tag
-# elif workview:
-# for t in tasks:
-# ta = self.req.get_task(t)
-# if ta and ta.is_in_workview() and t not in temp_list:
-# temp_list.append(t)
-# #non workview
-# else:
-# for t in tasks:
-# ta = self.req.get_task(t)
-# if ta and ta.get_status() == "Active" and t not in temp_list:
-# temp_list.append(t)
-# toreturn = len(temp_list)
-# return toreturn
- #is it useful to keep the tag in the tagstore.
- #if no attributes and no tasks, it is not useful.
+ return toreturn
+
def is_removable(self):
- attr = self.get_all_attributes(butname = True, withparent = True)
+ attr = self.get_all_attributes(butname=True, withparent=True)
return (len(attr) <= 0 and not self.is_used())
+
def is_used(self):
return len(self.tasks) > 0
+
def is_actively_used(self):
toreturn = False
for tid in self.tasks:
=== modified file 'GTG/core/task.py'
--- GTG/core/task.py 2010-07-01 09:59:33 +0000
+++ GTG/core/task.py 2010-08-18 19:18:41 +0000
@@ -44,16 +44,14 @@
def __init__(self, ze_id, requester, newtask=False):
TreeNode.__init__(self, ze_id)
- #the id of this task in the project should be set
- #tid is a string ! (we have to choose a type and stick to it)
- self.tid = str(ze_id)
+ self.tid = ze_id # if regression str(ze_id)
self.set_uuid(uuid.uuid4())
self.remote_ids = {}
self.content = ""
#self.content = \
# "<content>Press Escape or close this task to save it</content>"
self.title = _("My new task")
- #available status are: Active - Done - Dismiss - Note
+ #available status are: Active - Done - Dismiss
self.status = self.STA_ACTIVE
self.closed_date = no_date
self.due_date = no_date
@@ -66,13 +64,13 @@
self.loaded = newtask
if self.loaded:
self.req._task_loaded(self.tid)
- self.attributes={}
+ self.attributes = {}
self._modified_update()
def is_loaded(self):
return self.loaded
- def set_loaded(self,signal=True):
+ def set_loaded(self, signal=True):
#avoid doing it multiple times
if not self.loaded:
self.loaded = True
@@ -125,6 +123,7 @@
#Return True if the title was changed.
#False if the title was already the same.
+
def set_title(self, title):
#We should check for other task with the same title
#In that case, we should add a number (like Tomboy does)
@@ -146,9 +145,9 @@
if status:
#we first modify the status of the children
#If Done, we set the done date
- if status in [self.STA_DONE, self.STA_DISMISSED]:
- for c in self.get_subtasks():
- if c.get_status() in [self.STA_ACTIVE]:
+ if status in (self.STA_DONE, self.STA_DISMISSED):
+ for c in self.get_children():
+ if c.get_status() in self.STA_ACTIVE:
c.set_status(status, donedate=donedate)
#to the specified date (if any)
if donedate:
@@ -160,13 +159,13 @@
#Active, we break the parent/child relation
#It has no sense to have an active subtask of a done parent.
# (old_status check is necessary to avoid false positive a start)
- elif status in [self.STA_ACTIVE] and\
- old_status in [self.STA_DONE, self.STA_DISMISSED]:
- if self.has_parents():
+ elif status in self.STA_ACTIVE and\
+ old_status in (self.STA_DONE, self.STA_DISMISSED):
+ if TreeNode.has_parent(self):
for p_tid in self.get_parents():
par = self.req.get_task(p_tid)
if par.is_loaded() and par.get_status() in\
- [self.STA_DONE, self.STA_DISMISSED]:
+ (self.STA_DONE, self.STA_DISMISSED):
#we can either break the parent/child relationship
#self.remove_parent(p_tid)
#or restore the parent too
@@ -203,7 +202,7 @@
pardate = self.req.get_task(par).get_due_date()
if pardate and zedate > pardate:
zedate = pardate
-
+
return zedate
def set_start_date(self, fulldate):
@@ -218,7 +217,7 @@
assert(isinstance(fulldate, Date))
self.closed_date = fulldate
self.sync()
-
+
def get_closed_date(self):
return self.closed_date
@@ -227,7 +226,7 @@
if due_date == no_date:
return None
return due_date.days_left()
-
+
def get_days_late(self):
due_date = self.get_due_date()
if due_date == no_date:
@@ -238,11 +237,12 @@
def get_text(self):
#defensive programmtion to avoid returning None
if self.content:
- return str(self.content)
+ return self.content
else:
return ""
- def get_excerpt(self, lines=0, char=0, strip_tags=False, strip_subtasks=True):
+ def get_excerpt(self, lines=0, char=0, strip_tags=False,
+ strip_subtasks=True):
"""
get_excerpt return the beginning of the content of the task.
If "lines" is provided and different than 0, it return the number X
@@ -284,8 +284,8 @@
if element:
for n in element.childNodes:
if n.nodeType == n.ELEMENT_NODE:
- if strip_subtasks and n.tagName=='subtask':
- if txt[-2:]=='â ':
+ if strip_subtasks and n.tagName == 'subtask':
+ if txt[-2:] == 'ââ â ':
txt = txt[:-2]
else:
txt += self.__strip_content(n, strip_subtasks)
@@ -293,39 +293,39 @@
txt += n.nodeValue
return txt
- def set_text(self, texte):
+ def set_text(self, text):
self.can_be_deleted = False
- if texte != "<content/>":
+ if text != "<content/>":
#defensive programmation to filter bad formatted tasks
- if not texte.startswith("<content>"):
- texte = cgi.escape(texte, quote = True)
- texte = "<content>%s" %texte
- if not texte.endswith("</content>"):
- texte = "%s</content>" %texte
- self.content = str(texte)
+ if not text.startswith("<content>"):
+ text = cgi.escape(text, quote=True)
+ text = "<content>%s" % text
+ if not text.endswith("</content>"):
+ text = "%s</content>" % text
+ self.content = str(text)
else:
self.content = ''
### SUBTASKS #############################################################
- #
+
def new_subtask(self):
"""Add a newly created subtask to this task. Return the task added as
a subtask
"""
- subt = self.req.new_task(newtask=True)
+ subt = self.req.new_task(newtask=True)
#we use the inherited childrens
self.add_child(subt.get_id())
return subt
-
+
def add_child(self, tid):
"""Add a subtask to this task
@param child: the added task
"""
- Log.debug("adding child %s to task %s" %(tid, self.get_id()))
+ Log.debug("adding child %s to task %s" % (tid, self.get_id()))
self.can_be_deleted = False
#the core of the method is in the TreeNode object
- if TreeNode.add_child(self,tid):
+ if TreeNode.add_child(self, tid):
#now we set inherited attributes only if it's a new task
child = self.req.get_task(tid)
if child.can_be_deleted:
@@ -339,15 +339,16 @@
else:
Log.debug("child addition failed (or still pending)")
return False
-
-
+
+
#FIXME: remove this function. Handle that on the remove level
- def remove_child(self,tid):
+
+ def remove_child(self, tid):
"""Removed a subtask from the task.
@param tid: the ID of the task to remove
"""
- if TreeNode.remove_child(self,tid):
+ if TreeNode.remove_child(self, tid):
task = self.req.get_task(tid)
if task.can_be_deleted:
#child is a new, unmodified task
@@ -360,8 +361,16 @@
#FIXME : remove this method
+ #Help for removing. After removing, i can sat that removing this is easy
+ #except for delete_dialog.py, apparently, there's a problem with the
+ #function that is inside a for loop. This could be avoided and if someone
+ #could investigate why that function doesn't work with get_children, it
+ #would allow to remove this function. (And enhance code in ~5 places.)
+ #Tip: Use find . -iname '*py' | xargs grep 'get_subtasks' -sl to find
+ #places where this function is used.
+
def get_subtasks(self):
-# print "Deprecation Warning : use get_children instead of get_subtasks"
+ # print "Deprecation Warning : use get_children instead of get_subtasks"
#XXX: is this useful?
zelist = []
for i in self.get_children():
@@ -369,32 +378,15 @@
if t:
zelist.append(t)
return zelist
-
- #FIXME : why is this function used ? It's higly specific. Remove it ?
- def get_self_and_all_subtasks(self, active_only=False, tasks=[]):
- tasks.append(self)
- for tid in self.get_children():
- i = self.req.get_task(tid)
- if i:
- if not active_only or i.status == self.STA_ACTIVE:
- i.get_self_and_all_subtasks(active_only, tasks)
- return tasks
-
- def get_subtask(self, tid):
- #FIXMEÂ : remove this function. This is not useful
- """Return the task corresponding to a given ID.
-
- @param tid: the ID of the task to return.
- """
- return self.req.get_task(tid)
### PARENTS ##############################################################
- #Take a tid object as parameter
+ #add_parent and remove_parent both take a pid as parameter
+
def add_parent(self, parent_tid):
- #FIXMEÂ : the sync should be automatically done
+ #FIXME : the sync should be automatically done
#at the tree level. remove this function
- Log.debug("adding parent %s to task %s" %(parent_tid, self.get_id()))
+ Log.debug("adding parent %s to task %s" % (parent_tid, self.get_id()))
added = TreeNode.add_parent(self, parent_tid)
if added:
self.sync()
@@ -404,33 +396,15 @@
else:
return False
- #Take a tid as parameter
def remove_parent(self, tid):
- #FIXMEÂ : the sync should be automatically done
+ #FIXME : the sync should be automatically done
#at the tree level. remove this function
- TreeNode.remove_parent(self,tid)
+ TreeNode.remove_parent(self, tid)
self.sync()
parent = self.req.get_task(tid)
if parent:
parent.sync()
- #Return true is the task has parent
- #If tag is provided, return True only
- #if the parent has this particular tag
- #FIXMEÂ : this function should be removed. Use the tree instead !
- def has_parents(self, tag=None):
- has_par = TreeNode.has_parent(self)
- #The "all tag" argument
- if tag and has_par:
- a = 0
- for tid in self.get_parents():
- p = self.req.get_task(tid)
- a += p.has_tags(tag)
- to_return = a
- else:
- to_return = has_par
- return to_return
-
def set_attribute(self, att_name, att_value, namespace=""):
"""Set an arbitrary attribute.
@@ -441,7 +415,7 @@
val = unicode(str(att_value), "UTF-8")
self.attributes[(namespace, att_name)] = val
self.sync()
-
+
def get_attribute(self, att_name, namespace=""):
"""Get the attribute C{att_name}.
@@ -452,9 +426,10 @@
#Method called before the task is deleted
#This method is called by the datastore and should not be called directly
#Use the requester
+
def delete(self):
#we issue a delete for all the children
- for task in self.get_subtasks():
+ for task in self.get_children():
#I think it's superfluous (invernizzi)
#task.remove_parent(self.get_id())
task.delete()
@@ -476,9 +451,10 @@
return True
else:
return False
-
- #This function send the modified signals for the tasks,
+
+ #This function send the modified signals for the tasks,
#parents and children
+
def call_modified(self):
#we first modify children
for s in self.get_children():
@@ -496,7 +472,7 @@
self.modified = datetime.now()
### TAG FUNCTIONS ############################################################
-#
+
def get_tags_name(self):
#Return a copy of the list of tags. Not the original object.
return list(self.tags)
@@ -507,7 +483,7 @@
for tname in self.tags:
l.append(self.req.get_tag(tname))
return l
-
+
def rename_tag(self, old, new):
eold = saxutils.escape(saxutils.unescape(old))
enew = saxutils.escape(saxutils.unescape(new))
@@ -538,18 +514,18 @@
child.add_tag(t)
self.req._tag_modified(t)
return True
-
+
def add_tag(self, tagname):
"Add a tag to the task and insert '@tag' into the task's content"
if self.tag_added(tagname):
c = self.content
-
+
#strip <content>...</content> tags
if c.startswith('<content>'):
c = c[len('<content>'):]
if c.endswith('</content>'):
c = c[:-len('</content>')]
-
+
if not c:
# don't need a separator if it's the only text
sep = ''
@@ -559,7 +535,7 @@
else:
# other text at the beginning, so put the tag on its own line
sep = '\n\n'
-
+
self.content = "<content><tag>%s</tag>%s%s</content>" % (
tagname, sep, c)
@@ -573,28 +549,28 @@
if tagname in self.tags:
self.tags.remove(tagname)
modified = True
- for child in self.get_subtasks():
+ for child in self.get_children():
if child.can_be_deleted:
child.remove_tag(tagname)
self.content = self._strip_tag(self.content, tagname)
if modified:
self.req._tag_modified(tagname)
-
- def _strip_tag(self, text, tagname,newtag=''):
+
+ def _strip_tag(self, text, tagname, newtag=''):
return (text
- .replace('<tag>%s</tag>\n\n'%(tagname), newtag) #trail \n
- .replace('<tag>%s</tag>, '%(tagname), newtag) #trail comma
- .replace('<tag>%s</tag>'%(tagname), newtag)
+ .replace('<tag>%s</tag>\n\n' % (tagname), newtag) #trail \n
+ .replace('<tag>%s</tag>, ' % (tagname), newtag) #trail ','
+ .replace('<tag>%s</tag>' % (tagname), newtag)
#in case XML is missing (bug #504899)
- .replace('%s\n\n'%(tagname), newtag)
- .replace('%s, '%(tagname), newtag)
+ .replace('%s\n\n' % (tagname), newtag)
+ .replace('%s, ' % (tagname), newtag)
#don't forget a space a the end
- .replace('%s '%(tagname), newtag)
+ .replace('%s ' % (tagname), newtag)
)
-
#tag_list is a list of tags names
#return true if at least one of the list is in the task
+
def has_tags(self, tag_list=None, notag_only=False):
#We want to see if the task has no tags
if notag_only:
@@ -614,19 +590,13 @@
#return the color of one tag that have a color defined
#Yes, the choosen color is a bit random in case of multiple colored tags
+
def get_color(self):
- color = None
for t in self.get_tags():
- c = t.get_attribute("color")
- if c:
- color = c
- return color
+ if t.get_attribute("color"):
+ return t.get_attribute("color")
+ return None
def __str__(self):
- s = ""
- s = s + "Task Object\n"
- s = s + "Title: " + self.title + "\n"
- s = s + "Id: " + self.tid + "\n"
- s = s + "Status: " + self.status + "\n"
- s = s + "Tags: " + str(self.tags)
- return s
+ return "Task Object\nTitle: " + self.title + "\nId: " + self.tid \
+ + "\nStatus: " + self.status + "\nTags: " + str(self.tags)
=== modified file 'GTG/core/tree.py'
--- GTG/core/tree.py 2010-07-18 23:18:23 +0000
+++ GTG/core/tree.py 2010-08-18 19:18:41 +0000
@@ -17,10 +17,16 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------------
+"""Defines the Tree and Treenode class."""
+
from GTG.tools.logger import Log
+
class Tree():
-
+ """
+ Defines the Tree class, if root is provided, it will be used instead of
+ command TreeNode(id="root")
+ """
def __init__(self, root=None):
self.root_id = 'root'
@@ -37,20 +43,19 @@
return "<Tree: root = '%s'>" % (str(self.root))
def get_node_for_path(self, path):
- return self._node_for_path(self.root,path)
+ return self._node_for_path(self.root, path)
def get_path_for_node(self, node):
toreturn = self._path_for_node(node)
return toreturn
-
+
#a deleted path can be requested only once
- def get_deleted_path(self,id):
+ def get_deleted_path(self, id):
toreturn = None
- Log.debug( "old paths are : %s" %self.old_paths )
+ Log.debug("old paths are : %s" % self.old_paths)
if self.old_paths.has_key(id):
toreturn = self.old_paths.pop(id)
return toreturn
-
def get_root(self):
return self.root
@@ -64,12 +69,12 @@
#print "*************adding node %s %s" %(node, parent)
id = node.get_id()
if self.nodes.has_key(id):
- print "Error : A node with this id %s already exists" %id
+ print "Error : A node with this id %s already exists" % id
return False
else:
#We add the node
node.set_tree(self)
- if parent:#
+ if parent:
node.set_parent(parent.get_id())
parent.add_child(id)
else:
@@ -78,15 +83,16 @@
#build the relationships that were waiting for that node
for rel in list(self.pending_relationships):
if id in rel:
- self.new_relationship(rel[0],rel[1])
+ self.new_relationship(rel[0], rel[1])
return True
#this will remove a node and all his children
#does nothing if the node doesn't exist
+
def remove_node(self, id):
node = self.get_node(id)
path = self.get_path_for_node(node)
- if not node :
+ if not node:
return
else:
if node.has_child():
@@ -100,13 +106,14 @@
self.root.remove_child(id)
self.old_paths[id] = path
self.nodes.pop(id)
-
+
#create a new relationship between nodes if it doesn't already exist
#return False if nothing was done
- def new_relationship(self,parent_id,child_id):
- Log.debug("new relationship between %s and %s" %(parent_id,child_id))
- if [parent_id,child_id] in self.pending_relationships:
- self.pending_relationships.remove([parent_id,child_id])
+
+ def new_relationship(self, parent_id, child_id):
+ Log.debug("new relationship between %s and %s" % (parent_id, child_id))
+ if (parent_id, child_id) in self.pending_relationships:
+ self.pending_relationships.remove((parent_id, child_id))
toreturn = False
#no relationship allowed with yourself
if parent_id != child_id:
@@ -116,7 +123,7 @@
else:
p = self.get_node(parent_id)
c = self.get_node(child_id)
- if p and c :
+ if p and c:
#no circular relationship allowed
if not p.has_parent(child_id) and not c.has_child(parent_id):
if not p.has_child(child_id):
@@ -134,25 +141,26 @@
#a circular relationship was found
#undo everything
Log.debug(" * * * * * Circular relationship found : undo")
- self.break_relationship(parent_id,child_id)
+ self.break_relationship(parent_id, child_id)
toreturn = False
else:
- #at least one of the node is not loaded. Save the relation for later
- #undo everything
- self.break_relationship(parent_id,child_id)
+ #at least one of the node is not loaded.
+ #Save the relation for later undo everything
+ self.break_relationship(parent_id, child_id)
#save it for later
- if [parent_id,child_id] not in self.pending_relationships:
- self.pending_relationships.append([parent_id,child_id])
+ if (parent_id, child_id) not in self.pending_relationships:
+ self.pending_relationships.append((parent_id, child_id))
toreturn = True
return toreturn
-
+
#break an existing relationship. The child is added to the root
- #return False if the relationship didn't exist
- def break_relationship(self,parent_id,child_id):
+ #return False if the relationship didn't exist
+
+ def break_relationship(self, parent_id, child_id):
toreturn = False
p = self.get_node(parent_id)
c = self.get_node(child_id)
- if p and c :
+ if p and c:
if p.has_child(child_id):
ret = p.remove_child(child_id)
toreturn = True
@@ -163,14 +171,15 @@
if not c.has_parent():
self.root.add_child(child_id)
return toreturn
-
+
#Trying to make a function that bypass the weirdiness of lists
- def get_node(self,id):
+
+ def get_node(self, id):
return self.nodes.get(id)
-
+
def get_all_keys(self):
return list(self.nodes.keys())
-
+
def get_all_nodes(self):
li = []
for k in self.nodes.keys():
@@ -192,8 +201,8 @@
self._visit_node(node, pre_func, post_func)
### HELPER FUNCTION FOR TREE #################################################
-#
- def _node_for_path(self,node,path):
+
+ def _node_for_path(self, node, path):
if path[0] < node.get_n_children():
if len(path) == 1:
return node.get_nth_child(path[0])
@@ -205,21 +214,21 @@
return None
def _path_for_node(self, node):
- if node:
+ if node:
if node == self.root:
toreturn = ()
elif not node.has_parent():
- index = self.root.get_child_index(node.get_id())
+ index = self.root.get_child_index(node.get_id())
toreturn = self._path_for_node(self.root) + (index, )
else:
# no multiparent support here
parent_id = node.get_parent()
if len(node.get_parents()) >= 2:
- print "multiple parents for task %s" %node.get_id()
+ print "multiple parents for task %s" % node.get_id()
print "you should use a filteredtree above this tree"
parent = self.get_node(parent_id)
if parent:
- index = parent.get_child_index(node.get_id())
+ index = parent.get_child_index(node.get_id())
toreturn = self._path_for_node(parent) + (index, )
else:
toreturn = ()
@@ -250,9 +259,9 @@
class TreeNode():
def __init__(self, id, tree=None, parent=None):
- self.parents = []
- self.id = id
- self.children = []
+ self.parents = []
+ self.id = id
+ self.children = []
self.tree = tree
self.pending_relationship = []
if parent:
@@ -260,45 +269,46 @@
def __str__(self):
return "<TreeNode: '%s'>" % (self.id)
-
- def set_tree(self,tree):
+
+ def set_tree(self, tree):
self.tree = tree
- for rel in list(self.pending_relationship):
- self.tree.new_relationship(rel[0],rel[1])
+ for rel in tuple(self.pending_relationship):
+ self.tree.new_relationship(rel[0], rel[1])
self.pending_relationship.remove(rel)
-
+
def get_tree(self):
return self.tree
def get_id(self):
return self.id
-
-
- def new_relationship(self,par,chi):
+
+ def new_relationship(self, par, chi):
if self.tree:
- return self.tree.new_relationship(par,chi)
+ return self.tree.new_relationship(par, chi)
else:
- self.pending_relationship.append([par,chi])
+ self.pending_relationship.append((par, chi))
#it's pending, we return False
Log.debug("** There's still no tree, relationship is pending")
return False
-
-
+
##### Parents
- def has_parent(self,id=None):
+ def has_parent(self, id=None):
if id:
return id in self.parents
else:
- toreturn = len(self.parents) > 0
- return toreturn
-
+ return len(self.parents) > 0
+
#this one return only one parent.
#useful for tree where we know that there is only one
+
def get_parent(self):
#we should throw an error if there are multiples parents
- if len(self.parents) > 1 :
- print "Warning: get_parent will return one random parent for task %s because there are multiple parents." %(self.get_id())
+ if len(self.parents) > 1:
+ print """
+ Warning: get_parent will return one random parent for
+ task %s because there are multiple parents." %(self.get_id())
+ """
print "Get_parent is deprecated. Please use get_parents instead"
if self.has_parent():
return self.parents[0]
@@ -319,13 +329,13 @@
self.parents.append(parent_id)
toreturn = self.new_relationship(parent_id, self.get_id())
# if not toreturn:
-# Log.debug("** parent addition failed (probably already done)*")
+# Log.debug("** parent addition failed (probably already done)")
else:
toreturn = False
return toreturn
-
+
#set_parent means that we remove all other parents
- def set_parent(self,par_id):
+ def set_parent(self, par_id):
is_already_parent_flag = False
if par_id:
for i in self.parents:
@@ -335,19 +345,19 @@
is_already_parent_flag = True
if not is_already_parent_flag:
self.add_parent(par_id)
-
- def remove_parent(self,id):
+
+ def remove_parent(self, id):
if id in self.parents:
self.parents.remove(id)
- ret = self.tree.break_relationship(id,self.get_id())
+ ret = self.tree.break_relationship(id, self.get_id())
return ret
else:
return False
-
+
###### Children
- def has_child(self,id=None):
- if id :
+ def has_child(self, id=None):
+ if id:
return id in self.children
else:
return len(self.children) != 0
@@ -380,26 +390,25 @@
#return True if the child was added correctly. False otherwise
#takes the id of the child as parameter.
#if the child is not already in the tree, the relation is anyway "saved"
+
def add_child(self, id):
if id not in self.children:
self.children.append(id)
- toreturn = self.new_relationship(self.get_id(),id)
+ toreturn = self.new_relationship(self.get_id(), id)
# Log.debug("new relationship : %s" %toreturn)
else:
- Log.debug("%s was already in children of %s" %(id,self.get_id()))
+ Log.debug("%s was already in children of %s" % (id, self.get_id()))
toreturn = False
return toreturn
def remove_child(self, id):
if id in self.children:
self.children.remove(id)
- ret = self.tree.break_relationship(self.get_id(),id)
- return ret
+ return self.tree.break_relationship(self.get_id(), id)
else:
return False
-
- def change_id(self,newid):
+ def change_id(self, newid):
oldid = self.id
self.id = newid
for p in self.parents:
=== modified file 'GTG/gtk/browser/browser.py'
--- GTG/gtk/browser/browser.py 2010-08-13 22:37:12 +0000
+++ GTG/gtk/browser/browser.py 2010-08-18 19:18:41 +0000
@@ -920,7 +920,7 @@
# a non-capturing group, so it must not be returned
# to findall. http://www.amk.ca/python/howto/regex/regex.html
# ~~~~Invernizzi
- for match in re.findall(r'(?:^|[\s])(@\w+)', text, re.UNICODE):
+ for match in re.findall(r'(?[\s])(@\w+)', text, re.UNICODE):
tags.append(GTG.core.tagstore.Tag(match, self.req))
# Remove the @
#text =text.replace(match,match[1:],1)
@@ -928,8 +928,8 @@
regexp = r'([\s]*)([\w-]+):([^\s]+)'
for spaces, attribute, args in re.findall(regexp, text):
valid_attribute = True
- if attribute.lower() in ["tags", "tag"] or \
- attribute.lower() in [_("tags"), _("tag")]:
+ if attribute.lower() in ("tags", "tag") or \
+ attribute.lower() in (_("tags"), _("tag")):
for tag in args.split(","):
if not tag.startswith("@") :
tag = "@"+tag
@@ -1179,10 +1179,9 @@
if apply_to_subtasks.get_active():
for tid in self.tids_to_addtag:
task = self.req.get_task(tid)
- for i in task.get_self_and_all_subtasks():
- taskid = i.get_id()
- if taskid not in self.tids_to_addtag:
- self.tids_to_addtag.append(taskid)
+ for i in task.get_children():
+ if i not in self.tids_to_addtag:
+ self.tids_to_addtag.append(i)
for tid in self.tids_to_addtag:
task = self.req.get_task(tid)
for new_tag in new_tags:
=== modified file 'GTG/gtk/browser/tasktree.py'
--- GTG/gtk/browser/tasktree.py 2010-07-01 09:25:59 +0000
+++ GTG/gtk/browser/tasktree.py 2010-08-18 19:18:41 +0000
@@ -23,7 +23,7 @@
import pango
from GTG import _
-from GTG.core.tree import Tree, TreeNode
+#from GTG.core.tree import Tree, TreeNode
from GTG.core.task import Task
from GTG.gtk import colors
from GTG.gtk.browser.CellRendererTags import CellRendererTags
@@ -424,7 +424,7 @@
"""Moves the task identified by child_tid under
parent_tid, removing all the precedent parents.
Child becomes a root task if parent_tid is None"""
- #The genealogic search has been moved to liblarch and should be
+ #FIXME: The genealogic search has been moved to liblarch and should be
#removed from here
def genealogic_search(tid):
if tid not in genealogy:
=== modified file 'GTG/gtk/dbuswrapper.py'
--- GTG/gtk/dbuswrapper.py 2010-06-10 14:45:36 +0000
+++ GTG/gtk/dbuswrapper.py 2010-08-18 19:18:41 +0000
@@ -17,7 +17,6 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------------
-import unicodedata
import dbus
import dbus.glib
@@ -30,7 +29,6 @@
BUSNAME = CoreConfig.BUSNAME
BUSFACE = CoreConfig.BUSINTERFACE
-
def dsanitize(data):
"""
Clean up a dict so that it can be transmitted through D-Bus.
=== modified file 'GTG/gtk/editor/editor.py'
--- GTG/gtk/editor/editor.py 2010-07-06 04:01:50 +0000
+++ GTG/gtk/editor/editor.py 2010-08-18 19:18:41 +0000
@@ -294,7 +294,7 @@
self.tasksidebar.show()
#Refreshing the status bar labels and date boxes
- if status in [Task.STA_DISMISSED, Task.STA_DONE]:
+ if status in (Task.STA_DISMISSED, Task.STA_DONE):
self.builder.get_object("label2").hide()
self.builder.get_object("hbox1").hide()
self.builder.get_object("label4").show()
@@ -321,7 +321,7 @@
#If the task is marked as done, we display the delay between the
#due date and the actual closing date. If the task isn't marked
#as done, we display the number of days left.
- if status in [Task.STA_DISMISSED, Task.STA_DONE]:
+ if status in (Task.STA_DISMISSED, Task.STA_DONE):
delay = self.task.get_days_late()
if delay is None:
txt = ""
@@ -624,7 +624,7 @@
#destroy in the close function, this will cause the close to be called twice
#To solve that, close will just call "destroy" and the destroy signal
#Will be linked to this destruction method that will save the task
- def destruction(self,a=None) :#pylint: disable-msg=W0613
+ def destruction(self, a=None) :#pylint: disable-msg=W0613
#Save should be also called when buffer is modified
self.pengine.onTaskClose(self.plugins, self.te_plugin_api)
self.p_apis.remove(self.te_plugin_api)
@@ -641,7 +641,7 @@
############# Private functions #################
- def __focus_out(self,w=None,e=None) : #pylint: disable-msg=W0613
+ def __focus_out(self, w=None, e=None) : #pylint: disable-msg=W0613
#We should only close if the pointer click is out of the calendar !
p = self.calendar.window.get_pointer()
s = self.calendar.get_size()
@@ -649,7 +649,7 @@
self.__close_calendar()
- def __close_calendar(self,widget=None,e=None) : #pylint: disable-msg=W0613
+ def __close_calendar(self, widget=None, e=None) : #pylint: disable-msg=W0613
self.calendar.hide()
self.__opened_date = ''
gtk.gdk.pointer_ungrab()
=== modified file 'GTG/plugins/geolocalized_tasks/geolocalized_tasks.py'
--- GTG/plugins/geolocalized_tasks/geolocalized_tasks.py 2010-06-09 15:13:57 +0000
+++ GTG/plugins/geolocalized_tasks/geolocalized_tasks.py 2010-08-18 19:18:41 +0000
@@ -15,7 +15,7 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
import gtk
-import os, sys
+import os
#from time import sleep
#from configobj import ConfigObj
@@ -27,6 +27,7 @@
from GTG.plugins.geolocalized_tasks.marker import MarkerLayer
+
class geolocalizedTasks:
def __init__(self):
=== modified file 'GTG/plugins/import_json/import_json.py'
--- GTG/plugins/import_json/import_json.py 2010-04-27 02:52:37 +0000
+++ GTG/plugins/import_json/import_json.py 2010-08-18 19:18:41 +0000
@@ -40,7 +40,6 @@
import gtk
import os
import re
-import urllib2
import simplejson as json
from GTG.tools.readurl import readurl
=== modified file 'GTG/plugins/rtm_sync/pyrtm/rtm.py'
--- GTG/plugins/rtm_sync/pyrtm/rtm.py 2010-03-17 03:55:32 +0000
+++ GTG/plugins/rtm_sync/pyrtm/rtm.py 2010-08-18 19:18:41 +0000
@@ -10,7 +10,6 @@
import warnings
import urllib
-import time
from hashlib import md5
from GTG import _
=== modified file 'GTG/tests/test_backends.py'
--- GTG/tests/test_backends.py 2010-06-23 12:49:28 +0000
+++ GTG/tests/test_backends.py 2010-08-18 19:18:41 +0000
@@ -30,7 +30,6 @@
# GTG imports
from GTG.backends import backend_localfile as localfile
-from GTG.core import datastore
from GTG.tools import cleanxml
=== modified file 'GTG/tools/cleanxml.py'
--- GTG/tools/cleanxml.py 2010-06-17 13:36:59 +0000
+++ GTG/tools/cleanxml.py 2010-08-18 19:18:41 +0000
@@ -20,7 +20,6 @@
import os, xml.dom.minidom
import shutil
import sys
-import time
import re
from GTG.tools.logger import Log
@@ -55,7 +54,7 @@
def cleanString(string,indent="",newl=""):
#we will remove the pretty XML stuffs.
- #Firt, we remove the \n and tab in elements
+ #First, we remove the \n and tab in elements
e = re.compile('>\n\t*')
toreturn = e.sub('>',string)
#then we remove the \n tab before closing elements
=== modified file 'GTG/tools/liblarch/filters_bank.py'
--- GTG/tools/liblarch/filters_bank.py 2010-07-01 09:41:45 +0000
+++ GTG/tools/liblarch/filters_bank.py 2010-08-18 19:18:41 +0000
@@ -24,7 +24,7 @@
from datetime import datetime
from GTG.core.task import Task
-from GTG.tools.dates import date_today, no_date, Date
+from GTG.tools.dates import date_today, no_date
class Filter:
=== modified file 'GTG/tools/readurl.py'
--- GTG/tools/readurl.py 2010-04-27 02:52:37 +0000
+++ GTG/tools/readurl.py 2010-08-18 19:18:41 +0000
@@ -20,9 +20,6 @@
"""
Loads the contents of a given URL
"""
-
-import os
-import sys
import urllib2
def readurl(url):
=== modified file 'gtcli'
--- gtcli 2010-08-04 19:41:19 +0000
+++ gtcli 2010-08-18 19:18:41 +0000
@@ -27,7 +27,6 @@
def usage():
f = " %-30s %s\n"
- progname = sys.argv[0]
text = _("gtcli -- a command line interface to gtg\n")
text += "\n"
=== modified file 'scripts/debug.sh'
--- scripts/debug.sh 2010-08-03 00:34:42 +0000
+++ scripts/debug.sh 2010-08-18 19:18:41 +0000
@@ -1,5 +1,11 @@
#!/bin/bash
+#Don't let the user execute this as root, it breaks graphical login (Changes /tmp permissions)
+if [ "$(whoami)" = "root" ]; then
+ echo "You can't be logged in root, this breaks graphical login"
+ exit
+fi
+
args="--no-crash-handler"
set="default"
norun=0
Follow ups