From 21fe594802ecefadcac4ecb61a28d3c5834efe38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C2=96gniadeck?=
<77535280+gniadeck@users.noreply.github.com>
Date: Sun, 15 Oct 2023 17:50:15 +0200
Subject: [PATCH] :bookmark: Migrate code from dev repository - PWr-API 1.2.0
---
pom.xml | 91 ++-
.../dev/wms/pwrapi/PwrApiApplication.java | 12 +-
.../dev/wms/pwrapi/api/DevelopersAPI.java | 59 ++
.../java/dev/wms/pwrapi/api/EdukacjaAPI.java | 15 +-
.../java/dev/wms/pwrapi/api/EportalAPI.java | 37 +-
.../java/dev/wms/pwrapi/api/EventsAPI.java | 36 +
.../java/dev/wms/pwrapi/api/ForumAPI.java | 169 ++--
.../dev/wms/pwrapi/api/IsJsosDownAPI.java | 65 ++
src/main/java/dev/wms/pwrapi/api/JsosAPI.java | 8 +-
.../java/dev/wms/pwrapi/api/LibraryAPI.java | 30 +
.../java/dev/wms/pwrapi/api/ParkingAPI.java | 8 +-
.../dev/wms/pwrapi/api/StudentStatsAPI.java | 56 ++
.../dev/wms/pwrapi/api/TestController.java | 29 +
src/main/java/dev/wms/pwrapi/api/UsosAPI.java | 22 +
.../java/dev/wms/pwrapi/dao/auth/AuthDao.java | 22 +
.../wms/pwrapi/dao/auth/EportalAuthDao.java | 23 +
.../dev/wms/pwrapi/dao/auth/JsosAuthDao.java | 28 +
.../dev/wms/pwrapi/dao/auth/OauthPwrDao.java | 68 ++
.../dev/wms/pwrapi/dao/auth/OauthUsosDao.java | 55 ++
.../dev/wms/pwrapi/dao/auth/UsosAuthDao.java | 43 +
.../dao/edukacja/EduMessageDAOImpl.java | 51 --
.../pwrapi/dao/edukacja/EduSubjectDAO.java | 4 +-
.../dao/edukacja/EduSubjectDAOImpl.java | 32 +-
.../dao/eportal/EportalCalendarDAO.java | 67 +-
.../wms/pwrapi/dao/eportal/EportalDAO.java | 150 ++--
.../dev/wms/pwrapi/dao/events/EventsDAO.java | 13 +
.../wms/pwrapi/dao/events/EventsDAOImpl.java | 79 ++
.../dao/forum/DatabaseMetadataRepository.java | 11 +
.../dev/wms/pwrapi/dao/forum/ForumDAO.java | 65 --
.../wms/pwrapi/dao/forum/ForumDAOImpl.java | 231 ------
.../pwrapi/dao/forum/ReviewRepository.java | 16 +
.../pwrapi/dao/forum/TeacherRepository.java | 19 +
.../google/calendar/GoogleCalendarDAO.java | 20 +
.../calendar/GoogleCalendarDAOImpl.java | 71 ++
.../dao/isjsosdown/IsJsosDownClient.java | 42 +
.../dev/wms/pwrapi/dao/jsos/JsosDataDAO.java | 17 +-
.../wms/pwrapi/dao/jsos/JsosDataDAOImpl.java | 66 +-
.../wms/pwrapi/dao/jsos/JsosGeneralDAO.java | 25 -
.../pwrapi/dao/jsos/JsosGeneralDAOImpl.java | 115 ---
.../pwrapi/dao/jsos/JsosLessonsDAOImpl.java | 40 +-
.../pwrapi/dao/library/LibraryAuthDao.java | 13 +
.../wms/pwrapi/dao/library/LibraryDAO.java | 42 +
.../java/dev/wms/pwrapi/dao/news/NewsDAO.java | 16 +-
.../wms/pwrapi/dao/parking/IParkingDAO.java | 81 +-
.../wms/pwrapi/dao/parking/SKDParkingDAO.java | 8 +-
.../dao/prowadzacy/ProwadzacyDAOImpl.java | 28 +-
.../token/ConfirmationTokenRepository.java | 18 +
.../pwrapi/dao/user/ApiUserRepository.java | 24 +
.../wms/pwrapi/dao/usos/UsosApiClient.java | 9 +
.../dev/wms/pwrapi/dao/usos/UsosDataDAO.java | 39 +
.../wms/pwrapi/dao/usos/UsosMarksProxy.java | 38 +
.../pwrapi/dao/usos/UsosProxyApiClient.java | 51 ++
.../wms/pwrapi/dao/usos/UsosStudiesDao.java | 137 ++++
.../studentstats/StudentStatsCategory.java | 13 +
.../java/dev/wms/pwrapi/dto/ApiException.java | 73 ++
.../wms/pwrapi/dto/ExceptionMessagingDTO.java | 24 -
.../pwrapi/dto/edukacja/EduConnection.java | 25 -
.../dto/edukacja/EdukacjaConnection.java | 7 +
.../wms/pwrapi/dto/eportal/courseTitle.java | 6 +-
.../dto/eportal/sections/EportalSection.java | 6 +-
.../sections/EportalSectionElement.java | 6 -
.../wms/pwrapi/dto/eportal/userDetails.java | 2 +-
.../dev/wms/pwrapi/dto/events/EventDto.java | 17 +
.../wms/pwrapi/dto/google/GoogleBaseDTO.java | 22 +
.../pwrapi/dto/google/GoogleCalendarDTO.java | 19 +
.../wms/pwrapi/dto/google/GoogleDateDTO.java | 44 ++
.../wms/pwrapi/dto/google/GoogleEventDTO.java | 34 +
.../google/converters/EventDTOConverter.java | 69 ++
.../dto/isjsosdown/AdditionalStatsDTO.java | 20 +
.../dto/isjsosdown/DowntimeChartDataDTO.java | 10 +
.../pwrapi/dto/isjsosdown/DowntimeDTO.java | 27 +
.../dto/isjsosdown/DowntimeStatsDTO.java | 7 +
.../isjsosdown/DowntimeStatsRankingDTO.java | 13 +
.../pwrapi/dto/isjsosdown/HeadToHeadDTO.java | 10 +
.../InitialDownServiceStatsDTO.java | 15 +
.../isjsosdown/InitialServiceStatsDTO.java | 16 +
.../dto/isjsosdown/InitialStatsDTO.java | 10 +
.../wms/pwrapi/dto/isjsosdown/ServiceDTO.java | 8 +
.../dto/isjsosdown/TrackedServiceDTO.java | 7 +
.../dto/isjsosdown/TrafficStatsDTO.java | 9 +
.../wms/pwrapi/dto/library/LibraryTitle.java | 11 +
.../converters/LibraryDtoConverter.java | 45 ++
.../LibraryAdditionalProperties.java | 8 +
.../LibraryDisplayProperties.java | 9 +
.../LibraryResourceProperties.java | 4 +
.../LibraryResultProperties.java | 5 +
.../LibraryResultResponse.java | 4 +
.../LibrarySearchResponse.java | 6 +
.../dto/news/{Rss.java => NewsRss.java} | 2 +-
.../dto/thread/SemaphoredRateLimitData.java | 20 +
.../dev/wms/pwrapi/dto/usos/UsosCourse.java | 18 +
.../dev/wms/pwrapi/dto/usos/UsosSemester.java | 11 +
.../pwrapi/dto/usos/UsosStudentStatus.java | 7 +
.../dev/wms/pwrapi/dto/usos/UsosStudies.java | 22 +
.../dev/wms/pwrapi/dto/usos/UsosUser.java | 7 +
.../dev/wms/pwrapi/entity/edukacja/Group.java | 40 +-
.../wms/pwrapi/entity/edukacja/Subject.java | 41 +-
.../dev/wms/pwrapi/entity/forum/Review.java | 91 +--
.../dev/wms/pwrapi/entity/forum/Teacher.java | 87 +-
.../entity/token/ConfirmationToken.java | 27 +
.../dev/wms/pwrapi/entity/user/ApiUser.java | 64 ++
.../rateLimit/AdjustableRateLimitData.java | 27 +
.../entity/user/rateLimit/RateLimitData.java | 15 +
.../java/dev/wms/pwrapi/http/CORSFilter.java | 1 -
.../AbstractStudentStatsContent.java | 12 +
.../model/studentStats/StudentStatsChart.java | 17 +
.../studentStats/StudentStatsChartType.java | 7 +
.../studentStats/StudentStatsChartValue.java | 17 +
.../model/studentStats/StudentStatsData.java | 13 +
.../studentStats/StudentStatsDoubleText.java | 28 +
.../model/studentStats/StudentStatsFlag.java | 12 +
.../studentStats/StudentStatsObject.java | 22 +
.../StudentStatsPersonalData.java | 23 +
.../model/studentStats/StudentStatsText.java | 27 +
...ices.java => EdukacjaScrapperService.java} | 68 +-
.../eportal/EportalScrapperService.java | 98 ---
...Services.java => JsosScrapperService.java} | 73 +-
.../wms/pwrapi/security/SecurityConfig.java | 109 +++
.../security/encryption/SymmetricEncrypt.java | 10 +
.../encryption/SymmetricEncryptImpl.java | 74 ++
.../pwrapi/security/filters/ApiKeyFilter.java | 50 ++
.../filters/ApiKeyRateLimitFilter.java | 64 ++
.../security/filters/EnabledUserFilter.java | 34 +
.../filters/ExceptionHandlerFilter.java | 37 +
.../service/edukacja/EduServiceImpl.java | 9 +-
.../pwrapi/service/email/EmailService.java | 10 +
.../service/email/EmailServiceImpl.java | 36 +
.../service/eportal/EportalService.java | 8 +-
.../service/eportal/EportalServiceImpl.java | 11 +-
.../pwrapi/service/events/EventsService.java | 13 +
.../service/events/EventsServiceImpl.java | 25 +
.../pwrapi/service/forum/ForumService.java | 24 -
.../service/forum/ForumServiceImpl.java | 147 ++--
.../pwrapi/service/html/MarkdownService.java | 6 +
.../service/html/MarkdownServiceImpl.java | 30 +
.../styling/HeadingAttributeProvider.java | 26 +
.../html/styling/TextAttributeProvider.java | 16 +
.../LocalizedMessageService.java | 68 ++
.../LocalizedMessageServiceImpl.java | 53 ++
.../SupportedLanguage.java | 27 +
.../service/isjsosdown/IsJsosDownService.java | 57 ++
.../wms/pwrapi/service/jsos/JsosService.java | 13 +-
.../pwrapi/service/jsos/JsosServiceImpl.java | 48 +-
.../service/library/LibraryService.java | 20 +
.../service/metrics/ApiMetricsService.java | 8 +
.../metrics/ApiMetricsServiceImpl.java | 34 +
.../wms/pwrapi/service/news/NewsService.java | 2 -
.../pwrapi/service/parking/ParkingProxy.java | 2 +-
.../service/parking/ParkingService.java | 2 +-
.../service/parking/ParkingServiceImpl.java | 4 +-
.../prowadzacy/ProwadzacyServiceImpl.java | 9 +-
.../service/rateLimit/ApiUserRateLimiter.java | 45 ++
.../rateLimit/IpInMemoryRateLimiter.java | 42 +
.../pwrapi/service/rateLimit/RateLimiter.java | 95 +++
.../service/samorzad/SamorzadService.java | 34 +
.../service/samorzad/SamorzadServiceImpl.java | 53 ++
.../CourseDataDecisionExtractorStrategy.java | 67 ++
.../CourseDataDetailsExtractorStrategy.java | 11 +
.../CourseDataExtractionStrategy.java | 8 +
.../studentStats/StudentStatsDataService.java | 17 +
.../StudentStatsPersonalDataService.java | 53 ++
.../studentStats/StudentStatsService.java | 10 +
.../studentStats/StudentStatsServiceImpl.java | 747 ++++++++++++++++++
.../service/studentStats/UsosCardService.java | 80 ++
.../cards/usos/UsosAveragesCardCreator.java | 145 ++++
.../cards/usos/UsosCardCreator.java | 20 +
.../cards/usos/UsosCoursesCardCreator.java | 207 +++++
.../usos/UsosTeacherRatingCardCreator.java | 153 ++++
.../cards/usos/UsosTimeCardCreator.java | 86 ++
.../errors/StudentStatsErrorReporter.java | 23 +
.../pwrapi/service/token/TokenService.java | 19 +
.../service/token/TokenServiceImpl.java | 62 ++
.../pwrapi/service/user/ApiUserFactory.java | 33 +
.../pwrapi/service/user/ApiUserService.java | 15 +
.../service/user/ApiUserServiceImpl.java | 119 +++
.../wms/pwrapi/service/usos/UsosService.java | 7 +
.../pwrapi/service/usos/UsosServiceImpl.java | 18 +
.../wms/pwrapi/utils/common/DateFormats.java | 11 +
.../wms/pwrapi/utils/common/DateUtils.java | 70 ++
.../pwrapi/utils/common/JsonParsingUtils.java | 15 +
.../wms/pwrapi/utils/common/PageRequest.java | 10 +
.../utils/common/ResourceLoaderUtils.java | 28 +
.../wms/pwrapi/utils/common/URLValidator.java | 17 +
.../config/BuildPropertiesConfiguration.java | 22 +
.../pwrapi/utils/config/CachingConfig.java | 23 +-
.../utils/config/EnumMappingConfig.java | 14 +
.../pwrapi/utils/config/ExceptionHandler.java | 5 +
.../utils/config/ExceptionReporter.java | 21 +
.../config/GitPropertiesConfiguration.java | 21 +
.../LocalDateTimeFromMillisDeserializer.java | 19 +
.../utils/config/MessageSourceConfig.java | 20 +
.../pwrapi/utils/config/SentryReporter.java | 86 ++
.../pwrapi/utils/config/SwaggerConfig.java | 40 +
.../pwrapi/utils/cookies/CookieJarImpl.java | 56 +-
.../utils/csv/appendable/CSVAppendable.java | 9 +
.../pwrapi/utils/csv/builder/CSVBuilder.java | 13 +
.../csv/builder/StringBuilderCSVBuilder.java | 30 +
.../edukacja/advice/EdukacjaAPIAdvice.java | 19 +-
.../pwrapi/utils/email/EmailTextBuilder.java | 48 ++
.../wms/pwrapi/utils/email/EmailUtils.java | 104 +++
.../eportal/advice/EportalAPIAdvice.java | 24 +-
.../utils/forum/advice/ForumAPIAdvice.java | 38 +-
.../utils/forum/config/SpringJdbcConfig.java | 23 -
.../pwrapi/utils/forum/consts/Category.java | 13 +
.../utils/forum/dto/DatabaseMetadataDTO.java | 33 +-
.../utils/forum/dto/ReviewWithTeacherDTO.java | 39 +
.../utils/forum/dto/TeacherInfoDTO.java | 43 +
.../forum/dto/TeacherWithReviewsDTO.java | 38 +
.../CategoryMembersNotFoundException.java | 13 +-
.../exceptions/ReviewNotFoundException.java | 8 +-
.../exceptions/TeacherNotFoundException.java | 11 +
.../forum/rowMappers/ReviewRowMapper.java | 27 -
.../ReviewWithTeacherRowMapper.java | 32 -
.../forum/rowMappers/TeacherRowMapper.java | 25 -
.../GeneralAdvice.java | 83 +-
.../ResponseMessageHandler.java | 19 -
.../ConstraintViolationExceptionAdvice.java | 13 +-
.../ExpiredConfirmationTokenException.java | 12 +
.../generalExceptions/RateLimitException.java | 12 +
.../ResourceNotFoundException.java | 8 +
.../SystemTimeoutException.java | 2 +-
.../wms/pwrapi/utils/html/HtmlBuilder.java | 40 +
.../dev/wms/pwrapi/utils/http/HttpClient.java | 108 +++
.../dev/wms/pwrapi/utils/http/HttpUtils.java | 82 --
.../utils/http/helpers/ResponseAndStatus.java | 9 +
.../jsonProcessing/ObjectMapperJSON.java | 13 -
.../wms/pwrapi/utils/jsos/JsosHttpUtils.java | 28 -
.../pwrapi/utils/jsos/JsosLessonsUtils.java | 61 +-
.../utils/jsos/advice/JsosAPIAdvice.java | 35 +-
.../utils/jsos/cookies/CookieJarImpl.java | 7 +-
.../wms/pwrapi/utils/map/ExpirationCache.java | 161 ++++
.../utils/map/TimestampedContainer.java | 31 +
.../notifications/NotificationService.java | 7 +
.../utils/parking/advice/ParkingAdvice.java | 35 -
.../utils/properties/PropertiesProvider.java | 19 +
.../advices/EmptyResultsExceptionAdvice.java | 11 +-
src/main/resources/application.properties | 92 ++-
.../resources/messages/messages_en.properties | 91 +++
.../resources/messages/messages_pl.properties | 59 ++
.../resources/templates/email/banner.html | 24 +
.../resources/templates/email/footer.html | 38 +
src/main/resources/templates/email/text.html | 20 +
.../templates/email/text_button.html | 23 +
.../templates/email/text_wrapper.html | 20 +
.../resources/templates/email/wrapper.html | 19 +
src/test/java/dev/wms/pwrapi/BaseTest.java | 17 +
.../java/dev/wms/pwrapi/forum/ForumTests.java | 43 -
.../wms/pwrapi/jsos/UtilsClassesTests.java | 11 +-
.../NationalizedMessageServiceTest.java | 46 ++
.../wms/pwrapi/parking/ParkingProxyTest.java | 2 +
.../dev/wms/pwrapi/parking/ParkingTests.java | 1 +
.../pwrapi/prowadzacy/ProwadzacyTests.java | 28 +-
.../IpRateLimiterThreadSafetyTest.java | 91 +++
.../events/EventsServiceCachingTests.java | 40 +
.../service/news/NewsServiceCachingTest.java | 1 +
.../utils/common/JsonParsingUtilsTest.java | 27 +
.../utils/cookies/CookieJarImplTest.java | 135 ++++
.../resources/messages/messages_en.properties | 2 +
.../resources/messages/messages_pl.properties | 2 +
259 files changed, 7786 insertions(+), 2187 deletions(-)
create mode 100644 src/main/java/dev/wms/pwrapi/api/DevelopersAPI.java
create mode 100644 src/main/java/dev/wms/pwrapi/api/EventsAPI.java
create mode 100644 src/main/java/dev/wms/pwrapi/api/IsJsosDownAPI.java
create mode 100644 src/main/java/dev/wms/pwrapi/api/LibraryAPI.java
create mode 100644 src/main/java/dev/wms/pwrapi/api/StudentStatsAPI.java
create mode 100644 src/main/java/dev/wms/pwrapi/api/TestController.java
create mode 100644 src/main/java/dev/wms/pwrapi/api/UsosAPI.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/auth/AuthDao.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/auth/EportalAuthDao.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/auth/JsosAuthDao.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/auth/OauthPwrDao.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/auth/OauthUsosDao.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/auth/UsosAuthDao.java
delete mode 100644 src/main/java/dev/wms/pwrapi/dao/edukacja/EduMessageDAOImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/events/EventsDAO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/events/EventsDAOImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/forum/DatabaseMetadataRepository.java
delete mode 100644 src/main/java/dev/wms/pwrapi/dao/forum/ForumDAO.java
delete mode 100644 src/main/java/dev/wms/pwrapi/dao/forum/ForumDAOImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/forum/ReviewRepository.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/forum/TeacherRepository.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/google/calendar/GoogleCalendarDAO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/google/calendar/GoogleCalendarDAOImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/isjsosdown/IsJsosDownClient.java
delete mode 100644 src/main/java/dev/wms/pwrapi/dao/jsos/JsosGeneralDAO.java
delete mode 100644 src/main/java/dev/wms/pwrapi/dao/jsos/JsosGeneralDAOImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/library/LibraryAuthDao.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/library/LibraryDAO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/token/ConfirmationTokenRepository.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/user/ApiUserRepository.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/usos/UsosApiClient.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/usos/UsosDataDAO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/usos/UsosMarksProxy.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/usos/UsosProxyApiClient.java
create mode 100644 src/main/java/dev/wms/pwrapi/dao/usos/UsosStudiesDao.java
create mode 100644 src/main/java/dev/wms/pwrapi/domain/studentstats/StudentStatsCategory.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/ApiException.java
delete mode 100644 src/main/java/dev/wms/pwrapi/dto/ExceptionMessagingDTO.java
delete mode 100644 src/main/java/dev/wms/pwrapi/dto/edukacja/EduConnection.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/edukacja/EdukacjaConnection.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/events/EventDto.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/google/GoogleBaseDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/google/GoogleCalendarDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/google/GoogleDateDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/google/GoogleEventDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/google/converters/EventDTOConverter.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/AdditionalStatsDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/DowntimeChartDataDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/DowntimeDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/DowntimeStatsDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/DowntimeStatsRankingDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/HeadToHeadDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/InitialDownServiceStatsDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/InitialServiceStatsDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/InitialStatsDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/ServiceDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/TrackedServiceDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/isjsosdown/TrafficStatsDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/library/LibraryTitle.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/library/converters/LibraryDtoConverter.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/library/deserialization/LibraryAdditionalProperties.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/library/deserialization/LibraryDisplayProperties.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/library/deserialization/LibraryResourceProperties.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/library/deserialization/LibraryResultProperties.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/library/deserialization/LibraryResultResponse.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/library/deserialization/LibrarySearchResponse.java
rename src/main/java/dev/wms/pwrapi/dto/news/{Rss.java => NewsRss.java} (91%)
create mode 100644 src/main/java/dev/wms/pwrapi/dto/thread/SemaphoredRateLimitData.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/usos/UsosCourse.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/usos/UsosSemester.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/usos/UsosStudentStatus.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/usos/UsosStudies.java
create mode 100644 src/main/java/dev/wms/pwrapi/dto/usos/UsosUser.java
create mode 100644 src/main/java/dev/wms/pwrapi/entity/token/ConfirmationToken.java
create mode 100644 src/main/java/dev/wms/pwrapi/entity/user/ApiUser.java
create mode 100644 src/main/java/dev/wms/pwrapi/entity/user/rateLimit/AdjustableRateLimitData.java
create mode 100644 src/main/java/dev/wms/pwrapi/entity/user/rateLimit/RateLimitData.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/AbstractStudentStatsContent.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsChart.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsChartType.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsChartValue.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsData.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsDoubleText.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsFlag.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsObject.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsPersonalData.java
create mode 100644 src/main/java/dev/wms/pwrapi/model/studentStats/StudentStatsText.java
rename src/main/java/dev/wms/pwrapi/scrapper/edukacja/{EduScrapperServices.java => EdukacjaScrapperService.java} (73%)
delete mode 100644 src/main/java/dev/wms/pwrapi/scrapper/eportal/EportalScrapperService.java
rename src/main/java/dev/wms/pwrapi/scrapper/jsos/{JsosScrapperServices.java => JsosScrapperService.java} (62%)
create mode 100644 src/main/java/dev/wms/pwrapi/security/SecurityConfig.java
create mode 100644 src/main/java/dev/wms/pwrapi/security/encryption/SymmetricEncrypt.java
create mode 100644 src/main/java/dev/wms/pwrapi/security/encryption/SymmetricEncryptImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/security/filters/ApiKeyFilter.java
create mode 100644 src/main/java/dev/wms/pwrapi/security/filters/ApiKeyRateLimitFilter.java
create mode 100644 src/main/java/dev/wms/pwrapi/security/filters/EnabledUserFilter.java
create mode 100644 src/main/java/dev/wms/pwrapi/security/filters/ExceptionHandlerFilter.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/email/EmailService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/email/EmailServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/events/EventsService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/events/EventsServiceImpl.java
delete mode 100644 src/main/java/dev/wms/pwrapi/service/forum/ForumService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/html/MarkdownService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/html/MarkdownServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/html/styling/HeadingAttributeProvider.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/html/styling/TextAttributeProvider.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/internationalization/LocalizedMessageService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/internationalization/LocalizedMessageServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/internationalization/SupportedLanguage.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/isjsosdown/IsJsosDownService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/library/LibraryService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/metrics/ApiMetricsService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/metrics/ApiMetricsServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/rateLimit/ApiUserRateLimiter.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/rateLimit/IpInMemoryRateLimiter.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/rateLimit/RateLimiter.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/samorzad/SamorzadService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/samorzad/SamorzadServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/CourseDataDecisionExtractorStrategy.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/CourseDataDetailsExtractorStrategy.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/CourseDataExtractionStrategy.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/StudentStatsDataService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/StudentStatsPersonalDataService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/StudentStatsService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/StudentStatsServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/UsosCardService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/cards/usos/UsosAveragesCardCreator.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/cards/usos/UsosCardCreator.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/cards/usos/UsosCoursesCardCreator.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/cards/usos/UsosTeacherRatingCardCreator.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/cards/usos/UsosTimeCardCreator.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/studentStats/errors/StudentStatsErrorReporter.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/token/TokenService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/token/TokenServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/user/ApiUserFactory.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/user/ApiUserService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/user/ApiUserServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/usos/UsosService.java
create mode 100644 src/main/java/dev/wms/pwrapi/service/usos/UsosServiceImpl.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/common/DateFormats.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/common/DateUtils.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/common/JsonParsingUtils.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/common/PageRequest.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/common/ResourceLoaderUtils.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/common/URLValidator.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/BuildPropertiesConfiguration.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/EnumMappingConfig.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/ExceptionHandler.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/ExceptionReporter.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/GitPropertiesConfiguration.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/LocalDateTimeFromMillisDeserializer.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/MessageSourceConfig.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/SentryReporter.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/config/SwaggerConfig.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/csv/appendable/CSVAppendable.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/csv/builder/CSVBuilder.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/csv/builder/StringBuilderCSVBuilder.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/email/EmailTextBuilder.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/email/EmailUtils.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/config/SpringJdbcConfig.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/consts/Category.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/dto/ReviewWithTeacherDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/dto/TeacherInfoDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/dto/TeacherWithReviewsDTO.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/exceptions/TeacherNotFoundException.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/rowMappers/ReviewRowMapper.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/rowMappers/ReviewWithTeacherRowMapper.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/forum/rowMappers/TeacherRowMapper.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/generalExceptionHandling/ResponseMessageHandler.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/generalExceptions/ExpiredConfirmationTokenException.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/generalExceptions/RateLimitException.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/generalExceptions/ResourceNotFoundException.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/html/HtmlBuilder.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/http/HttpClient.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/http/HttpUtils.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/http/helpers/ResponseAndStatus.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/jsonProcessing/ObjectMapperJSON.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/jsos/JsosHttpUtils.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/map/ExpirationCache.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/map/TimestampedContainer.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/notifications/NotificationService.java
delete mode 100644 src/main/java/dev/wms/pwrapi/utils/parking/advice/ParkingAdvice.java
create mode 100644 src/main/java/dev/wms/pwrapi/utils/properties/PropertiesProvider.java
create mode 100644 src/main/resources/messages/messages_en.properties
create mode 100644 src/main/resources/messages/messages_pl.properties
create mode 100644 src/main/resources/templates/email/banner.html
create mode 100644 src/main/resources/templates/email/footer.html
create mode 100644 src/main/resources/templates/email/text.html
create mode 100644 src/main/resources/templates/email/text_button.html
create mode 100644 src/main/resources/templates/email/text_wrapper.html
create mode 100644 src/main/resources/templates/email/wrapper.html
create mode 100644 src/test/java/dev/wms/pwrapi/BaseTest.java
delete mode 100644 src/test/java/dev/wms/pwrapi/forum/ForumTests.java
create mode 100644 src/test/java/dev/wms/pwrapi/languages/NationalizedMessageServiceTest.java
create mode 100644 src/test/java/dev/wms/pwrapi/rateLimiting/IpRateLimiterThreadSafetyTest.java
create mode 100644 src/test/java/dev/wms/pwrapi/service/events/EventsServiceCachingTests.java
create mode 100644 src/test/java/dev/wms/pwrapi/utils/common/JsonParsingUtilsTest.java
create mode 100644 src/test/java/dev/wms/pwrapi/utils/cookies/CookieJarImplTest.java
create mode 100644 src/test/resources/messages/messages_en.properties
create mode 100644 src/test/resources/messages/messages_pl.properties
diff --git a/pom.xml b/pom.xml
index f12dc2b..0041097 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.6.7
+ 2.6.7
dev.wms
@@ -14,9 +14,23 @@
pwr-api
Unofficial PWr's api that provides access to all internal university systems at your fingertips.
- 11
-
+ 17
+ 17
+
+
+ io.micrometer
+ micrometer-registry-prometheus
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ io.sentry
+ sentry-spring-boot-starter
+ 6.13.1
+
org.springframework.boot
spring-boot-starter-cache
@@ -28,17 +42,22 @@
org.springframework.boot
- spring-boot-starter-web
-
+ spring-boot-starter-web
+
org.projectlombok
lombok
true
-
+
+
+ com.google.guava
+ guava
+ 32.0.1-jre
+
org.springframework.boot
spring-boot-starter-test
- test
+ test
org.springframework.boot
@@ -49,6 +68,10 @@
spring-jdbc
5.3.21
+
+ org.springframework.boot
+ spring-boot-starter-data-jdbc
+
org.springdoc
springdoc-openapi-ui
@@ -107,12 +130,14 @@
org.springframework.cloud
spring-cloud-starter-bootstrap
- 3.1.1
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
org.springframework.cloud
spring-cloud-starter-config
- 3.1.1
com.microsoft.azure
@@ -130,7 +155,31 @@
json-schema-validator
5.1.1
-
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.commonmark
+ commonmark
+ 0.21.0
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ 2021.0.2
+ pom
+ import
+
+
+
@@ -152,17 +201,17 @@
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
- org.projectlombok
- lombok
-
-
-
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
org.apache.maven.plugins
diff --git a/src/main/java/dev/wms/pwrapi/PwrApiApplication.java b/src/main/java/dev/wms/pwrapi/PwrApiApplication.java
index 2fa4cda..2d17d69 100644
--- a/src/main/java/dev/wms/pwrapi/PwrApiApplication.java
+++ b/src/main/java/dev/wms/pwrapi/PwrApiApplication.java
@@ -1,14 +1,16 @@
package dev.wms.pwrapi;
-import java.io.IOException;
-
-import com.fasterxml.jackson.core.exc.StreamWriteException;
-import com.fasterxml.jackson.databind.DatabindException;
-
+import io.swagger.v3.oas.annotations.OpenAPIDefinition;
+import io.swagger.v3.oas.annotations.servers.Server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
+@OpenAPIDefinition(servers = @Server(url = "/", description = "Default Server URL"))
+@EnableAsync(proxyTargetClass = true)
+@EnableFeignClients
public class PwrApiApplication {
public static void main(String[] args) {
diff --git a/src/main/java/dev/wms/pwrapi/api/DevelopersAPI.java b/src/main/java/dev/wms/pwrapi/api/DevelopersAPI.java
new file mode 100644
index 0000000..30268d7
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/api/DevelopersAPI.java
@@ -0,0 +1,59 @@
+package dev.wms.pwrapi.api;
+
+import dev.wms.pwrapi.service.internationalization.LocalizedMessageService;
+import dev.wms.pwrapi.service.internationalization.SupportedLanguage;
+import dev.wms.pwrapi.service.user.ApiUserService;
+import dev.wms.pwrapi.utils.config.SentryReporter;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirements;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/developers")
+@RequiredArgsConstructor
+@SecurityRequirements
+public class DevelopersAPI {
+
+ private final SentryReporter sentryReporter;
+ private final ApiUserService userService;
+ private final LocalizedMessageService msgService;
+
+ @PostMapping("/feedback")
+ @Operation(summary = "Send feedback to API Developers! Or request help with exception", description = "Wanna send feedback to us? Just simply" +
+ " invoke this POST request! Every successfull response is us getting notified about your message :) Leave " +
+ "your contact details there, if you want us to contact you about your feedback. You can also paste you supportCode " +
+ "so we can investigate your issue faster")
+ public ResponseEntity sendFeedback(@RequestParam(required = false) String email,
+ @RequestParam(required = false) String name,
+ @RequestParam(required = false) String errorId,
+ String feedback) {
+ sentryReporter.captureFeedback(feedback, email, name, errorId);
+ return ResponseEntity.ok("Thank you for your feedback!");
+ }
+
+ @PostMapping("/register")
+ public ResponseEntity registerUser(@RequestParam String email) {
+ userService.registerUser(email);
+
+ return ResponseEntity.ok(msgService.getMessage(
+ "msg.mail.subject.registration",
+ SupportedLanguage.EN)
+ );
+ }
+
+
+ @GetMapping("/confirm-email")
+ @Operation(summary = "Confirm email of the user using token", description = "This endpoint is used in email when " +
+ "user is prompted to confirm the email address. The method is GET as POST is sometimes restricted by email " +
+ "clients. If used twice will REMOVE previous api keys from user account")
+ public ResponseEntity confirmEmail(@RequestParam String token) {
+ userService.confirmEmail(token);
+
+ return ResponseEntity.ok(msgService.getMessageWithArgs(
+ "msg.mail.subject.generated-api-key",
+ SupportedLanguage.EN)
+ );
+ }
+}
diff --git a/src/main/java/dev/wms/pwrapi/api/EdukacjaAPI.java b/src/main/java/dev/wms/pwrapi/api/EdukacjaAPI.java
index 3aabbf6..658014e 100644
--- a/src/main/java/dev/wms/pwrapi/api/EdukacjaAPI.java
+++ b/src/main/java/dev/wms/pwrapi/api/EdukacjaAPI.java
@@ -4,10 +4,10 @@
import java.util.List;
import dev.wms.pwrapi.entity.edukacja.Subject;
-import dev.wms.pwrapi.scrapper.edukacja.EduScrapperServices;
+import dev.wms.pwrapi.scrapper.edukacja.EdukacjaScrapperService;
import dev.wms.pwrapi.service.edukacja.EduService;
import io.swagger.v3.oas.annotations.Operation;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@@ -17,14 +17,11 @@
@RestController
@RequestMapping(value = "/api/edukacja", produces = "application/json")
+@RequiredArgsConstructor
public class EdukacjaAPI {
- private EduService edukacjaService;
-
- @Autowired
- public EdukacjaAPI(EduService edukacjaService){
- this.edukacjaService = edukacjaService;
- }
+ private final EduService edukacjaService;
+ private final EdukacjaScrapperService scrapperService;
@GetMapping("/wektor")
@Operation(summary = "Return available group for user's most recent enrollments",
@@ -39,6 +36,6 @@ public ResponseEntity> getAvailableGroups(@RequestParam("login") S
@Operation(summary = "Checks if login and password can be used to login to edukacja.cl",
description = "Just a simple endpoint. You can use it to validate data and save it for later")
public void loginToEdukacja(@RequestParam("login") String login, @RequestParam("password") String password) throws IOException{
- EduScrapperServices.fetchHTMLConnectionDetails(login, password);
+ scrapperService.fetchHTMLConnectionDetails(login, password);
}
}
diff --git a/src/main/java/dev/wms/pwrapi/api/EportalAPI.java b/src/main/java/dev/wms/pwrapi/api/EportalAPI.java
index a2c1902..3d1ef56 100644
--- a/src/main/java/dev/wms/pwrapi/api/EportalAPI.java
+++ b/src/main/java/dev/wms/pwrapi/api/EportalAPI.java
@@ -3,13 +3,12 @@
import java.io.IOException;
import java.util.List;
-import com.fasterxml.jackson.core.JsonProcessingException;
-
import dev.wms.pwrapi.entity.eportal.MarkSummary;
import dev.wms.pwrapi.entity.eportal.calendar.CalendarMonth;
import dev.wms.pwrapi.dto.eportal.sections.EportalSection;
import dev.wms.pwrapi.service.eportal.EportalService;
import io.swagger.v3.oas.annotations.Operation;
+import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -27,43 +26,35 @@
@RestController
@RequestMapping(value = "/api/eportal", produces = "application/json")
+@RequiredArgsConstructor
public class EportalAPI {
- private EportalService eService;
-
- @Autowired
- public EportalAPI(EportalService eService){
- this.eService = eService;
- }
+ private final EportalService eportalService;
- @GetMapping()
+ @GetMapping
@Operation(summary = "Validates ePortal login data", description = "Can be used to cache login and password for later API usage")
- public void getEportalData(@RequestParam String login, @RequestParam String password) throws JsonProcessingException, IOException, LoginException {
- eService.getEportalData(login, password);
+ public void getEportalData(@RequestParam String login, @RequestParam String password) throws LoginException {
+ eportalService.getEportalData(login, password);
}
@GetMapping("/kursy")
@Operation(summary = "Returns all courses of the given user")
public ResponseEntity getEportalKursy(@RequestParam String login, @RequestParam String password) throws IOException, LoginException {
-
- String result = eService.getEportalKursy(login, password);
-
- return ResponseEntity.status(HttpStatus.OK).body(result);
+ return ResponseEntity.status(HttpStatus.OK).body(eportalService.getEportalKursy(login, password));
}
@GetMapping("/kurs/{id}/sekcje")
@Operation(summary = "Returns all sections for the given course", description = "You can fetch the course ID using /kursy endpoint")
- public ResponseEntity> getEportalSekcje(@RequestParam String login, @RequestParam String password, @PathVariable int id) throws JsonProcessingException, IOException, LoginException, WrongCourseIdException {
+ public ResponseEntity> getEportalSekcje(@RequestParam String login, @RequestParam String password, @PathVariable int id) throws IOException, LoginException, WrongCourseIdException {
- return ResponseEntity.status(HttpStatus.OK).body(eService.getEportalSekcje(login, password, id));
+ return ResponseEntity.status(HttpStatus.OK).body(eportalService.getEportalSekcje(login, password, id));
}
@GetMapping("/kursy/{id}/oceny")
@Operation(summary = "Returns all marks for the given course", description = "You can fetch the course ID using /kursy endpoint")
- public ResponseEntity> getEportalOceny(@RequestParam String login, @RequestParam String password, @PathVariable int id) throws JsonProcessingException {
-
- return ResponseEntity.status(HttpStatus.OK).body(eService.getEportalOceny(login, password, id));
+ public ResponseEntity> getEportalOceny(@RequestParam String login, @RequestParam String password, @PathVariable int id) {
+ return ResponseEntity.status(HttpStatus.OK).body(eportalService.getEportalOceny(login, password, id));
}
@@ -71,16 +62,14 @@ public ResponseEntity> getEportalOceny(@RequestParam String lo
@Operation(summary = "Returns events that take place in month with offset", description = "Max offset is from -10 to 10")
public ResponseEntity getEportalKalendarzMiesiac(@RequestParam String login, @RequestParam String password,
@RequestParam(defaultValue = "0") @Min(-10) @Max(10) int offset) throws IOException {
-
- return ResponseEntity.status(HttpStatus.OK).body(eService.getEportalKalendarzOffset(login, password, offset));
+ return ResponseEntity.status(HttpStatus.OK).body(eportalService.getEportalKalendarzOffset(login, password, offset));
}
@GetMapping("/kalendarz/pobierz")
@Operation(summary = "Returns calendar in ICS format", description = "Calendar range is 60 days back and forth")
public ResponseEntity getEportalICS(@RequestParam String login, @RequestParam String password) throws IOException {
-
- return ResponseEntity.status(HttpStatus.OK).body(eService.getEportalKalendarzIcsLink(login, password));
+ return ResponseEntity.status(HttpStatus.OK).body(eportalService.getEportalKalendarzIcsLink(login, password));
}
}
diff --git a/src/main/java/dev/wms/pwrapi/api/EventsAPI.java b/src/main/java/dev/wms/pwrapi/api/EventsAPI.java
new file mode 100644
index 0000000..01dba54
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/api/EventsAPI.java
@@ -0,0 +1,36 @@
+package dev.wms.pwrapi.api;
+
+
+import dev.wms.pwrapi.dto.events.EventDto;
+import dev.wms.pwrapi.service.events.EventsService;
+import io.swagger.v3.oas.annotations.Operation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.Month;
+import java.util.Optional;
+import java.util.Set;
+
+
+@RestController
+@RequestMapping(value = "api/events")
+@RequiredArgsConstructor
+public class EventsAPI {
+
+ private final EventsService eventsService;
+
+
+ @GetMapping
+ @Operation(summary = "returns list of events in PWr from given month and year (both optional)",
+ description = "endpoint gets events from site: https://pwr.edu.pl/uczelnia/przed-nami with given month and year" +
+ " By default month and year are current. When events are duplicated, it returns it merged")
+ public ResponseEntity> getEventsOfTheMonth(
+ @RequestParam Optional month, @RequestParam Optional year){
+ return ResponseEntity.ok(eventsService.getEventsOfMonth(month, year));
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/api/ForumAPI.java b/src/main/java/dev/wms/pwrapi/api/ForumAPI.java
index a27377e..22d6b2a 100644
--- a/src/main/java/dev/wms/pwrapi/api/ForumAPI.java
+++ b/src/main/java/dev/wms/pwrapi/api/ForumAPI.java
@@ -1,161 +1,114 @@
package dev.wms.pwrapi.api;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import dev.wms.pwrapi.entity.forum.Review;
-import dev.wms.pwrapi.entity.forum.Teacher;
-import dev.wms.pwrapi.service.forum.ForumService;
+import dev.wms.pwrapi.utils.forum.dto.ReviewWithTeacherDTO;
+import dev.wms.pwrapi.utils.forum.dto.TeacherInfoDTO;
+import dev.wms.pwrapi.utils.forum.dto.TeacherWithReviewsDTO;
+import dev.wms.pwrapi.service.forum.ForumServiceImpl;
+import dev.wms.pwrapi.utils.forum.consts.Category;
import dev.wms.pwrapi.utils.forum.dto.DatabaseMetadataDTO;
-import dev.wms.pwrapi.utils.forum.exceptions.*;
-import dev.wms.pwrapi.utils.generalExceptions.InvalidIdException;
import io.swagger.v3.oas.annotations.Operation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.http.HttpStatus;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.Min;
-import java.util.List;
+import javax.validation.constraints.Positive;
+import java.util.Set;
-@RestController("/api/forum")
-@RequestMapping(value = "/api/forum", produces = "application/json")
+@RestController
+@RequestMapping("/api/forum")
+@RequiredArgsConstructor
+@Validated
public class ForumAPI {
+ private final ForumServiceImpl forumService;
- private final ForumService forumService;
-
- @Autowired
- public ForumAPI(ForumService forumService){
- this.forumService = forumService;
- }
-
+ @Cacheable("forum-metadata")
@GetMapping
@Operation(summary = "Returns database metadata such as number of records in each category and latest refresh timestamp.")
- public ResponseEntity getDatabaseMetadata() throws JsonProcessingException {
- DatabaseMetadataDTO result = forumService.getDatabaseMetadata();
- return ResponseEntity.status(HttpStatus.OK).body(result);
+ public ResponseEntity getDatabaseMetadata() {
+ return ResponseEntity.ok(forumService.getDatabaseMetadata());
}
+ @Cacheable("reviews")
@GetMapping("/opinie")
- @Operation(summary = "Returns total number of reviews.")
- public ResponseEntity getTotalReviews() throws JsonProcessingException {
- DatabaseMetadataDTO result = forumService.getTotalReviews();
- return ResponseEntity.status(HttpStatus.OK).body(result);
+ @Operation(summary = "Returns total number of teacher reviews collected.")
+ public ResponseEntity getTotalReviews() {
+ return ResponseEntity.ok(forumService.getTotalReviews());
}
@GetMapping("/opinie/{reviewId}")
- @Operation(summary = "Returns review with specified id.")
- public ResponseEntity getReviewById(@PathVariable @Min(1) int reviewId) throws JsonProcessingException {
- try {
- Review result = forumService.getReviewById(reviewId);
- return ResponseEntity.status(HttpStatus.OK).body(result);
- }catch (EmptyResultDataAccessException e){
- throw new ReviewNotFoundException(reviewId);
- }
+ @Operation(summary = "Returns review with specified reviewId.")
+ public ResponseEntity getReviewById(@PathVariable @Positive Long reviewId) {
+ return ResponseEntity.ok(forumService.getReviewById(reviewId));
}
+ @Cacheable("teachers")
@GetMapping("/prowadzacy")
@Operation(summary = "Returns total number of teachers.")
- public ResponseEntity getTotalTeachers() throws JsonProcessingException {
- DatabaseMetadataDTO result = forumService.getTotalTeachers();
- return ResponseEntity.status(HttpStatus.OK).body(result);
+ public ResponseEntity getTotalTeachers() {
+ return ResponseEntity.ok(forumService.getTotalTeachers());
}
@GetMapping(value = "/prowadzacy/{teacherId}")
@Operation(summary = "Returns teacher with specified id.")
- public ResponseEntity fetchAllTeacherReviewsById(@PathVariable int teacherId) throws JsonProcessingException {
- if(teacherId <= 0) {
- throw new InvalidIdException(teacherId);
- }
-
- try{
- Teacher result = forumService.fetchLimitedTeacherReviewsById(teacherId, -1);
- return ResponseEntity.status(HttpStatus.OK).body(result);
- }catch(EmptyResultDataAccessException e){
- throw new TeacherNotFoundByIdException(teacherId);
- }
+ public ResponseEntity getTeacherWithReviews(@PathVariable @Positive Long teacherId) {
+ return ResponseEntity.ok(forumService.getTeacherWithAllReviewsById(teacherId));
}
@GetMapping("/prowadzacy/szukajId")
@Operation(summary = "Returns certain teacher specified by id and limited number of reviews.",
- description = "Maximal number of fetched reviews is specified by the limit parameter, set limit = -1 to fetch all available reviews.")
- public ResponseEntity fetchLimitedTeacherReviewsById(@RequestParam("teacherId") int teacherId, @RequestParam("limit") int limit) throws JsonProcessingException {
- if(teacherId <= 0){
- throw new InvalidIdException(teacherId);
- }
-
- if(limit >= -1) {
- try {
- Teacher response = forumService.fetchLimitedTeacherReviewsById(teacherId, limit);
- return ResponseEntity.status(HttpStatus.OK).body(response);
- }catch(EmptyResultDataAccessException e){
- throw new TeacherNotFoundByIdException(teacherId);
- }
- }else{
- throw new InvalidLimitException(limit);
- }
+ description = "Maximal number of fetched reviews is specified by the limit parameter, set limit = -1 to " +
+ "fetch all available reviews.")
+ public ResponseEntity getTeacherWithLimitedReviewsById(
+ @RequestParam @Positive Long teacherId,
+ @RequestParam(required = false, defaultValue = "10") @Min(-1) int limit) {
+ return ResponseEntity.ok(forumService.getTeacherWithLimitedReviewsById(teacherId, limit));
}
@GetMapping("/prowadzacy/szukajImie")
@Operation(summary = "Returns certain teacher specified by full name and limited number of reviews.",
- description = "Parameters firstName and lastName are interchangeable, query is based on pattern matching. " +
- "Maximal number of reviews is specified by the limit parameter, set limit = -1 to fetch all available reviews.")
- public ResponseEntity fetchTeacherReviewsByFullName(@RequestParam("firstName") String firstName,
- @RequestParam("lastName") String lastName, @RequestParam("limit") int limit) throws JsonProcessingException {
- if(limit >= -1){
- try {
- Teacher response = forumService.fetchLimitedTeacherReviewsByFullName(firstName, lastName, limit);
- return ResponseEntity.status(HttpStatus.OK).body(response);
- }catch(EmptyResultDataAccessException e){
- throw new TeacherNotFoundByFullNameException(firstName, lastName);
- }
- }else{
- throw new InvalidLimitException(limit);
- }
+ description = "Parameters firstName and lastName are interchangeable, query is based on pattern matching. " +
+ "Maximal number of reviews is specified by the limit parameter, set limit = -1 to fetch all available reviews.")
+ public ResponseEntity getTeacherWithLimitedReviewsByFullName(
+ @RequestParam(required = false) String firstName,
+ @RequestParam(required = false) String lastName,
+ @RequestParam(required = false) String query,
+ @RequestParam(required = false, defaultValue = "10") @Min(-1) int limit) {
+ return ResponseEntity.ok(forumService.getTeacherWithLimitedReviewsByFullName(firstName, lastName, query, limit));
}
@GetMapping("/prowadzacy/kategoria/{category}")
@Operation(summary = "Returns all teachers who belong to the specified category.")
- public ResponseEntity> getTeachersByCategory(@PathVariable String category) throws JsonProcessingException {
- List response = forumService.getTeachersByCategory(category);
- if(response.isEmpty()){
- throw new CategoryMembersNotFoundException(category);
- }
- return ResponseEntity.status(HttpStatus.OK).body(response);
+ public ResponseEntity> getTeachersByCategory(@PathVariable Category category) {
+ return ResponseEntity.ok(forumService.getTeachersInfoByCategory(category));
}
@GetMapping("/prowadzacy/ranking")
@Operation(summary = "Returns teachers who belong to the specified category ranked by their average rating.")
- public ResponseEntity> getTeachersRankedByCategory(@RequestParam("kategoria") String category) throws JsonProcessingException {
- List response = forumService.getBestTeachersRankedByCategory(category);
- if(response.isEmpty()){
- throw new CategoryMembersNotFoundException(category);
- }
- return ResponseEntity.status(HttpStatus.OK).body(response);
+ public ResponseEntity> getTeachersRankedByCategory(
+ @RequestParam(name = "kategoria") Category category) {
+ return ResponseEntity.ok(forumService.getBestTeachersOfCategory(category));
}
@GetMapping("/prowadzacy/{category}/ranking/najlepsi")
- @Operation(summary = "Returns limited number of best rated teachers who belong to the specified category, example reviews are provided.",
- description = "Number of return teachers is specified by the limit parameter, each teacher has a maximal example of three associated reviews.")
- public ResponseEntity> getBestRankedTeachersByCategoryWithReviewsLimited(@PathVariable String category, @RequestParam("limit") @Min(-1) int limit) throws JsonProcessingException {
-
- List response = forumService.getBestRankedTeachersByCategoryLimited(category, limit);
- if(response.isEmpty()){
- throw new CategoryMembersNotFoundException(category);
- }
-
- return ResponseEntity.status(HttpStatus.OK).body(response);
+ @Operation(summary = "Returns limited number of best rated teachers who belong to the specified category, " +
+ "example reviews are provided.",
+ description = "Number of return teachers is specified by the limit parameter, each teacher has a maximal " +
+ "example of three associated reviews.")
+ public ResponseEntity> getBestRankedTeachersByCategoryWithReviewsLimited(
+ @PathVariable Category category,
+ @RequestParam(required = false, defaultValue = "10") @Positive int limit) {
+ return ResponseEntity.ok(forumService.getBestTeachersInfoByCategoryLimitedWithExampleReviews(category, limit));
}
@GetMapping("/prowadzacy/{category}/ranking/najgorsi")
@Operation(summary = "Returns limited number of worst rated teachers who belong to the specified category, example reviews are provided.",
description = "Number of return teachers is specified by the limit parameter, each teacher has a maximal example of three associated reviews.")
- public ResponseEntity> getWorstRankedTeachersByCategoryWithReviewsLimited(@PathVariable String category, @RequestParam("limit") @Min(-1) int limit) throws JsonProcessingException {
- List response = forumService.getWorstRankedTeachersByCategoryLimited(category, limit);
- if(response.isEmpty()){
- throw new CategoryMembersNotFoundException(category);
- }
- return ResponseEntity.status(HttpStatus.OK).body(response);
+ public ResponseEntity> getWorstRankedTeachersByCategoryWithReviewsLimited(
+ @PathVariable Category category,
+ @RequestParam(required = false, defaultValue = "10") @Positive int limit) {
+ return ResponseEntity.ok(forumService.getWorstTeachersInfoByCategoryLimitedWithExampleReviews(category, limit));
}
-
-
}
diff --git a/src/main/java/dev/wms/pwrapi/api/IsJsosDownAPI.java b/src/main/java/dev/wms/pwrapi/api/IsJsosDownAPI.java
new file mode 100644
index 0000000..ffefe79
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/api/IsJsosDownAPI.java
@@ -0,0 +1,65 @@
+package dev.wms.pwrapi.api;
+
+import dev.wms.pwrapi.dto.isjsosdown.*;
+import dev.wms.pwrapi.service.isjsosdown.IsJsosDownService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+
+@RestController
+@RequestMapping("/api/isjsosdown")
+@RequiredArgsConstructor
+public class IsJsosDownAPI {
+
+ private final IsJsosDownService isJsosDownService;
+
+ @GetMapping("/initial-stats")
+ public ResponseEntity getInitialStats() {
+ return ResponseEntity.ok(isJsosDownService.getInitialStats());
+ }
+
+ @GetMapping("/additional-stats/{serviceName}")
+ public ResponseEntity getAdditionalStats(@PathVariable String serviceName) {
+ return ResponseEntity.ok(isJsosDownService.getAdditionalStats(serviceName));
+ }
+
+ @GetMapping("/additional-stats/h2h")
+ public ResponseEntity getHeadToHead(@RequestParam List services) {
+ return ResponseEntity.ok(isJsosDownService.getHeadToHead(services));
+ }
+
+ @GetMapping("/additional-stats/ranking")
+ public ResponseEntity> getDowntimeRanking(
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Optional startDate,
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Optional endDate,
+ @RequestParam(defaultValue = "True") Boolean descendingOrder) {
+ return ResponseEntity.ok(isJsosDownService.getDowntimeRanking(startDate, endDate, descendingOrder));
+ }
+
+ @GetMapping("/csv-data")
+ public ResponseEntity getDowntimeDataCSV() {
+ return isJsosDownService.getDowntimeDataCSV();
+ }
+
+ @GetMapping("/tracked-service/all")
+ public ResponseEntity> getAllServices(){
+ return ResponseEntity.ok(isJsosDownService.getAllServices());
+ }
+
+ @PostMapping("/tracked-service")
+ public ResponseEntity addService(@RequestBody ServiceDTO service) {
+ return ResponseEntity.ok(isJsosDownService.addService(service));
+ }
+
+ @PutMapping("/tracked-service/{serviceId}")
+ public ResponseEntity updateServiceById(
+ @PathVariable int serviceId, @RequestBody TrackedServiceDTO trackedService) {
+ return ResponseEntity.ok(isJsosDownService.updateServiceById(serviceId, trackedService));
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/api/JsosAPI.java b/src/main/java/dev/wms/pwrapi/api/JsosAPI.java
index 7f584d1..6e0f955 100644
--- a/src/main/java/dev/wms/pwrapi/api/JsosAPI.java
+++ b/src/main/java/dev/wms/pwrapi/api/JsosAPI.java
@@ -59,7 +59,7 @@ public ResponseEntity> getStudentsMessages(String login,
@Operation(summary = "Get lessons for whole week with given offset",
description = "You can use this endpoint to get all lessons in given week, up to 10 weeks back and forth. " +
"For higher limits you need to host the API yourself and change it in code")
- public ResponseEntity getOffsetWeekLessons(String login, String password, @PathVariable @Min(-10) @Max(10) int offset) throws IOException, TooBigOffsetException, LoginException {
+ public ResponseEntity getOffsetWeekLessons(String login, String password, @PathVariable @Min(-10) @Max(10) int offset) throws IOException, LoginException {
return ResponseEntity.status(HttpStatus.OK).body(jsosService.getOffsetLessons(login, password, offset));
}
@@ -102,7 +102,7 @@ public ResponseEntity> getAllStudentsLessons(String login, Stri
@GetMapping("/oceny")
@Operation(summary = "Returns student's marks from all semesters")
public ResponseEntity> getStudentMarks(String login, String password)
- throws LoginException, IOException {
+ throws LoginException {
return ResponseEntity.status(HttpStatus.OK).body(jsosService.getStudentMarks(login, password));
@@ -127,14 +127,14 @@ public ResponseEntity getDane(@RequestParam("login") String log
@GetMapping("/finanse")
@Operation(summary = "Return student financial information (paid and unpaid stuff)")
public ResponseEntity getFinanse(@RequestParam("login") String login,
- @RequestParam("password") String password) throws IOException {
+ @RequestParam("password") String password) {
return ResponseEntity.status(HttpStatus.OK).body(jsosService.getStudentFinanse(login, password));
}
@GetMapping("/finanse/operacje")
@Operation(summary = "Returns all operations registered on student's internal bank account")
public ResponseEntity getFinanceOperations(@RequestParam("login") String login,
- @RequestParam("password") String password) throws IOException {
+ @RequestParam("password") String password) {
return ResponseEntity.status(HttpStatus.OK).body(jsosService.getStudentFinanceOperations(login, password));
}
diff --git a/src/main/java/dev/wms/pwrapi/api/LibraryAPI.java b/src/main/java/dev/wms/pwrapi/api/LibraryAPI.java
new file mode 100644
index 0000000..f0bd6d3
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/api/LibraryAPI.java
@@ -0,0 +1,30 @@
+package dev.wms.pwrapi.api;
+
+import dev.wms.pwrapi.dto.library.LibraryTitle;
+import dev.wms.pwrapi.service.library.LibraryService;
+import dev.wms.pwrapi.utils.common.PageRequest;
+import io.swagger.v3.oas.annotations.Operation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/library")
+@RequiredArgsConstructor
+public class LibraryAPI {
+
+ private final LibraryService libraryService;
+
+ @GetMapping("/search")
+ @Operation(description = "Returns results from Politechnika's Primo VE search engine")
+ public ResponseEntity> searchFor(String query,
+ @RequestParam(value = "limit", defaultValue = "10") @Min(0) @Max(20) int limit,
+ @RequestParam(value = "offset", defaultValue = "0") @Min(0) int offset){
+ return ResponseEntity.ok(libraryService.searchFor(query, PageRequest.of(limit, offset)));
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/api/ParkingAPI.java b/src/main/java/dev/wms/pwrapi/api/ParkingAPI.java
index 8285856..bd9ee11 100644
--- a/src/main/java/dev/wms/pwrapi/api/ParkingAPI.java
+++ b/src/main/java/dev/wms/pwrapi/api/ParkingAPI.java
@@ -18,7 +18,7 @@
import io.swagger.v3.oas.annotations.Operation;
@RestController
-@RequestMapping(value="/api/parking", produces = "application/json")
+@RequestMapping(value = "/api/parking", produces = "application/json")
@AllArgsConstructor
public class ParkingAPI {
@@ -26,7 +26,7 @@ public class ParkingAPI {
@GetMapping
@Operation(summary = "Returns processed data from skd.pwr.edu.pl", description = "You can use it to get data from skd.pwr.edu.pl in simple format")
- public ResponseEntity> getProcessedParkingInfo() throws JsonProcessingException, IOException{
+ public ResponseEntity> getProcessedParkingInfo() throws IOException {
List result = parkingService.getParkingData();
return ResponseEntity.status(HttpStatus.OK).body(result);
@@ -35,9 +35,9 @@ public ResponseEntity> getProcessedParkingInfo() throws JsonProces
@GetMapping("/raw")
@Operation(summary = "Returns history data from skd.pwr.edu.pl",
description = "You can use it to get parking history data from last 24h")
- public ResponseEntity> getRawParkingInfo() throws IOException{
+ public ResponseEntity> getRawParkingInfo() throws IOException {
return ResponseEntity.status(HttpStatus.OK).body(parkingService.getRawParkingData());
}
-
+
}
diff --git a/src/main/java/dev/wms/pwrapi/api/StudentStatsAPI.java b/src/main/java/dev/wms/pwrapi/api/StudentStatsAPI.java
new file mode 100644
index 0000000..49714f8
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/api/StudentStatsAPI.java
@@ -0,0 +1,56 @@
+package dev.wms.pwrapi.api;
+
+import dev.wms.pwrapi.model.studentStats.StudentStatsData;
+import dev.wms.pwrapi.service.studentStats.StudentStatsService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+
+@RestController
+@RequestMapping(value = "/api/studentStats")
+@RequiredArgsConstructor
+@Validated
+public class StudentStatsAPI {
+
+ private final StudentStatsService studentStatsService;
+
+ @GetMapping("/getStaticMockedData")
+ @Operation(summary = "Returns static mocked data [DEBUG] TEST FOR CI")
+ @Deprecated(forRemoval = true)
+ public ResponseEntity getStaticMockedData(
+ @Parameter(name = "Accept-Language", in = ParameterIn.HEADER, schema = @Schema(type = "string", allowableValues = {"pl", "en"}))
+ @RequestHeader(name = "Accept-Language", required = false) String language){
+
+ return ResponseEntity.ok().body(studentStatsService.getStaticMockedData());
+ }
+
+ @PostMapping
+ @Operation(summary = "Get student stats")
+ public ResponseEntity getStudentStatsData(
+ String login, String password,
+ @Parameter(name = "Accept-Language", in = ParameterIn.HEADER, schema = @Schema(type = "string", allowableValues = {"pl", "en"}))
+ @RequestHeader(name = "Accept-Language", required = false) String language){
+
+ return ResponseEntity.ok().body(studentStatsService.get(login, password));
+ }
+
+ @GetMapping("/getDynamicMockedData/{numOfBlocks}")
+ @Operation(summary = "Returns dynamic mocked data [DEBUG] (number of objects in result is random, and values are also dynamic). " +
+ "Parameter numOfBlocks allows to get exact number of content as it needed [0-100], but to num over 28 cards may occur duplications")
+ @Deprecated(forRemoval = true)
+ public ResponseEntity getDynamicMockedData(
+ @PathVariable @Min(0) @Max(100) Integer numOfBlocks,
+ @Parameter(name = "Accept-Language", in = ParameterIn.HEADER, schema = @Schema(type = "string", allowableValues = {"pl", "en"}))
+ @RequestHeader(name = "Accept-Language", required = false) String language){
+
+ return ResponseEntity.ok().body(studentStatsService.getDynamicMockedData(numOfBlocks));
+ }
+}
diff --git a/src/main/java/dev/wms/pwrapi/api/TestController.java b/src/main/java/dev/wms/pwrapi/api/TestController.java
new file mode 100644
index 0000000..2cfca49
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/api/TestController.java
@@ -0,0 +1,29 @@
+package dev.wms.pwrapi.api;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+
+/**
+ * Used for DevOps testing purposes, will be removed soon.
+ */
+@RestController
+@RequestMapping("/api/test")
+@Deprecated(forRemoval = true)
+public class TestController {
+
+ @GetMapping("/jsos")
+ public String test() throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newBuilder().build();
+ return client.send(HttpRequest.newBuilder()
+ .GET()
+ .uri(URI.create("http://isjsosdown-backend:8081/api/test"))
+ .build(), HttpResponse.BodyHandlers.ofString()).body().toString();
+ }
+}
diff --git a/src/main/java/dev/wms/pwrapi/api/UsosAPI.java b/src/main/java/dev/wms/pwrapi/api/UsosAPI.java
new file mode 100644
index 0000000..6581365
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/api/UsosAPI.java
@@ -0,0 +1,22 @@
+package dev.wms.pwrapi.api;
+
+import dev.wms.pwrapi.service.usos.UsosService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("api/usos")
+@RequiredArgsConstructor
+public class UsosAPI {
+
+ private final UsosService usosService;
+
+ @GetMapping
+ public void loginToUsos(@RequestParam String login, @RequestParam String password) {
+ usosService.loginToUsos(login, password);
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/auth/AuthDao.java b/src/main/java/dev/wms/pwrapi/dao/auth/AuthDao.java
new file mode 100644
index 0000000..4b116a5
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/auth/AuthDao.java
@@ -0,0 +1,22 @@
+package dev.wms.pwrapi.dao.auth;
+
+import dev.wms.pwrapi.utils.generalExceptions.LoginException;
+import dev.wms.pwrapi.utils.http.HttpClient;
+
+import java.io.IOException;
+
+
+public interface AuthDao {
+ /**
+ * Login's to PWr websites using Cookies. Method is using custom OkHttp's CookieJar implementation, which
+ * swaps cookies for session cookies if needed.
+ *
+ * @param login
+ * @param password
+ * @return
+ * @throws IOException
+ * @throws LoginException
+ */
+ HttpClient login(String login, String password);
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/auth/EportalAuthDao.java b/src/main/java/dev/wms/pwrapi/dao/auth/EportalAuthDao.java
new file mode 100644
index 0000000..40828ed
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/auth/EportalAuthDao.java
@@ -0,0 +1,23 @@
+package dev.wms.pwrapi.dao.auth;
+
+
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@RequiredArgsConstructor
+public class EportalAuthDao implements AuthDao {
+
+ private final OauthPwrDao oauthPwrDao;
+ @Value("${url.auth-by-jsos}")
+ private String URL_EPORTAL_AUTH;
+
+ @Override
+ public HttpClient login(String login, String password) {
+ return oauthPwrDao.login(login, password, URL_EPORTAL_AUTH, new HttpClient());
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/auth/JsosAuthDao.java b/src/main/java/dev/wms/pwrapi/dao/auth/JsosAuthDao.java
new file mode 100644
index 0000000..0e90531
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/auth/JsosAuthDao.java
@@ -0,0 +1,28 @@
+package dev.wms.pwrapi.dao.auth;
+
+import dev.wms.pwrapi.utils.cookies.CookieJarImpl;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+
+import okhttp3.OkHttpClient;
+
+@Repository
+@RequiredArgsConstructor
+public class JsosAuthDao implements AuthDao {
+
+ private final OauthPwrDao oauthPwrDao;
+ @Value("${url.jsos}")
+ private String URL_JSOS;
+ @Value("${url.login-as-student}")
+ private String URL_LOGIN_AS_STUDENT;
+
+ @Override
+ public HttpClient login(String login, String password) {
+ var client = new HttpClient();
+ client.getResponse(URL_JSOS);
+ return oauthPwrDao.login(login, password, URL_LOGIN_AS_STUDENT, client);
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/auth/OauthPwrDao.java b/src/main/java/dev/wms/pwrapi/dao/auth/OauthPwrDao.java
new file mode 100644
index 0000000..63efa21
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/auth/OauthPwrDao.java
@@ -0,0 +1,68 @@
+package dev.wms.pwrapi.dao.auth;
+
+import dev.wms.pwrapi.utils.generalExceptions.LoginException;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import okhttp3.*;
+import org.jetbrains.annotations.NotNull;
+import org.jsoup.nodes.Document;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class OauthPwrDao {
+
+ private static final String EXPECTED_INCORRECT_LOGIN_MESSAGE = "Niepowodzenie logowania. Niepoprawna nazwa użytkownika lub hasło.";
+ @Value("${url.pwr-auth}")
+ private String URL_PWR_AUTH;
+
+ public HttpClient login(String login, String password, String url, HttpClient client){
+ return processLogin(login, password, url, client);
+ }
+
+ private HttpClient processLogin(String login, String password, String url, HttpClient client) {
+
+ Document doc = client.getDocument(url);
+
+ String oauthConsumerKey = doc.select("input[name=oauth_consumer_key]").attr("value");
+ String oauthToken = doc.select("input[name=oauth_token]").attr("value");
+
+ //prepare request for logging in
+ MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
+ RequestBody body = createRequestBody(login, password, oauthConsumerKey, oauthToken, mediaType);
+
+ Request request = new Request.Builder()
+ .url(createAuthRequestUrl(oauthConsumerKey, oauthToken))
+ .method("POST", body)
+ .build();
+
+ String responseString = client.getString(request);
+
+ if(responseString.contains(EXPECTED_INCORRECT_LOGIN_MESSAGE)){
+ throw new LoginException();
+ }
+
+ return client;
+ }
+
+ @NotNull
+ private String createAuthRequestUrl(String oauthConsumerKey, String oauthToken) {
+ return URL_PWR_AUTH +
+ "&oauth_token=" + oauthToken +
+ "&oauth_consumer_key=" + oauthConsumerKey +
+ "&oauth_locale=pl";
+ }
+
+ @NotNull
+ private RequestBody createRequestBody(String login, String password, String oauthConsumerKey, String oauthToken, MediaType mediaType) {
+ return RequestBody.create(mediaType,
+ "authenticateButton=Zaloguj&ida_hf_0=&oauth_callback_url=https://jsos.pwr.edu.pl/index.php/site/loginAsStudent"
+ +
+ "&oauth_consumer_key=" + oauthConsumerKey +
+ "&oauth_locale=pl" +
+ "&oauth_request_url=http://oauth.pwr.edu.pl/oauth/authenticate&oauth_symbol=EIS" +
+ "&oauth_token=" + oauthToken +
+ "&password=" + password +
+ "&username=" + login);
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/auth/OauthUsosDao.java b/src/main/java/dev/wms/pwrapi/dao/auth/OauthUsosDao.java
new file mode 100644
index 0000000..11b9da0
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/auth/OauthUsosDao.java
@@ -0,0 +1,55 @@
+package dev.wms.pwrapi.dao.auth;
+
+import dev.wms.pwrapi.utils.generalExceptions.LoginException;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import okhttp3.*;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+
+import java.util.Objects;
+
+@Repository
+public class OauthUsosDao {
+
+ private static final String EXPECTED_INCORRECT_LOGIN_MESSAGE = "Nieprawidłowa nazwa użytkownika lub hasło.";
+
+ @Value("${url.usos-login-auth}")
+ private String URL_USOS_LOGIN_AUTH;
+
+ public HttpClient login(String login, String password, String loginSiteUrl, HttpClient client){
+ return processLogin(login, password, loginSiteUrl, client);
+ }
+
+ private HttpClient processLogin(String login, String password, String loginSiteUrl, HttpClient client) {
+
+ Document document = client.getDocument(loginSiteUrl);
+ String authLink = document.getElementsByClass("login-form").attr("action");
+
+ MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
+ RequestBody body = RequestBody.create(mediaType, "password=" + password + "&username=" + login);
+ Request request = new Request.Builder()
+ .url(authLink)
+ .method("POST", body)
+ .build();
+
+ document = client.getDocument(request);
+
+ Elements alerts = document.getElementsByClass("alert alert-error");
+ checkForAuthErrors(alerts);
+
+ return client;
+ }
+
+ private void checkForAuthErrors(Elements alerts){
+ for(Element alert: alerts){
+ if(EXPECTED_INCORRECT_LOGIN_MESSAGE
+ .equals(Objects.requireNonNull(alert.getElementsByClass("feedback").first()).text())){
+ throw new LoginException();
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/auth/UsosAuthDao.java b/src/main/java/dev/wms/pwrapi/dao/auth/UsosAuthDao.java
new file mode 100644
index 0000000..1bfbe19
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/auth/UsosAuthDao.java
@@ -0,0 +1,43 @@
+package dev.wms.pwrapi.dao.auth;
+
+import dev.wms.pwrapi.utils.cookies.CookieJarImpl;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
+import okhttp3.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Repository;
+
+import java.time.Duration;
+
+@Repository
+@RequiredArgsConstructor
+public class UsosAuthDao implements AuthDao {
+
+ private final OauthUsosDao oauthUsosDao;
+ @Value("${url.usos}")
+ private String URL_USOS;
+ @Value("${url.usos-login-site}")
+ private String URL_USOS_LOGIN_SITE;
+
+ @Value("${usos.client-timeout-in-seconds}")
+ private int timeoutInSeconds;
+
+ @Override
+ @Cacheable("usos-login")
+ public HttpClient login(String login, String password) {
+
+ Duration timeoutDuration = Duration.ofSeconds(timeoutInSeconds);
+ OkHttpClient client = new OkHttpClient().newBuilder()
+ .cookieJar(new CookieJarImpl())
+ .callTimeout(timeoutDuration)
+ .readTimeout(timeoutDuration)
+ .connectTimeout(timeoutDuration)
+ .writeTimeout(timeoutDuration)
+ .build();
+
+ var httpClient = new HttpClient(client);
+ httpClient.getResponse(URL_USOS);
+ return oauthUsosDao.login(login, password, URL_USOS_LOGIN_SITE, httpClient);
+ }
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/edukacja/EduMessageDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/edukacja/EduMessageDAOImpl.java
deleted file mode 100644
index a7e7cc7..0000000
--- a/src/main/java/dev/wms/pwrapi/dao/edukacja/EduMessageDAOImpl.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package dev.wms.pwrapi.dao.edukacja;
-
-import dev.wms.pwrapi.scrapper.edukacja.EduScrapperServices;
-import dev.wms.pwrapi.dto.edukacja.EduConnection;
-import dev.wms.pwrapi.utils.generalExceptions.LoginException;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-
-import java.io.IOException;
-
-public class EduMessageDAOImpl {
-
- public static void fetchMessage(String login, String password) throws IOException, LoginException {
-
- EduConnection eduConnection = EduScrapperServices.fetchHTMLConnectionDetails(login, password);
- //eduConnection.
-
- String URL = "https://edukacja.pwr.wroc.pl/EdukacjaWeb/podgladWiadomosci.do?clEduWebSESSIONTOKEN=" + eduConnection.getSessionToken() + "==&event=positionRow&rowId=75792517&positionIterator=WiadomoscWSkrzynceViewIterator/WEB-INF/pages/secure/teksty/tekst.jsp";
- //String URLIndeks = "https://edukacja.pwr.wroc.pl/EdukacjaWeb/indeks.do?clEduWebSESSIONTOKEN=" + eduConnection.getSessionToken() + "==&event=WyborSluchacza";
-
- OkHttpClient client = new OkHttpClient().newBuilder()
- .build();
- Request request = new Request.Builder()
- .url(URL)
- .method("GET", null)
- .addHeader("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"")
- .addHeader("sec-ch-ua-mobile", "?0")
- .addHeader("sec-ch-ua-platform", "\"Windows\"")
- .addHeader("Upgrade-Insecure-Requests", "1")
- .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
- .addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
- .addHeader("host", "edukacja.pwr.wroc.pl")
- .addHeader("Cookie", "JSESSIONID=" + eduConnection.getJsessionid())
- .build();
- Response response = client.newCall(request).execute();
-
- String responseStr = response.body().string();
- //System.out.println(responseStr);
-
- Document document = Jsoup.parse(responseStr);
- //String message = document.selectXpath("//*[@id=\"GORAPORTALU\"]/tbody/tr[4]/td/table/tbody/tr[1]/td[3]/table/tbody/tr/td/table[1]/tbody/tr[8]/td[2]").text();
- //System.out.println(message);
- //*[@id="GORAPORTALU"]/tbody/tr[4]/td/table/tbody/tr[1]/td[3]/table/tbody/tr/td/table[1]/tbody/tr[8]/td[2]/text()[1]
- //System.out.println(document.selectXpath("/html/body/table/tbody/tr/td/table/tbody/tr[4]/td/table/tbody/tr[1]/td[3]/table/tbody/tr/td/table[4]"));
-
- }
-
-}
diff --git a/src/main/java/dev/wms/pwrapi/dao/edukacja/EduSubjectDAO.java b/src/main/java/dev/wms/pwrapi/dao/edukacja/EduSubjectDAO.java
index 768b926..e9bbac0 100644
--- a/src/main/java/dev/wms/pwrapi/dao/edukacja/EduSubjectDAO.java
+++ b/src/main/java/dev/wms/pwrapi/dao/edukacja/EduSubjectDAO.java
@@ -2,9 +2,9 @@
import dev.wms.pwrapi.entity.edukacja.Subject;
-import java.util.ArrayList;
+import java.util.List;
public interface EduSubjectDAO {
- ArrayList doFetchSubjects(String login, String password);
+ List doFetchSubjects(String login, String password);
}
diff --git a/src/main/java/dev/wms/pwrapi/dao/edukacja/EduSubjectDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/edukacja/EduSubjectDAOImpl.java
index a08a03e..32e22d9 100644
--- a/src/main/java/dev/wms/pwrapi/dao/edukacja/EduSubjectDAOImpl.java
+++ b/src/main/java/dev/wms/pwrapi/dao/edukacja/EduSubjectDAOImpl.java
@@ -2,7 +2,7 @@
import dev.wms.pwrapi.entity.edukacja.Group;
import dev.wms.pwrapi.entity.edukacja.Subject;
-import dev.wms.pwrapi.scrapper.edukacja.EduScrapperServices;
+import dev.wms.pwrapi.scrapper.edukacja.EdukacjaScrapperService;
import dev.wms.pwrapi.utils.edukacja.exceptions.EnrollmentAccessDeniedException;
import dev.wms.pwrapi.utils.generalExceptions.LoginException;
import okhttp3.*;
@@ -21,16 +21,18 @@
public class EduSubjectDAOImpl implements EduSubjectDAO {
private WebDriver driver;
- private OkHttpClient client;
+ private final OkHttpClient client;
+ private final EdukacjaScrapperService scrapperServices;
- public EduSubjectDAOImpl(){
+ public EduSubjectDAOImpl(EdukacjaScrapperService scrapperServices){
+ this.scrapperServices = scrapperServices;
client = new OkHttpClient();
}
@Override
- public ArrayList doFetchSubjects(String login, String password) {
- driver = EduScrapperServices.login(login, password);
+ public List doFetchSubjects(String login, String password) {
+ driver = scrapperServices.login(login, password);
// try to log into edukacja with given credential, if login fails throw login exceptio
try {
@@ -74,11 +76,8 @@ public ArrayList doFetchSubjects(String login, String password) {
// fetch data from first row of table
// get number of pages
- System.out.println(driver.findElements(new ByChained(By.cssSelector("input.paging-numeric-btn-disabled"),
- By.cssSelector("input.paging-numeric-btn"))).isEmpty());
- ArrayList pagination = new ArrayList<>(driver.findElements(By.className("paging-numeric-btn")));
- System.out.println(pagination.size());
- ArrayList subjects = new ArrayList();
+ List pagination = new ArrayList<>(driver.findElements(By.className("paging-numeric-btn")));
+ List subjects = new ArrayList<>();
int i = 2;
int j = 0;
while (true) {
@@ -113,13 +112,6 @@ public ArrayList doFetchSubjects(String login, String password) {
}
- System.out.println(subjects);
-
- // fetch groups
- // fetch group pagination
- ArrayList groupPagination = new ArrayList(driver.findElements(By.xpath(
- "/html/body/table/tbody/tr/td/table/tbody/tr[4]/td/table/tbody/tr[1]/td[3]/table/tbody/tr/td/table[7]/tbody/tr[34]/td/table/tbody/tr/td/span/input[2]")));
-
for (i = 0; i < subjects.size(); i++) {
int pageNum = 0;
@@ -184,12 +176,6 @@ public ArrayList doFetchSubjects(String login, String password) {
}
- for (Subject s : subjects) {
- System.out.println("Subjects for " + s.getId() + ": ");
- for (Group g : s.getGroups())
- System.out.println(g);
- }
-
return subjects;
}
diff --git a/src/main/java/dev/wms/pwrapi/dao/eportal/EportalCalendarDAO.java b/src/main/java/dev/wms/pwrapi/dao/eportal/EportalCalendarDAO.java
index 6f3fa0d..d1d0a34 100644
--- a/src/main/java/dev/wms/pwrapi/dao/eportal/EportalCalendarDAO.java
+++ b/src/main/java/dev/wms/pwrapi/dao/eportal/EportalCalendarDAO.java
@@ -1,9 +1,11 @@
package dev.wms.pwrapi.dao.eportal;
+import dev.wms.pwrapi.dao.auth.AuthDao;
import dev.wms.pwrapi.entity.eportal.calendar.CalendarEvent;
import dev.wms.pwrapi.entity.eportal.calendar.CalendarMonth;
-import dev.wms.pwrapi.scrapper.eportal.EportalScrapperService;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.jsoup.Jsoup;
@@ -16,42 +18,34 @@
import java.util.List;
@Repository
+@RequiredArgsConstructor
public class EportalCalendarDAO {
- public CalendarMonth getEventsWithOffset(String login, String password, int offset) throws IOException {
+ private final AuthDao eportalAuthDao;
- EportalScrapperService.loginToEportal(login, password);
- OkHttpClient client = EportalScrapperService.getClient();
+ public CalendarMonth getEventsWithOffset(String login, String password, int offset) throws IOException {
- Document page = getDocumentFromUrl(client, "https://eportal.pwr.edu.pl/calendar/view.php?view=month");
+ HttpClient client = eportalAuthDao.login(login, password);
- String buttonClassName;
+ Document page = client.getDocument("https://eportal.pwr.edu.pl/calendar/view.php?view=month");
- if(offset < 0){
- buttonClassName = "arrow_link previous";
- } else {
- buttonClassName = "arrow_link next";
- }
+ String buttonClassName = getButtonClassName(offset);
for(int i = 0; i < Math.abs(offset); i++){
-
String nextCalendarUrl = page.getElementsByClass(buttonClassName).first().attr("href");
-
- page = getDocumentFromUrl(client, nextCalendarUrl);
-
+ page = client.getDocument(nextCalendarUrl);
}
String monthName = page.getElementsByClass("current").text();
- List daysElement = page.getElementsByClass("day");
- daysElement.removeIf(day -> day.getElementsByClass("eventname").text().equals(""));
+ List days = page.getElementsByClass("day");
+ days.removeIf(day -> day.getElementsByClass("eventname").text().equals(""));
List events = new ArrayList<>();
- for(Element day : daysElement) {
+ for(Element day : days) {
String[] dateArray = day.getElementsByClass("sr-only").text().split(",");
-
CalendarEvent event = CalendarEvent.builder()
.title(day.getElementsByClass("eventname").text())
.date(dateArray[dateArray.length-2] + "," + dateArray[dateArray.length-1])
@@ -60,7 +54,6 @@ public CalendarMonth getEventsWithOffset(String login, String password, int offs
events.add(event);
}
-
return CalendarMonth.builder()
.monthName(monthName)
.events(events)
@@ -68,12 +61,16 @@ public CalendarMonth getEventsWithOffset(String login, String password, int offs
}
+ @NotNull
+ private String getButtonClassName(int offset) {
+ return offset < 0 ? "arrow_link previous" : "arrow_link next";
+ }
+
public String getIcsCalendarUrl(String login, String password) throws IOException {
- EportalScrapperService.loginToEportal(login, password);
- OkHttpClient client = EportalScrapperService.getClient();
+ HttpClient client = eportalAuthDao.login(login, password);
- Document page = getDocumentFromUrl(client, "https://eportal.pwr.edu.pl/calendar/export.php");
+ Document page = client.getDocument("https://eportal.pwr.edu.pl/calendar/export.php");
String sessionKey = page.getElementsByAttributeValue("name", "sesskey").attr("value");
@@ -82,34 +79,12 @@ public String getIcsCalendarUrl(String login, String password) throws IOExceptio
Request request = new Request.Builder()
.url("https://eportal.pwr.edu.pl/calendar/export.php")
.method("POST", body)
-
.build();
- Response response = client.newCall(request).execute();
-
-
- String calendarURL = Jsoup.parse(response.body().string())
+ return client.getDocument(request)
.getElementsByClass("calendarurl")
.text()
.replace("Adres URL kalendarza: ", "");
-
-
- return calendarURL;
- }
-
-
-
- @NotNull
- private Document getDocumentFromUrl(OkHttpClient client, String nextCalendarUrl) throws IOException {
- Request request;
- Document page;
- request = new Request.Builder()
- .url(nextCalendarUrl)
- .build();
-
- page = Jsoup.parse(client.newCall(request).execute().body().string());
- return page;
}
-
}
diff --git a/src/main/java/dev/wms/pwrapi/dao/eportal/EportalDAO.java b/src/main/java/dev/wms/pwrapi/dao/eportal/EportalDAO.java
index 387749c..20600d0 100644
--- a/src/main/java/dev/wms/pwrapi/dao/eportal/EportalDAO.java
+++ b/src/main/java/dev/wms/pwrapi/dao/eportal/EportalDAO.java
@@ -5,6 +5,7 @@
import java.util.ArrayList;
import java.util.List;
+import dev.wms.pwrapi.dao.auth.AuthDao;
import dev.wms.pwrapi.entity.eportal.Mark;
import dev.wms.pwrapi.entity.eportal.MarkSummary;
import dev.wms.pwrapi.dto.eportal.sections.EportalSection;
@@ -12,13 +13,15 @@
import dev.wms.pwrapi.utils.cookies.CookieJarImpl;
import dev.wms.pwrapi.utils.eportal.exceptions.WrongCourseIdException;
import dev.wms.pwrapi.utils.generalExceptions.LoginException;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
+import org.jetbrains.annotations.NotNull;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.stereotype.Repository;
-import dev.wms.pwrapi.scrapper.eportal.EportalScrapperService;
-import dev.wms.pwrapi.dto.eportal.courseTitle;
+import dev.wms.pwrapi.dto.eportal.CourseTitle;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
@@ -27,113 +30,77 @@
import okhttp3.Response;
@Repository
+@RequiredArgsConstructor
public class EportalDAO {
- public String login(String login, String password) throws IOException, LoginException {
+ private final AuthDao eportalAuthDao;
- EportalScrapperService.loginToEportal(login, password);
- OkHttpClient client = EportalScrapperService.getClient();
+ public String login(String login, String password) throws LoginException {
+ HttpClient client = eportalAuthDao.login(login, password);
return client.toString();
-
}
public String getEportalKursy(String login, String password) throws IOException, LoginException {
- EportalScrapperService.loginToEportal(login, password);
- OkHttpClient client = EportalScrapperService.getClient();
+ HttpClient client = eportalAuthDao.login(login, password);
- Request request = new Request.Builder()
- .url("https://eportal.pwr.edu.pl/my/")
- .build();
- Response response = client.newCall(request).execute();
- Document page = Jsoup.parse(response.body().string());
+ Document page = client.getDocument("https://eportal.pwr.edu.pl/my/");
- List wydzialy = page.getElementsByClass("categoryname");
- List nazwyKursow = page.getElementsByClass("multiline");
+ List faculties = page.getElementsByClass("categoryname");
+ List courses = page.getElementsByClass("multiline");
List detailsLinks = page.getElementsByClass("aalink");
- ArrayList result = new ArrayList();
+ List result = new ArrayList<>();
- for (int i = 0; i < nazwyKursow.size(); i++) {
+ for (int i = 0; i < courses.size(); i++) {
- courseTitle toAdd = new courseTitle().builder()
- .wydzial(wydzialy.get(i).text())
- .nazwa(nazwyKursow.get(i).text())
+ CourseTitle toAdd = CourseTitle.builder()
+ .faculty(faculties.get(i).text())
+ .name(courses.get(i).text())
.detailsLink(detailsLinks.get(i).text())
.build();
- System.out.println("Adding " + result);
result.add(toAdd);
}
- String moodleSession = ((CookieJarImpl) client.cookieJar()).getCookieStore().get("eportal.pwr.edu.pl").get(0)
- .value();
- System.out.println(moodleSession);
-
- String sessKey = page.getElementsByAttributeValue("name", "sesskey").get(0).attr("value");
+ String sessionKey = page.getElementsByAttributeValue("name", "sesskey").get(0).attr("value");
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,
"[{\"index\":0,\"methodname\":\"core_course_get_enrolled_courses_by_timeline_classification\",\"args\":{\"offset\":0,\"limit\":0,\"classification\":\"all\",\"sort\":\"fullname\",\"customfieldname\":\"\",\"customfieldvalue\":\"\"}}]");
- request = new Request.Builder()
- .url("https://eportal.pwr.edu.pl/lib/ajax/service.php?sesskey=" + sessKey
+
+ Request request = new Request.Builder()
+ .url("https://eportal.pwr.edu.pl/lib/ajax/service.php?sesskey=" + sessionKey
+ "&info=core_course_get_enrolled_courses_by_timeline_classification")
.method("POST", body)
.build();
- response = client.newCall(request).execute();
- return response.body().string();
+ return client.getString(request);
}
- public ArrayList getEportalSekcje(String login, String password, int id) throws IOException, LoginException, WrongCourseIdException {
-
- EportalScrapperService.loginToEportal(login, password);
- OkHttpClient client = EportalScrapperService.getClient();
-
-
- Request request = new Request.Builder()
- .url("https://eportal.pwr.edu.pl/course/view.php?id=" + id)
- .method("GET", null)
- .addHeader("sec-ch-ua",
- "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"")
- .addHeader("sec-ch-ua-mobile", "?0")
- .addHeader("sec-ch-ua-platform", "\"Windows\"")
- .addHeader("Upgrade-Insecure-Requests", "1")
- .addHeader("User-Agent",
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
- .addHeader("Accept",
- "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
- .addHeader("Sec-Fetch-Site", "same-origin")
- .addHeader("Sec-Fetch-Mode", "navigate")
- .addHeader("Sec-Fetch-User", "?1")
- .addHeader("Sec-Fetch-Dest", "document")
- .build();
+ public List getEportalSekcje(String login, String password, int id) throws IOException, LoginException, WrongCourseIdException {
- Response response = client.newCall(request).execute();
+ HttpClient client = eportalAuthDao.login(login, password);
- Document page = Jsoup.parse(response.body().string());
- System.out.println("Page title: " + page.title());
- if (page.title().contains("Błąd")) throw new WrongCourseIdException();
+ Document page = client.getDocument(createViewCourseRequest(id));
+ assertNoError(page);
- ArrayList result = new ArrayList();
+ List result = new ArrayList<>();
List sections = page.getElementsByClass("content");
List sectionsName = page.getElementsByClass("sectionname");
- System.out.println("Sections: " + sections.get(0) + " , " + sections.get(1));
for (int i = 0; i < sectionsName.size(); i++) {
Element section = sections.get(i);
- ArrayList sectionElements = new ArrayList();
+ List sectionElements = new ArrayList();
List sectionRealElements = section.getElementsByClass("activityinstance");
- System.out.println("SectionRealElements: " + sectionRealElements);
for (int j = 0; j < sectionRealElements.size(); j++) {
Element element = sectionRealElements.get(j);
- System.out.println("Analizying element " + element.text());
String type = "";
if (element.getElementsByClass("accesshide ").size() != 0)
@@ -158,18 +125,10 @@ public ArrayList getEportalSekcje(String login, String password,
return result;
}
- public List getEportalOceny(String login, String password, int id) {
-
- try {
- EportalScrapperService.loginToEportal(login, password);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
-
- OkHttpClient client = EportalScrapperService.getClient();
-
- Request request = new Request.Builder()
- .url("https://eportal.pwr.edu.pl/grade/report/user/index.php?id=" + id)
+ @NotNull
+ private Request createViewCourseRequest(int id) {
+ return new Request.Builder()
+ .url("https://eportal.pwr.edu.pl/course/view.php?id=" + id)
.method("GET", null)
.addHeader("sec-ch-ua",
"\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"")
@@ -185,20 +144,19 @@ public List getEportalOceny(String login, String password, int id)
.addHeader("Sec-Fetch-User", "?1")
.addHeader("Sec-Fetch-Dest", "document")
.build();
+ }
+ private void assertNoError(Document page) {
+ if (page.title().contains("Błąd")) throw new WrongCourseIdException();
+ }
- Response response = null;
- Document page;
- try {
- response = client.newCall(request).execute();
- page = Jsoup.parse(response.body().string());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ public List getEportalOceny(String login, String password, int id) {
+ HttpClient client = eportalAuthDao.login(login, password);
- System.out.println("Page title: " + page.title());
- if (page.title().contains("Błąd")) throw new WrongCourseIdException();
+ Document page = client.getDocument(createGetMarksRequest(id));
+
+ assertNoError(page);
List marksTable = page.getElementsByClass("user-grade");
@@ -211,7 +169,7 @@ public List getEportalOceny(String login, String password, int id)
List rowsToVisit = markTable.getElementsByTag("tr");
- //remove first two rows as it contains headers
+ //remove first two rows as they contain headers
rowsToVisit.remove(0);
rowsToVisit.remove(0);
@@ -229,7 +187,6 @@ public List getEportalOceny(String login, String password, int id)
.build();
markSummaryFromTable.getMarks().add(toAdd);
- System.out.println("Added " + toAdd);
}
result.add(markSummaryFromTable);
@@ -238,4 +195,25 @@ public List getEportalOceny(String login, String password, int id)
return result;
}
+
+ @NotNull
+ private Request createGetMarksRequest(int id) {
+ return new Request.Builder()
+ .url("https://eportal.pwr.edu.pl/grade/report/user/index.php?id=" + id)
+ .method("GET", null)
+ .addHeader("sec-ch-ua",
+ "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"")
+ .addHeader("sec-ch-ua-mobile", "?0")
+ .addHeader("sec-ch-ua-platform", "\"Windows\"")
+ .addHeader("Upgrade-Insecure-Requests", "1")
+ .addHeader("User-Agent",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
+ .addHeader("Accept",
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
+ .addHeader("Sec-Fetch-Site", "same-origin")
+ .addHeader("Sec-Fetch-Mode", "navigate")
+ .addHeader("Sec-Fetch-User", "?1")
+ .addHeader("Sec-Fetch-Dest", "document")
+ .build();
+ }
}
diff --git a/src/main/java/dev/wms/pwrapi/dao/events/EventsDAO.java b/src/main/java/dev/wms/pwrapi/dao/events/EventsDAO.java
new file mode 100644
index 0000000..7e06bf8
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/events/EventsDAO.java
@@ -0,0 +1,13 @@
+package dev.wms.pwrapi.dao.events;
+
+import dev.wms.pwrapi.dto.events.EventDto;
+
+import java.time.Month;
+import java.util.Optional;
+import java.util.Set;
+
+public interface EventsDAO {
+
+ Set getEventsOfMonth(Optional month, Optional year);
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/events/EventsDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/events/EventsDAOImpl.java
new file mode 100644
index 0000000..5dddfd1
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/events/EventsDAOImpl.java
@@ -0,0 +1,79 @@
+package dev.wms.pwrapi.dao.events;
+
+import dev.wms.pwrapi.dto.events.EventDto;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import okhttp3.OkHttpClient;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springframework.stereotype.Repository;
+
+import java.time.LocalDate;
+import java.time.Month;
+import java.util.*;
+
+@Repository
+public class EventsDAOImpl implements EventsDAO {
+
+ @Override
+ public Set getEventsOfMonth(Optional month, Optional year) {
+ return toEventDtoSet("https://pwr.edu.pl/uczelnia/przed-nami" + "/month," + parseMonth(month) + "-" +
+ parseYear(year) + ".html");
+ }
+
+ private int parseYear(Optional year){
+ return year.orElse(LocalDate.now().getYear());
+ }
+
+
+ private String parseMonth(Optional month){
+ int monthNumber = month.map(monthOptional -> monthOptional.getValue())
+ .orElse(LocalDate.now().getMonth().getValue());
+ return monthNumber < 10 ? "0" + monthNumber : String.valueOf(monthNumber);
+ }
+
+
+ private Set toEventDtoSet(String url){
+
+ var client = new HttpClient();
+
+ Document document = client.getDocument(url);
+
+ Set eventDtos = new LinkedHashSet<>();
+
+ Elements events = document.getElementsByClass("fc-evnt");
+ for(Element event: events){
+
+ EventDto eventDto = new EventDto();
+ eventDto.setTitle(event.ownText());
+
+ Elements eventDetails = event.getElementsByClass("fc-evnt-info").get(0)
+ .getElementsByClass("text").get(0).getElementsByTag("p");
+
+ for(Element eventDetail: eventDetails){
+ parseDetails(eventDto, eventDetail);
+ }
+
+ eventDtos.add(eventDto);
+ }
+
+ return eventDtos;
+
+ }
+
+ private void parseDetails(EventDto eventDtoToExtend, Element eventDetail){
+
+ Element typeOfDetail = eventDetail.getElementsByTag("strong").first();
+
+ if(typeOfDetail == null)
+ eventDtoToExtend.setDescription(eventDetail.text());
+ else{
+ switch (typeOfDetail.text()) {
+ case "Data:" -> eventDtoToExtend.setDate(eventDetail.ownText());
+ case "Godzina:" -> eventDtoToExtend.setTime(eventDetail.ownText());
+ case "Miejsce wydarzenia:" -> eventDtoToExtend.setPlace(eventDetail.ownText());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/forum/DatabaseMetadataRepository.java b/src/main/java/dev/wms/pwrapi/dao/forum/DatabaseMetadataRepository.java
new file mode 100644
index 0000000..fb60203
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/forum/DatabaseMetadataRepository.java
@@ -0,0 +1,11 @@
+package dev.wms.pwrapi.dao.forum;
+
+import dev.wms.pwrapi.utils.forum.dto.DatabaseMetadataDTO;
+import org.springframework.data.jdbc.repository.query.Query;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+public interface DatabaseMetadataRepository extends PagingAndSortingRepository {
+ @Query("SELECT (SELECT COUNT(*) FROM teacher) AS 'total_teachers', (SELECT COUNT(*) FROM review) AS 'total_reviews', " +
+ "(SELECT refresh_date FROM refresh_data) AS 'latest_refresh'")
+ DatabaseMetadataDTO getDatabaseMetadata();
+}
\ No newline at end of file
diff --git a/src/main/java/dev/wms/pwrapi/dao/forum/ForumDAO.java b/src/main/java/dev/wms/pwrapi/dao/forum/ForumDAO.java
deleted file mode 100644
index 5df94e9..0000000
--- a/src/main/java/dev/wms/pwrapi/dao/forum/ForumDAO.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package dev.wms.pwrapi.dao.forum;
-
-import dev.wms.pwrapi.entity.forum.Review;
-import dev.wms.pwrapi.entity.forum.Teacher;
-
-import java.util.List;
-
-public interface ForumDAO {
- int getNumberOfTeachers();
-
- int getNumberOfReviews();
-
- String getLastRefreshDate();
-
- List fetchAllTeachers();
-
- List fetchTeachersLimited(int limit);
-
- List fetchAllReviews();
-
- List fetchReviewsLimited(int limit);
-
- List fetchTeacherReviewsById(int teacherId);
-
- List fetchTeacherReviewsByFullName(String firstName, String lastName);
-
- List fetchTeacherReviewsByIdLimited(int teacherId, int limit);
-
- List fetchTeacherReviewsByFullNameLimited(String firstName, String lastName, int limit);
-
- List fetchRecentTeacherReviewsByFullNameLimited(String firstName, String lastName, int limit);
-
- List fetchOldestTeacherReviewsByFullNameLimited(String firstName, String lastName, int limit);
-
- List fetchRecentTeacherReviewsByIdLimited(int teacherId, int limit);
-
- List fetchOldestTeacherReviewsByIdLimited(int teacherId, int limit);
-
- Teacher findTeacherById(int teacherId);
-
- Teacher findTeacherByName(String firstName, String lastName);
-
- Review findReviewById(int reviewId);
-
- List fetchBestRatedTeachersLimited(int limit);
-
- List fetchWorstOrBestTeachersByCategoryWithReviewsLimited(String category, int teacherLimit, int reviewLimit, boolean isBest);
-
- List fetchWorstRatedTeachersLimited(int limit);
-
- Teacher fetchTeacherByIdWithReviews(int teacherId);
-
- Teacher fetchTeacherByIdWithLimitedReviews(int teacherId, int limit);
-
- Teacher fetchTeacherByFullNameWithReviews(String firstName, String lastName);
-
- Teacher fetchTeacherByFullNameWithLimitedReviews(String firstName, String lastName, int limit);
-
- List getTeachersByCategory(String category);
-
- List getTeachersRankedByCategory(String category, boolean isAscending);
-
- List getTeachersRankedByCategoryLimited(String category, int limit, boolean isAscending);
-
-}
diff --git a/src/main/java/dev/wms/pwrapi/dao/forum/ForumDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/forum/ForumDAOImpl.java
deleted file mode 100644
index 2bd7c61..0000000
--- a/src/main/java/dev/wms/pwrapi/dao/forum/ForumDAOImpl.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package dev.wms.pwrapi.dao.forum;
-
-import dev.wms.pwrapi.entity.forum.Review;
-import dev.wms.pwrapi.entity.forum.Teacher;
-import dev.wms.pwrapi.utils.forum.rowMappers.ReviewRowMapper;
-import dev.wms.pwrapi.utils.forum.rowMappers.ReviewWithTeacherRowMapper;
-import dev.wms.pwrapi.utils.forum.rowMappers.TeacherRowMapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
-import org.springframework.stereotype.Repository;
-
-import javax.sql.DataSource;
-import java.util.List;
-import java.util.Map;
-
-@Repository
-public class ForumDAOImpl implements ForumDAO {
-
- private NamedParameterJdbcTemplate jdbcTemplate;
- private TeacherRowMapper teacherRowMapper;
- private ReviewRowMapper reviewRowMapper;
- private ReviewWithTeacherRowMapper reviewWithTeacherRowMapper;
-
- @Autowired
- public ForumDAOImpl(DataSource dataSource, TeacherRowMapper teacherRowMapper,
- ReviewRowMapper reviewRowMapper, ReviewWithTeacherRowMapper reviewWithTeacherRowMapper){
- jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
- this.teacherRowMapper = teacherRowMapper;
- this.reviewRowMapper = reviewRowMapper;
- this.reviewWithTeacherRowMapper = reviewWithTeacherRowMapper;
- }
-
- @Override
- public int getNumberOfTeachers(){
- String query = "SELECT COUNT(*) FROM teacher";
- return jdbcTemplate.queryForObject(query, Map.of(), Integer.class);
- }
-
- @Override
- public int getNumberOfReviews(){
- String query = "SELECT COUNT(*) FROM review";
- return jdbcTemplate.queryForObject(query, Map.of(), Integer.class);
- }
-
- @Override
- public String getLastRefreshDate() {
- String query = "SELECT refresh_date FROM refresh_data ORDER BY refresh_date DESC LIMIT 1";
- return jdbcTemplate.queryForObject(query, Map.of(), String.class);
- }
-
- @Override
- public List fetchAllTeachers(){
- String query = "SELECT * FROM teacher";
- return jdbcTemplate.query(query, teacherRowMapper);
- }
-
- @Override
- public List fetchTeachersLimited(int limit){
- String query = "SELECT * FROM teacher LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("limit", limit), teacherRowMapper);
- }
-
- @Override
- public List fetchAllReviews(){
- String query = "SELECT * FROM review";
- return jdbcTemplate.query(query, reviewRowMapper);
- }
-
- @Override
- public List fetchReviewsLimited(int limit){
- String query = "SELECT * FROM review LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("limit", limit), reviewRowMapper);
- }
-
- @Override
- public List fetchTeacherReviewsById(int teacherId){
- String query = "SELECT * FROM review WHERE teacher_id = :tId";
- return jdbcTemplate.query(query, Map.of("tId", teacherId), reviewRowMapper);
- }
-
- @Override
- public List fetchTeacherReviewsByFullName(String firstName, String lastName){
- String query = "SELECT * FROM review WHERE teacher_id = (SELECT teacher_id FROM teacher WHERE full_name LIKE :fn AND full_name LIKE :ln)";
- return jdbcTemplate.query(query, Map.of("fn","%" + firstName + "%", "ln", "%" + lastName + "%"), reviewRowMapper);
- }
-
- @Override
- public List fetchTeacherReviewsByIdLimited(int teacherId, int limit){
- String query = "SELECT * FROM review WHERE teacher_id = :tId LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("tId", teacherId, "limit", limit), reviewRowMapper);
- }
-
- @Override
- public List fetchTeacherReviewsByFullNameLimited(String firstName, String lastName, int limit){
- String query = "SELECT * FROM review WHERE teacher_id = (SELECT teacher_id FROM teacher WHERE full_name LIKE :fn AND full_name LIKE :ln) LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("fn", "%" + firstName + "%", "ln", "%" + lastName + "%", "limit", limit), reviewRowMapper);
- }
-
- @Override
- public List fetchRecentTeacherReviewsByFullNameLimited(String firstName, String lastName, int limit){
- String query = "SELECT * FROM review WHERE teacher_id = (SELECT teacher_id FROM teacher WHERE full_name LIKE :fn AND full_name LIKE :ln) " +
- "ORDER BY post_date DESC LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("fn", "%" + firstName + "%", "ln", "%" + lastName + "%", "limit", limit), reviewRowMapper);
- }
-
- @Override
- public List fetchOldestTeacherReviewsByFullNameLimited(String firstName, String lastName, int limit){
- String query = "SELECT * FROM review WHERE teacher_id = (SELECT teacher_id FROM teacher WHERE full_name LIKE :fn AND full_name LIKE :ln) " +
- "ORDER BY post_date ASC LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("fn", "%" + firstName + "%", "ln","%" + lastName + "%", "limit", limit), reviewRowMapper);
- }
-
- @Override
- public List fetchRecentTeacherReviewsByIdLimited(int teacherId, int limit){
- String query = "SELECT * FROM review WHERE teacher_id = :tId ORDER BY post_date DESC LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("tId", teacherId,"limit", limit), reviewRowMapper);
- }
-
- @Override
- public List fetchOldestTeacherReviewsByIdLimited(int teacherId, int limit){
- String query = "SELECT * FROM review WHERE teacher_id = :tId ORDER BY post_date ASC LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("tId", teacherId, "limit", limit), reviewRowMapper);
- }
-
- @Override
- public Teacher findTeacherById(int teacherId){
- String query = "SELECT * FROM teacher WHERE teacher_id = :id";
- return jdbcTemplate.queryForObject(query, Map.of("id", teacherId), teacherRowMapper);
- }
-
- @Override
- public Teacher findTeacherByName(String firstName, String lastName){
- String query = "SELECT * FROM teacher WHERE full_name LIKE :fn AND full_name LIKE :ln";
- return jdbcTemplate.queryForObject(query, Map.of("fn", "%" + firstName + "%", "ln", "%" + lastName + "%"), teacherRowMapper);
- }
-
- @Override
- public Review findReviewById(int reviewId) {
- String query = "SELECT * FROM review JOIN teacher ON review.teacher_id = teacher.teacher_id WHERE review.review_id = :id";
- return jdbcTemplate.queryForObject(query, Map.of("id", reviewId), reviewWithTeacherRowMapper);
- }
-
- @Override
- public List fetchBestRatedTeachersLimited(int limit){
- String query = "SELECT * FROM teacher ORDER BY average_rating DESC LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("limit", limit), teacherRowMapper);
- }
-
- @Override
- public List fetchWorstOrBestTeachersByCategoryWithReviewsLimited(String category, int teacherLimit, int reviewLimit, boolean isBest){
- String queryTeacher = isBest ? "SELECT * FROM teacher WHERE category = :cat ORDER BY average_rating DESC LIMIT :tLimit"
- : "SELECT * FROM teacher WHERE category = :cat ORDER BY average_rating ASC LIMIT :tLimit";
- String queryReview = "SELECT * FROM review WHERE teacher_id = :tId LIMIT :rLimit";
- List teachers = jdbcTemplate.query(queryTeacher, Map.of("tLimit", teacherLimit, "cat", category), teacherRowMapper);
- teachers.forEach(teacher -> {
- jdbcTemplate.query(queryReview, Map.of("tId", teacher.getId(), "rLimit", reviewLimit), reviewRowMapper)
- .forEach(review -> teacher.addReview(review));
- });
- return teachers;
- }
-
- @Override
- public List fetchWorstRatedTeachersLimited(int limit){
- String query = "SELECT * FROM teacher ORDER BY average_rating ASC LIMIT :limit";
- return jdbcTemplate.query(query, Map.of("limit", limit), teacherRowMapper);
- }
-
- @Override
- public Teacher fetchTeacherByIdWithReviews(int teacherId){
- String queryTeacher = "SELECT * FROM teacher WHERE teacher_id = :tId";
- String queryReviews = "SELECT * FROM review WHERE teacher_id = :tId";
- Map map = Map.of("tId", teacherId);
- Teacher teacher = jdbcTemplate.queryForObject(queryTeacher, map, teacherRowMapper);
- jdbcTemplate.query(queryReviews, map, reviewRowMapper).forEach(review -> teacher.addReview(review));
- return teacher;
- }
-
- @Override
- public Teacher fetchTeacherByIdWithLimitedReviews(int teacherId, int limit){
- String queryTeacher = "SELECT * FROM teacher WHERE teacher_id = :tId";
- String queryReviews = "SELECT * FROM review WHERE teacher_id = :tId LIMIT :limit";
- Teacher teacher = jdbcTemplate.queryForObject(queryTeacher, Map.of("tId", teacherId), teacherRowMapper);
- jdbcTemplate.query(queryReviews, Map.of("tId", teacherId, "limit", limit), reviewRowMapper).forEach(review -> teacher.addReview(review));
- return teacher;
- }
-
- @Override
- public Teacher fetchTeacherByFullNameWithReviews(String firstName, String lastName){
- String queryTeacher = "SELECT * FROM teacher WHERE full_name LIKE :fn AND full_name LIKE :ln";
- //String queryTeacher = "SELECT * FROM teacher WHERE first_name = :fn AND last_name = :ln";
- String queryReviews = "SELECT * FROM review WHERE teacher_id = :tId";
- Teacher teacher = jdbcTemplate.queryForObject(queryTeacher, Map.of("fn", "%" + firstName + "%", "ln", "%" + lastName + "%"), teacherRowMapper);
- jdbcTemplate.query(queryReviews, Map.of("tId", teacher.getId()), reviewRowMapper).forEach(review -> teacher.addReview(review));
- return teacher;
- }
-
- @Override
- public Teacher fetchTeacherByFullNameWithLimitedReviews(String firstName, String lastName, int limit){
- String queryTeacher = "SELECT * FROM teacher WHERE full_name LIKE :fn AND full_name LIKE :ln";
- // String queryTeacher = "SELECT * FROM teacher WHERE first_name = :fn AND last_name = :ln";
- String queryReviews = "SELECT * FROM review WHERE teacher_id = :tId LIMIT :limit";
- Teacher teacher = jdbcTemplate.queryForObject(queryTeacher, Map.of("fn", "%" + firstName + "%", "ln", "%" + lastName + "%"), teacherRowMapper);
- jdbcTemplate.query(queryReviews, Map.of("tId", teacher.getId(), "limit", limit), reviewRowMapper).forEach(review -> teacher.addReview(review));
- return teacher;
- }
-
- @Override
- public List getTeachersByCategory(String category) {
- String query = "SELECT * FROM teacher WHERE category = :cat";
- List teachers = jdbcTemplate.query(query, Map.of("cat", category), teacherRowMapper);
- return teachers;
- }
-
- @Override
- public List getTeachersRankedByCategory(String category, boolean isAscending) {
- String query = isAscending ? "SELECT * FROM teacher WHERE category = :cat ORDER BY average_rating ASC"
- : "SELECT * FROM teacher WHERE category = :cat ORDER BY average_rating DESC";
-
- List teachers = jdbcTemplate.query(query, Map.of("cat", category), teacherRowMapper);
- return teachers;
- }
-
- @Override
- public List getTeachersRankedByCategoryLimited(String category, int limit, boolean isAscending) {
- String query = isAscending ? "SELECT * FROM teacher WHERE category = :cat ORDER BY average_rating ASC LIMIT :limit"
- : "SELECT * FROM teacher WHERE category = :cat ORDER BY average_rating DESC LIMIT :limit";
- List teachers = jdbcTemplate.query(query, Map.of("cat", category, "limit", limit), teacherRowMapper);
- return teachers;
- }
-
-}
diff --git a/src/main/java/dev/wms/pwrapi/dao/forum/ReviewRepository.java b/src/main/java/dev/wms/pwrapi/dao/forum/ReviewRepository.java
new file mode 100644
index 0000000..32e1eaa
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/forum/ReviewRepository.java
@@ -0,0 +1,16 @@
+package dev.wms.pwrapi.dao.forum;
+
+import dev.wms.pwrapi.entity.forum.Review;
+import dev.wms.pwrapi.entity.forum.Teacher;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jdbc.repository.query.Query;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+public interface ReviewRepository extends PagingAndSortingRepository {
+ List getReviewsByTeacherId(Long teacherId, Pageable pageable);
+}
\ No newline at end of file
diff --git a/src/main/java/dev/wms/pwrapi/dao/forum/TeacherRepository.java b/src/main/java/dev/wms/pwrapi/dao/forum/TeacherRepository.java
new file mode 100644
index 0000000..c27094e
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/forum/TeacherRepository.java
@@ -0,0 +1,19 @@
+package dev.wms.pwrapi.dao.forum;
+
+import dev.wms.pwrapi.entity.forum.Teacher;
+import dev.wms.pwrapi.utils.forum.consts.Category;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface TeacherRepository extends PagingAndSortingRepository {
+ Optional findTeacherByFullNameLikeIgnoreCase(String query);
+ Optional findTeacherByFullNameLikeIgnoreCaseOrFullNameLikeIgnoreCase(String firstVariant, String secondVariant);
+ List getTeachersByCategory(Category category);
+ List getTeachersByCategoryOrderByAverageRatingDesc(Category category);
+ List getTeachersByCategoryOrderByAverageRatingDesc(Category category, Pageable pageable);
+ List getTeachersByCategoryOrderByAverageRatingAsc(Category category, Pageable pageable);
+ Optional> findByFullNameContainingIgnoreCase(String fullName);
+}
\ No newline at end of file
diff --git a/src/main/java/dev/wms/pwrapi/dao/google/calendar/GoogleCalendarDAO.java b/src/main/java/dev/wms/pwrapi/dao/google/calendar/GoogleCalendarDAO.java
new file mode 100644
index 0000000..0284d04
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/google/calendar/GoogleCalendarDAO.java
@@ -0,0 +1,20 @@
+package dev.wms.pwrapi.dao.google.calendar;
+
+import dev.wms.pwrapi.dto.google.GoogleEventDTO;
+
+import java.time.LocalDateTime;
+import java.util.Set;
+
+public interface GoogleCalendarDAO {
+
+ /**
+ * Method that returns some events from Google calendar.
+ * @param calendarId - id of calendar from which events should be returned
+ * @param apiKey - key (token) required by Google API to get authenticated
+ * @param from - date for Europe/Warsaw time zone
+ * @param to - date for Europe/Warsaw time zone
+ *
+ * @return events where date is specified in the UTC time zone
+ * */
+ Set getEvents(String calendarId, String apiKey, LocalDateTime from, LocalDateTime to);
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/google/calendar/GoogleCalendarDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/google/calendar/GoogleCalendarDAOImpl.java
new file mode 100644
index 0000000..8f92d2c
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/google/calendar/GoogleCalendarDAOImpl.java
@@ -0,0 +1,71 @@
+package dev.wms.pwrapi.dao.google.calendar;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import dev.wms.pwrapi.dto.google.GoogleCalendarDTO;
+import dev.wms.pwrapi.dto.google.GoogleEventDTO;
+import dev.wms.pwrapi.utils.common.DateUtils;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import dev.wms.pwrapi.utils.http.helpers.ResponseAndStatus;
+import lombok.RequiredArgsConstructor;
+import okhttp3.OkHttpClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Repository;
+
+import java.time.LocalDateTime;
+import java.util.Set;
+import java.util.TimeZone;
+
+@Repository
+@RequiredArgsConstructor
+public class GoogleCalendarDAOImpl implements GoogleCalendarDAO {
+
+ @Value("${google.calendar.base-url}")
+ private String CALENDAR_BASE_URL;
+
+ private final ObjectMapper objectMapper;
+
+ @Override
+ public Set getEvents(String calendarId, String apiKey, LocalDateTime from, LocalDateTime to){
+ String url = createUrl(calendarId, apiKey, from, to);
+
+ ResponseAndStatus response = new HttpClient().getStringAndStatusCode(url);
+
+ try{
+ checkResponse(response.getStatusCode(), url);
+ return objectMapper.readValue(response.getResponseBody(), GoogleCalendarDTO.class).getEvents();
+ } catch (JsonProcessingException e){
+ throw new RuntimeException("Error while parsing response from Google Calendar API. Request url: " + url, e);
+ }
+ }
+
+ private String createUrl(String calendarId, String apiKey){
+ return CALENDAR_BASE_URL + "/" + calendarId + "/events?"
+ + "calendarId=" + calendarId + "%40group.calendar.google.com"
+ + "&showDeleted=false" // request will not return events with "status": "cancelled"
+ + "&singleEvents=true" // request will return recurring events as single events
+ + "&key=" + apiKey
+ + "&timeZone=Europe%2FWarsaw";
+ }
+
+ private String createUrl(String calendarId, String apiKey, LocalDateTime from, LocalDateTime to){
+ TimeZone UTC = TimeZone.getTimeZone("UTC");
+ TimeZone Warsaw = TimeZone.getTimeZone("Europe/Warsaw");
+
+ return createUrl(calendarId, apiKey)
+ + "&timeMin=" + DateUtils.formatToRFC3339(from, Warsaw, UTC)
+ + "&timeMax=" + DateUtils.formatToRFC3339(to, Warsaw, UTC);
+ }
+
+ private void checkResponse(int status, String url){
+ if(status != 200) {
+ throw new RuntimeException(
+ String.format(
+ "Bad response. Response code: %d. Url: %s",
+ status,
+ url
+ )
+ );
+ }
+ }
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/isjsosdown/IsJsosDownClient.java b/src/main/java/dev/wms/pwrapi/dao/isjsosdown/IsJsosDownClient.java
new file mode 100644
index 0000000..9835378
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/isjsosdown/IsJsosDownClient.java
@@ -0,0 +1,42 @@
+package dev.wms.pwrapi.dao.isjsosdown;
+
+import dev.wms.pwrapi.dto.isjsosdown.*;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.cloud.openfeign.SpringQueryMap;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(name = "IsJsosDown", url = "${isjsosdown.service-url}", path = "api/isjsosdown")
+public interface IsJsosDownClient {
+
+ @GetMapping("/initial-stats")
+ public InitialStatsDTO getInitialStats();
+
+ @GetMapping("/additional-stats/{serviceName}")
+ public AdditionalStatsDTO getAdditionalStats(@PathVariable String serviceName);
+
+ @GetMapping("/additional-stats/h2h")
+ public HeadToHeadDTO getHeadToHead(@RequestParam List services);
+
+ @GetMapping("/additional-stats/ranking")
+ public List getDowntimeRanking(
+ @SpringQueryMap Map optionalDates,
+ @RequestParam(defaultValue = "True") Boolean descendingOrder);
+
+ @GetMapping(value = "/csv-data", produces = "text/csv")
+ public ResponseEntity getDowntimeDataCSV();
+
+ @GetMapping("/tracked-service/all")
+ public List getAllServices();
+
+ @PostMapping("/tracked-service")
+ public TrackedServiceDTO addService(@RequestBody ServiceDTO service);
+
+ @PutMapping("/tracked-service/{serviceId}")
+ public TrackedServiceDTO updateServiceById(@PathVariable int serviceId, @RequestBody TrackedServiceDTO trackedService);
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosDataDAO.java b/src/main/java/dev/wms/pwrapi/dao/jsos/JsosDataDAO.java
index 1f653d8..425e26f 100644
--- a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosDataDAO.java
+++ b/src/main/java/dev/wms/pwrapi/dao/jsos/JsosDataDAO.java
@@ -18,31 +18,28 @@ public interface JsosDataDAO {
* @param login Login used for JSOS
* @param password Password used for JSOS
* @return List of JsosSemester objects. Each of them contains marks for given semester
- * @throws IOException When some parsing goes wrong
* @throws LoginException If password is wrong
*/
List getStudentMarks(String login, String password)
- throws IOException, LoginException;
+ throws LoginException;
/**
* Returns student data available in "Dane" JSOS's page
* @param login Login used for JSOS
* @param password Password used for JSOS
* @return StudentData object, which contains personal information
- * @throws IOException When some parsing goes wrong
* @throws LoginException If password is wrong
*/
- JsosStudentData getStudentData(String login, String password) throws IOException, LoginException;
+ JsosStudentData getStudentData(String login, String password) throws LoginException;
/**
* Return's student financial operations from /finanse page
* @param login Login used for JSOS
* @param password Password used for JSOS
* @return FinanceOperationResult object containing list of all operations on given account
- * @throws IOException
*/
- FinanceOperationResult getStudentFinanceOperations(String login, String password) throws IOException;
- FinanceResult getStudentFinance(String login, String password) throws IOException;
+ FinanceOperationResult getStudentFinanceOperations(String login, String password);
+ FinanceResult getStudentFinance(String login, String password);
/**
* Returns value of student's message with given internal id's from a given page number
* @param login Login used for JSOS
@@ -50,9 +47,8 @@ List getStudentMarks(String login, String password)
* @param pageNumber Page number of messages interface
* @param messageIds Internal ids of messages (can be fetched using general /wiadomosci endpoint)
* @return List of JsosMessageFull objects (POJO)
- * @throws IOException When some parsing goes wrong
*/
- List getStudentMessage(String login, String password, int pageNumber, Integer... messageIds) throws IOException;
+ List getStudentMessage(String login, String password, int pageNumber, Integer... messageIds) ;
/**
* Returns student's messages from given page number. Can be used to obtain message's internal ID
@@ -60,7 +56,6 @@ List getStudentMarks(String login, String password)
* @param password Password used for JSOS
* @param pageNumber Page number of messages interface
* @return List of JsosMessageShort objects (POJO)
- * @throws IOException When some parsing goes wrong
*/
- List getStudentMessages(String login, String password, int pageNumber) throws IOException;
+ List getStudentMessages(String login, String password, int pageNumber);
}
diff --git a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosDataDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/jsos/JsosDataDAOImpl.java
index 8aa89ac..e897954 100644
--- a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosDataDAOImpl.java
+++ b/src/main/java/dev/wms/pwrapi/dao/jsos/JsosDataDAOImpl.java
@@ -4,16 +4,16 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.stream.Collectors;
+import dev.wms.pwrapi.dao.auth.AuthDao;
import dev.wms.pwrapi.entity.jsos.finance.FinanceEntry;
import dev.wms.pwrapi.entity.jsos.finance.FinanceResult;
import dev.wms.pwrapi.entity.jsos.finance.operations.OperationEntry;
import dev.wms.pwrapi.entity.jsos.finance.operations.FinanceOperationResult;
import dev.wms.pwrapi.entity.jsos.messages.JsosMessageFull;
import dev.wms.pwrapi.entity.jsos.messages.JsosMessageShort;
-import dev.wms.pwrapi.utils.http.HttpUtils;
-import dev.wms.pwrapi.utils.jsos.JsosHttpUtils;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -26,10 +26,10 @@
import okhttp3.OkHttpClient;
@Repository
+@RequiredArgsConstructor
public class JsosDataDAOImpl implements JsosDataDAO {
-
- //this method could be improved
+ private final AuthDao jsosAuthDao;
/**
* Returns value of student's message with given internal id's from a given page number
@@ -40,11 +40,11 @@ public class JsosDataDAOImpl implements JsosDataDAO {
* @return List of JsosMessageFull objects (POJO)
* @throws IOException When some parsing goes wrong
*/
- public List getStudentMessage(String login, String password, int pageNumber, Integer... messageIds) throws IOException {
+ public List getStudentMessage(String login, String password, int pageNumber, Integer... messageIds) {
List messagesIdsToVisit = new ArrayList<>(Arrays.asList(messageIds));
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
Document page = getMessagePageWithNumber(pageNumber, client);
@@ -77,14 +77,12 @@ public List getStudentMessage(String login, String password, in
List urlsToVisit = messages.stream()
.filter(message -> messagesIdsToVisit.contains(message.getInternalId()))
- .map(message -> message.getDetailsLink())
- .collect(Collectors.toList());
+ .map(JsosMessageShort::getDetailsLink).toList();
List result = new ArrayList<>();
-
for(String url : urlsToVisit){
- page = HttpUtils.makeRequestWithClientAndGetDocument(client, "https://jsos.pwr.edu.pl" + url);
+ page = client.getDocument("https://jsos.pwr.edu.pl" + url);
List messageHeaders = page.getElementsByClass("pull-left")
.get(1)
@@ -96,7 +94,7 @@ public List getStudentMessage(String login, String password, in
int urlID = messages.stream()
.filter(m -> m.getDetailsLink().equals(url))
- .map(m -> m.getInternalId())
+ .map(JsosMessageShort::getInternalId)
.findFirst()
.orElseThrow();
@@ -111,15 +109,14 @@ public List getStudentMessage(String login, String password, in
}
-
return result;
}
- public List getStudentMessages(String login, String password, int pageNumber) throws IOException {
+ public List getStudentMessages(String login, String password, int pageNumber) {
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
Document page = getMessagePageWithNumber(pageNumber, client);
@@ -152,12 +149,11 @@ public List getStudentMessages(String login, String password,
}
- public FinanceOperationResult getStudentFinanceOperations(String login, String password) throws IOException {
+ public FinanceOperationResult getStudentFinanceOperations(String login, String password) {
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
- Document page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- " https://jsos.pwr.edu.pl/index.php/student/finanse/operacje");
+ Document page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/finanse/operacje");
List details = page.getElementsByClass("box-body")
.first()
@@ -193,23 +189,20 @@ public FinanceOperationResult getStudentFinanceOperations(String login, String p
.build();
operations.add(entry);
- System.out.println("Added " + entry + " to operations");
}
result.setEntries(operations);
return result;
}
- public FinanceResult getStudentFinance(String login, String password) throws IOException {
+ public FinanceResult getStudentFinance(String login, String password) {
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
- Document page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/student/finanse/oplaty");
+ Document page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/finanse/oplaty");
List rows = page.getElementsByClass("data");
-
List entries = new ArrayList<>();
for (Element row : rows) {
@@ -245,15 +238,13 @@ public FinanceResult getStudentFinance(String login, String password) throws IOE
@Override
- public List getStudentMarks(String login, String password)
- throws IOException, LoginException {
+ public List getStudentMarks(String login, String password) throws LoginException {
List result = new ArrayList();
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
- Document page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/student/indeksOceny/oceny/200");
+ Document page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/indeksOceny/oceny/200");
Element table = page.getElementsByTag("table").get(0);
@@ -295,12 +286,11 @@ public List getStudentMarks(String login, String password)
}
@Override
- public JsosStudentData getStudentData(String login, String password) throws IOException, LoginException {
+ public JsosStudentData getStudentData(String login, String password) throws LoginException {
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
- Document page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/student/indeksDane");
+ Document page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/indeksDane");
Element table = page.getElementById("design_1");
@@ -321,14 +311,12 @@ public JsosStudentData getStudentData(String login, String password) throws IOEx
}
@NotNull
- private Document getMessagePageWithNumber(int pageNumber, OkHttpClient client) throws IOException {
+ private Document getMessagePageWithNumber(int pageNumber, HttpClient client) {
Document page;
if(pageNumber == 1){
- page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/student/wiadomosci");
+ page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/wiadomosci");
} else {
- page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/student/wiadomosci/" + pageNumber);
+ page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/wiadomosci/" + pageNumber);
}
return page;
}
diff --git a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosGeneralDAO.java b/src/main/java/dev/wms/pwrapi/dao/jsos/JsosGeneralDAO.java
deleted file mode 100644
index f8693d4..0000000
--- a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosGeneralDAO.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package dev.wms.pwrapi.dao.jsos;
-
-import dev.wms.pwrapi.dto.jsos.JsosConnection;
-import dev.wms.pwrapi.utils.generalExceptions.LoginException;
-
-import java.io.IOException;
-
-public interface JsosGeneralDAO {
- /**
- * Login's to JSOS using Cookies. Method is using custom OkHttp's CookieJar implementation, which
- * swaps cookies for session cookies if needed.
- * @param login
- * @param password
- * @return
- * @throws IOException
- * @throws LoginException
- */
- JsosConnection login(String login, String password) throws IOException, LoginException;
-
- /**
- * Return's client instance. Mostly used for logging in in JsosHttpUtils class and getting logged client instance
- * @return OkHttpClient instance
- */
- okhttp3.OkHttpClient getClient();
-}
diff --git a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosGeneralDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/jsos/JsosGeneralDAOImpl.java
deleted file mode 100644
index 589c154..0000000
--- a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosGeneralDAOImpl.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package dev.wms.pwrapi.dao.jsos;
-
-import java.io.IOException;
-import java.util.List;
-
-import dev.wms.pwrapi.utils.http.HttpUtils;
-import org.jsoup.nodes.Document;
-import org.springframework.stereotype.Repository;
-
-import dev.wms.pwrapi.dto.jsos.JsosConnection;
-import dev.wms.pwrapi.utils.generalExceptions.LoginException;
-import dev.wms.pwrapi.utils.jsos.cookies.CookieJarImpl;
-import lombok.Getter;
-import okhttp3.CookieJar;
-import okhttp3.MediaType;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.RequestBody;
-import okhttp3.Response;
-
-@Repository
-@Getter
-public class JsosGeneralDAOImpl implements JsosGeneralDAO {
-
- private OkHttpClient client;
-
-
- @Override
- public JsosConnection login(String login, String password) throws IOException, LoginException {
-
- CookieJar cookieJar = new CookieJarImpl();
- JsosConnection jsosConnection = new JsosConnection();
-
- client = new OkHttpClient.Builder()
- .cookieJar(cookieJar)
- .build();
-
- Request request = new Request.Builder()
- .url("https://jsos.pwr.edu.pl/")
- .method("GET", null)
- .build();
-
- Response response = client.newCall(request).execute();
- List Cookielist = response.headers().values("Set-Cookie");
-
- String jsessionid = (Cookielist.get(0).split(";"))[0].replace("JSOSSESSID=", "");
- String YII_CSRF_TOKEN = (Cookielist.get(1).split(";"))[0].replace("YII_CSRF_TOKEN=", "");
-
-
- jsosConnection.setSessionID(jsessionid);
- jsosConnection.setYII_CSRF_TOKEN(YII_CSRF_TOKEN);
-
- // get oauth details
- Document doc = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/site/loginAsStudent");
-
- String oauthConsumerKey = doc.select("input[name=oauth_consumer_key]").attr("value");
- String oauthToken = doc.select("input[name=oauth_token]").attr("value");
-
- jsosConnection.setOauthConsumerKey(oauthConsumerKey);
- jsosConnection.setOauthToken(oauthToken);
-
- //prepare request for logging in
- MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
- RequestBody body = RequestBody.create(mediaType,
- "authenticateButton=Zaloguj&ida_hf_0=&oauth_callback_url=https://jsos.pwr.edu.pl/index.php/site/loginAsStudent"
- +
- "&oauth_consumer_key=" + jsosConnection.getOauthConsumerKey() +
- "&oauth_locale=pl" +
- "&oauth_request_url=http://oauth.pwr.edu.pl/oauth/authenticate&oauth_symbol=EIS" +
- "&oauth_token=" + jsosConnection.getOauthToken() +
- "&password=" + password +
- "&username=" + login);
-
- request = new Request.Builder()
- .url("https://oauth.pwr.edu.pl/oauth/authenticate?9-1.IFormSubmitListener-authenticateForm" +
- "&oauth_token=" + jsosConnection.getOauthToken() +
- "&oauth_consumer_key=" + jsosConnection.getOauthConsumerKey() +
- "&oauth_locale=pl")
- .method("POST", body)
- .addHeader("sec-ch-ua",
- "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"")
- .addHeader("sec-ch-ua-mobile", "?0")
- .addHeader("sec-ch-ua-platform", "\"Windows\"")
- .addHeader("Upgrade-Insecure-Requests", "1")
- .addHeader("Content-Type", "application/x-www-form-urlencoded")
- .addHeader("User-Agent",
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36")
- .addHeader("Accept",
- "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
- .addHeader("Sec-Fetch-Site", "same-origin")
- .addHeader("Sec-Fetch-Mode", "navigate")
- .addHeader("Sec-Fetch-User", "?1")
- .addHeader("Sec-Fetch-Dest", "document")
- .build();
-
- response = client.newCall(request).execute();
-
- String responseString = response.body().string();
- response.body().close();
-
- if(responseString.contains("Niepowodzenie logowania. Niepoprawna nazwa użytkownika lub hasło.")){
- throw new LoginException();
- }
-
- jsosConnection.setOauthSessionToken(((CookieJarImpl) cookieJar).getCookieStore()
- .get("oauth.pwr.edu.pl").toString().split(";")[0].replace("JSESSIONID=", ""));
-
- jsosConnection.setSessionID(((CookieJarImpl) cookieJar).getCookieStore()
- .get("jsos.pwr.edu.pl").get(2).toString().split(";")[0].replace("JSOSSESSID=", ""));
-
- return jsosConnection;
- }
-
-}
diff --git a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosLessonsDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/jsos/JsosLessonsDAOImpl.java
index 590c2aa..755b7b5 100644
--- a/src/main/java/dev/wms/pwrapi/dao/jsos/JsosLessonsDAOImpl.java
+++ b/src/main/java/dev/wms/pwrapi/dao/jsos/JsosLessonsDAOImpl.java
@@ -9,13 +9,14 @@
import java.util.List;
import java.util.Map;
-import dev.wms.pwrapi.utils.http.HttpUtils;
-import dev.wms.pwrapi.utils.jsos.JsosHttpUtils;
+import dev.wms.pwrapi.dao.auth.AuthDao;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.jsoup.nodes.*;
import org.springframework.stereotype.Repository;
-import dev.wms.pwrapi.scrapper.jsos.JsosScrapperServices;
+import dev.wms.pwrapi.scrapper.jsos.JsosScrapperService;
import dev.wms.pwrapi.entity.jsos.JsosLesson;
import dev.wms.pwrapi.entity.jsos.weeks.JsosDay;
import dev.wms.pwrapi.entity.jsos.weeks.JsosDaySubject;
@@ -28,16 +29,18 @@
import okhttp3.Response;
@Repository
+@RequiredArgsConstructor
public class JsosLessonsDAOImpl implements JsosLessonsDAO {
+ private final AuthDao jsosAuthDao;
+ private final JsosScrapperService jsosScrapperService;
@Override
- public JsosDay getTodaysLessons(String login, String password) throws IOException, LoginException, NoTodayClassException{
+ public JsosDay getTodaysLessons(String login, String password) throws LoginException, NoTodayClassException{
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
- Document page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/student/zajecia/tydzien");
+ Document page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/zajecia/tydzien");
if(page.getElementsByClass("rozkladyZajecDzien rozkladyDzisiaj").size() == 0){
throw new NoTodayClassException();
@@ -62,13 +65,12 @@ public JsosDay getTodaysLessons(String login, String password) throws IOExceptio
}
@Override
- public JsosDay getTomorrowLessons(String login, String password) throws IOException, LoginException{
+ public JsosDay getTomorrowLessons(String login, String password) throws LoginException{
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
- Document page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/student/zajecia/tydzien");
+ Document page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/zajecia/tydzien");
String todayNameDayShortcut;
Element todayRow;
@@ -88,7 +90,8 @@ public JsosDay getTomorrowLessons(String login, String password) throws IOExcept
//determine element num from day
List dayNames = new ArrayList(Arrays.asList("pn", "wt", "śr", "cz", "pt", "so", "n"));
- Map dayNamesMap = Map.of("pn", "Poniedziałek", "wt", "Wtorek", "śr", "Środa", "cz", "Czwartek", "pt", "Piątek", "so", "Sobota", "n", "Niedziela");
+ Map dayNamesMap = Map.of("pn", "Poniedziałek", "wt", "Wtorek", "śr",
+ "Środa", "cz", "Czwartek", "pt", "Piątek", "so", "Sobota", "n", "Niedziela");
//check if its sunday
int dayIndex = dayNames.indexOf(todayNameDayShortcut);
@@ -148,33 +151,32 @@ private JsosDay processDay(List coursesDays, String fullDayName, JsosDa
@Override
public JsosWeek getThisWeekLessons(String login, String password) throws IOException, LoginException{
- return JsosScrapperServices.getOffsetWeekLessons(login, password, 0);
+ return jsosScrapperService.getOffsetWeekLessons(login, password, 0);
}
@Override
public JsosWeek getNextWeekLessons(String login, String password) throws IOException, LoginException{
- return JsosScrapperServices.getOffsetWeekLessons(login, password, 1);
+ return jsosScrapperService.getOffsetWeekLessons(login, password, 1);
}
@Override
public JsosWeek getOffsetWeekLessons(String login, String password, int offset) throws IOException, LoginException{
- return JsosScrapperServices.getOffsetWeekLessons(login, password, offset);
+ return jsosScrapperService.getOffsetWeekLessons(login, password, offset);
}
@Override
public List getAllLessons(String login, String password) throws IOException, LoginException{
- OkHttpClient client = JsosHttpUtils.getLoggedClient(login, password);
+ HttpClient client = jsosAuthDao.login(login, password);
Request request = new Request.Builder()
.url("https://jsos.pwr.edu.pl/index.php/student/zajecia")
.build();
- Response response = client.newCall(request).execute();
+ client.getResponse(request);
- Document page = HttpUtils.makeRequestWithClientAndGetDocument(client,
- "https://jsos.pwr.edu.pl/index.php/student/zajecia");
+ Document page = client.getDocument("https://jsos.pwr.edu.pl/index.php/student/zajecia");
List rows = page.getElementsByClass("kliknij");
diff --git a/src/main/java/dev/wms/pwrapi/dao/library/LibraryAuthDao.java b/src/main/java/dev/wms/pwrapi/dao/library/LibraryAuthDao.java
new file mode 100644
index 0000000..dc2cda2
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/library/LibraryAuthDao.java
@@ -0,0 +1,13 @@
+package dev.wms.pwrapi.dao.library;
+
+import okhttp3.OkHttpClient;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class LibraryAuthDao {
+
+ public OkHttpClient getAnonymousClient(){
+ return new OkHttpClient();
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/library/LibraryDAO.java b/src/main/java/dev/wms/pwrapi/dao/library/LibraryDAO.java
new file mode 100644
index 0000000..d42ae71
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/library/LibraryDAO.java
@@ -0,0 +1,42 @@
+package dev.wms.pwrapi.dao.library;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import dev.wms.pwrapi.dto.library.LibraryTitle;
+import dev.wms.pwrapi.dto.library.converters.LibraryDtoConverter;
+import dev.wms.pwrapi.dto.library.deserialization.LibrarySearchResponse;
+import dev.wms.pwrapi.utils.common.PageRequest;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import okhttp3.Request;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@RequiredArgsConstructor
+@Repository
+public class LibraryDAO {
+
+ private final LibraryAuthDao authDao;
+ private final ObjectMapper objectMapper;
+ private final LibraryDtoConverter dtoConverter;
+
+ @SneakyThrows
+ public List searchFor(String query, PageRequest pageRequest) {
+ var client = authDao.getAnonymousClient();
+ Request request = new Request.Builder()
+ .url("https://omnis-pwr.primo.exlibrisgroup.com/primaws/rest/pub/pnxs?lang=pl" +
+ "&limit=" + pageRequest.limit() +
+ "&mode=Basic" +
+ "&offset=" + pageRequest.offset() +
+ "&q=any,contains," + query +
+ "&searchInFulltextUserSelection=true" +
+ "&sort=rank" +
+ "&vid=48OMNIS_TUR:48TUR")
+ .build();
+ var response = objectMapper.readValue(
+ new HttpClient(client).getString(request), LibrarySearchResponse.class);
+ return dtoConverter.toLibraryTitle(response);
+ }
+
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/news/NewsDAO.java b/src/main/java/dev/wms/pwrapi/dao/news/NewsDAO.java
index a885f0f..6965bb9 100644
--- a/src/main/java/dev/wms/pwrapi/dao/news/NewsDAO.java
+++ b/src/main/java/dev/wms/pwrapi/dao/news/NewsDAO.java
@@ -4,7 +4,7 @@
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import dev.wms.pwrapi.dto.news.*;
-import dev.wms.pwrapi.utils.http.HttpUtils;
+import dev.wms.pwrapi.utils.http.HttpClient;
import okhttp3.OkHttpClient;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -26,8 +26,7 @@ public class NewsDAO {
private final Pattern datePattern = Pattern.compile("\\d{2} [a-zA-Z]{3} \\d{4}");
public Channel parsePwrRSS(String rssUrl) {
- OkHttpClient client = new OkHttpClient();
- String response = HttpUtils.makeRequestWithClientAndGetString(client, rssUrl);
+ String response = new HttpClient().getString(rssUrl);
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
xmlMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
@@ -35,7 +34,7 @@ public Channel parsePwrRSS(String rssUrl) {
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
- Rss items = xmlMapper.readValue(response, Rss.class);
+ NewsRss items = xmlMapper.readValue(response, NewsRss.class);
for(Item item : items.getChannel().getItem()) reformatDate(item);
return items.getChannel();
@@ -46,9 +45,10 @@ public Channel parsePwrRSS(String rssUrl) {
private void reformatDate(Item item){
Matcher matcher = datePattern.matcher(item.getPubDate());
- matcher.find();
- LocalDate parsedDate = LocalDate.parse(matcher.group(), rssFormatter);
- item.setPubDate(parsedDate.format(goalFormatter));
+ if(matcher.find()) {
+ LocalDate parsedDate = LocalDate.parse(matcher.group(), rssFormatter);
+ item.setPubDate(parsedDate.format(goalFormatter));
+ }
}
public Channel getFacultyNews(FacultyType faculty) {
@@ -61,7 +61,7 @@ public Channel getFacultyNews(FacultyType faculty) {
private Channel parsePwrHTML(String url) {
OkHttpClient client = new OkHttpClient();
- Document document = HttpUtils.makeRequestWithClientAndGetDocument(client, url);
+ Document document = new HttpClient(client).getDocument(url);
Elements newsBoxes = document.getElementsByClass("news-box");
newsBoxes.removeIf(box -> box.text().isEmpty());
diff --git a/src/main/java/dev/wms/pwrapi/dao/parking/IParkingDAO.java b/src/main/java/dev/wms/pwrapi/dao/parking/IParkingDAO.java
index 7bf225f..db0357a 100644
--- a/src/main/java/dev/wms/pwrapi/dao/parking/IParkingDAO.java
+++ b/src/main/java/dev/wms/pwrapi/dao/parking/IParkingDAO.java
@@ -2,7 +2,6 @@
import java.io.IOException;
import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
import java.util.*;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -11,12 +10,11 @@
import dev.wms.pwrapi.dto.parking.DataWithLabels;
import dev.wms.pwrapi.dto.parking.ParkingWithHistory;
-import dev.wms.pwrapi.dto.parking.deserialization.ParkingWithHistoryArrayElement;
import dev.wms.pwrapi.dto.parking.deserialization.ParkingWithHistoryResponse;
-import dev.wms.pwrapi.utils.http.HttpUtils;
+import dev.wms.pwrapi.utils.http.HttpClient;
import dev.wms.pwrapi.utils.parking.ParkingDateUtils;
import dev.wms.pwrapi.utils.parking.ParkingGeneralUtils;
-import org.springframework.context.annotation.Primary;
+import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Repository;
import dev.wms.pwrapi.dto.parking.deserialization.ParkingArrayElement;
@@ -27,48 +25,29 @@
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
-import okhttp3.Response;
@Repository
public class IParkingDAO implements ParkingDAO {
@Override
- public ArrayList getProcessedParkingInfo() throws IOException {
+ public List getProcessedParkingInfo() throws IOException {
- ArrayList result = new ArrayList<>();
+ List result = new ArrayList<>();
- OkHttpClient client = new OkHttpClient().newBuilder()
- .build();
+ var client = new HttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"o\":\"get_parks\",\"ts\":\"1665147767564\"}");
- Request request = new Request.Builder()
- .url("https://iparking.pwr.edu.pl/modules/iparking/scripts/ipk_operations.php")
- .method("POST", body)
- .addHeader("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"")
- .addHeader("Accept", "application/json, text/javascript, */*; q=0.01")
- .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
- .addHeader("X-Requested-With", "XMLHttpRequest")
- .addHeader("sec-ch-ua-mobile", "?0")
- .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
- .addHeader("sec-ch-ua-platform", "\"Windows\"")
- .addHeader("Sec-Fetch-Site", "same-origin")
- .addHeader("Sec-Fetch-Mode", "cors")
- .addHeader("Sec-Fetch-Dest", "empty")
- .addHeader("Referer", "https://iparking.pwr.edu.pl/")
- .addHeader("Origin", "https://iparking.pwr.edu.pl")
- .build();
+ Request request = createIparkingStateRequest(body);
- ParkingResponse deserializedResponse = new ObjectMapper().readValue(
- HttpUtils.makeRequestWithClientAndGetString(client, request), ParkingResponse.class);
+ ParkingResponse deserializedResponse = new ObjectMapper().readValue(client.getString(request), ParkingResponse.class);
if (deserializedResponse.getSuccess() != 0) throw new WrongResponseCode();
-
LocalDateTime now = ParkingDateUtils.getDateTimeInPoland();
for (ParkingArrayElement parking : deserializedResponse.getPlaces()) {
- Parking toAdd = new Parking().builder()
+ Parking toAdd = Parking.builder()
.name(ParkingGeneralUtils.determineParking(parking.getParking_id()))
.lastUpdate(now.toString())
.leftPlaces(Integer.parseInt(parking.getLiczba_miejsc()))
@@ -81,8 +60,28 @@ public ArrayList getProcessedParkingInfo() throws IOException {
return result;
}
+ @NotNull
+ private Request createIparkingStateRequest(RequestBody body) {
+ return new Request.Builder()
+ .url("https://iparking.pwr.edu.pl/modules/iparking/scripts/ipk_operations.php")
+ .method("POST", body)
+ .addHeader("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"")
+ .addHeader("Accept", "application/json, text/javascript, */*; q=0.01")
+ .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
+ .addHeader("X-Requested-With", "XMLHttpRequest")
+ .addHeader("sec-ch-ua-mobile", "?0")
+ .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
+ .addHeader("sec-ch-ua-platform", "\"Windows\"")
+ .addHeader("Sec-Fetch-Site", "same-origin")
+ .addHeader("Sec-Fetch-Mode", "cors")
+ .addHeader("Sec-Fetch-Dest", "empty")
+ .addHeader("Referer", "https://iparking.pwr.edu.pl/")
+ .addHeader("Origin", "https://iparking.pwr.edu.pl")
+ .build();
+ }
+
@Override
- public List getRawParkingData() throws IOException {
+ public List getRawParkingData() {
Set parkingIds = ParkingGeneralUtils.getParkingIds();
List responses = new ArrayList<>();
parkingIds.forEach(p -> responses.add(requestDataForParkingId(p)));
@@ -105,28 +104,12 @@ public List getRawParkingData() throws IOException {
private ParkingWithHistoryResponse requestDataForParkingId(int parkingId) {
- OkHttpClient client = new OkHttpClient().newBuilder()
- .build();
+ var client = new HttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"o\":\"get_today_chart\",\"i\":\"" + parkingId + "\"}");
- Request request = new Request.Builder()
- .url("https://iparking.pwr.edu.pl/modules/iparking/scripts/ipk_operations.php")
- .method("POST", body)
- .addHeader("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"")
- .addHeader("Accept", "application/json, text/javascript, */*; q=0.01")
- .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
- .addHeader("X-Requested-With", "XMLHttpRequest")
- .addHeader("sec-ch-ua-mobile", "?0")
- .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
- .addHeader("sec-ch-ua-platform", "\"Windows\"")
- .addHeader("Sec-Fetch-Site", "same-origin")
- .addHeader("Sec-Fetch-Mode", "cors")
- .addHeader("Sec-Fetch-Dest", "empty")
- .addHeader("Referer", "https://iparking.pwr.edu.pl/")
- .addHeader("Origin", "https://iparking.pwr.edu.pl")
- .build();
+ Request request = createIparkingStateRequest(body);
- String stringResponse = HttpUtils.makeRequestWithClientAndGetString(client, request);
+ String stringResponse = client.getString(request);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
diff --git a/src/main/java/dev/wms/pwrapi/dao/parking/SKDParkingDAO.java b/src/main/java/dev/wms/pwrapi/dao/parking/SKDParkingDAO.java
index 36288b6..4b3d422 100644
--- a/src/main/java/dev/wms/pwrapi/dao/parking/SKDParkingDAO.java
+++ b/src/main/java/dev/wms/pwrapi/dao/parking/SKDParkingDAO.java
@@ -8,7 +8,7 @@
import java.util.regex.Pattern;
import dev.wms.pwrapi.dto.parking.ParkingWithHistory;
-import dev.wms.pwrapi.utils.http.HttpUtils;
+import dev.wms.pwrapi.utils.http.HttpClient;
import dev.wms.pwrapi.utils.parking.ParkingDateUtils;
import org.jetbrains.annotations.NotNull;
import org.jsoup.nodes.Document;
@@ -37,10 +37,8 @@ public List getRawParkingData() throws IOException{
return parseWithDetails(fetchParkingWebsite());
}
- private Document fetchParkingWebsite() throws IOException {
- OkHttpClient client = new OkHttpClient().newBuilder()
- .build();
- return HttpUtils.makeRequestWithClientAndGetDocument(client, "https://skd.pwr.edu.pl/");
+ private Document fetchParkingWebsite() {
+ return new HttpClient().getDocument("https://skd.pwr.edu.pl/");
}
private List parseProcessed(Element page){
diff --git a/src/main/java/dev/wms/pwrapi/dao/prowadzacy/ProwadzacyDAOImpl.java b/src/main/java/dev/wms/pwrapi/dao/prowadzacy/ProwadzacyDAOImpl.java
index 504ee8a..62f6c24 100644
--- a/src/main/java/dev/wms/pwrapi/dao/prowadzacy/ProwadzacyDAOImpl.java
+++ b/src/main/java/dev/wms/pwrapi/dao/prowadzacy/ProwadzacyDAOImpl.java
@@ -73,9 +73,7 @@ private ProwadzacyResult getPlanFromURL(String url, Integer offset){
Document page;
try(Response response = client.newCall(request).execute()) {
-
page = Jsoup.parse(response.body().string());
-
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -103,9 +101,7 @@ private ProwadzacyResult getPlanFromURL(String url, Integer offset){
}
}
- if(page.getElementById("wyniki").text().contains("Podana fraza nie została odnaleziona")){
- throw new EmptyResultsException();
- }
+ assertResultNotEmpty(page);
List days = page.getElementsByClass("day");
List daysHeaders = page.getElementsByAttributeValue("id","days").first().getElementsByTag("div");
@@ -113,17 +109,12 @@ private ProwadzacyResult getPlanFromURL(String url, Integer offset){
List processedDays = new ArrayList<>(Collections.nCopies(8, new ProwadzacyDay()));
-
int dayIndex = 0;
- Optional titleOptional = Optional.ofNullable(page.getElementsByTag("left").first());
- String title = null;
- if(titleOptional.isPresent()){
- title = titleOptional.get().text();
- if(title.equals("")){
- throw new EmptyResultsException();
- }
- }
+ String title = Optional.ofNullable(page.getElementsByTag("left").first())
+ .map(Element::text)
+ .filter(text -> text.equals(""))
+ .orElseThrow(EmptyResultsException::new);
for(Element day : days){
@@ -173,7 +164,8 @@ private ProwadzacyResult getPlanFromURL(String url, Integer offset){
}
int index = 0;
- ProwadzacyResult result = ProwadzacyResult.builder()
+
+ return ProwadzacyResult.builder()
.title(title)
.pn(processedDays.get(index++))
.wt(processedDays.get(index++))
@@ -185,8 +177,12 @@ private ProwadzacyResult getPlanFromURL(String url, Integer offset){
.icalLink(icalLink)
.build();
- return result;
+ }
+ private void assertResultNotEmpty(Document page) {
+ if(page.getElementById("wyniki").text().contains("Podana fraza nie została odnaleziona")){
+ throw new EmptyResultsException();
+ }
}
}
diff --git a/src/main/java/dev/wms/pwrapi/dao/token/ConfirmationTokenRepository.java b/src/main/java/dev/wms/pwrapi/dao/token/ConfirmationTokenRepository.java
new file mode 100644
index 0000000..9d31808
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/token/ConfirmationTokenRepository.java
@@ -0,0 +1,18 @@
+package dev.wms.pwrapi.dao.token;
+
+import dev.wms.pwrapi.entity.token.ConfirmationToken;
+import org.springframework.data.jdbc.repository.query.Modifying;
+import org.springframework.data.jdbc.repository.query.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface ConfirmationTokenRepository extends CrudRepository {
+ Optional findByToken(String token);
+
+ @Modifying
+ @Query("DELETE FROM opinie.confirmation_token WHERE user_id = :userId")
+ void deleteAllByUserId(Long userId);
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/user/ApiUserRepository.java b/src/main/java/dev/wms/pwrapi/dao/user/ApiUserRepository.java
new file mode 100644
index 0000000..1fd27c6
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/user/ApiUserRepository.java
@@ -0,0 +1,24 @@
+package dev.wms.pwrapi.dao.user;
+
+import dev.wms.pwrapi.entity.user.ApiUser;
+import org.springframework.data.jdbc.repository.query.Modifying;
+import org.springframework.data.jdbc.repository.query.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import java.time.LocalDateTime;
+import java.util.Optional;
+
+@Repository
+public interface ApiUserRepository extends CrudRepository {
+
+ Optional getApiUserByApiKey(String apiKey);
+
+ Optional getApiUserByEmail(String email);
+
+ @Modifying
+ @Query("UPDATE api_user user " +
+ "SET user.requests_left = :requestsLeft, user.requests_left_updated_at = :lastRequestTimestamp " +
+ "WHERE user.id = :userId")
+ void updateRequestDataById(Long userId, Integer requestsLeft, LocalDateTime lastRequestTimestamp);
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/usos/UsosApiClient.java b/src/main/java/dev/wms/pwrapi/dao/usos/UsosApiClient.java
new file mode 100644
index 0000000..154cb0e
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/usos/UsosApiClient.java
@@ -0,0 +1,9 @@
+package dev.wms.pwrapi.dao.usos;
+
+import dev.wms.pwrapi.utils.http.HttpClient;
+
+import java.util.Map;
+
+public interface UsosApiClient {
+ String perform(HttpClient client, String method, Map additionalProperties);
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/usos/UsosDataDAO.java b/src/main/java/dev/wms/pwrapi/dao/usos/UsosDataDAO.java
new file mode 100644
index 0000000..8282820
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/usos/UsosDataDAO.java
@@ -0,0 +1,39 @@
+package dev.wms.pwrapi.dao.usos;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import dev.wms.pwrapi.dto.usos.UsosStudies;
+import dev.wms.pwrapi.dto.usos.UsosUser;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import org.jsoup.nodes.Document;
+import org.springframework.stereotype.Repository;
+
+import java.util.*;
+
+@RequiredArgsConstructor
+@Repository
+public class UsosDataDAO {
+
+ private final UsosApiClient apiClient;
+ private final ObjectMapper objectMapper;
+
+ @SneakyThrows
+ public UsosUser getUsosUser(HttpClient client) {
+ var response = apiClient.perform(client, "services/users/user", Map.of("fields",
+ "id|first_name|last_name|sex|titles|student_status|staff_status|email|profile_url|" +
+ "phone_numbers|mobile_numbers|office_hours|interests|has_photo|photo_urls|student_number|" +
+ "pesel|birth_date|revenue_office_id|citizenship|room|student_programmes|" +
+ "employment_functions|employment_positions|postal_addresses|alt_email|external_ids|phd_student_status"));
+
+ return objectMapper.readValue(response, UsosUser.class);
+ }
+
+ public List getStudies(HttpClient client) {
+ return new UsosStudiesDao(client).parseStudies();
+ }
+
+ public Document getMyUsosWebPage(HttpClient client) {
+ return client.getDocument("https://web.usos.pwr.edu.pl/kontroler.php?_action=home/index");
+ }
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/usos/UsosMarksProxy.java b/src/main/java/dev/wms/pwrapi/dao/usos/UsosMarksProxy.java
new file mode 100644
index 0000000..d0490bb
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/usos/UsosMarksProxy.java
@@ -0,0 +1,38 @@
+package dev.wms.pwrapi.dao.usos;
+
+import dev.wms.pwrapi.dto.usos.UsosSemester;
+import dev.wms.pwrapi.dto.usos.UsosStudies;
+import dev.wms.pwrapi.service.studentStats.CourseDataDecisionExtractorStrategy;
+import dev.wms.pwrapi.service.studentStats.CourseDataDetailsExtractorStrategy;
+import dev.wms.pwrapi.service.studentStats.CourseDataExtractionStrategy;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import lombok.RequiredArgsConstructor;
+import okhttp3.OkHttpClient;
+
+import java.util.*;
+
+@RequiredArgsConstructor
+public class UsosMarksProxy {
+
+ private final HttpClient client;
+ private final CourseDataExtractionStrategy decisionStrategy = new CourseDataDecisionExtractorStrategy();
+ private final CourseDataExtractionStrategy detailsStrategy = new CourseDataDetailsExtractorStrategy();
+
+ public void enhanceWithMarks(List studies) {
+ studies.stream()
+ .map(UsosStudies::semesters)
+ .flatMap(Collection::stream)
+ .filter(semester -> semester.decisionUrls().isPresent())
+ .forEach(semester -> applyStrategy(semester, decisionStrategy));
+
+ studies.stream()
+ .map(UsosStudies::semesters)
+ .flatMap(Collection::stream)
+ .filter(semester -> semester.decisionUrls().isEmpty())
+ .forEach(semester -> applyStrategy(semester, detailsStrategy));
+ }
+
+ private void applyStrategy(UsosSemester semster, CourseDataExtractionStrategy strategy) {
+ strategy.getCoursesDataForSemester(semster, client);
+ }
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/usos/UsosProxyApiClient.java b/src/main/java/dev/wms/pwrapi/dao/usos/UsosProxyApiClient.java
new file mode 100644
index 0000000..43ab134
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/usos/UsosProxyApiClient.java
@@ -0,0 +1,51 @@
+package dev.wms.pwrapi.dao.usos;
+
+import dev.wms.pwrapi.utils.http.HttpClient;
+import okhttp3.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+@Service
+public class UsosProxyApiClient implements UsosApiClient {
+
+ @Value("${usos.proxy.url}")
+ private String proxyUrl;
+ private Pattern csrfPattern = Pattern.compile("csrftoken = \"\\S*\"");
+
+ @Override
+ public String perform(HttpClient client, String method, Map additionalProperties) {
+
+ Map params = new HashMap<>(additionalProperties);
+ params.put("_csrftoken_", getCsrfToken(client));
+ RequestBody body = formBodyFromMap(params);
+ Request request = new Request.Builder()
+ .url(proxyUrl + "?_method_=" + method)
+ .method("POST", body)
+ .build();
+
+
+ return client.getString(request);
+ }
+
+ private FormBody formBodyFromMap(Map params){
+ var builder = new FormBody.Builder();
+ params.entrySet().stream()
+ .forEach(entry -> builder.add(entry.getKey(), entry.getValue()));
+ return builder.build();
+ }
+
+ private String getCsrfToken(HttpClient client){
+ var response = client.getString("https://web.usos.pwr.edu.pl/kontroler.php?_action=dodatki/index");
+ var matcher = csrfPattern.matcher(response);
+ matcher.find();
+ return clearCsrfTokenMatch(matcher.group());
+ }
+
+ private String clearCsrfTokenMatch(String token){
+ return token.replace("csrftoken = ", "").replace("\"", "");
+ }
+}
diff --git a/src/main/java/dev/wms/pwrapi/dao/usos/UsosStudiesDao.java b/src/main/java/dev/wms/pwrapi/dao/usos/UsosStudiesDao.java
new file mode 100644
index 0000000..88bcb72
--- /dev/null
+++ b/src/main/java/dev/wms/pwrapi/dao/usos/UsosStudiesDao.java
@@ -0,0 +1,137 @@
+package dev.wms.pwrapi.dao.usos;
+
+import dev.wms.pwrapi.dto.usos.UsosCourse;
+import dev.wms.pwrapi.dto.usos.UsosSemester;
+import dev.wms.pwrapi.dto.usos.UsosStudies;
+import dev.wms.pwrapi.utils.common.URLValidator;
+import dev.wms.pwrapi.utils.http.HttpClient;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.regex.Pattern;
+
+public class UsosStudiesDao {
+
+ private static final String NO_MARKS_TEXT = "(brak ocen)";
+ private final HttpClient client;
+ private static final Pattern MARK_PATTERN = Pattern.compile("Ocena: \\d.\\d");
+
+ public UsosStudiesDao(HttpClient client) {
+ this.client = client;
+ }
+
+ public List parseStudies(){
+ var studies = getStudies();
+ enhanceWithMarks(studies);
+ return studies;
+ }
+
+ private void enhanceWithMarks(List studies) {
+ new UsosMarksProxy(client).enhanceWithMarks(studies);
+ }
+
+ private List