Package web2py :: Package gluon :: Module admin
[hide private]
[frames] | no frames]

Source Code for Module web2py.gluon.admin

  1  """ 
  2  This file is part of the web2py Web Framework 
  3  Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> 
  4  License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) 
  5   
  6  Utility functions for the Admin application 
  7  =========================================== 
  8  """ 
  9  import os 
 10  import sys 
 11  import traceback 
 12  import zipfile 
 13  import urllib 
 14  from shutil import rmtree 
 15  from utils import web2py_uuid 
 16  from fileutils import w2p_pack, w2p_unpack, w2p_pack_plugin, w2p_unpack_plugin 
 17  from fileutils import up, fix_newlines, abspath, recursive_unlink 
 18  from restricted import RestrictedError 
 19  from settings import global_settings 
 20   
21 -def apath(path='', r=None):
22 """ 23 Builds a path inside an application folder 24 25 Parameters 26 ---------- 27 path: 28 path within the application folder 29 r: 30 the global request object 31 32 """ 33 34 opath = up(r.folder) 35 while path[:3] == '../': 36 (opath, path) = (up(opath), path[3:]) 37 return os.path.join(opath, path).replace('\\', '/')
38 39
40 -def app_pack(app, request):
41 """ 42 Builds a w2p package for the application 43 44 Parameters 45 ---------- 46 app: 47 application name 48 request: 49 the global request object 50 51 Returns 52 ------- 53 filename: 54 filename of the w2p file or None on error 55 """ 56 try: 57 app_cleanup(app, request) 58 filename = apath('../deposit/%s.w2p' % app, request) 59 w2p_pack(filename, apath(app, request)) 60 return filename 61 except Exception: 62 return False
63 64
65 -def app_pack_compiled(app, request):
66 """ 67 Builds a w2p bytecode-compiled package for the application 68 69 Parameters 70 ---------- 71 app: 72 application name 73 request: 74 the global request object 75 76 Returns 77 ------- 78 filename: 79 filename of the w2p file or None on error 80 """ 81 82 try: 83 filename = apath('../deposit/%s.w2p' % app, request) 84 w2p_pack(filename, apath(app, request), compiled=True) 85 return filename 86 except Exception: 87 return None
88
89 -def app_cleanup(app, request):
90 """ 91 Removes session, cache and error files 92 93 Parameters 94 ---------- 95 app: 96 application name 97 request: 98 the global request object 99 """ 100 r = True 101 102 # Remove error files 103 path = apath('%s/errors/' % app, request) 104 if os.path.exists(path): 105 for f in os.listdir(path): 106 try: 107 os.unlink(os.path.join(path,f)) 108 except IOError: 109 r = False 110 111 # Remove session files 112 path = apath('%s/sessions/' % app, request) 113 if os.path.exists(path): 114 for f in os.listdir(path): 115 try: 116 recursive_unlink(os.path.join(path,f)) 117 except IOError: 118 r = False 119 120 # Remove cache files 121 path = apath('%s/sessions/' % app, request) 122 if os.path.exists(path): 123 for f in os.listdir(path): 124 try: 125 os.unlink(os.path.join(path,f)) 126 except IOError: 127 r = False 128 return r
129 130
131 -def app_compile(app, request):
132 """ 133 Compiles the application 134 135 Parameters 136 ---------- 137 app: 138 application name 139 request: 140 the global request object 141 """ 142 from compileapp import compile_application, remove_compiled_application 143 folder = apath(app, request) 144 try: 145 compile_application(folder) 146 return None 147 except (Exception, RestrictedError): 148 tb = traceback.format_exc(sys.exc_info) 149 remove_compiled_application(folder) 150 return tb
151
152 -def app_create(app, request,force=False,key=None):
153 """ 154 Create a copy of welcome.w2p (scaffolding) app 155 156 Parameters 157 ---------- 158 app: 159 application name 160 request: 161 the global request object 162 163 """ 164 try: 165 path = apath(app, request) 166 os.mkdir(path) 167 except: 168 if not force: 169 return False 170 try: 171 w2p_unpack('welcome.w2p', path) 172 for subfolder in ['models','views','controllers', 'databases', 173 'modules','cron','errors','sessions', 174 'languages','static','private','uploads']: 175 subpath = os.path.join(path,subfolder) 176 if not os.path.exists(subpath): 177 os.mkdir(subpath) 178 db = os.path.join(path, 'models', 'db.py') 179 if os.path.exists(db): 180 fp = open(db,'r') 181 data = fp.read() 182 fp.close() 183 data = data.replace('<your secret key>', 184 'sha512:'+(key or web2py_uuid())) 185 fp = open(db,'w') 186 fp.write(data) 187 fp.close() 188 return True 189 except: 190 rmtree(path) 191 return False
192 193
194 -def app_install(app, fobj, request, filename, overwrite=None):
195 """ 196 Installs an application: 197 198 - Identifies file type by filename 199 - Writes `fobj` contents to the `../deposit/` folder 200 - Calls `w2p_unpack()` to do the job. 201 202 Parameters 203 ---------- 204 app: 205 new application name 206 fobj: 207 file object containing the application to be installed 208 request: 209 the global request object 210 filename: 211 original filename of the `fobj`, required to determine extension 212 213 Returns 214 ------- 215 upname: 216 name of the file where app is temporarily stored or `None` on failure 217 """ 218 did_mkdir = False 219 if filename[-4:] == '.w2p': 220 extension = 'w2p' 221 elif filename[-7:] == '.tar.gz': 222 extension = 'tar.gz' 223 else: 224 extension = 'tar' 225 upname = apath('../deposit/%s.%s' % (app, extension), request) 226 227 try: 228 upfile = open(upname, 'wb') 229 upfile.write(fobj.read()) 230 upfile.close() 231 path = apath(app, request) 232 if not overwrite: 233 os.mkdir(path) 234 did_mkdir = True 235 w2p_unpack(upname, path) 236 if extension != 'tar': 237 os.unlink(upname) 238 fix_newlines(path) 239 return upname 240 except Exception: 241 if did_mkdir: 242 rmtree(path) 243 return False
244 245
246 -def app_uninstall(app, request):
247 """ 248 Uninstalls the application. 249 250 Parameters 251 ---------- 252 app: 253 application name 254 request: 255 the global request object 256 257 Returns 258 ------- 259 `True` on success, `False` on failure 260 """ 261 try: 262 # Hey App, this is your end... 263 path = apath(app, request) 264 rmtree(path) 265 return True 266 except Exception: 267 return False
268
269 -def plugin_pack(app, plugin_name, request):
270 """ 271 Builds a w2p package for the application 272 273 Parameters 274 ---------- 275 app: 276 application name 277 plugin_name: 278 the name of the plugin without plugin_ prefix 279 request: 280 the current request app 281 282 Returns 283 ------- 284 filename: 285 filename of the w2p file or None on error 286 """ 287 try: 288 filename = apath('../deposit/web2py.plugin.%s.w2p' % plugin_name, request) 289 w2p_pack_plugin(filename, apath(app, request), plugin_name) 290 return filename 291 except Exception: 292 return False
293
294 -def plugin_install(app, fobj, request, filename):
295 """ 296 Installs an application: 297 298 - Identifies file type by filename 299 - Writes `fobj` contents to the `../deposit/` folder 300 - Calls `w2p_unpack()` to do the job. 301 302 Parameters 303 ---------- 304 app: 305 new application name 306 fobj: 307 file object containing the application to be installed 308 request: 309 the global request object 310 filename: 311 original filename of the `fobj`, required to determine extension 312 313 Returns 314 ------- 315 upname: 316 name of the file where app is temporarily stored or `None` on failure 317 """ 318 319 upname = apath('../deposit/%s' % filename, request) 320 321 try: 322 upfile = open(upname, 'wb') 323 upfile.write(fobj.read()) 324 upfile.close() 325 path = apath(app, request) 326 w2p_unpack_plugin(upname, path) 327 fix_newlines(path) 328 return upname 329 except Exception: 330 os.unlink(upname) 331 return False
332
333 -def check_new_version(myversion, version_URL):
334 """ 335 Compares current web2py's version with the latest stable web2py version. 336 337 Parameters 338 ---------- 339 myversion: 340 the current version as stored in file `web2py/VERSION` 341 version_URL: 342 the URL that contains the version of the latest stable release 343 344 Returns 345 ------- 346 state: 347 `True` if upgrade available, `False` if current version if up-to-date, 348 -1 on error 349 version: 350 the most up-to-version available 351 """ 352 try: 353 from urllib import urlopen 354 version = urlopen(version_URL).read() 355 except Exception: 356 return -1, myversion 357 358 if version > myversion: 359 return True, version 360 else: 361 return False, version
362
363 -def unzip(filename, dir, subfolder=''):
364 """ 365 Unzips filename into dir (.zip only, no .gz etc) 366 if subfolder!='' it unzip only files in subfolder 367 """ 368 filename = abspath(filename) 369 if not zipfile.is_zipfile(filename): 370 raise RuntimeError, 'Not a valid zipfile' 371 zf = zipfile.ZipFile(filename) 372 if not subfolder.endswith('/'): 373 subfolder = subfolder + '/' 374 n = len(subfolder) 375 for name in sorted(zf.namelist()): 376 if not name.startswith(subfolder): 377 continue 378 #print name[n:] 379 if name.endswith('/'): 380 folder = os.path.join(dir,name[n:]) 381 if not os.path.exists(folder): 382 os.mkdir(folder) 383 else: 384 outfile = open(os.path.join(dir, name[n:]), 'wb') 385 outfile.write(zf.read(name)) 386 outfile.close()
387 388
389 -def upgrade(request, url='http://web2py.com'):
390 """ 391 Upgrades web2py (src, osx, win) is a new version is posted. 392 It detects whether src, osx or win is running and downloads the right one 393 394 Parameters 395 ---------- 396 request: 397 the current request object, required to determine version and path 398 url: 399 the incomplete url where to locate the latest web2py 400 actual url is url+'/examples/static/web2py_(src|osx|win).zip' 401 402 Returns 403 ------- 404 True on success, False on failure (network problem or old version) 405 """ 406 web2py_version = request.env.web2py_version 407 gluon_parent = request.env.gluon_parent 408 if not gluon_parent.endswith('/'): 409 gluon_parent = gluon_parent + '/' 410 (check, version) = check_new_version(web2py_version, 411 url+'/examples/default/version') 412 if not check: 413 return (False, 'Already latest version') 414 if os.path.exists(os.path.join(gluon_parent, 'web2py.exe')): 415 version_type = 'win' 416 destination = gluon_parent 417 subfolder = 'web2py/' 418 elif gluon_parent.endswith('/Contents/Resources/'): 419 version_type = 'osx' 420 destination = gluon_parent[:-len('/Contents/Resources/')] 421 subfolder = 'web2py/web2py.app/' 422 else: 423 version_type = 'src' 424 destination = gluon_parent 425 subfolder = 'web2py/' 426 427 full_url = url + '/examples/static/web2py_%s.zip' % version_type 428 filename = abspath('web2py_%s_downloaded.zip' % version_type) 429 file = None 430 try: 431 file = open(filename,'wb') 432 file.write(urllib.urlopen(full_url).read()) 433 file.close() 434 except Exception,e: 435 file and file.close() 436 return False, e 437 try: 438 unzip(filename, destination, subfolder) 439 return True, None 440 except Exception,e: 441 return False, e
442
443 -def add_path_first(path):
444 sys.path = [path]+[p for p in sys.path if (not p==path and not p==(path+'/'))]
445
446 -def create_missing_folders():
447 if not global_settings.web2py_runtime_gae: 448 for path in ('applications', 'deposit', 'site-packages', 'logs'): 449 path = abspath(path, gluon=True) 450 if not os.path.exists(path): 451 os.mkdir(path) 452 paths = (global_settings.gluon_parent, abspath('site-packages', gluon=True), abspath('gluon', gluon=True), '') 453 [add_path_first(path) for path in paths]
454
455 -def create_missing_app_folders(request):
456 if not global_settings.web2py_runtime_gae: 457 if request.folder not in global_settings.app_folders: 458 for subfolder in ('models', 'views', 'controllers', 'databases', 459 'modules', 'cron', 'errors', 'sessions', 460 'languages', 'static', 'private', 'uploads'): 461 path = os.path.join(request.folder, subfolder) 462 if not os.path.exists(path): 463 os.mkdir(path) 464 global_settings.app_folders.add(request.folder)
465