GithubHelp home page GithubHelp logo

minsoo0715 / everycalendar Goto Github PK

View Code? Open in Web Editor NEW
0.0 0.0 0.0 835 KB

에브리타임 시간표를 ical 형식으로 변환해줍니다.

Home Page: https://ecal.whiteb.dev

Java 83.26% HTML 12.76% CSS 3.03% Dockerfile 0.56% Shell 0.39%

everycalendar's Introduction

Introduction

  • 조민수
    • 한양대학교 ERICA 전자공학부 재학중 (컴퓨터학부 다중전공)
    • 한국디지털미디어고등학교 18기 웹프로그래밍과
    • 🌱 Java/Spring Boot를 학습중입니다.
    • 💻 웹, 특히 백엔드 분야에 관심을 가지고 공부중입니다.
    • 🔭 NGINX, Docker, AWS 등 SE/CE 관련 기술에 대해서도 관심을 가지고 공부중입니다.
    • ⚡ 소프트웨어의 기반이 되는 하드웨어에도 관심이 있습니다.
    • 📝 블로그에 주로 다양한 문제를 해결한 경험을 공유하고 있습니다.

everycalendar's People

Contributors

minsoo0715 avatar

Watchers

 avatar

everycalendar's Issues

에타 API 접근시 RestTemplate를 사용하도록 변경

Desc.

현재 HttpURLConnection 객체를 생성해 에타 API에 접근하고 있습니다. 해당 클래스는 BufferedReader 및 StringBuilder를 통해 직접 문자열 객체로 변경하는 과정이 필요합니다.
해당 객체 대신 ResponseEntity를 반환하는 등 추상화 레벨이 높은 RestTemplate를 사용해 에타 API에 접근하도록 변경합니다.

PR

개강일, 종강일을 학교 정보만으로 자동 입력되도록 변경

Desc.

현재 개강일 / 종강일은 하드코딩되어 있고, 사용자가 직접 선택해야 합니다.
이를 학교별 개강일 / 종강일 정보를 저장하고 사용자가 선택할 수 있도록 합니다.
해당 학교 정보가 없는 경우 사용자가 직접 등록 요청을 할 수 있도록 합니다.

PR

예외 핸들링 추가

Desc.

ControllerAdvice 클래스를 사용하여 예외 핸들링 관련 코드를 작성합니다.
추가적으로 error 페이지를 작성해 사용자가 에러 메시지를 확인할 수 있도록 합니다.

PR

PRG 패턴 적용

Desc.

현재 페이지에서 폼을 작성해 POST /calendar로 이동 후 ics를 다운로드 후 리프레쉬를 하면 서버에서는 다시 로직을 실행합니다.
이를 방지하기 위해서 PRG 패턴을 적용해 form submit -> POST /calendar -> (redirect) -> GET /success의 순서로 PRG 패턴을 적용합니다.
이때 RefreshAttributes Bean을 통해 redirect시 ics 문자열을 넘겨줍니다. 이때, ics 문자열의 크기가 매우 크기 때문에 flashAttribute로서 추가하도록 합니다. (RefreshAttributes.addFlashAttribute 사용)

PR

EveryCalendarService의 메서드들이 최소한의 책임을 가지도록 변경

Desc.

