def checkout(project, commit): if not is_git_repo(project): raise HTTP(400) run("git stash", project) run("git checkout " + commit, project) Reloader.import_app(project)
def process(self): query = None db = self.db if not self.param.search_form and self.param.search_queries: seach_type = safe_int(request.query.get("seach_type", 0), default=0) seach_string = request.query.get("seach_string") if seach_type < len(self.param.search_queries) and seach_string: query_lambda = self.param.search_queries[seach_type][1] try: query = query_lambda(seach_string) except: pass # flash a message here if not query: query = self.param.query else: query &= self.param.query parts = self.path.split("/") self.action = parts[0] or "select" self.tablename = self.get_tablenames( self.param.query)[0] # what if there ar 2? self.record_id = safe_int(parts[1] if len(parts) > 1 else None, default=None) if self.param.fields: if not isinstance(self.param.fields, list): self.param.fields = [self.param.fields] else: table = db[self.tablename] self.param.fields = [field for field in table if field.readable] self.readonly_fields = [ field for field in self.param.fields if not field.writable ] self.referrer = None if not self.tablename: raise HTTP(400) if self.action in ["new", "details", "edit"]: # SECURITY: if the record does not exist or does not match query, than we are not allowed if self.record_id: if (db((db[self.tablename]._id == self.record_id) & self.param.query).count() == 0): redirect(self.endpoint) ## maybe flash readonly = self.action == "details" for field in self.readonly_fields: db[field.tablename][field.name].writable = False if not self.param.show_id: # if not show id, find the "id" field and set readable/writable to False for field in db[self.tablename]: if field.type == "id": db[self.tablename][field.name].readable = False db[self.tablename][field.name].writable = False self.form = Form( db[self.tablename], record=self.record_id, readonly=readonly, formstyle=self.param.formstyle, ) # SECURITY: if the new record was created but does not match filter, delete it if self.form.accepted and not self.record_id: new_record = db[self.tablename]._id == self.form.vars["id"] if db(new_record & self.param.query).count() == 0: db(new_record).delete() # TODO: SHOULD FLASH SOME MESSAGE # redirect to the referrer if self.form.accepted or (readonly and request.method == "POST"): referrer = request.query.get("_referrer") if referrer: redirect( base64.b16decode( referrer.encode("utf8")).decode("utf8")) else: redirect(self.endpoint) elif self.action == "delete": db(db[self.tablename].id == self.record_id).delete() redirect(self.endpoint) elif self.action == "select": self.referrer = "_referrer=%s" % base64.b16encode( request.url.encode("utf8")).decode("utf8") # find the primary key of the primary table pt = db[self.tablename] key_is_missing = False for field in self.param.fields: if field.table._tablename == pt._tablename and field.name == pt._id: key_is_missing = True if key_is_missing: # primary key wasn't included, add it and set show_id to False so it doesn't display self.param.fields.append(pt._id) self.param.show_id = False self.current_page_number = safe_int(request.query.get("page"), default=1) select_params = dict() # try getting sort order from the request sort_order = request.query.get("orderby", "") try: parts = sort_order.lstrip("~").split(".") orderby = db[parts[0]][parts[1]] if sort_order.startswith("~"): orderby = ~orderby select_params["orderby"] = orderby except (IndexError, KeyError, TypeError, AttributeError): select_params["orderby"] = self.param.orderby if self.param.left: select_params["left"] = self.param.left if self.param.left: # TODO: maybe this can be made more efficient self.total_number_of_rows = len( db(query).select(db[self.tablename].id, **select_params)) else: self.total_number_of_rows = db(query).count() # if at a high page number and then filter causes less records to be displayed, reset to page 1 if (self.current_page_number - 1) * self.param.rows_per_page > self.total_number_of_rows: self.current_page_number = 1 if self.total_number_of_rows > self.param.rows_per_page: self.page_start = self.param.rows_per_page * ( self.current_page_number - 1) self.page_end = self.page_start + self.param.rows_per_page select_params["limitby"] = (self.page_start, self.page_end) else: self.page_start = 0 if self.total_number_of_rows > 1: self.page_start = 1 self.page_end = self.total_number_of_rows if self.param.fields: self.rows = db(query).select(*self.param.fields, **select_params) else: self.rows = db(query).select(**select_params) self.number_of_pages = self.total_number_of_rows // self.param.rows_per_page if self.total_number_of_rows % self.param.rows_per_page > 0: self.number_of_pages += 1 else: redirect(self.endpoint)
def __init__( self, table, record=None, readonly=False, deletable=True, noncreate=True, formstyle=FormStyleDefault, dbio=True, keep_values=False, form_name=None, hidden=None, validation=None, csrf_session=None, csrf_protection=True, lifespan=None, signing_info=None, submit_value="Submit", show_id=True, **kwargs ): self.param = Param( formstyle=formstyle, hidden=hidden, submit_value=submit_value, sidecar=[], ) if isinstance(table, list): dbio = False # Mimic a table from a list of fields without calling define_table form_name = form_name or "none" for field in table: field.tablename = getattr(field, "tablename", form_name) if isinstance(record, (int, str)): record_id = int(str(record)) self.record = table[record_id] if not self.record: raise HTTP(404) else: self.record = record # computed from input and not changed self.table = table self.deletable = self.record and deletable and not readonly self.dbio = dbio self.keep_values = True if keep_values or self.record else False self.form_name = form_name or table._tablename self.csrf_session = csrf_session self.signing_info = signing_info self.validation = validation self.lifespan = lifespan self.csrf_protection = csrf_protection self.show_id = show_id # initialized and can change self.vars = {} self.errors = {} self.readonly = readonly self.noncreate = noncreate self.submitted = False self.deleted = False self.accepted = False self.formkey = None self.cached_helper = None self.action = None self.kwargs = kwargs if kwargs else {} if self.record: self.vars = self._read_vars_from_record(table) if not readonly and request.method != "GET": post_vars = request.POST form_vars = copy.deepcopy(request.forms) for k in form_vars: self.vars[k] = form_vars[k] self.submitted = True process = False # We only a process a form if it is POST and the formkey matches (correct formname and crsf) # Notice: we never expose the crsf uuid, we only use to sign the form uuid if request.method == "POST": if not self.csrf_protection or self._verify_form(post_vars): process = True if process: record_id = self.record and self.record.get("id") if not post_vars.get("_delete"): validated_vars = {} uploaded_files = [] for field in self.table: if field.writable and field.type != "id": original_value = post_vars.get(field.name) if isinstance(original_value, list): if len(original_value) == 1: original_value = original_value[0] elif len(original_value) == 0: original_value = None if field.type.startswith("list:") and isinstance( original_value, str ): try: original_value = json.loads(original_value or "[]") except json.decoder.JSONDecodeError: # this happens if posting a single value pass (value, error) = field.validate(original_value, record_id) if field.type == "password" and record_id and value is None: continue if field.type == "upload": value = request.files.get(field.name) print(str(value)[:100]) delete = post_vars.get("_delete_" + field.name) if value is not None: if field.uploadfolder: uploaded_files.append(tuple((field, value))) validated_vars[field.name] = value elif self.record: if not delete: validated_vars[field.name] = self.record.get( field.name ) else: validated_vars[field.name] = value = None elif field.type == "boolean": validated_vars[field.name] = value is not None else: validated_vars[field.name] = value if error: self.errors[field.name] = error self.vars.update(validated_vars) if validation: validation(self) if self.record and dbio: self.vars["id"] = self.record.id if not self.errors: for file in uploaded_files: field, value = file value = field.store( value.file, value.filename, field.uploadfolder ) if value is not None: validated_vars[field.name] = value self.accepted = True self.vars.update(validated_vars) if dbio: self.update_or_insert(validated_vars) elif dbio: self.deleted = True self.record.delete_record() elif self.record: # This form should not be processed. We return the same as for GET. self.vars = self._read_vars_from_record(table) if self.csrf_protection: self._sign_form()
def page_with_raise(): raise HTTP(400, "oops")