Skip to content

Commit

Permalink
Merge pull request #141 from EATSTEAK/dev
Browse files Browse the repository at this point in the history
[release] 0.8.0
  • Loading branch information
EATSTEAK authored Dec 18, 2024
2 parents a8364af + 39b92e2 commit 47b323e
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 50 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
name: Build & Test

on:
workflow_dispatch:
pull_request:
branches: ["main", "dev"]
branches: [ "main", "dev" ]
schedule:
- cron: "23 3 * * *"
env:
Expand All @@ -14,6 +15,8 @@ jobs:
env:
SSO_ID: ${{ vars.SSO_ID }}
SSO_PASSWORD: ${{ secrets.SSO_PASSWORD }}
TARGET_YEAR: ${{ vars.TARGET_YEAR }}
TARGET_SEMESTER: ${{ vars.TARGET_SEMESTER }}
steps:
- uses: actions/checkout@v4
- name: Setup Rust
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/dry-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Dry-run before publish

on:
pull_request:
branches: ["main"]
branches: [ "main" ]
env:
CARGO_TERM_COLOR: always
jobs:
Expand All @@ -12,6 +12,8 @@ jobs:
env:
SSO_ID: ${{ vars.SSO_ID }}
SSO_PASSWORD: ${{ secrets.SSO_PASSWORD }}
TARGET_YEAR: ${{ vars.TARGET_YEAR }}
TARGET_SEMESTER: ${{ vars.TARGET_SEMESTER }}
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = ["packages/rusaint", "packages/rusaint-ffi", "uniffi-bindgen"]
resolver = "2"

[workspace.package]
version = "0.7.4"
version = "0.8.0"

keywords = ["ssu", "u-saint", "scraping", "parser"]
authors = ["Hyomin Koo <me@eatsteak.dev>"]
Expand All @@ -14,5 +14,5 @@ edition = "2021"
readme = "README.md"

