def task_from_xml(task, xmlnode): # print "********************************" # print xmlnode.toprettyxml() task.set_uuid(xmlnode.getAttribute("uuid")) task.set_title(read_node(xmlnode, "title")) status = xmlnode.getAttribute("status") donedate = Date.parse(read_node(xmlnode, "donedate")) task.set_status(status, donedate=donedate) duedate = Date(read_node(xmlnode, "duedate")) task.set_due_date(duedate) startdate = Date(read_node(xmlnode, "startdate")) task.set_start_date(startdate) modified = read_node(xmlnode, "modified") if modified != "": modified = datetime.strptime(modified, "%Y-%m-%dT%H:%M:%S") task.set_modified(modified) tags = xmlnode.getAttribute("tags").replace(' ', '') tags = (tag for tag in tags.split(',') if tag.strip() != "") for tag in tags: # FIXME why unescape???? task.tag_added(saxutils.unescape(tag)) # FIXME why we need to convert that through an XML? content = read_node(xmlnode, "content") if content != "": content = "<content>%s</content>" % content content = minidom.parseString(content).firstChild.toxml() task.set_text(content) for subtask in xmlnode.getElementsByTagName("subtask"): task.add_child(get_text(subtask)) for attr in xmlnode.getElementsByTagName("attribute"): if len(attr.childNodes) > 0: value = get_text(attr) else: value = "" key = attr.getAttribute("key") namespace = attr.getAttribute("namespace") task.set_attribute(key, value, namespace=namespace) # FIXME do we need remote task ids? I don't think so # FIXME if so => rework them into a more usable structure!!! # (like attributes) # REMOTE TASK IDS remote_ids_list = xmlnode.getElementsByTagName("task-remote-ids") for remote_id in remote_ids_list: if remote_id.childNodes: node = remote_id.childNodes[0] backend_id = node.firstChild.nodeValue remote_task_id = node.childNodes[1].firstChild.nodeValue task.add_remote_id(backend_id, remote_task_id) return task
def set_start_date(self, fulldate): self.start_date = Date(fulldate) if not Date(fulldate).is_fuzzy() and \ not self.due_date.is_fuzzy() and \ Date(fulldate) > self.due_date: self.set_due_date(fulldate) self.sync()
def get_fuzzy_date(self, current_due_date, due_date): #print "Current due_date = " + str(current_due_date) #print "New due date = " + str(Date(due_date).date()) #print "FUzzy date in datetime = " + str(Date(current_due_date).date()) if Date(current_due_date).date() == Date(due_date).date(): #print "Both are same" return current_due_date return due_date
def set_start_date(self, fulldate): self.start_date = Date(fulldate) if not Date(fulldate).is_fuzzy() and \ not self.due_date.is_fuzzy() and \ Date(fulldate) > self.due_date: self.set_due_date(fulldate) else: # BUG: nervous self._has_been_modified() self.sync()
def __day_selected(self, widget, date_type): if date_type == "RealDate": calendar_date = self.__calendar.get_date() date = self.__from_calendar_date_to_datetime(calendar_date) self.__date = Date(date) else: self.__date = Date(date_type) if self.__is_user_just_browsing_the_calendar: # this day-selected signal was caused by a month/year change self.__is_user_just_browsing_the_calendar = False else: # inform the Editor that the date has changed self.close_calendar() GObject.idle_add(self.emit, "date-changed")
def __day_selected(self, widget, date_type): if date_type == "RealDate": calendar_date = self.__calendar.get_date() date = self.__from_calendar_date_to_datetime(calendar_date) self.__date = Date(date) else: self.__date = Date(date_type) # Hackish? Give time for: # (1) the user to see the date turn blue, and # (2) for *most* button-released events to cancel the calendar's in_drag mode # As a side-effect, any dragged dates might drop into the window... # but that's better than the aweful alternatives of: # (1) "since when & why am I dragging a document into the calendar", and # (2) "why did clicking on this date open the link that was under the date" gtk.timeout_add(500, self.__maybe_close_calendar)
def set_due_date(self, new_duedate): """Defines the task's due date.""" def __get_defined_parent_list(task): """Recursively fetch a list of parents that have a defined due date which is not fuzzy""" parent_list = [] for par_id in task.parents: par = self.req.get_task(par_id) if par.get_due_date().is_fuzzy(): parent_list += __get_defined_parent_list(par) else: parent_list.append(par) return parent_list def __get_defined_child_list(task): """Recursively fetch a list of children that have a defined due date which is not fuzzy""" child_list = [] for child_id in task.children: child = self.req.get_task(child_id) if child.get_due_date().is_fuzzy(): child_list += __get_defined_child_list(child) else: child_list.append(child) return child_list old_due_date = self.due_date new_duedate_obj = Date(new_duedate) # caching the conversion self.due_date = new_duedate_obj # If the new date is fuzzy or undefined, we don't update related tasks if not new_duedate_obj.is_fuzzy(): # if the task's start date happens later than the # new due date, we update it (except for fuzzy dates) if not self.get_start_date().is_fuzzy() and \ self.get_start_date() > new_duedate_obj: self.set_start_date(new_duedate) # if some ancestors' due dates happen before the task's new # due date, we update them (except for fuzzy dates) for par in __get_defined_parent_list(self): if par.get_due_date() < new_duedate_obj: par.set_due_date(new_duedate) # we must apply the constraints to the defined & non-fuzzy children # as well for sub in __get_defined_child_list(self): sub_duedate = sub.get_due_date() # if the child's due date happens later than the task's: we # update it to the task's new due date if sub_duedate > new_duedate_obj: sub.set_due_date(new_duedate) # if the child's start date happens later than # the task's new due date, we update it # (except for fuzzy start dates) sub_startdate = sub.get_start_date() if not sub_startdate.is_fuzzy() and \ sub_startdate > new_duedate_obj: sub.set_start_date(new_duedate) # If the date changed, we notify the change for the children since the # constraints might have changed if old_due_date != new_duedate_obj: self.recursive_sync()
def get_due_date(self): ''' Gets the task due date ''' due = self.rtm_task.due if due == "": return Date.no_date() date = self.__time_rtm_to_datetime(due).date() return Date(date)
def local_update_task(self, remote_task, local_task): """ "Local Update" implementation. """ #print "Updating local task started ..." local_task.set_title(_(remote_task["name"])) local_task.set_text(_(remote_task["description"])) #print "Task Status = " + str(remote_task["status"]) status = self.WEB_STATUS_TO_GTG.get(remote_task["status"], 'Active') local_task.set_status(status) start_date = self.str_to_datetime(remote_task["start_date"], \ return_date = True, without_time = True) due_date = self.str_to_datetime(remote_task["due_date"], \ return_date = True, without_time = True) local_task.set_start_date(Date(start_date)) current_due_date = local_task.get_due_date() if current_due_date.is_fuzzy(): #print "Local task,= " + local_task.get_title() + " due date is FUZZY" due_date = self.get_fuzzy_date(current_due_date, due_date) local_task.set_due_date(Date(due_date)) new_tags = set(['@' + tag["name"] for tag in remote_task["tags"]]) #print "new_tags = " + str(new_tags) current_tags = set(local_task.get_tags_name()) # remove the lost tags for tag in current_tags.difference(new_tags): local_task.remove_tag(tag) # add the new ones for tag in new_tags.difference(current_tags): local_task.add_tag(tag) #if local_task.get_remote_ids().get(self.get_id(), None) == None: #local_task.add_remote_id(self.get_id(), remote_task["id"]) if len(local_task.get_subtasks()) != len(remote_task["subtasks"]): local_task = self.add_subtasks_from_remote(local_task, \ remote_task) #print "Before returning, local_task = " + str(local_task) return local_task
def __date_from_evo_to_gtg(self, evo_date_timestamp): """ Converts an evolution date object into the format understood by GTG @param evo_date: an int, which represent time from epoch in UTC convention """ evo_datetime = datetime.datetime.fromtimestamp(evo_date_timestamp) # See self.__date_from_gtg_to_evo for an explanation evo_datetime = evo_datetime.replace(tzinfo=tzlocal()) gtg_datetime = evo_datetime.astimezone(tzutc()) # we strip timezone infos, as they're not used or expected in GTG gtg_datetime.replace(tzinfo=None) return Date(gtg_datetime.date())
def on_date_selected(self, calendar, kind): """ Callback when a day is selected in the calendars.""" date = self.calendar_to_datetime(calendar) if kind == GTGCalendar.DATE_KIND_START: self.task.set_start_date(Date(date)) self.start_entry.set_text(str(Date(date))) elif kind == GTGCalendar.DATE_KIND_DUE: self.task.set_due_date(Date(date)) self.due_entry.set_text(str(Date(date))) elif kind == GTGCalendar.DATE_KIND_CLOSED: self.task.set_closed_date(Date(date)) self.closed_entry.set_text(str(Date(date)))
def test_parses_today_as_today(self): today = date.today() self.assertEqual(Date(today), today)
def set_closed_date(self, fulldate): self.closed_date = Date(fulldate) self.sync()
def set_closed_date(self, fulldate): self.closed_date = Date(fulldate) # BUG: nervouse self._has_been_modified()
def test_prevent_regression(self): """ A day represented in GTG Date must be still the same """ aday = date.today() self.assertEqual(Date(aday), aday)