-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: updater-scripts #733
Draft
adit-bala
wants to merge
29
commits into
gql
Choose a base branch
from
feat-updater-scripts
base: gql
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 15 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
90145f5
base section script
adit-bala 101301a
modularize data fetching
adit-bala f523109
new `Course` & `Class` Schema
adit-bala 7099aac
`courseParser` & `classParser`
adit-bala 7f4e9c9
Merge branch 'gql' into feat-updater-scripts
mathhulk 537af49
don't use terms for `course` api
adit-bala 7b9b141
add batching from @mathhulk
adit-bala e8a0f2b
insert results into the database
adit-bala 3f81826
only delete relevant objects
adit-bala d43c524
add mongodb loader
adit-bala edc75d1
update optional fields for `course`
adit-bala a0a6122
don't include invalid data
adit-bala 1d6f78f
simplify `course` and `class`
adit-bala ff86b7c
add required fields for section
adit-bala e7838e9
add testing script
adit-bala c2e46aa
init infra changes
adit-bala 469e691
denote required fields in typescript
adit-bala 676a797
decouple `datapuller` infra
adit-bala 57e1931
feat: log total errors for datapuller
adit-bala 9867932
rm dependecy
adit-bala a0e165c
fix: keep `datapuller` infra in `app`
adit-bala 85d99ba
chore: migrate logic to one file
adit-bala 489859d
chore: add encrypted env vars
adit-bala d8d099d
Merge branch 'gql' into feat-updater-scripts
adit-bala ad36e05
feat: logging + cleanup of logs
adit-bala c4b729a
fix: error types
adit-bala e4d8e4a
chore: more detailed logging
adit-bala 93adeab
fix: proper define
adit-bala 5a2f5ee
fix: remove `dev` check
adit-bala File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import mongoose from "mongoose"; | ||
|
||
import { Config } from "../../config"; | ||
|
||
// Close the Mongoose default connection is the event of application termination | ||
process.on("SIGINT", async () => { | ||
await mongoose.connection.close(); | ||
process.exit(0); | ||
}); | ||
|
||
// Your Mongoose setup goes here | ||
export default async (config: Config): Promise<mongoose.Mongoose> => { | ||
// Connect to MongoDB | ||
config.log.info("Connecting to MongoDB..."); | ||
const connection = await mongoose.connect(config.mongoDB.uri); | ||
|
||
// Log when the connection is established | ||
mongoose.connection.on("connected", () => { | ||
config.log.info("MongoDB connection established successfully"); | ||
}); | ||
|
||
// Log any errors during the connection | ||
mongoose.connection.on("error", (err) => { | ||
config.log.error("MongoDB connection error:", err); | ||
}); | ||
|
||
// Log when the connection is disconnected | ||
mongoose.connection.on("disconnected", () => { | ||
config.log.info("MongoDB connection disconnected"); | ||
}); | ||
|
||
return connection; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { IClassItem, NewClassModel } from "@repo/common"; | ||
import { ClassesAPI } from "@repo/sis-api/classes"; | ||
|
||
import { Config } from "./config"; | ||
import setup from "./shared"; | ||
import mapClassToNewClass, { CombinedClass } from "./shared/classParser"; | ||
import { fetchActiveTerms, fetchPaginatedData } from "./shared/utils"; | ||
|
||
export async function updateClasses(config: Config) { | ||
const log = config.log; | ||
const classesAPI = new ClassesAPI(); | ||
|
||
log.info("Fetching Active Terms"); | ||
const activeTerms = await fetchActiveTerms(log, { | ||
app_id: config.sis.TERM_APP_ID, | ||
app_key: config.sis.TERM_APP_KEY, | ||
}); | ||
|
||
log.info(activeTerms); | ||
|
||
const classes = await fetchPaginatedData<IClassItem, CombinedClass>( | ||
log, | ||
classesAPI.v1, | ||
activeTerms, | ||
"getClassesUsingGet", | ||
{ | ||
app_id: config.sis.CLASS_APP_ID, | ||
app_key: config.sis.CLASS_APP_KEY, | ||
}, | ||
(data) => data.apiResponse.response.classes || [], | ||
mapClassToNewClass | ||
); | ||
|
||
log.info("Example Class:", classes[0]); | ||
|
||
await NewClassModel.deleteMany({ | ||
"session.term.id": { $in: activeTerms }, | ||
}); | ||
|
||
// Insert classes in batches of 5000 | ||
const insertBatchSize = 5000; | ||
|
||
for (let i = 0; i < classes.length; i += insertBatchSize) { | ||
const batch = classes.slice(i, i + insertBatchSize); | ||
|
||
console.log(`Inserting batch ${i / insertBatchSize + 1}...`); | ||
|
||
await NewClassModel.insertMany(batch, { ordered: false }); | ||
} | ||
|
||
console.log(`Completed updating database with new class data.`); | ||
|
||
log.info(`Updated ${classes.length} classes for active terms`); | ||
} | ||
|
||
const initialize = async () => { | ||
const { config } = await setup(); | ||
try { | ||
config.log.info("\n=== UPDATE CLASSES ==="); | ||
await updateClasses(config); | ||
} catch (error) { | ||
config.log.error(error); | ||
process.exit(1); | ||
} | ||
|
||
process.exit(0); | ||
}; | ||
|
||
initialize(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,59 @@ | ||
import { TermModel } from "@repo/common"; | ||
import { ClassesAPI } from "@repo/sis-api/classes"; | ||
import { ICourseItem, NewCourseModel } from "@repo/common"; | ||
import { CoursesAPI } from "@repo/sis-api/courses"; | ||
import { TermsAPI } from "@repo/sis-api/terms"; | ||
|
||
import { Config } from "./config"; | ||
import setup from "./shared"; | ||
import mapCourseToNewCourse, { CombinedCourse } from "./shared/courseParser"; | ||
import { fetchPaginatedData } from "./shared/utils"; | ||
|
||
async function main() { | ||
const { log } = setup(); | ||
|
||
// Terms API example | ||
const termsAPI = new TermsAPI(); | ||
export async function updateCourses(config: Config) { | ||
const log = config.log; | ||
const coursesAPI = new CoursesAPI(); | ||
|
||
await termsAPI.v2.getByTermsUsingGet( | ||
const courses = await fetchPaginatedData<ICourseItem, CombinedCourse>( | ||
log, | ||
coursesAPI.v4, | ||
null, | ||
"findCourseCollectionUsingGet", | ||
{ | ||
"temporal-position": "Current", | ||
app_id: config.sis.COURSE_APP_ID, | ||
app_key: config.sis.COURSE_APP_KEY, | ||
}, | ||
{ | ||
headers: { | ||
app_id: "123", | ||
app_key: "abc", | ||
}, | ||
} | ||
(data) => data.apiResponse.response.courses || [], | ||
mapCourseToNewCourse | ||
); | ||
|
||
// Courses API example | ||
const coursesAPI = new CoursesAPI(); | ||
log.info("Example Course:", courses[0]); | ||
|
||
await NewCourseModel.deleteMany({}); | ||
|
||
await coursesAPI.v4.findCourseCollectionUsingGet({ | ||
"last-updated-since": "2021-01-01", | ||
}); | ||
// Insert courses in batches of 5000 | ||
const insertBatchSize = 5000; | ||
|
||
// Classes API example | ||
const classesAPI = new ClassesAPI(); | ||
for (let i = 0; i < courses.length; i += insertBatchSize) { | ||
const batch = courses.slice(i, i + insertBatchSize); | ||
|
||
await classesAPI.v1.getClassesUsingGet({ | ||
"term-id": "123", | ||
}); | ||
console.log(`Inserting batch ${i / insertBatchSize + 1}...`); | ||
|
||
log.info(TermModel); | ||
await NewCourseModel.insertMany(batch, { ordered: false }); | ||
} | ||
|
||
console.log(`Completed updating database with new course data.`); | ||
|
||
log.info(`Updated ${courses.length} courses for active terms`); | ||
} | ||
|
||
main(); | ||
const initialize = async () => { | ||
const { config } = await setup(); | ||
try { | ||
config.log.info("\n=== UPDATE COURSES ==="); | ||
await updateCourses(config); | ||
} catch (error) { | ||
config.log.error(error); | ||
process.exit(1); | ||
} | ||
|
||
process.exit(0); | ||
}; | ||
|
||
initialize(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { updateClasses } from "./class"; | ||
import { updateCourses } from "./course"; | ||
import { updateSections } from "./section"; | ||
import setup from "./shared"; | ||
|
||
const runDatapuller = async () => { | ||
const { config } = await setup(); | ||
try { | ||
config.log.info("\n=== UPDATE COURSES ==="); | ||
await updateCourses(config); | ||
|
||
config.log.info("\n=== UPDATE SECTIONS ==="); | ||
await updateSections(config); | ||
|
||
config.log.info("\n=== UPDATE CLASSES ==="); | ||
await updateClasses(config); | ||
|
||
config.log.info("\n=== DATA PULLING COMPLETED ==="); | ||
} catch (error) { | ||
config.log.error(error); | ||
process.exit(1); | ||
} | ||
|
||
process.exit(0); | ||
}; | ||
|
||
runDatapuller(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { ISectionItem, NewSectionModel } from "@repo/common"; | ||
import { ClassSection, ClassesAPI } from "@repo/sis-api/classes"; | ||
|
||
import { Config } from "./config"; | ||
import setup from "./shared"; | ||
import mapSectionToNewSection from "./shared/sectionParser"; | ||
import { fetchActiveTerms, fetchPaginatedData } from "./shared/utils"; | ||
|
||
export async function updateSections(config: Config) { | ||
const log = config.log; | ||
const classesAPI = new ClassesAPI(); | ||
|
||
log.info("Fetching Active Terms"); | ||
const activeTerms = await fetchActiveTerms(log, { | ||
app_id: config.sis.TERM_APP_ID, | ||
app_key: config.sis.TERM_APP_KEY, | ||
}); | ||
|
||
log.info(activeTerms); | ||
|
||
const sections = await fetchPaginatedData<ISectionItem, ClassSection>( | ||
log, | ||
classesAPI.v1, | ||
activeTerms, | ||
"getClassSectionsUsingGet", | ||
{ | ||
app_id: config.sis.CLASS_APP_ID, | ||
app_key: config.sis.CLASS_APP_KEY, | ||
}, | ||
(data) => data.apiResponse.response.classSections || [], | ||
mapSectionToNewSection | ||
); | ||
|
||
log.info("Example Section:", sections[0]); | ||
|
||
await NewSectionModel.deleteMany({}); | ||
adit-bala marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Insert sections in batches of 5000 | ||
const insertBatchSize = 5000; | ||
|
||
for (let i = 0; i < sections.length; i += insertBatchSize) { | ||
const batch = sections.slice(i, i + insertBatchSize); | ||
|
||
console.log(`Inserting batch ${i / insertBatchSize + 1}...`); | ||
|
||
await NewSectionModel.insertMany(batch, { ordered: false }); | ||
} | ||
|
||
console.log(`Completed updating database with new section data.`); | ||
|
||
log.info(`Updated ${sections.length} sections for active terms`); | ||
} | ||
|
||
const initialize = async () => { | ||
const { config } = await setup(); | ||
try { | ||
config.log.info("\n=== UPDATE SECTIONS ==="); | ||
await updateSections(config); | ||
} catch (error) { | ||
config.log.error(error); | ||
process.exit(1); | ||
} | ||
|
||
process.exit(0); | ||
}; | ||
|
||
initialize(); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just leaving this here, but we should probably do some testing on
hozer
to determine the final batch size. It all depends on amount of memory, etc.