1
- // deno run --allow-all scrape.ts <UqZBpD3n > <jlinksessionidx> <quarter >
1
+ // deno run --allow-all scrape.ts <quarter > <jlinksessionidx> <itscookie >
2
2
3
3
import { join as joinPath } from 'std/path/mod.ts'
4
4
import { ExamCodes , InstructionCodes } from './meeting-types.ts'
@@ -74,28 +74,24 @@ export interface RawGetClassResult extends CommonRawSectionResult {
74
74
}
75
75
76
76
type ScraperOptions = {
77
- /** The `jlinksessionidx` cookie */
78
- jlinksessionidx ?: string
79
- /** The `UqZBpD3n` cookie */
80
- UqZBpD3n ?: string
77
+ /** The cookie header used to authenticate WebReg requests. */
78
+ cookie ?: string
81
79
/** The path to cache WebReg response data in */
82
80
cachePath ?: string | null
83
81
}
84
82
85
83
/** Scrapes courses and sections from WebReg. */
86
84
export class Scraper {
87
85
#term: string
88
- #sessionIndex?: string
89
- #uqz?: string
86
+ #cookie?: string
90
87
#cachePath: string | null
91
88
92
89
constructor (
93
90
term : string ,
94
- { jlinksessionidx , UqZBpD3n , cachePath = null } : ScraperOptions = { }
91
+ { cookie , cachePath = null } : ScraperOptions = { }
95
92
) {
96
93
this . #term = term
97
- this . #sessionIndex = jlinksessionidx
98
- this . #uqz = UqZBpD3n
94
+ this . #cookie = cookie
99
95
this . #cachePath = cachePath
100
96
}
101
97
@@ -122,11 +118,7 @@ export class Scraper {
122
118
`https://act.ucsd.edu/webreg2/svc/wradapter/secure/${ path } ?${ new URLSearchParams (
123
119
query
124
120
) } `,
125
- {
126
- headers : {
127
- Cookie : `jlinksessionidx=${ this . #sessionIndex} ; UqZBpD3n=${ this . #uqz} `
128
- }
129
- }
121
+ { headers : { Cookie : this . #cookie ?? '' } }
130
122
) . then ( response =>
131
123
response . ok
132
124
? response . json ( )
@@ -507,6 +499,11 @@ export class Group extends BaseGroup<RawSearchLoadGroupDataResult> {
507
499
* Whether the section can be enrolled directly. This should reflect whether
508
500
* the button says "Enroll" (true) or "Waitlist" (false) on WebReg. False if
509
501
* `plannable` is false.
502
+ *
503
+ * NOTE: `waitlist` can be greater than 0 even when `enrollable` is true. This
504
+ * can happen if the course capacity was just increased, so students haven't
505
+ * been let off the waitlist yet, but there would still be seats available
506
+ * after everyone is off the waitlist.
510
507
*/
511
508
enrollable : boolean
512
509
@@ -703,16 +700,17 @@ export class ScheduleSection extends BaseGroup<RawGetClassResult> {
703
700
}
704
701
705
702
if ( import . meta. main ) {
706
- const [ UqZBpD3n , jlinksessionidx , quarter ] = Deno . args
703
+ // There might be multiple itscookies; try the last one first
704
+ const [ quarter , jlinksessionidx , itscookie ] = Deno . args
707
705
const getter = new Scraper ( quarter , {
708
- jlinksessionidx,
709
- UqZBpD3n,
706
+ cookie : `jlinksessionidx=${ jlinksessionidx } ; itscookie=${ itscookie } ;` ,
710
707
cachePath : 'cache-' + quarter . toLowerCase ( )
711
708
} )
712
709
const courses = [ ]
713
710
// const freq: Record<number, number> = {}
714
711
const examples : Record < number , string > = { }
715
712
// let count = 0
713
+ console . log ( '## Lower division (0xx)\n' )
716
714
for await ( const course of getter . allCourses ( ) ) {
717
715
courses . push ( course )
718
716
// if (course.hundred <= 1) {
@@ -727,6 +725,27 @@ if (import.meta.main) {
727
725
// }
728
726
// }
729
727
// }
728
+ if ( course . hundred !== 0 ) {
729
+ continue
730
+ }
731
+ const enrollable = course . groups . filter (
732
+ group =>
733
+ group . enrollable &&
734
+ group . capacity !== Infinity &&
735
+ group . enrolled + group . waitlist < group . capacity
736
+ )
737
+ if ( enrollable . length > 0 ) {
738
+ console . log (
739
+ `- **${ course . code } **: ${ enrollable
740
+ . map (
741
+ group =>
742
+ `${ group . code } (${ group . enrolled + group . waitlist } /${
743
+ group . capacity === Infinity ? '∞' : group . capacity
744
+ } )`
745
+ )
746
+ . join ( ' · ' ) } `
747
+ )
748
+ }
730
749
for ( const group of course . groups ) {
731
750
// freq[group.raw.DAY_CODE.length] ??= 0
732
751
// freq[group.raw.DAY_CODE.length]++
@@ -735,23 +754,38 @@ if (import.meta.main) {
735
754
// }
736
755
// Get list of lectures that meet on Friday
737
756
if ( group . time ?. days . includes ( 5 ) && ! group . isExam ( ) ) {
738
- console . log (
739
- `${ course . code } ${ group . code } ${ group . type } on ${ group . time . days } `
740
- )
741
- }
742
- if (
743
- ! group . isExam ( ) &&
744
- group . plannable &&
745
- group . time ?. location ?. building === 'RCLAS'
746
- ) {
747
- // count++
748
757
// console.log(
749
- // `${course.code} ${group.code} ${group.enrolled}/${
750
- // group.capacity
751
- // } WL ${group.waitlist} ${group.enrollable ? '✔️' : '❌'}`
758
+ // `${course.code} ${group.code} ${group.type} on ${group.time.days}`
752
759
// )
753
760
}
761
+ if ( group . enrollable ) {
762
+ // count++
763
+ }
764
+ }
765
+ }
766
+ // console.log(examples)
767
+ console . log ( '\n## Upper division (1xx)\n' )
768
+ for ( const course of courses ) {
769
+ if ( course . hundred !== 1 ) {
770
+ continue
771
+ }
772
+ const enrollable = course . groups . filter (
773
+ group =>
774
+ group . enrollable &&
775
+ group . capacity !== Infinity &&
776
+ group . enrolled + group . waitlist < group . capacity
777
+ )
778
+ if ( enrollable . length > 0 ) {
779
+ console . log (
780
+ `- **${ course . code } **: ${ enrollable
781
+ . map (
782
+ group =>
783
+ `${ group . code } (${ group . enrolled + group . waitlist } /${
784
+ group . capacity === Infinity ? '∞' : group . capacity
785
+ } )`
786
+ )
787
+ . join ( ' · ' ) } `
788
+ )
754
789
}
755
790
}
756
- console . log ( examples )
757
791
}
0 commit comments