Skip to content

Commit

Permalink
Merge pull request #28 from ant385525/sonarr_renamer
Browse files Browse the repository at this point in the history
Redo sonarr renamer to refresh sonarr and rename the file
  • Loading branch information
revenz authored Jun 9, 2024
2 parents 0f3a2f9 + 1cdd679 commit fe320fd
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 30 deletions.
131 changes: 103 additions & 28 deletions Scripts/Flow/Applications/Sonarr/Sonarr - Rename.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,117 @@
import { Sonarr } from 'Shared/Sonarr';
/**
* This script will send a rename command to Sonarr
* @author Anthony Clerici
* @author Shaun Agius
* @uid 5ac44abd-cfe9-4a84-904b-9424908509de
* @description This script will send a rename command to Sonarr
* @revision 6
* @version 1.0.0
* @revision 5
* @param {string} URI Sonarr root URI and port (e.g. http://sonarr:1234)
* @param {string} ApiKey API Key
* @output Item renamed
* @output Item not found
*/

function Script(URI, ApiKey) {
let sonarr = new Sonarr(URI, ApiKey);
let folder = Variables.folder.FullName
var season
if (folder.includes("Season"))
season = folder.indexOf('Season')-1
else
{
if (folder.includes("/"))
season = folder.lastIndexOf("/")
else if (folder.includes("\\"))
season = folder.lastIndexOf("\\")
}
let folder2 = folder.substring(0, season)
var slash
if (folder2.includes("/"))
slash = folder2.lastIndexOf("/") +1
else if (folder2.includes("\\"))
slash = folder2.lastIndexOf("\\") +1
let final = folder2.substring(slash)
let series = sonarr.getShowByPath(final);
if (!series)
const folderPath = Variables.folder.FullName;
const currentFileName = Variables.file.Name;
let newFileName = null;
let episodeFileId = null;

// Find series name from sonarr
let series = findSeries(folderPath, sonarr);

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

try {
// Ensure series is refreshed before renaming
let refreshBody = {
seriesId: series.id
}
let refreshData = sonarr.sendCommand('RescanSeries', refreshBody)
Logger.ILog(`Series refreshed`);

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

let renamedEpisodes = fetchRenamedFiles(series.id, sonarr);
if (!renamedEpisodes) {
Logger.ILog('No episodes need to be renamed');
return 2;
}

Logger.ILog(`Searching for an episode previously named ${currentFileName}`);
renamedEpisodes.every((episode) => {
if (episode.existingPath.endsWith(currentFileName)) {
episodeFileId = episode.episodeFileId;
newFileName = System.IO.Path.GetFileName(episode.newPath);
Logger.ILog(`Found it, renaming file ${episodeFileId} to ${newFileName}`);
return false;
}
return true;
});

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

let renameBody = {
seriesId: series.id,
files: [episodeFileId]
}
let renameResponse = sonarr.sendCommand('RenameFiles', renameBody, URI, ApiKey);
let renameCompleted = sonarr.waitForCompletion(renameResponse.id);

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

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

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

// Repeatedly try finding a show by shortening the path
function findSeries(filePath, sonarr) {
let currentPath = filePath;
let show = null;

while (currentPath) {
show = sonarr.getShowByPath(currentPath);
if (show) {
Logger.ILog('Show found: ' + show.id);
return show;
}

// If no show is found, go up 1 dir
currentPath = System.IO.Path.GetDirectoryName(currentPath);
if (currentPath === null || currentPath === "") {
Logger.WLog('Unable to find show file at path ' + filePath);
return null;
}
}
}

function fetchRenamedFiles(seriesId, sonarr) {
let endpoint = 'rename';
let queryParams = `seriesId=${seriesId}`;
let response = sonarr.fetchJson(endpoint, queryParams);
return response;
}
59 changes: 57 additions & 2 deletions Scripts/Shared/Sonarr.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @name Sonarr
* @uid 0f5836c0-d20b-4740-9824-f81b5200ec3d
* @description Class that interacts with Sonarr
* @revision 6
* @revision 7
* @minimumVersion 1.0.0.0
*/
export class Sonarr
Expand Down Expand Up @@ -231,4 +231,59 @@ export class Sonarr
}
return language[1];
}
}

/**
* 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);
Logger.ILog(`${commandName} command sent successfully`);
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;
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);
}
Logger.WLog('Timeout: Scan did not complete within 30 seconds.');
return false;
}
}

0 comments on commit fe320fd

Please sign in to comment.