Add new modules. Add head module (hms.py).

portnov [2008-06-10 12:54:06]
Add new modules. Add head module (hms.py).
Filename
hms.py
modules.py
modules/blocks.py
modules/bug_chart.py
modules/last_comments.py
modules/login.py
modules/menu.py
diff --git a/hms.py b/hms.py
new file mode 100644
index 0000000..cc4569a
--- /dev/null
+++ b/hms.py
@@ -0,0 +1,6 @@
+
+import modules
+from hooks import *
+from themes import *
+from generate import *
+modules.init()
diff --git a/modules.py b/modules.py
index 422bc9d..a8ddac6 100644
--- a/modules.py
+++ b/modules.py
@@ -6,6 +6,7 @@ def init():
   ... Here goes definitions.
 """

+import sys
 import os
 import os.path

@@ -14,7 +15,7 @@ from themes import *
 from generate import *

 MODS_DIR = "modules"
-modules = {}
+modules = []
 exports = ['export', 'export_as', 'hook', 'intercept','themeable','theme',
            'generates', 'generate', 'Generated']

@@ -32,21 +33,28 @@ def export_as(obj,name):
   exports.append(name)

 @hook
-def module_load(name):
-  global modules
+def module_load(mod):
   global exports
-  mod = modules[name]
   for n in exports:
     setattr(mod,n,globals()[n])
-  modules[name].init()
+  mod.init()

 def init():
-  for name in modules:
-    module_load(name)
+  for w,mod in modules:
+    module_load(mod)

-for dirpath, dirs, files in os.walk(MODS_DIR):
+for dirpath, dirs, files in os.walk(os.path.join(os.path.dirname(__file__),MODS_DIR)):
   for file in files:
     if file[-3:] == ".py":
       name = os.path.join(dirpath,file[:-3])
-      module = __import__(name)
-      modules[name] = module
+      try:
+        sys.path.append(os.path.dirname(name))
+        module = __import__(os.path.basename(name),{},{},[''])
+        try:
+          weight = module.weight
+        except AttributeError:
+          weight = 0
+      except ImportError,e:
+        raise ImportError,"Could not import module '%s': %s" % (name,e)
+      modules.append((weight,module))
+modules.sort()
diff --git a/modules/blocks.py b/modules/blocks.py
index 95732a6..ea785c2 100644
--- a/modules/blocks.py
+++ b/modules/blocks.py
@@ -1,4 +1,6 @@
+#encoding: utf-8

+weight = -10
 def init():

   print "Blocks module loaded."
@@ -8,12 +10,12 @@ def init():

   @themeable
   def block(blk):
-    return """<div class='block'>
+    return u"""<div class='block block-%s'>
     <h3>%s</h3>
     <div class='content'>
     %s
     </div>
-    </div>""" % (blk.title,blk.content)
+    </div>""" % (blk.name,blk.title,blk.content)

   class Block(Generated):
     name = "Block"
diff --git a/modules/bug_chart.py b/modules/bug_chart.py
new file mode 100755
index 0000000..1867947
--- /dev/null
+++ b/modules/bug_chart.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+#encoding: utf-8
+
+if __name__ == '__main__':
+  export = lambda f: f
+
+def init():
+  import os.path
+  import math
+  import cairo
+
+  root = "/home/portnov/www/projects/"
+  labels = [u"Неподтвержденые",u"Подтвержденные",u"В работе",u"Исправлены",u"Неактуальны"]
+  colors = [(0.75,0.75,1),
+            (1,0.75,0.75),
+            (1,1,0.75),
+            (0.75,1,0.75),
+            (0.75,0.75,0.75)]
+#   labels = ["U","P","W","F","N/A"]
+  width,height = 200,300
+
+  def piechart(data,outfile):
+    surf = cairo.ImageSurface(cairo.FORMAT_ARGB32,width,height)
+    cx = cairo.Context(surf)
+    centerx,centery = width/2, width/2
+    radius = 0.9*min(width,height)/2
+    s = sum(data)
+    n = len(data)
+    current_angle = 0
+    cx.set_source_rgb(255,255,255)
+    cx.rectangle(0,0,width,height)
+    cx.fill()
+    i=0
+    cx.select_font_face("DejaVu Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
+    cx.set_font_size(12)
+
+    for d in data:
+      angle = float(d)*math.pi*2.0/float(s)
+      end_angle = current_angle + angle
+      cx.new_path()
+      cx.set_source_rgb(*colors[i])
+      cx.move_to(centerx,centery)
+      cx.arc(centerx,centery,radius,current_angle,end_angle)
+      cx.line_to(centerx,centery)
+      cx.close_path()
+      current_angle = end_angle
+      cx.fill()
+      cx.set_source_rgb(*colors[i])
+      y = height-20*n+20*i
+      cx.rectangle(15,y,15,15)
+      cx.fill()
+      cx.set_source_rgb(0,0,0)
+      cx.move_to(40,y+12)
+      cx.show_text(labels[i])
+      cx.stroke()
+      i += 1
+    surf.write_to_png(outfile)
+
+  def chart_path(data):
+    return "/media/charts/chart_" + "_".join(map(str,data)) + ".png"
+
+  @export
+  def bug_chart(data):
+    path = chart_path(data)
+    if not os.path.exists(root+path):
+      piechart(data,root+path)
+    return "<img src='%s' alt='Bugs chart'/>" % path
+
+  if __name__ == '__main__':
+    piechart([0,0,1,0,0],'chart.png')
+
+if __name__ == '__main__':
+  init()
+
diff --git a/modules/last_comments.py b/modules/last_comments.py
new file mode 100644
index 0000000..702286c
--- /dev/null
+++ b/modules/last_comments.py
@@ -0,0 +1,27 @@
+#encoding: utf-8
+
+def init():
+
+  from mgmt.models import Comment
+
+  @block
+  def last_comments():
+    def short_comment(comment):
+      def get_url(comment):
+        type = comment.object_type
+        id = comment.object_id
+        if type=='Project':
+          return "/projects/%s/#comment-%s" % (id,comment.id)
+        if type=='Bug':
+          return "/bugs/%s/#comment-%s" % (id,comment.id)
+        if type=='Document':
+          return "/docs/%d/#comment-%s" % (id,comment.id)
+      return "<li><a href='%s'>%s</a></li>" % (get_url(comment),comment.title)
+    b = Block()
+    b.name='last_comments'
+    b.title = u"Последние комментарии"
+    comments = Comment.objects.order_by('-created')[:10]
+    b.content = "<ul>\n" + "\n".join(map(short_comment,comments)) + "\n</ul>\n"
+    return b
+
+
diff --git a/modules/login.py b/modules/login.py
new file mode 100644
index 0000000..66d761f
--- /dev/null
+++ b/modules/login.py
@@ -0,0 +1,17 @@
+#encoding: utf-8
+
+def init():
+
+  @block
+  def login_block():
+    b = Block()
+    b.name = 'login'
+    b.title = u'Вход в систему'
+    b.content = u"""
+    <form action='/login/' method='post'>
+    <p><label for="username">Логин:</label><input type="text" name="username" value="" id="username"/></p>
+    <p><label for="password">Пароль:</label><input type="password" name="password" value="" id="password"/></p>
+    <input type="submit" value="login" />
+    <input type='hidden' name='next' value='/'/>
+    </form>"""
+    return b
diff --git a/modules/menu.py b/modules/menu.py
new file mode 100644
index 0000000..86b9a25
--- /dev/null
+++ b/modules/menu.py
@@ -0,0 +1,14 @@
+#encoding: utf-8
+
+def init():
+
+  @export
+  def menu(request):
+    m = []
+    m.append((u'Главная','/'))
+    if request.user.is_authenticated():
+      m.append((u'Выход','/logout/'))
+    else:
+      m.append((u'Вход','/login/'))
+    L = ["<a href='%s'>%s</a>" % (l,t) for t,l in m]
+    return L
ViewGit