public String createIcsString(String identifier, Date startDate, Date endDate) throws Exception {
        Calendar calendar = new Calendar();

        List<EventDTO> lectures = getLecturesFromEverytime(identifier);

        // EventDTO를 Calendar 객체로 변환
        lectures.forEach(l -> {
            // ...
        });

        return calendar.toString();
    }

    private List<EventDTO> getLecturesFromEverytime(String identifier) throws Exception {
        ResponseEntity<String> response = 
// ... (외부 API 요청)

        String body = response.getBody();

        StringReader bodyReader = new StringReader(body);

        ResponseDTO responseDTO = (ResponseDTO) unmarshaller.unmarshal(new InputSource(bodyReader));

        if(responseDTO.getTable() == null) throw new Exception("시간표 URL이 올바르지 않습니다.");
        if(responseDTO.getTable().getSubjects() == null) throw new Exception("시간표가 공개되어 있지 않거나, 등록된 강의가 없습니다.");

        return responseDTO.convertToEvents();
    }
  • 현재 createIcsString()을 ics 문자열을 생성하는 그 역할에 맞추어 generateCalendar()로 메서드명을 변경합니다.
  • generateCalendar()는 EventDTO를 바탕으로 Calendar 객체를 직접 내부에서 생성하는 로직이 포함됩니다. 해당 메서드의 책임을 최소화하기 위해 해당 로직을createWeeklyCalendarBetween()으로 분리합니다.
  • getLecturesFromEverytime()은 메서드 내부에서 외부 API를 요청해 시간표를 가져오는 역할을 하고 있습니다. 해당 역할에 맞추어 메서드명을 requestTimetable()로 변경합니다.
  • requestTimetable()에서 파싱 테스트의 용이성을 위해 파싱 로직을 parseTimetable()로 분리합니다.
  • requestTimetable()은 외부 API에서 데이터를 받아와 파싱하는 역할만을 수행해야 합니다. 따라서 ResponseDTO.convertToEvents()의 호출을 제거하고 generateCalendar()에서 호출해 EventDTO 리스트로 변환하도록 하기 위해 requestTimetable()이 ResponseDTO를 반환하도록 합니다.

PR

Content Disposition 헤더를 객체로 관리하도록 변경

Desc.

현재 EveryCalendarControllersuccess()에서는 다음과 같이 Content Disposition 헤더를 하드코딩해서 사용하고 있습니다.

return ResponseEntity.ok()
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + "calendar.ics" +"\"")
        .header(HttpHeaders.CONTENT_TYPE, "text/calendar")
        .body(ics);

이를 객체를 사용해 관리하도록 아래와 같이 변경합니다.

ContentDisposition contentDisposition =
        ContentDisposition.attachment().filename("calendar.ics", StandardCharsets.UTF_8).build();

return ResponseEntity.ok()
        .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString())
        .header(HttpHeaders.CONTENT_TYPE, "text/calendar")
        .body(ics);

PR

개강일 다음 날부터 일정이 등록되는 오류

Desc.

개강일의 시작일이 해당 일이 아닌 개강일의 다음주로 설정되는 오류가 발생합니다.
해당 오류는 배포 환경에서만 발생하는 것으로 미루어 볼 때 TimeZone이 달라서 해당 버그가 발생하는 것으로 보입니다(배포: UTC, 개발: Asia/Seoul)

PR

시간표 공개/비공개 관련 문구 및 문의 이메일 추가

Desc.

시간표 비공개 상태에서 URL을 넣으면 오류가 발생하지만, 어떤 방법으로 해결할 수 있는지를 사용자가 알 수 없습니다.
따라서, 시간표 URL을 얻는 과정에 시간표를 공개로 설정하는 단계를 추가합니다. 또한 문의 이메일란도 추가합니다.

PR

배포환경의 timezone이 KST가 아닐 때 잘못된 시간이 설정되는 오류

Desc.

배포 환경의 Timezone이 KST가 아니라면 강의 시간이 올바르게 설정되지 않는 오류가 발생합니다.

Calendar cal = Calendar.getInstance(Locale.KOREA);
cal.setTime(startDate);

cal.set(Calendar.HOUR_OF_DAY, 0);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);

위 코드에서 Locale 설정됨에도 불구하고, UTC 기준 0시로 초기화되어서 KST 기준이 아닌 UTC 기준으로 날짜가 설정됩니다.
따라서 다음 코드를 통해 cal.setTimeZone(TimeZone.getTimeZone("Asia/Seoul")); timezone을 명시적으로 정해줍니다.

PR

jaxb로 파싱하도록 변경

Desc.

현재 코드에서는 DocumentBuilder를 통해 직접 XML을 파싱하고 있습니다.
이를 어노테이션으로 간단하게 파싱할 수 있도록 해주는 jaxb 패키지를 사용하도록 변경합니다.

PR

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.