root/trac/hacks/marketplugin/0.9/tracmarket/web_ui.py

Revision 117 (checked in by stevegt, 6 years ago)

checkpoint after mss tutorial, before moving order validity checks until after order entry into db

Line 
1
2 import random
3 import re
4 import sys
5 import urllib
6
7 from trac.core import *
8 from trac.web.api import IRequestPostProcessor
9 from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet
10 from trac.web.main import IRequestHandler
11 from trac.wiki.model import WikiPage
12 from trac.wiki.api import IWikiWorkflowController
13 from trac.util import escape, format_datetime, pretty_timedelta, Markup
14 from trac.wiki.formatter import wiki_to_html, wiki_to_oneliner
15
16 from api import *
17 from mq import *
18
19 class Market(Component):
20     implements(INavigationContributor, ITemplateProvider,
21             IRequestHandler, IRequestPostProcessor)
22
23     controllers = ExtensionPoint(IMarketController)
24
25     # INavigationContributor methods
26     def get_active_navigation_item(self, req):
27         return 'market'
28                
29     def get_navigation_items(self, req):
30         yield 'mainnav', 'market', Markup('<a href="%s">Market</a>' \
31                                   % self.env.href.market())
32
33     # ITemplateProvider methods
34     def get_templates_dirs(self):
35         """
36         Return the absolute path of the directory containing the provided
37         ClearSilver templates.
38         """
39         from pkg_resources import resource_filename
40         return [resource_filename(__name__, 'templates')]
41
42     def get_htdocs_dirs(self):
43         """
44         Return a list of directories with static resources (such as style
45         sheets, images, etc.)
46
47         Each item in the list must be a `(prefix, abspath)` tuple. The
48         `prefix` part defines the path in the URL that requests to these
49         resources are prefixed with.
50         
51         The `abspath` is the absolute path to the directory containing the
52         resources on the local file system.
53         """
54         from pkg_resources import resource_filename
55         return [('tracmarket', resource_filename(__name__, 'htdocs'))]
56
57     # IRequestHandler methods
58     def match_request(self, req):
59         return re.match('/market(/|$)', req.path_info)
60    
61     def process_request(self, req):
62         action = req.args.get('action')
63
64         # req.args['hdfdump'] = 1
65
66         add_stylesheet(req, 'common/css/trac.css')
67         # add_stylesheet(req, 'common/css/wiki.css')
68         add_stylesheet(req, 'tracmarket/css/market.css')
69         # add_stylesheet(req, 'tracmarket/css/luna/luna.css')
70         template = 'market.cs'
71         mime_type = 'text/html'
72
73         # construct cmd
74         cmds = []
75         if action == 'order':
76             symbol = req.args.get('symbol')
77             side = req.args.get('side')
78             size = req.args.get('size')
79             price = req.args.get('price')
80             # comment = req.args.get('comment')
81             cmd = "%s %s %s %s" % (symbol, side, size, price)
82             cmds.append(cmd)
83             cmds.append(symbol)
84         elif req.args.get('commands'):
85             script = req.args.get('commands')
86             script = urllib.unquote(script)
87             for cmd in script.split('\n'):
88                 cmd = cmd.strip()
89                 if not cmd:
90                     continue
91                 if cmd.startswith('#'):
92                     continue
93                 cmds.append(cmd)
94         else:
95             m = re.match('/market/(.*)', req.path_info)
96             if m and m.group(1):
97                 cmd = m.group(1)
98                 # reformat cmd from "wiki.FooPage.3?b+50+.23+TMP"
99                 #                to "wiki.FooPage.3 b 50 .23 TMP"
100                 parts = cmd.split('?', 2)
101                 symbol = parts[0]
102                 if len(parts) > 1:
103                     args = parts[1]
104                     args = urllib.unquote_plus(args)
105                     cmd = "%s %s" % (symbol, args)
106                 else:
107                     cmd = symbol
108                 cmds.append(cmd)
109         if not cmds:
110             cmds = ['portfolio', 'traders show_worth']
111        
112         # create bus
113         ctl = list(self.controllers)[0]
114         bus = ctl.open(req=req)
115
116         # set up initial subscriptions
117         bus.subscribe('debug', reader=self.debug)
118         bus.subscribe('res.', reader=self.build_response)
119
120         # send cmds
121         self.env.log.debug("commands " + '\n'.join(cmds))
122         try:
123             for cmd in cmds:
124                 self.env.log.debug("XA")
125                 msg = Msg(cmd)
126                 bus.send('market.cmd', msg)
127                 self.env.log.debug("XB")
128             msg = Msg('end')
129         except InsufficientFunds, e:
130             self.env.log.debug("XC")
131             ctl.rollback(bus)
132             bus.ctx.res.error(str(e))
133         except:
134             self.env.log.debug("XD")
135             ctl.rollback(bus)
136             raise
137         else:
138             self.env.log.debug("XE")
139             ctl.commit(bus)
140             self.env.log.debug("XF")
141
142         # XXX we assume the above send() calls are always blocking
143         if req.args.get('resdump'):
144             req.hdf['market.resdump'] = bus.ctx.res.dump()
145         self.env.log.debug("G")
146         return template,mime_type
147
148     def build_response(self, bus, group, msg):
149         self.env.log.debug("H")
150         req = bus.ctx.req
151         group = re.sub('^res\.', '', msg.group, count=1)
152         req.hdf[group] = msg.data
153
154     def debug(self, bus, group, msg):
155         self.env.log.debug("%s: %s" % (group, msg.data))
156
157     # IRequestPostProcessor methods
158
159     def process(self, req, template, mime_type):
160         page_name = req.hdf.get('wiki.page_name')
161         version = req.hdf.get('wiki.version')
162         action = req.hdf.get('wiki.action')
163         mime_type = mime_type or 'text/html'
164         if page_name and version and action == 'view' \
165                 and template == 'wiki.cs' and mime_type == 'text/html':
166             # override the default wiki template
167             template = 'market/wiki_override.cs'
168             # add the publishing cost calculations to the hdf
169             cmd = "wiki.%s estimate" % (page_name)
170             ctl = list(self.controllers)[0]
171             ctx = ctl.run_cmd(req=req, cmd=cmd)
172             ctx.res.to_hdf(req.hdf)
173         return template, mime_type
174
Note: See TracBrowser for help on using the browser.