def decrypt(self, keys): decrypted_files, undecrypted_files = self.attempt_decryption(keys) if not undecrypted_files + decrypted_files: print_warning("All files are already decrypted") elif undecrypted_files: if keys: print_error("Unable to decrypt some files with the keys", ", ".join(keys)) else: print_error("No keys found, could not decrypt any files") print_error(" Non-decrypted files:", *undecrypted_files)
def stream_listener(self, message): data = message.get('data') if not data: logging.info("Irrelevant message logged while listening") return action = data.get('action') sender = data.get('user') log.debug('Received new {} message from {}'.format(action, sender)) file_name = data.get('fileName') if action == "save": print("Saving {} locally (initiated by {})" .format(file_name, data.get('user'))) self.log_event('save', data) return self.save(data) elif action == "grade": print("Running tests locally (initiated by {})".format(data.get('user'))) self.log_event('grade', data) return self.run_tests(data) else: print_warning("Unknown action {}".format(action))
def run(self, messages, nointeract=False): if not self.assignment.endpoint: log.info('No assignment endpoint, skipping backup') return if self.args.local: print_warning("Cannot backup when running ok with --local.") return if not self.args.insecure: network.check_ssl() if self.args.revise: action = 'revision' elif self.args.submit: action = 'submission' else: action = 'backup' message_list = self.load_unsent_messages() access_token = self.assignment.authenticate(nointeract=nointeract) log.info('Authenticated with access token') log.info('Sending unsent messages') if not access_token: print_error( "Not authenticated. Cannot send {} to server".format(action)) self.dump_unsent_messages(message_list) return # Messages from the current backup to send first is_send_first = self.args.submit or self.args.revise subm_messages = [messages] if is_send_first else [] if is_send_first: response = self.send_all_messages(access_token, subm_messages, current=True) if message_list: self.send_all_messages(access_token, message_list, current=False) else: message_list.append(messages) response = self.send_all_messages(access_token, message_list, current=False) base_url = self.assignment.server_url + '/{}/{}/{}' if isinstance(response, dict): print_success('{action} successful for user: {email}'.format( action=action.title(), email=response['data']['email'])) submission_type = 'submissions' if self.args.submit else 'backups' url = base_url.format(response['data']['assignment'], submission_type, response['data']['key']) if self.args.submit or self.args.backup: print_success('URL: {0}'.format(url)) if self.args.backup: print('NOTE: this is only a backup. ' 'To submit your assignment, use:\n' '\tpython3 ok --submit') self.dump_unsent_messages(message_list + subm_messages) print()
def send_all_messages(self, access_token, message_list, current=False): if not self.args.insecure: ssl = network.check_ssl() else: ssl = None if current and self.args.revise: action = "Revise" elif current and self.args.submit: action = "Submit" else: action = "Backup" num_messages = len(message_list) send_all = self.args.submit or self.args.backup retries = self.RETRY_LIMIT if send_all: timeout = None stop_time = datetime.datetime.max retries = self.RETRY_LIMIT * 2 else: timeout = self.SHORT_TIMEOUT stop_time = datetime.datetime.now() + datetime.timedelta( seconds=timeout) log.info('Setting timeout to %d seconds', timeout) first_response = None error_msg = '' log.info("Sending {0} messages".format(num_messages)) while retries > 0 and message_list and datetime.datetime.now( ) < stop_time: log.info('Sending messages...%d left', len(message_list)) print('{action}... {percent}% complete'.format( action=action, percent=100 - round(len(message_list) * 100 / num_messages, 2)), end='\r') # message_list is assumed to be ordered in chronological order. # We want to send the most recent message first, and send older # messages after. message = message_list[-1] try: response = self.send_messages(access_token, message, timeout, current) except requests.exceptions.Timeout as ex: log.warning("HTTP request timeout: %s", str(ex)) retries -= 1 error_msg = 'Connection timed out after {} seconds. '.format(timeout) + \ 'Please check your network connection.' except (requests.exceptions.RequestException, requests.exceptions.BaseHTTPError) as ex: log.warning('%s: %s', ex.__class__.__name__, str(ex)) retries -= 1 if getattr(ex, 'response', None) is None: error_msg = 'Please check your network connection.' continue try: response_json = ex.response.json() except ValueError as ex: log.warning("Invalid JSON Response", exc_info=True) retries -= 1 error_msg = 'The server did not provide a valid response. Try again soon.' continue log.warning('%s error message: %s', ex.__class__.__name__, response_json['message']) if ex.response.status_code == 401: # UNAUTHORIZED (technically authorization != authentication, but oh well) raise exceptions.AuthenticationException( response_json.get( 'message')) # raise this for the caller elif ex.response.status_code == 403 and 'download_link' in response_json[ 'data']: retries = 0 error_msg = 'Aborting because OK may need to be updated.' else: retries -= 1 error_msg = response_json['message'] except Exception as ex: if ssl and isinstance(ex, ssl.CertificateError): retries = 0 log.warning("SSL Error: %s", str(ex)) error_msg = 'SSL Verification Error: {}\n'.format(ex) + \ 'Please check your network connection and SSL configuration.' else: retries -= 1 log.warning(error_msg, exc_info=True) error_msg = "Unknown Error: {}".format(ex) else: if not first_response: first_response = response message_list.pop() if current and error_msg: print() # Preserve progress bar. print_error('Could not', action.lower() + ':', error_msg) elif not message_list: print('{action}... 100% complete'.format(action=action)) due_date = self.get_due_date(access_token, timeout) if due_date is not None and action != "Revise": now = datetime.datetime.now(tz=datetime.timezone.utc) time_to_deadline = due_date - now if time_to_deadline < datetime.timedelta(0): print_error( "{action} past deadline by".format(action=action), display_timedelta(-time_to_deadline)) elif time_to_deadline < datetime.timedelta(hours=10): print_warning("Assignment is due in", display_timedelta(time_to_deadline)) return first_response elif not send_all: # Do not display any error messages if --backup or --submit are not # used. print() elif not error_msg: # No errors occurred, but could not complete request within TIMEOUT. print() # Preserve progress bar. print_error('Could not {} within {} seconds.'.format( action.lower(), timeout)) else: # If not all messages could be backed up successfully. print() # Preserve progress bar. print_error('Could not', action.lower() + ':', error_msg)