Event mechanism working perfectly and very simple and clean

main
Jonathan Grizou 12 years ago
parent ff195c0859
commit ed44a2c262

@ -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)

@ -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)

@ -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")

@ -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():

@ -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

Loading…
Cancel
Save