@ -3,13 +3,25 @@ import { ID } from "../types.d.ts";
import {
DOMParser ,
} from "https://denopkg.dev/gh/Ruthenic/deno-dom@master/deno-dom-wasm.ts" ;
import { HTMLDocument } from "../types.d.ts" ;
import Search , { SearchParameters } from "./Search.ts" ;
import {
CookieJar ,
wrapFetch ,
} from "https://deno.land/x/another_cookiejar@v5.0.1/mod.ts" ;
export default class AO3 {
session : {
get : ( path : string ) = > Promise < Response > ;
post : (
path : string ,
payload : Record < string , any > ,
) = > Promise < Response > ;
} ;
DOMParser = new DOMParser ( ) ;
fetch : typeof fetch ;
cookieJar : CookieJar ;
# headers : Record < string , any > ;
/ * *
* a representation of AO3 in class form
@ -17,15 +29,40 @@ export default class AO3 {
constructor ( opts ? : {
url? : string ;
} ) {
this . cookieJar = new CookieJar ( ) ;
this . fetch = wrapFetch ( { cookieJar : this.cookieJar } ) ;
this . # headers = {
"User-Agent" :
"Mozilla/5.0 (Windows NT 10.0; rv:108.0) Gecko/20100101 Firefox/108.0" ,
} ;
this . session = {
get : async ( path : string ) = > {
const res = await fetch (
const res = await this . fetch (
opts ? . url ? ? "https://archiveofourown.org/" + path ,
{
headers : {
"User-Agent" :
"Mozilla/5.0 (Windows NT 10.0; rv:106.0) Gecko/20100101 Firefox/106.0" ,
} ,
headers : this. # headers ,
} ,
) ;
if ( res . status > 300 ) {
console . log ( res ) ;
throw new Error ( "Failed request, probably rate-limited" ) ;
}
return res ;
} ,
post : async (
path : string ,
// deno-lint-ignore no-explicit-any
payload : any ,
headers? : string ,
) = > {
const res = await this . fetch (
opts ? . url ? ? "https://archiveofourown.org/" + path ,
{
"credentials" : "include" ,
headers : Object.assign ( headers ? ? { } , this . # headers ) ,
method : "POST" ,
body : payload ,
} ,
) ;
if ( res . status > 300 ) {
@ -48,6 +85,31 @@ export default class AO3 {
return new Work ( id , await res . text ( ) , this . session , new DOMParser ( ) ) ;
}
async authenticate ( username_or_email : string , password : string ) {
const loginPage = await this . session . get ( "/users/login" ) ;
const document = this . DOMParser . parseFromString (
await loginPage . text ( ) ,
"text/html" ,
) as HTMLDocument ;
const authenticity_token = document . querySelector (
"input[name='authenticity_token']" ,
) ? . getAttribute ( "value" ) ;
if ( authenticity_token ) {
await this . session . post (
"/users/login" ,
new URLSearchParams ( {
"user[login]" : username_or_email ,
"user[password]" : password ,
authenticity_token ,
utf8 : "✓" ,
commit : "Log In" ,
} ) ,
) ;
} else {
throw new Error ( "Failed to get authenticity token" ) ;
}
}
search ( opts : SearchParameters ) {
return new Search ( opts , this . session , new DOMParser ( ) ) ;
}