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