def create(self): if not self.ids['cbox'].active and self.ids['pwd'].text != self.ids[ 'rpwd'].text: self.highlight_textinput(self.ids['pwd']) self.highlight_textinput(self.ids['rpwd']) return if ':' in self.ids['username'].text: ErrorPopup(message='Username contains ":"') self.highlight_textinput(self.ids['username']) return elif ':' in self.ids['pwd'].text: ErrorPopup(message='Password contains ":"') self.highlight_textinput(self.ids['pwd']) return if self.ids['cbox'].active: self.ids['pwd'].text = ''.join( choices(list(alphanumeric_chars), k=10)) data = { 'permissions': titles_perm[self.ids['title'].text] % self.ids['username'].text } data[ 'fullname'] = self.ids['fname'].text + ' ' + self.ids['lname'].text data['email'] = self.ids['email'].text data['username'] = self.ids['username'].text data['title'] = self.ids['title'].text data['password'] = tokenize(self.ids['pwd'].text) url = urlTo('accounts') AsyncRequest(url, method='POST', data=data, on_success=self.success)
def reset(self): if not self.ids['cbox'].active and self.ids['pwd'].text != self.ids[ 'rpwd'].text: self.highlight_textinput(self.ids['pwd']) self.highlight_textinput(self.ids['rpwd']) return if ':' in self.ids['pwd'].text: ErrorPopup(message='Password contains ":"') self.highlight_textinput(self.ids['pwd']) return if self.ids['cbox'].active: self.ids['pwd'].text = ''.join( choices(list(alphanumeric_chars), k=10)) username = self.ids['username'].text self.selected_acct = self.get_user(username) if not self.selected_acct: ErrorPopup(username + ' not found') return self.selected_acct['password'] = tokenize(self.ids['pwd'].text) url = urlTo('accounts') params = {'superuser': True} if root.sm.is_admin else None AsyncRequest(url, method='PATCH', data=self.selected_acct, params=params, on_success=self.success)
def run(self): Window.set_system_cursor('wait') # update last_request_timestamp to track activity session_timer(self.url, self.params) try: if self.method == 'GET': self.resp = requests.get( self.url, headers=self.headers, params=self.params) elif self.method == 'POST': self.resp = requests.post( self.url, headers=self.headers, json=self.data, params=self.params) elif self.method == 'PUT': self.resp = requests.put( self.url, headers=self.headers, json=self.data, params=self.params) elif self.method == 'PATCH': self.resp = requests.patch( self.url, headers=self.headers, json=self.data, params=self.params) elif self.method == 'DELETE': self.resp = requests.delete( self.url, headers=self.headers, params=self.params) else: raise ValueError( '"method" arguement must be one of "GET", "POST", "PUT" or "DELETE"') self.resp.raise_for_status() except requests.exceptions.ConnectionError: msg = 'Server down' ErrorPopup(msg) # Restart server except requests.exceptions.HTTPError as err: if self.resp.status_code == 440: YesNoPopup(message='Session expired, login again?', on_yes=draw_sign_in_popup, title='Session Timeout') elif callable(self.on_failure): self.on_failure(self.resp) else: try: err_resp = self.resp.json() title = err_resp['title'] msg = err_resp['detail'] except json.decoder.JSONDecodeError: err = str(err) title = err[:err.find(":")] msg = err[err.find(":") + 1:].strip() except TypeError: title = 'Error' msg = self.resp.json() ErrorPopup(msg, title=title) else: if callable(self.on_success): self.on_success(self.resp) Window.set_system_cursor('arrow')
def update(self): if not self.ids['password'].text: ErrorPopup('Password field can\'t be empty') return if ':' in self.ids['password'].text: ErrorPopup('Password contains ":"') return self.data['password'] = tokenize(self.ids['password'].text) self.data['email'] = self.ids['email'].text url = urlTo('accounts') AsyncRequest(url, data=self.data, method='PATCH', on_success=self.update_success)
def show_error(self, resp): try: msg = resp.json() except json.decoder.JSONDecodeError: msg = 'Something went wrong' msg = msg['detail'] if 'detail' in msg else msg ErrorPopup(msg)
def show_error(self, resp): try: msg = resp.json() except: msg = 'Something went wrong' msg = msg['details'] if 'details' in msg else msg ErrorPopup(msg)
def load_data(self): data_for_widget = [] for index, row in enumerate(self._data): if len(row) != self.cols: ErrorPopup('Error parsing data') for col_num, col in enumerate(row): halign = 'center' padding = [0, 0] if bool(self.weightings): width = self.width * self.weightings[col_num] if self.weightings[col_num] >= 0.35: halign = 'left' padding = [sp(20), 0] else: width = self.widths[col_num] prop = { 'index': index, 'col_num': col_num, 'text': str(col), 'width': width, 'root': self } if self.rv.viewclass == 'DataViewerLabel': prop.update({'halign': halign, 'padding': padding}) for attr, val in self.prop.items(): if isinstance(val, list) and len(val) == self.cols: prop[attr] = val[col_num] else: prop[attr] = val data_for_widget.append(prop) return data_for_widget
def update_callback(self, resp): if resp.text: err_msg = '\n'.join(resp.json()) ErrorPopup(err_msg, title='Alert') else: msg = 'Update successful' SuccessPopup(msg) self.refresh()
def search(self): url = urlTo('results_stats_multiple') if self.validate_inputs(): session = int(self.ids['session'].text) level = int(self.ids['level'].text) self.query_params = {'acad_session': session, 'level': level} AsyncRequest(url, params=self.query_params, on_success=self.populate_fields) else: ErrorPopup('Fields can\'t be empty')
def search(self, *args): course_code = self.ids['code'].text if not course_code: ErrorPopup('Input can\'t be empty') return course_code = course_code[:3].upper() + course_code[3:] params = {'course_code': course_code} url = urlTo('course_details') AsyncRequest(url, params=params, on_success=self.populate_fields, on_failure=self.show_error)
def search(self, *args): url = urlTo('senate_version') try: acad_session = int(self.ids['acad_session'].text) level = int(self.ids['level'].text) except ValueError: ErrorPopup('Field cannot be empty') return params = {'acad_session': acad_session, 'level': level} AsyncRequest(url, params=params, on_success=self.generate_senate_version)
def register_courses(self): if not self.data: ErrorPopup('Registration error') return if not self.validate_inputs: ErrorPopup('Fees status field is empty') return self.data['fees_status'] = int(self.ids['fees_stat'].text == 'Paid') courses = { 'first_sem': self.first_sem_view.get_courses_for_reg(), 'second_sem': self.second_sem_view.get_courses_for_reg() } self.data['courses'] = courses url = urlTo('course_reg') params = {'superuser': True} if root.sm.is_admin else None AsyncRequest(url, data=self.data, params=params, method='POST', on_failure=self.show_reg_error, on_success=self.resp_on_success)
def search(self, *args): url = urlTo('broad_sheet') try: acad_session = int(self.ids['acad_session'].text) level = int(self.ids['level'].text) raw_score = self.ids['raw_score'].text == 'Yes' semester = self.ids['semester'].text == 'First Only' except ValueError: ErrorPopup('Field cannot be empty') return params = {'acad_session': acad_session, 'level': level, 'first_sem_only': semester, 'raw_score': raw_score} AsyncRequest(url, params=params, on_success=self.generate_broadsheet, on_failure=self.show_error)
def show_response(self, resp): resp = resp.json() if resp: _, err_msgs = zip(*resp) err_msgs = list(err_msgs) for idx in range(len(err_msgs)): trim_start = err_msgs[idx].find(' at index') trim_end = err_msgs[idx].find(';') if trim_start >= 0 and trim_end >= 0: err_msgs[idx] = err_msgs[idx][:trim_start] + err_msgs[idx][ trim_end:] err_msg = '\n'.join(err_msgs) ErrorPopup(err_msg, title='Alert')
def submit(self): if not self.validate_inputs(): ErrorPopup('Invalid field supplied') return if self.ids['pwd'].text != self.ids['rpwd'].text: self.highlight_textinput(self.ids['pwd']) self.highlight_textinput(self.ids['rpwd']) return if ':' in self.ids['username'].text: ErrorPopup(message='Username contains ":"') self.highlight_textinput(self.ids['username']) return if ':' in self.ids['pwd'].text: ErrorPopup(message='Password contains ":"') self.highlight_textinput(self.ids['pwd']) return data = { 'fullname': self.ids['fname'].text + ' ' + self.ids['lname'].text, 'email': self.ids['email'].text, 'username': self.ids['username'].text, 'password': tokenize(self.ids['pwd'].text) } AuthenticationPopup(data=data).open()
def upload(self, *args): url = urlTo('results') dv = self.edv.get_dataviewer() list_of_results = dv.get_data() self._strip_data(list_of_results) idx, is_valid = self.validate_data(list_of_results) if is_valid: params = {'superuser': True} if (root.sm.is_admin == 1) else None data = { 'level': get_assigned_level(), 'is_admin': root.sm.is_admin, 'list_of_results': list_of_results } AsyncRequest(url, data=data, params=params, method='POST', on_success=self.show_response) else: if idx != '': ErrorPopup('Error parsing results at index ' + str(idx + 1)) else: ErrorPopup('Error parsing results. Check your input')
def _delete_course_reg(self): if not self.data: ErrorPopup('Delete error') return params = { 'mat_no': self.data['mat_no'], 'acad_session': self.data['course_reg_session'], 'superuser': True if root.sm.is_admin else None } url = urlTo('course_reg') AsyncRequest(url, params=params, method='DELETE', on_failure=self.show_error, on_success=self.clear_fields)
def print_pdf(self): cwd = os.getcwd() os.chdir(os.path.expanduser('~')) try: if sys.platform == 'win32': os.startfile(self.filepath) # try: # os.startfile(self.filepath, 'print') # except OSError: # os.startfile(self.filepath) else: subprocess.run(['xdg-open', self.filepath]) except: ErrorPopup(f'Error trying to print {self.filepath}\nOS currently not supported') os.chdir(cwd)
def generate_course_form(self): url = urlTo('course_form') try: params = { 'mat_no': self.ids['mat_no'].text, 'session': int(self.ids['reg_session'].text), 'to_print': True } except ValueError: ErrorPopup('Fields cannot be empty') return AsyncRequest(url, params=params, method='GET', on_success=self.print_course_form)
def remove(self): course_code = self.ids['code'].text for course in self.course_details: if course['code'] == course_code: self.course_code = course_code break else: msg = '{} not found'.format(self.ids['code'].text) ErrorPopup(message=msg) return self.action = ['disable', 'delete'][self.ids['delete'].text == 'Yes'] if self.action == 'delete': YesNoPopup(f'Are you sure you want to Permanently delete {course_code}?', on_yes=self._remove) else: self._remove()
def parse_xl(self, parse_sequence): try: data = [] sheets = self.xl_workbook.sheets() for idx in range(len(parse_sequence)): if parse_sequence[idx]: data.extend( parse_xl_sheet(sheets[idx], *parse_xl_header(sheets[idx]))) if len(self.edv.data) == 1 and self.edv.data[0] == [''] * 4: self.edv.data = data else: self.edv.data.extend(data) except ValueError: ErrorPopup('Error parsing {}'.format( os.path.basename(self.xl_workbook.filepath))) self.xl_workbook = None
def paste(self): str_list = Clipboard.paste().split(os.linesep) data, count = [], 0 for row in str_list: if row == '': continue count += 1 row_data = row.split('\t') if len(row_data) != self.cols: ErrorPopup( f'Error parsing text on line {count}. Make sure each cell in the text is separated by tabs' ) return data.append(row_data) if len(self._data) == 1 and self._data[0] == [''] * self.cols: self._data = data else: self._data.extend(data)
def parse_txt(self, dialog): try: str_list = dialog.load_file().split('\n') data, str_len = [], len(str_list) for idx in range(str_len): row = str_list[idx] _row = row.split('\t') if len(_row) != 4 and idx != str_len - 1: raise ValueError data.append(_row) if data[-1] == ['']: data.pop() if len(self.edv.data) == 1 and self.edv.data[0] == [''] * 4: self.edv.data = data else: self.edv.data.extend(data) except ValueError: ErrorPopup('Error parsing {}'.format(dialog.file_name))
def add(self): try: data = {} for key in keys[:-3]: data[key] = self.ids[key].text data['credit'] = int(data['credit']) data['semester'] = [1, 2][data['semester'].strip().lower() == 'second'] data['level'] = int(self.ids['level'].text) data['start_date'] = get_current_session() + 1 data['end_date'] = 2999 optional = self.ids['opt_yes'].active data['options'] = [0, data['semester']][optional] data['code'] = data['code'].upper() data['teaching_dept'] = data['teaching_dept'].upper() url = urlTo('course_details') AsyncRequest(url, method='POST', data=data, on_success=self.success) except: ErrorPopup('Fields cannot be empty')
def session_timer(url, params): global last_request_timestamp, logged_in curr_timestamp = datetime.now().timestamp() if last_request_timestamp and curr_timestamp - last_request_timestamp > ALLOWABLE_IDLE_TIME: if url not in [urlTo('logout'), urlTo('login')] and logged_in: # if the request is logout or login, the let it pass # else logout silently try: requests.post( url=urlTo('logout'), headers={'Content-type': 'application/json', 'token': get_token()}, json={'token': get_token()} ) logged_in = False except requests.exceptions.ConnectionError: ErrorPopup('Server down') elif url == urlTo('login'): logged_in = True # don't update last_request_timestamp if logs is called w/o filters (from main menu) log_filter_params = ['time', 'operation', 'reverse'] if url != urlTo('logs') or any(map(lambda param: param in params, log_filter_params)): last_request_timestamp = curr_timestamp
def update_courses(self): url = urlTo('course_details') diffs = self.compute_diff() if not diffs: ErrorPopup(message='Nothing to update') return data = [] for row in diffs: course = {} for idx in range(len(row) - 3): course[keys[idx]] = row[idx] course['credit'] = int(course['credit']) course['semester'] = [1, 2][course['semester'].strip().lower() == 'second'] course['level'] = int(self.ids['lvl_spinner'].text[:3]) course['start_date'] = row[keys.index('start_date')] course['end_date'] = 2999 if not row[keys.index('end_date')] else row[keys.index('end_date')] course['options'] = [0, course['semester']][row[keys.index('options')] == 'Yes'] course['code'] = course['code'].upper() course['teaching_dept'] = course['teaching_dept'].upper() data.append(course) AsyncRequest(url, method='PUT', data=data, on_success=self.update_callback)
def show_input_error(self): ErrorPopup('Some input fields are missing')
def show_add_error(self, resp): resp = '' if not resp.text else resp.json() ErrorPopup('Record could not be added: ' + str(resp))
def show_error(self, resp): if resp.status_code == 500: ErrorPopup('Something went wrong') return resp = '' if not resp.text else resp.json() ErrorPopup('Record not found: ' + resp)
def show_error(self, resp): try: msg = resp.json() except json.decoder.JSONDecodeError: msg = 'Something went wrong' ErrorPopup(msg)