Thanks for the response, Richard. Would you please delete most of the gory detail in your previous response in p6 as I did. It makes it difficult to load the page.
In answer to your question, I could not run Welcome when i did the original update AND i cannot run Welcome now. Thanks again Richard. Love and peace, Joe On Monday, July 27, 2015 at 1:05:30 PM UTC-7, Richard wrote: > > It seems that it complain about git not up to date... > > Richard > > On Mon, Jul 27, 2015 at 4:04 PM, Richard Vézina <ml.richa...@gmail.com > <javascript:>> wrote: > > Did the update was succesful? > > Can you run Welcome... > > Your ticket traceback is not really friendly to analyse... > > :) > > Richard > > On Mon, Jul 27, 2015 at 3:59 PM, JoeCodeswell <joecod...@gmail.com > <javascript:>> wrote: > > > Dear web2py-users, > > On WebFaction, I just tried TWICE to update web2py stable FROM 2.9.12 TO > 2.11.2. > > Here's my scrubbed update commands. > > [usr@srvr bin]$ cd /THEPATH/apache2/bin > [usr@srvr bin]$ ./stop > [usr@srvr bin]$ cd /THEPATH > [usr@srvr DIRX]$ rm web2py_src.zip > [jdor@web396 DIRX]$ wget -q http:// > www.web2py.com/examples/static/web2py_src.zip > [jdor@web396 DIRX]$ unzip -q web2py_src.zip > replace web2py/web2py.py? [y]es, [n]o, [A]ll, [N]one, [r]ename: A > [jdor@web396 DIRX]$ cd /THEPATH/apache2/bin > [jdor@web396 bin]$ ./start > [jdor@web396 bin]$ > > RESULT Internal error Ticket issued: > admin/50.131.104.50.2015-07-27.18-04-23.6cbc7a3f-91c9-4f0c-...... > Here's a scrubbed partial listing. > > (dp1 > S'output' > p2 > S"<type 'exceptions.AttributeError'> type object 'DAL' has no attribute > 'Field'" > p3 > sS'layer' > p4 > S'/THEPATH/web2py/applications/admin/controllers/default.py' > p5 > sS'code' > p6 > S'# -*- coding: utf-8 -*-\n\nEXPERIMENTAL_STUFF = True\nMAXNFILES = > 1000\n\nif EXPERIMENTAL_STUFF:\n if is_mobile:\n response.view = > response.view.replace(\'default/\', \'default.mobile/\')\n > response.menu = []\n\nimport re\nfrom gluon.admin import *\nfrom > gluon.fileutils import abspath, read_file, write_file\nfrom gluon.utils > import web2py_uuid\nfrom gluon.tools import Config\nfrom gluon.compileapp > import find_exposed_functions\nfrom glob import glob\nimport shutil\nimport > platform\n\ntry:\n import git\n if git.__version__ < \'0.3.1\':\n > raise ImportError("Your version of git is %s. Upgrade to 0.3.1 or > better." % git.__version__)\n have_git = True\nexcept ImportError, e:\n > have_git = False\n GIT_MISSING = \'Requires gitpython module, but not > installed or incompatible version: %s\' % e\n\nfrom gluon.languages import > (read_possible_languages, read_dict, write_dict,\n > read_plural_dict, write_plural_dict)\n\n\nif DEMO_MODE and > request.function in [\'change_password\', > \'pack\',\n\'pack_custom\',\'pack_plugin\', \'upgrade_web2py\', > \'uninstall\',\n\'cleanup\', \'compile_app\', \'remove_compiled_app\', > \'delete\',\n\'delete_plugin\', \'create_file\', \'upload_file\', > \'update_languages\',\n\'reload_routes\', \'git_push\', \'git_pull\', > \'install_plugin\']:\n session.flash = T(\'disabled in demo mode\')\n > redirect(URL(\'site\'))\n\nif is_gae and request.function in (\'edit\', > \'edit_language\',\n\'edit_plurals\', \'update_languages\', > \'create_file\', \'install_plugin\'):\n session.flash = T(\'disabled in > GAE mode\')\n redirect(URL(\'site\'))\n\nif not is_manager() and > request.function in [\'change_password\', \'upgrade_web2py\']:\n > session.flash = T(\'disabled in multi user mode\')\n > redirect(URL(\'site\'))\n\nif FILTER_APPS and request.args(0) and not > request.args(0) in FILTER_APPS:\n session.flash = T(\'disabled in demo > mode\')\n redirect(URL(\'site\'))\n\n\nif not session.token:\n > session.token = web2py_uuid()\n\n\ndef count_lines(data):\n return > len([line for line in data.split(\'\\n\') if line.strip() and not > line.startswith(\'#\')])\n\n\ndef log_progress(app, mode=\'EDIT\', > filename=None, progress=0):\n progress_file = os.path.join(apath(app, > r=request), \'progress.log\')\n now = str(request.now)[:19]\n if not > os.path.exists(progress_file):\n safe_open(progress_file, > \'w\').write(\'[%s] START\\n\' % now)\n if filename:\n > safe_open(progress_file, \'a\').write(\n \'[%s] %s %s: %s\\n\' > % (now, mode, filename, progress))\n\n\ndef safe_open(a, b):\n if > (DEMO_MODE or is_gae) and (\'w\' in b or \'a\' in b):\n class tmp:\n > def write(self, data):\n pass\n def > close(self):\n pass\n return tmp()\n return > open(a, b)\n\n\ndef safe_read(a, b=\'r\'):\n safe_file = safe_open(a, > b)\n try:\n return safe_file.read()\n finally:\n > safe_file.close()\n\n\ndef safe_write(a, value, b=\'w\'):\n safe_file = > safe_open(a, b)\n try:\n safe_file.write(value)\n finally:\n > safe_file.close()\n\n\ndef get_app(name=None):\n app = name or > request.args(0)\n if (app and os.path.exists(apath(app, r=request)) > and\n (not MULTI_USER_MODE or is_manager() or\n db( > db.app.name == app)(db.app.owner == auth.user.id).count())):\n > return app\n session.flash = T(\'App does not exist or you are not > authorized\')\n redirect(URL(\'site\'))\n\n\ndef index():\n """ Index > handler """\n\n send = request.vars.send\n if DEMO_MODE:\n > session.authorized = True\n session.last_time = t0\n if not > send:\n send = URL(\'site\')\n if session.authorized:\n > redirect(send)\n elif request.vars.password:\n if > verify_password(request.vars.password[:1024]):\n > session.authorized = True\n login_record(True)\n\n > if CHECK_VERSION:\n session.check_version = True\n > else:\n session.check_version = False\n\n > session.last_time = t0\n if isinstance(send, list): # ## why > does this happen?\n send = str(send[0])\n\n > redirect(send)\n else:\n times_denied = > login_record(False)\n if times_denied >= > allowed_number_of_attempts:\n response.flash = \\\n > T(\'admin disabled because too many invalid login attempts\')\n > elif times_denied == allowed_number_of_attempts - 1:\n > response.flash = \\\n T(\'You have one more login > attempt before you are locked out\')\n else:\n > response.flash = T(\'invalid password.\')\n return > dict(send=send)\n\n\ndef check_version():\n """ Checks if web2py is up > to date """\n\n session.forget()\n session._unlock(response)\n\n > new_version, version = check_new_version(request.env.web2py_version,\n > WEB2PY_VERSION_URL)\n\n if > new_version == -1:\n return A(T(\'Unable to check for upgrades\'), > _href=WEB2PY_URL)\n elif new_version != True:\n return > A(T(\'web2py is up to date\'), _href=WEB2PY_URL)\n elif > platform.system().lower() in (\'windows\', \'win32\', \'win64\') and > os.path.exists("web2py.exe"):\n return SPAN(\'You should upgrade to > %s\' % version.split(\'(\')[0])\n else:\n return > sp_button(URL(\'upgrade_web2py\'), T(\'upgrade now to %s\') % > version.split(\'(\')[0])\n\n\ndef logout():\n """ Logout handler """\n > session.authorized = None\n if MULTI_USER_MODE:\n > redirect(URL(\'user/logout\'))\n redirect(URL(\'index\'))\n\n\ndef > change_password():\n\n if session.pam_user:\n session.flash = > T(\n \'PAM authenticated user, cannot change password here\')\n > redirect(URL(\'site\'))\n form = > SQLFORM.factory(Field(\'current_admin_password\', \'password\'),\n > Field(\'new_admin_password\',\n > \'password\', requires=IS_STRONG()),\n > Field(\'new_admin_password_again\', \'password\'),\n > _class="span4 well")\n if form.accepts(request.vars):\n if > not verify_password(request.vars.current_admin_password):\n > form.errors.current_admin_password = T(\'invalid password\')\n elif > form.vars.new_admin_password != form.vars.new_admin_password_again:\n > form.errors.new_admin_password_again = T(\'no match\')\n > else:\n path = abspath(\'parameters_%s.py\' % > request.env.server_port)\n safe_write(path, \'password="%s"\' % > CRYPT()(\n request.vars.new_admin_password)[0])\n > session.flash = T(\'password changed\')\n > redirect(URL(\'site\'))\n return dict(form=form)\n\n\ndef site():\n > """ Site handler """\n\n myversion = request.env.web2py_version\n\n > # Shortcut to make the elif statements more legible\n file_or_appurl = > \'file\' in request.vars or \'appurl\' in request.vars\n\n class > IS_VALID_APPNAME(object):\n def __call__(self, value):\n > if not re.compile(\'^\\w+$\').match(value):\n return > (value, T(\'Invalid application name\'))\n if not > request.vars.overwrite and \\\n > os.path.exists(os.path.join(apath(r=request), value)):\n > return (value, T(\'Application exists already\'))\n return > (value, None)\n\n is_appname = IS_VALID_APPNAME()\n form_create = > SQLFORM.factory(Field(\'name\', requires=is_appname),\n > table_name=\'appcreate\')\n form_update = > SQLFORM.factory(Field(\'name\', requires=is_appname),\n > Field(\'file\', \'upload\', uploadfield=False),\n > Field(\'url\'),\n > Field(\'overwrite\', \'boolean\'),\n > table_name=\'appupdate\')\n form_create.process()\n > form_update.process()\n\n if DEMO_MODE:\n pass\n\n elif > form_create.accepted:\n # create a new application\n appname > = cleanpath(form_create.vars.name)\n created, error = > app_create(appname, request, info=True)\n if created:\n > if MULTI_USER_MODE:\n db.app.insert(name=appname, owner= > auth.user.id)\n log_progress(appname)\n > session.flash = T(\'new application "%s" created\', appname)\n > redirect(URL(\'design\', args=appname))\n else:\n > session.flash = \\\n DIV(T(\'unable to create application > "%s"\', appname),\n PRE(error))\n > redirect(URL(r=request))\n\n elif form_update.accepted:\n if > (form_update.vars.url or \'\').endswith(\'.git\'):\n if not > have_git:\n session.flash = GIT_MISSING\n > redirect(URL(r=request))\n target = > os.path.join(apath(r=request), form_update.vars.name)\n try:\n > new_repo = git.Repo.clone_from(form_update.vars.url, > target)\n session.flash = T(\'new application "%s" > imported\',\n form_update.vars.name)\n > except git.GitCommandError, err:\n session.flash = > T(\'Invalid git repository specified.\')\n > redirect(URL(r=request))\n\n elif form_update.vars.url:\n > # fetch an application via URL or file upload\n try:\n > f = urllib.urlopen(form_update.vars.url)\n if f.code > == 404:\n raise Exception("404 file not found")\n > except Exception, e:\n session.flash = \\\n > DIV(T(\'Unable to download app because:\'), PRE(str(e)))\n > redirect(URL(r=request))\n fname = form_update.vars.url\n\n > elif form_update.accepted and form_update.vars.file:\n > fname = request.vars.file.filename\n f = > request.vars.file.file\n\n else:\n session.flash = \'No > file uploaded and no URL specified\'\n > redirect(URL(r=request))\n\n if f:\n appname = cleanpath( > form_update.vars.name)\n installed = app_install(appname, f,\n > request, fname,\n > overwrite=form_update.vars.overwrite)\n if f and > installed:\n msg = \'application %(appname)s installed with > md5sum: %(digest)s\'\n if MULTI_USER_MODE:\n > db.app.insert(name=appname, owner=auth.user.id)\n > log_progress(appname)\n session.flash = T(msg, > dict(appname=appname,\n > digest=md5_hash(installed)))\n elif f and > form_update.vars.overwrite:\n msg = \'unable to install > application "%(appname)s"\'\n session.flash = T(msg, > dict(appname=form_update.vars.name))\n else:\n msg = > \'unable to install application "%(appname)s"\'\n session.flash > = T(msg, dict(appname=form_update.vars.name))\n > redirect(URL(r=request))\n\n regex = re.compile(\'^\\w+$\')\n\n if > is_manager():\n apps = [f for f in os.listdir(apath(r=request)) if > regex.match(f)]\n else:\n apps = [f.name for f in > db(db.app.owner == auth.user_id).select()]\n\n if FILTER_APPS:\n > apps = [f for f in apps if f in FILTER_APPS]\n\n apps = sorted(apps, > lambda a, b: cmp(a.upper(), b.upper()))\n myplatform = > platform.python_version()\n return dict(app=None, apps=apps, > myversion=myversion, myplatform=myplatform,\n > form_create=form_create, form_update=form_update)\n\n\ndef > report_progress(app):\n import datetime\n progress_file = > os.path.join(apath(app, r=request), \'progress.log\')\n regex = > re.compile(\'\\[(.*?)\\][^\\:]+\\:\\s+(\\-?\\d+)\')\n if not > os.path.exists(progress_file):\n return []\n matches = > regex.findall(open(progress_file, \'r\').read())\n events, counter = [], > 0\n for m in matches:\n if not m:\n continue\n > days = -(request.now - datetime.datetime.strptime(m[0],\n > \'%Y-%m-%d %H:%M:%S\')).days\n counter += int(m[1])\n > events.append([days, counter])\n return events\n\n\ndef pack():\n > app = get_app()\n\n try:\n if len(request.args) == 1:\n > fname = \'web2py.app.%s.w2p\' % app\n filename = > app_pack(app, request, raise_ex=True)\n else:\n fname = > \'web2py.app.%s.compiled.w2p\' % app\n filename = > app_pack_compiled(app, request, raise_ex=True)\n except Exception, e:\n > filename = None\n\n if filename:\n > response.headers[\'Content-Type\'] = \'application/w2p\'\n > disposition = \'attachment; filename=%s\' % fname\n > response.headers[\'Content-Disposition\'] = disposition\n return > safe_read(filename, \'rb\')\n else:\n session.flash = > T(\'internal error: %s\', e)\n redirect(URL(\'site\'))\n\ndef > pack_plugin():\n app = get_app()\n if len(request.args) == 2:\n > fname = \'web2py.plugin.%s.w2p\' % request.args[1]\n filename = > plugin_pack(app, request.args[1], request)\n if filename:\n > response.headers[\'Content-Type\'] = \'application/w2p\'\n > disposition = \'attachment; filename=%s\' % fname\n > response.headers[\'Content-Disposition\'] = disposition\n return > safe_read(filename, \'rb\')\n else:\n session.flash = > T(\'internal error\')\n redirect(URL(\'plugin\', > args=request.args))\n\ndef pack_custom():\n app = get_app()\n base = > apath(app, r=request)\n if request.post_vars.file:\n files = > request.post_vars.file\n files = [files] if not > isinstance(files,list) else files\n fname = \'web2py.app.%s.w2p\' % > app\n try:\n filename = app_pack(app, request, > raise_ex=True, filenames=files)\n except Exception, e:\n > filename = None\n if filename:\n > response.headers[\'Content-Type\'] = \'application/w2p\'\n > disposition = \'attachment; filename=%s\' % fname\n > response.headers[\'Content-Disposition\'] = disposition\n > return safe_read(filename, \'rb\')\n else:\n > session.flash = T(\'internal error: %s\', e)\n > redirect(URL(args=request.args))\n def ignore(fs):\n return [f > for f in fs if not (\n f[:1] in \'#\' or f.endswith(\'~\') > or f.endswith(\'.bak\'))]\n files = {}\n for (r,d,f) in > os.walk(base):\n files[r] = > {\'folders\':ignore(d),\'files\':ignore(f)}\n return locals()\n\n\ndef > upgrade_web2py():\n dialog = FORM.confirm(T(\'Upgrade\'),\n > {T(\'Cancel\'): URL(\'site\')})\n if dialog.accepted:\n > (success, error) = upgrade(request)\n if success:\n > session.flash = T(\'web2py upgraded; please restart it\')\n else:\n > session.flash = T(\'unable to upgrade because "%s"\', error)\n > redirect(URL(\'site\'))\n return dict(dialog=dialog)\n\n\ndef > uninstall():\n app = get_app()\n\n dialog = > FORM.confirm(T(\'Uninstall\'),\n {T(\'Cancel\'): > URL(\'site\')})\n dialog[\'_id\'] = \'confirm_form\'\n > dialog[\'_class\'] = \'well\'\n for component in dialog.components:\n > component[\'_class\'] = \'btn\'\n\n if dialog.accepted:\n if > MULTI_USER_MODE:\n if is_manager() and db(db.app.name == > app).delete():\n pass\n elif db(db.app.name == > app)(db.app.owner == auth.user.id).delete():\n pass\n > else:\n session.flash = T(\'no permission to > uninstall "%s"\', app)\n redirect(URL(\'site\'))\n > try:\n filename = app_pack(app, request, raise_ex=True)\n > except:\n session.flash = T(\'unable to uninstall "%s"\', > app)\n else:\n if app_uninstall(app, request):\n > session.flash = T(\'application "%s" uninstalled\', app)\n > else:\n session.flash = T(\'unable to uninstall "%s"\', > app)\n redirect(URL(\'site\'))\n return dict(app=app, > dialog=dialog)\n\n\ndef cleanup():\n app = get_app()\n clean = > app_cleanup(app, request)\n if not clean:\n session.flash = > T("some files could not be removed")\n else:\n session.flash = > T(\'cache, errors and sessions cleaned\')\n\n > redirect(URL(\'site\'))\n\n\ndef compile_app():\n app = get_app()\n > c = app_compile(app, request)\n if not c:\n session.flash = > T(\'application compiled\')\n else:\n session.flash = > DIV(T(\'Cannot compile: there are errors in your app:\'),\n > CODE(c))\n redirect(URL(\'site\'))\n\n\ndef > remove_compiled_app():\n """ Remove the compiled application """\n > app = get_app()\n remove_compiled_application(apath(app, r=request))\n > session.flash = T(\'compiled application removed\')\n > redirect(URL(\'site\'))\n\n\ndef delete():\n """ Object delete handler > """\n app = get_app()\n filename = \'/\'.join(request.args)\n > sender = request.vars.sender\n\n if isinstance(sender, list): # ## fix > a problem with Vista\n sender = sender[0]\n\n dialog = > FORM.confirm(T(\'Delete\'),\n {T(\'Cancel\'): > URL(sender, anchor=request.vars.id)})\n\n if dialog.accepted:\n > try:\n full_path = apath(filename, r=request)\n > lineno = count_lines(open(full_path, \'r\').read())\n > os.unlink(full_path)\n log_progress(app, \'DELETE\', filename, > progress=-lineno)\n session.flash = T(\'file "%(filename)s" > deleted\',\n dict(filename=filename))\n > except Exception:\n session.flash = T(\'unable to delete file > "%(filename)s"\',\n dict(filename=filename))\n > redirect(URL(sender, anchor=request.vars.id2))\n return > dict(dialog=dialog, filename=filename)\n\n\ndef enable():\n app = > get_app()\n filename = os.path.join(apath(app, r=request), > \'DISABLED\')\n if is_gae:\n return SPAN(T(\'Not supported\'), > _style=\'color:yellow\')\n elif os.path.exists(filename):\n > os.unlink(filename)\n return SPAN(T(\'Disable\'), > _style=\'color:green\')\n else:\n safe_open(filename, > \'wb\').write(\'disabled: True\\ntime-disabled: %s\' % request.now)\n > return SPAN(T(\'Enable\'), _style=\'color:red\')\n\ndef peek():\n """ > Visualize object code """\n app = get_app(request.vars.app)\n > filename = \'/\'.join(request.args)\n if request.vars.app:\n > path = abspath(filename)\n else:\n path = apath(filename, > r=request)\n try:\n data = safe_read(path).replace(\'\\r\', > \'\')\n except IOError:\n session.flash = T(\'file does not > exist\')\n redirect(URL(\'site\'))\n\n extension = > filename[filename.rfind(\'.\') + 1:].lower()\n\n return dict(app=app,\n > filename=filename,\n data=data,\n > extension=extension)\n\n\ndef test():\n """ Execute controller tests > """\n app = get_app()\n if len(request.args) > 1:\n file = > request.args[1]\n else:\n file = \'.*\\.py\'\n\n controllers = > listdir(\n apath(\'%s/controllers/\' % app, r=request), file + > \'$\')\n\n return dict(app=app, controllers=controllers)\n\n\ndef > keepalive():\n return \'\'\n\n\ndef search():\n keywords = > request.vars.keywords or \'\'\n app = get_app()\n\n def > match(filename, keywords):\n filename = os.path.join(apath(app, > r=request), filename)\n if keywords in read_file(filename, > \'rb\'):\n return True\n return False\n path = > apath(request.args[0], r=request)\n files1 = glob(os.path.join(path, > \'*/*.py\'))\n files2 = glob(os.path.join(path, \'*/*.html\'))\n > files3 = glob(os.path.join(path, \'*/*/*.html\'))\n files = > [x[len(path) + 1:].replace(\n \'\\\\\', \'/\') for x in files1 + > files2 + files3 if match(x, keywords)]\n return > response.json(dict(files=files, message=T.M(\'Searching: **%s** %%{file}\', > len(files))))\n\n\ndef edit():\n """ File edit handler """\n # Load > json only if it is ajax edited...\n app = get_app(request.vars.app)\n > app_path = apath(app, r=request)\n preferences={\'theme\':\'web2py\', > \'editor\': \'default\', \'closetag\': \'true\', \'codefolding\': > \'false\', \'tabwidth\':\'4\', \'indentwithtabs\':\'false\', > \'linenumbers\':\'true\', \'highlightline\':\'true\'}\n config = > Config(os.path.join(request.folder, \'settings.cfg\'),\n > section=\'editor\', default_values={})\n > preferences.update(config.read())\n\n if not(request.ajax) and > not(is_mobile):\n # return the scaffolding, the rest will be through > ajax requests\n response.title = T(\'Editing %s\') % app\n > return response.render (\'default/edit.html\', dict(app=app, > editor_settings=preferences))\n\n # show settings tab and save > prefernces\n if \'settings\' in request.vars:\n if > request.post_vars: #save new preferences\n post_vars = > request.post_vars.items()\n # Since unchecked checkbox are not > serialized, we must set them as false by hand to store the correct > preference in the settings\n post_vars+= [(opt, \'false\') for > opt in preferences if opt not in request.post_vars ]\n if > config.save(post_vars):\n > response.headers["web2py-component-flash"] = T(\'Preferences saved > correctly\')\n else:\n > response.headers["web2py-component-flash"] = T(\'Preferences saved on > session only\')\n response.headers["web2py-component-command"] = > "update_editor(%s);$(\'a[href=#editor_settings] button.close\').click();" % > response.json(config.read())\n return\n else:\n > details = {\'realfilename\':\'settings\', \'filename\':\'settings\', > \'id\':\'editor_settings\', \'force\': False}\n > details[\'plain_html\'] = > response.render(\'default/editor_settings.html\', > {\'editor_settings\':preferences})\n return > response.json(details)\n\n """ File edit handler """\n # Load json > only if it is ajax edited...\n app = get_app(request.vars.app)\n > filename = \'/\'.join(request.args)\n realfilename = request.args[-1]\n > if request.vars.app:\n path = abspath(filename)\n else:\n > path = apath(filename, r=request)\n # Try to discover the file type\n > if filename[-3:] == \'.py\':\n filetype = \'python\'\n elif > filename[-5:] == \'.html\':\n filetype = \'html\'\n elif > filename[-5:] == \'.load\':\n filetype = \'html\'\n elif > filename[-4:] == \'.css\':\n filetype = \'css\'\n elif > filename[-3:] == \'.js\':\n filetype = \'javascript\'\n else:\n > filetype = \'html\'\n\n # ## check if file is not there\n if > (\'revert\' in request.vars) and os.path.exists(path + \'.bak\'):\n > try:\n data = safe_read(path + \'.bak\')\n data1 = > safe_read(path)\n except IOError:\n session.flash = > T(\'Invalid action\')\n if \'from_ajax\' in request.vars:\n > return response.json({\'error\': str(T(\'Invalid action\'))})\n > else:\n redirect(URL(\'site\'))\n\n > safe_write(path, data)\n file_hash = md5_hash(data)\n > saved_on = time.ctime(os.stat(path)[stat.ST_MTIME])\n > safe_write(path + \'.bak\', data1)\n response.flash = T(\'file "%s" > of %s restored\', (filename, saved_on))\n else:\n try:\n > data = safe_read(path)\n except IOError:\n > session.flash = T(\'Invalid action\')\n if \'from_ajax\' in > request.vars:\n return response.json({\'error\': > str(T(\'Invalid action\'))})\n else:\n > redirect(URL(\'site\'))\n\n lineno_old = count_lines(data)\n > file_hash = md5_hash(data)\n saved_on = > time.ctime(os.stat(path)[stat.ST_MTIME])\n\n if > request.vars.file_hash and request.vars.file_hash != file_hash:\n > session.flash = T(\'file changed on disk\')\n data = > request.vars.data.replace(\'\\r\\n\', \'\\n\').strip() + \'\\n\'\n > safe_write(path + \'.1\', data)\n if \'from_ajax\' in > request.vars:\n return response.json({\'error\': > str(T(\'file changed on disk\')),\n > \'redirect\': URL(\'resolve\',\n > args=request.args)})\n else:\n > redirect(URL(\'resolve\', args=request.args))\n elif > request.vars.data:\n safe_write(path + \'.bak\', data)\n > data = request.vars.data.replace(\'\\r\\n\', \'\\n\').strip() + > \'\\n\'\n safe_write(path, data)\n lineno_new = > count_lines(data)\n log_progress(\n app, > \'EDIT\', filename, progress=lineno_new - lineno_old)\n > file_hash = md5_hash(data)\n saved_on = > time.ctime(os.stat(path)[stat.ST_MTIME])\n response.flash = > T(\'file saved on %s\', saved_on)\n\n data_or_revert = > (request.vars.data or request.vars.revert)\n\n # Check compile errors\n > highlight = None\n if filetype == \'python\' and request.vars.data:\n > import _ast\n try:\n code = > request.vars.data.rstrip().replace(\'\\r\\n\', \'\\n\') + \'\\n\'\n > compile(code, path, "exec", _ast.PyCF_ONLY_AST)\n except > Exception, e:\n # offset calculation is only used for textarea > (start/stop)\n start = sum([len(line) + 1 for l, line\n > in enumerate(request.vars.data.split("\\n"))\n > if l < e.lineno - 1])\n if e.text and e.offset:\n > offset = e.offset - (len(e.text) - len(\n > e.text.splitlines()[-1]))\n else:\n offset = 0\n > highlight = {\'start\': start, \'end\': start +\n > offset + 1, \'lineno\': e.lineno, \'offset\': offset}\n > try:\n ex_name = e.__class__.__name__\n > except:\n ex_name = \'unknown exception!\'\n > response.flash = DIV(T(\'failed to compile file because:\'), BR(),\n > B(ex_name), \' \' + T(\'at line %s\', > e.lineno),\n offset and \' \' +\n > T(\'at char %s\', offset) or \'\',\n > PRE(str(e)))\n if data_or_revert and request.args[1] == > \'modules\':\n # Lets try to reload the modules\n try:\n > mopath = \'.\'.join(request.args[2:])[:-3]\n exec > \'import applications.%s.modules.%s\' % (\n request.args[0], > mopath)\n reload(sys.modules[\'applications.%s.modules.%s\'\n > % (request.args[0], mopath)])\n except > Exception, e:\n response.flash = DIV(\n > T(\'failed to reload module because:\'), PRE(str(e)))\n\n > edit_controller = None\n editviewlinks = None\n view_link = None\n > if filetype == \'html\' and len(request.args) >= 3:\n cfilename = > os.path.join(request.args[0], \'controllers\',\n > request.args[2] + \'.py\')\n if > os.path.exists(apath(cfilename, r=request)):\n edit_controller = > URL(\'edit\', args=[cfilename.replace(os.sep, "/")])\n view = > request.args[3].replace(\'.html\', \'\')\n view_link = > URL(request.args[0], request.args[2], view)\n elif filetype == > \'python\' and request.args[1] == \'controllers\':\n ## it\'s a > controller file.\n ## Create links to all of the associated view > files.\n app = get_app()\n viewname = > os.path.splitext(request.args[2])[0]\n viewpath = os.path.join(app, > \'views\', viewname)\n aviewpath = apath(viewpath, r=request)\n > viewlist = []\n if os.path.exists(aviewpath):\n if > os.path.isdir(aviewpath):\n viewlist = > glob(os.path.join(aviewpath, \'*.html\'))\n elif > os.path.exists(aviewpath + \'.html\'):\n > viewlist.append(aviewpath + \'.html\')\n if len(viewlist):\n > editviewlinks = []\n for v in sorted(viewlist):\n > vf = os.path.split(v)[-1]\n vargs = > "/".join([viewpath.replace(os.sep, "/"), vf])\n > editviewlinks.append(A(vf.split(".")[0],\n > _class="editor_filelink",\n > _href=URL(\'edit\', args=[vargs])))\n\n if len(request.args) > 2 and > request.args[1] == \'controllers\':\n controller = > (request.args[2])[:-3]\n functions = find_exposed_functions(data)\n > functions = functions and sorted(functions) or []\n else:\n > (controller, functions) = (None, None)\n\n if \'from_ajax\' in > request.vars:\n return response.json({\'file_hash\': file_hash, > \'saved_on\': saved_on, \'functions\': functions, \'controller\': > controller, \'application\': request.args[0], \'highlight\': highlight})\n > else:\n file_details = dict(app=request.args[0],\n > lineno=request.vars.lineno or 1,\n > editor_settings=preferences,\n filename=filename,\n > realfilename=realfilename,\n filetyp > > ... -- 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 web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.