Description:
add brython console for direct edit
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r582:c1e55e47fd4b - - 3 files changed: 232 inserted, 1 deleted
@@ -24,19 +24,20 | |||
|
24 | 24 | //= require ace/mode-javascript |
|
25 | 25 | //= require ace/mode-java |
|
26 | 26 | //= require ace/theme-merbivore |
|
27 | 27 | //= require custom |
|
28 | 28 | //= require jquery.countdown |
|
29 | 29 | //-------------- addition from local_jquery ----------- |
|
30 | 30 | //= require jquery.ui.datepicker |
|
31 | 31 | //= require jquery.ui.slider |
|
32 | 32 | //= require jquery-ui-timepicker-addon |
|
33 | 33 | //= require jquery-tablesorter |
|
34 | 34 | //= require best_in_place |
|
35 | 35 | //= require best_in_place.jquery-ui |
|
36 | + //= require brython | |
|
36 | 37 | |
|
37 | 38 | // since this is after blank line, it is not downloaded |
|
38 | 39 | //x= require prototype |
|
39 | 40 | //x= require prototype_ujs |
|
40 | 41 | //x= require effects |
|
41 | 42 | //x= require dragdrop |
|
42 | 43 | //x= require controls |
@@ -16,12 +16,242 | |||
|
16 | 16 | = hidden_field_tag 'editor_text', @source |
|
17 | 17 | = hidden_field_tag 'submission[problem_id]', @problem.id |
|
18 | 18 | .form-group |
|
19 | 19 | = label_tag "Task:" |
|
20 | 20 | = text_field_tag 'asdf', "#{@problem.long_name}", class: 'form-control', disabled: true |
|
21 | 21 | |
|
22 | 22 | .form-group |
|
23 | 23 | = label_tag 'Language' |
|
24 | 24 | = select_tag 'language_id', options_from_collection_for_select(Language.all, 'id', 'pretty_name', @lang_id || Language.first.id), class: 'form-control select', style: "width: 100px" |
|
25 | 25 | .form-group |
|
26 | 26 | = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit', |
|
27 | 27 | data: {confirm: "Submitting this source code for task #{@problem.long_name}?"} |
|
28 | + .row | |
|
29 | + .col-md-12 | |
|
30 | + %h2 Console | |
|
31 | + %textarea#console{style: 'height: 100%; width: 100%;background-color:#000;color:#fff;font-family: consolas, monaco, "Droid Sans Mono";',rows: 20} | |
|
32 | + | |
|
33 | + :javascript | |
|
34 | + $(document).ready(function() { | |
|
35 | + brython(); | |
|
36 | + }); | |
|
37 | + | |
|
38 | + | |
|
39 | + %script#__main__{type:'text/python3'} | |
|
40 | + :plain | |
|
41 | + import sys | |
|
42 | + import traceback | |
|
43 | + | |
|
44 | + from browser import document as doc | |
|
45 | + from browser import window, alert, console | |
|
46 | + | |
|
47 | + _credits = """ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands | |
|
48 | + for supporting Python development. See www.python.org for more information.""" | |
|
49 | + | |
|
50 | + _copyright = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com | |
|
51 | + All Rights Reserved. | |
|
52 | + | |
|
53 | + Copyright (c) 2001-2013 Python Software Foundation. | |
|
54 | + All Rights Reserved. | |
|
55 | + | |
|
56 | + Copyright (c) 2000 BeOpen.com. | |
|
57 | + All Rights Reserved. | |
|
58 | + | |
|
59 | + Copyright (c) 1995-2001 Corporation for National Research Initiatives. | |
|
60 | + All Rights Reserved. | |
|
61 | + | |
|
62 | + Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. | |
|
63 | + All Rights Reserved.""" | |
|
64 | + | |
|
65 | + _license = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com | |
|
66 | + All rights reserved. | |
|
67 | + | |
|
68 | + Redistribution and use in source and binary forms, with or without | |
|
69 | + modification, are permitted provided that the following conditions are met: | |
|
70 | + | |
|
71 | + Redistributions of source code must retain the above copyright notice, this | |
|
72 | + list of conditions and the following disclaimer. Redistributions in binary | |
|
73 | + form must reproduce the above copyright notice, this list of conditions and | |
|
74 | + the following disclaimer in the documentation and/or other materials provided | |
|
75 | + with the distribution. | |
|
76 | + Neither the name of the <ORGANIZATION> nor the names of its contributors may | |
|
77 | + be used to endorse or promote products derived from this software without | |
|
78 | + specific prior written permission. | |
|
79 | + | |
|
80 | + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
|
81 | + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
|
82 | + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
|
83 | + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
|
84 | + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
|
85 | + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
|
86 | + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
|
87 | + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
|
88 | + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
|
89 | + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
|
90 | + POSSIBILITY OF SUCH DAMAGE. | |
|
91 | + """ | |
|
92 | + | |
|
93 | + def credits(): | |
|
94 | + print(_credits) | |
|
95 | + credits.__repr__ = lambda:_credits | |
|
96 | + | |
|
97 | + def copyright(): | |
|
98 | + print(_copyright) | |
|
99 | + copyright.__repr__ = lambda:_copyright | |
|
100 | + | |
|
101 | + def license(): | |
|
102 | + print(_license) | |
|
103 | + license.__repr__ = lambda:_license | |
|
104 | + | |
|
105 | + def write(data): | |
|
106 | + doc['console'].value += str(data) | |
|
107 | + | |
|
108 | + | |
|
109 | + sys.stdout.write = sys.stderr.write = write | |
|
110 | + history = [] | |
|
111 | + current = 0 | |
|
112 | + _status = "main" # or "block" if typing inside a block | |
|
113 | + | |
|
114 | + # execution namespace | |
|
115 | + editor_ns = {'credits':credits, | |
|
116 | + 'copyright':copyright, | |
|
117 | + 'license':license, | |
|
118 | + '__name__':'__main__'} | |
|
119 | + | |
|
120 | + def cursorToEnd(*args): | |
|
121 | + pos = len(doc['console'].value) | |
|
122 | + doc['console'].setSelectionRange(pos, pos) | |
|
123 | + doc['console'].scrollTop = doc['console'].scrollHeight | |
|
124 | + | |
|
125 | + def get_col(area): | |
|
126 | + # returns the column num of cursor | |
|
127 | + sel = doc['console'].selectionStart | |
|
128 | + lines = doc['console'].value.split('\n') | |
|
129 | + for line in lines[:-1]: | |
|
130 | + sel -= len(line) + 1 | |
|
131 | + return sel | |
|
132 | + | |
|
133 | + | |
|
134 | + def myKeyPress(event): | |
|
135 | + global _status, current | |
|
136 | + if event.keyCode == 9: # tab key | |
|
137 | + event.preventDefault() | |
|
138 | + doc['console'].value += " " | |
|
139 | + elif event.keyCode == 13: # return | |
|
140 | + src = doc['console'].value | |
|
141 | + if _status == "main": | |
|
142 | + currentLine = src[src.rfind('>>>') + 4:] | |
|
143 | + elif _status == "3string": | |
|
144 | + currentLine = src[src.rfind('>>>') + 4:] | |
|
145 | + currentLine = currentLine.replace('\n... ', '\n') | |
|
146 | + else: | |
|
147 | + currentLine = src[src.rfind('...') + 4:] | |
|
148 | + if _status == 'main' and not currentLine.strip(): | |
|
149 | + doc['console'].value += '\n>>> ' | |
|
150 | + event.preventDefault() | |
|
151 | + return | |
|
152 | + doc['console'].value += '\n' | |
|
153 | + history.append(currentLine) | |
|
154 | + current = len(history) | |
|
155 | + if _status == "main" or _status == "3string": | |
|
156 | + try: | |
|
157 | + _ = editor_ns['_'] = eval(currentLine, editor_ns) | |
|
158 | + if _ is not None: | |
|
159 | + write(repr(_)+'\n') | |
|
160 | + doc['console'].value += '>>> ' | |
|
161 | + _status = "main" | |
|
162 | + except IndentationError: | |
|
163 | + doc['console'].value += '... ' | |
|
164 | + _status = "block" | |
|
165 | + except SyntaxError as msg: | |
|
166 | + if str(msg) == 'invalid syntax : triple string end not found' or \ | |
|
167 | + str(msg).startswith('Unbalanced bracket'): | |
|
168 | + doc['console'].value += '... ' | |
|
169 | + _status = "3string" | |
|
170 | + elif str(msg) == 'eval() argument must be an expression': | |
|
171 | + try: | |
|
172 | + exec(currentLine, editor_ns) | |
|
173 | + except: | |
|
174 | + traceback.print_exc() | |
|
175 | + doc['console'].value += '>>> ' | |
|
176 | + _status = "main" | |
|
177 | + elif str(msg) == 'decorator expects function': | |
|
178 | + doc['console'].value += '... ' | |
|
179 | + _status = "block" | |
|
180 | + else: | |
|
181 | + traceback.print_exc() | |
|
182 | + doc['console'].value += '>>> ' | |
|
183 | + _status = "main" | |
|
184 | + except: | |
|
185 | + traceback.print_exc() | |
|
186 | + doc['console'].value += '>>> ' | |
|
187 | + _status = "main" | |
|
188 | + elif currentLine == "": # end of block | |
|
189 | + block = src[src.rfind('>>>') + 4:].splitlines() | |
|
190 | + block = [block[0]] + [b[4:] for b in block[1:]] | |
|
191 | + block_src = '\n'.join(block) | |
|
192 | + # status must be set before executing code in globals() | |
|
193 | + _status = "main" | |
|
194 | + try: | |
|
195 | + _ = exec(block_src, editor_ns) | |
|
196 | + if _ is not None: | |
|
197 | + print(repr(_)) | |
|
198 | + except: | |
|
199 | + traceback.print_exc() | |
|
200 | + doc['console'].value += '>>> ' | |
|
201 | + else: | |
|
202 | + doc['console'].value += '... ' | |
|
203 | + | |
|
204 | + cursorToEnd() | |
|
205 | + event.preventDefault() | |
|
206 | + | |
|
207 | + def myKeyDown(event): | |
|
208 | + global _status, current | |
|
209 | + if event.keyCode == 37: # left arrow | |
|
210 | + sel = get_col(doc['console']) | |
|
211 | + if sel < 5: | |
|
212 | + event.preventDefault() | |
|
213 | + event.stopPropagation() | |
|
214 | + elif event.keyCode == 36: # line start | |
|
215 | + pos = doc['console'].selectionStart | |
|
216 | + col = get_col(doc['console']) | |
|
217 | + doc['console'].setSelectionRange(pos - col + 4, pos - col + 4) | |
|
218 | + event.preventDefault() | |
|
219 | + elif event.keyCode == 38: # up | |
|
220 | + if current > 0: | |
|
221 | + pos = doc['console'].selectionStart | |
|
222 | + col = get_col(doc['console']) | |
|
223 | + # remove current line | |
|
224 | + doc['console'].value = doc['console'].value[:pos - col + 4] | |
|
225 | + current -= 1 | |
|
226 | + doc['console'].value += history[current] | |
|
227 | + event.preventDefault() | |
|
228 | + elif event.keyCode == 40: # down | |
|
229 | + if current < len(history) - 1: | |
|
230 | + pos = doc['console'].selectionStart | |
|
231 | + col = get_col(doc['console']) | |
|
232 | + # remove current line | |
|
233 | + doc['console'].value = doc['console'].value[:pos - col + 4] | |
|
234 | + current += 1 | |
|
235 | + doc['console'].value += history[current] | |
|
236 | + event.preventDefault() | |
|
237 | + elif event.keyCode == 8: # backspace | |
|
238 | + src = doc['console'].value | |
|
239 | + lstart = src.rfind('\n') | |
|
240 | + if (lstart == -1 and len(src) < 5) or (len(src) - lstart < 6): | |
|
241 | + event.preventDefault() | |
|
242 | + event.stopPropagation() | |
|
243 | + | |
|
244 | + | |
|
245 | + doc['console'].bind('keypress', myKeyPress) | |
|
246 | + doc['console'].bind('keydown', myKeyDown) | |
|
247 | + doc['console'].bind('click', cursorToEnd) | |
|
248 | + v = sys.implementation.version | |
|
249 | + doc['console'].value = "Brython %s.%s.%s on %s %s\n>>> " % ( | |
|
250 | + v[0], v[1], v[2], window.navigator.appName, window.navigator.appVersion) | |
|
251 | + #doc['console'].value += 'Type "copyright", "credits" or "license" for more information.' | |
|
252 | + doc['console'].focus() | |
|
253 | + cursorToEnd() | |
|
254 | + | |
|
255 | + | |
|
256 | + | |
|
257 | + |
@@ -27,14 +27,14 | |||
|
27 | 27 | |
|
28 | 28 | # Log the query plan for queries taking more than this (works |
|
29 | 29 | # with SQLite, MySQL, and PostgreSQL) |
|
30 | 30 | config.active_record.auto_explain_threshold_in_seconds = 0.5 |
|
31 | 31 | |
|
32 | 32 | # Do not compress assets |
|
33 | 33 | config.assets.compress = false |
|
34 | 34 | |
|
35 | 35 | # Expands the lines which load the assets |
|
36 | 36 | config.assets.debug = true |
|
37 | 37 | |
|
38 | 38 | # Prevents assets from rendering twice |
|
39 |
- config.serve_static_assets = |
|
|
39 | + config.serve_static_assets = true | |
|
40 | 40 | end |
You need to be logged in to leave comments.
Login now