diff --git a/mgmt/hms/.gitignore b/mgmt/hms/.gitignore new file mode 100644 index 0000000..4e72520 --- /dev/null +++ b/mgmt/hms/.gitignore @@ -0,0 +1,3 @@ +.*.swp +*.swp +*.pyc diff --git a/mgmt/hms/debug.py b/mgmt/hms/debug.py new file mode 100644 index 0000000..11c39d1 --- /dev/null +++ b/mgmt/hms/debug.py @@ -0,0 +1,9 @@ + +DEBUG = 0 + +if DEBUG: + def debug(s): + print "| "+s +else: + def debug(s): + pass diff --git a/mgmt/hms/generate.py b/mgmt/hms/generate.py new file mode 100644 index 0000000..fb45085 --- /dev/null +++ b/mgmt/hms/generate.py @@ -0,0 +1,35 @@ +#!/usr/bin/python + +""" +Support of generated content. +You mark some function with @generates('some_type'). It must return an instance of Generated class. +""" + +generated = dict() + +def generates(cls): + "Mark function that generates content of some class." + def decorator(func): + global generated + name = func.__name__ + if cls in generated: + generated[cls].append(func) + else: + generated[cls] = [func] + return func + return decorator + +def generate(cls): + "Generate all content of given class." + r = [] + for b in generated[cls]: + r.append(b()) + return r + +class Generated(object): + name = "" + description = "" + def show(self): + return "" + def settings(self): + return diff --git a/mgmt/hms/hooks.py b/mgmt/hms/hooks.py new file mode 100755 index 0000000..f991423 --- /dev/null +++ b/mgmt/hms/hooks.py @@ -0,0 +1,72 @@ +#!/usr/bin/python + +""" +Each `hook' is actually event. You mark some function with @hook decorator, then call that function when you need it. Other modules can intercept that event, marking function with @intercept('hook_name') decorator. When you call function `hook_name()', all functions, marked with @intercept('hook_name'), will be called. +""" + +from debug import * + +hooks = dict() + +def call_hooks(hook,*args): + "Call all functions, intercepting given hook." + global hooks + debug("Test <%s> in %s" % (hook,hooks)) + if hook in hooks: + debug("Calling hooks for %s" % hook) + r = args + for h in hooks[hook]: + prev = r + debug("Calling %s (%s)" % (h,r)) + r = h(*r) + if not r: + return prev + return r + else: + return args + +def hook(func): + "Mark given function as a hook." + global hooks + name = func.__name__ + def wrapper(*args): + r = call_hooks(name,*args) + if type(r) in [str,unicode]: + return func(r) + else: + return func(*r) + wrapper.__name__ = name + return wrapper + + +def intercept(hook): + "Intercept some hook." + def decorator(func): + global hooks + if hook in hooks: + hooks[hook].append(func) + else: + hooks[hook] = [func] + debug("Now hooks = %s" % hooks) + return func + return decorator + +if __name__ == "__main__": + + @hook + def one(x,y): + print "Op One called: (%s,%s)" % (x,y) + + @intercept('one') + def i1(x,y): + print "Intercepting one." + return (x,y+1) + + @intercept('one') + def i2(x,y): + print "Intercepting one: %s,%s" % (x,y) + return x+3,y + + + print one(2,3) + print hooks diff --git a/mgmt/hms/modules.py b/mgmt/hms/modules.py new file mode 100644 index 0000000..495a4c9 --- /dev/null +++ b/mgmt/hms/modules.py @@ -0,0 +1,53 @@ + +""" +This module imports all mods from modules/ directory. Each module must be a *.py file of form: + +def init(): + ... Here goes definitions. +""" + +import os +import os.path + +from hooks import * +from themes import * +from generate import * + +MODS_DIR = "modules" +modules = {} +exports = ['export', 'export_as', 'hook', 'intercept','themeable','theme', + 'generates', 'generate', 'Generated'] + +def export(func): + "Mark this function to export." + global exports + globals()[func.__name__] = func + exports.append(func.__name__) + return func + +def export_as(obj,name): + "Export some object" + global exports + globals()[name] = obj + exports.append(name) + print globals().keys() + +@hook +def module_load(name): + global modules + global exports + mod = modules[name] + for n in exports: + setattr(mod,n,globals()[n]) + modules[name].init() + +def init(): + for name in modules: + module_load(name) + +for dirpath, dirs, files in os.walk(MODS_DIR): + for file in files: + if file[-3:] == ".py": + name = os.path.join(dirpath,file[:-3]) + module = __import__(name) + modules[name] = module diff --git a/mgmt/hms/modules/blocks.py b/mgmt/hms/modules/blocks.py new file mode 100644 index 0000000..95732a6 --- /dev/null +++ b/mgmt/hms/modules/blocks.py @@ -0,0 +1,25 @@ + +def init(): + + print "Blocks module loaded." + + block = generates('block') + export_as(block,'block') + + @themeable + def block(blk): + return """<div class='block'> + <h3>%s</h3> + <div class='content'> + %s + </div> + </div>""" % (blk.title,blk.content) + + class Block(Generated): + name = "Block" + title = "<none>" + content = "<empty>" + def show(self): + return theme('block', self) + + export_as(Block,'Block') diff --git a/mgmt/hms/modules/node.py b/mgmt/hms/modules/node.py new file mode 100644 index 0000000..ebea2b0 --- /dev/null +++ b/mgmt/hms/modules/node.py @@ -0,0 +1,19 @@ + +def init(): + + class Node(object): + author="" + title = "" + content = "" + fields = {} + + @themeable + def node(nd): + return """<div class='node'> + <h2>%s</h2> + <div class='content'> + %s + </div> + </div>""" % (nd.title, nd.content) + + export_as(Node,"Node") diff --git a/mgmt/hms/modules/test1.py b/mgmt/hms/modules/test1.py new file mode 100644 index 0000000..dccef22 --- /dev/null +++ b/mgmt/hms/modules/test1.py @@ -0,0 +1,15 @@ + +def init(): + print "Module <Test> imported." + + @intercept('do_something') + def func(s): + print "Intercepted." + return s + + @hook + def my_hook(): + print "Some event." + + + my_hook() diff --git a/mgmt/hms/modules/test2.py b/mgmt/hms/modules/test2.py new file mode 100644 index 0000000..f5d3524 --- /dev/null +++ b/mgmt/hms/modules/test2.py @@ -0,0 +1,7 @@ + +def init(): + print "Test 2 loaded" + + @intercept('my_hook') + def on_hook(): + print "<myhook> intercepted." diff --git a/mgmt/hms/modules/testblock.py b/mgmt/hms/modules/testblock.py new file mode 100644 index 0000000..be49e4f --- /dev/null +++ b/mgmt/hms/modules/testblock.py @@ -0,0 +1,10 @@ + +def init(): + + @block + def testblk(): + b = Block() + b.name = "testblk" + b.title = "Test block" + b.content = "Content of test block." + return b diff --git a/mgmt/hms/test.py b/mgmt/hms/test.py new file mode 100755 index 0000000..8fbf658 --- /dev/null +++ b/mgmt/hms/test.py @@ -0,0 +1,31 @@ +#!/usr/bin/python + +import os.path + +import modules +from hooks import * +from themes import * +from generate import generate +modules.init() + +THEME = "default" + +@hook +def do_something(s): + print "Doing something with",s + + +@themeable +def page(path): + return "Content for "+path + +print "All modules loaded." + +th= __import__(os.path.join("themes",THEME,"theme")) +th.override = override +th.init() + +print theme('page','/') + +for b in generate('block'): + print b.show() diff --git a/mgmt/hms/th1.py b/mgmt/hms/th1.py new file mode 100755 index 0000000..095473b --- /dev/null +++ b/mgmt/hms/th1.py @@ -0,0 +1,10 @@ +#!/usr/bin/python + +from themes import theme,override + +@override +def Test(x,y): + return "Some vars: [%s, %s]" % (x,y) + + +print theme('Test',2,3) diff --git a/mgmt/hms/themes.py b/mgmt/hms/themes.py new file mode 100644 index 0000000..8b642c8 --- /dev/null +++ b/mgmt/hms/themes.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +themed = dict() + +def themeable(func): + global themed + name = func.__name__ + themed[name] = func + def wrapper(*args,**kwargs): + return (themed[name])(*args,**kwargs) + wrapper.__name__ = name + return wrapper + +def override(func): + global themed + themed[func.__name__] = func + return func + +def theme(name,*args,**kwargs): + global themed + f = themed[name] + return f(*args,**kwargs) + + +@themeable +def Test(x,y): + return "<%s, %s>" % (x,y) diff --git a/mgmt/hms/themes/default/theme.py b/mgmt/hms/themes/default/theme.py new file mode 100644 index 0000000..1a8e10b --- /dev/null +++ b/mgmt/hms/themes/default/theme.py @@ -0,0 +1,11 @@ + +def init(): + @override + def page(path): + return """<html> + <title>%s</title> + <body> + Some content. + </body> + </html>""" % path + diff --git a/mgmt/models.py b/mgmt/models.py index 76fde06..f09f103 100644 --- a/mgmt/models.py +++ b/mgmt/models.py @@ -5,6 +5,8 @@ class Object(models.Model): name = models.CharField(max_length=64) text = models.TextField() created = models.DateTimeField() + def __unicode__(self): + return self.name class Project(Object): repo = models.CharField(max_length=64) @@ -24,8 +26,6 @@ class Bug(Object): confirmed = models.ForeignKey(User,related_name='confirmed_bugs',null=True) responsible = models.ForeignKey(User,related_name='resp_bugs',null=True) status = models.IntegerField() - def __unicode__(self): - return self.name class Meta: ordering = ("-created",) class Admin: @@ -34,8 +34,6 @@ class Bug(Object): class Document(Object): project = models.ForeignKey(Project) author = models.ForeignKey(User) - def __unicode__(self): - return self.name class Meta: ordering = ("-created",) class Admin: