Skip to content

Commit

Permalink
Merge pull request #29 from ant385525/radarr_renamer
Browse files Browse the repository at this point in the history
Fix radarr to rescan and run rename commands
  • Loading branch information
revenz authored Jun 9, 2024
2 parents 23d60b0 + de92df7 commit 4048931
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 14 deletions.
136 changes: 124 additions & 12 deletions Scripts/Flow/Applications/Radarr/Radarr - Rename.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,136 @@
import { Radarr } from 'Shared/Radarr';
/**
* This script will send a rename command to Radarr
* @author Anthony Clerici
* @author Shaun Agius
* @uid bd6f02c8-e650-4916-bcae-46f382d20388
* @version 1.0.0
* @revision 4
* @descripttion This script will send a rename command to Radarr
* @revision 5
* @param {string} URI Radarr root URI and port (e.g. http://radarr:1234)
* @param {string} ApiKey API Key
* @output Item renamed
* @output Item not found
*/
function Script(URI, ApiKey) {
let radarr = new Radarr(URI, ApiKey);
let movie = radarr.getMovieByFile(Variables.file.Name);
if (!movie)
let folderPath = Variables.folder.FullName;
let filePath = Variables.file.FullName;
let currentFileName = Variables.file.Name;
let newFileName = null;

// Find movie name from radarr
let movie = findMovie(folderPath, radarr);

if (!movie) {
Logger.WLog('Movie not found for path: ' + folderPath);
Logger.ILog('Returning 2');
return 2;
Logger.ILog(`Renaming ${movie.title}`);
let endpoint = `rename`;
let queryParmeters = `movieId=${movie.id}`
let response = radarr.fetchJson(endpoint, queryParmeters);
Logger.ILog(`Response ${response}`);
return 1;
}
}

// Get Movie File info
let movieFiles = radarr.findMovieFiles(movie.id, radarr);
if (!movieFiles) {
Logger.ILog(`No files found for movie ${movie.id}`);
return -1
}

let fileList = [];
movieFiles.forEach(file => {
fileList.push(file.id);
});

try {
// Ensure movie is refreshed before renaming
let refreshBody = {
movieId: movie.id
}
let refreshData = radarr.sendCommand('RescanMovie', refreshBody)
Logger.ILog(`Movie refreshed: ${JSON.stringify(refreshData)}`);

// Wait for the completion of the refresh scan
let refreshCompleted = radarr.waitForCompletion(refreshData.id);
if (!refreshCompleted) {
Logger.ILog('Refresh not completed');
return -1;
}

// Get what radarr wants to rename the movie
let renamedMovies = radarr.fetchRenamedMovies(movie.id, radarr);
let renamedMovie = null;
if (!renamedMovies) {
Logger.ILog('No movies need to be renamed');
Logger.ILog('Returning 2');
return 2;
}

renamedMovies.every(element => {
if (element.existingPath.endsWith(currentFileName)) {
renamedMovie = element;
return false
}
return true;
});

// Ensure movie is found
if (!renamedMovie) {
Logger.ILog(`Current file not found in list to be renamed for movie ${movie.id}`)
Logger.ILog('Returning 2');
return 2;
}

newFileName = System.IO.Path.GetFileName(renamedMovie.newPath);
Logger.ILog(`Found it, renaming file to ${newFileName}`);

if (newFileName === null) {
Logger.WLog('No matching movie found to rename.');
Logger.ILog('Returning 2');
return 2;
}

// Now rename the file to what Radarr specifies
let renameBody = {
movieId: movie.id,
files: fileList
}
Logger.ILog(renameBody);
let renameResponse = radarr.sendCommand('RenameFiles', renameBody);
let renameCompleted = radarr.waitForCompletion(renameResponse.id);

if (!renameCompleted) {
Logger.ILog('Rename not completed');
return -1;
}
Logger.ILog(`Movie ${movie.id} successfully renamed. Setting as working file.`)

// Radarr has successfully renamed the file, set new filename as working directory
let newFilePath = System.IO.Path.Combine(Variables.folder.FullName, newFileName);
Flow.SetWorkingFile(newFilePath);
Logger.ILog('Returning 1');
return 1;

} catch (error) {
Logger.WLog('Error: ' + error.message);
Logger.ILog('Returning -1');
return -1;
}
}

// Function to repeatedly try finding a movie by shortening the path
function findMovie(filePath, radarr) {
let currentPath = filePath;
let movie = null;

while (currentPath) {
movie = radarr.getMovieByPath(currentPath);
if (movie) {
Logger.ILog('Movie found: ' + movie.id);
return movie;
}

// If no movie is found go 1 dir up
currentPath = System.IO.Path.GetDirectoryName(currentPath);
}

Logger.WLog('Unable to find movie file at path ' + filePath);
return null;
}

82 changes: 81 additions & 1 deletion Scripts/Shared/Radarr.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,84 @@ export class Radarr
}
return movie.originalLanguage?.name;
}
}

/**
* Returns movie files info for an already identified movie
* @param {int} movieId ID of previously identified movie
* @returns list of radarr movieFile objects
*/
findMovieFiles(movieId) {
let endpoint = 'moviefile';
let queryParams = `movieId=${movieId}`;
let response = this.fetchJson(endpoint, queryParams);

Logger.ILog(`Movie found: ${movieId}`);
return response;
}

/**
* Returns files under a movie that need to be renamed
* @param {int} movieId Previously determined ID of the movie
* @returns list of radarr rename movie objects
*/
fetchRenamedMovies(movieId)
{
let endpoint = 'rename';
let queryParams = `movieId=${movieId}`;
let response = this.fetchJson(endpoint, queryParams);
return response;
}

/**
* Specifies a command for Sonarr to run. see sonarr rename script for usage
* @param {string} commandName the name of the command to be run
* @param {object} commandBody the body of the command to be sent
* @returns {object} JSON of the response or null if unsuccessful
*/
sendCommand(commandName, commandBody) {
let endpoint = `${this.URL}/api/v3/command`;
commandBody['name'] = commandName;

let jsonData = JSON.stringify(commandBody);
http.DefaultRequestHeaders.Add("X-API-Key", this.ApiKey);
let response = http.PostAsync(endpoint, JsonContent(jsonData)).Result;

http.DefaultRequestHeaders.Remove("X-API-Key");

if (response.IsSuccessStatusCode) {
let responseData = JSON.parse(response.Content.ReadAsStringAsync().Result);
return responseData;
} else {
let error = response.Content.ReadAsStringAsync().Result;
Logger.WLog("API error: " + error);
return null;
}
}

/**
* Sleeps, waiting for a command to complete
* @param {int} commandId ID of command being run
* @returns bool whether the coommand ran successfully
*/
waitForCompletion(commandId)
{
const startTime = new Date().getTime();
const timeout = 30000; // 30 seconds in milliseconds
const endpoint = `command/${commandId}`;

while (new Date().getTime() - startTime <= timeout) {
let response = this.fetchJson(endpoint, '');
if (response.status === 'completed') {
Logger.ILog('Scan completed!');
return true;
} else if (response.status === 'failed') {
Logger.WLog(`Command ${commandId} failed`)
return false;
}
Logger.ILog(`Checking status: ${response.status}`);
Sleep(100); // Delay before next check
}
Logger.WLog('Timeout: Scan did not complete within 30 seconds.');
return false;
}
}
2 changes: 1 addition & 1 deletion Scripts/Shared/Sonarr.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,4 @@ export class Sonarr
}
return language[1];
}
}
}

0 comments on commit 4048931

Please sign in to comment.