UCSBCurriculumService.java

  1. package edu.ucsb.cs156.courses.services;

  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import edu.ucsb.cs156.courses.documents.ConvertedSection;
  4. import edu.ucsb.cs156.courses.documents.CoursePage;
  5. import java.util.Arrays;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.beans.factory.annotation.Value;
  12. import org.springframework.boot.web.client.RestTemplateBuilder;
  13. import org.springframework.http.HttpEntity;
  14. import org.springframework.http.HttpHeaders;
  15. import org.springframework.http.HttpMethod;
  16. import org.springframework.http.HttpStatus;
  17. import org.springframework.http.MediaType;
  18. import org.springframework.http.ResponseEntity;
  19. import org.springframework.stereotype.Service;
  20. import org.springframework.web.client.RestTemplate;

  21. /** Service object that wraps the UCSB Academic Curriculum API */
  22. @Service
  23. @Slf4j
  24. public class UCSBCurriculumService {

  25.   @Autowired private ObjectMapper objectMapper;

  26.   @Value("${app.ucsb.api.consumer_key}")
  27.   private String apiKey;

  28.   private RestTemplate restTemplate = new RestTemplate();

  29.   public UCSBCurriculumService(RestTemplateBuilder restTemplateBuilder) throws Exception {
  30.     restTemplate = restTemplateBuilder.build();
  31.   }

  32.   public static final String CURRICULUM_ENDPOINT =
  33.       "https://api.ucsb.edu/academics/curriculums/v1/classes/search";

  34.   public static final String SUBJECTS_ENDPOINT =
  35.       "https://api.ucsb.edu/students/lookups/v1/subjects";

  36.   public static final String SECTION_ENDPOINT =
  37.       "https://api.ucsb.edu/academics/curriculums/v1/classsection/{quarter}/{enrollcode}";

  38.   public static final String ALL_SECTIONS_ENDPOINT =
  39.       "https://api.ucsb.edu/academics/curriculums/v3/classes/{quarter}/{enrollcode}";

  40.   public String getJSON(String subjectArea, String quarter, String courseLevel) throws Exception {

  41.     HttpHeaders headers = new HttpHeaders();
  42.     headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
  43.     headers.setContentType(MediaType.APPLICATION_JSON);
  44.     headers.set("ucsb-api-version", "1.0");
  45.     headers.set("ucsb-api-key", this.apiKey);

  46.     HttpEntity<String> entity = new HttpEntity<>("body", headers);

  47.     String params =
  48.         String.format(
  49.             "?quarter=%s&subjectCode=%s&objLevelCode=%s&pageNumber=%d&pageSize=%d&includeClassSections=%s",
  50.             quarter, subjectArea, courseLevel, 1, 100, "true");
  51.     String url = CURRICULUM_ENDPOINT + params;

  52.     if (courseLevel.equals("A")) {
  53.       params =
  54.           String.format(
  55.               "?quarter=%s&subjectCode=%s&pageNumber=%d&pageSize=%d&includeClassSections=%s",
  56.               quarter, subjectArea, 1, 100, "true");
  57.       url = CURRICULUM_ENDPOINT + params;
  58.     }

  59.     log.info("url=" + url);

  60.     String retVal = "";
  61.     MediaType contentType = null;
  62.     HttpStatus statusCode = null;

  63.     ResponseEntity<String> re = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
  64.     contentType = re.getHeaders().getContentType();
  65.     statusCode = (HttpStatus) re.getStatusCode();
  66.     retVal = re.getBody();

  67.     log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
  68.     return retVal;
  69.   }

  70.   public List<ConvertedSection> getConvertedSections(
  71.       String subjectArea, String quarter, String courseLevel) throws Exception {
  72.     String json = getJSON(subjectArea, quarter, courseLevel);
  73.     CoursePage coursePage = objectMapper.readValue(json, CoursePage.class);
  74.     List<ConvertedSection> result = coursePage.convertedSections();
  75.     return result;
  76.   }

  77.   public String getSectionJSON(String subjectArea, String quarter, String courseLevel)
  78.       throws Exception {
  79.     List<ConvertedSection> l = getConvertedSections(subjectArea, quarter, courseLevel);

  80.     String arrayToJson = objectMapper.writeValueAsString(l);

  81.     return arrayToJson;
  82.   }

  83.   public String getSubjectsJSON() throws Exception {

  84.     HttpHeaders headers = new HttpHeaders();
  85.     headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
  86.     headers.setContentType(MediaType.APPLICATION_JSON);
  87.     headers.set("ucsb-api-version", "1.0");
  88.     headers.set("ucsb-api-key", this.apiKey);

  89.     HttpEntity<String> entity = new HttpEntity<>("body", headers);

  90.     log.info("url=" + SUBJECTS_ENDPOINT);

  91.     String retVal = "";
  92.     MediaType contentType = null;
  93.     HttpStatus statusCode = null;

  94.     ResponseEntity<String> re =
  95.         restTemplate.exchange(SUBJECTS_ENDPOINT, HttpMethod.GET, entity, String.class);
  96.     contentType = re.getHeaders().getContentType();
  97.     statusCode = (HttpStatus) re.getStatusCode();
  98.     retVal = re.getBody();

  99.     log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
  100.     return retVal;
  101.   }

  102.   /**
  103.    * This method retrieves exactly one section matching the enrollCode and quarter arguments, if
  104.    * such a section exists.
  105.    */
  106.   public String getSection(String enrollCode, String quarter) throws Exception {

  107.     HttpHeaders headers = new HttpHeaders();
  108.     headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
  109.     headers.setContentType(MediaType.APPLICATION_JSON);
  110.     headers.set("ucsb-api-version", "1.0");
  111.     headers.set("ucsb-api-key", this.apiKey);

  112.     HttpEntity<String> entity = new HttpEntity<>("body", headers);

  113.     String url = SECTION_ENDPOINT;

  114.     log.info("url=" + url);

  115.     Map<String, String> params = new HashMap<>();
  116.     params.put("quarter", quarter);
  117.     params.put("enrollcode", enrollCode);

  118.     String retVal = "";
  119.     MediaType contentType = null;
  120.     HttpStatus statusCode = null;

  121.     ResponseEntity<String> re =
  122.         restTemplate.exchange(url, HttpMethod.GET, entity, String.class, params);
  123.     contentType = re.getHeaders().getContentType();
  124.     statusCode = (HttpStatus) re.getStatusCode();
  125.     retVal = re.getBody();

  126.     if (retVal.equals("null")) {
  127.       retVal = "{\"error\": \"Enroll code doesn't exist in that quarter.\"}";
  128.     }

  129.     log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
  130.     return retVal;
  131.   }

  132.   /**
  133.    * This method retrieves all of the sections related to a certain enroll code. For example, if the
  134.    * enrollCode is for a discussion section, the lecture section and all related discussion sections
  135.    * will also be returned.
  136.    */
  137.   public String getAllSections(String enrollCode, String quarter) throws Exception {

  138.     HttpHeaders headers = new HttpHeaders();
  139.     headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
  140.     headers.setContentType(MediaType.APPLICATION_JSON);
  141.     headers.set("ucsb-api-version", "3.0");
  142.     headers.set("ucsb-api-key", this.apiKey);

  143.     HttpEntity<String> entity = new HttpEntity<>("body", headers);

  144.     String url = ALL_SECTIONS_ENDPOINT;

  145.     log.info("url=" + url);

  146.     Map<String, String> params = new HashMap<>();
  147.     params.put("quarter", quarter);
  148.     params.put("enrollcode", enrollCode);

  149.     String retVal = "";
  150.     MediaType contentType = null;
  151.     HttpStatus statusCode = null;

  152.     ResponseEntity<String> re =
  153.         restTemplate.exchange(url, HttpMethod.GET, entity, String.class, params);
  154.     contentType = re.getHeaders().getContentType();
  155.     statusCode = (HttpStatus) re.getStatusCode();
  156.     retVal = re.getBody();

  157.     if (retVal.equals("null")) {
  158.       retVal = "{\"error\": \"Enroll code doesn't exist in that quarter.\"}";
  159.     }

  160.     log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
  161.     return retVal;
  162.   }

  163.   public String getJSONbyQtrEnrollCd(String quarter, String enrollCd) throws Exception {

  164.     HttpHeaders headers = new HttpHeaders();
  165.     headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
  166.     headers.setContentType(MediaType.APPLICATION_JSON);
  167.     headers.set("ucsb-api-version", "1.0");
  168.     headers.set("ucsb-api-key", this.apiKey);

  169.     HttpEntity<String> entity = new HttpEntity<>("body", headers);

  170.     String url =
  171.         "https://api.ucsb.edu/academics/curriculums/v3/classsection/" + quarter + "/" + enrollCd;

  172.     log.info("url=" + url);

  173.     String retVal = "";
  174.     MediaType contentType = null;
  175.     HttpStatus statusCode = null;

  176.     ResponseEntity<String> re = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
  177.     contentType = re.getHeaders().getContentType();
  178.     statusCode = (HttpStatus) re.getStatusCode();
  179.     retVal = re.getBody();

  180.     log.info("json: {} contentType: {} statusCode: {}", retVal, contentType, statusCode);
  181.     return retVal;
  182.   }
  183. }