-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlevraoueg.brython.js
42 lines (42 loc) · 17.5 KB
/
levraoueg.brython.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
__BRYTHON__.use_VFS = true;
var scripts = {
"$timestamp": 1570444786485,
"console": [
".py",
"import sys\nimport tb as traceback\n\nfrom browser import document as doc\nfrom browser import window,alert,console\n\nclass Trace:\n\n def __init__(self):\n self.buf=\"\"\n \n def write(self,data):\n self.buf +=str(data)\n \n def format(self):\n ''\n lines=self.buf.split(\"\\n\")\n stripped=[lines[0]]\n for i in range(1,len(lines),2):\n if __file__ in lines[i]:\n continue\n stripped +=lines[i:i+2]\n return \"\\n\".join(stripped)\n \n \nclass Console:\n\n def __init__(self,element,namespace={}):\n self.element=element\n element.bind('keypress',self.keypress)\n element.bind('keydown',self.keydown)\n element.bind('click',self.cursorToEnd)\n element.focus()\n self.cursorToEnd()\n self.status=\"main\"\n self.current=0\n self.history=[]\n self.buffer=\"\"\n sys.stdout=self\n sys.stderr=self\n self.namespace=namespace\n \n def clear(self):\n self.buffer=''\n self.element.value=''\n \n def cursorToEnd(self,*args):\n pos=len(self.element.value)\n self.element.setSelectionRange(pos,pos)\n self.element.scrollTop=self.element.scrollHeight\n \n def keypress(self,event):\n if event.keyCode ==9:\n event.preventDefault()\n self.element.value +=\" \"\n elif event.keyCode ==13:\n src=self.element.value\n if self.status ==\"main\":\n currentLine=src[src.rfind('>>>')+4:]\n elif self.status ==\"3string\":\n currentLine=src[src.rfind('>>>')+4:]\n currentLine=currentLine.replace('\\n... ','\\n')\n else :\n currentLine=src[src.rfind('...')+4:]\n if self.status =='main'and not currentLine.strip():\n self.element.value +='\\n>>> '\n event.preventDefault()\n return\n self.element.value +='\\n'\n self.history.append(currentLine)\n self.current=len(self.history)\n if self.status ==\"main\"or self.status ==\"3string\":\n try :\n _=self.namespace['_']=eval(currentLine,self.namespace)\n if _ is not None :\n self.write(repr(_)+'\\n')\n self.write('>>> ')\n self.status=\"main\"\n except IndentationError:\n self.element.value +='... '\n self.status=\"block\"\n except SyntaxError as msg:\n if str(msg)=='invalid syntax : triple string end not found'or\\\n str(msg).startswith('Unbalanced bracket'):\n self.element.value +='... '\n self.status=\"3string\"\n elif str(msg)=='eval() argument must be an expression':\n try :\n exec(currentLine,self.namespace)\n except :\n self.print_tb()\n self.write('>>> ')\n self.status=\"main\"\n elif str(msg)=='decorator expects function':\n self.element.value +='... '\n self.status=\"block\"\n else :\n self.syntax_error(msg.args)\n self.element.value +='>>> '\n self.status=\"main\"\n except :\n \n \n \n self.print_tb()\n self.element.value +='>>> '\n self.status=\"main\"\n elif currentLine ==\"\":\n block=src[src.rfind('>>>')+4:].splitlines()\n block=[block[0]]+[b[4:]for b in block[1:]]\n block_src='\\n'.join(block)\n \n self.status=\"main\"\n try :\n _=exec(block_src,self.namespace)\n if _ is not None :\n print(repr(_))\n except :\n self.print_tb()\n self.write('>>> ')\n else :\n self.element.value +='... '\n \n self.cursorToEnd()\n event.preventDefault()\n \n def keydown(self,event):\n if event.keyCode ==37:\n sel=self.get_col()\n if sel <5:\n event.preventDefault()\n event.stopPropagation()\n elif event.keyCode ==36:\n pos=self.element.selectionStart\n col=self.get_col()\n self.element.setSelectionRange(pos -col+4,pos -col+4)\n event.preventDefault()\n elif event.keyCode ==38:\n if self.current >0:\n pos=self.element.selectionStart\n col=self.get_col()\n \n self.element.value=self.element.value[:pos -col+4]\n self.current -=1\n self.element.value +=self.history[self.current]\n event.preventDefault()\n elif event.keyCode ==40:\n if self.current <len(self.history)-1:\n pos=self.element.selectionStart\n col=self.get_col()\n \n self.element.value=self.element.value[:pos -col+4]\n self.current +=1\n self.element.value +=self.history[self.current]\n event.preventDefault()\n elif event.keyCode ==8:\n src=self.element.value\n lstart=src.rfind('\\n')\n if (lstart ==-1 and len(src)<5)or (len(src)-lstart <6):\n event.preventDefault()\n event.stopPropagation()\n elif event.ctrlKey and event.keyCode ==65:\n src=self.element.value\n pos=self.element.selectionStart\n col=self.get_col()\n self.element.setSelectionRange(pos -col+4,len(src))\n event.preventDefault()\n elif event.keyCode in [33,34]:\n event.preventDefault()\n \n def get_col(self):\n \n sel=self.element.selectionStart\n lines=self.element.value.split('\\n')\n for line in lines[:-1]:\n sel -=len(line)+1\n return sel\n \n def print_tb(self):\n trace=Trace()\n traceback.print_exc(file=trace)\n self.write(trace.format())\n \n def prompt(self):\n if self.element.value and not self.element.value.endswith('\\n'):\n self.write('\\n')\n self.write(\">>> \")\n self.element.focus()\n \n def syntax_error(self,args):\n info,filename,lineno,offset,line=args\n print(f\" File {filename}, line {lineno}\")\n print(\" \"+line)\n print(\" \"+offset *\" \"+\"^\")\n print(\"SyntaxError:\",info)\n \n def write(self,data):\n self.element.value +=str(data)\n \n \ndef mark(element):\n Console(element)\n",
[
"browser",
"sys",
"tb"
]
],
"editor": [
".py",
"import re\n\nfrom browser import ajax,bind,confirm,document,window,alert,prompt,html\nfrom browser import console\nfrom browser.widgets import dialog\n\nfrom scripts_finder import ScriptsFinder\n\ndocument[\"wait\"].remove()\ndocument[\"container\"].style.visibility=\"visible\"\ndocument[\"legend\"].style.visibility=\"visible\"\n\nimport sys\nimport tb\n\nsys.meta_path.append(ScriptsFinder)\n\n\nif window.location.href.startswith(\"file://\"):\n import _importlib\n sys.meta_path.remove(_importlib.ImporterPath)\n sys.meta_path.remove(_importlib.StdlibStatic)\n \nfrom console import Console\n\ntranslations={\n\"fr\":{\n\"close\":\"Fermer\",\n\"confirm_delete\":\"Voulez-vous supprimer le fichier\\n{} ?\",\n\"file_changed\":\"Le fichier {} a chang\u00e9.\\nEnregistrer ?\",\n\"file_deleted\":\"Fichier supprim\u00e9\",\n\"new_script\":\"Nouveau script\",\n\"open\":\"Ouvrir\",\n\"redo\":\"Refaire\",\n\"save\":\"Enregistrer\",\n\"undo\":\"D\u00e9faire\",\n\"run_source\":\"Ex\u00e9cuter\",\n\"legend_text\":\"\"\"Editeur de code Python. Utilise\n <a href=\"https://brython.info\" target=\"_blank\">Brython</a> et\n <a href=\"https://ace.c9.io/\">Ace</a>\"\"\",\n\"trash\":\"Supprimer\"\n}\n}\n\nlanguage=document.query.getfirst(\"lang\")\nif language is None :\n language=window.navigator.language\n if language is not None :\n language=language[:2]\n \n \nif language in translations:\n for elt_id,translation in translations[language].items():\n if elt_id in document:\n document[elt_id].attrs[\"title\"]=translation\n \n \n \nload_file=document.query.getfirst(\"file\")\nif load_file:\n\n req=ajax.get(load_file,\n oncomplete=lambda evt:load3(evt.text,load_file))\n \n \nheight=document.documentElement.clientHeight\ndocument['container'].style.height=f'{int(height * 0.8)}px'\n\n\ndocument['legend'].style.top=f'{int(height * 0.9)}px'\n\nfilezone=document[\"filezone\"]\nfilebrowser=document[\"file-browser\"]\n\nopen_files={}\n\neditor=None\n\n\ndef create_editor():\n global editor\n document[\"editor\"].style.backgroundColor=\"#fff\"\n editor=window.ace.edit(\"editor\")\n editor.setTheme(\"ace/theme/github\")\n editor.session.setMode(\"ace/mode/python\")\n editor.focus()\n editor.on(\"change\",editor_changed)\n return editor\n \ndef editor_changed(*args):\n ''\n current=document.select(\".current\")\n if current:\n filename=current[0].text.rstrip(\"*\")\n if open_files[filename][\"content\"]!=editor.getValue():\n if not current[0].text.endswith(\"*\"):\n current[0].text +=\"*\"\n elif current[0].text.endswith(\"*\"):\n current[0].text=current[0].text.rstrip(\"*\")\n \ndef _(id,default):\n ''\n if language and language in translations and\\\n id in translations[language]:\n return translations[language][id]\n return default\n \n \nIDB=window.indexedDB\nrequest=IDB.open(\"brython_scripts\")\n\nscripts={}\n\n@bind(request,\"upgradeneeded\")\ndef create_db(evt):\n\n db=evt.target.result\n store=db.createObjectStore(\"scripts\",{\"keyPath\":\"name\"})\n \n@bind(request,\"success\")\ndef load_scripts(evt):\n db=request.result\n tx=db.transaction(\"scripts\",\"readonly\")\n store=tx.objectStore(\"scripts\")\n req=store.getAll()\n \n @bind(req,\"success\")\n def check(evt):\n for script in evt.target.result:\n name=script.name\n if name.endswith(\".py\"):\n name=name[:-3]\n ScriptsFinder.scripts[name]=script.content\n \n@bind(\"#new_script\",\"click\")\ndef new_script(evt):\n ''\n \n db=request.result\n tx=db.transaction(\"scripts\",\"readonly\")\n store=tx.objectStore(\"scripts\")\n cursor=store.openCursor()\n \n nums=[]\n \n def get_scripts(evt):\n res=evt.target.result\n if res:\n name=res.value.name\n mo=re.match(\"^module(\\d+).py$\",name)\n if mo:\n nums.append(int(mo.groups()[0]))\n getattr(res,\"continue\")()\n else :\n if not nums:\n num=1\n else :\n num=max(nums)+1\n create_editor()\n editor.setValue(\"\")\n filename=f\"module{num}.py\"\n open_files[filename]={\"content\":\"\",\"cursor\":[0,0]}\n update_filebrowser(filename)\n \n cursor.bind('success',get_scripts)\n \n@bind(\"#run_source\",\"click\")\ndef run(evt):\n ''\n \n ns={}\n output.clear()\n try :\n exec(editor.getValue(),ns)\n \n output.namespace=ns\n except :\n tb.print_exc(file=output)\n output.prompt()\n \ndef display(evt):\n ''\n file_name=evt.target.text\n \n current=document.select_one(\".current\")\n if current.text ==file_name:\n rename(current)\n return\n position=editor.getCursorPosition()\n open_files[current.text]={\n \"content\":editor.getValue(),\n \"cursor\":[position.row,position.column]\n }\n \n \n current.classList.remove(\"current\")\n evt.target.classList.add(\"current\")\n \n \n new_file=open_files[file_name]\n editor.setValue(new_file[\"content\"])\n editor.moveCursorTo(*new_file[\"cursor\"],False )\n editor.scrollToLine(new_file[\"cursor\"][0],True )\n editor.clearSelection()\n editor.focus()\n \ndef rename2(evt,old_name):\n new_name=evt.target.value\n if new_name ==old_name:\n update_filebrowser(old_name)\n return\n \n \n db=request.result\n tx=db.transaction(\"scripts\",\"readonly\")\n store=tx.objectStore(\"scripts\")\n req=store.count(new_name)\n \n @bind(req,\"success\")\n def exists(evt):\n if evt.target.result:\n \n replace=confirm(\"A script called \"+new_name+\n \" already exists. Overwrite ?\")\n if replace:\n \n tx=db.transaction(\"scripts\",\"readwrite\")\n store=tx.objectStore(\"scripts\")\n data={\"name\":new_name,\"content\":editor.getValue()}\n req=store.put(data)\n \n @bind(req,\"success\")\n def replaced(evt):\n \n req=store.delete(old_name)\n \n @bind(req,\"success\")\n def removed(evt):\n del open_files[old_name]\n if not new_name in open_files:\n open_files[new_name]={\n \"content\":editor.getValue(),\n \"cursor\":[0,0]\n }\n update_filebrowser(new_name)\n else :\n \n tx=db.transaction(\"scripts\",\"readwrite\")\n store=tx.objectStore(\"scripts\")\n data={\"name\":new_name,\"content\":editor.getValue()}\n req=store.put(data)\n \n @bind(req,\"success\")\n def created(evt):\n del open_files[old_name]\n open_files[new_name]={\"content\":\"\",\"cursor\":[0,0]}\n update_filebrowser(new_name)\n \n \ndef keyup_rename(evt,filename):\n ''\n if evt.keyCode ==27:\n evt.target.parent.remove()\n update_filebrowser(filename)\n evt.preventDefault()\n evt.stopPropagation()\n elif evt.keyCode ==13:\n rename2(evt,filename)\n evt.preventDefault()\n evt.stopPropagation()\n \ndef rename(current):\n ''\n current.unbind(\"click\",display)\n filename=current.text.rstrip(\"*\")\n current.html=f'<input value=\"{filename}\">'\n entry=current.children[0]\n pos=filename.find(\".\")\n entry.setSelectionRange(pos,pos)\n entry.bind(\"blur\",lambda evt:rename2(evt,filename))\n entry.bind(\"keyup\",lambda evt:keyup_rename(evt,filename))\n entry.focus()\n \ndef update_filebrowser(current=None ):\n ''\n \n files=list(open_files)\n files.sort()\n filebrowser.clear()\n for f in files:\n line=html.DIV(f,Class=\"pyfile\")\n if f ==current:\n line.classList.add(\"current\")\n line.bind(\"click\",display)\n filebrowser <=line\n \ndef load3(content,filename):\n ''\n open_files[filename]={\"content\":content,\"cursor\":[0,0]}\n update_filebrowser(filename)\n \n create_editor()\n editor.setValue(content)\n editor.moveCursorTo(0,0,False )\n editor.focus()\n \ndef open_script(evt):\n ''\n\n \n current=evt.target.text\n db=request.result\n tx=db.transaction(\"scripts\",\"readonly\")\n store=tx.objectStore(\"scripts\")\n req=store.get(current)\n \n def success(evt):\n if not hasattr(req,\"result\"):\n print(\"not found\")\n else :\n load3(req.result.content,current)\n \n dialog_window=evt.target.parent.parent\n dialog_window.remove()\n \n req.bind(\"success\",success)\n \n@bind(\"#open\",\"click\")\ndef vfs_open(evt):\n ''\n \n db=request.result\n tx=db.transaction(\"scripts\",\"readonly\")\n store=tx.objectStore(\"scripts\")\n req=store.getAllKeys()\n \n dialog_window=dialog.Dialog(\"Open file...\",\n top=filebrowser.abs_top,\n left=filebrowser.abs_left)\n \n scripts=[]\n script_style={\n \"cursor\":\"default\"\n }\n def get_scripts(evt):\n scripts=evt.target.result\n scripts.sort()\n for script in scripts:\n script_elt=html.SPAN(script,style=script_style)\n dialog_window.panel <=script_elt+html.BR()\n script_elt.bind(\"click\",open_script)\n \n req.bind('success',get_scripts)\n \ndef _remove(filename):\n ''\n del open_files[filename]\n if open_files:\n files=list(open_files)\n filename=files[-1]\n update_filebrowser(filename)\n editor.setValue(open_files[filename][\"content\"])\n else :\n filebrowser.clear()\n document[\"editor\"].clear()\n document[\"editor\"].style.backgroundColor=\"#aaa\"\n editor.destroy()\n \n@bind(\"#close\",\"click\")\ndef close(evt):\n ''\n current=filebrowser.select_one(\".current\")\n if current is None :\n return\n filename=current.text\n if filename.endswith(\"*\"):\n msg=_(\"file_changed\",\"File {} changed; save it ?\")\n resp=confirm(msg.format(filename.rstrip(\"*\")))\n if resp:\n save(evt)\n filename=filename[:-1]\n _remove(filename)\n \n@bind(\"#redo\",\"click\")\ndef redo(evt):\n manager=editor.session.getUndoManager()\n if manager.hasRedo():\n editor.redo()\n editor.clearSelection()\n editor.focus()\n \n@bind(\"#undo\",\"click\")\ndef undo(evt):\n if editor.session.getUndoManager().hasUndo():\n editor.undo()\n \n@bind(\"#save\",\"click\")\ndef save(evt):\n ''\n current=filebrowser.select_one(\".current\")\n if current is None :\n return\n name=current.text\n if not name:\n return\n name=name.rstrip(\"*\")\n db=request.result\n tx=db.transaction(\"scripts\",\"readwrite\")\n store=tx.objectStore(\"scripts\")\n cursor=store.openCursor()\n data={\"name\":name,\"content\":editor.getValue()}\n store.put(data)\n \n \n def ok(evt):\n current.text=name\n dialog.InfoDialog(\"Text editor\",f\"{name} saved\",\n remove_after=2)\n \n if name.endswith(\".py\"):\n mod_name=name[:-3]\n ScriptsFinder.scripts[mod_name]=editor.getValue()\n \n if mod_name in sys.modules:\n del sys.modules[mod_name]\n \n cursor.bind('success',ok)\n \n@bind(\"#trash\",\"click\")\ndef trash(evt):\n ''\n current=filebrowser.select_one(\".current\")\n if current is None :\n return\n name=current.text\n if not name:\n return\n name=name.rstrip(\"*\")\n msg=_(\"confirm_delete\",\"Do you want to delete\\nfile {} ?\")\n resp=confirm(msg.format(name))\n if not resp:\n return\n db=request.result\n tx=db.transaction(\"scripts\",\"readwrite\")\n store=tx.objectStore(\"scripts\")\n cursor=store.openCursor()\n store.delete(name)\n \n def ok(evt):\n alert(_(\"file_deleted\",\"File deleted\"))\n _remove(name)\n \n cursor.bind(\"success\",ok)\n \n \noutput=Console(document[\"console\"])\noutput.prompt()\n",
[
"_importlib",
"browser",
"browser.widgets",
"console",
"re",
"scripts_finder",
"sys",
"tb"
]
],
"scripts_finder": [
".py",
"import sys\nfrom browser import console\n\nclass ScriptsFinder:\n ''\n \n scripts={}\n \n @classmethod\n def find_spec(cls,fullname,path=None ):\n if fullname in ScriptsFinder.scripts:\n spec=ModuleSpec(fullname,ScriptsFinder)\n spec.cached=False\n spec.has_location=True\n spec.loader_state={\n \"content\":ScriptsFinder.scripts[fullname],\n \"path\":fullname,\n \"is_package\":False\n }\n spec.origin=fullname\n spec.parent=fullname\n spec.submodule_search_locations=None\n return spec\n \n @classmethod\n def create_module(cls,spec):\n pass\n \n @classmethod\n def exec_module(cls,module):\n spec=module.__spec__\n sys.modules[spec.name]=module\n ns={}\n \n exec(spec.loader_state[\"content\"],ns)\n for key,value in ns.items():\n setattr(module,key,value)\n \nclass ModuleSpec:\n\n def __init__(self,name,loader):\n self.name=name\n self.loader=loader\n",
[
"browser",
"sys"
]
],
"": [
".py",
"",
[],
1
]
}
__BRYTHON__.update_VFS(scripts)