Esempio n. 1
0
def main():
    """Run all relevant aspects of ok.py."""
    args = parse_input()

    log.setLevel(logging.DEBUG if args.debug else logging.ERROR)
    log.debug(args)

    if args.version:
        print("okpy=={}".format(client.__version__))
        exit(0)
    elif args.update:
        print("Current version: {}".format(client.__version__))
        software_update.check_version(args.server,
                                      client.__version__,
                                      client.FILE_NAME,
                                      timeout=10)
        exit(0)

    assign = None
    try:
        if args.authenticate:
            auth.authenticate(True)

        # Instantiating assignment
        assign = assignment.load_config(args.config, args)
        assign.load()

        if args.tests:
            print('Available tests:')
            for name in assign.test_map:
                print('    ' + name)
            exit(0)

        msgs = messages.Messages()
        for name, proto in assign.protocol_map.items():
            log.info('Execute {}.run()'.format(name))
            proto.run(msgs)

        msgs['timestamp'] = str(datetime.now())

    except ex.LoadingException as e:
        log.warning('Assignment could not load', exc_info=True)
        print('Error loading assignment: ' + str(e))
    except ex.OkException as e:
        log.warning('General OK exception occurred', exc_info=True)
        print('Error: ' + str(e))
    except KeyboardInterrupt:
        log.info('KeyboardInterrupt received.')
    finally:
        if not args.no_update:
            try:
                software_update.check_version(args.server, client.__version__,
                                              client.FILE_NAME)
            except KeyboardInterrupt:
                pass

        if assign:
            assign.dump_tests()
Esempio n. 2
0
def main():
    """Run all relevant aspects of ok.py."""
    args = parse_input()

    log.setLevel(logging.DEBUG if args.debug else logging.ERROR)
    log.debug(args)

    if args.version:
        print("okpy=={}".format(client.__version__))
        exit(0)
    elif args.update:
        print("Current version: {}".format(client.__version__))
        software_update.check_version(args.server, client.__version__,
                                      client.FILE_NAME, timeout=10)
        exit(0)

    assign = None
    try:
        if args.authenticate:
            auth.authenticate(True)

        # Instantiating assignment
        assign = assignment.load_config(args.config, args)
        assign.load()

        if args.tests:
            print('Available tests:')
            for name in assign.test_map:
                print('    ' + name)
            exit(0)

        msgs = messages.Messages()
        for name, proto in assign.protocol_map.items():
            log.info('Execute {}.run()'.format(name))
            proto.run(msgs)

        msgs['timestamp'] = str(datetime.now())

    except ex.LoadingException as e:
        log.warning('Assignment could not load', exc_info=True)
        print('Error loading assignment: ' + str(e))
    except ex.OkException as e:
        log.warning('General OK exception occurred', exc_info=True)
        print('Error: ' + str(e))
    except KeyboardInterrupt:
        log.info('KeyboardInterrupt received.')
    finally:
        if not args.no_update:
            try:
                software_update.check_version(args.server, client.__version__,
                                              client.FILE_NAME)
            except KeyboardInterrupt:
                pass

        if assign:
            assign.dump_tests()
Esempio n. 3
0
    def run(self, messages):
        """If the --restore flag is present, allow users to select
        a backup to restore from.
        """
        if not self.args.restore:
            return

        self.access_token = auth.authenticate(self.args.authenticate)

        print("Loading backups...")

        response = self.request("user")
        if not response:
            print("Could not connect to server.")
            return
        user = response["data"]["results"][0]
        email = user["email"][0]
        assign_id = self.get_assign_id(self.assignment.endpoint)
        backups = self.get_backups(email, assign_id)
        current_time = datetime.now()
        print("0: Cancel Restore")
        for current in range(0, len(backups)):
            backup = backups[current]
            time_diff = get_time_diff(backup["timestamp"], current_time)
            print("{0}: {1} by {2}".format(current + 1, time_diff, backup["submitter"]))
        response = input("Backup #: ")
        selection = int(response) - 1
        if selection < 0 or selection >= len(backups):
            print("Invalid option for restoring backups.")
            return
        self.restore_backup(backups[selection])
