├── .travis.yml ├── .gitignore ├── openstud_driver.iml ├── src ├── main │ └── java │ │ └── lithium │ │ └── openstud │ │ └── driver │ │ ├── core │ │ ├── models │ │ │ ├── EventType.java │ │ │ ├── CertificateType.java │ │ │ ├── Exam.java │ │ │ ├── Lesson.java │ │ │ ├── ExamDoable.java │ │ │ ├── PaymentDescription.java │ │ │ ├── StudentCard.java │ │ │ ├── Isee.java │ │ │ ├── NewsEvent.java │ │ │ ├── News.java │ │ │ ├── ExamDone.java │ │ │ ├── Career.java │ │ │ ├── Tax.java │ │ │ ├── Classroom.java │ │ │ ├── Event.java │ │ │ ├── ExamReservation.java │ │ │ └── Student.java │ │ ├── internals │ │ │ ├── NewsHandler.java │ │ │ ├── ProviderConfig.java │ │ │ ├── ClassroomHandler.java │ │ │ ├── AuthenticationHandler.java │ │ │ ├── TaxHandler.java │ │ │ ├── BioHandler.java │ │ │ └── ExamHandler.java │ │ ├── OpenstudValidator.java │ │ ├── OpenstudBuilder.java │ │ ├── providers │ │ │ └── sapienza │ │ │ │ ├── SapienzaConfig.java │ │ │ │ ├── SapienzaNewsHandler.java │ │ │ │ ├── SapienzaClassroomHandler.java │ │ │ │ ├── SapienzaTaxHandler.java │ │ │ │ ├── SapienzaHelper.java │ │ │ │ ├── SapienzaAuthenticationHandler.java │ │ │ │ └── SapienzaBioHandler.java │ │ ├── OpenstudHelper.java │ │ └── Openstud.java │ │ └── exceptions │ │ ├── OpenstudConnectionException.java │ │ ├── OpenstudInvalidAnswerException.java │ │ ├── OpenstudUserNotEnabledException.java │ │ ├── OpenstudInvalidResponseException.java │ │ ├── OpenstudRefreshException.java │ │ ├── OpenstudInvalidCredentialsException.java │ │ ├── OpenstudBaseResponseException.java │ │ └── OpenstudBaseLoginException.java └── test │ └── java │ └── lithium │ └── openstud │ └── driver │ └── OpenstudSapienzaTest.java ├── README.md └── pom.xml /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - openjdk8 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | src/main/java/lithium/openstud/driver/App.java 3 | target/ -------------------------------------------------------------------------------- /openstud_driver.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/EventType.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | public enum EventType { 4 | DOABLE, RESERVED, LESSON, THEATRE 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/CertificateType.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | public enum CertificateType { 4 | REGISTRATION, EXAMS_COMPLETED, DEGREE_WITH_EXAMS, DEGREE_WITH_EVALUATION, DEGREE_WITH_THESIS, DEGREE_FOR_RANSOM, 5 | DEGREE_WITH_THESIS_ENG, DEGREE_WITH_EXAMS_ENG, DEGREE_WITH_EVALUATION_ENG 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/exceptions/OpenstudConnectionException.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.exceptions; 2 | 3 | public class OpenstudConnectionException extends Exception { 4 | public OpenstudConnectionException(String message) { 5 | super(message); 6 | } 7 | 8 | public OpenstudConnectionException(Exception e) { 9 | super(e); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/exceptions/OpenstudInvalidAnswerException.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.exceptions; 2 | 3 | public class OpenstudInvalidAnswerException extends Exception { 4 | public OpenstudInvalidAnswerException(String message) { 5 | super(message); 6 | } 7 | 8 | public OpenstudInvalidAnswerException(Exception e) { 9 | super(e); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/exceptions/OpenstudUserNotEnabledException.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.exceptions; 2 | 3 | public class OpenstudUserNotEnabledException extends Exception { 4 | public OpenstudUserNotEnabledException(String message) { 5 | super(message); 6 | } 7 | 8 | public OpenstudUserNotEnabledException(Exception e) { 9 | super(e); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/internals/NewsHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.internals; 2 | 3 | import lithium.openstud.driver.core.models.Event; 4 | import lithium.openstud.driver.core.models.News; 5 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 6 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 7 | 8 | import java.util.List; 9 | 10 | public interface NewsHandler { 11 | List getNews(String locale, boolean withDescription, Integer limit, Integer page, Integer maxPage, 12 | String query) throws OpenstudInvalidResponseException, OpenstudConnectionException; 13 | 14 | List getNewsletterEvents() throws OpenstudInvalidResponseException, OpenstudConnectionException; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/Exam.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | public abstract class Exam { 4 | private String description; 5 | private String examCode; 6 | private String ssd; 7 | private int cfu; 8 | 9 | public String getDescription() { 10 | return description; 11 | } 12 | 13 | public void setDescription(String description) { 14 | this.description = description; 15 | } 16 | 17 | public String getExamCode() { 18 | return examCode; 19 | } 20 | 21 | public void setExamCode(String examCode) { 22 | this.examCode = examCode; 23 | } 24 | 25 | public String getSsd() { 26 | return ssd; 27 | } 28 | 29 | public void setSsd(String ssd) { 30 | this.ssd = ssd; 31 | } 32 | 33 | public int getCfu() { 34 | return cfu; 35 | } 36 | 37 | public void setCfu(int cfu) { 38 | this.cfu = cfu; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/exceptions/OpenstudInvalidResponseException.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.exceptions; 2 | 3 | public class OpenstudInvalidResponseException extends OpenstudBaseResponseException { 4 | public OpenstudInvalidResponseException(String message) { 5 | super(message); 6 | } 7 | 8 | public OpenstudInvalidResponseException(Exception e) { 9 | super(e); 10 | } 11 | 12 | @Override 13 | public OpenstudInvalidResponseException setJSONType() { 14 | super.setJSONType(); 15 | return this; 16 | } 17 | 18 | public OpenstudInvalidResponseException setMaintenanceType() { 19 | super.setMaintenanceType(); 20 | return this; 21 | } 22 | 23 | public OpenstudInvalidResponseException setRateLimitType() { 24 | super.setRateLimitType(); 25 | return this; 26 | } 27 | 28 | public OpenstudInvalidResponseException setHTMLType() { 29 | super.setHTMLType(); 30 | return this; 31 | } 32 | 33 | public OpenstudInvalidResponseException setSSLType() { 34 | super.setSSLType(); 35 | return this; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/internals/ProviderConfig.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.internals; 2 | 3 | import lithium.openstud.driver.core.OpenstudHelper; 4 | import lithium.openstud.driver.core.models.CertificateType; 5 | 6 | import java.util.Map; 7 | 8 | public interface ProviderConfig { 9 | String getEndpointAPI(OpenstudHelper.Mode mode); 10 | 11 | String getEndpointTimetable(OpenstudHelper.Mode mode); 12 | 13 | String getEmailURL(); 14 | 15 | boolean isAuthEnabled(); 16 | 17 | boolean isClassroomEnabled(); 18 | 19 | boolean isExamEnabled(); 20 | 21 | boolean isNewsEnabled(); 22 | 23 | boolean isTaxEnabled(); 24 | 25 | boolean isBioEnabled(); 26 | 27 | boolean isSurveyEnabled(); 28 | 29 | boolean isCareerForCertificateEnabled(); 30 | 31 | boolean isCertEnabled(); 32 | 33 | boolean isRefreshEnabled(); 34 | 35 | boolean isCertSupported(CertificateType certificate); 36 | 37 | boolean isStudentCardEnabled(); 38 | 39 | boolean isStudentPhotoEnabled(); 40 | 41 | String getKey(String key); 42 | 43 | void addKeys(Map customKeys); 44 | 45 | String getKey(OpenstudHelper.Mode mode); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/internals/ClassroomHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.internals; 2 | 3 | import lithium.openstud.driver.core.models.Classroom; 4 | import lithium.openstud.driver.core.models.ExamDoable; 5 | import lithium.openstud.driver.core.models.Lesson; 6 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 7 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 8 | import org.threeten.bp.LocalDate; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public interface ClassroomHandler { 14 | List getClassRoom(String query, boolean withTimetable) throws OpenstudInvalidResponseException, 15 | OpenstudConnectionException; 16 | 17 | List getClassroomTimetable(Classroom room, LocalDate date) throws OpenstudConnectionException, 18 | OpenstudInvalidResponseException; 19 | 20 | List getClassroomTimetable(int id, LocalDate date) throws OpenstudConnectionException, OpenstudInvalidResponseException; 21 | 22 | Map> getTimetable(List exams) throws OpenstudInvalidResponseException, 23 | OpenstudConnectionException; 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/exceptions/OpenstudRefreshException.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.exceptions; 2 | 3 | public class OpenstudRefreshException extends OpenstudBaseLoginException { 4 | public OpenstudRefreshException(String message) { 5 | super(message); 6 | } 7 | 8 | public OpenstudRefreshException(Exception e) { 9 | super(e); 10 | if (e instanceof OpenstudBaseLoginException) { 11 | OpenstudBaseLoginException obj = (OpenstudBaseLoginException) e; 12 | if (obj.isAccountBlocked()) this.setAccountBlockedType(); 13 | else if (obj.isPasswordExpired()) this.setPasswordExpiredType(); 14 | else if (obj.isPasswordInvalid()) this.setPasswordInvalidType(); 15 | } 16 | } 17 | 18 | @Override 19 | public OpenstudRefreshException setPasswordExpiredType() { 20 | super.setPasswordExpiredType(); 21 | return this; 22 | } 23 | 24 | public OpenstudRefreshException setPasswordInvalidType() { 25 | super.setPasswordInvalidType(); 26 | return this; 27 | } 28 | 29 | public OpenstudRefreshException setAccountBlockedType() { 30 | super.setAccountBlockedType(); 31 | return this; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/internals/AuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.internals; 2 | 3 | import lithium.openstud.driver.exceptions.*; 4 | 5 | public interface AuthenticationHandler { 6 | String getSecurityQuestion() throws OpenstudConnectionException, OpenstudInvalidResponseException, 7 | OpenstudInvalidCredentialsException; 8 | 9 | boolean recoverPassword(String answer) throws OpenstudConnectionException, OpenstudInvalidResponseException, 10 | OpenstudInvalidCredentialsException, OpenstudInvalidAnswerException; 11 | 12 | void resetPassword(String new_password) throws OpenstudConnectionException, OpenstudInvalidResponseException, 13 | OpenstudInvalidCredentialsException; 14 | 15 | boolean recoverPasswordWithEmail(String email, String answer) throws OpenstudConnectionException, 16 | OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudInvalidAnswerException; 17 | 18 | void login() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, 19 | OpenstudInvalidResponseException, OpenstudUserNotEnabledException; 20 | 21 | void refreshToken() throws OpenstudRefreshException, OpenstudInvalidResponseException; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/internals/TaxHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.internals; 2 | 3 | import lithium.openstud.driver.core.models.Isee; 4 | import lithium.openstud.driver.core.models.Tax; 5 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 6 | import lithium.openstud.driver.exceptions.OpenstudInvalidCredentialsException; 7 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 8 | 9 | import java.util.List; 10 | 11 | public interface TaxHandler { 12 | List getUnpaidTaxes() throws OpenstudConnectionException, OpenstudInvalidResponseException, 13 | OpenstudInvalidCredentialsException; 14 | 15 | List getPaidTaxes() throws OpenstudConnectionException, OpenstudInvalidResponseException, 16 | OpenstudInvalidCredentialsException; 17 | 18 | byte[] getPaymentSlipPDF(Tax unpaidTax) throws OpenstudConnectionException, OpenstudInvalidResponseException, 19 | OpenstudInvalidCredentialsException; 20 | 21 | Isee getCurrentIsee() throws OpenstudConnectionException, OpenstudInvalidResponseException, 22 | OpenstudInvalidCredentialsException; 23 | 24 | List getIseeHistory() throws OpenstudConnectionException, OpenstudInvalidResponseException, 25 | OpenstudInvalidCredentialsException; 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/exceptions/OpenstudInvalidCredentialsException.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.exceptions; 2 | 3 | public class OpenstudInvalidCredentialsException extends OpenstudBaseLoginException { 4 | public OpenstudInvalidCredentialsException(String message) { 5 | super(message); 6 | } 7 | 8 | public OpenstudInvalidCredentialsException(Exception e) { 9 | super(e); 10 | if (e instanceof OpenstudBaseLoginException) { 11 | OpenstudBaseLoginException obj = (OpenstudBaseLoginException) e; 12 | if (obj.isAccountBlocked()) this.setAccountBlockedType(); 13 | else if (obj.isPasswordExpired()) this.setPasswordExpiredType(); 14 | else if (obj.isPasswordInvalid()) this.setPasswordInvalidType(); 15 | } 16 | } 17 | 18 | @Override 19 | public OpenstudInvalidCredentialsException setPasswordExpiredType() { 20 | super.setPasswordExpiredType(); 21 | return this; 22 | } 23 | 24 | public OpenstudInvalidCredentialsException setPasswordInvalidType() { 25 | super.setPasswordInvalidType(); 26 | return this; 27 | } 28 | 29 | public OpenstudInvalidCredentialsException setAccountBlockedType() { 30 | super.setAccountBlockedType(); 31 | return this; 32 | } 33 | 34 | public OpenstudInvalidCredentialsException setCaptchaRequired() { 35 | super.setCaptchaRequired(); 36 | return this; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/internals/BioHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.internals; 2 | 3 | import lithium.openstud.driver.core.models.Career; 4 | import lithium.openstud.driver.core.models.CertificateType; 5 | import lithium.openstud.driver.core.models.Student; 6 | import lithium.openstud.driver.core.models.StudentCard; 7 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 8 | import lithium.openstud.driver.exceptions.OpenstudInvalidCredentialsException; 9 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 10 | 11 | import java.util.List; 12 | 13 | 14 | public interface BioHandler { 15 | Student getInfoStudent() throws OpenstudConnectionException, OpenstudInvalidResponseException, 16 | OpenstudInvalidCredentialsException; 17 | 18 | List getCareersChoicesForCertificate(Student student, CertificateType certificate) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException; 19 | 20 | byte[] getCertificatePDF(Student student, Career career, CertificateType certificate) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException; 21 | 22 | 23 | byte[] getStudentPhoto(Student student) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException; 24 | 25 | StudentCard getStudentCard(Student student, boolean withPhoto) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException; 26 | } -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/Lesson.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | 4 | import org.threeten.bp.LocalDateTime; 5 | 6 | public class Lesson { 7 | private String name; 8 | private String where; 9 | private LocalDateTime start; 10 | private LocalDateTime end; 11 | private String teacher; 12 | 13 | public String getName() { 14 | return name; 15 | } 16 | 17 | public void setName(String name) { 18 | this.name = name; 19 | } 20 | 21 | public String getWhere() { 22 | return where; 23 | } 24 | 25 | public void setWhere(String where) { 26 | this.where = where; 27 | } 28 | 29 | public LocalDateTime getStart() { 30 | return start; 31 | } 32 | 33 | public void setStart(LocalDateTime start) { 34 | this.start = start; 35 | } 36 | 37 | public LocalDateTime getEnd() { 38 | return end; 39 | } 40 | 41 | public void setEnd(LocalDateTime end) { 42 | this.end = end; 43 | } 44 | 45 | public String getTeacher() { 46 | return teacher; 47 | } 48 | 49 | public void setTeacher(String teacher) { 50 | this.teacher = teacher; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "Lesson{" + 56 | "name='" + name + '\'' + 57 | ", where='" + where + '\'' + 58 | ", start=" + start + 59 | ", end=" + end + 60 | ", teacher='" + teacher + '\'' + 61 | '}'; 62 | } 63 | } -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/OpenstudValidator.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core; 2 | 3 | import lithium.openstud.driver.exceptions.OpenstudInvalidCredentialsException; 4 | 5 | public class OpenstudValidator { 6 | 7 | public static boolean validatePassword(Openstud os) { 8 | return validatePassword(os, os.getStudentPassword()); 9 | } 10 | 11 | public static boolean validatePassword(Openstud os, String password) { 12 | OpenstudHelper.Provider provider = os.getProvider(); 13 | String nice_path; 14 | if (provider == OpenstudHelper.Provider.SAPIENZA) { 15 | nice_path = "^" + // start 16 | "(?=.*[0-9])" + // at least one digit 17 | "(?=.*[a-z])" + // at least one lower case letter 18 | "(?=.*[A-Z])" + // at least one upper case letter 19 | "(?=.*[\\[\\]*?.@#$%^&!=_-])" + // =.][#?!@$%^&*_- 20 | "(?=\\S+$)" + // no spaces 21 | ".{8,16}" + // length in [8, 16] 22 | "$"; // end 23 | } else { 24 | throw new IllegalArgumentException("Password validation not supported for this provider"); 25 | } 26 | return password != null && password.matches(nice_path); 27 | } 28 | 29 | //to be used when password is forgotten 30 | public static boolean validateUserID(Openstud os) throws OpenstudInvalidCredentialsException { 31 | return os.getStudentID() != null; 32 | } 33 | 34 | public static boolean validate(Openstud os) throws OpenstudInvalidCredentialsException { 35 | return validatePassword(os) && validateUserID(os); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/exceptions/OpenstudBaseResponseException.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.exceptions; 2 | 3 | public abstract class OpenstudBaseResponseException extends Exception { 4 | public enum Type { 5 | JSON_ERROR, MAINTENANCE, RATE_LIMIT, HTML_ERROR, SSL_ERROR, GENERIC 6 | } 7 | 8 | Type type; 9 | 10 | OpenstudBaseResponseException(String message) { 11 | super(message); 12 | type = Type.GENERIC; 13 | } 14 | 15 | OpenstudBaseResponseException(Exception e) { 16 | super(e); 17 | if (e instanceof OpenstudBaseResponseException) this.type = ((OpenstudBaseResponseException) e).type; 18 | } 19 | 20 | 21 | OpenstudBaseResponseException(OpenstudBaseResponseException e) { 22 | super(e); 23 | this.type = e.type; 24 | } 25 | 26 | public boolean isJSONError() { 27 | return type == Type.JSON_ERROR; 28 | } 29 | 30 | public boolean isMaintenance() { 31 | return type == Type.MAINTENANCE; 32 | } 33 | 34 | public boolean isRateLimit() { 35 | return type == Type.RATE_LIMIT; 36 | } 37 | 38 | public boolean isHTMLError() { 39 | return type == Type.HTML_ERROR; 40 | } 41 | 42 | public boolean isSSLType() { 43 | return type == Type.SSL_ERROR; 44 | } 45 | 46 | 47 | Exception setMaintenanceType() { 48 | type = Type.MAINTENANCE; 49 | return this; 50 | } 51 | 52 | Exception setJSONType() { 53 | type = Type.JSON_ERROR; 54 | return this; 55 | } 56 | 57 | Exception setRateLimitType() { 58 | type = Type.RATE_LIMIT; 59 | return this; 60 | } 61 | 62 | Exception setHTMLType() { 63 | type = Type.HTML_ERROR; 64 | return this; 65 | } 66 | 67 | Exception setSSLType() { 68 | type = Type.SSL_ERROR; 69 | return this; 70 | } 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/ExamDoable.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import java.util.Objects; 4 | 5 | public class ExamDoable extends Exam { 6 | private String courseCode; 7 | private String moduleCode; 8 | 9 | public String getCourseCode() { 10 | return courseCode; 11 | } 12 | 13 | public void setCourseCode(String courseCode) { 14 | this.courseCode = courseCode; 15 | } 16 | 17 | public String getModuleCode() { 18 | return moduleCode; 19 | } 20 | 21 | public void setModuleCode(String moduleCode) { 22 | this.moduleCode = moduleCode; 23 | } 24 | 25 | 26 | @Override 27 | public String toString() { 28 | return "ExamDoable{" + 29 | "description='" + getDescription() + '\'' + 30 | ", courseCode='" + courseCode + '\'' + 31 | ", moduleCode='" + moduleCode + '\'' + 32 | ", subjectCode='" + getExamCode() + '\'' + 33 | ", ssd='" + getSsd() + '\'' + 34 | ", cfu=" + getCfu() + 35 | '}'; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) return true; 41 | if (o == null || getClass() != o.getClass()) return false; 42 | ExamDoable that = (ExamDoable) o; 43 | return getCfu() == that.getCfu() && 44 | Objects.equals(getDescription(), that.getDescription()) && 45 | Objects.equals(getExamCode(), that.getExamCode()) && 46 | Objects.equals(getSsd(), that.getSsd()) && 47 | Objects.equals(courseCode, that.courseCode) && 48 | Objects.equals(moduleCode, that.moduleCode); 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | return Objects.hash(getDescription(), getExamCode(), getSsd(), getCfu(), courseCode, moduleCode); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/PaymentDescription.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import java.util.Objects; 4 | 5 | public class PaymentDescription { 6 | private String description; 7 | private Double amount; 8 | private Double amountPaid; 9 | private String academicYear; 10 | 11 | public String getDescription() { 12 | return description; 13 | } 14 | 15 | public void setDescription(String description) { 16 | this.description = description; 17 | } 18 | 19 | public Double getAmount() { 20 | return amount; 21 | } 22 | 23 | public void setAmount(Double amount) { 24 | this.amount = amount; 25 | } 26 | 27 | public Double getAmountPaid() { 28 | return amountPaid; 29 | } 30 | 31 | public void setAmountPaid(Double amountPaid) { 32 | this.amountPaid = amountPaid; 33 | } 34 | 35 | public String getAcademicYear() { 36 | return academicYear; 37 | } 38 | 39 | public void setAcademicYear(String academicYear) { 40 | this.academicYear = academicYear; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "PaymentDescription{" + 46 | "description='" + description + '\'' + 47 | ", amount=" + amount + 48 | ", amountPaid=" + amountPaid + 49 | ", academicYear='" + academicYear + '\'' + 50 | '}'; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object o) { 55 | if (this == o) return true; 56 | if (o == null || getClass() != o.getClass()) return false; 57 | PaymentDescription that = (PaymentDescription) o; 58 | return Objects.equals(description, that.description) && 59 | Objects.equals(amount, that.amount) && 60 | Objects.equals(amountPaid, that.amountPaid) && 61 | Objects.equals(academicYear, that.academicYear); 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return Objects.hash(description, amount, amountPaid, academicYear); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/internals/ExamHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.internals; 2 | 3 | import lithium.openstud.driver.core.models.*; 4 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 5 | import lithium.openstud.driver.exceptions.OpenstudInvalidCredentialsException; 6 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 7 | import org.apache.commons.lang3.tuple.Pair; 8 | 9 | import java.util.List; 10 | 11 | public interface ExamHandler { 12 | List getExamsDoable() throws OpenstudConnectionException, OpenstudInvalidResponseException, 13 | OpenstudInvalidCredentialsException; 14 | 15 | List getExamsDone() throws OpenstudConnectionException, OpenstudInvalidResponseException, 16 | OpenstudInvalidCredentialsException; 17 | 18 | List getActiveReservations() throws OpenstudConnectionException, OpenstudInvalidResponseException, 19 | OpenstudInvalidCredentialsException; 20 | 21 | List getAvailableReservations(ExamDoable exam, Student student) throws OpenstudConnectionException, 22 | OpenstudInvalidResponseException, OpenstudInvalidCredentialsException; 23 | 24 | Pair insertReservation(ExamReservation res) throws OpenstudInvalidResponseException, 25 | OpenstudConnectionException, OpenstudInvalidCredentialsException; 26 | 27 | int deleteReservation(ExamReservation res) throws OpenstudInvalidResponseException, OpenstudConnectionException, 28 | OpenstudInvalidCredentialsException; 29 | 30 | byte[] getExamReservationPDF(ExamReservation reservation) throws OpenstudConnectionException, OpenstudInvalidResponseException, 31 | OpenstudInvalidCredentialsException; 32 | 33 | List getCalendarEvents(Student student) throws OpenstudConnectionException, OpenstudInvalidResponseException, 34 | OpenstudInvalidCredentialsException; 35 | 36 | String getCourseSurvey(String surveyCode) throws OpenstudConnectionException, OpenstudInvalidResponseException, 37 | OpenstudInvalidCredentialsException; 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/exceptions/OpenstudBaseLoginException.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.exceptions; 2 | 3 | public abstract class OpenstudBaseLoginException extends Exception { 4 | public enum Type { 5 | INVALID_PASSWORD, EXPIRED_PASSWORD, ACCOUNT_BLOCKED, CAPTCHA_REQUIRED 6 | } 7 | 8 | private Type type; 9 | private int attemptNumber = -1; 10 | private int maxAttempts = -1; 11 | OpenstudBaseLoginException(String message) { 12 | super(message); 13 | type = Type.INVALID_PASSWORD; 14 | } 15 | 16 | OpenstudBaseLoginException(Exception e) { 17 | super(e); 18 | if (e instanceof OpenstudBaseLoginException) this.type = ((OpenstudBaseLoginException) e).type; 19 | } 20 | 21 | 22 | OpenstudBaseLoginException(OpenstudBaseLoginException e) { 23 | super(e); 24 | this.type = e.type; 25 | } 26 | 27 | public boolean isPasswordExpired() { 28 | return type == Type.EXPIRED_PASSWORD; 29 | } 30 | 31 | public boolean isPasswordInvalid() { 32 | return type == Type.INVALID_PASSWORD; 33 | } 34 | 35 | public boolean isAccountBlocked() { 36 | return type == Type.ACCOUNT_BLOCKED; 37 | } 38 | 39 | public boolean isCaptchaRequired() { 40 | return type == Type.CAPTCHA_REQUIRED; 41 | } 42 | 43 | public int getAttemptNumber(){ 44 | return attemptNumber; 45 | } 46 | 47 | public int getMaxAttempts(){ 48 | return maxAttempts; 49 | } 50 | 51 | public void setAttemptNumber(int attemptNumber){ 52 | this.attemptNumber = attemptNumber; 53 | } 54 | 55 | public void setMaxAttempts(int maxAttempts){ 56 | this.maxAttempts = maxAttempts; 57 | } 58 | 59 | Exception setPasswordExpiredType() { 60 | type = Type.EXPIRED_PASSWORD; 61 | return this; 62 | } 63 | 64 | Exception setPasswordInvalidType() { 65 | type = Type.INVALID_PASSWORD; 66 | return this; 67 | } 68 | 69 | Exception setAccountBlockedType() { 70 | type = Type.ACCOUNT_BLOCKED; 71 | return this; 72 | } 73 | 74 | Exception setCaptchaRequired() { 75 | type = Type.CAPTCHA_REQUIRED; 76 | return this; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/StudentCard.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import org.apache.commons.codec.binary.Base64; 4 | import org.threeten.bp.LocalDateTime; 5 | 6 | import java.util.Objects; 7 | 8 | public class StudentCard { 9 | private String code; 10 | private LocalDateTime issueDate; 11 | private String studentId; 12 | private String imageBase64; 13 | private boolean isEnabled; 14 | 15 | 16 | public boolean isEnabled() { 17 | return isEnabled; 18 | } 19 | 20 | public void setEnabled(boolean enabled) { 21 | isEnabled = enabled; 22 | } 23 | 24 | public String getStudentId() { 25 | return studentId; 26 | } 27 | 28 | public void setStudentId(String studentId) { 29 | this.studentId = studentId; 30 | } 31 | 32 | public String getCode() { 33 | return code; 34 | } 35 | 36 | public void setCode(String code) { 37 | this.code = code; 38 | } 39 | 40 | 41 | public LocalDateTime getIssueDate() { 42 | return issueDate; 43 | } 44 | 45 | public void setIssueDate(LocalDateTime issueDate) { 46 | this.issueDate = issueDate; 47 | } 48 | 49 | public byte[] getImage() { 50 | if (imageBase64 == null) return null; 51 | return Base64.decodeBase64(imageBase64.getBytes()); 52 | } 53 | 54 | public void setImage(byte[] image) { 55 | if (image == null) imageBase64 = null; 56 | else imageBase64 = new String(Base64.encodeBase64(image)); 57 | } 58 | 59 | @Override 60 | public boolean equals(Object o) { 61 | if (this == o) return true; 62 | if (o == null || getClass() != o.getClass()) return false; 63 | StudentCard that = (StudentCard) o; 64 | return isEnabled == that.isEnabled && 65 | Objects.equals(code, that.code) && 66 | Objects.equals(issueDate, that.issueDate) && 67 | Objects.equals(studentId, that.studentId) && 68 | Objects.equals(imageBase64, that.imageBase64); 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | return Objects.hash(code, issueDate, studentId, imageBase64, isEnabled); 74 | } 75 | 76 | @Override 77 | public String toString() { 78 | return "StudentCard{" + 79 | "code='" + code + '\'' + 80 | ", issueDate=" + issueDate + 81 | ", studentId='" + studentId + '\'' + 82 | ", isEnabled=" + isEnabled + 83 | '}'; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/Isee.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | 4 | import org.threeten.bp.LocalDate; 5 | 6 | import java.util.Objects; 7 | 8 | public class Isee { 9 | private double value; 10 | private String protocol; 11 | private LocalDate dateOperation; 12 | private LocalDate dateDeclaration; 13 | private boolean isEditable; 14 | 15 | public double getValue() { 16 | return value; 17 | } 18 | 19 | public String getProtocol() { 20 | return protocol; 21 | } 22 | 23 | public LocalDate getDateOperation() { 24 | return dateOperation; 25 | } 26 | 27 | public LocalDate getDateDeclaration() { 28 | return dateDeclaration; 29 | } 30 | 31 | public boolean isEditable() { 32 | return isEditable; 33 | } 34 | 35 | public void setValue(double value) { 36 | this.value = value; 37 | } 38 | 39 | public void setProtocol(String protocol) { 40 | this.protocol = protocol; 41 | } 42 | 43 | public void setDateOperation(LocalDate dateOperation) { 44 | this.dateOperation = dateOperation; 45 | } 46 | 47 | public void setDateDeclaration(LocalDate dateDeclaration) { 48 | this.dateDeclaration = dateDeclaration; 49 | } 50 | 51 | public void setEditable(boolean editable) { 52 | isEditable = editable; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return "Isee{" + 58 | "value=" + value + 59 | ", protocol='" + protocol + '\'' + 60 | ", dateOperation=" + dateOperation + 61 | ", dateDeclaration=" + dateDeclaration + 62 | ", isEditable=" + isEditable + 63 | '}'; 64 | } 65 | 66 | public boolean isValid() { 67 | return protocol != null && !protocol.isEmpty(); 68 | } 69 | 70 | @Override 71 | public boolean equals(Object o) { 72 | if (this == o) return true; 73 | if (o == null || getClass() != o.getClass()) return false; 74 | Isee isee = (Isee) o; 75 | return Double.compare(isee.value, value) == 0 && 76 | isEditable == isee.isEditable && 77 | Objects.equals(protocol, isee.protocol) && 78 | Objects.equals(dateOperation, isee.dateOperation) && 79 | Objects.equals(dateDeclaration, isee.dateDeclaration); 80 | } 81 | 82 | @Override 83 | public int hashCode() { 84 | return Objects.hash(value, protocol, dateOperation, dateDeclaration, isEditable); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/NewsEvent.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import java.util.Objects; 4 | 5 | public class NewsEvent { 6 | // to local date 7 | private String date; 8 | private String hour; 9 | private String description; 10 | private String where; 11 | private String room; 12 | private String url; 13 | private String imageUrl; 14 | 15 | 16 | public String getDate() { 17 | return date; 18 | } 19 | 20 | public void setDate(String date) { 21 | this.date = date; 22 | } 23 | 24 | public String getDescription() { 25 | return description; 26 | } 27 | 28 | public void setDescription(String description) { 29 | this.description = description; 30 | } 31 | 32 | public String getWhere() { 33 | return where; 34 | } 35 | 36 | public void setWhere(String where) { 37 | this.where = where; 38 | } 39 | 40 | public String getRoom() { 41 | return room; 42 | } 43 | 44 | public void setRoom(String room) { 45 | this.room = room; 46 | } 47 | 48 | public String getUrl() { 49 | return url; 50 | } 51 | 52 | public void setUrl(String url) { 53 | this.url = url; 54 | } 55 | 56 | @Override 57 | public boolean equals(Object o) { 58 | if (this == o) 59 | return true; 60 | if (o == null || getClass() != o.getClass()) 61 | return false; 62 | NewsEvent newsEvent = (NewsEvent) o; 63 | return Objects.equals(date, newsEvent.date) && 64 | Objects.equals(description, newsEvent.description) && 65 | Objects.equals(where, newsEvent.where) && 66 | Objects.equals(room, newsEvent.room) && 67 | Objects.equals(url, newsEvent.url) && 68 | Objects.equals(imageUrl, newsEvent.imageUrl); 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | return Objects.hash(date, description, where, room, url, imageUrl); 74 | } 75 | 76 | @Override 77 | public String toString() { 78 | return "NewsEvent{" + "date=" + date + ", description='" + description + '\'' + ", where='" + where + '\'' + 79 | ", room='" + room + '\'' + ", url='" + url + '\'' + imageUrl + '\'' + '}'; 80 | } 81 | 82 | public String getHour() { 83 | return hour; 84 | } 85 | 86 | public void setHour(String hour) { 87 | this.hour = hour; 88 | } 89 | 90 | public String getImageUrl() { 91 | return imageUrl; 92 | } 93 | 94 | public void setImageUrl(String imageUrl) { 95 | this.imageUrl = imageUrl; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/OpenstudBuilder.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.logging.Logger; 6 | 7 | public class OpenstudBuilder { 8 | OpenstudHelper.Mode mode = OpenstudHelper.Mode.MOBILE; 9 | OpenstudHelper.Provider provider = OpenstudHelper.Provider.SAPIENZA; 10 | int retryCounter = 3; 11 | int connectTimeout = 10; 12 | int writeTimeout = 10; 13 | int readTimeout = 30; 14 | String studentID; 15 | String password; 16 | Logger logger; 17 | boolean readyState = false; 18 | int limitSearchResults = 13; 19 | int waitTimeClassroomRequest = 200; 20 | Map keyMap = new HashMap<>(); 21 | 22 | public void setLimitSearchResults(int limitSearchResults) { 23 | this.limitSearchResults = limitSearchResults; 24 | } 25 | 26 | public void setClassroomWaitRequest(int millis) { 27 | if (millis < 0) return; 28 | this.waitTimeClassroomRequest = millis; 29 | } 30 | 31 | public OpenstudBuilder setRetryCounter(int retryCounter) { 32 | this.retryCounter = retryCounter; 33 | return this; 34 | } 35 | 36 | public OpenstudBuilder setConnectTimeout(int connectTimeout) { 37 | this.connectTimeout = connectTimeout; 38 | return this; 39 | } 40 | 41 | public OpenstudBuilder setReadTimeout(int readTimeout) { 42 | this.readTimeout = readTimeout; 43 | return this; 44 | } 45 | 46 | public OpenstudBuilder setWriteTimeout(int writeTimeout) { 47 | this.writeTimeout = writeTimeout; 48 | return this; 49 | } 50 | 51 | public OpenstudBuilder setStudentID(String id) { 52 | this.studentID = id; 53 | return this; 54 | } 55 | 56 | public OpenstudBuilder setPassword(String password) { 57 | this.password = password; 58 | return this; 59 | } 60 | 61 | public OpenstudBuilder setLogger(Logger logger) { 62 | this.logger = logger; 63 | return this; 64 | } 65 | 66 | public OpenstudBuilder forceReadyState() { 67 | this.readyState = true; 68 | return this; 69 | } 70 | 71 | public OpenstudBuilder setMode(OpenstudHelper.Mode mode) { 72 | this.mode = mode; 73 | return this; 74 | } 75 | 76 | public OpenstudBuilder setProvider(OpenstudHelper.Provider provider) { 77 | this.provider = provider; 78 | return this; 79 | } 80 | 81 | public OpenstudBuilder setKeys(Map keyMap) { 82 | this.keyMap = keyMap; 83 | return this; 84 | } 85 | 86 | public Openstud build() { 87 | 88 | return new Openstud(this); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/News.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import org.threeten.bp.LocalDate; 4 | 5 | import java.util.Objects; 6 | 7 | public class News { 8 | private String imageUrl; 9 | private String smallImageUrl; 10 | private String title; 11 | private String url; 12 | private String locale; 13 | private String description; 14 | private LocalDate date; 15 | 16 | public String getDescription() { 17 | return description; 18 | } 19 | 20 | public void setDescription(String description) { 21 | this.description = description; 22 | } 23 | 24 | public String getLocale() { 25 | return locale; 26 | } 27 | 28 | public void setLocale(String locale) { 29 | this.locale = locale; 30 | } 31 | 32 | public String getImageUrl() { 33 | return imageUrl; 34 | } 35 | 36 | public void setImageUrl(String imageUrl) { 37 | this.imageUrl = imageUrl; 38 | } 39 | 40 | public String getTitle() { 41 | return title; 42 | } 43 | 44 | public void setTitle(String title) { 45 | this.title = title; 46 | } 47 | 48 | public String getUrl() { 49 | return url; 50 | } 51 | 52 | public void setUrl(String url) { 53 | this.url = url; 54 | } 55 | 56 | public String getSmallImageUrl() { 57 | return smallImageUrl; 58 | } 59 | 60 | public void setSmallImageUrl(String smallUrl) { 61 | this.smallImageUrl = smallUrl; 62 | } 63 | 64 | public LocalDate getDate() { 65 | return date; 66 | } 67 | 68 | public void setDate(LocalDate date) { 69 | this.date = date; 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return "News{" + 75 | "imageUrl='" + imageUrl + '\'' + 76 | ", title='" + title + '\'' + 77 | ", url='" + url + '\'' + 78 | ", locale='" + locale + '\'' + 79 | ", description='" + description + '\'' + 80 | ", smallImageUrl='" + smallImageUrl + '\'' + 81 | ", date='" + date + '\'' + 82 | '}'; 83 | } 84 | 85 | @Override 86 | public boolean equals(Object o) { 87 | if (this == o) return true; 88 | if (o == null || getClass() != o.getClass()) return false; 89 | News news = (News) o; 90 | return Objects.equals(imageUrl, news.imageUrl) && 91 | Objects.equals(smallImageUrl, news.smallImageUrl) && 92 | Objects.equals(title, news.title) && 93 | Objects.equals(url, news.url) && 94 | Objects.equals(locale, news.locale) && 95 | Objects.equals(description, news.description) && 96 | Objects.equals(date, news.date); 97 | } 98 | 99 | @Override 100 | public int hashCode() { 101 | return Objects.hash(imageUrl, smallImageUrl, title, url, locale, description, date); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/ExamDone.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | 4 | import org.threeten.bp.LocalDate; 5 | 6 | import java.util.Objects; 7 | 8 | public class ExamDone extends Exam { 9 | private LocalDate date; 10 | private int year; 11 | private String nominalResult; 12 | private int result; 13 | private boolean passed; 14 | private boolean certified; 15 | 16 | public LocalDate getDate() { 17 | return date; 18 | } 19 | 20 | public void setDate(LocalDate date) { 21 | this.date = date; 22 | } 23 | 24 | public int getYear() { 25 | return year; 26 | } 27 | 28 | public void setYear(int year) { 29 | this.year = year; 30 | } 31 | 32 | public String getNominalResult() { 33 | return nominalResult; 34 | } 35 | 36 | public void setNominalResult(String nominalResult) { 37 | this.nominalResult = nominalResult; 38 | } 39 | 40 | public int getResult() { 41 | return result; 42 | } 43 | 44 | public void setResult(int result) { 45 | this.result = result; 46 | } 47 | 48 | public boolean isPassed() { 49 | return passed; 50 | } 51 | 52 | public void setPassed(boolean passed) { 53 | this.passed = passed; 54 | } 55 | 56 | public boolean isCertified() { 57 | return certified; 58 | } 59 | 60 | public void setCertified(boolean certified) { 61 | this.certified = certified; 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return "ExamDone{" + 67 | "description='" + getDescription() + '\'' + 68 | "date=" + date + 69 | ", year=" + year + 70 | ", nominalResult='" + nominalResult + '\'' + 71 | ", result=" + result + 72 | ", passed=" + passed + 73 | ", certified=" + certified + 74 | ", subjectCode='" + getExamCode() + '\'' + 75 | ", ssd='" + getSsd() + '\'' + 76 | ", cfu=" + getCfu() + 77 | '}'; 78 | } 79 | 80 | @Override 81 | public boolean equals(Object o) { 82 | if (this == o) return true; 83 | if (o == null || getClass() != o.getClass()) return false; 84 | ExamDone examDone = (ExamDone) o; 85 | return getCfu() == examDone.getCfu() && 86 | Objects.equals(getDescription(), examDone.getDescription()) && 87 | Objects.equals(getExamCode(), examDone.getExamCode()) && 88 | Objects.equals(getSsd(), examDone.getSsd()) && 89 | year == examDone.year && 90 | result == examDone.result && 91 | passed == examDone.passed && 92 | certified == examDone.certified && 93 | Objects.equals(date, examDone.date) && 94 | Objects.equals(nominalResult, examDone.nominalResult); 95 | } 96 | 97 | @Override 98 | public int hashCode() { 99 | return Objects.hash(getDescription(), getExamCode(), getSsd(), getCfu(), date, year, nominalResult, result, passed, certified); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/Career.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import java.util.Objects; 4 | 5 | public class Career { 6 | private int index; 7 | private String registrationCode; 8 | private String codeCourse; 9 | private String description; 10 | private String descriptionComplete; 11 | private String organization; 12 | private String type; 13 | private String teachingCode; 14 | 15 | public String getTeachingCode() { 16 | return teachingCode; 17 | } 18 | 19 | public void setTeachingCode(String teachingCode) { 20 | this.teachingCode = teachingCode; 21 | } 22 | 23 | public int getIndex() { 24 | return index; 25 | } 26 | 27 | public void setIndex(int index) { 28 | this.index = index; 29 | } 30 | 31 | public String getRegistrationCode() { 32 | return registrationCode; 33 | } 34 | 35 | public void setRegistrationCode(String registrationCode) { 36 | this.registrationCode = registrationCode; 37 | } 38 | 39 | public String getCodeCourse() { 40 | return codeCourse; 41 | } 42 | 43 | public void setCodeCourse(String codeCourse) { 44 | this.codeCourse = codeCourse; 45 | } 46 | 47 | public String getDescription() { 48 | return description; 49 | } 50 | 51 | public void setDescription(String description) { 52 | this.description = description; 53 | } 54 | 55 | public String getDescriptionComplete() { 56 | return descriptionComplete; 57 | } 58 | 59 | public void setDescriptionComplete(String descriptionComplete) { 60 | this.descriptionComplete = descriptionComplete; 61 | } 62 | 63 | public String getOrganization() { 64 | return organization; 65 | } 66 | 67 | public void setOrganization(String organization) { 68 | this.organization = organization; 69 | } 70 | 71 | public String getType() { 72 | return type; 73 | } 74 | 75 | public void setType(String type) { 76 | this.type = type; 77 | } 78 | 79 | @Override 80 | public boolean equals(Object o) { 81 | if (this == o) return true; 82 | if (o == null || getClass() != o.getClass()) return false; 83 | Career career = (Career) o; 84 | return index == career.index && 85 | Objects.equals(registrationCode, career.registrationCode) && 86 | Objects.equals(codeCourse, career.codeCourse) && 87 | Objects.equals(description, career.description) && 88 | Objects.equals(descriptionComplete, career.descriptionComplete) && 89 | Objects.equals(organization, career.organization) && 90 | Objects.equals(type, career.type) && 91 | Objects.equals(teachingCode, career.teachingCode); 92 | } 93 | 94 | @Override 95 | public int hashCode() { 96 | return Objects.hash(index, registrationCode, codeCourse, description, descriptionComplete, organization, type, teachingCode); 97 | } 98 | 99 | @Override 100 | public String toString() { 101 | return "Career{" + 102 | "index=" + index + 103 | ", registrationCode='" + registrationCode + '\'' + 104 | ", codeCourse='" + codeCourse + '\'' + 105 | ", description='" + description + '\'' + 106 | ", descriptionComplete='" + descriptionComplete + '\'' + 107 | ", organization='" + organization + '\'' + 108 | ", type='" + type + '\'' + 109 | ", teachingCode='" + teachingCode + '\'' + 110 | '}'; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/Tax.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import org.threeten.bp.LocalDate; 4 | 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import java.util.Objects; 8 | 9 | public class Tax { 10 | private TaxStatus status; 11 | private String code; 12 | private String codeCourse; 13 | private String descriptionCourse; 14 | private double amount; 15 | private LocalDate paymentDate; 16 | private LocalDate expirationDate; 17 | private List paymentDescriptionList; 18 | private int academicYear; 19 | 20 | public Tax() { 21 | paymentDescriptionList = new LinkedList(); 22 | } 23 | 24 | public String getCode() { 25 | return code; 26 | } 27 | 28 | public void setCode(String code) { 29 | this.code = code; 30 | } 31 | 32 | public String getCodeCourse() { 33 | return codeCourse; 34 | } 35 | 36 | public void setCodeCourse(String codeCourse) { 37 | this.codeCourse = codeCourse; 38 | } 39 | 40 | public String getDescriptionCourse() { 41 | return descriptionCourse; 42 | } 43 | 44 | public void setDescriptionCourse(String descriptionCourse) { 45 | this.descriptionCourse = descriptionCourse; 46 | } 47 | 48 | public double getAmount() { 49 | return amount; 50 | } 51 | 52 | public void setAmount(double amount) { 53 | this.amount = amount; 54 | } 55 | 56 | public LocalDate getPaymentDate() { 57 | return paymentDate; 58 | } 59 | 60 | public void setPaymentDate(LocalDate paymentDate) { 61 | this.paymentDate = paymentDate; 62 | } 63 | 64 | public LocalDate getExpirationDate() { 65 | return expirationDate; 66 | } 67 | 68 | public void setExpirationDate(LocalDate expirationDate) { 69 | this.expirationDate = expirationDate; 70 | } 71 | 72 | public List getPaymentDescriptionList() { 73 | return paymentDescriptionList; 74 | } 75 | 76 | public void setPaymentDescriptionList(List paymentDescriptionList) { 77 | this.paymentDescriptionList = paymentDescriptionList; 78 | } 79 | 80 | public int getAcademicYear() { 81 | return academicYear; 82 | } 83 | 84 | public void setAcademicYear(int academicYear) { 85 | this.academicYear = academicYear; 86 | } 87 | 88 | public TaxStatus getStatus() { 89 | return status; 90 | } 91 | 92 | public void setStatus(TaxStatus status) { 93 | this.status = status; 94 | } 95 | 96 | @Override 97 | public boolean equals(Object o) { 98 | if (this == o) return true; 99 | if (o == null || getClass() != o.getClass()) return false; 100 | Tax tax = (Tax) o; 101 | return Double.compare(tax.amount, amount) == 0 && 102 | academicYear == tax.academicYear && 103 | Objects.equals(code, tax.code) && 104 | Objects.equals(codeCourse, tax.codeCourse) && 105 | Objects.equals(descriptionCourse, tax.descriptionCourse) && 106 | Objects.equals(paymentDate, tax.paymentDate) && 107 | Objects.equals(expirationDate, tax.expirationDate) && 108 | Objects.equals(paymentDescriptionList, tax.paymentDescriptionList); 109 | } 110 | 111 | @Override 112 | public int hashCode() { 113 | return Objects.hash(code, codeCourse, descriptionCourse, amount, paymentDate, expirationDate, paymentDescriptionList, academicYear); 114 | } 115 | 116 | @Override 117 | public String toString() { 118 | return "Tax{" + 119 | "code='" + code + '\'' + 120 | ", codeCourse='" + codeCourse + '\'' + 121 | ", descriptionCourse='" + descriptionCourse + '\'' + 122 | ", amount=" + amount + 123 | ", paymentDate=" + paymentDate + 124 | ", expirationDate=" + expirationDate + 125 | ", paymentDescriptionList=" + paymentDescriptionList + 126 | ", academicYear=" + academicYear + 127 | '}'; 128 | } 129 | 130 | public enum TaxStatus{ 131 | UNPAID,PAID 132 | } 133 | } 134 | 135 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/providers/sapienza/SapienzaConfig.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.providers.sapienza; 2 | 3 | import lithium.openstud.driver.core.OpenstudHelper; 4 | import lithium.openstud.driver.core.internals.ProviderConfig; 5 | import lithium.openstud.driver.core.models.CertificateType; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | public class SapienzaConfig implements ProviderConfig { 11 | private final boolean AUTH_ENABLED = true; 12 | private final boolean BIO_ENABLED = true; 13 | private final boolean CLASSROOM_ENABLED = true; 14 | private final boolean EXAM_ENABLED = true; 15 | private final boolean NEWS_ENABLED = true; 16 | private final boolean TAX_ENABLED = true; 17 | private final boolean REFRESH_ENABLED = true; 18 | private final boolean SURVEY_ENABLED = true; 19 | private final boolean CERT_ENABLED = true; 20 | private final boolean CAREER_FOR_CERTIFICATE_ENABLED = true; 21 | private final boolean CARD_ENABLED = true; 22 | private final boolean PHOTO_ENABLED = true; 23 | private final Map CUSTOM_KEY_MAP = new HashMap<>(); 24 | private final CertificateType[] SUPPORTED_CERTIFICATES = new CertificateType[]{CertificateType.EXAMS_COMPLETED, 25 | CertificateType.DEGREE_FOR_RANSOM, CertificateType.DEGREE_WITH_EVALUATION, CertificateType.DEGREE_WITH_EVALUATION_ENG, 26 | CertificateType.DEGREE_WITH_EXAMS, CertificateType.DEGREE_WITH_EXAMS_ENG, CertificateType.REGISTRATION, 27 | CertificateType.DEGREE_WITH_THESIS, CertificateType.DEGREE_WITH_THESIS_ENG}; 28 | 29 | @Override 30 | public String getEndpointAPI(OpenstudHelper.Mode mode) { 31 | if (mode == OpenstudHelper.Mode.MOBILE) return "https://www.studenti.uniroma1.it/phxdroidws"; 32 | else return "https://www.studenti.uniroma1.it/phoenixws"; 33 | } 34 | 35 | @Override 36 | public String getEndpointTimetable(OpenstudHelper.Mode mode) { 37 | return "https://gomp.sapienzaapps.it"; 38 | } 39 | 40 | @Override 41 | public String getEmailURL() { 42 | return "https://mail.google.com/a/studenti.uniroma1.it"; 43 | } 44 | 45 | @Override 46 | public boolean isAuthEnabled() { 47 | return AUTH_ENABLED; 48 | } 49 | 50 | @Override 51 | public boolean isClassroomEnabled() { 52 | return CLASSROOM_ENABLED; 53 | } 54 | 55 | @Override 56 | public boolean isExamEnabled() { 57 | return EXAM_ENABLED; 58 | } 59 | 60 | @Override 61 | public boolean isNewsEnabled() { 62 | return NEWS_ENABLED; 63 | } 64 | 65 | @Override 66 | public boolean isTaxEnabled() { 67 | return TAX_ENABLED; 68 | } 69 | 70 | @Override 71 | public boolean isBioEnabled() { 72 | return BIO_ENABLED; 73 | } 74 | 75 | @Override 76 | public boolean isCertEnabled() { 77 | return CERT_ENABLED; 78 | } 79 | 80 | @Override 81 | public boolean isSurveyEnabled() { 82 | return SURVEY_ENABLED; 83 | } 84 | 85 | @Override 86 | public boolean isCareerForCertificateEnabled() { 87 | return CAREER_FOR_CERTIFICATE_ENABLED; 88 | } 89 | 90 | @Override 91 | public boolean isStudentCardEnabled() { 92 | return CARD_ENABLED; 93 | } 94 | 95 | @Override 96 | public boolean isStudentPhotoEnabled() { 97 | return PHOTO_ENABLED; 98 | } 99 | 100 | @Override 101 | public boolean isRefreshEnabled() { 102 | return REFRESH_ENABLED; 103 | } 104 | 105 | @Override 106 | public boolean isCertSupported(CertificateType certificate) { 107 | for (CertificateType cert : SUPPORTED_CERTIFICATES) { 108 | if (cert == certificate) return true; 109 | } 110 | return false; 111 | } 112 | 113 | @Override 114 | public String getKey(OpenstudHelper.Mode mode) { 115 | if (mode == OpenstudHelper.Mode.WEB) return "1nf0r1cc1"; 116 | else return "r4g4zz3tt1"; 117 | } 118 | 119 | public synchronized String getKey(String key) { 120 | if (CUSTOM_KEY_MAP.containsKey(key)) return CUSTOM_KEY_MAP.get(key); 121 | else return null; 122 | } 123 | 124 | public synchronized void addKeys(Map customKeys) { 125 | CUSTOM_KEY_MAP.putAll(customKeys); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenStud Driver [![Build Status](https://travis-ci.com/LithiumSR/openstud_driver.svg?branch=master)](https://travis-ci.com/LithiumSR/openstud_driver) [![CodeFactor](https://www.codefactor.io/repository/github/lithiumsr/openstud_driver/badge)](https://www.codefactor.io/repository/github/lithiumsr/openstud_driver) [![Language grade: Java](https://img.shields.io/lgtm/grade/java/g/LithiumSR/openstud_driver.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/LithiumSR/openstud_driver/context:java) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) 2 | 3 | OpenStud Driver is Java Libary to obtain infos from Sapienza University's Infostud. 4 | 5 | This library is thread-safe and Android-friendly. 6 | 7 | ## Getting started 8 | 9 | ### Prerequisites 10 | This application is written with JDK8 in mind. If you don't have a Java Development Kit installed you can download it from [Oracle](http://www.oracle.com/technetwork/java/javase/downloads/index.html). 11 | 12 | ### Compile from sources 13 | - `git clone` or download this repo. 14 | - Open a terminal in the directory where the sources are stored. 15 | - Execute `mvn install -DskipTests` . You will find the .jar file in the target folder. 16 | 17 | ### Add to your project 18 | 19 | OpenStud Driver can be easily added to your existing project through Maven or Gradle. 20 | 21 | **Maven** 22 | 23 | 1) Add the JitPack repository 24 | ``` 25 | 26 | 27 | jitpack.io 28 | https://jitpack.io 29 | 30 | 31 | ``` 32 | 2) Add the dependency 33 | ``` 34 | 35 | com.github.LithiumSR 36 | openstud_driver 37 | 0.60.0 38 | 39 | ``` 40 | 41 | **Gradle** 42 | 43 | 1) Add it in your root build.gradle at the end of repositories: 44 | ``` 45 | allprojects { 46 | repositories { 47 | maven { url 'https://jitpack.io' } 48 | } 49 | } 50 | ``` 51 | 2) Add the dependency 52 | ``` 53 | dependencies { 54 | implementation 'com.github.LithiumSR:openstud_driver:0.60.0' 55 | } 56 | ``` 57 | 58 | ## Functionalities 59 | **Authentication** 60 | - [x] Login 61 | - [x] Security question and password recovery 62 | - [x] Passsword reset 63 | 64 | **Profile** 65 | - [x] Student infos 66 | - [x] Certificates 67 | - [x] Photo and student card 68 | 69 | **Classroom** 70 | - [x] Classroom and timetable 71 | 72 | **Exams** 73 | - [x] Doable and done exams 74 | - [x] Active and available reservations 75 | - [x] Insert and delete reservations 76 | - [x] Pdf reservation 77 | - [x] Calendar events 78 | - [x] Course surveys (OPIS) 79 | 80 | **Taxes** 81 | - [x] Paid and unpaid taxes 82 | - [x] Current ISEE and ISEE history 83 | 84 | **News** 85 | - [x] News and newsletter events 86 | 87 | ## Documentation 88 | 89 | Soon(tm) 90 | 91 | ### Examples 92 | ``` 93 | Logger log = Logger.getLogger("lithium.openstud"); 94 | 95 | //Create an OpenStud object and sign-in 96 | Openstud os = new OpenstudBuilder().setPassword("myPassword").setStudentID(123456).setLogger(log).build(); 97 | os.login(); 98 | 99 | //Get personal infos about a student 100 | Student st = os.getInfoStudent(); 101 | 102 | //Get a list of exams that the student hasn't passed yet 103 | List doable = os.getExamsDoable(); 104 | 105 | //Get a list of exams that the student passed with flying colors :) 106 | List passed = os.getExamsPassed()); 107 | 108 | //Get a list of reservations that the student has already placed 109 | List active = os.getActiveReservations(); 110 | 111 | //Get a list of the reservations avaiable for a particular exam 112 | List available = os.getAvailableReservations(doable.get(0),st); 113 | 114 | //Place a reservation for a particulare session of an exam 115 | Pair pr = os.insertReservation(available.get(0)); 116 | 117 | //Download the PDF of a particular active reservation 118 | byte[] pdf = os.getPdf(active.get(0)); 119 | 120 | //Delete an active reservation 121 | int result = os.deleteReservation(active.get(0)); 122 | ``` 123 | 124 | ## Dependencies 125 | - [Square OkHttp](https://github.com/square/okhttp) 126 | - [JUnit](https://github.com/junit-team/junit4) 127 | - [jsoup](https://jsoup.org/) 128 | - [ThreeTenBP](https://github.com/ThreeTen/threetenbp) 129 | - [org/Json](https://github.com/stleary/JSON-java) 130 | - [Apache HttpComponents](https://hc.apache.org/) 131 | - [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/) 132 | - [Apache Commons-IO](https://commons.apache.org/proper/commons-io/) 133 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 4.0.0 7 | 8 | lithium.openstud.driver 9 | openstud-driver 10 | 0.60.0 11 | 12 | openstud-driver 13 | 14 | 15 | 16 | jitpack.io 17 | https://jitpack.io 18 | 19 | 20 | 21 | 22 | UTF-8 23 | 1.8 24 | 1.8 25 | 26 | 27 | 28 | 29 | github 30 | GitHub LithiumSR Apache Maven Packages 31 | https://maven.pkg.github.com/LithiumSR/openstud_driver 32 | 33 | 34 | 35 | 36 | 37 | com.github.LithiumSR 38 | Kapitalize 39 | 1.6.0 40 | 41 | 42 | com.squareup.okhttp3 43 | okhttp 44 | 4.7.2 45 | 46 | 47 | 48 | org.apache.httpcomponents 49 | httpclient 50 | 4.5.13 51 | 52 | 53 | 54 | 55 | org.threeten 56 | threetenbp 57 | 1.4.4 58 | 59 | 60 | 61 | 62 | org.apache.httpcomponents 63 | httpasyncclient 64 | 4.1.4 65 | 66 | 67 | 68 | org.apache.httpcomponents 69 | httpmime 70 | 4.5.12 71 | 72 | 73 | org.json 74 | json 75 | 20200518 76 | 77 | 78 | junit 79 | junit 80 | 4.13.1 81 | test 82 | 83 | 84 | commons-io 85 | commons-io 86 | 2.7 87 | 88 | 89 | 90 | org.apache.commons 91 | commons-lang3 92 | 3.10 93 | 94 | 95 | 96 | org.jsoup 97 | jsoup 98 | 1.15.3 99 | 100 | 101 | 102 | commons-validator 103 | commons-validator 104 | 1.6 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | maven-clean-plugin 114 | 3.0.0 115 | 116 | 117 | 118 | maven-resources-plugin 119 | 3.0.2 120 | 121 | 122 | maven-compiler-plugin 123 | 3.7.0 124 | 125 | 126 | maven-surefire-plugin 127 | 2.21.0 128 | 129 | 130 | maven-jar-plugin 131 | 3.0.2 132 | 133 | 134 | maven-install-plugin 135 | 2.5.2 136 | 137 | 138 | maven-deploy-plugin 139 | 2.8.2 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/Classroom.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import java.util.List; 4 | import java.util.Objects; 5 | 6 | public class Classroom { 7 | private double latitude; 8 | private double longitude; 9 | private String where; 10 | private String name; 11 | private String fullName; 12 | private int internalId; 13 | private String roomId; 14 | private boolean occupied; 15 | private boolean willBeOccupied; 16 | private Lesson lessonNow; 17 | private Lesson nextLesson; 18 | private int weight; 19 | private List todayLessons; 20 | private boolean hasCoordinates; 21 | 22 | public double getLatitude() { 23 | return latitude; 24 | } 25 | 26 | public void setLatitude(double latitude) { 27 | hasCoordinates = true; 28 | this.latitude = latitude; 29 | } 30 | 31 | public double getLongitude() { 32 | return longitude; 33 | } 34 | 35 | public void setLongitude(double longitude) { 36 | hasCoordinates = true; 37 | this.longitude = longitude; 38 | } 39 | 40 | public String getWhere() { 41 | return where; 42 | } 43 | 44 | public void setWhere(String where) { 45 | this.where = where; 46 | } 47 | 48 | public String getName() { 49 | return name; 50 | } 51 | 52 | public void setName(String name) { 53 | this.name = name; 54 | } 55 | 56 | public String getFullName() { 57 | return fullName; 58 | } 59 | 60 | public void setFullName(String fullName) { 61 | this.fullName = fullName; 62 | } 63 | 64 | public int getInternalId() { 65 | return internalId; 66 | } 67 | 68 | public void setInternalId(int internalId) { 69 | this.internalId = internalId; 70 | } 71 | 72 | public String getRoomId() { 73 | return roomId; 74 | } 75 | 76 | public void setRoomId(String roomId) { 77 | this.roomId = roomId; 78 | } 79 | 80 | public boolean isOccupied() { 81 | return occupied; 82 | } 83 | 84 | public void setOccupied(boolean occupied) { 85 | this.occupied = occupied; 86 | } 87 | 88 | public boolean isWillBeOccupied() { 89 | return willBeOccupied; 90 | } 91 | 92 | public void setWillBeOccupied(boolean willBeOccupied) { 93 | this.willBeOccupied = willBeOccupied; 94 | } 95 | 96 | public int getWeight() { 97 | return weight; 98 | } 99 | 100 | public void setWeight(int weight) { 101 | this.weight = weight; 102 | } 103 | 104 | public Lesson getLessonNow() { 105 | return lessonNow; 106 | } 107 | 108 | public void setLessonNow(Lesson lessonNow) { 109 | this.lessonNow = lessonNow; 110 | } 111 | 112 | public Lesson getNextLesson() { 113 | return nextLesson; 114 | } 115 | 116 | public void setNextLesson(Lesson nextLesson) { 117 | this.nextLesson = nextLesson; 118 | } 119 | 120 | public List getTodayLessons() { 121 | return todayLessons; 122 | } 123 | 124 | public void setTodayLessons(List todayLessons) { 125 | this.todayLessons = todayLessons; 126 | } 127 | 128 | public boolean hasCoordinates() { 129 | return hasCoordinates; 130 | } 131 | 132 | @Override 133 | public String toString() { 134 | return "Classroom{" + 135 | "latitude=" + latitude + 136 | ", longitude=" + longitude + 137 | ", where='" + where + '\'' + 138 | ", name='" + name + '\'' + 139 | ", fullName='" + fullName + '\'' + 140 | ", internalId=" + internalId + 141 | ", roomId='" + roomId + '\'' + 142 | ", occupied=" + occupied + 143 | ", willBeOccupied=" + willBeOccupied + 144 | ", lessonNow=" + lessonNow + 145 | ", nextLesson=" + nextLesson + 146 | ", weight=" + weight + 147 | '}'; 148 | } 149 | 150 | @Override 151 | public boolean equals(Object o) { 152 | if (this == o) return true; 153 | if (o == null || getClass() != o.getClass()) return false; 154 | Classroom classroom = (Classroom) o; 155 | return Double.compare(classroom.latitude, latitude) == 0 && 156 | Double.compare(classroom.longitude, longitude) == 0 && 157 | internalId == classroom.internalId && 158 | occupied == classroom.occupied && 159 | willBeOccupied == classroom.willBeOccupied && 160 | weight == classroom.weight && 161 | Objects.equals(where, classroom.where) && 162 | Objects.equals(name, classroom.name) && 163 | Objects.equals(fullName, classroom.fullName) && 164 | Objects.equals(roomId, classroom.roomId) && 165 | Objects.equals(lessonNow, classroom.lessonNow) && 166 | Objects.equals(nextLesson, classroom.nextLesson); 167 | } 168 | 169 | @Override 170 | public int hashCode() { 171 | return Objects.hash(latitude, longitude, where, name, fullName, internalId, roomId, occupied, willBeOccupied, lessonNow, nextLesson, weight); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/Event.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | 4 | import org.threeten.bp.LocalDate; 5 | import org.threeten.bp.LocalDateTime; 6 | import org.threeten.bp.ZoneId; 7 | 8 | import java.sql.Timestamp; 9 | import java.util.Objects; 10 | 11 | public class Event { 12 | private EventType eventType; 13 | private String title; 14 | private String teacher; 15 | private LocalDateTime start; //Only lessons 16 | private LocalDateTime end; //Only lessons 17 | private ExamReservation res; //Only Doable,Reserved 18 | private String where; //Only lessons and theatre 19 | //Only Theatre 20 | private String description; 21 | private String url; 22 | private String imageUrl; 23 | private String room; 24 | 25 | public Event(EventType eventType) { 26 | this.eventType = eventType; 27 | } 28 | 29 | 30 | public String getTitle() { 31 | return title; 32 | } 33 | 34 | public void setTitle(String title) { 35 | this.title = title; 36 | } 37 | 38 | public String getDescription() { 39 | return description; 40 | } 41 | 42 | public void setDescription(String description) { 43 | this.description = description; 44 | } 45 | 46 | public LocalDateTime getStart() { 47 | return start; 48 | } 49 | 50 | public void setStart(LocalDateTime when) { 51 | this.start = when; 52 | } 53 | 54 | public EventType getEventType() { 55 | return eventType; 56 | } 57 | 58 | public void setEventType(EventType eventType) { 59 | this.eventType = eventType; 60 | } 61 | 62 | public String getTeacher() { 63 | return teacher; 64 | } 65 | 66 | public void setTeacher(String teacher) { 67 | this.teacher = teacher; 68 | } 69 | 70 | public LocalDateTime getEnd() { 71 | return end; 72 | } 73 | 74 | public void setEnd(LocalDateTime end) { 75 | this.end = end; 76 | } 77 | 78 | public String getWhere() { 79 | return where; 80 | } 81 | 82 | public void setWhere(String where) { 83 | this.where = where; 84 | } 85 | 86 | public ExamReservation getReservation() { 87 | return res; 88 | } 89 | 90 | public void setReservation(ExamReservation res) { 91 | this.res = res; 92 | } 93 | 94 | public String getUrl() { 95 | return url; 96 | } 97 | 98 | public void setUrl(String url) { 99 | this.url = url; 100 | } 101 | 102 | public String getImageUrl() { 103 | return imageUrl; 104 | } 105 | 106 | public void setImageUrl(String imageUrl) { 107 | this.imageUrl = imageUrl; 108 | } 109 | 110 | public String getRoom() { 111 | return room; 112 | } 113 | 114 | public void setRoom(String room) { 115 | this.room = room; 116 | } 117 | 118 | public Timestamp getTimestamp(ZoneId zoneId) { 119 | if (getEventType() == EventType.LESSON || getEventType() == EventType.THEATRE) { 120 | if (getStart() != null) 121 | return new Timestamp(getStart().toLocalDate().atStartOfDay(zoneId).toInstant().toEpochMilli()); 122 | else return null; 123 | } else { 124 | if (getReservation() != null && getReservation().getExamDate() != null) 125 | return new Timestamp(getReservation().getExamDate().atStartOfDay(zoneId).toInstant().toEpochMilli()); 126 | else return null; 127 | } 128 | } 129 | 130 | public LocalDate getEventDate() { 131 | if (getEventType() == EventType.LESSON || getEventType() == EventType.THEATRE) { 132 | if (getStart() != null) return getStart().toLocalDate(); 133 | else return null; 134 | } else { 135 | if (getReservation() != null) return getReservation().getExamDate(); 136 | else return null; 137 | } 138 | } 139 | 140 | 141 | @Override 142 | public String toString() { 143 | return "Event{" + 144 | "eventType=" + eventType + 145 | ", title='" + title + '\'' + 146 | ", teacher='" + teacher + '\'' + 147 | ", start=" + start + 148 | ", end=" + end + 149 | ", res=" + res + 150 | ", where='" + where + '\'' + 151 | ", description='" + description + '\'' + 152 | ", url='" + url + '\'' + 153 | ", imageUrl='" + imageUrl + '\'' + 154 | ", room='" + room + '\'' + 155 | '}'; 156 | } 157 | 158 | @Override 159 | public boolean equals(Object o) { 160 | if (this == o) return true; 161 | if (o == null || getClass() != o.getClass()) return false; 162 | Event event = (Event) o; 163 | return eventType == event.eventType && 164 | Objects.equals(title, event.title) && 165 | Objects.equals(teacher, event.teacher) && 166 | Objects.equals(start, event.start) && 167 | Objects.equals(end, event.end) && 168 | Objects.equals(res, event.res) && 169 | Objects.equals(where, event.where) && 170 | Objects.equals(description, event.description) && 171 | Objects.equals(url, event.url) && 172 | Objects.equals(imageUrl, event.imageUrl) && 173 | Objects.equals(room, event.room); 174 | } 175 | 176 | @Override 177 | public int hashCode() { 178 | return Objects.hash(eventType, title, teacher, start, end, res, where, description, url, imageUrl, room); 179 | } 180 | } -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/ExamReservation.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import org.threeten.bp.LocalDate; 4 | 5 | import java.util.Objects; 6 | 7 | public class ExamReservation { 8 | private int reportID; 9 | private int sessionID; 10 | private int courseCode; 11 | private int cfu; 12 | private int reservationNumber = -1; 13 | private String yearCourse; 14 | private String courseDescription; 15 | private String examSubject; 16 | private String teacher; 17 | private String department; 18 | private String channel; 19 | private LocalDate endDate; 20 | private LocalDate startDate; 21 | private LocalDate reservationDate; 22 | private LocalDate examDate; 23 | private String note; 24 | private String ssd; 25 | private String module; 26 | 27 | public LocalDate getExamDate() { 28 | return examDate; 29 | } 30 | 31 | public void setExamDate(LocalDate examDate) { 32 | this.examDate = examDate; 33 | } 34 | 35 | public String getCourseDescription() { 36 | return courseDescription; 37 | } 38 | 39 | public void setCourseDescription(String courseDescription) { 40 | this.courseDescription = courseDescription; 41 | } 42 | 43 | public int getReportID() { 44 | return reportID; 45 | } 46 | 47 | public void setReportID(int reportID) { 48 | this.reportID = reportID; 49 | } 50 | 51 | public int getSessionID() { 52 | return sessionID; 53 | } 54 | 55 | public void setSessionID(int sessionID) { 56 | this.sessionID = sessionID; 57 | } 58 | 59 | public int getCourseCode() { 60 | return courseCode; 61 | } 62 | 63 | public void setCourseCode(int courseCode) { 64 | this.courseCode = courseCode; 65 | } 66 | 67 | public int getCfu() { 68 | return cfu; 69 | } 70 | 71 | public void setCfu(int cfu) { 72 | this.cfu = cfu; 73 | } 74 | 75 | public String getYearCourse() { 76 | return yearCourse; 77 | } 78 | 79 | public void setYearCourse(String yearCourse) { 80 | this.yearCourse = yearCourse; 81 | } 82 | 83 | public int getReservationNumber() { 84 | return reservationNumber; 85 | } 86 | 87 | public void setReservationNumber(int reservationNumber) { 88 | this.reservationNumber = reservationNumber; 89 | } 90 | 91 | public String getExamSubject() { 92 | return examSubject; 93 | } 94 | 95 | public void setExamSubject(String examSubject) { 96 | this.examSubject = examSubject; 97 | } 98 | 99 | public String getTeacher() { 100 | return teacher; 101 | } 102 | 103 | public void setTeacher(String teacher) { 104 | this.teacher = teacher; 105 | } 106 | 107 | public String getChannel() { 108 | return channel; 109 | } 110 | 111 | public void setChannel(String channel) { 112 | this.channel = channel; 113 | } 114 | 115 | public String getDepartment() { 116 | return department; 117 | } 118 | 119 | public void setDepartment(String department) { 120 | this.department = department; 121 | } 122 | 123 | public LocalDate getEndDate() { 124 | return endDate; 125 | } 126 | 127 | public void setEndDate(LocalDate endDate) { 128 | this.endDate = endDate; 129 | } 130 | 131 | public LocalDate getStartDate() { 132 | return startDate; 133 | } 134 | 135 | public void setStartDate(LocalDate startDate) { 136 | this.startDate = startDate; 137 | } 138 | 139 | public LocalDate getReservationDate() { 140 | return reservationDate; 141 | } 142 | 143 | public void setReservationDate(LocalDate reservationDate) { 144 | this.reservationDate = reservationDate; 145 | } 146 | 147 | public String getNote() { 148 | return note; 149 | } 150 | 151 | public void setNote(String note) { 152 | this.note = note; 153 | } 154 | 155 | public String getSsd() { 156 | return ssd; 157 | } 158 | 159 | public void setSsd(String ssd) { 160 | this.ssd = ssd; 161 | } 162 | 163 | public String getModule() { 164 | return module; 165 | } 166 | 167 | public void setModule(String module) { 168 | this.module = module; 169 | } 170 | 171 | @Override 172 | public String toString() { 173 | return "ExamReservation{" + 174 | "examSubject='" + examSubject + '\'' + 175 | ", reportID=" + reportID + 176 | ", sessionID=" + sessionID + 177 | ", courseCode=" + courseCode + 178 | ", cfu=" + cfu + 179 | ", channel=" + channel + 180 | ", reservationNumber=" + reservationNumber + 181 | ", yearCourse='" + yearCourse + '\'' + 182 | ", courseDescription='" + courseDescription + '\'' + 183 | ", teacher='" + teacher + '\'' + 184 | ", department='" + department + '\'' + 185 | ", endDate=" + endDate + 186 | ", startDate=" + startDate + 187 | ", reservationDate=" + reservationDate + 188 | ", examDate=" + examDate + 189 | ", note='" + note + '\'' + 190 | ", ssd='" + ssd + '\'' + 191 | ", module='" + module + '\'' + 192 | '}'; 193 | } 194 | 195 | @Override 196 | public boolean equals(Object o) { 197 | if (this == o) return true; 198 | if (o == null || getClass() != o.getClass()) return false; 199 | ExamReservation that = (ExamReservation) o; 200 | return reportID == that.reportID && 201 | sessionID == that.sessionID && 202 | courseCode == that.courseCode && 203 | cfu == that.cfu && 204 | reservationNumber == that.reservationNumber && 205 | Objects.equals(yearCourse, that.yearCourse) && 206 | Objects.equals(courseDescription, that.courseDescription) && 207 | Objects.equals(examSubject, that.examSubject) && 208 | Objects.equals(teacher, that.teacher) && 209 | Objects.equals(department, that.department) && 210 | Objects.equals(channel, that.channel) && 211 | Objects.equals(endDate, that.endDate) && 212 | Objects.equals(startDate, that.startDate) && 213 | Objects.equals(reservationDate, that.reservationDate) && 214 | Objects.equals(examDate, that.examDate) && 215 | Objects.equals(note, that.note) && 216 | Objects.equals(ssd, that.ssd) && 217 | Objects.equals(module, that.module); 218 | } 219 | 220 | @Override 221 | public int hashCode() { 222 | return Objects.hash(reportID, sessionID, courseCode, cfu, reservationNumber, yearCourse, courseDescription, examSubject, teacher, department, channel, endDate, startDate, reservationDate, examDate, note, ssd, module); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/OpenstudHelper.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core; 2 | 3 | import lithium.openstud.driver.core.models.*; 4 | import org.apache.commons.validator.routines.UrlValidator; 5 | import org.threeten.bp.LocalDate; 6 | 7 | import java.util.Collections; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public class OpenstudHelper { 13 | 14 | public static boolean isValidUrl(String url) { 15 | if (url == null) return false; 16 | String[] schemes = {"http", "https"}; 17 | UrlValidator urlValidator = new UrlValidator(schemes); 18 | return urlValidator.isValid(url); 19 | } 20 | 21 | public static double computeWeightedAverage(List list, int laude) { 22 | double cfu = 0; 23 | double sum = 0; 24 | for (ExamDone exam : list) { 25 | if (exam.isPassed() && exam.getResult() >= 18) { 26 | int grade = exam.getResult(); 27 | if (grade == 31) grade = laude; 28 | sum += grade * exam.getCfu(); 29 | cfu += exam.getCfu(); 30 | } 31 | } 32 | if (cfu == 0 || sum == 0) return -1; 33 | return sum / cfu; 34 | } 35 | 36 | public static int computeBaseGraduation(List list, int laude, boolean removeMaxMin) { 37 | if (list.size() == 0 || (removeMaxMin && list.size() <= 2)) return -1; 38 | List tmp = new LinkedList<>(list); 39 | if (removeMaxMin) { 40 | ExamDone max = null; 41 | ExamDone min = null; 42 | for (ExamDone exam : tmp) { 43 | if (max == null) max = exam; 44 | else if (exam.getResult() > max.getResult()) max = exam; 45 | } 46 | tmp.remove(max); 47 | for (ExamDone exam : tmp) { 48 | if (min == null) min = exam; 49 | else if (exam.getResult() < min.getResult()) min = exam; 50 | } 51 | tmp.remove(min); 52 | } 53 | double result = (computeWeightedAverage(tmp, laude) * 110) / 30; 54 | return (int) Math.round(result); 55 | } 56 | 57 | public static double computeArithmeticAverage(List list, int laude) { 58 | int num = 0; 59 | double sum = 0; 60 | for (ExamDone exam : list) { 61 | if (exam.isPassed() && exam.getResult() >= 18) { 62 | int grade = exam.getResult(); 63 | if (grade == 31) grade = laude; 64 | sum += grade; 65 | num++; 66 | } 67 | } 68 | if (num == 0 || sum == 0) return -1; 69 | return sum / num; 70 | } 71 | 72 | public static int getSumCFU(List list) { 73 | int cfu = 0; 74 | for (ExamDone exam : list) { 75 | if (exam.isPassed()) { 76 | cfu += exam.getCfu(); 77 | } 78 | } 79 | return cfu; 80 | } 81 | 82 | public static ExamDone createFakeExamDone(String description, int cfu, int grade) { 83 | if (cfu <= 0 || grade < 18) return null; 84 | ExamDone done = new ExamDone(); 85 | done.setCertified(true); 86 | done.setPassed(true); 87 | done.setCfu(cfu); 88 | done.setDate(LocalDate.now()); 89 | done.setDescription(description); 90 | done.setResult(Math.min(grade, 31)); 91 | return done; 92 | } 93 | 94 | public static List generateEventsFromTimetable(Map> timetable) { 95 | List events = new LinkedList<>(); 96 | for (String code : timetable.keySet()) { 97 | List lessons = timetable.get(code); 98 | events.addAll(generateEventsFromTimetable(lessons)); 99 | } 100 | return events; 101 | } 102 | 103 | public static List generateEventsFromTimetable(List timetable) { 104 | List events = new LinkedList<>(); 105 | for (Lesson lesson : timetable) { 106 | Event ev = new Event(EventType.LESSON); 107 | ev.setTitle(lesson.getName()); 108 | ev.setStart(lesson.getStart()); 109 | ev.setEnd(lesson.getEnd()); 110 | ev.setTeacher(lesson.getTeacher()); 111 | ev.setWhere(lesson.getWhere()); 112 | events.add(ev); 113 | } 114 | return events; 115 | } 116 | 117 | public static List generateEvents(List reservations, 118 | List avaiableReservations) { 119 | List events = new LinkedList<>(); 120 | for (ExamReservation res : reservations) { 121 | Event ev = new Event(EventType.RESERVED); 122 | ev.setTitle(res.getExamSubject()); 123 | ev.setTeacher(res.getTeacher()); 124 | ev.setReservation(res); 125 | events.add(ev); 126 | } 127 | for (ExamReservation res : avaiableReservations) { 128 | boolean exist = false; 129 | for (ExamReservation res_active : reservations) { 130 | if (res_active.getReportID() == res.getReportID() && res_active.getSessionID() == res.getSessionID()) { 131 | exist = true; 132 | break; 133 | } 134 | } 135 | if (exist) continue; 136 | Event event = new Event(EventType.DOABLE); 137 | event.setTitle(res.getExamSubject()); 138 | event.setTeacher(res.getTeacher()); 139 | event.setReservation(res); 140 | events.add(event); 141 | } 142 | return events; 143 | } 144 | 145 | public static List sortExamByDate(List list, boolean ascending) { 146 | Collections.sort(list, (o1, o2) -> { 147 | if (o1.getDate() == null && o2.getDate() == null) return 0; 148 | if (ascending) 149 | if (o1.getDate() == null) return 1; 150 | else if (o2.getDate() == null) return -1; 151 | else return o1.getDate().compareTo(o2.getDate()); 152 | else { 153 | if (o1.getDate() == null) return -1; 154 | else if (o2.getDate() == null) return 1; 155 | else return o2.getDate().compareTo(o1.getDate()); 156 | } 157 | }); 158 | return list; 159 | } 160 | 161 | public static List sortReservationByDate(List list, boolean ascending) { 162 | Collections.sort(list, (o1, o2) -> { 163 | if (o1.getExamDate() == null && o2.getExamDate() == null) return 0; 164 | if (ascending) 165 | if (o1.getExamDate() == null) return 1; 166 | else if (o2.getExamDate() == null) return -1; 167 | else return o1.getExamDate().compareTo(o2.getExamDate()); 168 | else { 169 | if (o1.getExamDate() == null) return -1; 170 | else if (o2.getExamDate() == null) return 1; 171 | else return o2.getExamDate().compareTo(o1.getExamDate()); 172 | } 173 | }); 174 | return list; 175 | } 176 | 177 | public static List sortLessonsByStartDate(List list, boolean ascending) { 178 | Collections.sort(list, (o1, o2) -> { 179 | if (o1.getStart() == null && o2.getStart() == null) return 0; 180 | if (ascending) 181 | if (o1.getStart() == null) return 1; 182 | else if (o2.getStart() == null) return -1; 183 | else return o1.getStart().compareTo(o2.getStart()); 184 | else { 185 | if (o1.getStart() == null) return -1; 186 | else if (o2.getStart() == null) return 1; 187 | else return o2.getStart().compareTo(o1.getStart()); 188 | } 189 | }); 190 | return list; 191 | } 192 | 193 | public static List sortExamByGrade(List list, boolean ascending) { 194 | Collections.sort(list, (o1, o2) -> { 195 | if (ascending) 196 | return Integer.compare(o1.getResult(), o2.getResult()); 197 | else { 198 | return Integer.compare(o2.getResult(), o1.getResult()); 199 | } 200 | }); 201 | return list; 202 | } 203 | 204 | public enum Mode { 205 | MOBILE, WEB 206 | } 207 | 208 | public enum Provider { 209 | SAPIENZA 210 | } 211 | 212 | } 213 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/models/Student.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.models; 2 | 3 | import org.threeten.bp.LocalDate; 4 | 5 | import java.util.Objects; 6 | 7 | public class Student { 8 | private String CF; 9 | private String firstName; 10 | private String lastName; 11 | private LocalDate birthDate; 12 | private String birthCity; 13 | private String birthPlace; 14 | private String courseYear; 15 | private String firstEnrollment; 16 | private String lastEnrollment; 17 | private String departmentName; 18 | private String courseName; 19 | private String nation; 20 | private String email; 21 | private String citizenship; 22 | private String gender; 23 | private String studentStatus; 24 | private int academicYear; 25 | private int academicYearCourse; 26 | private String studentID; 27 | private int codeCourse; 28 | private int typeStudent; 29 | private int cfu; 30 | private boolean isErasmus; 31 | 32 | public String getStudentStatus() { 33 | return studentStatus; 34 | } 35 | 36 | public void setStudentStatus(String studentStatus) { 37 | this.studentStatus = studentStatus; 38 | } 39 | 40 | public String getBirthPlace() { 41 | return birthPlace; 42 | } 43 | 44 | public void setBirthPlace(String birthPlace) { 45 | this.birthPlace = birthPlace; 46 | } 47 | 48 | public String getCitizenship() { 49 | return citizenship; 50 | } 51 | 52 | public void setCitizenship(String citizenship) { 53 | this.citizenship = citizenship; 54 | } 55 | 56 | public String getEmail() { 57 | return email; 58 | } 59 | 60 | public void setEmail(String email) { 61 | this.email = email; 62 | } 63 | 64 | public int getCfu() { 65 | return cfu; 66 | } 67 | 68 | public void setCfu(int cfu) { 69 | this.cfu = cfu; 70 | } 71 | 72 | public String getSocialSecurityNumber() { 73 | return CF; 74 | } 75 | 76 | public void setSocialSecurityNumber(String CF) { 77 | this.CF = CF; 78 | } 79 | 80 | public String getFirstName() { 81 | return firstName; 82 | } 83 | 84 | public void setFirstName(String firstName) { 85 | this.firstName = firstName; 86 | } 87 | 88 | public String getLastName() { 89 | return lastName; 90 | } 91 | 92 | public void setLastName(String lastName) { 93 | this.lastName = lastName; 94 | } 95 | 96 | public LocalDate getBirthDate() { 97 | return birthDate; 98 | } 99 | 100 | public void setBirthDate(LocalDate birthDate) { 101 | this.birthDate = birthDate; 102 | } 103 | 104 | public String getBirthCity() { 105 | return birthCity; 106 | } 107 | 108 | public void setBirthCity(String birthCity) { 109 | this.birthCity = birthCity; 110 | } 111 | 112 | public String getCourseYear() { 113 | return courseYear; 114 | } 115 | 116 | public void setCourseYear(String courseYear) { 117 | this.courseYear = courseYear; 118 | } 119 | 120 | public String getFirstEnrollment() { 121 | return firstEnrollment; 122 | } 123 | 124 | public void setFirstEnrollment(String firstEnrollment) { 125 | this.firstEnrollment = firstEnrollment; 126 | } 127 | 128 | public String getLastEnrollment() { 129 | return lastEnrollment; 130 | } 131 | 132 | public void setLastEnrollment(String lastEnrollment) { 133 | this.lastEnrollment = lastEnrollment; 134 | } 135 | 136 | public String getDepartmentName() { 137 | return departmentName; 138 | } 139 | 140 | public void setDepartmentName(String departmentName) { 141 | this.departmentName = departmentName; 142 | } 143 | 144 | public String getCourseName() { 145 | return courseName; 146 | } 147 | 148 | public void setCourseName(String courseName) { 149 | this.courseName = courseName; 150 | } 151 | 152 | public String getNation() { 153 | return nation; 154 | } 155 | 156 | public void setNation(String nation) { 157 | this.nation = nation; 158 | } 159 | 160 | public int getAcademicYear() { 161 | return academicYear; 162 | } 163 | 164 | public void setAcademicYear(int academicYear) { 165 | this.academicYear = academicYear; 166 | } 167 | 168 | public int getAcademicYearCourse() { 169 | return academicYearCourse; 170 | } 171 | 172 | public void setAcademicYearCourse(int academicYearCourse) { 173 | this.academicYearCourse = academicYearCourse; 174 | } 175 | 176 | public String getStudentID() { 177 | return studentID; 178 | } 179 | 180 | public void setStudentID(String studentID) { 181 | this.studentID = studentID; 182 | } 183 | 184 | public int getCodeCourse() { 185 | return codeCourse; 186 | } 187 | 188 | public void setCodeCourse(int codeCourse) { 189 | this.codeCourse = codeCourse; 190 | } 191 | 192 | public int getTypeStudent() { 193 | return typeStudent; 194 | } 195 | 196 | public void setTypeStudent(int typeStudent) { 197 | this.typeStudent = typeStudent; 198 | } 199 | 200 | public String getGender() { 201 | return gender; 202 | } 203 | 204 | public void setGender(String gender) { 205 | this.gender = gender; 206 | } 207 | 208 | public boolean isErasmus() { 209 | return isErasmus; 210 | } 211 | 212 | public void setErasmus(boolean erasmus) { 213 | isErasmus = erasmus; 214 | } 215 | 216 | public boolean isEnrolled() { 217 | return getTypeStudent() != -1; 218 | } 219 | 220 | @Override 221 | public String toString() { 222 | return "Student{" + 223 | "CF='" + CF + '\'' + 224 | ", firstName='" + firstName + '\'' + 225 | ", lastName='" + lastName + '\'' + 226 | ", birthDate=" + birthDate + 227 | ", birthCity='" + birthCity + '\'' + 228 | ", birthPlace='" + birthPlace + '\'' + 229 | ", courseYear='" + courseYear + '\'' + 230 | ", firstEnrollment='" + firstEnrollment + '\'' + 231 | ", lastEnrollment='" + lastEnrollment + '\'' + 232 | ", departmentName='" + departmentName + '\'' + 233 | ", courseName='" + courseName + '\'' + 234 | ", nation='" + nation + '\'' + 235 | ", email='" + email + '\'' + 236 | ", citizenship='" + citizenship + '\'' + 237 | ", gender='" + gender + '\'' + 238 | ", studentStatus='" + studentStatus + '\'' + 239 | ", academicYear=" + academicYear + 240 | ", academicYearCourse=" + academicYearCourse + 241 | ", studentID=" + studentID + 242 | ", codeCourse=" + codeCourse + 243 | ", typeStudent=" + typeStudent + 244 | ", cfu=" + cfu + 245 | ", isErasmus=" + isErasmus + 246 | '}'; 247 | } 248 | 249 | @Override 250 | public boolean equals(Object o) { 251 | if (this == o) return true; 252 | if (o == null || getClass() != o.getClass()) return false; 253 | Student student = (Student) o; 254 | return academicYear == student.academicYear && 255 | academicYearCourse == student.academicYearCourse && 256 | studentID.equals(student.studentID) && 257 | codeCourse == student.codeCourse && 258 | typeStudent == student.typeStudent && 259 | cfu == student.cfu && 260 | isErasmus == student.isErasmus && 261 | Objects.equals(CF, student.CF) && 262 | Objects.equals(firstName, student.firstName) && 263 | Objects.equals(lastName, student.lastName) && 264 | Objects.equals(birthDate, student.birthDate) && 265 | Objects.equals(birthCity, student.birthCity) && 266 | Objects.equals(birthPlace, student.birthPlace) && 267 | Objects.equals(courseYear, student.courseYear) && 268 | Objects.equals(firstEnrollment, student.firstEnrollment) && 269 | Objects.equals(lastEnrollment, student.lastEnrollment) && 270 | Objects.equals(departmentName, student.departmentName) && 271 | Objects.equals(courseName, student.courseName) && 272 | Objects.equals(nation, student.nation) && 273 | Objects.equals(email, student.email) && 274 | Objects.equals(citizenship, student.citizenship) && 275 | Objects.equals(gender, student.gender) && 276 | Objects.equals(studentStatus, student.studentStatus); 277 | } 278 | 279 | @Override 280 | public int hashCode() { 281 | return Objects.hash(CF, firstName, lastName, birthDate, birthCity, birthPlace, courseYear, firstEnrollment, lastEnrollment, departmentName, courseName, nation, email, citizenship, gender, studentStatus, academicYear, academicYearCourse, studentID, codeCourse, typeStudent, cfu, isErasmus); 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/providers/sapienza/SapienzaNewsHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.providers.sapienza; 2 | 3 | import lithium.openstud.driver.core.Openstud; 4 | import lithium.openstud.driver.core.OpenstudHelper; 5 | import lithium.openstud.driver.core.internals.NewsHandler; 6 | import lithium.openstud.driver.core.models.Event; 7 | import lithium.openstud.driver.core.models.EventType; 8 | import lithium.openstud.driver.core.models.News; 9 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 10 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 11 | import org.jsoup.Connection; 12 | import org.jsoup.Jsoup; 13 | import org.jsoup.nodes.Document; 14 | import org.jsoup.nodes.Element; 15 | import org.jsoup.select.Elements; 16 | import org.threeten.bp.LocalDate; 17 | import org.threeten.bp.LocalDateTime; 18 | import org.threeten.bp.format.DateTimeFormatter; 19 | import org.threeten.bp.format.DateTimeFormatterBuilder; 20 | import org.threeten.bp.format.DateTimeParseException; 21 | 22 | import java.io.IOException; 23 | import java.util.LinkedList; 24 | import java.util.List; 25 | import java.util.Locale; 26 | import java.util.logging.Level; 27 | 28 | public class SapienzaNewsHandler implements NewsHandler { 29 | private Openstud os; 30 | 31 | public SapienzaNewsHandler(Openstud os) { 32 | this.os = os; 33 | } 34 | 35 | @Override 36 | public List getNews(String locale, boolean withDescription, Integer limit, Integer page, Integer maxPage, String query) throws OpenstudInvalidResponseException, OpenstudConnectionException { 37 | if (limit == null && page == null && maxPage == null) 38 | throw new IllegalStateException("limit, page and maxpage can't be all null"); 39 | return _getNews(locale, withDescription, limit, page, maxPage, query); 40 | } 41 | 42 | private List _getNews(String locale, boolean withDescription, Integer limit, Integer page, Integer maxPage, String query) throws OpenstudConnectionException, OpenstudInvalidResponseException { 43 | if (locale == null) 44 | locale = "en"; 45 | Locale localeFormatter; 46 | if (locale.toLowerCase().equals("it")) localeFormatter = Locale.ITALIAN; 47 | else localeFormatter = Locale.ENGLISH; 48 | 49 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMMM yyyy").withLocale(localeFormatter); 50 | try { 51 | List ret = new LinkedList<>(); 52 | int startPage = 0; 53 | int endPage = maxPage == null ? 1 : maxPage; 54 | if (page != null) { 55 | startPage = page; 56 | endPage = startPage + 1; 57 | } 58 | String website_url = "https://www.uniroma1.it"; 59 | String page_key = "page"; 60 | String query_key = "search_api_views_fulltext"; 61 | boolean shouldStop = false; 62 | int iterations = 0; 63 | int miss = 0; 64 | for (int i = startPage; i < endPage && !shouldStop; i++) { 65 | Connection connection = Jsoup.connect(String.format("%s/%s/tutte-le-notizie", website_url, locale)) 66 | .data(page_key, i + ""); 67 | if (query != null) 68 | connection = connection.data(query_key, query); 69 | Document doc = connection.get(); 70 | Elements boxes = doc.getElementsByClass("box-news"); 71 | for (Element box : boxes) { 72 | News news = new News(); 73 | news.setTitle(box.getElementsByTag("img").attr("title")); 74 | // handle empty news 75 | if (news.getTitle().isEmpty()) 76 | continue; 77 | news.setLocale(locale); 78 | news.setUrl(website_url + box.getElementsByTag("a").attr("href").trim()); 79 | news.setSmallImageUrl(box.getElementsByTag("img").attr("src")); 80 | ret.add(news); 81 | if (limit != null && ret.size() >= limit) { 82 | shouldStop = true; 83 | break; 84 | } 85 | } 86 | if (boxes.isEmpty()) miss++; 87 | iterations++; 88 | } 89 | if (iterations == miss) { 90 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException("invalid HTML").setHTMLType(); 91 | os.log(Level.SEVERE, invalidResponse); 92 | throw invalidResponse; 93 | } 94 | LinkedList ignored = new LinkedList<>(); 95 | for (News news : ret) { 96 | if (!OpenstudHelper.isValidUrl(news.getUrl())) ignored.add(news); 97 | Document doc = Jsoup.connect(news.getUrl()).get(); 98 | if (withDescription) { 99 | Element start = doc.getElementsByAttributeValueEnding("class", "testosommario").first(); 100 | if (start != null) 101 | news.setDescription(start.getElementsByClass("field-item even").first().text()); 102 | } 103 | Element date = doc.getElementsByClass("date-display-single").first(); 104 | if (date != null) { 105 | try { 106 | news.setDate(LocalDate.parse(date.text().substring(date.text().indexOf(",") + 1).trim(), formatter)); 107 | } catch (DateTimeParseException e) { 108 | e.printStackTrace(); 109 | } 110 | } 111 | news.setImageUrl(doc.getElementsByClass("img-responsive").attr("src")); 112 | } 113 | ret.removeAll(ignored); 114 | return ret; 115 | 116 | } catch (IOException e) { 117 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 118 | os.log(Level.SEVERE, connectionException); 119 | throw connectionException; 120 | } 121 | } 122 | 123 | @Override 124 | public List getNewsletterEvents() throws OpenstudInvalidResponseException, OpenstudConnectionException { 125 | return _getNewsletterEvents(); 126 | } 127 | 128 | private List _getNewsletterEvents() throws OpenstudInvalidResponseException, OpenstudConnectionException { 129 | try { 130 | List ret = new LinkedList<>(); 131 | 132 | String website_url = "https://www.uniroma1.it/it/newsletter"; 133 | Document doc = Jsoup.connect(website_url).get(); 134 | Elements events = doc.getElementsByClass("event"); 135 | DateTimeFormatter formatter = new DateTimeFormatterBuilder() 136 | .appendOptional(DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm")) 137 | .appendOptional(DateTimeFormatter.ofPattern("dd MMMM yyyy HH:mm")) 138 | .appendOptional(DateTimeFormatter.ofPattern("d MMM yyyy HH:mm")) 139 | .appendOptional(DateTimeFormatter.ofPattern("d MMMM yyyy HH:mm")) 140 | .toFormatter(Locale.ENGLISH); 141 | int failed = 0; 142 | for (Element event : events) { 143 | Elements views = event.getElementsByClass("views-field"); 144 | if (views.size() != 5) { 145 | failed++; 146 | continue; 147 | } 148 | Event ev = new Event(EventType.THEATRE); 149 | String date = views.remove(0).getElementsByTag("a").text().replace(",", ""); 150 | String time = views.remove(0).getElementsByTag("a").text(); 151 | try { 152 | ev.setStart(LocalDateTime.parse(date + " " + time, formatter)); 153 | } catch (DateTimeParseException e) { 154 | failed++; 155 | continue; 156 | } 157 | Elements title = views.remove(0).getElementsByTag("a"); 158 | ev.setTitle(title.text()); 159 | ev.setUrl(title.attr("href")); 160 | doc = Jsoup.connect(ev.getUrl()).get(); 161 | ev.setRoom(doc.getElementsByClass("views-field-field-apm-aula").first().text().trim().replaceAll(" ?- ?",", ")); 162 | ev.setWhere(doc.getElementsByClass("views-field-field-apm-edificio").first().text().trim()); 163 | Element image = doc.getElementsByClass("field-type-image").first(); 164 | if (image != null) { 165 | ev.setImageUrl(image.getElementsByTag("img").first().attr("src")); 166 | } 167 | Element description = doc.getElementsByClass("article-body").first(); 168 | if (description != null) ev.setDescription(description.text()); 169 | ret.add(ev); 170 | } 171 | 172 | if (failed == events.size() && !events.isEmpty()) { 173 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException("invalid HTML").setHTMLType(); 174 | os.log(Level.SEVERE, invalidResponse); 175 | throw invalidResponse; 176 | } 177 | return ret; 178 | 179 | } catch (IOException e) { 180 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 181 | os.log(Level.SEVERE, connectionException); 182 | throw connectionException; 183 | } 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /src/test/java/lithium/openstud/driver/OpenstudSapienzaTest.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver; 2 | 3 | import lithium.openstud.driver.core.Openstud; 4 | import lithium.openstud.driver.core.OpenstudBuilder; 5 | import lithium.openstud.driver.core.OpenstudValidator; 6 | import lithium.openstud.driver.core.models.*; 7 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 8 | import lithium.openstud.driver.exceptions.OpenstudInvalidCredentialsException; 9 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 10 | import lithium.openstud.driver.exceptions.OpenstudUserNotEnabledException; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | import static org.junit.Assert.*; 18 | 19 | 20 | public class OpenstudSapienzaTest 21 | { 22 | 23 | private static boolean setUpIsDone = false; 24 | private static boolean invalidCredentials = false; 25 | private static Openstud os; 26 | 27 | @Before 28 | public void setUp() throws OpenstudConnectionException, OpenstudUserNotEnabledException, OpenstudInvalidResponseException { 29 | if (setUpIsDone || invalidCredentials) { 30 | return; 31 | } 32 | os = new OpenstudBuilder().setPassword(System.getenv("OPENSTUD_TESTPWD")).setStudentID(System.getenv("OPENSTUD_TESTID")).build(); 33 | try { 34 | os.login(); 35 | } catch (OpenstudInvalidCredentialsException e) { 36 | e.printStackTrace(); 37 | invalidCredentials = true; 38 | } 39 | setUpIsDone = true; 40 | } 41 | 42 | @Test 43 | public void testPasswordValidation() throws OpenstudInvalidCredentialsException { 44 | String id = "12345678"; 45 | String malformed_pwd = "No_Numbers!"; 46 | Openstud os = new OpenstudBuilder().setPassword(malformed_pwd).setStudentID(id).build(); 47 | assertFalse(OpenstudValidator.validate(os)); 48 | malformed_pwd = "NoSp3ci4l"; 49 | os = new OpenstudBuilder().setPassword(malformed_pwd).setStudentID(id).build(); 50 | assertFalse(OpenstudValidator.validate(os)); 51 | malformed_pwd = "2 Spaces !"; 52 | os = new OpenstudBuilder().setPassword(malformed_pwd).setStudentID(id).build(); 53 | assertFalse(OpenstudValidator.validate(os)); 54 | malformed_pwd = "Long_Password_17!"; 55 | os = new OpenstudBuilder().setPassword(malformed_pwd).setStudentID(id).build(); 56 | assertFalse(OpenstudValidator.validate(os)); 57 | String correct_pwd = "#8_Chars"; 58 | os = new OpenstudBuilder().setPassword(correct_pwd).setStudentID(id).build(); 59 | assertTrue(OpenstudValidator.validate(os)); 60 | correct_pwd = "[.!-=?#@]1aA"; 61 | os = new OpenstudBuilder().setPassword(correct_pwd).setStudentID(id).build(); 62 | assertTrue(OpenstudValidator.validate(os)); 63 | } 64 | 65 | @Test 66 | public void testUserIDValidation() throws OpenstudInvalidCredentialsException { 67 | Openstud os = new OpenstudBuilder().setPassword("Perfect_psw1").build(); 68 | assertFalse(OpenstudValidator.validate(os)); 69 | } 70 | 71 | @Test 72 | public void testLogin() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudUserNotEnabledException { 73 | assertTrue( os.isReady() ); 74 | } 75 | 76 | @Test 77 | public void testGetSecurityQuestion() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException { 78 | Openstud os = new OpenstudBuilder().setStudentID(System.getenv("OPENSTUD_TESTID")).build(); 79 | assertNotNull(os.getSecurityQuestion()); 80 | } 81 | 82 | @Test 83 | public void testGetCalendar() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudUserNotEnabledException { 84 | Student st = os.getInfoStudent(); 85 | os.getCalendarEvents(st); 86 | } 87 | 88 | @Test 89 | public void testGetIsee() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudUserNotEnabledException { 90 | Isee res=os.getCurrentIsee(); 91 | assertTrue(res!=null && res.isValid()); 92 | } 93 | 94 | @Test 95 | public void testGetIseeHistory() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudUserNotEnabledException { 96 | List res=os.getIseeHistory(); 97 | assertTrue(res!=null && res.size()!=0); 98 | } 99 | 100 | @Test 101 | public void testGetInfoStudent() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 102 | Student st=os.getInfoStudent(); 103 | assertTrue(st!=null && st.getStudentID()!=null); 104 | } 105 | 106 | @Test 107 | public void testGetExamsDoable() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 108 | List list=os.getExamsDoable(); 109 | assertNotNull(list); 110 | } 111 | 112 | @Test 113 | public void testGetTimetable() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 114 | List list=os.getExamsDoable(); 115 | Map> map = os.getTimetable(list); 116 | assertNotNull(map); 117 | } 118 | 119 | 120 | @Test 121 | public void testGetExamsPassed() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 122 | List list=os.getExamsDone(); 123 | assertNotNull(list); 124 | } 125 | 126 | @Test 127 | public void testGetActiveReservations() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 128 | List list=os.getActiveReservations(); 129 | assertNotNull(list); 130 | } 131 | 132 | @Test 133 | public void testClassroomInfos() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 134 | List list=os.getClassRoom("San pietro", true); 135 | assertNotNull(list); 136 | } 137 | 138 | 139 | @Test 140 | public void testGetAvailableReservations() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 141 | List list=os.getExamsDoable(); 142 | Student st=os.getInfoStudent(); 143 | if(list.size()>0) { 144 | List ret=os.getAvailableReservations(list.get(0),st); 145 | assertNotNull(ret); 146 | } 147 | assertTrue(true); 148 | } 149 | 150 | @Test 151 | public void testGetExamReservationPDF() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 152 | List list=os.getActiveReservations(); 153 | if(list.size()>=1) { 154 | byte[] pdf = os.getExamReservationPDF(list.get(0)); 155 | assertNotNull(pdf); 156 | } 157 | assertTrue(true); 158 | } 159 | 160 | @Test 161 | public void testGetPaidTaxes() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 162 | List list=os.getPaidTaxes(); 163 | assertNotNull(list); 164 | assertFalse(list.isEmpty()); 165 | } 166 | 167 | @Test 168 | public void testGetNewsEnglish() throws OpenstudInvalidResponseException, OpenstudConnectionException { 169 | List list=os.getNews("en", true, null, 0, null, null); 170 | assertNotNull(list); 171 | assertFalse(list.isEmpty()); 172 | } 173 | 174 | @Test 175 | public void testGetNewsItalian() throws OpenstudInvalidResponseException, OpenstudConnectionException { 176 | List list=os.getNews("it", true, null, 0, null, null); 177 | assertNotNull(list); 178 | int limit = 5; 179 | list=os.getNews("it", true, limit, null, null, null); 180 | assertFalse(list.isEmpty()); 181 | assertTrue(list.size() <= limit); 182 | } 183 | 184 | 185 | @Test 186 | public void testGetNewsEventsEnglish() throws OpenstudInvalidResponseException, OpenstudConnectionException { 187 | List list=os.getNewsletterEvents(); 188 | assertNotNull(list); 189 | } 190 | 191 | @Test 192 | public void testGetUnpaidTaxes() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 193 | List list=os.getUnpaidTaxes(); 194 | assertNotNull(list); 195 | } 196 | 197 | @Test 198 | public void testGetSurvey() throws OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudUserNotEnabledException { 199 | assertNotNull(os.getCourseSurvey("42FESHPE")); 200 | } 201 | 202 | @Test 203 | public void testGetCertificatePDF() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException { 204 | Student student = os.getInfoStudent(); 205 | List careers = os.getCareersChoicesForCertificate(student, CertificateType.DEGREE_WITH_THESIS_ENG); 206 | assertNotNull(careers); 207 | assertNotNull(os.getCertificatePDF(student,careers.get(0), CertificateType.DEGREE_WITH_THESIS_ENG)); 208 | } 209 | 210 | @Test 211 | public void testGetPhoto() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException { 212 | Student student = os.getInfoStudent(); 213 | os.getStudentPhoto(student); 214 | } 215 | 216 | @Test 217 | public void testGetCard() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException { 218 | Student student = os.getInfoStudent(); 219 | StudentCard card = os.getStudentCard(student, false); 220 | } 221 | 222 | @Test 223 | public void testGetPaymentSlipPDF() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException { 224 | List unpaidTaxes = os.getUnpaidTaxes(); 225 | if (unpaidTaxes.size()>0) { 226 | byte[] pdf = os.getPaymentSlipPDF(unpaidTaxes.get(0)); 227 | assert(pdf.length > 0); 228 | } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/providers/sapienza/SapienzaClassroomHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.providers.sapienza; 2 | 3 | import lithium.openstud.driver.core.Openstud; 4 | import lithium.openstud.driver.core.OpenstudHelper; 5 | import lithium.openstud.driver.core.internals.ClassroomHandler; 6 | import lithium.openstud.driver.core.models.Classroom; 7 | import lithium.openstud.driver.core.models.ExamDoable; 8 | import lithium.openstud.driver.core.models.Lesson; 9 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 10 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 11 | import okhttp3.Request; 12 | import okhttp3.Response; 13 | import org.json.JSONArray; 14 | import org.json.JSONException; 15 | import org.json.JSONObject; 16 | import org.threeten.bp.LocalDate; 17 | import org.threeten.bp.LocalDateTime; 18 | import org.threeten.bp.ZoneOffset; 19 | import org.threeten.bp.format.DateTimeFormatter; 20 | 21 | import java.io.IOException; 22 | import java.util.HashMap; 23 | import java.util.LinkedList; 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.logging.Level; 27 | 28 | public class SapienzaClassroomHandler implements ClassroomHandler { 29 | private Openstud os; 30 | 31 | public SapienzaClassroomHandler(Openstud os) { 32 | this.os = os; 33 | } 34 | 35 | @Override 36 | public List getClassRoom(String query, boolean withTimetable) throws OpenstudInvalidResponseException, OpenstudConnectionException { 37 | if (!os.isReady()) return null; 38 | int count = 0; 39 | while (true) { 40 | try { 41 | return _getClassroom(query, withTimetable); 42 | } catch (OpenstudInvalidResponseException e) { 43 | if (e.isRateLimit()) throw e; 44 | if (++count == os.getMaxTries()) { 45 | os.log(Level.SEVERE, e); 46 | throw e; 47 | } 48 | } 49 | } 50 | } 51 | 52 | private List _getClassroom(String query, boolean withTimetable) throws OpenstudInvalidResponseException, OpenstudConnectionException { 53 | List ret = new LinkedList<>(); 54 | try { 55 | Request req = new Request.Builder().url(String.format("%s/classroom/search?q=%s", os.getEndpointTimetable(), query.replace(" ", "%20"))).build(); 56 | String body = handleRequest(req); 57 | JSONArray array = new JSONArray(body); 58 | LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC); 59 | LocalDateTime zonedTime = now.atOffset(ZoneOffset.UTC).withOffsetSameInstant(ZoneOffset.of("+1")).toLocalDateTime(); 60 | for (int i = 0; i < array.length(); i++) { 61 | if (i == os.getLimitSearch()) break; 62 | JSONObject object = array.getJSONObject(i); 63 | Classroom classroom = parseClassroom(object); 64 | if (withTimetable) { 65 | List classLessons = getClassroomTimetable(classroom.getInternalId(), LocalDate.now()); 66 | for (Lesson lesson : classLessons) { 67 | if (lesson.getStart().isBefore(zonedTime) && lesson.getEnd().isAfter(zonedTime)) { 68 | classroom.setLessonNow(lesson); 69 | classroom.setOccupied(true); 70 | } 71 | else if (lesson.getStart().isAfter(zonedTime)) { 72 | classroom.setNextLesson(lesson); 73 | break; 74 | } 75 | } 76 | classroom.setTodayLessons(classLessons); 77 | Thread.sleep(os.getWaitTimeClassroomRequest()); 78 | } 79 | ret.add(classroom); 80 | } 81 | } catch (IOException e) { 82 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 83 | os.log(Level.SEVERE, connectionException); 84 | throw connectionException; 85 | } catch (JSONException e) { 86 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 87 | os.log(Level.SEVERE, invalidResponse); 88 | throw invalidResponse; 89 | } catch (InterruptedException e) { 90 | e.printStackTrace(); 91 | } 92 | return ret; 93 | } 94 | 95 | private String handleRequest(Request req) throws IOException, OpenstudInvalidResponseException { 96 | Response resp = os.getClient().newCall(req).execute(); 97 | if (resp.body() == null) throw new OpenstudInvalidResponseException("GOMP answer is not valid"); 98 | String body = resp.body().string(); 99 | resp.close(); 100 | if (body.contains("maximum request limit")) 101 | throw new OpenstudInvalidResponseException("Request rate limit reached").setRateLimitType(); 102 | os.log(Level.INFO, body); 103 | return body; 104 | } 105 | 106 | private Classroom parseClassroom(JSONObject object) { 107 | Classroom classroom = new Classroom(); 108 | for (String info : object.keySet()) { 109 | if (object.isNull(info)) continue; 110 | switch (info) { 111 | case "roominternalid": 112 | classroom.setInternalId(object.getInt(info)); 113 | break; 114 | case "fullname": 115 | classroom.setFullName(object.getString(info)); 116 | break; 117 | case "name": 118 | classroom.setName(object.getString(info)); 119 | break; 120 | case "site": 121 | classroom.setWhere(object.getString(info)); 122 | break; 123 | case "lat": 124 | classroom.setLatitude(object.getDouble(info)); 125 | break; 126 | case "lng": 127 | classroom.setLongitude(object.getDouble(info)); 128 | break; 129 | case "occupied": 130 | classroom.setOccupied(object.getBoolean(info)); 131 | break; 132 | case "willbeoccupied": 133 | classroom.setWillBeOccupied(object.getBoolean(info)); 134 | break; 135 | case "weight": 136 | classroom.setWeight(object.getInt(info)); 137 | break; 138 | default: 139 | break; 140 | } 141 | } 142 | return classroom; 143 | } 144 | 145 | @Override 146 | public List getClassroomTimetable(Classroom room, LocalDate date) throws OpenstudConnectionException, OpenstudInvalidResponseException { 147 | if (room == null) return new LinkedList<>(); 148 | return getClassroomTimetable(room.getInternalId(), date); 149 | } 150 | 151 | @Override 152 | public List getClassroomTimetable(int id, LocalDate date) throws OpenstudConnectionException, OpenstudInvalidResponseException { 153 | if (!os.isReady()) return null; 154 | int count = 0; 155 | while (true) { 156 | try { 157 | return _getClassroomTimetable(id, date); 158 | } catch (OpenstudInvalidResponseException e) { 159 | if (e.isRateLimit()) throw e; 160 | if (++count == os.getMaxTries()) { 161 | os.log(Level.SEVERE, e); 162 | throw e; 163 | } 164 | } 165 | } 166 | } 167 | 168 | private List _getClassroomTimetable(int id, LocalDate date) throws OpenstudInvalidResponseException, OpenstudConnectionException { 169 | List ret = new LinkedList<>(); 170 | try { 171 | Request req = new Request.Builder().url(String.format("%s/events/%s/%s/%s/%s", os.getEndpointTimetable(), date.getYear(), date.getMonthValue(), date.getDayOfMonth(), id)).build(); 172 | String body = handleRequest(req); 173 | JSONArray array = new JSONArray(body); 174 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm"); 175 | for (int i = 0; i < array.length(); i++) { 176 | JSONObject object = array.getJSONObject(i); 177 | ret.add(SapienzaHelper.extractLesson(object, formatter, 0)); 178 | } 179 | return OpenstudHelper.sortLessonsByStartDate(ret, true); 180 | 181 | } catch (IOException e) { 182 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 183 | os.log(Level.SEVERE, connectionException); 184 | throw connectionException; 185 | } catch (JSONException e) { 186 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 187 | os.log(Level.SEVERE, invalidResponse); 188 | throw invalidResponse; 189 | } 190 | } 191 | 192 | @Override 193 | public Map> getTimetable(List exams) throws OpenstudInvalidResponseException, OpenstudConnectionException { 194 | if (!os.isReady()) return null; 195 | int count = 0; 196 | Map> ret; 197 | while (true) { 198 | try { 199 | ret = _getTimetable(exams); 200 | break; 201 | } catch (OpenstudInvalidResponseException e) { 202 | if (e.isRateLimit()) throw e; 203 | if (++count == os.getMaxTries()) { 204 | os.log(Level.SEVERE, e); 205 | throw e; 206 | } 207 | } 208 | } 209 | return ret; 210 | } 211 | 212 | private Map> _getTimetable(List exams) throws OpenstudInvalidResponseException, OpenstudConnectionException { 213 | Map> ret = new HashMap<>(); 214 | if (exams.isEmpty()) return ret; 215 | try { 216 | StringBuilder builderExams = new StringBuilder(); 217 | boolean first = true; 218 | for (ExamDoable exam : exams) { 219 | if (!first) 220 | builderExams.append(","); 221 | first = false; 222 | builderExams.append(exam.getExamCode()); 223 | } 224 | String codes = builderExams.toString(); 225 | Request req = new Request.Builder().url(String.format("%s/lectures/%s", os.getEndpointTimetable(), builderExams.toString())).build(); 226 | String body = handleRequest(req); 227 | JSONObject response = new JSONObject(body); 228 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm"); 229 | for (String examCode : response.keySet()) { 230 | if (!codes.contains(examCode)) continue; 231 | JSONArray array = response.getJSONArray(examCode); 232 | LinkedList lessons = new LinkedList<>(); 233 | for (int i = 0; i < array.length(); i++) { 234 | JSONObject object = array.getJSONObject(i); 235 | lessons.add(SapienzaHelper.extractLesson(object, formatter, -1)); 236 | } 237 | ret.put(examCode, lessons); 238 | } 239 | return ret; 240 | 241 | } catch (IOException e) { 242 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 243 | os.log(Level.SEVERE, connectionException); 244 | throw connectionException; 245 | } catch (JSONException e) { 246 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 247 | os.log(Level.SEVERE, invalidResponse); 248 | throw invalidResponse; 249 | } 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/providers/sapienza/SapienzaTaxHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.providers.sapienza; 2 | 3 | import lithium.openstud.driver.core.Openstud; 4 | import lithium.openstud.driver.core.internals.TaxHandler; 5 | import lithium.openstud.driver.core.models.Isee; 6 | import lithium.openstud.driver.core.models.Tax; 7 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 8 | import lithium.openstud.driver.exceptions.OpenstudInvalidCredentialsException; 9 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 10 | import lithium.openstud.driver.exceptions.OpenstudRefreshException; 11 | import okhttp3.Request; 12 | import okhttp3.Response; 13 | import org.json.JSONArray; 14 | import org.json.JSONException; 15 | import org.json.JSONObject; 16 | import org.threeten.bp.LocalDate; 17 | import org.threeten.bp.format.DateTimeFormatter; 18 | 19 | import java.io.IOException; 20 | import java.util.LinkedList; 21 | import java.util.List; 22 | import java.util.logging.Level; 23 | 24 | public class SapienzaTaxHandler implements TaxHandler { 25 | private Openstud os; 26 | 27 | public SapienzaTaxHandler(Openstud os) { 28 | this.os = os; 29 | } 30 | 31 | @Override 32 | public List getPaidTaxes() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 33 | if (!os.isReady()) return null; 34 | int count = 0; 35 | List taxes; 36 | while (true) { 37 | try { 38 | if (count > 0) os.refreshToken(); 39 | taxes = _getTaxes(true); 40 | break; 41 | } catch (OpenstudInvalidResponseException e) { 42 | if (e.isMaintenance()) throw e; 43 | if (++count == os.getMaxTries()) { 44 | os.log(Level.SEVERE, e); 45 | throw e; 46 | } 47 | } catch (OpenstudRefreshException e) { 48 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 49 | os.log(Level.SEVERE, invalidCredentials); 50 | throw invalidCredentials; 51 | } 52 | } 53 | return taxes; 54 | } 55 | 56 | @Override 57 | public byte[] getPaymentSlipPDF(Tax unpaidTax) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 58 | if (!os.isReady() || unpaidTax == null) return null; 59 | int count = 0; 60 | byte[] pdf; 61 | while (true) { 62 | try { 63 | if (count > 0) os.refreshToken(); 64 | pdf = _getPaymentSlip(unpaidTax); 65 | break; 66 | } catch (OpenstudInvalidResponseException e) { 67 | if (e.isMaintenance()) throw e; 68 | if (++count == os.getMaxTries()) { 69 | os.log(Level.SEVERE, e); 70 | throw e; 71 | } 72 | } catch (OpenstudRefreshException e) { 73 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 74 | os.log(Level.SEVERE, invalidCredentials); 75 | throw invalidCredentials; 76 | } 77 | } 78 | return pdf; 79 | } 80 | 81 | private byte[] _getPaymentSlip(Tax unpaidTax) throws OpenstudInvalidResponseException, OpenstudConnectionException { 82 | try { 83 | Request req = new Request.Builder().url(String.format("%s/contabilita/%s/%s/ristampa?ingresso=%s", os.getEndpointAPI(), os.getStudentID(), unpaidTax.getCode(), os.getToken())).build(); 84 | Response resp = os.getClient().newCall(req).execute(); 85 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 86 | String body = resp.body().string(); 87 | resp.close(); 88 | os.log(Level.INFO, body); 89 | JSONObject response = new JSONObject(body); 90 | if (!response.has("risultato") || response.isNull("risultato")) 91 | throw new OpenstudInvalidResponseException("Infostud answer is not valid, maybe the token is no longer valid"); 92 | response = response.getJSONObject("risultato"); 93 | if (!response.has("byte") || response.isNull("byte")) 94 | throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 95 | JSONArray byteArray = response.getJSONArray("byte"); 96 | byte[] pdf = new byte[byteArray.length()]; 97 | for (int i = 0; i < byteArray.length(); i++) pdf[i] = (byte) byteArray.getInt(i); 98 | os.log(Level.INFO, "Found PDF made of " + pdf.length + " bytes \n"); 99 | return pdf; 100 | } catch (IOException e) { 101 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 102 | os.log(Level.SEVERE, connectionException); 103 | throw connectionException; 104 | } catch (JSONException e) { 105 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 106 | os.log(Level.SEVERE, invalidResponse); 107 | throw invalidResponse; 108 | } 109 | } 110 | 111 | 112 | @Override 113 | public List getUnpaidTaxes() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 114 | if (!os.isReady()) return null; 115 | int count = 0; 116 | List taxes; 117 | while (true) { 118 | try { 119 | if (count > 0) os.refreshToken(); 120 | taxes = _getTaxes(false); 121 | break; 122 | } catch (OpenstudInvalidResponseException e) { 123 | if (e.isMaintenance()) throw e; 124 | if (++count == os.getMaxTries()) { 125 | os.log(Level.SEVERE, e); 126 | throw e; 127 | } 128 | } catch (OpenstudRefreshException e) { 129 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 130 | os.log(Level.SEVERE, invalidCredentials); 131 | throw invalidCredentials; 132 | } 133 | } 134 | return taxes; 135 | } 136 | 137 | private List _getTaxes(boolean paid) throws OpenstudConnectionException, OpenstudInvalidResponseException { 138 | try { 139 | String partial; 140 | if (paid) partial = "bollettinipagati"; 141 | else partial = "bollettininonpagati"; 142 | Request req = new Request.Builder().url(String.format("%s/contabilita/%s/%s?ingresso=%s", os.getEndpointAPI(), os.getStudentID(), partial, os.getToken())).build(); 143 | Response resp = os.getClient().newCall(req).execute(); 144 | List list = new LinkedList<>(); 145 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 146 | String body = resp.body().string(); 147 | resp.close(); 148 | os.log(Level.INFO, body); 149 | JSONObject response = new JSONObject(body); 150 | if (!response.has("risultatoLista")) 151 | throw new OpenstudInvalidResponseException("Infostud response is not valid. I guess the token is no longer valid"); 152 | if (response.isNull("risultatoLista")) 153 | return new LinkedList<>(); 154 | response = response.getJSONObject("risultatoLista"); 155 | if (!response.has("risultati") || response.isNull("risultati")) return new LinkedList<>(); 156 | JSONArray array = response.getJSONArray("risultati"); 157 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 158 | for (int i = 0; i < array.length(); i++) { 159 | JSONObject obj = array.getJSONObject(i); 160 | Tax tax = new Tax(); 161 | for (String element : obj.keySet()) { 162 | switch (element) { 163 | case "codiceBollettino": 164 | tax.setCode(obj.getString(element)); 165 | break; 166 | case "corsoDiStudi": 167 | tax.setCodeCourse(obj.getString(element)); 168 | break; 169 | case "descCorsoDiStudi": 170 | tax.setDescriptionCourse(obj.getString(element)); 171 | break; 172 | case "impoVers": 173 | try { 174 | String content = obj.getString(element); 175 | if (!content.isEmpty()) tax.setAmount(Double.parseDouble(obj.getString(element))); 176 | } catch (NumberFormatException e) { 177 | e.printStackTrace(); 178 | os.log(Level.SEVERE, e); 179 | } 180 | break; 181 | case "annoAcca": 182 | tax.setAcademicYear(obj.getInt(element)); 183 | break; 184 | case "dataVers": 185 | if (!paid) break; 186 | tax.setPaymentDate(LocalDate.parse(obj.getString(element), formatter)); 187 | break; 188 | case "importoBollettino": 189 | if (obj.isNull(element)) break; 190 | try { 191 | double value = Double.parseDouble(obj.getString(element).replace(",", ".")); 192 | tax.setAmount(value); 193 | } catch (NumberFormatException e) { 194 | e.printStackTrace(); 195 | os.log(Level.SEVERE, e); 196 | } 197 | break; 198 | case "scadenza": 199 | if (obj.getString(element).isEmpty()) continue; 200 | tax.setExpirationDate(LocalDate.parse(obj.getString(element), formatter)); 201 | break; 202 | default: 203 | break; 204 | } 205 | } 206 | tax.setPaymentDescriptionList(SapienzaHelper.extractPaymentDescriptionList(os, obj.getJSONArray("causali"))); 207 | if (paid) tax.setStatus(Tax.TaxStatus.PAID); 208 | else tax.setStatus(Tax.TaxStatus.UNPAID); 209 | list.add(tax); 210 | } 211 | return list; 212 | } catch (IOException e) { 213 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 214 | os.log(Level.SEVERE, connectionException); 215 | throw connectionException; 216 | } catch (JSONException e) { 217 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 218 | os.log(Level.SEVERE, invalidResponse); 219 | throw invalidResponse; 220 | } 221 | } 222 | 223 | public Isee getCurrentIsee() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 224 | if (!os.isReady()) return null; 225 | int count = 0; 226 | Isee isee; 227 | while (true) { 228 | try { 229 | if (count > 0) os.refreshToken(); 230 | isee = _getCurrentIsee(); 231 | break; 232 | } catch (OpenstudInvalidResponseException e) { 233 | if (e.isMaintenance()) throw e; 234 | if (++count == os.getMaxTries()) { 235 | os.log(Level.SEVERE, e); 236 | throw e; 237 | } 238 | } catch (OpenstudRefreshException e) { 239 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 240 | os.log(Level.SEVERE, invalidCredentials); 241 | throw invalidCredentials; 242 | } 243 | } 244 | return isee; 245 | } 246 | 247 | private Isee _getCurrentIsee() throws OpenstudConnectionException, OpenstudInvalidResponseException { 248 | try { 249 | Request req = new Request.Builder().url(String.format("%s/contabilita/%s/isee?ingresso=%s", os.getEndpointAPI(), os.getStudentID(), os.getToken())).build(); 250 | Response resp = os.getClient().newCall(req).execute(); 251 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 252 | String body = resp.body().string(); 253 | resp.close(); 254 | os.log(Level.INFO, body); 255 | JSONObject response = new JSONObject(body); 256 | if (!response.has("risultato")) 257 | throw new OpenstudInvalidResponseException("Infostud response is not valid. I guess the token is no longer valid"); 258 | response = response.getJSONObject("risultato"); 259 | return SapienzaHelper.extractIsee(os, response); 260 | } catch (IOException e) { 261 | os.log(Level.SEVERE, e); 262 | throw new OpenstudConnectionException(e); 263 | } catch (JSONException e) { 264 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 265 | os.log(Level.SEVERE, invalidResponse); 266 | throw invalidResponse; 267 | } 268 | } 269 | 270 | public List getIseeHistory() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 271 | if (!os.isReady()) return null; 272 | int count = 0; 273 | List history; 274 | while (true) { 275 | try { 276 | if (count > 0) os.refreshToken(); 277 | history = _getIseeHistory(); 278 | break; 279 | } catch (OpenstudInvalidResponseException e) { 280 | if (e.isMaintenance()) throw e; 281 | if (++count == os.getMaxTries()) { 282 | os.log(Level.SEVERE, e); 283 | throw e; 284 | } 285 | } catch (OpenstudRefreshException e) { 286 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 287 | os.log(Level.SEVERE, invalidCredentials); 288 | throw invalidCredentials; 289 | } 290 | } 291 | return history; 292 | } 293 | 294 | private List _getIseeHistory() throws OpenstudConnectionException, OpenstudInvalidResponseException { 295 | try { 296 | Request req = new Request.Builder().url(String.format("%s/contabilita/%s/listaIsee?ingresso=%s", os.getEndpointAPI(), os.getStudentID(), os.getToken())).build(); 297 | Response resp = os.getClient().newCall(req).execute(); 298 | List list = new LinkedList<>(); 299 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 300 | String body = resp.body().string(); 301 | resp.close(); 302 | os.log(Level.INFO, body); 303 | JSONObject response = new JSONObject(body); 304 | if (!response.has("risultatoLista")) 305 | throw new OpenstudInvalidResponseException("Infostud response is not valid. I guess the token is no longer valid"); 306 | response = response.getJSONObject("risultatoLista"); 307 | if (!response.has("risultati") || response.isNull("risultati")) return new LinkedList<>(); 308 | JSONArray array = response.getJSONArray("risultati"); 309 | for (int i = 0; i < array.length(); i++) { 310 | Isee result = SapienzaHelper.extractIsee(os, array.getJSONObject(i)); 311 | if (result == null) continue; 312 | list.add(SapienzaHelper.extractIsee(os, array.getJSONObject(i))); 313 | } 314 | return list; 315 | } catch (IOException e) { 316 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 317 | os.log(Level.SEVERE, connectionException); 318 | throw connectionException; 319 | } catch (JSONException e) { 320 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 321 | os.log(Level.SEVERE, invalidResponse); 322 | throw invalidResponse; 323 | } 324 | } 325 | } 326 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/Openstud.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core; 2 | 3 | import lithium.openstud.driver.core.internals.*; 4 | import lithium.openstud.driver.core.models.*; 5 | import lithium.openstud.driver.core.providers.sapienza.*; 6 | import lithium.openstud.driver.exceptions.*; 7 | import okhttp3.ConnectionSpec; 8 | import okhttp3.OkHttpClient; 9 | import org.apache.commons.lang3.tuple.Pair; 10 | import org.threeten.bp.LocalDate; 11 | import java.util.Collections; 12 | import java.util.List; 13 | import java.util.Map; 14 | import java.util.concurrent.TimeUnit; 15 | import java.util.logging.Level; 16 | import java.util.logging.Logger; 17 | 18 | public class Openstud implements AuthenticationHandler, BioHandler, NewsHandler, TaxHandler, ClassroomHandler, ExamHandler { 19 | private int maxTries; 20 | private String endpointAPI; 21 | private String endpointTimetable; 22 | private volatile String token; 23 | private String studentPassword; 24 | private String studentID; 25 | private boolean isReady; 26 | private Logger logger; 27 | private OkHttpClient client; 28 | private String key; 29 | private int waitTimeClassroomRequest; 30 | private int limitSearch; 31 | private OpenstudHelper.Provider provider; 32 | private AuthenticationHandler authenticator; 33 | private BioHandler personal; 34 | private NewsHandler newsHandler; 35 | private TaxHandler taxHandler; 36 | private ClassroomHandler classroomHandler; 37 | private ExamHandler examHandler; 38 | private ProviderConfig config; 39 | private OpenstudHelper.Mode mode; 40 | 41 | public Openstud() { 42 | super(); 43 | } 44 | 45 | Openstud(OpenstudBuilder builder) { 46 | this.provider = builder.provider; 47 | this.maxTries = builder.retryCounter; 48 | this.studentID = builder.studentID; 49 | this.studentPassword = builder.password; 50 | this.logger = builder.logger; 51 | this.isReady = builder.readyState; 52 | this.waitTimeClassroomRequest = builder.waitTimeClassroomRequest; 53 | this.limitSearch = builder.limitSearchResults; 54 | this.mode = builder.mode; 55 | client = new OkHttpClient.Builder() 56 | .connectTimeout(builder.connectTimeout, TimeUnit.SECONDS) 57 | .writeTimeout(builder.writeTimeout, TimeUnit.SECONDS) 58 | .readTimeout(builder.readTimeout, TimeUnit.SECONDS) 59 | .retryOnConnectionFailure(true) 60 | .connectionSpecs(Collections.singletonList(ConnectionSpec.COMPATIBLE_TLS)) 61 | .build(); 62 | init(); 63 | config.addKeys(builder.keyMap); 64 | } 65 | 66 | private void init() { 67 | if (provider == null) throw new IllegalArgumentException("Provider can't be left null"); 68 | else if (provider == OpenstudHelper.Provider.SAPIENZA) { 69 | authenticator = new SapienzaAuthenticationHandler(this); 70 | personal = new SapienzaBioHandler(this); 71 | newsHandler = new SapienzaNewsHandler(this); 72 | taxHandler = new SapienzaTaxHandler(this); 73 | classroomHandler = new SapienzaClassroomHandler(this); 74 | examHandler = new SapienzaExamHandler(this); 75 | config = new SapienzaConfig(); 76 | } 77 | endpointAPI = config.getEndpointAPI(mode); 78 | endpointTimetable = config.getEndpointTimetable(mode); 79 | key = config.getKey(mode); 80 | } 81 | 82 | public ProviderConfig getConfig() { 83 | return config; 84 | } 85 | 86 | public OpenstudHelper.Provider getProvider(){ 87 | return provider; 88 | } 89 | 90 | public String getStudentID() { 91 | return studentID; 92 | } 93 | 94 | public String getEndpointAPI() { 95 | return endpointAPI; 96 | } 97 | 98 | public String getEndpointTimetable() { 99 | return endpointTimetable; 100 | } 101 | 102 | public String getStudentPassword() { 103 | return studentPassword; 104 | } 105 | 106 | public Logger getLogger() { 107 | return logger; 108 | } 109 | 110 | public OkHttpClient getClient() { 111 | return client; 112 | } 113 | 114 | public String getKey() { 115 | return key; 116 | } 117 | 118 | public String getKey(String keyName) { 119 | return config.getKey(keyName); 120 | } 121 | 122 | public int getWaitTimeClassroomRequest() { 123 | return waitTimeClassroomRequest; 124 | } 125 | 126 | public int getLimitSearch() { 127 | return limitSearch; 128 | } 129 | 130 | public void setStudentPassword(String password) { 131 | studentPassword = password; 132 | } 133 | 134 | public void setReady(boolean isReady) { 135 | this.isReady = isReady; 136 | } 137 | 138 | public int getMaxTries() { 139 | return maxTries; 140 | } 141 | 142 | public void setToken(String token) { 143 | this.token = token; 144 | } 145 | 146 | public synchronized String getToken() { 147 | return this.token; 148 | } 149 | 150 | void log(Level lvl, String str) { 151 | if (logger != null) logger.log(lvl, str); 152 | } 153 | 154 | public void log(Level lvl, Object obj) { 155 | if (logger != null) logger.log(lvl, obj.toString()); 156 | } 157 | 158 | public boolean isReady() { 159 | return isReady; 160 | } 161 | 162 | @Override 163 | public synchronized void refreshToken() throws OpenstudRefreshException, OpenstudInvalidResponseException { 164 | if (!config.isRefreshEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 165 | authenticator.refreshToken(); 166 | } 167 | 168 | @Override 169 | public void login() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudUserNotEnabledException { 170 | if (!config.isAuthEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 171 | authenticator.login(); 172 | } 173 | 174 | @Override 175 | public String getSecurityQuestion() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 176 | if (!config.isAuthEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 177 | return authenticator.getSecurityQuestion(); 178 | } 179 | 180 | @Override 181 | public boolean recoverPassword(String answer) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudInvalidAnswerException { 182 | if (!config.isAuthEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 183 | return authenticator.recoverPassword(answer); 184 | } 185 | 186 | @Override 187 | public void resetPassword(String new_password) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 188 | if (!config.isAuthEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 189 | authenticator.resetPassword(new_password); 190 | } 191 | 192 | @Override 193 | public boolean recoverPasswordWithEmail(String email, String answer) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudInvalidAnswerException { 194 | if (!config.isAuthEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 195 | return authenticator.recoverPasswordWithEmail(email, answer); 196 | } 197 | 198 | @Override 199 | public Student getInfoStudent() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 200 | if (!config.isBioEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 201 | return personal.getInfoStudent(); 202 | } 203 | 204 | @Override 205 | public List getCareersChoicesForCertificate(Student student, CertificateType certificate) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 206 | if (!config.isCareerForCertificateEnabled() || !config.isCertSupported(certificate)) 207 | throw new IllegalStateException("Provider doesn't support this feature"); 208 | return personal.getCareersChoicesForCertificate(student, certificate); 209 | } 210 | 211 | @Override 212 | public byte[] getCertificatePDF(Student student, Career career, CertificateType certificate) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 213 | if (!config.isCertEnabled() || !config.isCertSupported(certificate)) 214 | throw new IllegalStateException("Provider doesn't support this feature"); 215 | return personal.getCertificatePDF(student, career, certificate); 216 | } 217 | 218 | @Override 219 | public List getNews(String locale, boolean withDescription, Integer limit, Integer page, Integer maxPage, 220 | String query) throws OpenstudInvalidResponseException, OpenstudConnectionException { 221 | if (!config.isNewsEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 222 | return newsHandler.getNews(locale, withDescription, limit, page, maxPage, query); 223 | } 224 | 225 | @Override 226 | public List getNewsletterEvents() throws OpenstudInvalidResponseException, OpenstudConnectionException { 227 | if (!config.isNewsEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 228 | return newsHandler.getNewsletterEvents(); 229 | } 230 | 231 | @Override 232 | public List getUnpaidTaxes() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 233 | if (!config.isTaxEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 234 | return taxHandler.getUnpaidTaxes(); 235 | } 236 | 237 | @Override 238 | public List getPaidTaxes() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 239 | if (!config.isTaxEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 240 | return taxHandler.getPaidTaxes(); 241 | } 242 | 243 | @Override 244 | public byte[] getPaymentSlipPDF(Tax unpaidTax) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 245 | if (!config.isTaxEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 246 | if (unpaidTax.getStatus() == Tax.TaxStatus.PAID) throw new IllegalStateException("Provider doesn't support printing of paid slips"); 247 | return taxHandler.getPaymentSlipPDF(unpaidTax); 248 | } 249 | 250 | @Override 251 | public Isee getCurrentIsee() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 252 | if (!config.isTaxEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 253 | return taxHandler.getCurrentIsee(); 254 | } 255 | 256 | @Override 257 | public List getIseeHistory() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 258 | if (!config.isTaxEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 259 | return taxHandler.getIseeHistory(); 260 | } 261 | 262 | @Override 263 | public List getClassRoom(String query, boolean withTimetable) throws OpenstudInvalidResponseException, OpenstudConnectionException { 264 | if (!config.isClassroomEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 265 | return classroomHandler.getClassRoom(query, withTimetable); 266 | } 267 | 268 | @Override 269 | public List getClassroomTimetable(Classroom room, LocalDate date) throws OpenstudConnectionException, OpenstudInvalidResponseException { 270 | if (!config.isClassroomEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 271 | return classroomHandler.getClassroomTimetable(room, date); 272 | } 273 | 274 | @Override 275 | public List getClassroomTimetable(int id, LocalDate date) throws OpenstudConnectionException, OpenstudInvalidResponseException { 276 | if (!config.isClassroomEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 277 | return classroomHandler.getClassroomTimetable(id, date); 278 | } 279 | 280 | @Override 281 | public Map> getTimetable(List exams) throws OpenstudInvalidResponseException, OpenstudConnectionException { 282 | if (!config.isClassroomEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 283 | return classroomHandler.getTimetable(exams); 284 | } 285 | 286 | @Override 287 | public List getExamsDoable() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 288 | if (!config.isExamEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 289 | return examHandler.getExamsDoable(); 290 | } 291 | 292 | @Override 293 | public List getExamsDone() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 294 | if (!config.isExamEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 295 | return examHandler.getExamsDone(); 296 | } 297 | 298 | @Override 299 | public String getCourseSurvey(String surveyCode) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 300 | if (!config.isSurveyEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 301 | return examHandler.getCourseSurvey(surveyCode); 302 | } 303 | 304 | @Override 305 | public List getActiveReservations() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 306 | if (!config.isExamEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 307 | return examHandler.getActiveReservations(); 308 | } 309 | 310 | @Override 311 | public List getAvailableReservations(ExamDoable exam, Student student) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 312 | if (!config.isExamEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 313 | return examHandler.getAvailableReservations(exam, student); 314 | } 315 | 316 | @Override 317 | public Pair insertReservation(ExamReservation res) throws OpenstudInvalidResponseException, OpenstudConnectionException, OpenstudInvalidCredentialsException { 318 | if (!config.isExamEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 319 | return examHandler.insertReservation(res); 320 | } 321 | 322 | @Override 323 | public int deleteReservation(ExamReservation res) throws OpenstudInvalidResponseException, OpenstudConnectionException, OpenstudInvalidCredentialsException { 324 | if (!config.isExamEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 325 | return examHandler.deleteReservation(res); 326 | } 327 | 328 | @Override 329 | public byte[] getExamReservationPDF(ExamReservation reservation) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 330 | if (!config.isExamEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 331 | return examHandler.getExamReservationPDF(reservation); 332 | } 333 | 334 | @Override 335 | public List getCalendarEvents(Student student) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 336 | if (!config.isExamEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 337 | return examHandler.getCalendarEvents(student); 338 | } 339 | 340 | @Override 341 | public byte[] getStudentPhoto(Student student) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 342 | if (!config.isStudentPhotoEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 343 | return personal.getStudentPhoto(student); 344 | } 345 | 346 | @Override 347 | public StudentCard getStudentCard(Student student, boolean withPhoto) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 348 | if (!config.isStudentCardEnabled()) throw new IllegalStateException("Provider doesn't support this feature"); 349 | return personal.getStudentCard(student, withPhoto); 350 | } 351 | } -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/providers/sapienza/SapienzaHelper.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.providers.sapienza; 2 | 3 | import com.lithium.kapitalize.Kapitalize; 4 | import com.lithium.kapitalize.languages.EnglishLanguage; 5 | import com.lithium.kapitalize.languages.SpecialRules; 6 | import lithium.openstud.driver.core.Openstud; 7 | import lithium.openstud.driver.core.models.*; 8 | import org.apache.commons.lang3.math.NumberUtils; 9 | import org.json.JSONArray; 10 | import org.json.JSONObject; 11 | import org.threeten.bp.LocalDate; 12 | import org.threeten.bp.LocalDateTime; 13 | import org.threeten.bp.format.DateTimeFormatter; 14 | import org.threeten.bp.format.DateTimeParseException; 15 | 16 | import java.util.LinkedList; 17 | import java.util.List; 18 | import java.util.logging.Level; 19 | 20 | class SapienzaHelper { 21 | 22 | static Lesson extractLesson(JSONObject response, DateTimeFormatter formatter, int offset) { 23 | Lesson lesson = new Lesson(); 24 | for (String lessonInfo : response.keySet()) { 25 | if (response.isNull(lessonInfo)) continue; 26 | switch (lessonInfo) { 27 | case "name": 28 | String name = response.getString(lessonInfo); 29 | int startIdx = name.indexOf(" "); 30 | int endIdx = name.indexOf("Docente:"); 31 | if (startIdx != -1 && endIdx != -1) { 32 | if (name.endsWith(" ")) { 33 | name = name.substring(0, name.length() - 1); 34 | } 35 | lesson.setName(name.substring(startIdx, endIdx).trim()); 36 | } else lesson.setName(name); 37 | int indexTeacher = name.indexOf("Docente:"); 38 | if (indexTeacher != -1) lesson.setTeacher(name.substring(indexTeacher + "Docente: ".length())); 39 | break; 40 | case "where": 41 | lesson.setWhere(response.getString(lessonInfo)); 42 | break; 43 | case "start": 44 | LocalDateTime startTime = LocalDateTime.parse(response.getString(lessonInfo), formatter); 45 | startTime = startTime.plusHours(offset); 46 | lesson.setStart(startTime); 47 | break; 48 | case "end": 49 | LocalDateTime endTime = LocalDateTime.parse(response.getString(lessonInfo), formatter); 50 | endTime = endTime.plusHours(offset); 51 | lesson.setEnd(endTime); 52 | break; 53 | default: 54 | break; 55 | } 56 | } 57 | return lesson; 58 | } 59 | 60 | static Isee extractIsee(Openstud os, JSONObject response) { 61 | Isee res = new Isee(); 62 | for (String element : response.keySet()) { 63 | switch (element) { 64 | case "valore": 65 | double value = response.getDouble("valore"); 66 | if (value == -2) return null; 67 | res.setValue(response.getDouble("valore")); 68 | break; 69 | case "protocollo": 70 | String protocol = response.getString("protocollo"); 71 | if (protocol == null || protocol.isEmpty()) return null; 72 | res.setProtocol(response.getString("protocollo")); 73 | break; 74 | case "modificabile": 75 | res.setEditable(response.getInt("modificabile") == 1); 76 | break; 77 | case "dataOperazione": 78 | if (response.isNull("dataOperazione")) break; 79 | DateTimeFormatter formatterOperation = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); 80 | String dateOperation = response.getString("dataOperazione"); 81 | if (!(dateOperation == null || dateOperation.isEmpty())) { 82 | try { 83 | res.setDateOperation(LocalDate.parse(response.getString("dataOperazione"), formatterOperation)); 84 | } catch (DateTimeParseException e) { 85 | e.printStackTrace(); 86 | os.log(Level.SEVERE, e); 87 | } 88 | } 89 | break; 90 | case "data": 91 | DateTimeFormatter formatterDateDeclaration = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 92 | if (response.isNull("data")) return null; 93 | String dateDeclaration = response.getString("data"); 94 | if (!(dateDeclaration == null || dateDeclaration.isEmpty())) { 95 | try { 96 | res.setDateDeclaration(LocalDate.parse(response.getString("data"), formatterDateDeclaration)); 97 | } catch (DateTimeParseException e) { 98 | e.printStackTrace(); 99 | os.log(Level.SEVERE, e); 100 | } 101 | } 102 | break; 103 | default: 104 | break; 105 | } 106 | 107 | } 108 | return res; 109 | } 110 | 111 | static List extractPaymentDescriptionList(Openstud os, JSONArray array) { 112 | List list = new LinkedList<>(); 113 | if (array == null) return list; 114 | for (int i = 0; i < array.length(); i++) { 115 | JSONObject obj = array.getJSONObject(i); 116 | PaymentDescription pdes = new PaymentDescription(); 117 | for (String element : obj.keySet()) { 118 | switch (element) { 119 | case "descrizione": 120 | pdes.setDescription(obj.getString("descrizione")); 121 | break; 122 | case "importo": 123 | try { 124 | Double value = Double.parseDouble(obj.getString("importo")); 125 | pdes.setAmount(value); 126 | } catch (NumberFormatException e) { 127 | e.printStackTrace(); 128 | os.log(Level.SEVERE, e); 129 | } 130 | break; 131 | case "annoAccademicoString": 132 | pdes.setAcademicYear(obj.getString("annoAccademicoString")); 133 | break; 134 | case "impoVers": 135 | try { 136 | Double valueVers = Double.parseDouble(obj.getString("impoVers")); 137 | pdes.setAmountPaid(valueVers); 138 | } catch (NumberFormatException e) { 139 | e.printStackTrace(); 140 | os.log(Level.SEVERE, e); 141 | } 142 | break; 143 | default: 144 | break; 145 | } 146 | } 147 | list.add(pdes); 148 | } 149 | return list; 150 | } 151 | 152 | static List extractReservations(Openstud os, JSONArray array) { 153 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 154 | List list = new LinkedList<>(); 155 | for (int i = 0; i < array.length(); i++) { 156 | JSONObject obj = array.getJSONObject(i); 157 | ExamReservation res = new ExamReservation(); 158 | for (String element : obj.keySet()) { 159 | switch (element) { 160 | case "codIdenVerb": 161 | res.setReportID(obj.getInt("codIdenVerb")); 162 | break; 163 | case "canale": 164 | res.setChannel(obj.getString("canale")); 165 | break; 166 | case "codAppe": 167 | res.setSessionID(obj.getInt("codAppe")); 168 | break; 169 | case "codCorsoStud": 170 | res.setCourseCode(Integer.parseInt(obj.getString("codCorsoStud"))); 171 | break; 172 | case "descrizione": 173 | res.setExamSubject(obj.getString("descrizione")); 174 | break; 175 | case "descCorsoStud": 176 | res.setCourseDescription(obj.getString("descCorsoStud")); 177 | break; 178 | case "crediti": 179 | res.setCfu(obj.getInt("crediti")); 180 | break; 181 | case "docente": 182 | res.setTeacher(obj.getString("docente")); 183 | break; 184 | case "annoAcca": 185 | res.setYearCourse(obj.getString("annoAcca")); 186 | break; 187 | case "facolta": 188 | res.setDepartment(obj.getString("facolta")); 189 | break; 190 | case "numeroPrenotazione": 191 | if (obj.isNull("numeroPrenotazione")) break; 192 | res.setReservationNumber(obj.getInt("numeroPrenotazione")); 193 | break; 194 | case "ssd": 195 | if (obj.isNull("ssd")) break; 196 | res.setSsd(obj.getString("ssd")); 197 | break; 198 | case "dataprenotazione": 199 | if (obj.isNull("dataprenotazione")) break; 200 | String reservationDate = obj.getString("dataprenotazione"); 201 | if (!(reservationDate == null || reservationDate.isEmpty())) { 202 | try { 203 | res.setReservationDate(LocalDate.parse(reservationDate, formatter)); 204 | } catch (DateTimeParseException e) { 205 | e.printStackTrace(); 206 | os.log(Level.SEVERE, e); 207 | } 208 | } 209 | break; 210 | case "note": 211 | res.setNote(obj.getString("note")); 212 | break; 213 | case "dataAppe": 214 | String examDate = obj.getString("dataAppe"); 215 | if (!(examDate == null || examDate.isEmpty())) { 216 | try { 217 | res.setExamDate(LocalDate.parse(examDate, formatter)); 218 | } catch (DateTimeParseException e) { 219 | e.printStackTrace(); 220 | os.log(Level.SEVERE, e); 221 | } 222 | } 223 | break; 224 | case "dataInizioPrenotazione": 225 | if (obj.isNull("dataInizioPrenotazione")) break; 226 | String startDate = obj.getString("dataInizioPrenotazione"); 227 | if (!(startDate == null || startDate.isEmpty())) { 228 | try { 229 | res.setStartDate(LocalDate.parse(startDate, formatter)); 230 | } catch (DateTimeParseException e) { 231 | e.printStackTrace(); 232 | os.log(Level.SEVERE, e); 233 | } 234 | } 235 | break; 236 | case "dataFinePrenotazione": 237 | if (obj.isNull("dataFinePrenotazione")) break; 238 | String endDate = obj.getString("dataFinePrenotazione"); 239 | if (!(endDate == null || endDate.isEmpty())) { 240 | try { 241 | res.setEndDate(LocalDate.parse(endDate, formatter)); 242 | } catch (DateTimeParseException e) { 243 | e.printStackTrace(); 244 | os.log(Level.SEVERE, e); 245 | } 246 | } 247 | break; 248 | case "SiglaModuloDidattico": 249 | if (!obj.isNull("SiglaModuloDidattico")) res.setModule(obj.getString("SiglaModuloDidattico")); 250 | break; 251 | default: 252 | break; 253 | } 254 | } 255 | list.add(res); 256 | } 257 | return list; 258 | } 259 | 260 | static Student extractStudent(Openstud os, JSONObject response) { 261 | Student st = new Student(); 262 | st.setStudentID(os.getStudentID()); 263 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 264 | EnglishLanguage lang = new EnglishLanguage(SpecialRules.ITALIAN); 265 | lang.setCapitalizePostNominalsInitials(false); 266 | Kapitalize kapitalize = new Kapitalize(lang); 267 | for (String element : response.keySet()) { 268 | if (response.isNull(element)) continue; 269 | switch (element) { 270 | case "codiceFiscale": 271 | st.setSocialSecurityNumber(response.getString("codiceFiscale")); 272 | break; 273 | case "cognome": 274 | st.setLastName(kapitalize.capitalize(response.getString("cognome"))); 275 | break; 276 | case "nome": 277 | st.setFirstName(kapitalize.capitalize(response.getString("nome"))); 278 | break; 279 | case "dataDiNascita": 280 | String dateBirth = response.getString("dataDiNascita"); 281 | if (!(dateBirth == null || dateBirth.isEmpty())) { 282 | try { 283 | st.setBirthDate(LocalDate.parse(response.getString("dataDiNascita"), formatter)); 284 | } catch (DateTimeParseException e) { 285 | e.printStackTrace(); 286 | os.log(Level.SEVERE, e); 287 | } 288 | } 289 | break; 290 | case "comuneDiNasciata": 291 | st.setBirthCity(response.getString("comuneDiNasciata")); 292 | break; 293 | case "luogoDiNascita": 294 | st.setBirthPlace(response.getString("luogoDiNascita")); 295 | break; 296 | case "annoCorso": 297 | st.setCourseYear(response.getString("annoCorso")); 298 | break; 299 | case "primaIscr": 300 | st.setFirstEnrollment(response.getString("primaIscr")); 301 | break; 302 | case "ultIscr": 303 | st.setLastEnrollment(response.getString("ultIscr")); 304 | break; 305 | case "facolta": 306 | st.setDepartmentName(response.getString("facolta")); 307 | break; 308 | case "nomeCorso": 309 | st.setCourseName(response.getString("nomeCorso")); 310 | break; 311 | case "annoAccaAtt": 312 | st.setAcademicYear(response.getInt("annoAccaAtt")); 313 | break; 314 | case "codCorso": 315 | st.setCodeCourse(response.getInt("codCorso")); 316 | break; 317 | case "tipoStudente": 318 | st.setTypeStudent(response.getInt("tipoStudente")); 319 | break; 320 | case "tipoIscrizione": 321 | st.setStudentStatus(response.getString("tipoIscrizione")); 322 | break; 323 | case "isErasmus": 324 | st.setErasmus(response.getBoolean("isErasmus")); 325 | break; 326 | case "nazioneNascita": 327 | st.setNation(response.getString("nazioneNascita")); 328 | break; 329 | case "creditiTotali": 330 | String cfu = response.getString("creditiTotali"); 331 | if (NumberUtils.isDigits(cfu)) st.setCfu(Integer.parseInt(cfu)); 332 | break; 333 | case "indiMailIstituzionale": 334 | st.setEmail(response.getString("indiMailIstituzionale")); 335 | case "sesso": 336 | st.setGender(response.getString("sesso")); 337 | break; 338 | case "annoAccaCors": 339 | st.setAcademicYearCourse(response.getInt("annoAccaCors")); 340 | break; 341 | case "cittadinanza": 342 | st.setCitizenship(response.getString("cittadinanza")); 343 | break; 344 | default: 345 | break; 346 | } 347 | } 348 | return st; 349 | } 350 | 351 | 352 | static int getCertificateValue(CertificateType certificate) { 353 | switch (certificate) { 354 | case REGISTRATION: 355 | return 1; 356 | case DEGREE_WITH_EXAMS: 357 | case DEGREE_WITH_EXAMS_ENG: 358 | return 7; 359 | case DEGREE_WITH_THESIS: 360 | case DEGREE_WITH_THESIS_ENG: 361 | return 6; 362 | case DEGREE_WITH_EVALUATION: 363 | case DEGREE_WITH_EVALUATION_ENG: 364 | return 9; 365 | case EXAMS_COMPLETED: 366 | return 2; 367 | case DEGREE_FOR_RANSOM: 368 | return 8; 369 | default: 370 | return -1; 371 | } 372 | } 373 | 374 | } 375 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/providers/sapienza/SapienzaAuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.providers.sapienza; 2 | 3 | import lithium.openstud.driver.core.Openstud; 4 | import lithium.openstud.driver.core.internals.AuthenticationHandler; 5 | import lithium.openstud.driver.exceptions.*; 6 | import okhttp3.FormBody; 7 | import okhttp3.Request; 8 | import okhttp3.RequestBody; 9 | import okhttp3.Response; 10 | import org.apache.commons.lang3.StringUtils; 11 | import org.json.JSONException; 12 | import org.json.JSONObject; 13 | 14 | import java.io.IOException; 15 | import java.util.logging.Level; 16 | import java.util.regex.Pattern; 17 | 18 | public class SapienzaAuthenticationHandler implements AuthenticationHandler { 19 | private Openstud os; 20 | 21 | public SapienzaAuthenticationHandler(Openstud openstud) { 22 | this.os = openstud; 23 | } 24 | 25 | @Override 26 | public synchronized void refreshToken() throws OpenstudRefreshException, OpenstudInvalidResponseException { 27 | try { 28 | if (!StringUtils.isNumeric(os.getStudentID())) 29 | throw new OpenstudRefreshException("Student ID is not valid"); 30 | String body = executeLoginRequest(); 31 | JSONObject response = new JSONObject(body); 32 | if (body.toLowerCase().contains("utenza bloccata")) throw new OpenstudRefreshException("Account is blocked").setAccountBlockedType(); 33 | if (response.has("output") && !response.isNull("output") && !response.getString("output").isEmpty()) os.setToken(response.getString("output")); 34 | if (response.has("esito")) { 35 | switch (response.getJSONObject("esito").getInt("flagEsito")) { 36 | case -6: 37 | if (response.getJSONObject("esito").getBoolean("captcha")) throw new OpenstudRefreshException("Captcha required"); 38 | else throw new OpenstudInvalidResponseException("Infostud is not working as intended"); 39 | case -4: 40 | throw new OpenstudRefreshException("User is not enabled to use Infostud service"); 41 | case -2: 42 | throw new OpenstudRefreshException("Password expired").setPasswordExpiredType(); 43 | case -1: 44 | throw new OpenstudRefreshException("Invalid credentials when refreshing token").setPasswordInvalidType(); 45 | case 0: 46 | break; 47 | default: 48 | throw new OpenstudInvalidResponseException("Infostud is not working as intended"); 49 | } 50 | } 51 | } catch (IOException | JSONException e) { 52 | os.log(Level.SEVERE, e); 53 | e.printStackTrace(); 54 | } 55 | } 56 | 57 | private String executeLoginRequest() throws IOException, OpenstudInvalidResponseException { 58 | RequestBody formBody = new FormBody.Builder() 59 | .add("key", os.getKey()).add("matricola", os.getStudentID()).add("stringaAutenticazione", os.getStudentPassword()).build(); 60 | Request req = new Request.Builder().url(String.format("%s/autenticazione", os.getEndpointAPI())).header("Accept", "application/json") 61 | .header("Content-EventType", "application/x-www-form-urlencoded").post(formBody).build(); 62 | Response resp = os.getClient().newCall(req).execute(); 63 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 64 | String body = resp.body().string(); 65 | resp.close(); 66 | if (body.contains("the page you are looking for is currently unavailable")) 67 | throw new OpenstudInvalidResponseException("InfoStud is in maintenance").setMaintenanceType(); 68 | return body; 69 | } 70 | 71 | @Override 72 | public String getSecurityQuestion() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 73 | int count = 0; 74 | if (os.getStudentID() == null) throw new OpenstudInvalidResponseException("StudentID can't be left empty"); 75 | while (true) { 76 | try { 77 | return _getSecurityQuestion(); 78 | } catch (OpenstudInvalidResponseException e) { 79 | if (e.isMaintenance()) throw e; 80 | if (++count == os.getMaxTries()) { 81 | os.log(Level.SEVERE, e); 82 | throw e; 83 | } 84 | } 85 | } 86 | } 87 | 88 | private String _getSecurityQuestion() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 89 | try { 90 | RequestBody formBody = new FormBody.Builder() 91 | .add("matricola", String.valueOf(os.getStudentID())).build(); 92 | Request req = new Request.Builder().url(String.format("%s/pwd/recuperaDomanda/matricola/", os.getEndpointAPI())).header("Accept", "application/json") 93 | .header("Content-EventType", "application/x-www-form-urlencoded").post(formBody).build(); 94 | Response resp = os.getClient().newCall(req).execute(); 95 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 96 | String body = resp.body().string(); 97 | resp.close(); 98 | if (body.contains("the page you are looking for is currently unavailable")) 99 | throw new OpenstudInvalidResponseException("InfoStud is in maintenance").setMaintenanceType(); 100 | if (body.contains("Matricola Errata")) throw new OpenstudInvalidCredentialsException("Invalid studentID"); 101 | if (body.contains("Impossibile recuperare la password per email")) return null; 102 | os.log(Level.INFO, body); 103 | JSONObject response = new JSONObject(body); 104 | if (response.isNull("risultato")) 105 | throw new OpenstudInvalidResponseException("Infostud response is not valid."); 106 | return response.getString("risultato"); 107 | } catch (IOException e) { 108 | os.log(Level.SEVERE, e); 109 | throw new OpenstudConnectionException(e); 110 | } catch (JSONException e) { 111 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e); 112 | os.log(Level.SEVERE, invalidResponse); 113 | throw invalidResponse; 114 | } 115 | } 116 | 117 | @Override 118 | public boolean recoverPassword(String answer) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudInvalidAnswerException { 119 | int count = 0; 120 | if (os.getStudentID() == null) throw new OpenstudInvalidResponseException("StudentID can't be left empty"); 121 | while (true) { 122 | try { 123 | return _recoverPassword(answer); 124 | } catch (OpenstudInvalidResponseException e) { 125 | if (e.isMaintenance()) throw e; 126 | if (++count == os.getMaxTries()) { 127 | os.log(Level.SEVERE, e); 128 | throw e; 129 | } 130 | } 131 | } 132 | } 133 | 134 | private boolean _recoverPassword(String answer) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudInvalidAnswerException { 135 | try { 136 | RequestBody formBody = new FormBody.Builder() 137 | .add("matricola", String.valueOf(os.getStudentID())).add("risposta", answer).build(); 138 | String body = executeRecoveryRequest(formBody); 139 | if (body.contains("the page you are looking for is currently unavailable")) 140 | throw new OpenstudInvalidResponseException("InfoStud is in maintenance").setMaintenanceType(); 141 | if (body.contains("Matricola Errata")) throw new OpenstudInvalidCredentialsException("Invalid studentID"); 142 | if (body.contains("Impossibile recuperare la password per email")) return false; 143 | os.log(Level.INFO, body); 144 | JSONObject response = new JSONObject(body); 145 | if (response.isNull("livelloErrore")) 146 | throw new OpenstudInvalidResponseException("Infostud response is not valid."); 147 | switch (response.getInt("livelloErrore")) { 148 | case 3: 149 | throw new OpenstudInvalidAnswerException("Answer is not correct"); 150 | case 0: 151 | break; 152 | default: 153 | throw new OpenstudInvalidResponseException("Infostud is not working as expected"); 154 | } 155 | } catch (IOException e) { 156 | os.log(Level.SEVERE, e); 157 | throw new OpenstudConnectionException(e); 158 | } catch (JSONException e) { 159 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e); 160 | os.log(Level.SEVERE, invalidResponse); 161 | throw invalidResponse; 162 | } 163 | return true; 164 | } 165 | 166 | private String executeRecoveryRequest(RequestBody formBody) throws IOException, OpenstudInvalidResponseException { 167 | Request req = new Request.Builder().url(String.format("%s/pwd/recupera/matricola", os.getEndpointAPI())).header("Accept", "application/json") 168 | .header("Content-EventType", "application/x-www-form-urlencoded").post(formBody).build(); 169 | Response resp = os.getClient().newCall(req).execute(); 170 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 171 | return resp.body().string(); 172 | } 173 | 174 | @Override 175 | public void resetPassword(String new_password) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 176 | int count = 0; 177 | if (os.getStudentID() == null) throw new OpenstudInvalidResponseException("StudentID can't be left empty"); 178 | while (true) { 179 | try { 180 | _resetPassword(new_password); 181 | break; 182 | } catch (OpenstudInvalidResponseException e) { 183 | if (++count == os.getMaxTries()) { 184 | os.log(Level.SEVERE, e); 185 | throw e; 186 | } 187 | } 188 | } 189 | } 190 | 191 | private void _resetPassword(String new_password) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 192 | try { 193 | RequestBody formBody = new FormBody.Builder() 194 | .add("oldPwd", os.getStudentPassword()) 195 | .add("newPwd", new_password) 196 | .add("confermaPwd", new_password) 197 | .build(); 198 | 199 | Request req = new Request.Builder().url(String.format("%s/pwd/%s/reset?ingresso=%s", os.getEndpointAPI(), os.getStudentID(), os.getToken())).header("Accept", "application/json") 200 | .header("Content-EventType", "application/x-www-form-urlencoded").post(formBody).build(); 201 | Response resp = os.getClient().newCall(req).execute(); 202 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 203 | String body = resp.body().string(); 204 | resp.close(); 205 | os.log(Level.INFO, body); 206 | JSONObject response = new JSONObject(body); 207 | if (response.isNull("codiceErrore") || response.isNull("risultato")) 208 | throw new OpenstudInvalidResponseException("Infostud response is not valid."); 209 | 210 | String error_code = response.getString("codiceErrore"); 211 | boolean result = response.getBoolean("risultato"); 212 | if (error_code.equals("000") && result) { 213 | os.setStudentPassword(new_password); 214 | return; 215 | } 216 | 217 | throw new OpenstudInvalidCredentialsException("Answer is not correct"); 218 | 219 | } catch (IOException e) { 220 | os.log(Level.SEVERE, e); 221 | throw new OpenstudConnectionException(e); 222 | } catch (JSONException e) { 223 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e); 224 | os.log(Level.SEVERE, invalidResponse); 225 | throw invalidResponse; 226 | } 227 | } 228 | 229 | public boolean recoverPasswordWithEmail(String email, String answer) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudInvalidAnswerException { 230 | int count = 0; 231 | if (os.getStudentID() == null) throw new OpenstudInvalidResponseException("StudentID can't be left empty"); 232 | while (true) { 233 | try { 234 | return _recoverPasswordWithEmail(email, answer); 235 | } catch (OpenstudInvalidResponseException e) { 236 | if (++count == os.getMaxTries()) { 237 | os.log(Level.SEVERE, e); 238 | throw e; 239 | } 240 | } 241 | } 242 | } 243 | 244 | private boolean _recoverPasswordWithEmail(String email, String answer) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException, OpenstudInvalidAnswerException { 245 | try { 246 | RequestBody formBody = new FormBody.Builder() 247 | .add("matricola", String.valueOf(os.getStudentID())).add("email", email).add("risposta", answer).build(); 248 | String body = executeRecoveryRequest(formBody); 249 | if (body.contains("Matricola Errata")) throw new OpenstudInvalidCredentialsException("Invalid studentID"); 250 | if (body.contains("Impossibile recuperare la password per email")) return false; 251 | os.log(Level.INFO, body); 252 | JSONObject response = new JSONObject(body); 253 | if (response.isNull("livelloErrore")) 254 | throw new OpenstudInvalidResponseException("Infostud response is not valid."); 255 | switch (response.getInt("livelloErrore")) { 256 | case 3: 257 | throw new OpenstudInvalidAnswerException("Answer is not correct"); 258 | case 0: 259 | break; 260 | default: 261 | throw new OpenstudInvalidResponseException("Infostud is not working as expected"); 262 | } 263 | } catch (IOException e) { 264 | os.log(Level.SEVERE, e); 265 | throw new OpenstudConnectionException(e); 266 | } catch (JSONException e) { 267 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e); 268 | os.log(Level.SEVERE, invalidResponse); 269 | throw invalidResponse; 270 | } 271 | return true; 272 | } 273 | 274 | 275 | public void login() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudUserNotEnabledException { 276 | int count = 0; 277 | if (os.getStudentPassword() == null || os.getStudentPassword().isEmpty()) 278 | throw new OpenstudInvalidCredentialsException("Password can't be left empty"); 279 | if (os.getStudentID() == null) throw new OpenstudInvalidResponseException("StudentID can't be left empty"); 280 | while (true) { 281 | try { 282 | _login(); 283 | break; 284 | } catch (OpenstudInvalidResponseException e) { 285 | if (++count == os.getMaxTries()) { 286 | os.log(Level.SEVERE, e); 287 | throw e; 288 | } 289 | } 290 | } 291 | } 292 | 293 | private synchronized void _login() throws OpenstudInvalidCredentialsException, OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudUserNotEnabledException { 294 | try { 295 | if (!StringUtils.isNumeric(os.getStudentID())) 296 | throw new OpenstudInvalidCredentialsException("Student ID is not valid"); 297 | String body = executeLoginRequest(); 298 | os.log(Level.INFO, body); 299 | JSONObject response = new JSONObject(body); 300 | if (response.has("output") && !response.isNull("output")) os.setToken(response.getString("output")); 301 | if (body.toLowerCase().contains("password errata")) { 302 | OpenstudInvalidCredentialsException e = new OpenstudInvalidCredentialsException("Credentials are not valid"); 303 | String out = StringUtils.substringBetween(body.toLowerCase(), "tentativo", "effettuato").trim(); 304 | if (out.contains("/")) { 305 | String[] elements = out.split("/"); 306 | try { 307 | if (elements.length == 2) { 308 | e.setAttemptNumber(Integer.parseInt(elements[0])); 309 | e.setMaxAttempts(Integer.parseInt(elements[1])); 310 | } 311 | } catch (NumberFormatException ignored) { 312 | 313 | } 314 | } 315 | throw e; 316 | } 317 | else if (body.toLowerCase().contains("utenza bloccata")) throw new OpenstudInvalidCredentialsException("Account is blocked").setAccountBlockedType(); 318 | if (response.has("output")) os.setToken(response.getString("output")); 319 | else if (!response.has("output")) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 320 | if (response.has("esito")) { 321 | switch (response.getJSONObject("esito").getInt("flagEsito")) { 322 | case -6: 323 | if (response.getJSONObject("esito").getBoolean("captcha")) throw new OpenstudInvalidCredentialsException("Captcha required"); 324 | else throw new OpenstudInvalidResponseException("Infostud is not working as intended"); 325 | case -4: 326 | throw new OpenstudUserNotEnabledException("User is not enabled to use Infostud service."); 327 | case -2: 328 | throw new OpenstudInvalidCredentialsException("Password expired").setPasswordExpiredType(); 329 | case -1: 330 | throw new OpenstudInvalidCredentialsException("Password not valid").setPasswordInvalidType(); 331 | case 0: 332 | break; 333 | default: 334 | throw new OpenstudInvalidResponseException("Infostud is not working as expected"); 335 | } 336 | } 337 | } catch (IOException e) { 338 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 339 | os.log(Level.SEVERE, connectionException); 340 | throw connectionException; 341 | } catch (JSONException e) { 342 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 343 | os.log(Level.SEVERE, invalidResponse); 344 | throw invalidResponse; 345 | } 346 | os.setReady(true); 347 | } 348 | } 349 | -------------------------------------------------------------------------------- /src/main/java/lithium/openstud/driver/core/providers/sapienza/SapienzaBioHandler.java: -------------------------------------------------------------------------------- 1 | package lithium.openstud.driver.core.providers.sapienza; 2 | 3 | import lithium.openstud.driver.core.Openstud; 4 | import lithium.openstud.driver.core.internals.BioHandler; 5 | import lithium.openstud.driver.core.models.Career; 6 | import lithium.openstud.driver.core.models.CertificateType; 7 | import lithium.openstud.driver.core.models.Student; 8 | import lithium.openstud.driver.core.models.StudentCard; 9 | import lithium.openstud.driver.exceptions.OpenstudConnectionException; 10 | import lithium.openstud.driver.exceptions.OpenstudInvalidCredentialsException; 11 | import lithium.openstud.driver.exceptions.OpenstudInvalidResponseException; 12 | import lithium.openstud.driver.exceptions.OpenstudRefreshException; 13 | import okhttp3.Request; 14 | import okhttp3.Response; 15 | import okhttp3.ResponseBody; 16 | import org.json.JSONArray; 17 | import org.json.JSONException; 18 | import org.json.JSONObject; 19 | import org.threeten.bp.LocalDateTime; 20 | import org.threeten.bp.format.DateTimeFormatter; 21 | 22 | import javax.net.ssl.SSLException; 23 | import java.io.IOException; 24 | import java.util.LinkedList; 25 | import java.util.List; 26 | import java.util.logging.Level; 27 | 28 | public class SapienzaBioHandler implements BioHandler { 29 | private Openstud os; 30 | 31 | public SapienzaBioHandler(Openstud os) { 32 | this.os = os; 33 | } 34 | 35 | @Override 36 | public Student getInfoStudent() throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 37 | if (!os.isReady()) return null; 38 | int count = 0; 39 | while (true) { 40 | try { 41 | if (count > 0) os.refreshToken(); 42 | return _getInfoStudent(); 43 | } catch (OpenstudInvalidResponseException e) { 44 | if (e.isMaintenance()) throw e; 45 | if (++count == os.getMaxTries()) { 46 | os.log(Level.SEVERE, e); 47 | throw e; 48 | } 49 | } catch (OpenstudRefreshException e) { 50 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 51 | os.log(Level.SEVERE, invalidCredentials); 52 | throw invalidCredentials; 53 | } 54 | } 55 | } 56 | 57 | 58 | @Override 59 | public byte[] getCertificatePDF(Student student, Career career, CertificateType certificate) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 60 | if (!os.isReady()) return null; 61 | int count = 0; 62 | byte[] ret; 63 | while (true) { 64 | try { 65 | if (count > 0) os.refreshToken(); 66 | ret = _getCertificatePDF(student, career, certificate); 67 | break; 68 | } catch (OpenstudInvalidResponseException e) { 69 | if (++count == os.getMaxTries()) { 70 | os.log(Level.SEVERE, e); 71 | throw e; 72 | } 73 | } catch (OpenstudRefreshException e) { 74 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 75 | os.log(Level.SEVERE, invalidCredentials); 76 | throw invalidCredentials; 77 | } 78 | } 79 | return ret; 80 | } 81 | 82 | 83 | private byte[] _getCertificatePDF(Student student, Career career, CertificateType certificate) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 84 | try { 85 | String lang = "it"; 86 | String teachingCode = ""; 87 | if (certificate == CertificateType.DEGREE_WITH_EXAMS_ENG || certificate == CertificateType.DEGREE_WITH_EVALUATION_ENG || certificate == CertificateType.DEGREE_WITH_THESIS_ENG) 88 | lang = "en"; 89 | if (career.getTeachingCode() != null) teachingCode = career.getTeachingCode(); 90 | Request req = new Request.Builder().url(String.format("%s/certificati/corsodilaurea/%s/%s/%s?ingresso=%s&codiceDidattica=%s&indiceCarriera=%s", os.getEndpointAPI(), student.getStudentID(), SapienzaHelper.getCertificateValue(certificate), lang, os.getToken(), teachingCode, career.getIndex())).build(); 91 | Response resp = os.getClient().newCall(req).execute(); 92 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 93 | String body = resp.body().string(); 94 | resp.close(); 95 | os.log(Level.INFO, body); 96 | JSONObject response = new JSONObject(body); 97 | if (!response.has("risultato")) 98 | throw new OpenstudInvalidResponseException("Infostud response is not valid. I guess the token is no longer valid"); 99 | response = response.getJSONObject("risultato"); 100 | if (!response.has("result") || response.isNull("result")) return null; 101 | response = response.getJSONObject("result"); 102 | if (!response.has("documentServerResultDTO") || response.isNull("documentServerResultDTO")) return null; 103 | response = response.getJSONObject("documentServerResultDTO"); 104 | if (response.has("pdf_file_http_path") && !response.isNull("pdf_file_http_path")) { 105 | Request request = new Request.Builder().url(response.getString("pdf_file_http_path")).build(); 106 | Response fileResponse = os.getClient().newCall(request).execute(); 107 | if (!fileResponse.isSuccessful()) { 108 | throw new IOException("Failed to download file: " + response); 109 | } 110 | if (fileResponse.body() == null) throw new IOException("Error when downloading pdf"); 111 | return fileResponse.body().bytes(); 112 | } else return null; 113 | } catch (IOException e) { 114 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 115 | os.log(Level.SEVERE, connectionException); 116 | throw connectionException; 117 | } catch (JSONException e) { 118 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 119 | os.log(Level.SEVERE, invalidResponse); 120 | throw invalidResponse; 121 | } 122 | } 123 | 124 | @Override 125 | public List getCareersChoicesForCertificate(Student student, CertificateType certificate) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 126 | if (!os.isReady()) return null; 127 | int count = 0; 128 | List ret; 129 | while (true) { 130 | try { 131 | if (count > 0) os.refreshToken(); 132 | ret = _getCareersChoicesForCertificate(student, certificate); 133 | break; 134 | } catch (OpenstudInvalidResponseException e) { 135 | if (++count == os.getMaxTries()) { 136 | os.log(Level.SEVERE, e); 137 | throw e; 138 | } 139 | } catch (OpenstudRefreshException e) { 140 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 141 | os.log(Level.SEVERE, invalidCredentials); 142 | throw invalidCredentials; 143 | } 144 | } 145 | return ret; 146 | } 147 | 148 | private List _getCareersChoicesForCertificate(Student student, CertificateType certificate) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 149 | try { 150 | Request req = new Request.Builder().url(String.format("%s/certificati/corsodilaurea/%s/listaCarriere?ingresso=%s&codiceTipoCertificato=%s", os.getEndpointAPI(), student.getStudentID(), os.getToken(), SapienzaHelper.getCertificateValue(certificate))).build(); 151 | Response resp = os.getClient().newCall(req).execute(); 152 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 153 | String body = resp.body().string(); 154 | resp.close(); 155 | os.log(Level.INFO, body); 156 | JSONObject response = new JSONObject(body); 157 | if (response.has("descrizioneErrore") && !response.isNull("descrizioneErrore") && response.getString("descrizioneErrore").toLowerCase().contains("non risultano")) 158 | return new LinkedList<>(); 159 | if (!response.has("risultatoLista")) 160 | throw new OpenstudInvalidResponseException("Infostud response is not valid. I guess the token is no longer valid"); 161 | response = response.getJSONObject("risultatoLista"); 162 | if (response == null) return new LinkedList<>(); 163 | JSONArray array = response.getJSONArray("risultati"); 164 | if (array == null) return new LinkedList<>(); 165 | List ret = new LinkedList<>(); 166 | for (int i = 0; i < array.length(); i++) { 167 | JSONObject obj = array.getJSONObject(i); 168 | Career car = new Career(); 169 | car.setIndex(i); 170 | for (String element : obj.keySet()) { 171 | switch (element) { 172 | case "codiIscr": 173 | car.setRegistrationCode(obj.getString(element)); 174 | break; 175 | case "codiCorsStud": 176 | car.setCodeCourse(obj.getString(element)); 177 | break; 178 | case "descCorsStud": 179 | car.setDescriptionComplete(obj.getString(element)); 180 | break; 181 | case "descDenoCost": 182 | car.setDescription(obj.getString(element)); 183 | break; 184 | case "descStruOrga": 185 | car.setOrganization(obj.getString(element)); 186 | break; 187 | case "descTipoTito": 188 | car.setType(obj.getString(element)); 189 | break; 190 | case "codiDida": 191 | car.setTeachingCode(obj.getString(element)); 192 | break; 193 | } 194 | } 195 | ret.add(car); 196 | } 197 | return ret; 198 | } catch (IOException e) { 199 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 200 | os.log(Level.SEVERE, connectionException); 201 | throw connectionException; 202 | } catch (JSONException e) { 203 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 204 | os.log(Level.SEVERE, invalidResponse); 205 | throw invalidResponse; 206 | } 207 | } 208 | 209 | 210 | private Student _getInfoStudent() throws OpenstudConnectionException, OpenstudInvalidResponseException { 211 | try { 212 | Request req = new Request.Builder().url(String.format("%s/studente/%s?ingresso=%s", os.getEndpointAPI(), os.getStudentID(), os.getToken())).build(); 213 | Response resp = os.getClient().newCall(req).execute(); 214 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 215 | String body = resp.body().string(); 216 | resp.close(); 217 | os.log(Level.INFO, body); 218 | JSONObject response = new JSONObject(body); 219 | if (!response.has("ritorno")) 220 | throw new OpenstudInvalidResponseException("Infostud response is not valid. I guess the token is no longer valid"); 221 | response = response.getJSONObject("ritorno"); 222 | return SapienzaHelper.extractStudent(os, response); 223 | } catch (IOException e) { 224 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 225 | os.log(Level.SEVERE, connectionException); 226 | throw connectionException; 227 | } catch (JSONException e) { 228 | OpenstudInvalidResponseException invalidResponse = new OpenstudInvalidResponseException(e).setJSONType(); 229 | os.log(Level.SEVERE, invalidResponse); 230 | throw invalidResponse; 231 | } 232 | } 233 | 234 | 235 | public byte[] getStudentPhoto(Student student) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 236 | if (!os.isReady() || student == null) return null; 237 | int count = 0; 238 | while (true) { 239 | try { 240 | if (count > 0) os.refreshToken(); 241 | byte[] ret = _getStudentPhoto(student); 242 | if (ret != null && ret.length == 0) return null; 243 | return ret; 244 | } catch (OpenstudInvalidResponseException e) { 245 | if (e.isMaintenance()) throw e; 246 | if (++count == os.getMaxTries()) { 247 | os.log(Level.SEVERE, e); 248 | throw e; 249 | } 250 | } catch (OpenstudRefreshException e) { 251 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 252 | os.log(Level.SEVERE, invalidCredentials); 253 | throw invalidCredentials; 254 | } 255 | } 256 | } 257 | 258 | private byte[] _getStudentPhoto(Student student) throws OpenstudInvalidResponseException, OpenstudConnectionException { 259 | try { 260 | Request req = new Request.Builder().url(String.format("%s/cartastudente/%s/foto?ingresso=%s", "https://www.studenti.uniroma1.it/phoenixws", student.getStudentID(), os.getToken())).build(); 261 | Response resp = os.getClient().newCall(req).execute(); 262 | byte[] ret = resp.body().bytes(); 263 | resp.close(); 264 | return ret; 265 | } catch (IOException e) { 266 | if (e instanceof SSLException) { 267 | OpenstudInvalidResponseException invalidResponseException = new OpenstudInvalidResponseException(e); 268 | invalidResponseException.setSSLType(); 269 | os.log(Level.SEVERE, invalidResponseException); 270 | throw invalidResponseException; 271 | } 272 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 273 | os.log(Level.SEVERE, connectionException); 274 | throw connectionException; 275 | } 276 | } 277 | 278 | 279 | public StudentCard getStudentCard(Student student, boolean withPhoto) throws OpenstudConnectionException, OpenstudInvalidResponseException, OpenstudInvalidCredentialsException { 280 | if (!os.isReady() || student == null) return null; 281 | int count = 0; 282 | StudentCard card; 283 | while (true) { 284 | try { 285 | if (count > 0) os.refreshToken(); 286 | card = _getStudentCard(student); 287 | break; 288 | } catch (OpenstudInvalidResponseException e) { 289 | if (e.isMaintenance()) throw e; 290 | if (++count == os.getMaxTries()) { 291 | os.log(Level.SEVERE, e); 292 | throw e; 293 | } 294 | } catch (OpenstudRefreshException e) { 295 | OpenstudInvalidCredentialsException invalidCredentials = new OpenstudInvalidCredentialsException(e); 296 | os.log(Level.SEVERE, invalidCredentials); 297 | throw invalidCredentials; 298 | } 299 | } 300 | if (card != null && withPhoto) { 301 | byte[] image = _getStudentPhoto(student); 302 | if (image != null && image.length != 0) card.setImage(image); 303 | } 304 | return card; 305 | } 306 | 307 | private StudentCard _getStudentCard(Student student) throws OpenstudInvalidResponseException, OpenstudConnectionException { 308 | try { 309 | Request req = new Request.Builder().url(String.format("%s/cartastudente/%s/info?ingresso=%s", os.getEndpointAPI(), student.getStudentID(), os.getToken())).build(); 310 | Response resp = os.getClient().newCall(req).execute(); 311 | if (resp.body() == null) throw new OpenstudInvalidResponseException("Infostud answer is not valid"); 312 | ResponseBody body = resp.body(); 313 | if (body == null) return null; 314 | String stringBody = body.string(); 315 | os.log(Level.INFO, stringBody); 316 | JSONObject response = new JSONObject(stringBody); 317 | if (!response.has("ritorno")) 318 | throw new OpenstudInvalidResponseException("Infostud response is not valid. I guess the token is no longer valid"); 319 | response = response.getJSONObject("ritorno"); 320 | if (!response.has("carte")) 321 | throw new OpenstudInvalidResponseException("Infostud response is not valid. I guess the token is no longer valid"); 322 | JSONArray array = response.getJSONArray("carte"); 323 | List cards = new LinkedList<>(); 324 | for (int i = 0; i < array.length(); i++) { 325 | JSONObject obj = array.getJSONObject(i); 326 | StudentCard card = new StudentCard(); 327 | for (String element : obj.keySet()) { 328 | switch (element) { 329 | case "codice": 330 | card.setCode(obj.getString(element)); 331 | break; 332 | case "matricola": 333 | card.setStudentId(String.valueOf(obj.getInt(element))); 334 | break; 335 | case "stato": 336 | if (obj.getString(element).toLowerCase().equals("attiva")) card.setEnabled(true); 337 | break; 338 | case "dataRichiesta": 339 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); 340 | card.setIssueDate(LocalDateTime.parse(obj.getString(element), formatter)); 341 | break; 342 | } 343 | } 344 | cards.add(card); 345 | } 346 | StudentCard ret = null; 347 | for (StudentCard card: cards){ 348 | if (card.getCode()!=null && card.isEnabled()) { 349 | if (ret == null) ret = card; 350 | else { 351 | if (ret.getIssueDate()!= null && card.getIssueDate() != null && ret.getIssueDate().isBefore(card.getIssueDate())) { 352 | ret = card; 353 | } 354 | } 355 | } 356 | } 357 | return ret; 358 | } catch (IOException e) { 359 | OpenstudConnectionException connectionException = new OpenstudConnectionException(e); 360 | os.log(Level.SEVERE, connectionException); 361 | throw connectionException; 362 | } 363 | } 364 | } 365 | --------------------------------------------------------------------------------