Skip to content

Commit

Permalink
wxGTD v0.12.2
Browse files Browse the repository at this point in the history
  • Loading branch information
KarolBedkowski committed Aug 13, 2013
2 parents 22a6610 + 2ee2b10 commit 7ecac85
Show file tree
Hide file tree
Showing 17 changed files with 92 additions and 66 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
wxgtd 0.12.2 2013-08-13

* minor bug fixes

wxgtd 0.12.1 2013-07-16

* bug fixes
Expand Down
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
:Tags: gtd, tasks management

Desktop application for task management compatible with `DGT GTD`_.
Support synchronisation data via sync file by Dropbox.
Support synchronisation data via Dropbox (file or API).

.. _`DGT GTD`: http://www.dgtale.ch/

Expand Down
2 changes: 1 addition & 1 deletion setup.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SetCompressor /SOLID lzma

; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "wxGTD"
!define PRODUCT_VERSION "0.x.0"
!define PRODUCT_VERSION "0.x"
!define PRODUCT_PUBLISHER "Karol Bêdkowski"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\wxgtd.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
Expand Down
17 changes: 13 additions & 4 deletions wxgtd/gui/_base_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class BaseDialog:
def __init__(self, parent, dialog_name='dialog', resource='wxgtd.xrc',
icon=None, save_pos=True):
self._dialog_name = dialog_name
self._obj_key = None
self.obj_key = None
self._save_pos = save_pos
# setup
self._wnd = self._create_window(dialog_name, resource, parent)
Expand Down Expand Up @@ -74,7 +74,7 @@ def create(cls, key, *args, **kwargs):
wx.CallAfter(dlg.wnd.Raise)
else:
cls._windows[key] = dlg = cls(*args, **kwargs)
dlg._obj_key = key
dlg.obj_key = key
return dlg

def run(self, modal=False):
Expand Down Expand Up @@ -106,6 +106,15 @@ def __getitem__(self, key):
assert ctrl is not None, 'ctrl %s not found' % key
return ctrl

def __setitem__(self, _key, _val):
pass

def __delitem__(self, _key):
pass

def __len__(self):
return len(self._wnd.GetChildren()) if self.wnd else 0

def _create_window(self, dialog_name, resource, # pylint: disable=R0201
parent):
""" Load resources & create window """
Expand Down Expand Up @@ -171,8 +180,8 @@ def _on_close(self, _evt):
self._appconfig.set(self._dialog_name, 'position',
self._wnd.GetPositionTuple())
# remove from cache.
if self._obj_key and self._obj_key in self._windows:
del self._windows[self._obj_key]
if self.obj_key and self.obj_key in self._windows:
del self._windows[self.obj_key]
self._wnd.Destroy()

def _on_cancel(self, _evt):
Expand Down
9 changes: 9 additions & 0 deletions wxgtd/gui/_base_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ def __getitem__(self, key):
assert ctrl is not None, 'Control %r not found' % key
return ctrl

def __setitem__(self, _key, _val):
pass

def __delitem__(self, _key):
pass

def __len__(self):
return len(self.wnd.GetChildren()) if self.wnd else 0

def _setup_wnd(self, wnd):
if self._window_icon:
wnd.SetIcon(iconprovider.get_icon(self._window_icon))
Expand Down
26 changes: 11 additions & 15 deletions wxgtd/gui/_tasklistctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,30 +266,26 @@ def fill(self, tasks, active_only=False):

def _setup_columns(self):
info = ULC.UltimateListItem()
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT
info._format = 0
info._text = _("Prio")
info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT)
info.SetText(_("Prio"))
self.InsertColumnInfo(0, info)

info = ULC.UltimateListItem()
info._format = wx.LIST_FORMAT_LEFT
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT
info._image = []
info._text = _("Title")
info.SetAlign(ULC.ULC_FORMAT_LEFT)
info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT)
info.SetText(_("Title"))
self.InsertColumnInfo(1, info)

info = ULC.UltimateListItem()
info._format = wx.LIST_FORMAT_LEFT
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT
info._image = []
info._text = _("Due")
info.SetAlign(ULC.ULC_FORMAT_LEFT)
info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT)
info.SetText(_("Due"))
self.InsertColumnInfo(2, info)

info = ULC.UltimateListItem()
info._format = wx.LIST_FORMAT_LEFT
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT
info._image = []
info._text = _("Info")
info.SetAlign(ULC.ULC_FORMAT_LEFT)
info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT)
info.SetText(_("Info"))
self.InsertColumnInfo(3, info)

self.SetColumnWidth(0, 24)
Expand Down
8 changes: 5 additions & 3 deletions wxgtd/gui/frame_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ def _on_menu_file_save(self, _evt):

def _on_menu_file_sync(self, _evt):
self._synchronize(False)
Publisher().sendMessage('task.update')
Publisher().sendMessage('dict.update')

