-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
173 lines (143 loc) · 6 KB
/
script.js
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Clear the console when first running
console.clear();
// Require all dependencies
import Prompts from 'prompts';
import Fs from 'fs';
import Ora from 'ora';
import Chalk from 'chalk';
// Create a blank state to store all information about the process
const state = {};
// Options object for Prompts that clears the terminal after each question submission
const clearOnSubmit = { onSubmit: () => console.clear() };
// Useful prototypes
Array.prototype.sortByIndex = function (arrayOfIndices) { return arrayOfIndices?.map(i => this[i]); };
// Main IIFE Function
(async () => {
// Ask the user to pick between TV or Movie Renaming
const response = await Prompts({
type: 'select',
name: 'type',
message: Chalk.green('What are you looking to rename?\n'),
choices: [
{title: 'TV Show', value: 'tv'},
{title: 'Movie', value: 'movie'}
],
}, clearOnSubmit);
// Call the handlers for the selected format
if (response.type === 'tv') await handleTV();
else if (response.type === 'film') await handleFilm();
})();
// Handle TV Series Renaming
async function handleTV() {
// Ask the user for the file path of the files
const { path } = await Prompts({
type: 'text',
name: 'path',
message: Chalk.green('Where are the files located?\n')
}, clearOnSubmit);
// Check if the given path exists and return if not
if (!await Fs.existsSync(path)) return console.log(Chalk.red('An invalid path has been provided!'));
// Start a loader while getting all files (This should never run but here in case there is lots of files.)
const fileLoader = Ora('Loading Files...').start();
// Get all files from the directory
const files = await Fs.readdirSync(path);
// Stop the loader
fileLoader.stop();
// Display found files and select which ones they want to use
const { selectedFiles } = await Prompts({
type: 'multiselect',
name: 'selectedFiles',
message: Chalk.green(`Found ${files.length} file(s), please select which you want to re-name!\n`),
choices: files,
min: 1
}, clearOnSubmit);
// Update the State with the files information
state.files = selectedFiles.map(i => files[i]).map((f, i) => ({
extension: f.substr(f.lastIndexOf('.'), f.length), // .mkv
original_name: f, // Marvel's Agents Of S.H.I.E.L.D.- Season 2 (Disc 3)_t00.mkv
possible_show_name: f.split('-')[0], // Marvel's Agents Of S.H.I.E.L.D.
index: i, // 0
}));
// Run through the questions about the show and episode files
state.show = await Prompts([
// Take a guess at the title based on filename, and ask the user if they should use it or not.
{
type: () => state.files[0]?.possible_show_name ? 'toggle' : null,
name: 'name',
message: Chalk.green(`Is this the correct show name?\n${state.files[0]?.possible_show_name}\n`),
format: (value) => !value ? state.files[0]?.possible_show_name : null,
initial: false,
active: 'No',
inactive: 'Yes'
},
// If NOT then ask for a free input of the title
{
type: prev => prev ? null : 'text',
name: 'name',
message: Chalk.green('What is the name of the show?\n')
},
// Get the season number to apply to the files
{
type: 'number',
name: 'season',
message: Chalk.green('Which season is the file(s) part of?\n'),
initial: 1,
min: 1
},
], clearOnSubmit);
console.log('GETTING ORDER')
// Display the episodes in order and ask which order they should be in till correct, updates state.show property
await getEpisodeOrder(state.files);
// Temp, log the state after all questions
console.log('State', JSON.stringify(state))
console.log('FILES IN NEW ORDER', state.files.sortByIndex(state.show.order).map(f => f.original_name))
}
// Handle Movie File Renaming
async function handleFilm() {
// TODO - Work on adding film re-namer
}
async function getEpisodeOrder(files) {
console.log('GETTING FILES', files)
state.show = {
...state.show,
...(await Prompts([
// Ask if they are in the correct order (yes/no)
{
type: 'toggle',
name: 'order',
message: Chalk.green(`Are these in the correct order?\n\n${files.map((f, i) => Chalk.blue(`Episode ${i+1}: ${f.original_name}`)).join('\n')}\n\n`),
// TODO - FIX THIS TO GET CORRECT UPDATED ORDER ON FINAL CONFIRM
format: (correct) => !correct ? !state.show.order ? Array.from({ length: files.length },(_, i)=>i) : state.show.order : false,
initial: false,
active: 'No',
inactive: 'Yes'
},
// If NOT in order Ask to select episode for every episode file in order
...state.files.map((f, i) => ({
type: prev => !Array.isArray(prev) ? 'select' : null,
name: `episode-${i}`,
message: Chalk.green(`Please select the file to be used for Episode ${i+1}\n`),
format: (value) => ({ episode: value, order: i }),
choices: (prev, currValues) => files.map((f, i) => ({
title: f.original_name,
value: i,
// Disable if the episode has already been picked and is in the show object
disabled: !!Object.entries(currValues).filter(([k]) => k.startsWith('episode-'))?.find(([,cv]) => cv?.episode === i)
})),
// Set this to start on the previously selected episode so it's seamless
// TODO - Idea to move to the next available be that up or down an index, checking for start and end of the array.
initial: prev => prev?.episode
}))
], clearOnSubmit))
};
if (!state.show.order) {
// Remove all the episode keys from the results of the questions as its a limit of the prompts system.
// Remove episode key and add the episode index to the order array in the correct order.
state.show.order = Object.entries(state.show)
.filter(([k]) => k.startsWith('episode-'))
.sort((o1, o2) => o1[1]?.order - o2[1]?.order)
.map(([k, e]) => { delete state.show[k]; return e.episode });
// Re-start the loop asking if it is correct
await getEpisodeOrder(files.sortByIndex(state.show.order));
}
}