diff --git a/papers/commands/remove_cmd.py b/papers/commands/remove_cmd.py index b312c1d..9d3ac7d 100644 --- a/papers/commands/remove_cmd.py +++ b/papers/commands/remove_cmd.py @@ -3,6 +3,13 @@ from .. import color from .. import configs from .helpers import add_references_argument, parse_references +from ..events import Event + +class RemoveEvent(Event): + def __init__(self, config, ui, citekey): + self.config = config + self.ui = ui + self.citekey = citekey def parser(subparsers, config): parser = subparsers.add_parser('remove', help='removes a paper') @@ -19,12 +26,8 @@ def command(config, ui, references): sure = ui.input_yn(question=are_you_sure, default='n') if sure: for c in citekeys: - # Extend with plugin commands, think about how to create a smart registering system for plugins - plugs = configs.get_plugins(config) - for plugname in plugs: - module_name = 'papers.plugins.' + plugname + '.' + plugname + '_cmd' - plug = __import__(module_name, globals(), locals(), ['callback'], -1) - plug.callback(config, ui, 'remove', c) + rmevent = RemoveEvent(config, ui, c) + rmevent.send() rp.remove(c) diff --git a/papers/events.py b/papers/events.py new file mode 100644 index 0000000..da61858 --- /dev/null +++ b/papers/events.py @@ -0,0 +1,77 @@ +msg_list = {} + +def listen(EventClass): + def wrap(f): + if isinstance(EventClass, type) \ + and issubclass(EventClass, Event) \ + and EventClass != Event: + + if not EventClass.__name__ in msg_list: + msg_list[EventClass.__name__] = [] + msg_list[EventClass.__name__].append(f) + # next step allow us to call the function itself without Event raised + def wrapped_f(*args): + f(*args) + return wrapped_f + else: + raise IOError('{} is not an Event subclass'.format(EventClass)) + return wrap + + +class Event(object): + def __init__(self, string): + """This is an example of simple event that can be raised + Inherit from this class and redefine whatever you need, + except the send funtion + """ + self.string = string + + def send(self): + """ This function send the instance of the class, i.e. the event to be sent, + to all function that listen to it + """ + if self.__class__.__name__ in msg_list: + for f in msg_list[self.__class__.__name__]: + f(self) + +if __name__ == "__main__": + + class TestEvent(Event): + def print_one(self): + print 'one' + + @listen(TestEvent) + def Display(TestEventInstance): + print TestEventInstance.string + + @listen(TestEvent) + def Helloword(TestEventInstance): + print 'Helloword' + + @listen(TestEvent) + def PrintIt(TestEventInstance): + TestEventInstance.print_one() + + class AddEvent(Event): + def __init__(self): + pass + + def add(self, a, b): + return a + b + + @listen(AddEvent) + def DoIt(AddEventInstance): + print AddEventInstance.add(17, 25) + + # using the callback system + myevent = TestEvent('abcdefghijklmnopqrstuvwxyz') + myevent.send() # this one call three function + + addevent = AddEvent() + addevent.send() + + # but also work without the event raising system! + Display(myevent) + Helloword(myevent) + PrintIt(myevent) + DoIt(addevent) diff --git a/papers/papers b/papers/papers index 659bbfb..5058445 100755 --- a/papers/papers +++ b/papers/papers @@ -29,18 +29,10 @@ config = configs.read_config() ui = UI(config) # Extend with plugin commands -plugs = configs.get_plugins(config) -for plugname in plugs: - module_name = 'papers.plugs.' + plugname + '.' + plugname + '_cmd' - plug = __import__(module_name, globals(), locals(), - ['parser', 'command'], -1) - cmds.update(collections.OrderedDict([(plugname, plug)])) - -plugins.load_plugins(config, ui, plugs) +plugins.load_plugins(config, ui, configs.get_plugins(config)) for p in plugins.get_plugins().values(): cmds.update(collections.OrderedDict([(p.name, p)])) - -##### +# parser = argparse.ArgumentParser(description="research papers repository") subparsers = parser.add_subparsers(title="valid commands", dest="command") diff --git a/papers/plugins.py b/papers/plugins.py index 7626ddb..87883a3 100644 --- a/papers/plugins.py +++ b/papers/plugins.py @@ -22,8 +22,8 @@ class PapersPlugin(object): #two options: #- create specific cases in script papers/papers #- do not store self.config and self.ui and use them if needed when command is called - #this may end up a lot of function with config/ui in argument - #or just keep it this way... + #this may end up with a lot of function with config/ui in argument + #or just keep it that way... def parser(self, subparsers, config): """ Should retrun the parser with plugins specific command. This is a basic example @@ -54,7 +54,7 @@ def load_plugins(config, ui, names): except ImportError as exc: # Again, this is hacky: if exc.args[0].endswith(' ' + name): - ui.warning('** plugin %s not found' % name) + ui.warning('plugin {} not found'.format(name)) else: raise else: @@ -65,7 +65,7 @@ def load_plugins(config, ui, names): _instances[obj] = obj(config, ui) except: - ui.warning('** error loading plugin %s' % name) + ui.warning('error loading plugin {}'.format(name)) def get_plugins(): diff --git a/papers/plugs/texnote/texnote.py b/papers/plugs/texnote/texnote.py index 7ef9b0c..34b9f39 100644 --- a/papers/plugs/texnote/texnote.py +++ b/papers/plugs/texnote/texnote.py @@ -8,6 +8,9 @@ from ... import files from ...plugins import PapersPlugin from ...commands.helpers import add_references_argument, parse_reference +from ...events import listen +from ...commands.remove_cmd import RemoveEvent + TEXNOTE_SECTION = 'texnote' TEXNOTE_SAMPLE_FILE = os.path.join(os.path.dirname(__file__), 'note_sample.tex') TEXNOTE_DIR = 'texnote' @@ -27,19 +30,16 @@ class TexnotePlugin(PapersPlugin): open_texnote(config, ui, reference) -# temporary - - -def callback(config, ui, name, ref): - if name == 'remove': - rp = repo.Repository.from_directory(config) - paper = rp.get_paper(parse_reference(ui, rp, ref)) +@listen(RemoveEvent) +def remove(rmevent): + rp = repo.Repository.from_directory(rmevent.config) + paper = rp.get_paper(parse_reference(rmevent.ui, rp, rmevent.citekey)) - if 'texnote' in paper.metadata: - os.remove(paper.metadata['texnote']) - paper.metadata.pop('texnote') - metapath = rp.path_to_paper_file(paper.citekey, 'meta') - files.save_meta(paper.metadata, metapath) + if 'texnote' in paper.metadata: + os.remove(paper.metadata['texnote']) + paper.metadata.pop('texnote') + metapath = rp.path_to_paper_file(paper.citekey, 'meta') + files.save_meta(paper.metadata, metapath) def open_texnote(config, ui, ref): @@ -108,7 +108,7 @@ def autofill_texnote(texnote_path, bibentry): text = f.read() f.close() # modify with bib info - print bibentry + #print bibentry fields = bibentry.fields persons = bibentry.persons