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