root/trunk/plugins/Admin.py

Revision 155 (checked in by llimllib, 2 years ago)

File adding works, and general improvemnts to admin module

Line 
1 import cherrypy as cpy
2 import md5
3 import os
4 import FileCabinet
5 from utils import config, htmlescape, htmlunescape, run_callback
6
7 class Admin(object):
8     _cp_config = {"tools.basic_auth.on": True,
9         "tools.basic_auth.realm": "localhost",
10         "tools.basic_auth.users": {config("admin_user"):
11                                    md5.new(config("admin_pw")).hexdigest()},
12         "tools.expires.on": True}
13
14     def __init__(self, parent):
15         self.parent = parent
16
17     @cpy.expose
18     def index(self):
19         #TODO: what's the right redirect to give here?
20         raise cpy.InternalRedirect("/Admin/ls")
21
22     def navbar(self, ns):
23         """Run a callback so that any module can add an element to the Admin
24         navbar"""
25         ### this callback gives an admin module the ability to add a link to
26         ### the navigation bar of the Admin section. It should return a list of
27         ### (string, string) tuples where the first string is the relative link
28         ### to the function, and the second is the name to display on the menu
29         ns['modules'] = run_callback(self.parent.plugins, "cb_admin_navbar", )
30         return ('admin_head', ns)
31
32     def cb_admin_navbar(self):
33         return [('ls', 'Edit Stories'), ('add', 'Add Story')]
34
35     @cpy.expose
36     def add(self):
37         #XXX: Should I move story editing to a plugin?
38         ns = {'title': "Adding New Entry"}
39         return [self.navbar(ns), ('admin_storyadd', ns)]
40
41     @cpy.expose
42     def add_story(self, story_title="", story_body="", filename=""):
43         if story_title == "" or story_body == "" or filename == "":
44             raise cpy.InternalRedirect("ls")
45
46         filename = os.path.join(config('datadir'), filename)
47         if not filename.endswith('.txt'): filename += '.txt'
48        
49         if os.path.isfile(filename):
50             ns = {'title': 'File Already Exists', 'filename': filename}
51             return [self.navbar(ns), ('admin_story_already_exists', ns)]
52
53         try:
54             f = open(filename, 'w')
55             f.write(story_title + "\n")
56             f.write(htmlunescape(story_body))
57         except Exception, e:
58             cpy.log("unable to log: " + e.Message)
59         finally:
60             f.close()
61
62     @cpy.expose
63     def edit(self, filename):
64         try:
65             #XXX: are we sure that filename can't ref previous dirs? ../ didn't
66             #       work in my basic test, but how should we better sanitize
67             #       this?
68             fullname = os.path.join(config("datadir"), filename)
69             f = file(fullname)
70         except IOError:
71             cpy.log("Unable to open file %s for editing" % fullname)
72             return
73         title = "Editing file %s" % filename
74         story_title = f.readline()
75         body = htmlescape(f.read())
76
77         ns = locals()
78         del ns['self']
79
80         return [self.navbar(ns), ('admin_storyedit', ns)]
81
82     @cpy.expose
83     def update_story(self, story_title="", story_body="", filename=""):
84         if story_title == "" or story_body == "" or filename == "":
85             raise cpy.InternalRedirect("ls")
86
87         filename = os.path.join(config('datadir'), filename)
88         tmpfile = filename + ".bak"
89         try:
90             f = open(tmpfile, 'w')
91             f.write(story_title + "\n")
92             f.write(htmlunescape(story_body))
93         except Exception, e:
94             os.unlink(tmpfile)
95             cpy.log("unable to log: " + e.Message)
96         finally:
97             f.close()
98         os.rename(tmpfile, filename)
99
100         return [self.navbar({"title": "Successfully updated"}),
101                 ('admin_updated', {"filename": f})]
102
103     @cpy.expose
104     def ls(self, dir=""):
105         dirname = os.path.join(config('datadir'), dir)
106         l = [f for f in os.listdir(dirname) if f.endswith('.txt')]
107         title = "Listing dir %s" % dir
108
109         ns = locals()
110         del ns['self']
111
112         return [self.navbar(ns), ('admin_ls', ns)]
113
114     @cpy.expose
115     def default(self, *args, **kwargs):
116         try:
117             f = args[0]
118         except ValueError: pass
119
120         #cb_admin_call should return (("template1", {namespace}), ("template2", {ns}))
121         #if it handles function f
122         page = [self.navbar({'title': f})]
123         page.extend(run_callback(
124             self.parent.plugins, "cb_admin_call", f, args, kwargs))
125         return page
Note: See TracBrowser for help on using the browser.