def add_filters(cls, url, filters): """add_filters adds dict values (filters) to url as query parameters :param url: base URL for the request :param filters: dict with var:val pairs to add as parameters to URL :returns: url string """ return url + "?" + parse(filters)
def _to_python(self, value, state): try: return parse(value) except (ValueError, TypeError): if self.if_invalid != formencode.api.NoDefault: return self.if_invalid else: raise
def get_context(self): aux = self.block_course_id course_key = CourseKey.from_string(aux) context = {'xblock': self} if self.show_staff_grading_interface(): context['is_course_staff'] = True else: context['id_form'] = self.idform context['is_course_staff'] = False context['timify'] = False context["expired"] = False context["score"] = "None" user_id = self.scope_ids.user_id id_form = self.idform if self.is_past_due(): context["expired"] = True state = self.get_link(user_id) if len(state) > 0: context["score"] = state['score'] return context if id_form != "": connectsid, apiKey = self.get_api_token() if connectsid is False: return context student_module = self.get_or_create_student_module(user_id) state = json.loads(student_module.state) if len(state) == 0: context = self.create_link(context, connectsid, apiKey, student_module, state) elif state["id_form"] == id_form: from dateutil.parser import parse context['done'] = self.get_done(state['id_link'], connectsid, apiKey) context['timify'] = True context[ 'link'] = "https://quilgo.com/link/" + state['link'] context['name_link'] = state['name_link'] context['id_form'] = id_form context['score'] = state['score'] expired_date = self.expired_date() if state[ 'expired'] is not None and expired_date is not None: context['late'] = parse( state['expired']) > expired_date else: context['late'] = "Sin Registros" else: context = self.create_link(context, connectsid, apiKey, student_module, state) return context
def test_url_is_set(self): """ Tests that URL is provided with token for OAuth """ pump = WebPump(self.client) self.assertOk(pump.url) url = parse(pump.url) query = parse.parse_qs(url.query) self.assertEqual(url.netloc, "somewhere.com") self.assertEqual(url.path, "/oauth/authorize") self.assertTrue("token" in query) self.assertEqual(pump.get_registration()[0], query["token"])
def __deserialize_date(self, string): """Deserializes string to date. :param string: str. :return: date. """ try: from dateutil.parser import parse return parse(string).date() except ImportError: return string except ValueError: raise rest.ApiException( status=0, reason="Failed to parse `{0}` as date object".format(string) )
def main(): """Setup parameters for the test and call the test function This is a very simple interface with fixed cli arguments. If there are no arguments it defaults to a standard internal set of arguments """ if len(sys.argv) < 7: print("Requires fixed set of arguments or defaults to internally\n " "defined arguments.\n" "Usage: %s <url> <username> <password> <indication-count>" \ "Where: <url> server url, ex. http://localhost\n" \ " <port> http listener port, ex. 5000\n" \ " <username> username for authentication\n" \ " <password> password for authentication\n" \ " <indication-count> Number of indications to request.\n" \ " <repeat_loop> Repeat the send test repeat_loop times.\n" "Ex: %s http://fred 5000 blah blah 1000 10 " \ % (sys.argv[0], sys.argv[0])) server_url = 'http://localhost' username = '******' password = '******' http_listener_port = 5000 requested_indications = 1000 repeat_loop = 1 else: server_url = sys.argv[1] http_listener_port = int(sys.argv[2]) username = sys.argv[3] password = sys.argv[4] requested_indications = int(sys.argv[5]) repeat_loop = int(sys.argv[6]) listener_addr = urllib.parse(server_url).netloc print('url=%s listener=%s port=%s usr=%s pw=%s cnt=%s repeat=%s' % \ (server_url, listener_addr, http_listener_port, \ username, password, requested_indications, repeat_loop)) #https_listener_port = http_listener_port + 1 https_listener_port = None run_test(server_url, listener_addr, username, password, http_listener_port, https_listener_port, requested_indications, repeat_loop) return 0
def __deserialize_datatime(self, string): """Deserializes string to datetime. The string should be in iso8601 datetime format. :param string: str. :return: datetime. """ try: from dateutil.parser import parse return parse(string) except ImportError: return string except ValueError: raise rest.ApiException( status=0, reason=( "Failed to parse `{0}` as datetime object" .format(string) ) )
def setup_ssh(config, secrets): def iter_lines_clean(blob): for line in blob.splitlines(): if not line or line.startswith("#"): continue else: yield line try: create_at = config.ssh.create_at except AttributeError: create_at = None if not create_at: return try: os.makedirs(create_at) except OSError as e: if e.errno == errno.EEXIST: if not os.path.isdir(create_at): raise else: raise try: ssh_conf = config.ssh.config except AttributeError: ssh_conf = None if ssh_conf: ssh_conf_path = os.path.join(create_at, "config") with open(ssh_conf_path, 'wb') as fh: fh.write(ssh_conf) os.chmod(ssh_conf_path, 0o600) try: ssh_priv = config.ssh.private_key except AttributeError: ssh_priv = None if ssh_priv: ssh_priv_path = os.path.join(create_at, "id_rsa") with open(ssh_priv_path, 'wb') as fh: fh.write(ssh_priv) os.chmod(ssh_priv_path, 0o600) try: ssh_pub = config.ssh.public_key except AttributeError: ssh_pub = None if ssh_pub: ssh_pub_path = os.path.join(create_at, "id_rsa.pub") with open(ssh_pub_path, 'wb') as fh: fh.write(ssh_pub) os.chmod(ssh_pub_path, 0o600) try: known_hosts = config.ssh.known_hosts except AttributeError: known_hosts = () known_hosts_lines = [] for host in known_hosts: scan_command = ['ssh-keyscan'] # Use urlparse and fake an https address using the given host. # This works well with both hostnames and IPs (v4/v6), and ALSO ports. parsed = urllib.parse("https://{}".format(host)) if parsed.port: scan_command.extend(['-p', parsed.port]) scan_command.append(parsed.hostname) r = pu.run(scan_command, stdout=pu.PIPE, stderr=pu.PIPE) r.raise_for_status() known_hosts_lines.append("# Keyscan for '%s'" % host) known_hosts_lines.extend(iter_lines_clean(r.stdout)) try: fetcher_func = config.plugins.env_fetcher_func except AttributeError: fetcher_func = None else: fetcher_func = utils.import_func(fetcher_func) render_bin = utils.find_executable("render") if render_bin and fetcher_func: for env_name, env_topo_fn in fetcher_func( env_dir=config.get("env_dir")): r = pu.run([render_bin, '-e', env_topo_fn, 'known_hosts'], stdout=pu.PIPE, stderr=pu.PIPE) r.raise_for_status() known_hosts_lines.append("# Environment '%s'" % env_name) known_hosts_lines.extend(iter_lines_clean(r.stdout)) if known_hosts_lines: known_hosts_path = os.path.join(create_at, "known_hosts") with open(known_hosts_path, 'wb') as fh: fh.write(("# WARNING: DO NOT EDIT THIS" " FILE (IT WAS AUTOGENERATED ON BOT BOOTSTRAP!!!)\n")) fh.write("\n".join(known_hosts_lines)) os.chmod(known_hosts_path, 0o644)
def main(): """Start the tool. If the command line arguments are those of the 'manual' mode, then starts a manual one-time harvesting. Else trigger a BibSched task for automated harvesting based on the OAIHarvest admin settings. """ # Let's try to parse the arguments as used in manual harvesting: try: opts, args = getopt.getopt(sys.argv[1:], "o:v:m:p:i:s:f:u:r:c:k:l:w:", [ "output=", "verb=", "method=", "metadataPrefix=", "identifier=", "set=", "from=", "until=", "resumptionToken=", "certificate=", "key=", "user="******"password="******"workflow=", ]) # So everything went smoothly: start harvesting in manual mode if len([opt for opt, opt_value in opts if opt in ['-v', '--verb']]) > 0: # verb parameter is given http_param_dict = {} method = "POST" output = "" user = None password = None cert_file = None key_file = None sets = [] # get options and arguments for opt, opt_value in opts: if opt in ["-v", "--verb"]: http_param_dict['verb'] = opt_value elif opt in ["-m", '--method']: if opt_value == "GET" or opt_value == "POST": method = opt_value elif opt in ["-p", "--metadataPrefix"]: http_param_dict['metadataPrefix'] = opt_value elif opt in ["-i", "--identifier"]: http_param_dict['identifier'] = opt_value elif opt in ["-s", "--set"]: sets = opt_value.split() elif opt in ["-f", "--from"]: http_param_dict['from'] = opt_value elif opt in ["-u", "--until"]: http_param_dict['until'] = opt_value elif opt in ["-r", "--resumptionToken"]: http_param_dict['resumptionToken'] = opt_value elif opt in ["-o", "--output"]: output = opt_value elif opt in ["-c", "--certificate"]: cert_file = opt_value elif opt in ["-k", "--key"]: key_file = opt_value elif opt in ["-l", "--user"]: user = opt_value elif opt in ["-w", "--password"]: password = opt_value elif opt in ["-V", "--version"]: print(__revision__) sys.exit(0) else: usage(1, "Option %s is not allowed" % opt) if len(args) > 0: base_url = args[-1] if not base_url.lower().startswith('http'): base_url = 'http://' + base_url (addressing_scheme, network_location, path, dummy1, dummy2, dummy3) = urllib.parse(base_url) secure = (addressing_scheme == "https") if (cert_file and not key_file) or \ (key_file and not cert_file): # Both are needed if one specified usage(1, "You must specify both certificate and key files") if password and not user: # User must be specified when password is given usage(1, "You must specify a username") elif user and not password: if not secure: sys.stderr.write( "*WARNING* Your password will be sent in clear!\n") try: password = getpass.getpass() except KeyboardInterrupt as error: sys.stderr.write("\n%s\n" % (error, )) sys.exit(0) getter.harvest(network_location, path, http_param_dict, method, output, sets, secure, user, password, cert_file, key_file) sys.stderr.write( "Harvesting completed at: %s\n\n" % time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime())) return else: usage(1, "You must specify the URL to harvest") else: # verb is not given. We will continue with periodic # harvesting. But first check if URL parameter is given: # if it is, then warn directly now if len([opt for opt, opt_value in opts if opt in ['-i', '--identifier']]) == 0 \ and len(args) > 1 or \ (len(args) == 1 and not args[0].isdigit()): usage(1, "You must specify the --verb parameter") except getopt.error: # So could it be that we are using different arguments? Try to # start the BibSched task (automated harvesting) and see if it # validates pass # BibSched mode - periodical harvesting # Note that the 'help' is common to both manual and automated # mode. num_of_critical_parameter = 0 num_of_critical_parameterb = 0 repositories = [] for opt in sys.argv[1:]: if opt in "-r" or opt in "--repository": num_of_critical_parameter += 1 elif opt in "--workflow": num_of_critical_parameterb += 1 if num_of_critical_parameter > 1 or num_of_critical_parameterb > 1: usage(1, "You can't specify twice -r or --workflow") if num_of_critical_parameter == 1: if "-r" in sys.argv: position = sys.argv.index("-r") else: position = sys.argv.index("--repository") repositories = sys.argv[position + 1].split(",") if len(repositories) > 1 and \ ("-i" in sys.argv or "--identifier" in sys.argv): usage( 1, "It is impossible to harvest an identifier from several " "repositories.") if num_of_critical_parameterb == 1: position = sys.argv.index("--workflow") workflows = sys.argv[position + 1].split(",") for workflow_candidate in workflows: if workflow_candidate not in registry_workflows: usage(1, "The workflow %s doesn't exist." % workflow_candidate) if num_of_critical_parameter == 1 and num_of_critical_parameterb == 0: for name_repository in repositories: try: oaiharvest_instance = OaiHARVEST.get( OaiHARVEST.name == name_repository).one() if oaiharvest_instance.workflows not in registry_workflows: usage( 1, "The repository %s doesn't have a valid workflow specified." % name_repository) except orm.exc.NoResultFound: usage( 1, "The repository %s doesn't exist in our database." % name_repository) elif num_of_critical_parameter == 1 and num_of_critical_parameterb == 1: for name_repository in repositories: try: OaiHARVEST.get(OaiHARVEST.name == name_repository).one() except orm.exc.NoResultFound: usage( 1, "The repository %s doesn't exist in our database." % name_repository) print("A workflow has been specified, overriding the repository one.") task_set_option("repository", None) task_set_option("dates", None) task_set_option("workflow", None) task_set_option("identifiers", None) task_init( authorization_action='runoaiharvest', authorization_msg="oaiharvest Task Submission", description=""" Harvest records from OAI sources. Manual vs automatic harvesting: - Manual harvesting retrieves records from the specified URL, with the specified OAI arguments. Harvested records are displayed on the standard output or saved to a file, but are not integrated into the repository. This mode is useful to 'play' with OAI repositories or to build special harvesting scripts. - Automatic harvesting relies on the settings defined in the OAI Harvest admin interface to periodically retrieve the repositories and sets to harvest. It also take care of harvesting only new or modified records. Records harvested using this mode are converted and integrated into the repository, according to the settings defined in the OAI Harvest admin interface. Examples: Manual (single-shot) harvesting mode: Save to /tmp/z.xml records from CDS added/modified between 2004-04-01 and 2004-04-02, in MARCXML: $ oaiharvest -vListRecords -f2004-04-01 -u2004-04-02 -pmarcxml -o/tmp/z.xml http://cds.cern.ch/oai2d Automatic (periodical) harvesting mode: Schedule daily harvesting of all repositories defined in OAIHarvest admin: $ oaiharvest -s 24h Schedule daily harvesting of repository 'arxiv', defined in OAIHarvest admin: $ oaiharvest -r arxiv -s 24h Harvest in 10 minutes from 'pubmed' repository records added/modified between 2005-05-05 and 2005-05-10: $ oaiharvest -r pubmed -d 2005-05-05:2005-05-10 -t 10m """, help_specific_usage='Manual single-shot harvesting mode:\n' ' -o, --output specify output file\n' ' -v, --verb OAI verb to be executed\n' ' -m, --method http method (default POST)\n' ' -p, --metadataPrefix metadata format\n' ' -i, --identifier OAI identifier\n' ' -s, --set OAI set(s). Whitespace-separated list\n' ' -r, --resuptionToken Resume previous harvest\n' ' -f, --from from date (datestamp)\n' ' -u, --until until date (datestamp)\n' ' -c, --certificate path to public certificate (in case of certificate-based harvesting)\n' ' -k, --key path to private key (in case of certificate-based harvesting)\n' ' -l, --user username (in case of password-protected harvesting)\n' ' -w, --password password (in case of password-protected harvesting)\n' 'Deamon mode (periodical or one-shot harvesting mode):\n' ' -r, --repository="repo A"[,"repo B"] \t which repositories to harvest (default=all)\n' ' -d, --dates=yyyy-mm-dd:yyyy-mm-dd \t reharvest given dates only\n' ' -i, --identifier OAI identifier if wished to run in as a task.\n' ' --notify-email-to Receive notifications on given email on successful upload and/or finished harvest.\n' ' --workflow specify the workflow to execute.\n' ' --create-ticket-in Provide desired ticketing queue to create a ticket in it on upload and/or finished harvest.\n' ' Requires a configured ticketing system (BibCatalog).\n', specific_params=("r:i:d:W", [ "repository=", "identifier=", "dates=", "workflow=", "notify-email-to=", "create-ticket-in=" ]), task_submit_elaborate_specific_parameter_fnc= task_submit_elaborate_specific_parameter, task_run_fnc=task_run_core)
def ago_string(s): try: return ago(parse(s, ignoretz=True)) except (ValueError, AttributeError, TypeError): return 'unknown'
def main(): """Start the tool. If the command line arguments are those of the 'manual' mode, then starts a manual one-time harvesting. Else trigger a BibSched task for automated harvesting based on the OAIHarvest admin settings. """ # Let's try to parse the arguments as used in manual harvesting: try: opts, args = getopt.getopt(sys.argv[1:], "o:v:m:p:i:s:f:u:r:c:k:l:w:", ["output=", "verb=", "method=", "metadataPrefix=", "identifier=", "set=", "from=", "until=", "resumptionToken=", "certificate=", "key=", "user="******"password="******"workflow=", ]) # So everything went smoothly: start harvesting in manual mode if len([opt for opt, opt_value in opts if opt in ['-v', '--verb']]) > 0: # verb parameter is given http_param_dict = {} method = "POST" output = "" user = None password = None cert_file = None key_file = None sets = [] # get options and arguments for opt, opt_value in opts: if opt in ["-v", "--verb"]: http_param_dict['verb'] = opt_value elif opt in ["-m", '--method']: if opt_value == "GET" or opt_value == "POST": method = opt_value elif opt in ["-p", "--metadataPrefix"]: http_param_dict['metadataPrefix'] = opt_value elif opt in ["-i", "--identifier"]: http_param_dict['identifier'] = opt_value elif opt in ["-s", "--set"]: sets = opt_value.split() elif opt in ["-f", "--from"]: http_param_dict['from'] = opt_value elif opt in ["-u", "--until"]: http_param_dict['until'] = opt_value elif opt in ["-r", "--resumptionToken"]: http_param_dict['resumptionToken'] = opt_value elif opt in ["-o", "--output"]: output = opt_value elif opt in ["-c", "--certificate"]: cert_file = opt_value elif opt in ["-k", "--key"]: key_file = opt_value elif opt in ["-l", "--user"]: user = opt_value elif opt in ["-w", "--password"]: password = opt_value elif opt in ["-V", "--version"]: print(__revision__) sys.exit(0) else: usage(1, "Option %s is not allowed" % opt) if len(args) > 0: base_url = args[-1] if not base_url.lower().startswith('http'): base_url = 'http://' + base_url (addressing_scheme, network_location, path, dummy1, dummy2, dummy3) = urllib.parse(base_url) secure = (addressing_scheme == "https") if (cert_file and not key_file) or \ (key_file and not cert_file): # Both are needed if one specified usage(1, "You must specify both certificate and key files") if password and not user: # User must be specified when password is given usage(1, "You must specify a username") elif user and not password: if not secure: sys.stderr.write( "*WARNING* Your password will be sent in clear!\n") try: password = getpass.getpass() except KeyboardInterrupt as error: sys.stderr.write("\n%s\n" % (error,)) sys.exit(0) getter.harvest(network_location, path, http_param_dict, method, output, sets, secure, user, password, cert_file, key_file) sys.stderr.write("Harvesting completed at: %s\n\n" % time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime())) return else: usage(1, "You must specify the URL to harvest") else: # verb is not given. We will continue with periodic # harvesting. But first check if URL parameter is given: # if it is, then warn directly now if len([opt for opt, opt_value in opts if opt in ['-i', '--identifier']]) == 0 \ and len(args) > 1 or \ (len(args) == 1 and not args[0].isdigit()): usage(1, "You must specify the --verb parameter") except getopt.error: # So could it be that we are using different arguments? Try to # start the BibSched task (automated harvesting) and see if it # validates pass # BibSched mode - periodical harvesting # Note that the 'help' is common to both manual and automated # mode. num_of_critical_parameter = 0 num_of_critical_parameterb = 0 repositories = [] for opt in sys.argv[1:]: if opt in "-r" or opt in "--repository": num_of_critical_parameter += 1 elif opt in "--workflow": num_of_critical_parameterb += 1 if num_of_critical_parameter > 1 or num_of_critical_parameterb > 1: usage(1, "You can't specify twice -r or --workflow") if num_of_critical_parameter == 1: if "-r" in sys.argv: position = sys.argv.index("-r") else: position = sys.argv.index("--repository") repositories = sys.argv[position + 1].split(",") if len(repositories) > 1 and \ ("-i" in sys.argv or "--identifier" in sys.argv): usage(1, "It is impossible to harvest an identifier from several " "repositories.") if num_of_critical_parameterb == 1: position = sys.argv.index("--workflow") workflows = sys.argv[position + 1].split(",") for workflow_candidate in workflows: if workflow_candidate not in registry_workflows: usage(1, "The workflow %s doesn't exist." % workflow_candidate) if num_of_critical_parameter == 1 and num_of_critical_parameterb == 0: for name_repository in repositories: try: oaiharvest_instance = OaiHARVEST.get( OaiHARVEST.name == name_repository).one() if oaiharvest_instance.workflows not in registry_workflows: usage(1, "The repository %s doesn't have a valid workflow specified." % name_repository) except orm.exc.NoResultFound: usage(1, "The repository %s doesn't exist in our database." % name_repository) elif num_of_critical_parameter == 1 and num_of_critical_parameterb == 1: for name_repository in repositories: try: OaiHARVEST.get(OaiHARVEST.name == name_repository).one() except orm.exc.NoResultFound: usage(1, "The repository %s doesn't exist in our database." % name_repository) print("A workflow has been specified, overriding the repository one.") task_set_option("repository", None) task_set_option("dates", None) task_set_option("workflow", None) task_set_option("identifiers", None) task_init(authorization_action='runoaiharvest', authorization_msg="oaiharvest Task Submission", description=""" Harvest records from OAI sources. Manual vs automatic harvesting: - Manual harvesting retrieves records from the specified URL, with the specified OAI arguments. Harvested records are displayed on the standard output or saved to a file, but are not integrated into the repository. This mode is useful to 'play' with OAI repositories or to build special harvesting scripts. - Automatic harvesting relies on the settings defined in the OAI Harvest admin interface to periodically retrieve the repositories and sets to harvest. It also take care of harvesting only new or modified records. Records harvested using this mode are converted and integrated into the repository, according to the settings defined in the OAI Harvest admin interface. Examples: Manual (single-shot) harvesting mode: Save to /tmp/z.xml records from CDS added/modified between 2004-04-01 and 2004-04-02, in MARCXML: $ oaiharvest -vListRecords -f2004-04-01 -u2004-04-02 -pmarcxml -o/tmp/z.xml http://cds.cern.ch/oai2d Automatic (periodical) harvesting mode: Schedule daily harvesting of all repositories defined in OAIHarvest admin: $ oaiharvest -s 24h Schedule daily harvesting of repository 'arxiv', defined in OAIHarvest admin: $ oaiharvest -r arxiv -s 24h Harvest in 10 minutes from 'pubmed' repository records added/modified between 2005-05-05 and 2005-05-10: $ oaiharvest -r pubmed -d 2005-05-05:2005-05-10 -t 10m """, help_specific_usage='Manual single-shot harvesting mode:\n' ' -o, --output specify output file\n' ' -v, --verb OAI verb to be executed\n' ' -m, --method http method (default POST)\n' ' -p, --metadataPrefix metadata format\n' ' -i, --identifier OAI identifier\n' ' -s, --set OAI set(s). Whitespace-separated list\n' ' -r, --resuptionToken Resume previous harvest\n' ' -f, --from from date (datestamp)\n' ' -u, --until until date (datestamp)\n' ' -c, --certificate path to public certificate (in case of certificate-based harvesting)\n' ' -k, --key path to private key (in case of certificate-based harvesting)\n' ' -l, --user username (in case of password-protected harvesting)\n' ' -w, --password password (in case of password-protected harvesting)\n' 'Deamon mode (periodical or one-shot harvesting mode):\n' ' -r, --repository="repo A"[,"repo B"] \t which repositories to harvest (default=all)\n' ' -d, --dates=yyyy-mm-dd:yyyy-mm-dd \t reharvest given dates only\n' ' -i, --identifier OAI identifier if wished to run in as a task.\n' ' --notify-email-to Receive notifications on given email on successful upload and/or finished harvest.\n' ' --workflow specify the workflow to execute.\n' ' --create-ticket-in Provide desired ticketing queue to create a ticket in it on upload and/or finished harvest.\n' ' Requires a configured ticketing system (BibCatalog).\n', specific_params=( "r:i:d:W", ["repository=", "identifier=", "dates=", "workflow=", "notify-email-to=", "create-ticket-in="]), task_submit_elaborate_specific_parameter_fnc=task_submit_elaborate_specific_parameter, task_run_fnc=task_run_core)
def show_score(self, data, suffix=''): """ Return a list with all score, finished date, email, name_link and username of the students """ pageId = self.idform user_id = self.scope_ids.user_id connectsid, apiKey = self.get_api_token() if connectsid is False: log.error( "Error with get api_key or connect.sid, pageId: {}, user_id: {}" .format(pageId, user_id)) return {'result': 'error'} result = requests.get( "https://quilgo.com/api/v1/~/Link?formId={}&sortBy=createdAt". format(pageId), cookies={'connect.sid': connectsid}, headers={ 'content-type': 'application/json', "x-api-key": apiKey }) if result.status_code == 200: from django.contrib.auth.models import User from dateutil.parser import parse aux = self.block_course_id course_key = CourseKey.from_string(aux) enrolled_students = User.objects.filter( courseenrollment__course_id=course_key, courseenrollment__is_active=1).order_by('username').values( 'id', 'username', 'email') datajson = json.loads(result.text) aux_links = datajson["links"] if len(aux_links) > 0: links = {} for link in aux_links: ids = str(link['id']) links[ids] = [ str(link['score']) if link['score'] is not None else "Sin Registros", link["finishedAt"] ] list_student = [] for student in enrolled_students: student_module = self.get_or_create_student_module( student['id']) state = json.loads(student_module.state) if len(state) > 0 and state['id_link'] in links: id_link = state['id_link'] expired_date = self.expired_date() if links[id_link][ 1] is not None and expired_date is not None: aux_date = "Si" if parse( links[id_link][1]) > expired_date else "No" else: aux_date = "Sin Registros" list_student.append([ student['id'], student['username'], student['email'], state['name_link'], links[id_link][0], aux_date ]) state['score'] = links[id_link][0] state['expired'] = links[id_link][1] student_module.state = json.dumps(state) student_module.save() elif len(state) > 0: list_student.append([ student['id'], student['username'], student['email'], state['name_link'], "Sin Registros", "Sin Registros" ]) else: list_student.append([ student['id'], student['username'], student['email'], "Sin Registros", "Sin Registros", "Sin Registros" ]) return {'result': 'success', 'list_student': list_student} else: return {'result': 'error2'} else: log.error( "Error to get all Links, pageId: {}, userId: {}, response: {}". format(pageId, user_id, result.content)) return {'result': 'error'}