summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aplus.go76
-rw-r--r--canvas.go57
-rw-r--r--file.html213
-rw-r--r--funcs.go128
-rw-r--r--main.go17
5 files changed, 140 insertions, 351 deletions
diff --git a/aplus.go b/aplus.go
new file mode 100644
index 0000000..e2ec53b
--- /dev/null
+++ b/aplus.go
@@ -0,0 +1,76 @@
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "net/http"
8 "net/url"
9 "strings"
10)
11
12func get_aplus(token string, link string, client http.Client) string {
13 resp, err := client.Get(link)
14
15 if err != nil {
16 fmt.Println("Error performing GET request to initial link.")
17 }
18 defer resp.Body.Close()
19 body, _ := io.ReadAll(resp.Body)
20
21 var aplus Aplus
22 json.Unmarshal(body, &aplus)
23
24 return aplus.URL
25}
26
27func get_form_from_request_body(req_body []byte) string {
28 body_str := string(req_body)
29 form_start := strings.Index(body_str, "<form")
30 form_end := strings.Index(body_str, "</form>") + 7
31 form_html := req_body[form_start:form_end]
32
33 return string(form_html)
34}
35
36// parse_form extracts form fields and values from the given HTML form string.
37func parse_form(form_html string) url.Values {
38 form_values := make(url.Values)
39 inputs := strings.Split(form_html, "<input")
40
41 for _, input := range inputs {
42 // Extract field name and value
43 name := extract_attribute(input, "name")
44 value := extract_attribute(input, "value")
45
46 if name != "" {
47 form_values.Add(name, value)
48 }
49 }
50
51 return form_values
52}
53
54func extract_attribute(input string, attribute string) string {
55 start := strings.Index(input, attribute+"=\"")
56 if start == -1 {
57 start = strings.Index(input, attribute+"='")
58 }
59
60 if start == -1 {
61 return ""
62 }
63
64 start += len(attribute) + 2
65
66 end := strings.Index(input[start:], "\"")
67 if end == -1 {
68 end = strings.Index(input[start:], "'")
69 }
70
71 if end == -1 {
72 return ""
73 }
74
75 return input[start : start+end]
76}
diff --git a/canvas.go b/canvas.go
new file mode 100644
index 0000000..33c7f6b
--- /dev/null
+++ b/canvas.go
@@ -0,0 +1,57 @@
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "net/http"
8 "os"
9)
10
11func initialize() {
12 base_link = "https://floridapolytechnic.instructure.com/api/v1"
13 token = os.Getenv("CANVAS_API_KEY")
14}
15
16func get_courses(token string, link string, client http.Client) []CanvasCourse {
17 resp, err := client.Get(link)
18 if err != nil {
19 fmt.Println("Error performing GET request to get courses.")
20 }
21 defer resp.Body.Close()
22 body, _ := io.ReadAll(resp.Body)
23
24 var canvas_courses []CanvasCourse
25 err2 := json.Unmarshal(body, &canvas_courses)
26 if err2 != nil {
27 fmt.Println(err2)
28 return nil
29 }
30
31 return canvas_courses
32}
33
34// Need to change this to grab both ID and name, return as pairs.
35func get_course_id_name_pair(canvas_courses []CanvasCourse) []uint64 {
36 var courses []uint64
37
38 for _, course := range canvas_courses {
39 courses = append(courses, course.ID%10000)
40 }
41 return courses
42}
43
44/*
45func select_course() int {
46 // course selection by user happens below
47 favorites := fmt.Sprintf("%s/users/self/favorites/courses?access_token=%s&per_page=100", base_link, token)
48 all_courses := fmt.Sprintf("%s/courses?access_token=%s&per_page=100", base_link, token)
49 var canvas_courses []CanvasCourse
50 canvas_courses = get_courses(token, favorites, client)
51 var course_ids []uint64
52 course_ids = get_course_ids(canvas_courses)
53 //selected := 1 // course_ids[selected]
54 // course selection by user happens above
55 return 0
56}
57*/
diff --git a/file.html b/file.html
deleted file mode 100644
index 9a0d8cc..0000000
--- a/file.html
+++ /dev/null
@@ -1,213 +0,0 @@
1<!DOCTYPE html>
2<html dir="ltr" lang="en">
3<head>
4 <meta charset="utf-8">
5 <meta name="sentry-trace" content="43617b9773274affb36a01071b39ea46-646bc3b45c594c51-0"/>
6 <link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/fonts/lato/extended/Lato-Regular-bd03a2cc27.woff2" as="font" type="font/woff2" crossorigin="anonymous">
7 <link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/fonts/lato/extended/Lato-Bold-cccb897485.woff2" as="font" type="font/woff2" crossorigin="anonymous">
8 <link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/fonts/lato/extended/Lato-Italic-4eb103b4d1.woff2" as="font" type="font/woff2" crossorigin="anonymous">
9 <link rel="stylesheet" href="https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/no_variables/bundles/fonts-6ee09b0b2f.css" media="screen" />
10 <script>if (navigator.userAgent.match(/(MSIE|Trident\/)/)) location.replace('/ie-is-not-supported.html')</script>
11
12 <link rel="icon" type="image/x-icon" href="https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136261/favicon2.png?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA&amp;Expires=1924178496&amp;Signature=3IZaeFGClMQRZf9ZAf%2BFbpdwwCg%3D&amp;response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public&amp;response-expires=473364000" />
13 <link rel="apple-touch-icon" href="https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136262/mobile-homescreen-icon1.png?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA&amp;Expires=1924178497&amp;Signature=oMCTe4hgrUPz9l01yfeVNLkYFoE%3D&amp;response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public&amp;response-expires=473364000" />
14 <link rel="stylesheet" href="https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/a069aee40beb810e784f27bdb7a32d37/variables-7dd4b80918af0e0218ec0229e4bd5873.css" media="all" />
15 <link rel="stylesheet" href="https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/new_styles_normal_contrast/bundles/common-c5d9e08ec7.css" media="all" />
16 <meta name="apple-itunes-app" content="app-id=480883488">
17<link rel="manifest" href="/web-app-manifest/manifest.json">
18 <meta name="viewport" content="width=device-width, initial-scale=1">
19 <meta name="theme-color" content="#394b58">
20 <meta name="robots" content="noindex,nofollow" />
21
22 <link rel="stylesheet" href="https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136373/work.css?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA&amp;Expires=1924253856&amp;Signature=6uDeFOZy0ITUxClp2KMDdw6xXRk%3D&amp;response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public&amp;response-expires=473364000" media="all" />
23
24
25 <script>
26 INST = {"environment":"production","allowMediaComments":true,"kalturaSettings":{"domain":"nv.instructuremedia.com","resource_domain":"nv.instructuremedia.com","rtmp_domain":"iad.rtmp.instructuremedia.com","partner_id":"9","subpartner_id":"0","player_ui_conf":"0","kcw_ui_conf":"0","upload_ui_conf":"0","max_file_size_bytes":534773760,"do_analytics":false,"hide_rte_button":false,"js_uploader":true},"logPageViews":true,"editorButtons":[{"name":"Khan Academy","id":7,"favorite":false,"url":"https://www.edu-apps.org/lti_public_resources/?tool_id=khan_academy","icon_url":"https://www.edu-apps.org/assets/lti_public_resources/khan_academy_icon.png","canvas_icon_class":null,"width":560,"height":600,"use_tray":false,"description":"\u003cp\u003eSearch for and embed Khan Academy lessons and exercise into course material. Khan Academy focuses on short lessons on math, science, etc. Uses the embedded player so students earn points for watching videos.\u003c/p\u003e\n"},{"name":"TED Ed","id":8,"favorite":false,"url":"https://www.edu-apps.org/tool_redirect?id=ted_ed","icon_url":"https://www.edu-apps.org/tools/ted_ed/icon.png","canvas_icon_class":null,"width":690,"height":530,"use_tray":false,"description":"\u003cp\u003eOnline instructional videos\u003c/p\u003e\n"},{"name":"Panopto","id":26,"favorite":true,"url":"https://flpoly.hosted.panopto.com/Panopto/LTI/LTI.aspx","icon_url":"https://flpoly.hosted.panopto.com/Panopto/images/panopto_logo_globe.png","canvas_icon_class":null,"width":900,"height":700,"use_tray":false,"description":""},{"name":"Commons Favorites","id":255,"favorite":false,"url":"https://lor.instructure.com/api/lti/favorite-resources","icon_url":"https://lor.instructure.com/img/icon_commons.png","canvas_icon_class":null,"width":800,"height":400,"use_tray":true,"description":"\u003cp\u003eFind and share course content\u003c/p\u003e\n"},{"name":"GitHub","id":256,"favorite":false,"url":"https://www.edu-apps.org/tool_redirect?id=github","icon_url":"https://www.edu-apps.org/tools/github/icon.png","canvas_icon_class":null,"width":600,"height":320,"use_tray":false,"description":"\u003cp\u003eEmbeds project summaries or code gists from GitHub's social coding site. Includes major language, commit dates, forks and watchers for repos, syntax-highlighted code for gists.\u003c/p\u003e\n"},{"name":"YouTube","id":408,"favorite":false,"url":"https://www.edu-apps.org/lti_public_resources/?tool_id=youtube","icon_url":"https://www.edu-apps.org/assets/lti_public_resources/youtube_icon.png","canvas_icon_class":null,"width":560,"height":600,"use_tray":false,"description":"\u003cp\u003eSearch publicly available YouTube videos. A new icon will show up in your course rich editor letting you search YouTube and click to embed videos in your course material.\u003c/p\u003e\n"},{"name":"Microsoft Office 365","id":1342,"favorite":false,"url":"https://office365-iad-prod.instructure.com/lti/rce-content-item","icon_url":"https://office365-iad-prod.instructure.com/images/office365_icon.png","canvas_icon_class":null,"width":900,"height":600,"use_tray":false,"description":"\u003cp\u003eAllows you to pull in documents from Office 365 to Canvas\u003c/p\u003e\n"},{"name":"Insert a math equation - MathType","id":1467,"favorite":false,"url":"https://www.wiris.net/instructure.com/canvas/editor/dialog","icon_url":"https://www.wiris.net/instructure.com/canvas/editor/icon.gif","canvas_icon_class":null,"width":570,"height":450,"use_tray":false,"description":"\u003cp\u003eInsert and edit mathematical formulas with MathType\u003c/p\u003e\n"},{"name":"Interactive Content – H5P","id":2079,"favorite":false,"url":"https://floridapoly.h5p.com","icon_url":"https://floridapoly.h5p.com/img/h5p-icon.png","canvas_icon_class":null,"width":800,"height":600,"use_tray":false,"description":"\u003cp\u003eCreate, share and reuse interactive HTML5 content in your browser\u003c/p\u003e\n"},{"name":"Follett Discover","id":3458,"favorite":false,"url":"https://blti.betterknow.com/","icon_url":"","canvas_icon_class":null,"width":400,"height":300,"use_tray":false,"description":"\u003cp\u003eFaculty can discover and adopt the best course materials, made available seamlessly to your students. Students can conveniently acquire all materials with options to choose rental, new, used or digital.\u003c/p\u003e\n"},{"name":"Insert a Wiley Resource","id":4149,"favorite":true,"url":"https://lti.education.wiley.com/wpng/api/v1/lti/resourcediscoverytool","icon_url":"https://education.wiley.com/assets/images/wp.svg","canvas_icon_class":null,"width":1160,"height":660,"use_tray":false,"description":"\u003cp\u003eOutcomes-based learning.\u003c/p\u003e\n"},{"name":"Studio","id":4213,"favorite":false,"url":"https://floridapolytechnic.instructuremedia.com/lti/launch?custom_arc_launch_type=content_select\u0026custom_lti_use_case=editor_button","icon_url":"https://files.instructuremedia.com/logos/studio-logo-squid-tiny-electric.svg","canvas_icon_class":null,"width":560,"height":600,"use_tray":false,"description":"\u003cp\u003eVideo for Education\u003c/p\u003e\n"}]};
27 ENV = {"ASSET_HOST":"https://du11hjcvx0uqb.cloudfront.net","active_brand_config_json_url":"https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/a069aee40beb810e784f27bdb7a32d37/variables-7dd4b80918af0e0218ec0229e4bd5873.json","active_brand_config":{"md5":"a069aee40beb810e784f27bdb7a32d37","variables":{"ic-brand-primary":"#008ee2","ic-brand-font-color-dark":"#2d3b45","ic-link-color":"#008ee2","ic-brand-button--secondary-bgd":"#2d3b45","ic-brand-global-nav-bgd":"#394b58","ic-brand-global-nav-logo-bgd":"#394b58","ic-brand-header-image":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/2386089/flpolylogo.png","ic-brand-watermark-opacity":"1","ic-brand-favicon":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136261/favicon2.png?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA\u0026Expires=1924178496\u0026Signature=3IZaeFGClMQRZf9ZAf%2BFbpdwwCg%3D\u0026response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public\u0026response-expires=473364000","ic-brand-apple-touch-icon":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136262/mobile-homescreen-icon1.png?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA\u0026Expires=1924178497\u0026Signature=oMCTe4hgrUPz9l01yfeVNLkYFoE%3D\u0026response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public\u0026response-expires=473364000","ic-brand-msapplication-tile-square":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136263/windows-tile-square1.png?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA\u0026Expires=1924178497\u0026Signature=7%2BWmXBVI%2FPZFfE%2BDz%2F4%2FaClVeuE%3D\u0026response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public\u0026response-expires=473364000","ic-brand-msapplication-tile-wide":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136264/windows-tile-wide1.png?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA\u0026Expires=1924178497\u0026Signature=xZmtnyLhxFFZqKppIrH1eMmzZjE%3D\u0026response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public\u0026response-expires=473364000","ic-brand-right-sidebar-logo":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/452631/canvas.png","ic-brand-Login-body-bgd-color":"#394b58","ic-brand-Login-body-bgd-image":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136266/cas-bg.jpg?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA\u0026Expires=1924178596\u0026Signature=285zPnRkOqsoyT7KAw2khFMAqNo%3D\u0026response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public\u0026response-expires=473364000","ic-brand-Login-body-bgd-shadow-color":"#2d3b45","ic-brand-Login-logo":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/452632/login-logo.png","ic-brand-Login-Content-bgd-color":"#492f92","ic-brand-Login-Content-border-color":"#3c2675","ic-brand-Login-Content-inner-bgd":"#492f92","ic-brand-Login-Content-inner-border":"#ffffff","ic-brand-Login-Content-inner-body-bgd":"#2d3b45","ic-brand-Login-Content-inner-body-border":"#2d3b45","ic-brand-Login-instructure-logo":"#3c2675"},"share":false,"name":null,"created_at":"2022-08-05T09:25:10-04:00","js_overrides":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/4681647/BlueCanvasConfig.js","css_overrides":"https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/136373/work.css?AWSAccessKeyId=AKIAJFNFXH2V2O7RPCAA\u0026Expires=1924253856\u0026Signature=6uDeFOZy0ITUxClp2KMDdw6xXRk%3D\u0026response-cache-control=Cache-Control%3Amax-age%3D473364000%2C%20public\u0026response-expires=473364000","parent_md5":null,"mobile_js_overrides":"","mobile_css_overrides":""},"confetti_branding_enabled":false,"url_to_what_gets_loaded_inside_the_tinymce_editor_css":["https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/a069aee40beb810e784f27bdb7a32d37/variables-7dd4b80918af0e0218ec0229e4bd5873.css","https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/new_styles_normal_contrast/bundles/what_gets_loaded_inside_the_tinymce_editor-a64c7fe33c.css","https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/no_variables/bundles/fonts-6ee09b0b2f.css"],"url_for_high_contrast_tinymce_editor_css":["https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/default/variables-high_contrast-7dd4b80918af0e0218ec0229e4bd5873.css","https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/new_styles_high_contrast/bundles/what_gets_loaded_inside_the_tinymce_editor-fa0672d544.css","https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/no_variables/bundles/fonts-6ee09b0b2f.css"],"current_user_id":null,"current_user_global_id":null,"current_user_heap_id":null,"current_user_roles":null,"current_user_is_student":false,"current_user_types":null,"current_user_disabled_inbox":null,"current_user_visited_tabs":null,"discussions_reporting":false,"files_domain":"cluster53.canvas-user-content.com","group_information":null,"DOMAIN_ROOT_ACCOUNT_ID":"26070000000000001","DOMAIN_ROOT_ACCOUNT_UUID":"ORgdQ0h5HuS0d5X8yEiEMtnAEO2jjrFi4GQo7NCe","k12":false,"help_link_name":"Help","help_link_icon":"help","use_high_contrast":null,"auto_show_cc":null,"disable_celebrations":null,"disable_keyboard_shortcuts":null,"LTI_LAUNCH_FRAME_ALLOWANCES":["geolocation *","microphone *","camera *","midi *","encrypted-media *","autoplay *","clipboard-write *","display-capture *"],"DEEP_LINKING_POST_MESSAGE_ORIGIN":"https://floridapolytechnic.instructure.com","DEEP_LINKING_LOGGING":null,"comment_library_suggestions_enabled":null,"SETTINGS":{"open_registration":false,"collapse_global_nav":null,"release_notes_badge_disabled":null},"FULL_STORY_ENABLED":false,"RAILS_ENVIRONMENT":"Production","IN_PACED_COURSE":false,"SENTRY_FRONTEND":{"dsn":"https://355a1d96717e4038ac25aa852fa79a8f@relay-iad.sentry.insops.net/388","org_slug":"instructure","base_url":"https://sentry.insops.net","normalized_route":"/courses/{course_id}/external_tools/sessionless_launch","errors_sample_rate":"0.0005","traces_sample_rate":"0.0005","url_deny_pattern":"instructure-uploads.*amazonaws.com","revision":"canvas-lms@20231025.250"},"DATA_COLLECTION_ENDPOINT":"https://canvas-frontend-data-iad-prod.inscloudgate.net/submit","DOMAIN_ROOT_ACCOUNT_SFID":"001A0000010pKREIA2","DIRECT_SHARE_ENABLED":false,"CAN_VIEW_CONTENT_SHARES":null,"FEATURES":{"featured_help_links":true,"lti_platform_storage":true,"calendar_series":true,"account_level_blackout_dates":false,"render_both_to_do_lists":false,"course_paces_redesign":true,"course_paces_for_students":true,"module_publish_menu":true,"explicit_latex_typesetting":false,"dev_key_oidc_alert":true,"media_links_use_attachment_id":false,"permanent_page_links":true,"differentiated_modules":false,"enhanced_course_creation_account_fetching":false,"instui_for_import_page":false,"product_tours":false,"usage_rights_discussion_topics":true,"granular_permissions_manage_users":true,"create_course_subaccount_picker":true,"lti_deep_linking_module_index_menu_modal":true,"lti_multiple_assignment_deep_linking":true,"lti_overwrite_user_url_input_select_content_dialog":true,"buttons_and_icons_root_account":false,"extended_submission_state":false,"scheduled_page_publication":true,"send_usage_metrics":true,"rce_transform_loaded_content":false,"lti_assignment_page_line_items":true,"mobile_offline_mode":false,"react_discussions_post":false,"instui_nav":false,"embedded_release_notes":true,"canvas_k6_theme":false,"new_math_equation_handling":true},"current_user":{},"context_asset_string":"course_7329","ping_url":"https://floridapolytechnic.instructure.com/api/v1/courses/7329/ping","TIMEZONE":"America/New_York","CONTEXT_TIMEZONE":"America/New_York","LOCALES":["en"],"BIGEASY_LOCALE":"en_US","FULLCALENDAR_LOCALE":"en","MOMENT_LOCALE":"en","rce_auto_save_max_age_ms":86400000,"K5_USER":false,"USE_CLASSIC_FONT":false,"K5_HOMEROOM_COURSE":false,"K5_SUBJECT_COURSE":false,"LOCALE_TRANSLATION_FILE":"/dist/javascripts/translations/en-888412cb6b.json","ACCOUNT_ID":"45","active_context_tab":null};
28 BRANDABLE_CSS_HANDLEBARS_INDEX = [["new_styles_normal_contrast","new_styles_high_contrast","new_styles_normal_contrast_rtl","new_styles_high_contrast_rtl"],{"10":["8300658022",0,"250b5824c2",2],"15":["fc26aa5fd4",0,"f904416063",2],"19":["df5777ed9c"],"61":["f3934dab06","f405852bb2","ee5810890b","3fd9943b9a"],"67":["8b57f54e71",0,"43833dde85",2],"71":["35b89b103a","4304be7d41","58dbfc2651","2932678b1c"],"06":["cb9f63cba6",0,"2be010fc14",2],"f0":["7c947dce20",0,0,0],"c8":["12d5e4d1e8","9f7b02d283","4ebd280f3e","b547456f4c"],"1e":["02e336724a","d7bb142b0a","d7ac7fdfb8","c03b9b261e"],"b3":["8ebc71ebc3","cf8efa05c8","4efdc93a21","fd6d3a9780"],"0c":["c26e82abac",0,"b71e9cbd6d",2],"da":["efb9fe6d7c","edbd1b5e83","a6dc56afb7","dfb2d13098"],"1d":["a3bfcb7961",0,"90682b3bbe",2],"08":["64bff5a97d"],"e2":["11429f119a"],"9f":["35936a18c3",0,0,0],"2b":["abf63f48ef","bf8e135ffe","378e0c136b","9833e305e6"],"2c":["6d919206cd",0,0,0],"c2":["6f2721ae01"],"9c":["ecafc938e4",0,"59e7c22304",2],"c5":["ebf0e1382f","7f587d9a8a","afbdabf23d","0d398196a8"],"f2":["51574f9b13"]}]
29;
30 </script>
31
32 <link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/a069aee40beb810e784f27bdb7a32d37/variables-7dd4b80918af0e0218ec0229e4bd5873.js" as="script" type="text/javascript"><link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/timezone/America/New_York-692f7d27e4.js" as="script" type="text/javascript"><link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/timezone/America/New_York-692f7d27e4.js" as="script" type="text/javascript"><link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/timezone/en_US-80a0ce259b.js" as="script" type="text/javascript"><link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/main-e-4723ea22a5.js" as="script" type="text/javascript" crossorigin="anonymous"><script>
33//<![CDATA[
34
35 ;["https://du11hjcvx0uqb.cloudfront.net/dist/brandable_css/a069aee40beb810e784f27bdb7a32d37/variables-7dd4b80918af0e0218ec0229e4bd5873.js", "https://du11hjcvx0uqb.cloudfront.net/dist/timezone/America/New_York-692f7d27e4.js", "https://du11hjcvx0uqb.cloudfront.net/dist/timezone/America/New_York-692f7d27e4.js", "https://du11hjcvx0uqb.cloudfront.net/dist/timezone/en_US-80a0ce259b.js"].forEach(function(src) {
36 var s = document.createElement('script'); s.src = src; s.async = false;
37 document.head.appendChild(s)
38 });
39//]]>
40</script><script>
41//<![CDATA[
42
43 ;["https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/main-e-4723ea22a5.js"].forEach(function(src) {
44 var s = document.createElement('script'); s.src = src; s.async = false; s.crossOrigin = 'anonymous';
45 document.head.appendChild(s)
46 });
47//]]>
48</script><link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/external_tools_show-c-ca25ca7b62.js" as="script" type="text/javascript"><link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/edit_rubric-c-ac32a605ba.js" as="script" type="text/javascript"><link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/navigation_header-c-db122ba197.js" as="script" type="text/javascript"><script>
49//<![CDATA[
50(window.bundles || (window.bundles = [])).push('external_tools_show');
51(window.bundles || (window.bundles = [])).push('edit_rubric');
52(window.bundles || (window.bundles = [])).push('navigation_header');
53//]]>
54</script>
55 <title>aPlus+ Attendance</title>
56
57
58
59 <script type="text/javascript">
60 window.heap=window.heap||[],heap.load=function(e,t){window.heap.appid=e,window.heap.config=t=t||{};var r=document.createElement("script");r.type="text/javascript",r.async=!0,r.src="https://cdn.heapanalytics.com/js/heap-"+e+".js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(r,a);for(var n=function(e){return function(){heap.push([e].concat(Array.prototype.slice.call(arguments,0)))}},p=["addEventProperties","addUserProperties","clearEventProperties","identify","resetIdentity","removeEventProperty","setEventProperties","track","unsetEventProperty"],o=0;o<p.length;o++)heap[p[o]]=n(p[o])};
61 heap.load("3001039959");
62 setTimeout(() => {
63 if (ENV.current_user_heap_id && ENV.current_user_heap_id !== heap.identity) {
64 heap.identify(ENV.current_user_heap_id);
65 }
66 props = {}
67 if (ENV.current_user_roles) {
68 props['role'] = ENV.current_user_roles[ENV.current_user_roles.length - 1]
69 }
70 if (ENV.DOMAIN_ROOT_ACCOUNT_UUID) {
71 props['Canvas.accountId'] = ENV.DOMAIN_ROOT_ACCOUNT_UUID
72 }
73 if (ENV.DOMAIN_ROOT_ACCOUNT_SFID) {
74 props['Canvas.salesforceAccountId'] = ENV.DOMAIN_ROOT_ACCOUNT_SFID
75 }
76 if (Object.keys(props).length > 0) {
77 heap.addUserProperties(props);
78 }
79 }, 1000);
80 </script>
81
82</head>
83
84
85
86
87
88
89
90
91
92
93
94
95
96<div class="tool_content_wrapper
97 "
98 data-tool-wrapper-id="320a0477-1125-4b70-9695-4a6ad94f041a"
99>
100 <form action="https://floridapoly.aplusattendance.com/canvas"
101 class="hide"
102 method="POST"
103 target="tool_content"
104 id="tool_form"
105 data-tool-launch-type="self"
106 data-tool-id="aplus_attendance"
107 data-tool-path="/canvas"
108 data-message-type="tool_launch">
109 <input type="hidden" name="oauth_consumer_key" id="oauth_consumer_key" value="aplus-attendance" autocomplete="off" />
110 <input type="hidden" name="oauth_signature_method" id="oauth_signature_method" value="HMAC-SHA1" autocomplete="off" />
111 <input type="hidden" name="oauth_timestamp" id="oauth_timestamp" value="1698447463" autocomplete="off" />
112 <input type="hidden" name="oauth_nonce" id="oauth_nonce" value="7lyNYfB0yrVAm9VEJhxMuahKR2OUARmjIB9Bn7WiE" autocomplete="off" />
113 <input type="hidden" name="oauth_version" id="oauth_version" value="1.0" autocomplete="off" />
114 <input type="hidden" name="context_id" id="context_id" value="0c1f49ff7b35cba2226f93e9cbb84ae810ed00ab" autocomplete="off" />
115 <input type="hidden" name="context_label" id="context_label" value="CIS4367.01I&amp;T" autocomplete="off" />
116 <input type="hidden" name="context_title" id="context_title" value="Computer Security(FA 2023_CIS4367.01 I&amp;T)" autocomplete="off" />
117 <input type="hidden" name="custom_canvas_api_domain" id="custom_canvas_api_domain" value="floridapolytechnic.instructure.com" autocomplete="off" />
118 <input type="hidden" name="custom_canvas_course_id" id="custom_canvas_course_id" value="7329" autocomplete="off" />
119 <input type="hidden" name="custom_canvas_enrollment_state" id="custom_canvas_enrollment_state" value="active" autocomplete="off" />
120 <input type="hidden" name="custom_canvas_user_id" id="custom_canvas_user_id" value="6858" autocomplete="off" />
121 <input type="hidden" name="custom_canvas_user_login_id" id="custom_canvas_user_login_id" value="jroig9590" autocomplete="off" />
122 <input type="hidden" name="custom_canvas_workflow_state" id="custom_canvas_workflow_state" value="available" autocomplete="off" />
123 <input type="hidden" name="ext_roles" id="ext_roles" value="urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Learner,urn:lti:sysrole:ims/lis/User" autocomplete="off" />
124 <input type="hidden" name="launch_presentation_document_target" id="launch_presentation_document_target" value="iframe" autocomplete="off" />
125 <input type="hidden" name="launch_presentation_locale" id="launch_presentation_locale" value="en" autocomplete="off" />
126 <input type="hidden" name="launch_presentation_return_url" id="launch_presentation_return_url" value="https://floridapolytechnic.instructure.com/courses/7329" autocomplete="off" />
127 <input type="hidden" name="lis_course_offering_sourcedid" id="lis_course_offering_sourcedid" value="7093" autocomplete="off" />
128 <input type="hidden" name="lis_person_contact_email_primary" id="lis_person_contact_email_primary" value="jroig9590@floridapoly.edu" autocomplete="off" />
129 <input type="hidden" name="lis_person_name_family" id="lis_person_name_family" value="Roig" autocomplete="off" />
130 <input type="hidden" name="lis_person_name_full" id="lis_person_name_full" value="Juan Roig" autocomplete="off" />
131 <input type="hidden" name="lis_person_name_given" id="lis_person_name_given" value="Juan" autocomplete="off" />
132 <input type="hidden" name="lis_person_sourcedid" id="lis_person_sourcedid" value="10308" autocomplete="off" />
133 <input type="hidden" name="lti_message_type" id="lti_message_type" value="basic-lti-launch-request" autocomplete="off" />
134 <input type="hidden" name="lti_version" id="lti_version" value="LTI-1p0" autocomplete="off" />
135 <input type="hidden" name="oauth_callback" id="oauth_callback" value="about:blank" autocomplete="off" />
136 <input type="hidden" name="resource_link_id" id="resource_link_id" value="0c1f49ff7b35cba2226f93e9cbb84ae810ed00ab" autocomplete="off" />
137 <input type="hidden" name="resource_link_title" id="resource_link_title" value="aPlus+ Attendance" autocomplete="off" />
138 <input type="hidden" name="roles" id="roles" value="Learner" autocomplete="off" />
139 <input type="hidden" name="tool_consumer_info_product_family_code" id="tool_consumer_info_product_family_code" value="canvas" autocomplete="off" />
140 <input type="hidden" name="tool_consumer_info_version" id="tool_consumer_info_version" value="cloud" autocomplete="off" />
141 <input type="hidden" name="tool_consumer_instance_contact_email" id="tool_consumer_instance_contact_email" value="notifications@instructure.com" autocomplete="off" />
142 <input type="hidden" name="tool_consumer_instance_guid" id="tool_consumer_instance_guid" value="7db438071375c02373713c12c73869ff2f470b68.floridapolytechnic.instructure.com" autocomplete="off" />
143 <input type="hidden" name="tool_consumer_instance_name" id="tool_consumer_instance_name" value="Florida Polytechnic University" autocomplete="off" />
144 <input type="hidden" name="user_id" id="user_id" value="91ba5b390440f646d9d4c47a0dc14f91cf595887" autocomplete="off" />
145 <input type="hidden" name="user_image" id="user_image" value="https://canvas.instructure.com/images/messages/avatar-50.png" autocomplete="off" />
146 <input type="hidden" name="oauth_signature" id="oauth_signature" value="594h5aYeeCIAVKXp85K8VDjIWwM=" autocomplete="off" />
147 <div style="margin-bottom: 20px;">
148 <div class="load_tab">
149 This tool needs to be loaded in a new browser window
150 <div style="margin: 10px 0;">
151 <button class="btn" type="submit"
152 data-expired_message="The session for this tool has expired. Please reload the page to access the tool again">
153 Load aPlus+ Attendance in a new window
154 </button>
155 </div>
156 </div>
157 <div class="tab_loaded" style="display: none;">
158 This tool was successfully loaded in a new browser window. Reload the page to access the tool again.
159 </div>
160 </div>
161 </form>
162
163 <div class="before_external_content_info_alert screenreader-only-tool" tabindex="0">
164 <div class="ic-flash-info">
165 <div class="ic-flash__icon" aria-hidden="true">
166 <i class="icon-info"></i>
167 </div>
168 The following content is partner provided
169 </div>
170 </div>
171
172 <iframe src="about:blank" name="tool_content" id="tool_content" class="tool_launch" allowfullscreen="allowfullscreen" webkitallowfullscreen="true" mozallowfullscreen="true" tabindex="0" title="aPlus+ Attendance" style="height:100%;width:100%;" allow="geolocation *; microphone *; camera *; midi *; encrypted-media *; autoplay *; clipboard-write *; display-capture *" data-lti-launch="true"></iframe>
173
174 <div class="after_external_content_info_alert screenreader-only-tool" tabindex="0">
175 <div class="ic-flash-info">
176 <div class="ic-flash__icon" aria-hidden="true">
177 <i class="icon-info"></i>
178 </div>
179 The preceding content is partner provided
180 </div>
181 </div>
182</div>
183
184
185
186
187
188
189<div id="module_sequence_footer"></div>
190
191
192
193
194 <iframe src="https://sso.canvaslms.com/post_message_forwarding" name="post_message_forwarding" title="post_message_forwarding" id="post_message_forwarding" sandbox="allow-scripts allow-same-origin" style="display:none;"></iframe>
195
196
197
198<link rel="preload" href="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/inst_fs_service_worker-c-7146c1678a.js" as="script" type="text/javascript"><script>
199//<![CDATA[
200(window.bundles || (window.bundles = [])).push('inst_fs_service_worker');
201//]]>
202</script>
203 <script>
204//<![CDATA[
205
206 ;["https://instructure-uploads.s3.amazonaws.com/account_26070000000000001/attachments/4681647/BlueCanvasConfig.js"].forEach(function(src) {
207 var s = document.createElement('script'); s.src = src; s.async = false;
208 document.head.appendChild(s)
209 });
210//]]>
211</script>
212
213
diff --git a/funcs.go b/funcs.go
deleted file mode 100644
index 5e334ff..0000000
--- a/funcs.go
+++ /dev/null
@@ -1,128 +0,0 @@
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "net/http"
8 "net/url"
9 "strings"
10)
11
12/*
13func get_courses(token string, link string, client http.Client) []CanvasCourse {
14 resp, err := client.Get(link)
15 if err != nil {
16 fmt.Println("Error performing GET request to get courses.")
17 }
18 defer resp.Body.Close()
19 body, err := io.ReadAll(resp.Body)
20
21 if err != nil {
22 fmt.Println("Error trying to read html body for courses.")
23 }
24
25 var canvas_courses []CanvasCourse
26 err2 := json.Unmarshal(body, &canvas_courses)
27 if err2 != nil {
28 fmt.Println(err2)
29 return nil
30 }
31
32 return canvas_courses
33}
34
35// Need to change this to grab both ID and name, return as pairs.
36func get_course_id_name_pair(canvas_courses []CanvasCourse) []uint64 {
37 var courses []uint64
38
39 for _, course := range canvas_courses {
40 courses = append(courses, course.ID%10000)
41 }
42 return courses
43}
44
45func select_course() int {
46 // course selection by user happens below
47 //favorites := fmt.Sprintf("%s/users/self/favorites/courses?access_token=%s&per_page=100", base_link, token)
48 //all_courses := fmt.Sprintf("%s/courses?access_token=%s&per_page=100", base_link,token)
49 // var canvas_courses []CanvasCourse
50 //canvas_courses = get_courses(token, favorites, client)
51 //var course_ids []uint64
52 //course_ids = get_course_ids(canvas_courses)
53 //selected := 1 // course_ids[selected]
54 // course selection by user happens above
55 return 0
56}
57*/
58
59func get_aplus(token string, link string, client http.Client) string {
60 resp, err := client.Get(link)
61
62 if err != nil {
63 fmt.Println("Error performing GET request to initial link.")
64 }
65 defer resp.Body.Close()
66 body, err := io.ReadAll(resp.Body)
67
68 if err != nil {
69 fmt.Println("Error reading body of initial aplus html response " +
70 "which is supposed to contain a one-time link for getting the form.")
71 }
72
73 var aplus Aplus
74 json.Unmarshal(body, &aplus)
75
76 return aplus.URL
77}
78
79func get_form_from_request_body(req_body []byte) string {
80 body_str := string(req_body)
81 form_start := strings.Index(body_str, "<form")
82 form_end := strings.Index(body_str, "</form>") + 7
83 form_html := req_body[form_start:form_end]
84
85 return string(form_html)
86}
87
88// parse_form extracts form fields and values from the given HTML form string.
89func parse_form(form_html string) url.Values {
90 form_values := make(url.Values)
91 inputs := strings.Split(form_html, "<input")
92
93 for _, input := range inputs {
94 // Extract field name and value
95 name := extract_attribute(input, "name")
96 value := extract_attribute(input, "value")
97
98 if name != "" {
99 form_values.Add(name, value)
100 }
101 }
102
103 return form_values
104}
105
106func extract_attribute(input string, attribute string) string {
107 start := strings.Index(input, attribute+"=\"")
108 if start == -1 {
109 start = strings.Index(input, attribute+"='")
110 }
111
112 if start == -1 {
113 return ""
114 }
115
116 start += len(attribute) + 2
117
118 end := strings.Index(input[start:], "\"")
119 if end == -1 {
120 end = strings.Index(input[start:], "'")
121 }
122
123 if end == -1 {
124 return ""
125 }
126
127 return input[start : start+end]
128}
diff --git a/main.go b/main.go
index 27dc3fd..0480117 100644
--- a/main.go
+++ b/main.go
@@ -4,9 +4,11 @@ import (
4 "fmt" 4 "fmt"
5 "io" 5 "io"
6 "net/http" 6 "net/http"
7 "os"
8) 7)
9 8
9var base_link string
10var token string
11
10func main() { 12func main() {
11 client := http.Client{ 13 client := http.Client{
12 CheckRedirect: func(req *http.Request, via []*http.Request) error { 14 CheckRedirect: func(req *http.Request, via []*http.Request) error {
@@ -15,8 +17,7 @@ func main() {
15 }, 17 },
16 } 18 }
17 19
18 base_link := "https://floridapolytechnic.instructure.com/api/v1" 20 initialize()
19 token := os.Getenv("CANVAS_API_KEY")
20 21
21 // select_course() 22 // select_course()
22 23
@@ -30,11 +31,7 @@ func main() {
30 } 31 }
31 32
32 defer resp.Body.Close() 33 defer resp.Body.Close()
33 body, err := io.ReadAll(resp.Body) 34 body, _ := io.ReadAll(resp.Body)
34
35 if err != nil {
36 fmt.Println("Error reading body of initial aplus html response.")
37 }
38 35
39 form_str := get_form_from_request_body(body) 36 form_str := get_form_from_request_body(body)
40 fmt.Println(form_str) 37 fmt.Println(form_str)
@@ -62,8 +59,8 @@ func main() {
62 fmt.Println(req) 59 fmt.Println(req)
63 60
64 // we need to submit the above post request correctly in order to submit this request. 61 // we need to submit the above post request correctly in order to submit this request.
65 //resp, err = client.Get("https://floridapoly.aplusattendance.com/canvas/student/?canvasCourse=7329&doStudentAuth=true") 62 //resp, _ = client.Get("https://floridapoly.aplusattendance.com/canvas/student/?canvasCourse=7329&doStudentAuth=true")
66 //body, err = io.ReadAll(req.Body) 63 //body, _ = io.ReadAll(resp.Body)
67 64
68 //fmt.Println(string(body)) 65 //fmt.Println(string(body))
69 //fmt.Println(req) 66 //fmt.Println(req)