def _on_menu_sett_preferences(self, _evt):
if DlgPreferences(self.wnd).run(True):
Expand Down Expand Up @@ -711,6 +713,9 @@ def _autosync(self, on_load=True):
if not self._appconfig.get('files', 'last_sync_file'):
return
self._synchronize(on_load, autoclose=True)
if on_load:
Publisher().sendMessage('task.update')
Publisher().sendMessage('dict.update')

def _delete_selected_task(self, permanently=False):
tasks_uuid = list(self._items_list_ctrl.get_selected_items_uuid())
Expand Down Expand Up @@ -898,9 +903,6 @@ def _synchronize(self, on_load=True, autoclose=False):
dlg.update(100, _("Error: ") + str(err))
autoclose = False
dlg.mark_finished(2 if autoclose else -1)
if on_load:
Publisher().sendMessage('task.update')
Publisher().sendMessage('dict.update')


class _TasksPopupMenu:
Expand Down
10 changes: 5 additions & 5 deletions wxgtd/gui/frame_reminders.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ class FrameReminders(BaseFrame):

_xrc_resource = 'wxgtd.xrc'
_window_name = 'frame_reminders'
_instance = None
INSTANCE = None

def __init__(self, parent, session):
self._task_list_ctrl = None
BaseFrame.__init__(self, parent)
self._obj_key = 'dlg_reminders'
self.obj_key = 'dlg_reminders'
self._setup(session)
self._refresh()

Expand All @@ -61,9 +61,9 @@ def check(cls, parent_wnd, session):
continue
tasks_to_show.append(task)
if tasks_to_show:
window = cls._instance
window = cls.INSTANCE
if not window:
window = cls._instance = FrameReminders(parent_wnd, session)
window = cls.INSTANCE = FrameReminders(parent_wnd, session)
window.wnd.Show()
window.load_tasks(tasks_to_show)
wx.CallAfter(window.wnd.Raise)
Expand Down Expand Up @@ -106,7 +106,7 @@ def _refresh(self):
self._task_list_ctrl.fill(self._reminders)

def _on_close(self, event):
self.__class__._instance = None
self.__class__.INSTANCE = None
BaseFrame._on_close(self, event)

def _on_btn_close(self, _evt):
Expand Down
12 changes: 1 addition & 11 deletions wxgtd/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@
from contextlib import contextmanager


def two_elements_iter(seq, return_last=False):
prev = None
for item in seq:
if prev is not None:
yield prev, item
prev = item
if return_last:
yield prev, None


@contextmanager
def ignore_exceptions(*exceptions):
""" Ignored exceptions in wrapped code.
Expand All @@ -30,7 +20,7 @@ def ignore_exceptions(*exceptions):
Sample:
>>> with ignore_exceptions(OSError):
... os.unlink('/tmp/test')
... os.unlink('/tmp/test')
"""
try:
yield
Expand Down
14 changes: 10 additions & 4 deletions wxgtd/lib/appconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def get(self, section, key, default=None):
try:
return eval(self._config.get(section, key))
except: # catch all errors; pylint: disable=W0702
_LOG.exception('AppConfig.get(%s, %s, %r)' % (section, key, default))
_LOG.exception('AppConfig.get(%s, %s, %r)', section, key, default)
return default

def get_items(self, section):
Expand All @@ -191,7 +191,7 @@ def get_items(self, section):
result = list((key, eval(val)) for key, val in items)
return result
except: # catch all errors; pylint: disable=W0702
_LOG.exception('AppConfig.get(%s)' % section)
_LOG.exception('AppConfig.get(%s)', section)
return None

def get_secure(self, section, key, default=None):
Expand Down Expand Up @@ -268,8 +268,8 @@ def _get_config_path(self, app_name):
try:
os.makedirs(config_path)
except IOError:
_LOG.exception('Error creating config directory: %s'
% self.config_path)
_LOG.exception('Error creating config directory: %s',
self.config_path)
config_path = self.main_dir
return config_path

Expand Down Expand Up @@ -313,6 +313,12 @@ def __setitem__(self, key, value):
key = key.split('/')
self._config.set(key[0], key[1], value)

def __delitem__(self, _key):
pass

def __len__(self):
return 0

def get(self, key, default=None):
key = key.split('/')
return self._config.get(key[0], key[1], default)
Expand Down
4 changes: 2 additions & 2 deletions wxgtd/lib/locales.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def setup_locale(app_config):
""" setup locales and gettext """
locales_dir = app_config.locales_dir
package_name = 'wxgtd'
_LOG.info('run: locale dir: %s' % locales_dir)
_LOG.info('run: locale dir: %s', locales_dir)
try:
locale.bindtextdomain(package_name, locales_dir)
locale.bind_textdomain_codeset(package_name, "UTF-8")
Expand All @@ -41,4 +41,4 @@ def setup_locale(app_config):
gettext.textdomain(package_name)
gettext.bindtextdomain('wxstd', locales_dir)
gettext.bind_textdomain_codeset(package_name, "UTF-8")
_LOG.info('locale: %s' % str(locale.getlocale()))
_LOG.info('locale: %s', str(locale.getlocale()))
14 changes: 6 additions & 8 deletions wxgtd/lib/logging_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,14 @@

