File size: 2,640 Bytes
0bfe2e3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { PARSE_REGEX } from './regex';
import * as PTT from 'parse-torrent-title';
import { ParsedFile } from '../db';

function matchPattern(
  filename: string,
  patterns: Record<string, RegExp>
): string | undefined {
  return Object.entries(patterns).find(([_, pattern]) =>
    pattern.test(filename)
  )?.[0];
}

function matchMultiplePatterns(
  filename: string,
  patterns: Record<string, RegExp>
): string[] {
  return Object.entries(patterns)
    .filter(([_, pattern]) => pattern.test(filename))
    .map(([tag]) => tag);
}

class FileParser {
  static parse(filename: string): ParsedFile {
    const parsed = PTT.parse(filename);
    // prevent the title from being parsed for info
    if (parsed.title && parsed.title.length > 4) {
      filename = filename.replace(parsed.title, '').trim();
      filename = filename.replace(/\s+/g, '.').replace(/^\.+|\.+$/g, '');
    }
    const resolution = matchPattern(filename, PARSE_REGEX.resolutions);
    const quality = matchPattern(filename, PARSE_REGEX.qualities);
    const encode = matchPattern(filename, PARSE_REGEX.encodes);
    const audioChannels = matchMultiplePatterns(
      filename,
      PARSE_REGEX.audioChannels
    );
    const visualTags = matchMultiplePatterns(filename, PARSE_REGEX.visualTags);
    const audioTags = matchMultiplePatterns(filename, PARSE_REGEX.audioTags);
    const languages = matchMultiplePatterns(filename, PARSE_REGEX.languages);

    const getPaddedNumber = (number: number, length: number) =>
      number.toString().padStart(length, '0');

    const releaseGroup = parsed.group;
    const title = parsed.title;
    const year = parsed.year ? parsed.year.toString() : undefined;
    const season = parsed.season;
    const seasons = parsed.seasons;
    const episode = parsed.episode;
    const formattedSeasonString = seasons?.length
      ? seasons.length === 1
        ? `S${getPaddedNumber(seasons[0], 2)}`
        : `S${getPaddedNumber(seasons[0], 2)}-${getPaddedNumber(
            seasons[seasons.length - 1],
            2
          )}`
      : season
        ? `S${getPaddedNumber(season, 2)}`
        : undefined;
    const formattedEpisodeString = episode
      ? `E${getPaddedNumber(episode, 2)}`
      : undefined;

    const seasonEpisode = [
      formattedSeasonString,
      formattedEpisodeString,
    ].filter((v) => v !== undefined);

    return {
      resolution,
      quality,
      languages,
      encode,
      audioChannels,
      audioTags,
      visualTags,
      releaseGroup,
      title,
      year,
      season,
      seasons,
      episode,
      seasonEpisode,
    };
  }
}

export default FileParser;