Added raw data retrieval for shows, seasons and full list of the shows for cr.

This commit is contained in:
Burve 2025-06-15 01:20:33 +03:00
parent e679721c9d
commit be7407fe49
3 changed files with 211 additions and 0 deletions

View file

@ -140,6 +140,18 @@ export default class Crunchy implements ServiceClass {
await this.refreshToken();
await this.logMovieListingById(argv['movie-listing'] as string);
}
else if(argv['show-raw'] && argv['show-raw'].match(/^[0-9A-Z]{9}$/)){
await this.refreshToken();
await this.logShowRawById(argv['show-raw'] as string);
}
else if(argv['season-raw'] && argv['season-raw'].match(/^[0-9A-Z]{9}$/)){
await this.refreshToken();
await this.logSeasonRawById(argv['season-raw'] as string);
}
else if(argv['show-list-raw']){
await this.refreshToken();
await this.logShowListRaw();
}
else if(argv.s && argv.s.match(/^[0-9A-Z]{9}$/)){
await this.refreshToken();
if (argv.dubLang.length > 1) {
@ -191,6 +203,173 @@ export default class Crunchy implements ServiceClass {
}
}
public async logShowRawById(id: string){
// check token
if(!this.cmsToken.cms){
console.error('Authentication required!');
return;
}
// opts
const AuthHeaders = {
headers: {
Authorization: `Bearer ${this.token.access_token}`,
...api.crunchyDefHeader
},
useProxy: true
};
// seasons list
const seriesSeasonListReq = await this.req.getData(`${api.cms}/series/${id}/seasons?force_locale=&preferred_audio_language=ja-JP&locale=${this.locale}`, AuthHeaders);
if(!seriesSeasonListReq.ok || !seriesSeasonListReq.res){
console.error('Series Request FAILED!');
return;
}
const seriesData = await seriesSeasonListReq.res.json();
for (const item of seriesData.data) {
// stringify each object, then a newline
console.log(JSON.stringify(item));
}
return seriesData.data;
}
public async logSeasonRawById(id: string){
// check token
if(!this.cmsToken.cms){
console.error('Authentication required!');
return;
}
// opts
const AuthHeaders = {
headers: {
Authorization: `Bearer ${this.token.access_token}`,
...api.crunchyDefHeader
},
useProxy: true
};
// seasons list
let episodeList = { total: 0, data: [], meta: {} } as CrunchyEpisodeList;
//get episode info
if (this.api == 'android') {
const reqEpsListOpts = [
api.beta_cms,
this.cmsToken.cms.bucket,
'/episodes?',
new URLSearchParams({
'force_locale': '',
'preferred_audio_language': 'ja-JP',
'locale': this.locale,
'season_id': id,
'Policy': this.cmsToken.cms.policy,
'Signature': this.cmsToken.cms.signature,
'Key-Pair-Id': this.cmsToken.cms.key_pair_id,
}),
].join('');
const reqEpsList = await this.req.getData(reqEpsListOpts, AuthHeaders);
if(!reqEpsList.ok || !reqEpsList.res){
console.error('Episode List Request FAILED!');
return { isOk: false, reason: new Error('Episode List request failed. No more information provided.') };
}
//CrunchyEpisodeList
const episodeListAndroid = await reqEpsList.res.json() as CrunchyAndroidEpisodes;
episodeList = {
total: episodeListAndroid.total,
data: episodeListAndroid.items,
meta: {}
};
} else {
const reqEpsList = await this.req.getData(`${api.cms}/seasons/${id}/episodes?force_locale=&preferred_audio_language=ja-JP&locale=${this.locale}`, AuthHeaders);
if(!reqEpsList.ok || !reqEpsList.res){
console.error('Episode List Request FAILED!');
return { isOk: false, reason: new Error('Episode List request failed. No more information provided.') };
}
//CrunchyEpisodeList
episodeList = await reqEpsList.res.json() as CrunchyEpisodeList;
}
for (const item of episodeList.data) {
// stringify each object, then a newline
console.log(JSON.stringify(item));
}
// Return the data directly if this function is called by other code
return episodeList.data;
}
public async logShowListRaw() {
// check token
if(!this.cmsToken.cms){
console.error('Authentication required!');
return;
}
// opts
const AuthHeaders = {
headers: {
Authorization: `Bearer ${this.token.access_token}`,
...api.crunchyDefHeader
},
useProxy: true
};
let allShows: any[] = [];
let page = 1;
let hasMorePages = true;
if(this.debug){
console.info('Retrieving complete show list...');
}
while (hasMorePages) {
const searchStart = (page - 1) * 50;
const params = new URLSearchParams({
'preferred_audio_language': 'ja-JP',
'locale': this.locale,
'ratings': 'true',
'sort_by': 'alphabetical',
'n': '50',
'start': searchStart.toString()
}).toString();
const showListReq = await this.req.getData(`${api.browse_all_series}?${params}`, AuthHeaders);
if (!showListReq.ok || !showListReq.res) {
console.error(`Show List Request FAILED on page ${page}!`);
return allShows;
}
const showListData = await showListReq.res.json();
// Add current page data
for (const item of showListData.data) {
// stringify each object, then a newline
console.log(JSON.stringify(item));
allShows.push(item);
}
// Calculate pagination info
const totalItems = showListData.total;
const totalPages = Math.ceil(totalItems / 50);
if(this.debug){
console.info(`Retrieved page ${page}/${totalPages} (${allShows.length}/${totalItems} items)`);
}
// Check if we need to fetch more pages
if (page >= totalPages) {
hasMorePages = false;
} else {
page++;
// Add a small delay to avoid rate limiting
await this.sleep(1000);
}
}
if(this.debug){
console.info(`Complete show list retrieved: ${allShows.length} items`);
}
return allShows;
}
public async getFonts() {
console.info('Downloading fonts...');
const fonts = Object.values(fontsData.fontFamilies).reduce((pre, curr) => pre.concat(curr));

View file

@ -26,6 +26,7 @@ export type APIType = {
defaultUserAgent: string,
beta_profile: string
beta_cmsToken: string
browse_all_series: string,
search: string
cms: string
beta_browse: string
@ -73,6 +74,7 @@ const api: APIType = {
cms: `${domain.api_beta}/content/v2/cms`,
beta_browse: `${domain.api_beta}/content/v1/browse`,
beta_cms: `${domain.api_beta}/cms/v2`,
browse_all_series: `${domain.api_beta}/content/v2/discover/browse`,
// beta api
// broken - deprecated since 06.05.2025
drm: `${domain.api_beta}/drm/v1/auth`,

View file

@ -144,6 +144,36 @@ const args: TAppArg<boolean|number|string|unknown[]>[] = [
type: 'string',
usage: '${ID}',
},
{
group: 'dl',
alias: 'sraw',
name: 'show-raw',
describe: 'get raw show data',
docDescribe: true,
service: ['crunchy'],
type: 'string',
usage: '${ID}',
},
{
group: 'dl',
alias: 'seraw',
name: 'season-raw',
describe: 'Get Raw Season data',
docDescribe: true,
service: ['crunchy'],
type: 'string',
usage: '${ID}',
},
{
group: 'dl',
alias: 'slraw',
name: 'show-list-raw',
describe: 'Get Raw show list data',
docDescribe: true,
service: ['crunchy'],
type: 'boolean',
usage: '',
},
{
name: 'series',
group: 'dl',