Event mechanism working perfectly and very simple and clean
This commit is contained in:
parent
ff195c0859
commit
ed44a2c262
@ -3,6 +3,13 @@ from .. import color
|
|||||||
from .. import configs
|
from .. import configs
|
||||||
from .helpers import add_references_argument, parse_references
|
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):
|
def parser(subparsers, config):
|
||||||
parser = subparsers.add_parser('remove', help='removes a paper')
|
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')
|
sure = ui.input_yn(question=are_you_sure, default='n')
|
||||||
if sure:
|
if sure:
|
||||||
for c in citekeys:
|
for c in citekeys:
|
||||||
# Extend with plugin commands, think about how to create a smart registering system for plugins
|
rmevent = RemoveEvent(config, ui, c)
|
||||||
plugs = configs.get_plugins(config)
|
rmevent.send()
|
||||||
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)
|
|
||||||
|
|
||||||
rp.remove(c)
|
rp.remove(c)
|
||||||
|
|
||||||
|
77
papers/events.py
Normal file
77
papers/events.py
Normal file
@ -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)
|
ui = UI(config)
|
||||||
|
|
||||||
# Extend with plugin commands
|
# Extend with plugin commands
|
||||||
plugs = configs.get_plugins(config)
|
plugins.load_plugins(config, ui, 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)
|
|
||||||
for p in plugins.get_plugins().values():
|
for p in plugins.get_plugins().values():
|
||||||
cmds.update(collections.OrderedDict([(p.name, p)]))
|
cmds.update(collections.OrderedDict([(p.name, p)]))
|
||||||
|
#
|
||||||
#####
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="research papers repository")
|
parser = argparse.ArgumentParser(description="research papers repository")
|
||||||
subparsers = parser.add_subparsers(title="valid commands", dest="command")
|
subparsers = parser.add_subparsers(title="valid commands", dest="command")
|
||||||
|
@ -22,8 +22,8 @@ class PapersPlugin(object):
|
|||||||
#two options:
|
#two options:
|
||||||
#- create specific cases in script papers/papers
|
#- create specific cases in script papers/papers
|
||||||
#- do not store self.config and self.ui and use them if needed when command is called
|
#- 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
|
#this may end up with a lot of function with config/ui in argument
|
||||||
#or just keep it this way...
|
#or just keep it that way...
|
||||||
def parser(self, subparsers, config):
|
def parser(self, subparsers, config):
|
||||||
""" Should retrun the parser with plugins specific command.
|
""" Should retrun the parser with plugins specific command.
|
||||||
This is a basic example
|
This is a basic example
|
||||||
@ -54,7 +54,7 @@ def load_plugins(config, ui, names):
|
|||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
# Again, this is hacky:
|
# Again, this is hacky:
|
||||||
if exc.args[0].endswith(' ' + name):
|
if exc.args[0].endswith(' ' + name):
|
||||||
ui.warning('** plugin %s not found' % name)
|
ui.warning('plugin {} not found'.format(name))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
@ -65,7 +65,7 @@ def load_plugins(config, ui, names):
|
|||||||
_instances[obj] = obj(config, ui)
|
_instances[obj] = obj(config, ui)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
ui.warning('** error loading plugin %s' % name)
|
ui.warning('error loading plugin {}'.format(name))
|
||||||
|
|
||||||
|
|
||||||
def get_plugins():
|
def get_plugins():
|
||||||
|
@ -8,6 +8,9 @@ from ... import files
|
|||||||
from ...plugins import PapersPlugin
|
from ...plugins import PapersPlugin
|
||||||
from ...commands.helpers import add_references_argument, parse_reference
|
from ...commands.helpers import add_references_argument, parse_reference
|
||||||
|
|
||||||
|
from ...events import listen
|
||||||
|
from ...commands.remove_cmd import RemoveEvent
|
||||||
|
|
||||||
TEXNOTE_SECTION = 'texnote'
|
TEXNOTE_SECTION = 'texnote'
|
||||||
TEXNOTE_SAMPLE_FILE = os.path.join(os.path.dirname(__file__), 'note_sample.tex')
|
TEXNOTE_SAMPLE_FILE = os.path.join(os.path.dirname(__file__), 'note_sample.tex')
|
||||||
TEXNOTE_DIR = 'texnote'
|
TEXNOTE_DIR = 'texnote'
|
||||||
@ -27,19 +30,16 @@ class TexnotePlugin(PapersPlugin):
|
|||||||
open_texnote(config, ui, reference)
|
open_texnote(config, ui, reference)
|
||||||
|
|
||||||
|
|
||||||
# temporary
|
@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:
|
||||||
def callback(config, ui, name, ref):
|
os.remove(paper.metadata['texnote'])
|
||||||
if name == 'remove':
|
paper.metadata.pop('texnote')
|
||||||
rp = repo.Repository.from_directory(config)
|
metapath = rp.path_to_paper_file(paper.citekey, 'meta')
|
||||||
paper = rp.get_paper(parse_reference(ui, rp, ref))
|
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):
|
def open_texnote(config, ui, ref):
|
||||||
@ -108,7 +108,7 @@ def autofill_texnote(texnote_path, bibentry):
|
|||||||
text = f.read()
|
text = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
# modify with bib info
|
# modify with bib info
|
||||||
print bibentry
|
#print bibentry
|
||||||
fields = bibentry.fields
|
fields = bibentry.fields
|
||||||
persons = bibentry.persons
|
persons = bibentry.persons
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user