class ColorFormatter(logging.Formatter):
""" Formatter for logs that color messages according to level. """
COLORS = {'DEBUG': 34,
'INFO': 37,
'WARNING': 33,
'ERROR': 31,
'CRITICAL': 31}
FORMAT_SEQ = "\033[1;%dm%s\033[0m"
FORMAT_MAP = {level: ("\033[1;%dm%s\033[0m" % (color, level))
for level, color in
(('DEBUG', 34), ('INFO', 37), ('WARNING', 33), ('ERROR', 31),
('CRITICAL', 31))}

def format(self, record):
record.levelname = self.FORMAT_SEQ % (
self.COLORS.get(record.levelname, 37), record.levelname)
record.levelname = self.FORMAT_MAP.get(record.levelname,
record.levelname)
return logging.Formatter.format(self, record)


Expand Down
4 changes: 3 additions & 1 deletion wxgtd/logic/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ def update_task_alarm(task):
_LOG.debug('update_task_alarm: %r', task)
alarm_pattern = task.alarm_pattern
if not alarm_pattern:
if task.alarm == task.due_date:
task.alarm_pattern = 'due'
return
if alarm_pattern == 'due':
task.alarm = task.due_date
Expand Down Expand Up @@ -151,7 +153,7 @@ def update_task_hide(task):
'Quarterly': relativedelta(months=+3),
'Semiannually': relativedelta(months=+6),
'Yearly': relativedelta(years=+1)}
RE_REPEAT_XT = re.compile("^Every (\d+) (\w+)$", re.IGNORECASE)
RE_REPEAT_XT = re.compile(r"^Every (\d+) (\w+)$", re.IGNORECASE)
RE_REPEAT_EVERYW = re.compile("^Every ((Mon|Tue|Wed|Thu|Fri|Sat|Sun),? ?)+$",
re.IGNORECASE)
_WEEKDAYS = {'mon': 0,
Expand Down
4 changes: 2 additions & 2 deletions wxgtd/model/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def before_cursor_execute(_conn, _cursor, # pylint: disable=W0612
@sqlalchemy.event.listens_for(Engine, "after_cursor_execute")
def after_cursor_execute(_conn, _cursor, # pylint: disable=W0612
_stmt, _params, context, _executemany):
_LOG.debug("Query time: %.02fms" % (
(time.time() - context.app_query_start) * 1000))
_LOG.debug("Query time: %.02fms",
(time.time() - context.app_query_start) * 1000)

_LOG.info('Database create_all START')
objects.Base.metadata.create_all(engine)
Expand Down
11 changes: 6 additions & 5 deletions wxgtd/model/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,13 @@ def sort_objects_by_parent(objs):
return []
all_objs_count = len(objs)
# no parent
result = filter(lambda x: x["parent_id"] == 0, objs)
result = [x for x in objs if x["parent_id"] == 0]
result_uuids = set(obj["_id"] for obj in result)
objs = filter(lambda x: x["parent_id"] != 0, objs)
objs = [x for x in objs if x["parent_id"] != 0]
# rest
while objs:
objs_to_add = filter(lambda x: x["parent_id"] in result_uuids, objs)
objs = filter(lambda x: x["parent_id"] not in result_uuids, objs)
objs_to_add = [x for x in objs if x["parent_id"] in result_uuids]
objs = [x for x in objs if x["parent_id"] not in result_uuids]
result.extend(objs_to_add)
result_uuids.update(obj["_id"] for obj in objs_to_add)
assert len(result) == all_objs_count
Expand Down Expand Up @@ -442,6 +442,7 @@ def _load_tasks(data, session, notify_cb):
task["goal_uuid"] = None
task_obj = _create_or_update(session, objects.Task, task)
task_logic.update_task_hide(task_obj)
task_logic.update_task_alarm(task_obj)
if tasks:
del data["task"]
notify_cb(29, _("Loaded %d tasks") % len(tasks_cache))
Expand Down Expand Up @@ -470,7 +471,7 @@ def _load_alarms(data, session, tasks_cache, notify_cb):
for alarm in alarms:
task_uuid = _replace_ids(alarm, tasks_cache, "task_id")
if not task_uuid:
_LOG.error("load alarm error %r; %r; %r", alarm, task_uuid)
_LOG.error("load alarm error %r", alarm)
continue
_convert_timestamps(alarm, "alarm")
task = session.query( # pylint: disable=E1101
Expand Down
6 changes: 3 additions & 3 deletions wxgtd/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

SHORTNAME = 'wxgtd'
NAME = _("wxGTD")
VERSION = '0.12.0'
VERSION_INFO = (0, 12, 1, 'beta', 1)
RELEASE = '2013-07-16'
VERSION = '0.12.2'
VERSION_INFO = (0, 12, 2, 'beta', 1)
RELEASE = '2013-08-13'
DESCRIPTION = _('''wxGTD''')
DEVELOPERS = u'''Karol Będkowski'''
TRANSLATORS = u'''Karol Będkowski'''
Expand Down
Loading

0 comments on commit 7ecac85

Please sign in to comment.