58 lines
2.7 KiB
TypeScript
58 lines
2.7 KiB
TypeScript
import { BaseCommand } from '@adonisjs/core/ace'
|
|
import { CommandOptions } from '@adonisjs/core/types/ace'
|
|
import db from '@adonisjs/lucid/services/db'
|
|
|
|
/** Prints how well files are being grouped into releases. */
|
|
export default class ReleaseStats extends BaseCommand {
|
|
public static commandName = 'release:stats'
|
|
public static description = 'Shows release recognition statistics.'
|
|
|
|
public static options: CommandOptions = {
|
|
startApp: true,
|
|
}
|
|
|
|
public async run() {
|
|
const { rows } = await db.rawQuery(`
|
|
WITH r AS (
|
|
SELECT r.id, r.file_total, r.poster IS NULL AS weak, r.source,
|
|
count(b.id) AS binaries,
|
|
count(b.id) FILTER (WHERE b.completed_at IS NOT NULL) AS completed
|
|
FROM releases r LEFT JOIN binaries b ON b.release_id = r.id
|
|
GROUP BY r.id
|
|
)
|
|
SELECT
|
|
count(*) AS releases,
|
|
count(*) FILTER (WHERE completed > 0) AS with_files,
|
|
count(*) FILTER (WHERE completed >= 2) AS multi_file,
|
|
count(*) FILTER (WHERE file_total IS NOT NULL AND completed >= file_total) AS complete_by_counter,
|
|
count(*) FILTER (WHERE weak) AS from_obfuscated,
|
|
count(*) FILTER (WHERE weak AND completed > 0) AS from_obfuscated_with_files
|
|
FROM r`)
|
|
const { rows: coverage } = await db.rawQuery(`
|
|
SELECT count(*) AS completed_files,
|
|
count(*) FILTER (WHERE release_id IS NOT NULL) AS in_release
|
|
FROM binaries WHERE completed_at IS NOT NULL`)
|
|
const { rows: bySource } = await db.rawQuery(`
|
|
SELECT coalesce(r.source, 'unknown') AS source, count(DISTINCT r.id) AS releases,
|
|
count(b.id) FILTER (WHERE b.completed_at IS NOT NULL) AS completed_files
|
|
FROM releases r JOIN binaries b ON b.release_id = r.id GROUP BY 1 ORDER BY 2 DESC`)
|
|
// Readable names: descriptive as posted, or recovered from contents.
|
|
const { rows: naming } = await db.rawQuery(`
|
|
WITH f AS (
|
|
SELECT real_name IS NOT NULL AS recovered,
|
|
is_readable_name(coalesce(real_name, filename)) AS readable_name,
|
|
regexp_replace(coalesce(real_name, filename),
|
|
'(\\.(part\\d+\\.rar|r\\d{2,3}|rar|vol\\d+[+-]\\d+\\.par2|par2|7z(\\.\\d{3})?|zip|\\d{3}|nfo|sfv|nzb|tar|zst|mkv|mp4|avi|flac|mp3|jpg))+$', '', 'i') AS stem,
|
|
coalesce(real_name, filename) AS name
|
|
FROM files
|
|
)
|
|
SELECT count(*) AS files,
|
|
count(*) FILTER (WHERE recovered) AS names_recovered,
|
|
count(*) FILTER (WHERE name ~ '\\.[A-Za-z0-9]{1,5}$' AND readable_name) AS readable
|
|
FROM f`)
|
|
this.logger.info(JSON.stringify({ ...rows[0], ...coverage[0] }))
|
|
this.logger.info(`naming: ${JSON.stringify(naming[0])}`)
|
|
this.logger.info(`by source: ${JSON.stringify(bySource)}`)
|
|
}
|
|
}
|