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]>: > 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]. > 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.

