Create the static directory if it is missing
[cookbook.git] / bin / cook.py
1 #!/usr/bin/python
2
3 # Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
4 #
5 # This file is part of Cookbook.
6 #
7 # Cookbook is free software: you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by the
9 # Free Software Foundation, either version 3 of the License, or (at your
10 # option) any later version.
11 #
12 # Cookbook is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Cookbook.  If not, see <http://www.gnu.org/licenses/>.
19
20 from __future__ import with_statement
21
22 import os
23 import os.path
24 import uuid
25
26 import cookbook
27 from cookbook import Cookbook
28 from cookbook.mom import MomParser
29 from cookbook.cookbook import test as test_cookbook
30
31 try:
32     import jinja2
33     import cherrypy
34     from cookbook.server import Server
35     from cookbook.server import test as test_server
36 except ImportError, e:
37     cherrypy = e
38     def test_server():
39         pass
40
41
42 if __name__ == '__main__':
43     import optparse
44     import sys
45
46     # HACK! to ensure we *always* get utf-8 output
47     p = optparse.OptionParser()
48     p.add_option('-t', '--test', dest='test', default=False,
49                  action='store_true', help='run internal tests and exit')
50     p.add_option('-m', '--mom', dest='mom', metavar='PATH',
51                  help="load Mom's cookbook")
52     p.add_option('-s', '--serve', dest='serve', default=False,
53                  action='store_true', help='serve cookbook')
54     p.add_option('-a', '--address', dest='address', default='127.0.0.1',
55                  metavar='ADDR',
56                  help='address that the server will bind to (%default)')
57     p.add_option('-p', '--port', dest='port', default='8080',
58                  metavar='PORT',
59                  help='port that the server will listen on (%default)')
60
61     options,arguments = p.parse_args()
62
63     if options.test == True:
64         test_cookbook()
65         test_server()
66         sys.exit(0)
67
68     if isinstance(cherrypy, ImportError):
69         raise cherrypy
70
71     sys.stderr.write('Loading cookbook\n')
72     if options.mom == None:
73         c = Cookbook()
74         c.load()
75     else:
76         p = MomParser()
77         c = p.parse(options.mom)
78
79     if options.serve == False:
80         sys.stderr.write('Saving cookbook\n')
81         c.save('new-recipe')
82     else:
83         #reload(sys)
84         #sys.setdefaultencoding('utf-8')
85         sys.stderr.write('Serving cookbook\n')
86         module_dir = os.path.dirname(os.path.abspath(cookbook.__file__))
87         static_dir = os.path.join(module_dir, 'static')
88         if not os.path.exists(static_dir):
89             os.mkdir(static_dir)
90         template_dir = os.path.join(module_dir, 'template')
91         config = os.path.join(module_dir, 'config')
92         s = Server(c, template_dir)
93         if cherrypy.__version__.startswith('3.'):
94             cherrypy.config.update({ # http://www.cherrypy.org/wiki/ConfigAPI
95                     'server.socket_host': options.address,
96                     'server.socket_port': int(options.port),
97                     'tools.decode.on': True,
98                     'tools.encode.on': True,
99                     'tools.encode.encoding': 'utf8',
100                     'tools.staticdir.root': static_dir,
101                     })
102             if cherrypy.__version__.startswith('3.2'):
103                 get_ha1 = cherrypy.lib.auth_digest.get_ha1_file_htdigest(
104                     '.htaccess')
105                 digest_auth = {
106                     'tools.auth_digest.on': True,
107                     'tools.auth_digest.realm': 'cookbook',
108                     'tools.auth_digest.get_ha1': get_ha1,
109                     'tools.auth_digest.key': str(uuid.uuid4()),
110                     }
111             else:
112                 passwds = {}
113                 with open('.htaccess', 'r') as f:
114                     for line in f:
115                         user,realm,ha1 = line.strip().split(':')
116                         passwds[user] = ha1  # use the ha1 as the password
117                 digest_auth = {
118                     'tools.digest_auth.on': True,
119                     'tools.digest_auth.realm': 'cookbook',
120                     'tools.digest_auth.users': passwds,
121                     }
122                 print passwds
123                 del(passwds)
124             app_config = {
125                 '/static': {
126                     'tools.staticdir.on': True,
127                     'tools.staticdir.dir': '',
128                     },
129                 '/edit': digest_auth,
130                 '/add_tag': digest_auth,
131                 '/remove_tag': digest_auth,
132                 }
133             cherrypy.quickstart(root=s, config=app_config)
134         elif cherrypy.__version__.startswith('2.'):
135             cherrypy.root = s
136             cherrypy.config.update({
137                     'server.environment': 'production',
138                     'server.socket_host': options.address,
139                     'server.socket_port': int(options.port),
140                     'decoding_filter.on': True,
141                     'encoding_filter.on': True,
142                     'encodinf_filter.encoding': 'utf8',
143                     'static_filter.on': True,
144                     'static_filter.dir': static_dir,
145                     })
146             import pprint
147             pprint.pprint(cherrypy.config.configs)
148             cherrypy.server.start()
149         s.cleanup()