Can you comment out the part of the scheduler, the db lock file may come from there...
On Thu, Jun 16, 2016 at 12:05 PM, Marty Jones <murtin.jo...@gmail.com> wrote: > Controller logic is below. Error 1 is occuring under the "dashboard" > function. Errors 2/3 under the user function. > > # -*- coding: utf-8 -*- > # this file is released under public domain and you can use without > limitations > > > ############################################################################### > ## Launch with all settings via "sudo python run_server.py" > > ############################################################################### > > import operator # needed for manager_status variable > > response.title = 'nolabills' > > def jspage(): > link = URL('static', 'main.js') > return dict(link=link) > > def index(): > """ > For registered users, redirects to the requests page > For unregistered users, displays intro message > """ > > signup = URL(a=request.application, c='default', f='user/register') > > return dict(is_logged_in=auth.is_logged_in(), signup=signup) > > @auth.requires_membership('manager') > def manage(): > """ > This page, accessible by only managers, shows the current employees > of a company as well as any users who are registering themselves as > employees of the company. > From this page a manager can approve a pending user's membership, > as well as revoke the membership of a user on the current employee > list. > """ > pending_list = [] > approved_list = [] > if request.post_vars: > for each in request.post_vars: > key = request.post_vars.keys()[0] > underscore = key.find('_') > id = key[0:underscore] > change = key[underscore+1:len(key)] > change = None if change == "approve" else "unapproved" > # modify db accordingly > record = db(db.auth_user.id==id).select().first() > record.registration_key=change > record.update_record() > > for row in db().select(): > #for row in db(db.auth_user.company==auth.user.company).select(): > if row.registration_key: # if pending approval by manager > pending_list.append({row.id: > {"first":row.first_name,"last":row.last_name}}) > else: > manager_status = auth.has_membership('manager', row.id) > approved_list.append({row.id: > {"first":row.first_name,"last":row.last_name,"manager_status":manager_status}}) > return dict(pending_list=pending_list, approved_list=approved_list) > > @auth.requires_login() > def dashboard(): > """ > This page allows a user to send an email to > a potential customer, requesting access to bill data > """ > i = 0 > already_submitted = False # default is false; can only be changed if > request.post_vars == True > > # SQLFORM version > data_requests = > SQLFORM.grid(db(db.data_requests.company==auth.user.company), > fields=[db.data_requests.last_name, \ > db.data_requests.first_name, \ > db.data_requests.email, \ > db.data_requests.status, \ > db.data_requests.bill_1, > ], > headers={'data_requests.bill_1':'Most > Recent Bill'}, > sortable=False, > create=False, > editable=False, > deletable=True, > details=False, > maxtextlength=30, > csv=False, > upload=URL('download'), > ) > > pending_list = db().select(db.data_requests.email) > # if a new request has been made, update the database > if request.post_vars: > > while not already_submitted and i <= len(data_requests): > already_submitted = [True for row in pending_list if row.email > == request.post_vars.email] > i += 1 > > from entergy_scraper import download > from mailer import send_request > > if not already_submitted: > # generate token > import random, base64, sha > token = > base64.b64encode(sha.sha(str(random.random())).hexdigest())[:8] > db.tokens.insert(token = token, > first_name = request.post_vars.first_name, > last_name = request.post_vars.last_name, > email = request.post_vars.email, > company = auth.user.company, > ) > > # send request to user > db.scheduler_task.insert(status = 'QUEUED', > application_name = > request.application+'/default', > task_name = 'request', > group_name = 'email', > function_name = 'send_request', > args = '["{0}", "{1}", "{2}", > "{3}"]'.format( \ > request.post_vars.first, > request.post_vars.last, request.post_vars.email, token), > vars = '{}', > enabled = True, > start_time = request.now, > timeout = 500, # should take less > than 500 secs > ) > # update data_requests to show that the task is > AWAITING_CUSTOMER > db.data_requests.insert(first_name = > request.post_vars.first_name, > last_name = > request.post_vars.last_name, > email = request.post_vars.email, > company = auth.user.company, > status = 'AWAITING_CUSTOMER', > ) > > > return dict(already_submitted=already_submitted, > data_requests=data_requests, pending_list=pending_list) > > def approve_request(): > """ > Allows a customer to approve a data request > """ > submitted = 'submitted' > valid_token = 'valid_token' > invalid_token = 'invalid_token' > > > # if the user has submitted their data and it's not already in the > database, let them know we'll get their data > if request.post_vars: > status = submitted > > token_submitted = True if db(db.data_requests.email == > request.post_vars.email).select(db.tokens.submitted).first() else False > > if token_submitted == False: > # download data > db.data_requests.insert(first_name = > request.post_vars.first_name, > last_name = > request.post_vars.last_name, > email = request.post_vars.email, > company = auth.user.company, > energy_username = > request.post_vars.energy_username, > energy_password = > request.post_vars.energy_password, > ) > > # if no submission of info, try to give them the option to do so > else: > try: > status = valid_token > token = request.get_vars.token > token_row = db(db.tokens.token == token).select().first() > first_name = token_row.first_name > last_name = token_row.last_name > email = token_row.email > except: > status = invalid_token > > if status == submitted or status == invalid_token: > return dict(status=status, submitted=submitted, > invalid_token=invalid_token, token_submitted=token_submitted) > else: > return dict(status=status, first_name=first_name, > last_name=last_name, email=email, submitted=False, invalid_token=False, > token_submitted=False) > > def user(): > """ > exposes: > http://..../[app]/default/user/login > http://..../[app]/default/user/logout > http://..../[app]/default/user/register > http://..../[app]/default/user/profile > http://..../[app]/default/user/retrieve_password > http://..../[app]/default/user/change_password > http://..../[app]/default/user/bulk_register > use @auth.requires_login() > @auth.requires_membership('group name') > @auth.requires_permission('read','table name',record_id) > to decorate functions that need access control > also notice there is http://..../[app]/appadmin/manage/auth to allow > administrator to manage users > """ > return dict(form=auth()) > > @cache.action() > def download(): > """ > allows downloading of uploaded files > http://..../[app]/default/download/[filename] > """ > return response.download(request, db) > > def call(): > """ > exposes services. for example: > http://..../[app]/default/call/jsonrpc > decorate with @services.jsonrpc the functions to expose > supports xml, json, xmlrpc, jsonrpc, amfrpc, rss, csv > """ > return service() > > > > On Thursday, June 16, 2016 at 9:36:18 AM UTC-4, Marty Jones wrote: >> >> I uploaded a local application to my DigitalOcean droplet and have been >> having a nightmare of a time with the databases. I get this variety of >> errors on various pages: >> >> *Error 1:* >> >> Traceback (most recent call last): >> File "/home/murtyjones/app/gluon/restricted.py", line 227, in restricted >> exec ccode in environment >> File "/home/murtyjones/app/applications/nolabills/controllers/default.py" >> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>, >> line 230, in <module> >> File "/home/murtyjones/app/gluon/globals.py", line 417, in <lambda> >> self._caller = lambda f: f() >> File "/home/murtyjones/app/gluon/tools.py", line 4241, in f >> return action(*a, **b) >> File "/home/murtyjones/app/applications/nolabills/controllers/default.py" >> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>, >> line 73, in dashboard >> data_requests = >> SQLFORM.grid(db(db.data_requests.company==auth.user.company), >> File "/home/murtyjones/app/gluon/packages/dal/pydal/objects.py", line 91, >> in __getattr__ >> raise AttributeError >> AttributeError >> >> >> *Error 2 (trying to apply changes as a user to own profile):* >> >> Traceback (most recent call last): >> File "/home/murtyjones/app/gluon/restricted.py", line 227, in restricted >> exec ccode in environment >> File "/home/murtyjones/app/applications/nolabills/controllers/default.py" >> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>, >> line 230, in <module> >> File "/home/murtyjones/app/gluon/globals.py", line 417, in <lambda> >> self._caller = lambda f: f() >> File "/home/murtyjones/app/applications/nolabills/controllers/default.py" >> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>, >> line 211, in user >> return dict(form=auth()) >> File "/home/murtyjones/app/gluon/tools.py", line 1941, in __call__ >> return getattr(self, args[0])() >> File "/home/murtyjones/app/gluon/tools.py", line 4026, in profile >> hideerror=self.settings.hideerror): >> File "/home/murtyjones/app/gluon/sqlhtml.py", line 1744, in accepts >> self.id_field_name]).update(**fields) >> File "/home/murtyjones/app/gluon/packages/dal/pydal/objects.py", line >> 2041, in update >> ret = db._adapter.update("%s" % table._tablename, self.query, fields) >> File "/home/murtyjones/app/gluon/packages/dal/pydal/adapters/base.py", >> line 519, in update >> raise e >> OperationalError: attempt to write a readonly database >> >> >> *Error 3 (trying to logout as a user):* >> >> Traceback (most recent call last): >> File "/home/murtyjones/app/gluon/restricted.py", line 227, in restricted >> exec ccode in environment >> File "/home/murtyjones/app/applications/nolabills/controllers/default.py" >> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>, >> line 230, in <module> >> File "/home/murtyjones/app/gluon/globals.py", line 417, in <lambda> >> self._caller = lambda f: f() >> File "/home/murtyjones/app/applications/nolabills/controllers/default.py" >> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>, >> line 211, in user >> return dict(form=auth()) >> File "/home/murtyjones/app/gluon/tools.py", line 1941, in __call__ >> return getattr(self, args[0])() >> File "/home/murtyjones/app/gluon/tools.py", line 3235, in logout >> self.log_event(log, self.user) >> File "/home/murtyjones/app/gluon/tools.py", line 2530, in log_event >> self.table_event().insert(description=str(description % vars), >> origin=origin, user_id=user_id) >> File "/home/murtyjones/app/gluon/packages/dal/pydal/objects.py", line 740, >> in insert >> ret = self._db._adapter.insert(self, self._listify(fields)) >> File "/home/murtyjones/app/gluon/packages/dal/pydal/adapters/base.py", >> line 482, in insert >> raise e >> IntegrityError: FOREIGN KEY constraint failed >> >> >> *db.py* >> ## app configuration made easy. Look inside private/appconfig.ini >> from gluon.contrib.appconfig import AppConfig >> ## import current for current.db = db line >> from gluon import current >> >> ## once in production, remove reload=True to gain full speed >> myconf = AppConfig(reload=True) >> >> ## if NOT running on Google App Engine use SQLite or other DB >> db = DAL(myconf.take('db.uri'), pool_size=myconf.take('db.pool_size', >> cast=int), migrate_enabled = myconf.get('db.migrate'), >> check_reserved=['all']) >> >> ## define current.db for module usage >> current.db = db >> >> ## by default give a view/generic.extension to all actions from localhost >> ## none otherwise. a pattern can be 'controller/function.extension' >> response.generic_patterns = ['*'] if request.is_local else [] >> ## choose a style for forms >> response.formstyle = myconf.take('forms.formstyle') # or >> 'bootstrap3_stacked' or 'bootstrap2' or other >> response.form_label_separator = myconf.take('forms.separator') >> >> from gluon.tools import Auth, Service, PluginManager >> >> auth = Auth(db) >> service = Service() >> plugins = PluginManager() >> >> auth.settings.extra_fields['auth_user']= [ >> Field('company'), >> ] >> >> ## create all tables needed by auth if not custom tables >> auth.define_tables(username=False, signature=False, migrate=True, >> fake_migrate=True) >> >> ## configure email >> mail = auth.settings.mailer >> mail.settings.server = 'smtp.gmail.com' >> mail.settings.sender = 'em...@gmail.com' >> mail.settings.login = 'em...@gmail.com:password' >> >> ## configure auth policy >> auth.settings.registration_requires_verification = True >> auth.settings.registration_requires_approval = True >> auth.settings.reset_password_requires_verification = True >> >> ## after defining tables, uncomment below to enable auditing >> # auth.enable_record_versioning(db) >> >> >> ## create list of companies for which this is available >> db.define_table('company_info', >> Field('name'), >> Field('street_address'), >> ) >> >> ## create a table for the queue of not yet fulfilled data requests >> db.define_table('data_requests', >> Field('first_name'), >> Field('last_name'), >> Field('entergy_username'), >> Field('entergy_password'), >> Field('email'), >> Field('company'), >> Field('status', default='QUEUED'), >> Field('runs', 'integer', default=0), >> Field('bill_1', 'upload', uploadfield='bill_1_file'), >> Field('bill_1_file', 'blob'), >> ) >> >> >> ## create a table for generating tokens >> db.define_table('tokens', >> Field('first_name'), >> Field('last_name'), >> Field('email'), >> Field('company'), >> Field('token'), >> Field('submitted', default=False), >> ) >> >> >> >> *sql.log* >> timestamp: 2016-06-15T14:20:52.811948 >> CREATE TABLE auth_user( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> first_name CHAR(128), >> last_name CHAR(128), >> email CHAR(512), >> password CHAR(512), >> registration_key CHAR(512), >> reset_password_key CHAR(512), >> registration_id CHAR(512) >> ); >> success! >> timestamp: 2016-06-15T14:20:52.856816 >> CREATE TABLE auth_group( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> role CHAR(512), >> description TEXT >> ); >> success! >> timestamp: 2016-06-15T14:20:52.899975 >> CREATE TABLE auth_membership( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> user_id INTEGER REFERENCES auth_user (id) ON DELETE CASCADE , >> group_id INTEGER REFERENCES auth_group (id) ON DELETE CASCADE >> ); >> success! >> timestamp: 2016-06-15T14:20:53.040386 >> CREATE TABLE auth_permission( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> group_id INTEGER REFERENCES auth_group (id) ON DELETE CASCADE , >> name CHAR(512), >> table_name CHAR(512), >> record_id INTEGER >> ); >> success! >> timestamp: 2016-06-15T14:20:53.092848 >> CREATE TABLE auth_event( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> time_stamp TIMESTAMP, >> client_ip CHAR(512), >> user_id INTEGER REFERENCES auth_user (id) ON DELETE CASCADE , >> origin CHAR(512), >> description TEXT >> ); >> success! >> timestamp: 2016-06-15T14:20:53.223004 >> CREATE TABLE auth_cas( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> user_id INTEGER REFERENCES auth_user (id) ON DELETE CASCADE , >> created_on TIMESTAMP, >> service CHAR(512), >> ticket CHAR(512), >> renew CHAR(1) >> ); >> success! >> timestamp: 2016-06-15T14:22:53.166163 >> ALTER TABLE auth_user ADD company CHAR(512); >> success! >> timestamp: 2016-06-15T14:22:53.554653 >> CREATE TABLE company_info( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> name CHAR(512), >> street_address CHAR(512) >> ); >> success! >> timestamp: 2016-06-15T14:22:53.604055 >> CREATE TABLE data_requests( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> first_name CHAR(512), >> last_name CHAR(512), >> entergy_username CHAR(512), >> entergy_password CHAR(512), >> email CHAR(512), >> company CHAR(512), >> status CHAR(512), >> runs INTEGER, >> bill_1 CHAR(512), >> bill_1_file BLOB >> ); >> success! >> timestamp: 2016-06-15T14:22:53.645905 >> CREATE TABLE tokens( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> first_name CHAR(512), >> last_name CHAR(512), >> email CHAR(512), >> company CHAR(512), >> token CHAR(512), >> submitted CHAR(512) >> ); >> success! >> timestamp: 2016-06-15T14:22:56.435830 >> CREATE TABLE scheduler_task( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> application_name CHAR(512), >> task_name CHAR(512), >> group_name CHAR(512), >> status CHAR(512), >> function_name CHAR(512), >> uuid CHAR(255) UNIQUE, >> args TEXT, >> vars TEXT, >> enabled CHAR(1), >> start_time TIMESTAMP, >> next_run_time TIMESTAMP, >> stop_time TIMESTAMP, >> repeats INTEGER, >> retry_failed INTEGER, >> period INTEGER, >> prevent_drift CHAR(1), >> timeout INTEGER, >> sync_output INTEGER, >> times_run INTEGER, >> times_failed INTEGER, >> last_run_time TIMESTAMP, >> assigned_worker_name CHAR(512) >> ); >> success! >> timestamp: 2016-06-15T14:22:56.501649 >> CREATE TABLE scheduler_run( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> task_id INTEGER REFERENCES scheduler_task (id) ON DELETE CASCADE , >> status CHAR(512), >> start_time TIMESTAMP, >> stop_time TIMESTAMP, >> run_output TEXT, >> run_result TEXT, >> traceback TEXT, >> worker_name CHAR(512) >> ); >> success! >> timestamp: 2016-06-15T14:22:56.546304 >> CREATE TABLE scheduler_worker( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> worker_name CHAR(255) UNIQUE, >> first_heartbeat TIMESTAMP, >> last_heartbeat TIMESTAMP, >> status CHAR(512), >> is_ticker CHAR(1), >> group_names TEXT, >> worker_stats TEXT >> ); >> success! >> timestamp: 2016-06-15T14:22:56.589493 >> CREATE TABLE scheduler_task_deps( >> id INTEGER PRIMARY KEY AUTOINCREMENT, >> job_name CHAR(512), >> task_parent INTEGER, >> task_child INTEGER REFERENCES scheduler_task (id) ON DELETE CASCADE , >> can_visit CHAR(1) >> ); >> success! >> >> No idea where to even start with this and would appreciate help. >> >> -- > 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. > -- 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.