Esempio n. 4
0
    def run(self, messages):
        if self.args.local or self.args.restore:
            print("Cannot backup when running ok with --local.")
            return

        if self.args.revise:
            action = 'Revise'
        elif self.args.submit:
            action = 'Submission'
        else:
            action = 'Backup'

        message_list = self.load_unsent_messages()

        access_token = auth.authenticate(False)
        log.info('Authenticated with access token')
        log.info('Sending unsent messages')

        if not access_token:
            print("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)

        prefix = 'http' if self.args.insecure else 'https'
        base_url = '{0}://{1}'.format(prefix, self.args.server) + '/{}/{}/{}'

        if isinstance(response, dict):
            print('{action} successful for user: {email}'.format(action=action,
                        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('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()
Esempio n. 5
0
    def run(self, messages):
        """If the --restore flag is present, allow users to select
        a backup to restore from.
        """
        if not self.args.restore:
            return

        self.access_token = auth.authenticate(self.args.authenticate)

        print('Loading backups...')

        response = self.request('user')
        if not response:
            print('Could not connect to server.')
            return
        user = response['data']['results'][0]
        email = user['email'][0]
        assign_id = self.get_assign_id(self.assignment.endpoint)
        backups = self.get_backups(email, assign_id)
        current_time = datetime.now()
        print('0: Cancel Restore')
        for current in range(0, len(backups)):
            backup = backups[current]
            time_diff = get_time_diff(backup['timestamp'], current_time)
            print('{0}: {1} by {2}'.format(current + 1, time_diff,
                                           backup['submitter']))
        response = input('Backup #: ')
        selection = int(response) - 1
        if selection < 0 or selection >= len(backups):
            print("Invalid option for restoring backups.")
            return
        self.restore_backup(backups[selection])
Esempio n. 6
0
    def run(self, messages):
        if self.args.local or self.args.export or self.args.restore:
            return

        message_list = self.load_unsent_messages()
        message_list.append(messages)

        self.check_ssl()

        access_token = auth.authenticate(False)
        log.info('Authenticated with access token %s', access_token)

        response = self.send_all_messages(access_token, message_list)

        if isinstance(response, dict):
            print('Backup successful for user: '******'{0}'.format(response['data']['email']))
            if self.args.submit or self.args.backup:
                print('URL: https://ok-server.appspot.com/#/'
                      '{0}/submission/{1}'.format(response['data']['course'],
                                                  response['data']['key']))
            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)
        print()
Esempio n. 7
0
    def run(self, messages):
        return
        if self.args.local or self.args.export or self.args.restore:
            return

        message_list = self.load_unsent_messages()
        message_list.append(messages)

        self.check_ssl()

        access_token = auth.authenticate(False)
        log.info('Authenticated with access token %s', access_token)

        response = self.send_all_messages(access_token, message_list)

        if isinstance(response, dict):
            print('Backup successful for user: '******'{0}'.format(response['data']['email']))
            if self.args.submit or self.args.backup:
                print('URL: https://ok-server.appspot.com/#/'
                      '{0}/submission/{1}'.format(response['data']['course'],
                                                  response['data']['key']))
            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)
        print()
Esempio n. 8
0
 def authenticate(self, force=False, inline=False):
     if not inline:
         return auth.authenticate(self.cmd_args,
                                  endpoint=self.endpoint,
                                  force=force)
     else:
         return auth.notebook_authenticate(self.cmd_args, force=force)
Esempio n. 9
0
    def run(self, messages):
        """If the --export parameter was used, downloads all submissions
        for the current assignment from the server and then exits
        """
        if not self.args.export:
            return

        self.access_token = auth.authenticate(self.args.authenticate)
        log.info('Authenticated with access token %s', self.access_token)

        data = None
        try:
            data = pickle.load(open(EXPORT_CACHE, "rb"))
        except IOError:
            data = {
                'endpoint': self.assignment.endpoint
            }
            data['assign'], data['course'] = self.get_ids(data['endpoint'])
            data['students'] = self.get_students(data['course'])
            if not data['students']:
                return
            data['current'] = 0

        current_student = 0
        try:
            if not os.path.exists(SUBMISSION_DIR):
                os.makedirs(SUBMISSION_DIR)

            downloads_left = len(data['students']) - data['current']

            print("{0} submissions left to download.".format(downloads_left))

            for current_student in range(data['current'], len(data['students'])):
                student = data['students'][current_student]
                try:
                    self.download_submission(student, data['assign'])
                except (IOError, error.HTTPError):
                    data['current'] = current_student
                    abort(data, len(data['students']), current_student)
                    return
                data['current'] = current_student + 1

        except KeyboardInterrupt:
            pickle.dump(data, open("export_cache.pkl", "wb"))
            abort(data, len(data['students']), current_student)
            return

        print("Submissions downloaded.")
        if os.path.exists(EXPORT_CACHE):
            os.remove(EXPORT_CACHE)
Esempio n. 10
0
    def run(self, messages):
        """Responsible for unlocking each test.

        The unlocking process can be aborted by raising a KeyboardInterrupt or
        an EOFError.

        RETURNS:
        dict; mapping of test name (str) -> JSON-serializable object. It is up
        to each test to determine what information is significant for analytics.
        """
        if not self.args.unlock:
            return
        if not self.args.local:
            self.access_token = auth.authenticate(False)

        format.print_line('~')
        print('Unlocking tests')
        print()

        print('At each "{}", type what you would expect the output to be.'.
              format(self.PROMPT))
        print('Type {} to quit'.format(self.EXIT_INPUTS[0]))
        print()

        for test in self.assignment.specified_tests:
            log.info('Unlocking test {}'.format(test.name))
            self.current_test = test.name

            try:
                test.unlock(self.interact)
            except (KeyboardInterrupt, EOFError):
                try:
                    # TODO(albert): When you use Ctrl+C in Windows, it
                    # throws two exceptions, so you need to catch both
                    # of them. Find a cleaner fix for this.
                    print()
                    print('-- Exiting unlocker --')
                except (KeyboardInterrupt, EOFError):
                    pass
                print()
                break
        messages['unlock'] = self.analytics
Esempio n. 11
0
def main():
    """Run all relevant aspects of ok.py."""
    args = parse_input()
    log.setLevel(logging.DEBUG if args.debug else logging.ERROR)
    log.debug(args)

    # Checking user's Python bit version
    bit_v = (8 * struct.calcsize("P"))
    log.debug("Python {} ({}bit)".format(sys.version, bit_v))

    if args.version:
        print("okpy=={}".format(client.__version__))
        exit(0)
    elif args.update:
        print("Current version: {}".format(client.__version__))
        did_update = software_update.check_version(args.server,
                                                   client.__version__,
                                                   client.FILE_NAME,
                                                   timeout=10)
        exit(not did_update)  # exit with error if ok failed to update

    assign = None
    try:
        if args.get_token:
            if args.nointeract:
                print_error(
                    "Cannot pass in --get-token and --nointeract, the only way to get a token is by interaction"
                )
                exit(1)
            access_token = auth.authenticate(args, force=True)
            print("Token: {}".format(access_token))
            exit(not access_token)  # exit with error if no access_token

        # Instantiating assignment
        assign = assignment.load_assignment(args.config, args)

        if assign.decryption_keypage:
            # do not allow running locally if decryption keypage is provided
            args.local = False

        if args.autobackup_actual_run_sync:
            assign.autobackup(run_sync=True)
            # do not dump tests back out, this overwrites any changes that may have been made
            assign = None
            exit(0)

        if args.generate_encryption_key:
            assign.generate_encryption_key(args.generate_encryption_key)
            exit(0)

        if args.encrypt:
            assign.encrypt(args.encrypt, args.encrypt_padding)
            # do not dump tests back out, this overwrites any changes that may have been made
            assign = None
            exit(0)

        if args.decrypt is not None:
            raise ex.ForceDecryptionException(args.decrypt)

        if args.tests:
            print('Available tests:')
            for name in assign.test_map:
                print('    ' + name)
            exit(0)

        if args.autobackup:
            assign.autobackup(run_sync=False)
            exit(0)

        force_authenticate = args.authenticate
        retry = True
        while retry:
            retry = False
            if force_authenticate:
                if args.nointeract:
                    print_error(
                        "Cannot pass in --authenticate and --nointeract")
                    exit(1)
                # Authenticate and check for success
                if not assign.authenticate(force=True):
                    exit(1)

            try:
                msgs = messages.Messages()
                for name, proto in assign.protocol_map.items():
                    log.info('Execute {}.run()'.format(name))
                    proto.run(msgs)
                msgs['timestamp'] = str(datetime.now())
            except ex.AuthenticationException as e:
                if not force_authenticate:
                    force_authenticate = True
                    retry = True
                elif not args.no_browser:
                    args.no_browser = True
                    retry = True
                if retry:
                    msg = "without a browser" if args.no_browser else "with a browser"
                    log.warning(
                        'Authentication exception occurred; will retry {0}'.
                        format(msg),
                        exc_info=True)
                    print_error(
                        'Authentication error; will try to re-authenticate {0}...'
                        .format(msg))
                else:
                    raise  # outer handler will be called

    except ex.ForceDecryptionException as e:
        assign.decrypt(e.keys)
        # begin an autobackup
        assign.autobackup(run_sync=False)
        # do not dump tests back out, this could overwrite any changes that may have been made
        assign = None
        exit(0)
    except ex.LoadingException as e:
        log.warning('Assignment could not load', exc_info=True)
        print_error('Error loading assignment: ' + str(e))
    except ex.AuthenticationException as e:
        log.warning('Authentication exception occurred', exc_info=True)
        print_error('Authentication error: {0}'.format(e))
    except ex.EarlyExit as e:
        log.warning('OK exited early (non-error)')
        print_error(str(e))
    except ex.OkException as e:
        log.warning('General OK exception occurred', exc_info=True)
        print_error('Error: ' + str(e))
    except KeyboardInterrupt:
        log.info('KeyboardInterrupt received.')
    finally:
        if not args.no_update and not args.local:
            try:
                software_update.check_version(args.server, client.__version__,
                                              client.FILE_NAME)
            except KeyboardInterrupt:
                pass

        if assign:
            assign.dump_tests()
Esempio n. 12
0
def main():
    """Run all relevant aspects of ok.py."""
    args = parse_input()

    logging.basicConfig(format=LOGGING_FORMAT)
    log = logging.getLogger(__name__)
    if args.debug:
        log.setLevel(logging.INFO)
    else:
        log.setLevel(logging.ERROR)

    log.info(args)

    if args.version:
        print("okpy=={}".format(client.__version__))
        exit(0)

    if not args.local and not args.insecure:
        try:
            import ssl
        except:
            log.warning('Error importing ssl', stack_info=True)
            sys.exit("SSL Bindings are not installed. You can install python3 SSL bindings or \nrun ok locally with python3 ok --local")


    server_thread, timer_thread = None, None
    try:
        print("You are running version {0} of ok.py".format(client.__version__))

        cases = {case.type: case for case in core.get_testcases(config.cases)}
        assignment = None
        try:
            assignment = loading.load_tests(args.tests, cases)
        except exceptions.OkException as e:
            print('Error:', e)
            exit(1)

        log.info('Replacing stdout with OutputLogger')
        output_logger = sys.stdout = output.OutputLogger()

        log.info('Instantiating protocols')
        protocols = [p(args, assignment, output_logger, log)
                     for p in protocol.get_protocols(config.protocols)]

        messages = dict()
        msg_list= []

        try:
            with open(BACKUP_FILE, 'rb') as fp:
                msg_list = pickle.load(fp)
                log.info('Loaded %d backed up messages from %s',
                         len(msg_list), BACKUP_FILE)
        except (IOError, EOFError) as e:
            log.info('Error reading from ' + BACKUP_FILE \
                    + ', assume nothing backed up')

        for proto in protocols:
            log.info('Execute %s.on_start()', proto.name)
            messages[proto.name] = proto.on_start()
        messages['timestamp'] = str(datetime.now())

        interact_msg = {}

        for proto in protocols:
            log.info('Execute %s.on_interact()', proto.name)
            interact_msg[proto.name] = proto.on_interact()

        interact_msg['timestamp'] = str(datetime.now())

        # TODO(denero) Print server responses.

        if not args.local:
            msg_list.append(interact_msg)

            try:
                access_token = auth.authenticate(args.authenticate)
                log.info('Authenticated with access token %s', access_token)

                msg_list.append(messages)
                print("Attempting to send files to server...")
                network.dump_to_server(access_token, msg_list,
                        assignment['name'], args.server, args.insecure,
                        client.__version__, log, send_all=args.submit)

            except error.URLError as ex:
                log.warning('on_start messages not sent to server: %s', str(e))

            with open(BACKUP_FILE, 'wb') as fp:
                log.info('Save %d unsent messages to %s', len(msg_list),
                         BACKUP_FILE)

                pickle.dump(msg_list, fp)
                os.fsync(fp)

            if len(msg_list) == 0:
                print("Server submission successful")

    except KeyboardInterrupt:
        print("Quitting ok.")

    finally:
        if assignment:
            log.info('Dump tests for %s to %s', assignment['name'], args.tests)
            loading.dump_tests(args.tests, assignment, log)
Esempio n. 13
0
def main():
    """Run all relevant aspects of ok.py."""
    args = parse_input()

    log.setLevel(logging.DEBUG if args.debug else logging.ERROR)
    log.debug(args)

    # Checking user's Python bit version
    bit_v = (8 * struct.calcsize("P"))
    log.debug("Python {} ({}bit)".format(sys.version, bit_v))

    if args.version:
        print("okpy=={}".format(client.__version__))
        exit(0)
    elif args.update:
        print("Current version: {}".format(client.__version__))
        did_update = software_update.check_version(
                args.server, client.__version__, client.FILE_NAME, timeout=10)
        exit(not did_update)  # exit with error if ok failed to update

    assign = None
    try:
        if args.get_token:
            access_token = auth.authenticate(args, force=True)
            print("Token: {}".format(access_token))
            exit(not access_token)  # exit with error if no access_token

        # Instantiating assignment
        assign = assignment.load_assignment(args.config, args)

        if args.authenticate:
            # Authenticate and check for success
            if not assign.authenticate(force=True):
                exit(1)

        if args.tests:
            print('Available tests:')
            for name in assign.test_map:
                print('    ' + name)
            exit(0)

        msgs = messages.Messages()
        for name, proto in assign.protocol_map.items():
            log.info('Execute {}.run()'.format(name))
            proto.run(msgs)

        msgs['timestamp'] = str(datetime.now())

    except ex.LoadingException as e:
        log.warning('Assignment could not load', exc_info=True)
        print('Error loading assignment: ' + str(e))
    except ex.AuthenticationException as e:
        log.warning('Authentication exception occurred', exc_info=True)
        print('Authentication error: {0}'.format(e))
    except ex.OkException as e:
        log.warning('General OK exception occurred', exc_info=True)
        print('Error: ' + str(e))
    except KeyboardInterrupt:
        log.info('KeyboardInterrupt received.')
    finally:
        if not args.no_update and not args.local:
            try:
                software_update.check_version(args.server, client.__version__,
                                              client.FILE_NAME)
            except KeyboardInterrupt:
                pass

        if assign:
            assign.dump_tests()
Esempio n. 14
0
import sys
import os
from local_server import open_in_browser
from client.utils import auth
from client.cli.ok import parse_input
args = parse_input()
args.parsons = True
if not auth.authenticate(args):
    exit(1)
open_in_browser(args)
Esempio n. 15
0
 def authenticate(self, force=False, inline=False, nointeract=False):
     nointeract = nointeract or self.cmd_args.nointeract
     if not inline:
         return auth.authenticate(self.cmd_args, endpoint=self.endpoint, force=force, nointeract=nointeract)
     else:
         return auth.notebook_authenticate(self.cmd_args, force=force, nointeract=nointeract)
Esempio n. 16
0
 def authenticate(self, force=False, inline=False):
     if not inline:
         return auth.authenticate(self.cmd_args, endpoint=self.endpoint, force=force)
     else:
         return auth.notebook_authenticate(self.cmd_args, force=force)
Esempio n. 17
0
def main():
    """Run all relevant aspects of ok.py."""
    args = parse_input()
    log.setLevel(logging.DEBUG if args.debug else logging.ERROR)
    log.debug(args)

    # Checking user's Python bit version
    bit_v = (8 * struct.calcsize("P"))
    log.debug("Python {} ({}bit)".format(sys.version, bit_v))

    if args.version:
        print("okpy=={}".format(client.__version__))
        exit(0)
    elif args.update:
        print("Current version: {}".format(client.__version__))
        did_update = software_update.check_version(
                args.server, client.__version__, client.FILE_NAME, timeout=10)
        exit(not did_update)  # exit with error if ok failed to update

    assign = None
    try:
        if args.get_token:
            access_token = auth.authenticate(args, force=True)
            print("Token: {}".format(access_token))
            exit(not access_token)  # exit with error if no access_token

        # Instantiating assignment
        assign = assignment.load_assignment(args.config, args)

        if args.authenticate:
            # Authenticate and check for success
            if not assign.authenticate(force=True):
                exit(1)

        if args.tests:
            print('Available tests:')
            for name in assign.test_map:
                print('    ' + name)
            exit(0)

        msgs = messages.Messages()
        for name, proto in assign.protocol_map.items():
            log.info('Execute {}.run()'.format(name))
            proto.run(msgs)

        msgs['timestamp'] = str(datetime.now())

    except ex.LoadingException as e:
        log.warning('Assignment could not load', exc_info=True)
        print('Error loading assignment: ' + str(e))
    except ex.AuthenticationException as e:
        log.warning('Authentication exception occurred', exc_info=True)
        print('Authentication error: {0}'.format(e))
    except ex.EarlyExit as e:
        log.warning('OK exited early (non-error)')
        print(str(e))
    except ex.OkException as e:
        log.warning('General OK exception occurred', exc_info=True)
        print('Error: ' + str(e))
    except KeyboardInterrupt:
        log.info('KeyboardInterrupt received.')
    finally:
        if not args.no_update and not args.local:
            try:
                software_update.check_version(args.server, client.__version__,
                                              client.FILE_NAME)
            except KeyboardInterrupt:
                pass

        if assign:
            assign.dump_tests()
Esempio n. 18
0
    )
    with open('ok', 'rb') as f:
        github_asset = post_request(
            'https://uploads.github.com/repos/{}/releases/{}/assets'.format(
                GITHUB_REPO, github_release['id']),
            params={'name': 'ok'},
            headers={
                'Authorization': 'token ' + github_token,
                'Content-Type': 'application/octet-stream',
            },
            data=f,
        )

    print('Updating version on {}...'.format(OK_SERVER_URL))
    args = assignment.Settings(server=OK_SERVER_URL)
    access_token = auth.authenticate(args, force=True)
    post_request(
        'https://{}/api/v3/version/ok-client'.format(OK_SERVER_URL),
        headers={
            'Authorization': 'Bearer ' + access_token,
        },
        json={
            'current_version': new_release,
            'download_link': github_asset['browser_download_url'],
        },
    )

    print('Uploading release to PyPI...')
    shell('python setup.py sdist bdist_wheel upload')

    print()
Esempio n. 19
0
        github_asset = post_request(
            'https://uploads.github.com/repos/{}/releases/{}/assets'.format(
                GITHUB_REPO, github_release['id']),
            params={
                'name': 'ok'
            },
            headers={
                'Authorization': 'token ' + github_token,
                'Content-Type': 'application/octet-stream',
            },
            data=f,
        )

    print('Updating version on {}...'.format(OK_SERVER_URL))
    args = assignment.Settings(server=OK_SERVER_URL)
    access_token = auth.authenticate(args)
    post_request('https://{}/api/v3/version/ok-client'.format(OK_SERVER_URL),
        headers={
            'Authorization': 'Bearer ' + access_token,
        },
        json={
            'current_version': new_release,
            'download_link': github_asset['browser_download_url'],
        },
    )

    print('Uploading release to PyPI...')
    shell('python setup.py sdist bdist_wheel upload')

    print()
    print('Released okpy=={}'.format(new_release))
Esempio n. 20
0
def main():
    """Run all relevant aspects of ok.py."""
    args = parse_input()

    log.setLevel(logging.DEBUG if args.debug else logging.ERROR)
    log.debug(args)

    if args.version:
        print("okpy=={}".format(client.__version__))
        exit(0)

    # Check if ssl is available
    if not args.local and not args.insecure:
        try:
            import ssl
        except:
            log.warning('Error importing ssl', stack_info=True)
            sys.exit("SSL Bindings are not installed. You can install python3 SSL bindings or \nrun ok locally with python3 ok --local")

    # Load assignment
    try:
        assign = assignment.load_config(args.config, args)
    except (ex.LoadingException, ex.SerializeException) as e:
        print(str(e))
        exit(1)
    except KeyboardInterrupt:
        print("Quitting ok.")

    # Load backup files
    try:
        with open(BACKUP_FILE, 'rb') as fp:
            msg_list = pickle.load(fp)
            log.info('Loaded %d backed up messages from %s',
                     len(msg_list), BACKUP_FILE)
    except (IOError, EOFError) as e:
        log.info('Error reading from ' + BACKUP_FILE \
                + ', assume nothing backed up')
        msg_list = []
    except KeyboardInterrupt:
        print("Quitting ok.")

    try:
        # Run protocol.on_start
        start_messages = dict()
        for name, proto in assign.protocol_map.items():
            log.info('Execute {}.on_start()'.format(name))
            start_messages[name] = proto.on_start()
        start_messages['timestamp'] = str(datetime.now())

        # Run protocol.on_interact
        interact_msg = {}
        for name, proto in assign.protocol_map.items():
            log.info('Execute {}.on_interact()'.format(name))
            interact_msg[name] = proto.on_interact()
        interact_msg['timestamp'] = str(datetime.now())
    except KeyboardInterrupt:
        print("Quitting ok.")
    finally:
        # Running protocols is the only task that modifies the assignment, so
        # dumping is only necessary here.
        assign.dump_tests()


    # Send request to server
    try:
        # TODO(denero) Print server responses.
        if not args.local:
            msg_list.append(interact_msg)

            try:
                access_token = auth.authenticate(args.authenticate)
                log.info('Authenticated with access token %s', access_token)

                msg_list.append(start_messages)
                print("Backing up your work...")
                response = network.dump_to_server(access_token, msg_list,
                                   assign.endpoint, args.server, args.insecure,
                                   client.__version__, log, send_all=args.submit)

                if response:
                    # Hardcode course id- we need to return it from the server at some point...
                    print("Back-up successful: https://ok-server.appspot.com/#/5165212546105344/submission/{0}".format(response['data']['key']))

            except error.URLError as e:
                log.warning('on_start messages not sent to server: %s', str(e))

            with open(BACKUP_FILE, 'wb') as fp:
                log.info('Save %d unsent messages to %s', len(msg_list),
                         BACKUP_FILE)

                pickle.dump(msg_list, fp)
                os.fsync(fp)

            if len(msg_list) == 0:
                print("Server submission successful")
    except KeyboardInterrupt:
        print("Quitting ok.")
Esempio n. 21
0
    def start_firebase(self, messages):
        access_token = auth.authenticate(False)
        email = auth.get_student_email(access_token)
        identifier = auth.get_identifier(token=access_token, email=email)

        firebase = pyrebase.initialize_app(self.FIREBASE_CONFIG)
        self.fire_auth = firebase.auth()
        self.fire_db = firebase.database()

        self.user_email = email
        self.hostname = platform.node()

        data = {
            'access_token': access_token,
            'email': email,
            'identifier': identifier,
            'assignment': self.assignment.endpoint,
            'file_contents': messages.get('file_contents'),
            'analytics': messages.get('analytics'),
        }

        # Check for existing sessions first - TBD Future
        # existing_sessions = self.send_messages(data, endpoint='/collab/list')
        # response = self.prompt_for_existing_session(existing_sessions.get('sessions'))
        # if response:
        #     data['desired_session'] = response

        # Send data to collaborate server
        response_data = self.send_messages(data, self.LONG_TIMEOUT)
        if 'error' in response_data or 'session' not in response_data:
            print("There was an error while starting the session: {} Try again later"
                  .format(response_data.get('error')))
            log.warning("Error: {}".format(response_data.get('error')))
            return

        self.session_id = response_data['session']
        self.short_url = response_data['short_url']
        self.login_user = response_data.get('login_user')

        # Login as the firebase user
        email, password = response_data.get('login_user'), response_data.get('password')

        try:
            self.fire_user = self.fire_auth.sign_in_with_email_and_password(email,
                                                                            password)
            self.fire_uid = self.fire_user['localId']
        except (ValueError, KeyError) as e:
            log.warning("Could not login", exc_info=True)
            print("Could not login to the collaboration server.")
            return

        self.stream = (self.get_firebase()
                           .child('actions').stream(self.stream_listener,
                                                    self.fire_user['idToken']))

        self.presence = (self.get_firebase()
                             .child('clients').push({'computer': platform.node(),
                                                     'uid': self.fire_uid,
                                                     'owner': self.user_email,
                                                     'email': self.user_email},
                                                    self.fire_user['idToken']))

        # Parse response_url
        if response_data:
            open_url = response_data['url']
            if 'access_token' not in open_url:
                open_url = open_url + "?access_token={}".format(access_token)
            could_open = webbrowser.open_new(open_url)
            if not could_open:
                print("Could not open browser. Go to {}".format(open_url))
        else:
            log.error("There was an error with the server. Please try again later!")
            return

        print("Tell your group members or course staff to go to {}"
              .format(self.short_url))

        while True:
            data = input("[{}] Type exit to disconnect: ".format(self.short_url))
            if data.strip().lower() == 'exit':
                raise ValueError('Done with session')
Esempio n. 22
0
def main():
    """Run all relevant aspects of ok.py."""
    args = parse_input()

    log.setLevel(logging.DEBUG if args.debug else logging.ERROR)
    log.debug(args)

    if args.version:
        print("okpy=={}".format(client.__version__))
        exit(0)

    # Instantiating assignment
    try:
        assign = assignment.load_config(args.config, args)
    except ex.LoadingException as e:
        log.warning('Assignment could not instantiate', exc_info=True)
        print('Error: ' + str(e).strip())
        exit(1)

    # Load backup files
    msg_list = []
    try:
        with open(BACKUP_FILE, 'rb') as fp:
            msg_list = pickle.load(fp)
            log.info('Loaded %d backed up messages from %s',
                     len(msg_list), BACKUP_FILE)
    except (IOError, EOFError) as e:
        log.info('Error reading from ' + BACKUP_FILE \
                + ', assume nothing backed up')
    except KeyboardInterrupt:
        log.warning('Backup messages were not loaded due to KeyboardInterrupt')


    try:
        # Load tests and protocols
        assign.load()

        if args.tests:
            print('Available tests:')
            for name in assign.test_map:
                print('    ' + name)
            exit(0)

        # Run protocol.on_start
        start_messages = dict()
        for name, proto in assign.protocol_map.items():
            log.info('Execute {}.on_start()'.format(name))
            start_messages[name] = proto.on_start()
        # TODO(albert): doesn't AnalyticsProtocol store the timestamp?
        start_messages['timestamp'] = str(datetime.now())
        msg_list.append(start_messages)

        # Run protocol.on_interact
        interact_msg = {}
        for name, proto in assign.protocol_map.items():
            log.info('Execute {}.on_interact()'.format(name))
            interact_msg[name] = proto.on_interact()
        # TODO(albert): doesn't AnalyticsProtocol store the timestamp?
        interact_msg['timestamp'] = str(datetime.now())
        msg_list.append(interact_msg)
    except ex.LoadingException as e:
        log.warning('Assignment could not load', exc_info=True)
        print('Error loading assignment: ' + str(e))
    except ex.OkException as e:
        log.warning('General OK exception occurred', exc_info=True)
        print('Error: ' + str(e))
    except KeyboardInterrupt:
        log.info('Quitting protocols')
        assign.dump_tests()
    else:
        assign.dump_tests()

    if args.local:
        return

    # Send request to server
    try:
        # TODO(denero) Print server responses.

        # Check if ssl is available
        if not args.insecure:
            try:
                import ssl
            except:
                log.warning('Error importing ssl', stack_info=True)
                sys.exit("SSL Bindings are not installed. You can install python3 SSL bindings or \nrun ok locally with python3 ok --local")

        try:
            access_token = auth.authenticate(args.authenticate)
            log.info('Authenticated with access token %s', access_token)

            print("Backing up your work...")
            response = network.dump_to_server(access_token, msg_list,
                               assign.endpoint, args.server, args.insecure,
                               client.__version__, log,
                               send_all=args.submit or args.backup)

            if isinstance(response, dict):
                print("Backup successful for user: {0}".format(response['data']['email']))
                if args.submit or args.backup:
                    print("URL: https://ok-server.appspot.com/#/{0}/submission/{1}".format(response['data']['course'], response['data']['key']))
                if args.backup:
                    print('NOTE: this is only a backup. '
                          'To submit your assignment, run ok with --submit.')

            else:
                print('Unable to complete backup.')
                log.warning('network.dump_to_server returned {}'.format(response))

        except error.URLError as e:
            log.warning('on_start messages not sent to server: %s', str(e))

        with open(BACKUP_FILE, 'wb') as fp:
            log.info('Save %d unsent messages to %s', len(msg_list),
                     BACKUP_FILE)

            pickle.dump(msg_list, fp)
            os.fsync(fp)
    except KeyboardInterrupt:
        print("Quitting ok.")