42fc032b40c9e4431fff2649d73f3840f6352cbc
[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.path
23 import uuid
24
25 import cookbook
26 from cookbook import Cookbook
27 from cookbook.mom import MomParser
28 from cookbook.cookbook import test as test_cookbook
29
30 try:
31     import jinja2
32     import cherrypy
33     from cookbook.server import Server
34     from cookbook.server import test as test_server
35 except ImportError, e:
36     cherrypy = e
37     def test_server():
38         pass
39
40
41 if __name__ == '__main__':
42     import optparse
43     import sys
44
45     # HACK! to ensure we *always* get utf-8 output
46     p = optparse.OptionParser()
47     p.add_option('-t', '--test', dest='test', default=False,
48                  action='store_true', help='run internal tests and exit')
49     p.add_option('-m', '--mom', dest='mom', metavar='PATH',
50                  help="load Mom's cookbook")
51     p.add_option('-s', '--serve', dest='serve', default=False,
52                  action='store_true', help='serve cookbook')
53     p.add_option('-a', '--address', dest='address', default='127.0.0.1',
54                  metavar='ADDR',
55                  help='address that the server will bind to (%default)')
56     p.add_option('-p', '--port', dest='port', default='8080',
57                  metavar='PORT',
58                  help='port that the server will listen on (%default)')
59
60     options,arguments = p.parse_args()
61
62     if options.test == True:
63         test_cookbook()
64         test_server()
65         sys.exit(0)
66
67     if isinstance(cherrypy, ImportError):
68         raise cherrypy
69
70     sys.stderr.write('Loading cookbook\n')
71     if options.mom == None:
72         c = Cookbook()
73         c.load()
74     else:
75         p = MomParser()
76         c = p.parse(options.mom)
77
78     if options.serve == False:
79         sys.stderr.write('Saving cookbook\n')
80         c.save('new-recipe')
81     else:
82         #reload(sys)
83         #sys.setdefaultencoding('utf-8')
84         sys.stderr.write('Serving cookbook\n')
85         module_dir = os.path.dirname(os.path.abspath(cookbook.__file__))
86         static_dir = os.path.join(module_dir, 'static')
87         template_dir = os.path.join(module_dir, 'template')
88         config = os.path.join(module_dir, 'config')
89         s = Server(c, template_dir)
90         if cherrypy.__version__.startswith('3.'):
91             cherrypy.config.update({ # http://www.cherrypy.org/wiki/ConfigAPI
92                     'server.socket_host': options.address,
93                     'server.socket_port': int(options.port),
94                     'tools.decode.on': True,
95                     'tools.encode.on': True,
96                     'tools.encode.encoding': 'utf8',
97                     'tools.staticdir.root': static_dir,
98                     })
99             if cherrypy.__version__.startswith('3.2'):
100                 get_ha1 = cherrypy.lib.auth_digest.get_ha1_file_htdigest(
101                     '.htaccess')
102                 digest_auth = {
103                     'tools.auth_digest.on': True,
104                     'tools.auth_digest.realm': 'cookbook',
105                     'tools.auth_digest.get_ha1': get_ha1,
106                     'tools.auth_digest.key': str(uuid.uuid4()),
107                     }
108             else:
109                 passwds = {}
110                 with open('.htaccess', 'r') as f:
111                     for line in f:
112                         user,realm,ha1 = line.strip().split(':')
113                         passwds[user] = ha1  # use the ha1 as the password
114                 digest_auth = {
115                     'tools.digest_auth.on': True,
116                     'tools.digest_auth.realm': 'cookbook',
117                     'tools.digest_auth.users': passwds,
118                     }
119                 print passwds
120                 del(passwds)
121             app_config = {
122                 '/static': {
123                     'tools.staticdir.on': True,
124                     'tools.staticdir.dir': '',
125                     },
126                 '/edit': digest_auth,
127                 '/add_tag': digest_auth,
128                 '/remove_tag': digest_auth,
129                 }
130             cherrypy.quickstart(root=s, config=app_config)
131         elif cherrypy.__version__.startswith('2.'):
132             cherrypy.root = s
133             cherrypy.config.update({
134                     'server.environment': 'production',
135                     'server.socket_host': options.address,
136                     'server.socket_port': int(options.port),
137                     'decoding_filter.on': True,
138                     'encoding_filter.on': True,
139                     'encodinf_filter.encoding': 'utf8',
140                     'static_filter.on': True,
141                     'static_filter.dir': static_dir,
142                     })
143             import pprint
144             pprint.pprint(cherrypy.config.configs)
145             cherrypy.server.start()
146         s.cleanup()