Merge lp:~scott-armitage/pyng/uri-pattern into lp:pyng
- uri-pattern
- Merge into trunk
Proposed by
Scott Armitage
Status: | Merged |
---|---|
Approved by: | Scott Armitage |
Approved revision: | 17 |
Merged at revision: | not available |
Proposed branch: | lp:~scott-armitage/pyng/uri-pattern |
Merge into: | lp:pyng |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~scott-armitage/pyng/uri-pattern |
Related bugs: | |
Related blueprints: |
Exceptions
(Undefined)
Simple page templating engine
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Scott Armitage | Approve | ||
Review via email: mp+6787@code.launchpad.net |
Commit message
Added URI handling and basic exception definitions.
Description of the change
To post a comment you must log in.
Revision history for this message
Scott Armitage (scott-armitage) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'PyngPyng/__init__.py' (properties changed: +x to -x) | |||
2 | --- PyngPyng/__init__.py 2009-05-24 23:57:05 +0000 | |||
3 | +++ PyngPyng/__init__.py 2009-05-26 02:25:17 +0000 | |||
4 | @@ -16,6 +16,7 @@ | |||
5 | 16 | 16 | ||
6 | 17 | # Extension modules ----------------------------------------------------------- | 17 | # Extension modules ----------------------------------------------------------- |
7 | 18 | from PyngPyng.pages import Page, ErrorPage | 18 | from PyngPyng.pages import Page, ErrorPage |
8 | 19 | from PyngPyng import exceptions as exc | ||
9 | 19 | from PyngPyng import version | 20 | from PyngPyng import version |
10 | 20 | 21 | ||
11 | 21 | # Module function ------------------------------------------------------------- | 22 | # Module function ------------------------------------------------------------- |
12 | @@ -53,9 +54,9 @@ | |||
13 | 53 | # Run the requested page | 54 | # Run the requested page |
14 | 54 | try: | 55 | try: |
15 | 55 | page = Page(environ) | 56 | page = Page(environ) |
19 | 56 | page.parse_request() | 57 | page.do_it() |
20 | 57 | page.execute() | 58 | if not page.content: |
21 | 58 | page.composite() | 59 | raise exc.NoContentException('Expected page content to be generated. Perhaps the page compositor has not been implemented?') |
22 | 59 | start_response(page.status,page.headers) | 60 | start_response(page.status,page.headers) |
23 | 60 | return page.content | 61 | return page.content |
24 | 61 | except: | 62 | except: |
25 | 62 | 63 | ||
26 | === modified file 'PyngPyng/exceptions.py' | |||
27 | --- PyngPyng/exceptions.py 2009-05-25 03:11:31 +0000 | |||
28 | +++ PyngPyng/exceptions.py 2009-05-26 02:09:15 +0000 | |||
29 | @@ -14,6 +14,12 @@ | |||
30 | 14 | # Exception class ------------------------------------------------------------- | 14 | # Exception class ------------------------------------------------------------- |
31 | 15 | class Pyngception(Exception): | 15 | class Pyngception(Exception): |
32 | 16 | """An internal PyngPyng exception occured.""" | 16 | """An internal PyngPyng exception occured.""" |
33 | 17 | http_code = '500 Internal Server Error' | ||
34 | 18 | |||
35 | 19 | |||
36 | 20 | # Exception class ------------------------------------------------------------- | ||
37 | 21 | class NoContentException(Pyngception): | ||
38 | 22 | """The page content is empty or None.""" | ||
39 | 17 | pass | 23 | pass |
40 | 18 | 24 | ||
41 | 19 | 25 | ||
42 | 20 | 26 | ||
43 | === modified file 'PyngPyng/pages.py' | |||
44 | --- PyngPyng/pages.py 2009-05-25 03:11:31 +0000 | |||
45 | +++ PyngPyng/pages.py 2009-05-26 02:25:17 +0000 | |||
46 | @@ -12,22 +12,58 @@ | |||
47 | 12 | 12 | ||
48 | 13 | # Extension modules ----------------------------------------------------------- | 13 | # Extension modules ----------------------------------------------------------- |
49 | 14 | from PyngPyng import version | 14 | from PyngPyng import version |
50 | 15 | from PyngPyng import exceptions as exc | ||
51 | 16 | |||
52 | 17 | # Class factory --------------------------------------------------------------- | ||
53 | 18 | def Page(environ): | ||
54 | 19 | """ | ||
55 | 20 | Create a Page object (of appropriate subclass) based on the request URI. | ||
56 | 21 | |||
57 | 22 | Parameters | ||
58 | 23 | ---------- | ||
59 | 24 | environ : dict | ||
60 | 25 | The WSGI environment variable is a dictionary object containing CGI- | ||
61 | 26 | style environment variables. See PEP333 for specification. It also | ||
62 | 27 | contains the pre-parsed URI and ARGS parameters. | ||
63 | 28 | |||
64 | 29 | Returns | ||
65 | 30 | ------- | ||
66 | 31 | page : PageBase | ||
67 | 32 | The PageBase (or PageBase-subclass) object associated with the request. | ||
68 | 33 | |||
69 | 34 | """ | ||
70 | 35 | pagename = environ['URI'][0] | ||
71 | 36 | if pagename == '': # we are at the application root | ||
72 | 37 | return RootPage(environ) | ||
73 | 38 | elif pagename == 'rules': # we are at the rules static-ish page | ||
74 | 39 | return RulesPage(environ) | ||
75 | 40 | elif pagename == 'retired': # we are looking at retired players | ||
76 | 41 | return RetiredPage(environ) | ||
77 | 42 | elif pagename == '+game': # we are adding a game | ||
78 | 43 | return GameAction(environ) | ||
79 | 44 | elif pagename == '+user': # we are adding a user | ||
80 | 45 | return UserAction(environ) | ||
81 | 46 | elif pagename == '+retire': # we are retiring a user | ||
82 | 47 | return RetireAction(environ) | ||
83 | 48 | else: # we expect uri[0] to be a {username} | ||
84 | 49 | return FilterPage(environ) | ||
85 | 15 | 50 | ||
86 | 16 | 51 | ||
87 | 17 | # Module class ---------------------------------------------------------------- | 52 | # Module class ---------------------------------------------------------------- |
89 | 18 | class Page(object): | 53 | class PageBase(object): |
90 | 19 | 54 | ||
91 | 20 | """ | 55 | """ |
94 | 21 | A Page object is resonsible for processing content, applying themes, and | 56 | A PageBase object is resonsible for processing content, applying themes, |
95 | 22 | returning the XHTML to the user via HTTP. | 57 | and returning the XHTML to the user via HTTP. This is a base class that |
96 | 58 | should be subclassed for specific functionality. | ||
97 | 23 | 59 | ||
98 | 24 | """ | 60 | """ |
99 | 25 | 61 | ||
100 | 26 | # Class initializer ------------------------------------------------------- | 62 | # Class initializer ------------------------------------------------------- |
101 | 27 | def __init__(self,environ): | 63 | def __init__(self,environ): |
102 | 28 | """ | 64 | """ |
105 | 29 | Initialize the Page instance. This is a lean operation in that the page | 65 | Initialize the PageBase instance. This is a lean operation in that the |
106 | 30 | content is not generated until required. | 66 | page content is not generated until required. |
107 | 31 | 67 | ||
108 | 32 | Parameters | 68 | Parameters |
109 | 33 | ---------- | 69 | ---------- |
110 | @@ -44,13 +80,17 @@ | |||
111 | 44 | # Set status and headers (assume OK; if not, these will get changed) | 80 | # Set status and headers (assume OK; if not, these will get changed) |
112 | 45 | self.status = '200 OK' | 81 | self.status = '200 OK' |
113 | 46 | self.headers = [('Content-Type','text/html')] | 82 | self.headers = [('Content-Type','text/html')] |
115 | 47 | self.template = 'PyngPyng/templates/pyng.page' | 83 | self.template = 'PyngPyng/templates/pyng.tpl' |
116 | 48 | # Copy environment parameters | 84 | # Copy environment parameters |
117 | 49 | self.script_name = environ.get('SCRIPT_NAME','') | 85 | self.script_name = environ.get('SCRIPT_NAME','') |
118 | 50 | self.request_method = environ.get('REQUEST_METHOD',None) | 86 | self.request_method = environ.get('REQUEST_METHOD',None) |
121 | 51 | self.args = environ.get('ARGS',None) | 87 | self.args = environ['ARGS'] # If args or uri are not set, something is messed up |
122 | 52 | self.uri = environ.get('URI',None) | 88 | self.uri = environ['URI'] |
123 | 53 | # Set initial page attributes | 89 | # Set initial page attributes |
124 | 90 | self.template_parameters = { | ||
125 | 91 | 'uri' : self.uri | ||
126 | 92 | } | ||
127 | 93 | self.is_action = False | ||
128 | 54 | self.is_composited = False | 94 | self.is_composited = False |
129 | 55 | self.content = None | 95 | self.content = None |
130 | 56 | self.page = None | 96 | self.page = None |
131 | @@ -70,8 +110,11 @@ | |||
132 | 70 | None | 110 | None |
133 | 71 | 111 | ||
134 | 72 | """ | 112 | """ |
137 | 73 | pass | 113 | if self.request_method == 'POST' and not self.is_action: |
138 | 74 | 114 | raise exc.HTTPMethodNotAllowedError('POST methods are only allowed for ''action'' resources, indicated by a ''+''.') | |
139 | 115 | elif self.request_method != 'GET': | ||
140 | 116 | raise exc.HTTPMethodNotAllowedError('Only GET and POST methods are allowed at this time; POST methods are only allowed on ''action'' resources, indicated by a ''+''.') | ||
141 | 117 | |||
142 | 75 | # Class function ---------------------------------------------------------- | 118 | # Class function ---------------------------------------------------------- |
143 | 76 | def execute(self): | 119 | def execute(self): |
144 | 77 | """ | 120 | """ |
145 | @@ -106,23 +149,66 @@ | |||
146 | 106 | None | 149 | None |
147 | 107 | 150 | ||
148 | 108 | """ | 151 | """ |
159 | 109 | self.page = '\n'.join([ | 152 | pass |
160 | 110 | 'Hello, world!', | 153 | |
161 | 111 | 'How are you today?', | 154 | # Class function ---------------------------------------------------------- |
162 | 112 | 'I am fine, thank you!' | 155 | def do_it(self): |
163 | 113 | ]) | 156 | self.parse_request() |
164 | 114 | template_parameters = { | 157 | self.execute() |
165 | 115 | 'title' : 'PyngPyng games ladder', | 158 | self.composite() |
166 | 116 | 'page' : self.page, | 159 | |
167 | 117 | 'uri' : self.uri | 160 | |
168 | 118 | } | 161 | # Module class ---------------------------------------------------------------- |
169 | 162 | class ActionBase(PageBase): | ||
170 | 163 | def __init__(self,environ): | ||
171 | 164 | PageBase.__init__(self,environ) | ||
172 | 165 | self.is_action = self.request_method == 'POST' | ||
173 | 166 | |||
174 | 167 | |||
175 | 168 | # Module class ---------------------------------------------------------------- | ||
176 | 169 | class RootPage(PageBase): | ||
177 | 170 | pass | ||
178 | 171 | |||
179 | 172 | |||
180 | 173 | # Module class ---------------------------------------------------------------- | ||
181 | 174 | class RulesPage(PageBase): | ||
182 | 175 | def composite(self): | ||
183 | 176 | self.template_parameters['title'] = 'PyngPyng games ladder' | ||
184 | 177 | with open('PyngPyng/templates/rules.page','r') as rules: | ||
185 | 178 | self.page = rules.read() | ||
186 | 119 | with open(self.template,'r') as template: | 179 | with open(self.template,'r') as template: |
188 | 120 | self.content = template.read() % template_parameters | 180 | self.template_parameters['page'] = self.page |
189 | 181 | self.content = template.read() % self.template_parameters | ||
190 | 121 | self.is_composited = True | 182 | self.is_composited = True |
191 | 122 | 183 | ||
192 | 123 | 184 | ||
193 | 124 | # Module class ---------------------------------------------------------------- | 185 | # Module class ---------------------------------------------------------------- |
195 | 125 | class ErrorPage(Page): | 186 | class RetiredPage(PageBase): |
196 | 187 | pass | ||
197 | 188 | |||
198 | 189 | |||
199 | 190 | # Module class ---------------------------------------------------------------- | ||
200 | 191 | class GameAction(ActionBase): | ||
201 | 192 | pass | ||
202 | 193 | |||
203 | 194 | |||
204 | 195 | # Module class ---------------------------------------------------------------- | ||
205 | 196 | class UserAction(ActionBase): | ||
206 | 197 | pass | ||
207 | 198 | |||
208 | 199 | |||
209 | 200 | # Module class ---------------------------------------------------------------- | ||
210 | 201 | class RetireAction(ActionBase): | ||
211 | 202 | pass | ||
212 | 203 | |||
213 | 204 | |||
214 | 205 | # Module class ---------------------------------------------------------------- | ||
215 | 206 | class FilterPage(PageBase): | ||
216 | 207 | pass | ||
217 | 208 | |||
218 | 209 | |||
219 | 210 | # Module class ---------------------------------------------------------------- | ||
220 | 211 | class ErrorPage(PageBase): | ||
221 | 126 | 212 | ||
222 | 127 | """ | 213 | """ |
223 | 128 | An ErrorPage object is responsible for reporting application errors to the | 214 | An ErrorPage object is responsible for reporting application errors to the |
224 | @@ -133,14 +219,26 @@ | |||
225 | 133 | # Class function ---------------------------------------------------------- | 219 | # Class function ---------------------------------------------------------- |
226 | 134 | def __init__(self,environ,exc_info): | 220 | def __init__(self,environ,exc_info): |
227 | 135 | """ | 221 | """ |
229 | 136 | Initialize the ErrorPage instance. | 222 | Initialize the ErrorPage instance. This is generates the output |
230 | 223 | immediately. | ||
231 | 224 | |||
232 | 225 | Parameters | ||
233 | 226 | ---------- | ||
234 | 227 | environ : dict | ||
235 | 228 | The WSGI environment variable is a dictionary object containing CGI- | ||
236 | 229 | style environment variables. See PEP333 for specification. It also | ||
237 | 230 | contains the pre-parsed URI and ARGS parameters. | ||
238 | 231 | |||
239 | 232 | Returns | ||
240 | 233 | ------- | ||
241 | 234 | None | ||
242 | 137 | 235 | ||
243 | 138 | """ | 236 | """ |
244 | 139 | import traceback | 237 | import traceback |
246 | 140 | Page.__init__(self,environ) | 238 | PageBase.__init__(self,environ) |
247 | 141 | # Copy exception information | 239 | # Copy exception information |
248 | 142 | self.etype, self.evalue, self.etrace = exc_info | 240 | self.etype, self.evalue, self.etrace = exc_info |
250 | 143 | self.template = 'PyngPyng/templates/error.page' | 241 | self.template = 'PyngPyng/templates/error.tpl' |
251 | 144 | # Set default error status and headers (can be changed later to | 242 | # Set default error status and headers (can be changed later to |
252 | 145 | # customize for particular error conditions) | 243 | # customize for particular error conditions) |
253 | 146 | try: | 244 | try: |
254 | 147 | 245 | ||
255 | === removed file 'PyngPyng/templates/error.page' | |||
256 | --- PyngPyng/templates/error.page 2009-05-24 19:57:14 +0000 | |||
257 | +++ PyngPyng/templates/error.page 1970-01-01 00:00:00 +0000 | |||
258 | @@ -1,34 +0,0 @@ | |||
259 | 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | ||
260 | 2 | |||
261 | 3 | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
262 | 4 | <head profile="http://gmpg.org/xfn/11"> | ||
263 | 5 | <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" /> | ||
264 | 6 | <meta name="robots" content="none" /> | ||
265 | 7 | <title>%(title)s</title> | ||
266 | 8 | <style type="text/css"> | ||
267 | 9 | body { font-family:Verdana; font-size:10pt; } | ||
268 | 10 | h1 { font-weight:normal; font-size:18pt; color:red; } | ||
269 | 11 | h2 { font-weight:normal; font-style:italic; font-size:14pt; color:maroon; } | ||
270 | 12 | div#trace { background-color:#FFFFCC; margin-top:-0.75em; } | ||
271 | 13 | div#version { color:gray; } | ||
272 | 14 | </style> | ||
273 | 15 | </head> | ||
274 | 16 | |||
275 | 17 | <body> | ||
276 | 18 | <h1>Server Error at '%(request_uri)s' in %(app_name)s.</h1> | ||
277 | 19 | <hr width="100%%" size=1 color="silver" /> | ||
278 | 20 | <h2>%(exc_type)s » %(exc_details)s</h2> | ||
279 | 21 | |||
280 | 22 | <b>Description:</b> %(exc_description)s<br/><br/> | ||
281 | 23 | <b>Exception Details:</b> %(exc_type)s: %(exc_details)s<br/><br/> | ||
282 | 24 | |||
283 | 25 | <b>Stack Trace:</b> | ||
284 | 26 | <div id="trace"> | ||
285 | 27 | <code><pre>%(exc_trace)s</code></pre> | ||
286 | 28 | </div> | ||
287 | 29 | <hr width="100%%" size=1 color="silver" /> | ||
288 | 30 | <div id="version"> | ||
289 | 31 | <b>Version Information:</b> %(version)s | ||
290 | 32 | </div> | ||
291 | 33 | </body> | ||
292 | 34 | </html> | ||
293 | 35 | 0 | ||
294 | === added file 'PyngPyng/templates/error.tpl' | |||
295 | --- PyngPyng/templates/error.tpl 1970-01-01 00:00:00 +0000 | |||
296 | +++ PyngPyng/templates/error.tpl 2009-05-25 18:49:00 +0000 | |||
297 | @@ -0,0 +1,34 @@ | |||
298 | 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | ||
299 | 2 | |||
300 | 3 | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
301 | 4 | <head profile="http://gmpg.org/xfn/11"> | ||
302 | 5 | <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" /> | ||
303 | 6 | <meta name="robots" content="none" /> | ||
304 | 7 | <title>%(title)s</title> | ||
305 | 8 | <style type="text/css"> | ||
306 | 9 | body { font-family:Verdana; font-size:10pt; } | ||
307 | 10 | h1 { font-weight:normal; font-size:18pt; color:red; } | ||
308 | 11 | h2 { font-weight:normal; font-style:italic; font-size:14pt; color:maroon; } | ||
309 | 12 | div#trace { background-color:#FFFFCC; margin-top:-0.75em; } | ||
310 | 13 | div#version { color:gray; } | ||
311 | 14 | </style> | ||
312 | 15 | </head> | ||
313 | 16 | |||
314 | 17 | <body> | ||
315 | 18 | <h1>Server Error at '%(request_uri)s' in %(app_name)s.</h1> | ||
316 | 19 | <hr width="100%%" size=1 color="silver" /> | ||
317 | 20 | <h2>%(exc_type)s » %(exc_details)s</h2> | ||
318 | 21 | |||
319 | 22 | <b>Description:</b> %(exc_description)s<br/><br/> | ||
320 | 23 | <b>Exception Details:</b> %(exc_type)s: %(exc_details)s<br/><br/> | ||
321 | 24 | |||
322 | 25 | <b>Stack Trace:</b> | ||
323 | 26 | <div id="trace"> | ||
324 | 27 | <code><pre>%(exc_trace)s</code></pre> | ||
325 | 28 | </div> | ||
326 | 29 | <hr width="100%%" size=1 color="silver" /> | ||
327 | 30 | <div id="version"> | ||
328 | 31 | <b>Version Information:</b> %(version)s | ||
329 | 32 | </div> | ||
330 | 33 | </body> | ||
331 | 34 | </html> | ||
332 | 0 | 35 | ||
333 | === removed file 'PyngPyng/templates/pyng.page' | |||
334 | --- PyngPyng/templates/pyng.page 2009-05-25 03:11:31 +0000 | |||
335 | +++ PyngPyng/templates/pyng.page 1970-01-01 00:00:00 +0000 | |||
336 | @@ -1,24 +0,0 @@ | |||
337 | 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | ||
338 | 2 | |||
339 | 3 | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
340 | 4 | <head profile="http://gmpg.org/xfn/11"> | ||
341 | 5 | <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" /> | ||
342 | 6 | <meta name="distribution" content="global" /> | ||
343 | 7 | <meta name="robots" content="index,follow" /> | ||
344 | 8 | <meta name="language" content="en, sv" /> | ||
345 | 9 | <title>%(title)s</title> | ||
346 | 10 | <!--<link rel="stylesheet" type="text/css" charset="utf-8" media="all" href="http://localhost:8080/static/default.css" />--> | ||
347 | 11 | </head> | ||
348 | 12 | |||
349 | 13 | <body> | ||
350 | 14 | <div id="header"> | ||
351 | 15 | %(uri)s | ||
352 | 16 | </div> | ||
353 | 17 | <div id="page"> | ||
354 | 18 | %(page)s | ||
355 | 19 | </div> | ||
356 | 20 | <div id="footer"> | ||
357 | 21 | <div id="xhtml">Valid <a href="http://validator.w3.org/check/referer">XHTML</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a></div> | ||
358 | 22 | </div> | ||
359 | 23 | </body> | ||
360 | 24 | </html> | ||
361 | 25 | 0 | ||
362 | === added file 'PyngPyng/templates/pyng.tpl' | |||
363 | --- PyngPyng/templates/pyng.tpl 1970-01-01 00:00:00 +0000 | |||
364 | +++ PyngPyng/templates/pyng.tpl 2009-05-25 18:49:00 +0000 | |||
365 | @@ -0,0 +1,24 @@ | |||
366 | 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | ||
367 | 2 | |||
368 | 3 | <html xmlns="http://www.w3.org/1999/xhtml"> | ||
369 | 4 | <head profile="http://gmpg.org/xfn/11"> | ||
370 | 5 | <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" /> | ||
371 | 6 | <meta name="distribution" content="global" /> | ||
372 | 7 | <meta name="robots" content="index,follow" /> | ||
373 | 8 | <meta name="language" content="en, sv" /> | ||
374 | 9 | <title>%(title)s</title> | ||
375 | 10 | <!--<link rel="stylesheet" type="text/css" charset="utf-8" media="all" href="http://localhost:8080/static/default.css" />--> | ||
376 | 11 | </head> | ||
377 | 12 | |||
378 | 13 | <body> | ||
379 | 14 | <div id="header"> | ||
380 | 15 | %(uri)s | ||
381 | 16 | </div> | ||
382 | 17 | <div id="page"> | ||
383 | 18 | %(page)s | ||
384 | 19 | </div> | ||
385 | 20 | <div id="footer"> | ||
386 | 21 | <div id="xhtml">Valid <a href="http://validator.w3.org/check/referer">XHTML</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a></div> | ||
387 | 22 | </div> | ||
388 | 23 | </body> | ||
389 | 24 | </html> | ||
390 | 0 | 25 | ||
391 | === added file 'PyngPyng/templates/rules.page' | |||
392 | --- PyngPyng/templates/rules.page 1970-01-01 00:00:00 +0000 | |||
393 | +++ PyngPyng/templates/rules.page 2009-05-25 18:49:00 +0000 | |||
394 | @@ -0,0 +1,13 @@ | |||
395 | 1 | <ol id="rules"> | ||
396 | 2 | <li>All matches are to be best of three games.</li> | ||
397 | 3 | <li>All games are to be played to 21 points.</li> | ||
398 | 4 | <li>A game weighting is to be decided on before the game. It must be an integer from 1 to 10 (inclusive).</li> | ||
399 | 5 | <li>The higher the weight of the game the more points the winners can win (and the losers can lose).</li> | ||
400 | 6 | <li>If no game weight is chosen, the default game weight is 4.</li> | ||
401 | 7 | <li>Both singles and doubles games count towards the SFL Ping Pong ladder.</li> | ||
402 | 8 | <li>We salute those SFL Ping Pongers that have come before us.</li> | ||
403 | 9 | <li>By default assume that Grant is cheating and take appropriate action.</li> | ||
404 | 10 | <li>Let Mark win sometimes, his score is pathetic.</li> | ||
405 | 11 | <li>Honour Chris for creating this magical software.</li> | ||
406 | 12 | <li>If Guy is going to smash, for safety's sake get as close to the table as possible, because the ball is not going anywhere near it.</li> | ||
407 | 13 | </ol> | ||
408 | 0 | 14 | ||
409 | === modified file 'PyngPyng/version.py' (properties changed: -x to +x) | |||
410 | --- PyngPyng/version.py 2009-05-24 23:57:05 +0000 | |||
411 | +++ PyngPyng/version.py 2009-05-25 12:12:54 +0000 | |||
412 | @@ -10,7 +10,7 @@ | |||
413 | 10 | # Version information --------------------------------------------------------- | 10 | # Version information --------------------------------------------------------- |
414 | 11 | project = 'PyngPyng' | 11 | project = 'PyngPyng' |
415 | 12 | release = '0' | 12 | release = '0' |
417 | 13 | revision = 'lp:pyng (trunk)' | 13 | revision = 'lp:~scott-armitage/pyng/uri-pattern' |
418 | 14 | agent = ' '.join((project,release,revision)) | 14 | agent = ' '.join((project,release,revision)) |
419 | 15 | 15 | ||
420 | 16 | # Script body ----------------------------------------------------------------- | 16 | # Script body ----------------------------------------------------------------- |