[workspace.dependencies]
thiserror = "1.0.44"
thiserror = "2.0.8"
tokio = { version = "1.29.1" }
2 changes: 1 addition & 1 deletion languages/kotlin/lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ plugins {

group = "dev.eatsteak"
description = "Easy and Reliable SSU u-saint scraper"
version = "0.7.4"
version = "0.8.0"

android {
namespace = "dev.eatsteak.rusaint"
Expand Down
4 changes: 2 additions & 2 deletions packages/rusaint-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ crate-type = ["lib", "cdylib", "staticlib"]
name = "rusaint_ffi"

[dependencies]
uniffi = { version = "0.28.1", features = ["tokio"] }
uniffi = { version = "0.28.3", features = ["tokio"] }
rusaint = { path = "../rusaint", features = ["uniffi"] }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["sync"] }

[build-dependencies]
uniffi = { version = "0.28.1", features = ["build"] }
uniffi = { version = "0.28.3", features = ["build"] }
4 changes: 2 additions & 2 deletions packages/rusaint-ffi/src/application/course_grades.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl CourseGradesApplication {
pub async fn classes(
&self,
course_type: CourseType,
year: &str,
year: u32,
semester: SemesterType,
include_details: bool,
) -> Result<Vec<ClassGrade>, RusaintError> {
Expand All @@ -68,7 +68,7 @@ impl CourseGradesApplication {
pub async fn class_detail(
&self,
course_type: CourseType,
year: &str,
year: u32,
semester: SemesterType,
code: &str,
) -> Result<HashMap<String, f32>, RusaintError> {
Expand Down
12 changes: 6 additions & 6 deletions packages/rusaint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ application = ["element"]
uniffi = ["dep:uniffi", "application"]

[dependencies]
uniffi = { version = "0.28.1", optional = true }
derive_builder = "0.20.0"
reqwest = { version = "0.12.7", features = [
uniffi = { version = "0.28.3", optional = true }
derive_builder = "0.20.2"
reqwest = { version = "0.12.9", features = [
"charset",
"http2",
"macos-system-configuration",
Expand All @@ -33,10 +33,10 @@ reqwest = { version = "0.12.7", features = [
thiserror = { workspace = true }
tokio = { workspace = true, features = ["sync"] }
html-escape = "0.2.13"
url = "2.5.2"
url = "2.5.4"
roxmltree = "0.20.0"
lol_html = "1.2.1"
scraper = { version = "0.20.0", features = ["atomic"], optional = true }
scraper = { version = "0.22.0", features = ["atomic"], optional = true }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
custom_debug_derive = "0.6.1"
Expand All @@ -52,4 +52,4 @@ tokio-test = "0.4.4"
tokio = { workspace = true, features = ["macros", "test-util"] }

[build-dependencies]
uniffi = { version = "0.28.1", features = ["build"] }
uniffi = { version = "0.28.3", features = ["build"] }
18 changes: 10 additions & 8 deletions packages/rusaint/src/application/course_grades/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ impl<'a> CourseGradesApplication {
/// # use rusaint::model::SemesterType;
/// # let session = Arc::new(USaintSession::with_password("20212345", "password").await.unwrap());
/// let mut app = USaintClientBuilder::new().session(session).build_into::<CourseGradesApplication>().await.unwrap();
/// let classes = app.classes(CourseType::Bachelor, "2022", SemesterType::Two, false).await.unwrap();
/// let classes = app.classes(CourseType::Bachelor, 2022, SemesterType::Two, false).await.unwrap();
/// println!("{:?}", classes); // around 3s(depends on network environment)
/// // [ClassGrade { ... }, ClassGrade { ... }]
/// # })
Expand All @@ -377,23 +377,24 @@ impl<'a> CourseGradesApplication {
/// # use rusaint::application::USaintClientBuilder;
/// # let session = Arc::new(USaintSession::with_password("20212345", "password").await.unwrap());
/// let mut app = USaintClientBuilder::new().session(session).build_into::<CourseGradesApplication>().await.unwrap();
/// let classes = app.classes(CourseType::Bachelor, "2022", SemesterType::Two, true).await.unwrap();
/// let classes = app.classes(CourseType::Bachelor, 2022, SemesterType::Two, true).await.unwrap();
/// println!("{:?}", classes); // around 10s(depends on network environment)
/// // [ClassGrade { ... }, ClassGrade { ... }]
/// # })
/// ```
pub async fn classes(
&mut self,
course_type: CourseType,
year: &str,
year: u32,
semester: SemesterType,
include_details: bool,
) -> Result<Vec<ClassGrade>, RusaintError> {
let year = year.to_string();
{
self.close_popups().await?;
let parser = ElementParser::new(self.client.body());
self.select_course(&parser, course_type).await?;
self.select_semester(&parser, year, semester).await?;
self.select_semester(&parser, &year, semester).await?;
}
let parser = ElementParser::new(self.client.body());
let class_grades: Vec<(Option<Event>, HashMap<String, String>)> = {
Expand Down Expand Up @@ -461,25 +462,26 @@ impl<'a> CourseGradesApplication {
/// # use rusaint::application::USaintClientBuilder;
/// # let session = Arc::new(USaintSession::with_password("20212345", "password").await.unwrap());
/// let mut app = USaintClientBuilder::new().session(session).build_into::<CourseGradesApplication>().await.unwrap();
/// let classes = app.classes(CourseType::Bachelor, "2022", SemesterType::Two, false).await.unwrap();
/// let classes = app.classes(CourseType::Bachelor, 2022, SemesterType::Two, false).await.unwrap();
/// let class = classes.iter().next().unwrap();
/// let class_detail = app.class_detail(CourseType::Bachelor, "2022", SemesterType::Two, class.code()).await.unwrap();
/// let class_detail = app.class_detail(CourseType::Bachelor, 2022, SemesterType::Two, class.code()).await.unwrap();
/// println!("{:?}", class_detail);
/// // {"출석(20.000)": 20.0, "중간고사(30.000)": 30.0, "과제(20.000)": 20.0, "기말고사(30.000)": 28.0}
/// # })
/// ```
pub async fn class_detail(
&mut self,
course_type: CourseType,
year: &str,
year: u32,
semester: SemesterType,
code: &str,
) -> Result<HashMap<String, f32>, RusaintError> {
let year = year.to_string();
{
self.close_popups().await?;
let parser = ElementParser::new(self.client.body());
self.select_course(&parser, course_type).await?;
self.select_semester(&parser, year, semester).await?;
self.select_semester(&parser, &year, semester).await?;
}
let parser = ElementParser::new(self.client.body());
let table = parser.read(SapTableBodyCommand::new(Self::GRADE_BY_CLASSES_TABLE))?;
Expand Down
42 changes: 39 additions & 3 deletions packages/rusaint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,10 @@ pub mod global_test_utils {
use dotenv::dotenv;
use std::sync::{Arc, OnceLock};

use crate::USaintSession;

pub static SESSION: OnceLock<Arc<USaintSession>> = OnceLock::new();
use crate::{model::SemesterType, USaintSession};

pub async fn get_session() -> Result<Arc<USaintSession>> {
static SESSION: OnceLock<Arc<USaintSession>> = OnceLock::new();
if let Some(session) = SESSION.get() {
Ok(session.to_owned())
} else {
Expand All @@ -106,4 +105,41 @@ pub mod global_test_utils {
.ok_or(Error::msg("Session is not initsiated"))
}
}

#[cfg(feature = "application")]
pub async fn get_year() -> Result<i32> {
static TARGET_YEAR: OnceLock<i32> = OnceLock::new();
if let Some(year) = TARGET_YEAR.get() {
Ok(*year)
} else {
let year = std::env::var("TARGET_YEAR")?.parse()?;
let _ = TARGET_YEAR.set(year);
TARGET_YEAR
.get()
.copied()
.ok_or(Error::msg("Year is not initsiated"))
}
}

#[cfg(feature = "application")]
pub fn get_semester() -> Result<SemesterType> {
static TARGET_SEMESTER: OnceLock<SemesterType> = OnceLock::new();
if let Some(semester) = TARGET_SEMESTER.get() {
Ok(*semester)
} else {
let semester = std::env::var("TARGET_SEMESTER")?;
let semester_type = match semester.to_uppercase().as_str() {
"1" | "ONE" => SemesterType::One,
"SUMMER" => SemesterType::Summer,
"2" | "TWO" => SemesterType::Two,
"WINTER" => SemesterType::Winter,
_ => return Err(Error::msg("Invalid semester")),
};
let _ = TARGET_SEMESTER.set(semester_type);
TARGET_SEMESTER
.get()
.copied()
.ok_or(Error::msg("Semester is not initsiated"))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct SapTableBody {
}

impl<'a> SapTableBody {
/// TODO: Implement unit test for rowspan/colspan handling
pub(super) fn new(
table_def: SapTableDef,
elem_ref: ElementRef<'a>,
Expand Down Expand Up @@ -96,7 +97,7 @@ impl<'a> SapTableBody {
if rowspan > 1 {
spans.insert(col_counter, (cell.clone(), rowspan, colspan));
}
for _ in 0..rowspan {
for _ in 0..colspan {
cells.push(cell.clone());
col_counter += 1;
}
Expand Down
12 changes: 7 additions & 5 deletions packages/rusaint/tests/application/chapel.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::{get_semester, get_session, get_year};
use rusaint::model::SemesterType;
use rusaint::{
application::{chapel::ChapelApplication, USaintClientBuilder},
model::SemesterType,
ApplicationError, RusaintError,
};
use serial_test::serial;

use crate::get_session;

#[tokio::test]
#[serial]
async fn chapel() {
Expand All @@ -16,7 +15,10 @@ async fn chapel() {
.build_into::<ChapelApplication>()
.await
.unwrap();
let info = app.information(2022, SemesterType::Two).await.unwrap();
let info = app
.information(get_year().unwrap(), get_semester().unwrap())
.await
.unwrap();
println!("{:?}", info);
}

Expand All @@ -29,7 +31,7 @@ async fn no_chapel() {
.build_into::<ChapelApplication>()
.await
.unwrap();
let info = app.information(2024, SemesterType::Two).await.unwrap_err();
let info = app.information(2017, SemesterType::Two).await.unwrap_err();
assert!(matches!(
info,
RusaintError::ApplicationError(ApplicationError::NoChapelInformation)
Expand Down
22 changes: 12 additions & 10 deletions packages/rusaint/tests/application/course_grades.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use rusaint::{
application::{
course_grades::{model::CourseType, CourseGradesApplication},
USaintClientBuilder,
},
model::SemesterType,
use rusaint::application::{
course_grades::{model::CourseType, CourseGradesApplication},
USaintClientBuilder,
};
use serial_test::serial;

use crate::get_session;
use crate::{get_semester, get_session, get_year};

#[tokio::test]
#[serial]
Expand Down Expand Up @@ -67,7 +64,12 @@ async fn classes_with_detail() {
.await
.unwrap();
let details = app
.classes(CourseType::Bachelor, "2022", SemesterType::Two, true)
.classes(
CourseType::Bachelor,
get_year().unwrap(),
get_semester().unwrap(),
true,
)
.await
.unwrap();
println!("{:?}", details);
Expand All @@ -80,8 +82,8 @@ async fn classes_with_detail() {
let detail = app
.class_detail(
CourseType::Bachelor,
"2022",
SemesterType::Two,
get_year().unwrap(),
get_semester().unwrap(),
detail_code.code(),
)
.await
Expand Down
12 changes: 7 additions & 5 deletions packages/rusaint/tests/application/personal_course_schedule.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use crate::{get_semester, get_session, get_year};
use rusaint::model::SemesterType;
use rusaint::{
application::{
personal_course_schedule::PersonalCourseScheduleApplication, USaintClientBuilder,
},
model::SemesterType,
ApplicationError, RusaintError,
};
use serial_test::serial;

use crate::get_session;

#[tokio::test]
#[serial]
async fn schedule() {
Expand All @@ -18,7 +17,10 @@ async fn schedule() {
.build_into::<PersonalCourseScheduleApplication>()
.await
.unwrap();
let info = app.schedule(2022, SemesterType::Two).await.unwrap();
let info = app
.schedule(get_year().unwrap(), get_semester().unwrap())
.await
.unwrap();
println!("{:?}", info);
}

Expand All @@ -31,7 +33,7 @@ async fn no_schedule() {
.build_into::<PersonalCourseScheduleApplication>()
.await
.unwrap();
let info = app.schedule(2024, SemesterType::Two).await.unwrap_err();
let info = app.schedule(2017, SemesterType::Two).await.unwrap_err();
assert!(matches!(
info,
RusaintError::ApplicationError(ApplicationError::NoScheduleInformation)
Expand Down
Loading

0 comments on commit 47b323e

Please sign in to comment.