aplus

A+Attendance CLI utility via Instructure Canvas
Log | Files | Refs | README | LICENSE

canvas.go (2749B)


      1 package main
      2 
      3 import (
      4 	"encoding/json"
      5 	"errors"
      6 	"fmt"
      7 	"io"
      8 	"net/http"
      9 	"net/http/cookiejar"
     10 	"os"
     11 	"strings"
     12 
     13 	"golang.org/x/net/publicsuffix"
     14 )
     15 
     16 func initialize() {
     17 	instance_url := os.Getenv("CANVAS_INSTANCE")
     18 	if len(instance_url) == 0 {
     19 		fmt.Println("The CANVAS_INSTANCE environment variable seems to be empty. Exiting.")
     20 		os.Exit(1)
     21 	}
     22 
     23 	base_link = instance_url + "/api/v1"
     24 	token = os.Getenv("CANVAS_API_KEY")
     25 	if len(token) == 0 {
     26 		fmt.Println("The CANVAS_API_KEY environment variable seems to be empty. Exiting.")
     27 		os.Exit(1)
     28 	}
     29 
     30 	jar, _ := cookiejar.New(&cookiejar.Options{
     31 		PublicSuffixList: publicsuffix.List,
     32 	})
     33 
     34 	client = http.Client{
     35 		CheckRedirect: func(req *http.Request, via []*http.Request) error {
     36 			if verbose {
     37 				fmt.Println("Redirected to:", req.URL)
     38 				fmt.Println(req.Cookies())
     39 			}
     40 			return nil
     41 		},
     42 		Jar: jar,
     43 	}
     44 }
     45 
     46 func get_courses(token string, link string, client http.Client) []CanvasCourse {
     47 	resp, err := client.Get(link)
     48 	if err != nil {
     49 		fmt.Println("Error performing GET request to get courses.")
     50 		return nil
     51 	}
     52 	defer resp.Body.Close()
     53 	body, _ := io.ReadAll(resp.Body)
     54 
     55 	var canvas_courses []CanvasCourse
     56 	err2 := json.Unmarshal(body, &canvas_courses)
     57 	if err2 != nil {
     58 		fmt.Println(err2)
     59 		return nil
     60 	}
     61 
     62 	return canvas_courses
     63 }
     64 
     65 func init_aplus_toolid(course_id int) error {
     66 	link := fmt.Sprintf("%s/courses/%d/external_tools?access_token=%s&search_term=aplus&include_parents=true", base_link, course_id, token)
     67 
     68 	resp, err := client.Get(link)
     69 	if err != nil {
     70 		return err
     71 	}
     72 	defer resp.Body.Close()
     73 	body, _ := io.ReadAll(resp.Body)
     74 
     75 	var external_tools []ExternalTool
     76 	err = json.Unmarshal(body, &external_tools)
     77 	if err != nil && !strings.Contains(string(body), "\"unauthorized\"") {
     78 		return err
     79 	}
     80 
     81 	for _, tool := range external_tools {
     82 		if strings.Contains(tool.URL, ".aplusattendance.com/") {
     83 			base_aplus_link = tool.URL
     84 			external_tools_code = tool.ID
     85 			return nil
     86 		}
     87 	}
     88 
     89 	return errors.New("Could not find A+ link and tool ID")
     90 }
     91 
     92 func list_all_courses(onlyreturn bool) []CanvasCourse {
     93 	all_courses := fmt.Sprintf("%s/courses?access_token=%s&enrollment_state=active&per_page=100", base_link, token)
     94 
     95 	canvas_courses := get_courses(token, all_courses, client)
     96 
     97 	if !onlyreturn {
     98 		for _, course := range canvas_courses {
     99 			fmt.Printf("%d, %s\n", course.ID%10000, course.Name)
    100 		}
    101 
    102 		return nil
    103 	}
    104 
    105 	return canvas_courses
    106 }
    107 
    108 func list_favorite_courses() {
    109 
    110 	// course selection by user happens below
    111 	favorites := fmt.Sprintf("%s/users/self/favorites/courses?access_token=%s&per_page=100", base_link, token)
    112 
    113 	canvas_courses := get_courses(token, favorites, client)
    114 
    115 	for _, course := range canvas_courses {
    116 		fmt.Printf("%d, %s\n", course.ID%10000, course.Name)
    117 	}
    118 }