I think that scheduler is designed for asynchronous tasks, but I want to see changes effect immediately after edit/save pyj-file(s) and update web page. So, all pyj-files must be checked for out-of-date and recompiled (if there is anyone) per request call. I believe that cool IDEs allow doing this w/o extra coding, but I use Pyscripter only.
On Monday, February 8, 2016 at 11:50:08 AM UTC+3, mcm wrote: > > Very nice. > Did you evaluate running compile_pyjs() as a web2py's scheduler task? > It could simplify your code and make it more resilient. > > > 2016-02-08 0:20 GMT+01:00 Val K <[email protected] <javascript:>>: > >> Hi! >> Coding Python with switching to coding JS - really painful. >> So, I tried Rapydscript (RS) and I like it very much! Unfortunately, I >> couldn't find how to automate compilation RS-files to pure JS. >> Here is my solution to embed RS to web2py >> >> 1. Download and install Node.js <http://Nodejs.org> to anywhere >> (RS-compiler works on it, i.e. it's required only for developing, it >> won't >> be a dependence of your web2py project) >> 2. Download and unpack Rapydscript <http://rapydscript.pyjeon.com>to >> anywhere. Or you can done it using GIT, as suggested in the manual (it's >> version 0.3.9 at the moment and it works w/o GIT-install) >> 3. Code a little module to automate compilation your RS-files to pure >> JS and place it in* your_w2p_app/modUles* dir, here is my one >> >> import sys >> import os >> from stat import ST_MTIME >> import json as js >> import subprocess as subp >> import portalocker >> >> get_fname = lambda full_name: os.path.split(full_name)[1] >> >> def change_ext(f_name, ext): >> return os.path.splitext(f_name)[0] + ext >> >> def clear_file(f): >> f.seek(0) >> f.truncate() >> >> class _log(object): # used to track changes to avoid parallel and extra >> recompilation >> >> def __init__(self, f_name): >> self.f_name=f_name >> self.error={} >> self.f_obj=None >> self.log = None >> >> def open_read(self): >> f_name=self.f_name >> try: >> if os.path.isfile(f_name): >> md='r+' >> else: >> md='w' >> f = open(f_name, md) >> self.f_obj = f >> portalocker.lock(f, portalocker.LOCK_EX ) >> if md=='r+': >> tmp= f.read() >> self.log = (tmp and js.loads(tmp)) or {} >> else: >> self.log = {} >> except : >> self.error['open_read'] = sys.exc_info()[0] >> return self.error['open_read'] is None >> >> def save(self): >> if not self.f_obj: >> return >> try: >> clear_file(self.f_obj) >> self.f_obj.write(js.dumps(self.log)) >> self.f_obj.close() >> except : >> self.error['save'] = sys.exc_info()[0] >> >> def set_compile_time(self, pyj_fname): >> if self.log is None: >> return >> f_stat = os.stat(pyj_fname) >> self.log[ get_fname(pyj_fname) ] = f_stat[ST_MTIME] >> >> def is_up_to_date(self, pyj_fname): >> if self.log is None: >> return False >> f_stat = os.stat(pyj_fname) >> return self.log[ get_fname(pyj_fname) ] == f_stat[ST_MTIME] >> >> >> class rs_compiler(object): >> def __init__(self, path_to_nodejs, path_to_RS): >> self.node = path_to_nodejs >> self.rs_engine = path_to_RS >> self.last_ret_code = None >> self.last_rslts = None >> >> def _rs_compile(self, src, dst, log, force_compile=False): >> ret = None >> if force_compile or not log.is_up_to_date(src) or not >> os.path.isfile(dst): >> ret = subp.call( [self.node, self.rs_engine, src, '-p', '-o', >> dst]) >> if ret==0: >> log.set_compile_time(src) >> self.last_ret_code = ret >> return ret >> >> def rs_compile_dir(self, src, dst, force_compile=False): >> >> log = _log(os.path.join(dst, 'compile_inf.json' )) # >> 'compile_inf.json' >> - contains dict { 'file_1.pyj' : ST_MTIME, 'file_2.pyj' : ST_MTIME ... >> } >> >> # it will be >> created/overwrited in the same dir as JS-files >> if not log.open_read(): >> return {}; >> >> joinp = os.path.join >> all_dir = os.listdir(src) >> src_files = [f for f in all_dir if os.path.isfile(joinp(src, f)) >> and f[-4:]=='.pyj'] >> ret={} >> for f in src_files: >> src_f = joinp(src, f) >> dst_f = joinp(dst, change_ext(f, '.js')) >> self._rs_compile(src_f, dst_f, log, >> force_compile=force_compile) >> rslt=dict( >> ret_code = self.last_ret_code, >> open_read = log.error.get('open_read', None), >> log_save_err = log.error.get('save', None), >> ) >> ret[f] = rslt >> self.last_rslts=ret >> log.save() >> return ret >> >> >> >> def main(): >> pass >> >> if __name__ == '__main__': >> main() >> >> >> >> Now, to automate compilation you can place some code like below in db.py >> (or in another model-file) >> >> ... >> import rs_compiler >> >> def compile_pyj(): >> node='path_to/nodejs/node.exe' >> rs_engine = 'path_to/RapydScript-master/bin/rapydscript' >> rs = rs_compiler.rs_compiler(node, rs_engine) >> src = os.path.join(request.folder, 'private') # I place my RS-files >> in 'w2p_app/private' dir - you can choose another one >> dst = os.path.join(request.folder, 'static/js') >> >> print rs.rs_compile_dir(src, dst) # compile each src/file_name.pyj >> to dst/file_name.js - overwriting JS-files without any warning! >> >> compile_pyj() >> >> >> >> >> >> >> >> >> >> -- >> Resources: >> - http://web2py.com >> - http://web2py.com/book (Documentation) >> - http://github.com/web2py/web2py (Source code) >> - https://code.google.com/p/web2py/issues/list (Report Issues) >> --- >> You received this message because you are subscribed to the Google Groups >> "web2py-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.

