Commit 4908b64d authored by Bram Schoenmakers's avatar Bram Schoenmakers

Split watchdog functionality to TodoFileWatched class

Also improve the logic to prevent updates for changes caused by the
current topydo instance. This was done to ignore the first file update
event after writing out the file, and trigger updates for all other
file updates that have to be external.
parent c13af1fc
...@@ -28,42 +28,8 @@ class TodoFile(object): ...@@ -28,42 +28,8 @@ class TodoFile(object):
to. to.
""" """
def __init__(self, p_path, p_on_update=None): def __init__(self, p_path):
self.path = os.path.abspath(p_path) self.path = os.path.abspath(p_path)
self.write_lock = False
if p_on_update:
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler, FileModifiedEvent, FileCreatedEvent
class EventHandler(FileSystemEventHandler):
"""
Event handler to catch modifications (or creations) of the
current todo.txt file.
"""
def __init__(self, p_file):
super().__init__()
self.file = p_file
def _handle(self, p_event):
right_type = isinstance(p_event, FileModifiedEvent) or isinstance(p_event, FileCreatedEvent)
if not self.file.write_lock and right_type and p_event.src_path == self.file.path:
p_on_update()
def on_created(self, p_event):
"""
Because vim deletes and creates a file on buffer save, also
catch a creation event.
"""
self._handle(p_event)
def on_modified(self, p_event):
self._handle(p_event)
observer = Observer()
observer.schedule(EventHandler(self), os.path.dirname(self.path))
observer.start()
def read(self): def read(self):
""" Reads the todo.txt file and returns a list of todo items. """ """ Reads the todo.txt file and returns a list of todo items. """
...@@ -85,10 +51,6 @@ class TodoFile(object): ...@@ -85,10 +51,6 @@ class TodoFile(object):
to the file. to the file.
""" """
# make sure not to reread the todo file because this instance is
# actually writing it
self.write_lock = True
todofile = codecs.open(self.path, 'w', encoding="utf-8") todofile = codecs.open(self.path, 'w', encoding="utf-8")
if p_todos is list: if p_todos is list:
...@@ -100,4 +62,3 @@ class TodoFile(object): ...@@ -100,4 +62,3 @@ class TodoFile(object):
todofile.write("\n") todofile.write("\n")
todofile.close() todofile.close()
self.write_lock = False
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2016 Bram Schoenmakers <bram@topydo.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
This module deals with todo.txt files while putting a watch on them for file
changes.
"""
import os.path
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler, FileModifiedEvent, FileCreatedEvent
from topydo.lib.TodoFile import TodoFile
class TodoFileWatched(TodoFile):
"""
This class represents a todo.txt file, which can be read from or written
to.
"""
def __init__(self, p_path, p_on_update):
super().__init__(p_path)
class EventHandler(FileSystemEventHandler):
"""
Event handler to catch modifications (or creations) of the
current todo.txt file.
"""
def __init__(self, p_file):
super().__init__()
self.file = p_file
def _handle(self, p_event):
right_type = isinstance(p_event, FileModifiedEvent) or isinstance(p_event, FileCreatedEvent)
should_trigger = right_type and p_event.src_path == self.file.path
if self.file.self_write and should_trigger:
# the file was written by topydo, unmark that so we can
# record external writes again.
self.file.self_write = False
elif should_trigger:
p_on_update()
def on_created(self, p_event):
"""
Because vim deletes and creates a file on buffer save, also
catch a creation event.
"""
self._handle(p_event)
def on_modified(self, p_event):
self._handle(p_event)
observer = Observer()
observer.schedule(EventHandler(self), os.path.dirname(self.path))
observer.start()
def write(self, p_todos):
# make sure not to reread the todo file because this instance is
# actually writing it
self.self_write = True
super().write(p_todos)
...@@ -30,7 +30,7 @@ from topydo.lib.Sorter import Sorter ...@@ -30,7 +30,7 @@ from topydo.lib.Sorter import Sorter
from topydo.lib.Filter import get_filter_list, RelevanceFilter, DependencyFilter from topydo.lib.Filter import get_filter_list, RelevanceFilter, DependencyFilter
from topydo.lib.Utils import get_terminal_size from topydo.lib.Utils import get_terminal_size
from topydo.lib.View import View from topydo.lib.View import View
from topydo.lib import TodoFile from topydo.lib.TodoFileWatched import TodoFileWatched
from topydo.lib import TodoList from topydo.lib import TodoList
from topydo.ui.CLIApplicationBase import CLIApplicationBase, error from topydo.ui.CLIApplicationBase import CLIApplicationBase, error
from topydo.ui.columns.CommandLineWidget import CommandLineWidget from topydo.ui.columns.CommandLineWidget import CommandLineWidget
...@@ -115,7 +115,7 @@ class UIApplication(CLIApplicationBase): ...@@ -115,7 +115,7 @@ class UIApplication(CLIApplicationBase):
self._redraw() self._redraw()
self.column_width = config().column_width() self.column_width = config().column_width()
self.todofile = TodoFile.TodoFile(config().todotxt(), callback) self.todofile = TodoFileWatched(config().todotxt(), callback)
self.todolist = TodoList.TodoList(self.todofile.read()) self.todolist = TodoList.TodoList(self.todofile.read())
self.marked_todos = [] self.marked_todos = []
......
...@@ -37,7 +37,7 @@ except ConfigError as config_error: ...@@ -37,7 +37,7 @@ except ConfigError as config_error:
sys.exit(1) sys.exit(1)
from topydo.Commands import get_subcommand from topydo.Commands import get_subcommand
from topydo.lib import TodoFile from topydo.lib.TodoFileWatched import TodoFileWatched
from topydo.lib import TodoList from topydo.lib import TodoList
...@@ -52,7 +52,7 @@ class PromptApplication(CLIApplicationBase): ...@@ -52,7 +52,7 @@ class PromptApplication(CLIApplicationBase):
self._process_flags() self._process_flags()
self.completer = None self.completer = None
self.todofile = TodoFile.TodoFile(config().todotxt(), self._load_file) self.todofile = TodoFileWatched(config().todotxt(), self._load_file)
def _load_file(self): def _load_file(self):
""" """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment