`;
});
return accordionOptions;
}
function buildAccordion(array, open = false) {
var items = "";
var mainId = createRandomString(10);
$.each(array, function (i, v) {
var collapse = open && i == 0 ? "collapse in" : "collapse";
var collapsed = open && i == 0 ? "" : "collapsed";
var id = mainId + "-" + i;
items +=
`
';
$.each(array, function (i, v) {
mainCount++;
var count = 0;
var total = v.length;
var active = mainCount == 1 ? "active" : "";
var customID = createRandomString(10);
if (i == "custom") {
group += v;
} else {
uList +=
`
`;
}
group += builtItems;
if (count % 2 == 0 || count == total) {
group += "
";
}
});
group += "
";
}
});
return uList + "
" + group + "
";
}
function createImageSwal(attr) {
let title = attr.attr("data-title");
let fullPath = attr.attr("data-image-path");
let clipboardText = attr.attr("data-clipboard-text");
let name = attr.attr("data-image-name");
let extension = attr.attr("data-image-name-ext");
let div =
`
` +
title +
`
Choose action:
`;
swal({
content: createElementFromHTML(div),
buttons: false,
className: "bg-org",
});
}
function buildImageManagerViewItem(array) {
var imageListing = "";
if (Array.isArray(array)) {
$.each(array, function (i, v) {
var filepath = v.split("/");
var name = filepath[filepath.length - 1].split(".");
var clipboardText = v.replace(/ /g, "%20");
var fileAndExt = filepath[filepath.length - 1];
imageListing +=
`
`;
});
}
return imageListing;
}
function buildImageManagerView() {
organizrAPI2("GET", "api/v2/image")
.success(function (data) {
try {
let response = data.response;
$(".settings-image-manager-list").html(
buildImageManagerViewItem(response.data)
);
$container = $("#gallery-content-center");
try {
if (typeof $container.isotope == "undefined") {
$container.isotope({ itemSelector: "img" });
} else {
$container.isotope({ itemSelector: "img" });
}
} catch (e) {
$container.isotope("destroy");
$container.isotope({ itemSelector: "img" });
}
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function buildPluginsSettings() {
organizrAPI2("GET", "api/v2/settings/plugin")
.success(function (data) {
try {
let response = data.response;
$("#plugin-settings-form").html(buildFormGroup(response.data));
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function buildThemeSettings() {
organizrAPI2("GET", "api/v2/settings/theme")
.success(function (data) {
try {
let response = data.response;
$("#theme-settings-form").html(buildFormGroup(response.data));
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function buildCustomizeAppearance() {
organizrAPI2("GET", "api/v2/settings/appearance")
.success(function (data) {
try {
var response = data.response;
} catch (e) {
organizrCatchError(e, data);
}
$("#customize-appearance-form").html(buildFormGroup(response.data));
$("input.pick-a-color-custom-options").ColorPickerSliders({
placement: "bottom",
color: "#987654",
hsvpanel: true,
previewformat: "hex",
});
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function buildSSO() {
organizrAPI2("GET", "api/v2/settings/sso")
.success(function (data) {
try {
var response = data.response;
} catch (e) {
organizrCatchError(e, data);
}
$("#sso-form").html(buildFormGroup(response.data));
})
.fail(function (xhr) {
console.error("Organizr Function: API Connection Failed");
});
}
function buildSettingsMain() {
organizrAPI2("GET", "api/v2/settings/main")
.success(function (data) {
try {
var response = data.response;
} catch (e) {
organizrCatchError(e, data);
}
$("#settings-main-form").html(buildFormGroup(response.data));
changeAuth();
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function buildUserManagement() {
organizrAPI2("GET", "api/v2/users?includeGroups")
.success(function (data) {
try {
var response = data.response;
} catch (e) {
organizrCatchError(e, data);
}
$("#manageUserTable").html(buildUserManagementItem(response.data));
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function buildGroupManagement() {
organizrAPI2("GET", "api/v2/groups?includeUsers")
.success(function (data) {
try {
var response = data.response;
} catch (e) {
organizrCatchError(e, data);
}
$("#manageGroupTable").html(buildGroupManagementItem(response.data));
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function buildTabEditor() {
organizrAPI2("GET", "api/v2/tabs")
.success(function (data) {
try {
var response = data.response;
} catch (e) {
organizrCatchError(e, data);
}
$("#tabEditorTable").html(buildTabEditorItem(response.data));
checkTabHomepageItems();
addTabSortable();
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function addTabSortable() {
let el = document.getElementById("tabEditorTable");
let tabSorter = new Sortable(el, {
handle: ".sort-tabs-handle",
ghostClass: "sortable-ghost",
multiDrag: true,
selectedClass: "multi-selected",
onUpdate: function (evt) {
$("input.order").each(function (idx) {
$(this).val(idx + 1);
});
newTabsGlobal = $("#submit-tabs-form").serializeToJSON();
$(".saveTabOrderButton").removeClass("hidden");
},
});
}
function checkTabHomepageItems() {
var tabList = $(".checkTabHomepageItem");
$.each(tabList, function (i, v) {
var el = $(v);
var id = el.attr("id");
var name = el.attr("data-name");
var url = el.attr("data-url");
var urlLocal = el.attr("data-url-local");
checkTabHomepageItem(id, name, url, urlLocal);
});
}
function sortHomepageItemHrefs() {
var hrefList = $(".popup-with-form");
window.hrefList = new Array();
$.each(hrefList, function (i, v) {
var el = $(v);
var href = el.attr("href");
if (href.includes("#homepage-")) {
var splitHref = href.split("-");
window.hrefList[splitHref[1]] = i;
}
});
}
function checkTabHomepageItemList(name, url, urlLocal, id, check, tab) {
// might use this later
if (name.includes(check) || url.includes(check) || urlLocal.includes(check)) {
addEditHomepageItem(id, tab);
}
}
function checkTabHomepageItem(id, name, url, urlLocal) {
name = name.toLowerCase();
url = url.toLowerCase();
urlLocal = urlLocal.toLowerCase();
try {
let urlObject = new URL(url);
if (urlObject.pathname !== "/" && urlObject !== "#") {
url = urlObject.pathname;
}
} catch {
url = url;
}
if (
name.includes("sonarr") ||
url.includes("sonarr") ||
urlLocal.includes("sonarr")
) {
addEditHomepageItem(id, "Sonarr");
} else if (
name.includes("radarr") ||
url.includes("radarr") ||
urlLocal.includes("radarr")
) {
addEditHomepageItem(id, "Radarr");
} else if (
name.includes("lidarr") ||
url.includes("lidarr") ||
urlLocal.includes("lidarr")
) {
addEditHomepageItem(id, "Lidarr");
} else if (
name.includes("couchpotato") ||
url.includes("couchpotato") ||
urlLocal.includes("couchpotato")
) {
addEditHomepageItem(id, "CouchPotato");
} else if (
name.includes("sick") ||
url.includes("sick") ||
urlLocal.includes("sick")
) {
addEditHomepageItem(id, "SickRage");
} else if (
(name.includes("plex") ||
url.includes("plex") ||
urlLocal.includes("plex")) &&
!name.includes("plexpy")
) {
addEditHomepageItem(id, "Plex");
} else if (
name.includes("emby") ||
url.includes("emby") ||
urlLocal.includes("emby")
) {
addEditHomepageItem(id, "Emby");
} else if (
name.includes("jdownloader") ||
url.includes("jdownloader") ||
urlLocal.includes("jdownloader") ||
name.includes("rsscrawler") ||
url.includes("rsscrawler") ||
urlLocal.includes("rsscrawler")
) {
addEditHomepageItem(id, "jDownloader");
} else if (
name.includes("sab") ||
url.includes("sab") ||
urlLocal.includes("sab")
) {
addEditHomepageItem(id, "SabNZBD");
} else if (
name.includes("nzbget") ||
url.includes("nzbget") ||
urlLocal.includes("nzbget")
) {
addEditHomepageItem(id, "NZBGet");
} else if (
name.includes("transmission") ||
url.includes("transmission") ||
urlLocal.includes("transmission")
) {
addEditHomepageItem(id, "Transmission");
} else if (
name.includes("qbit") ||
url.includes("qbit") ||
urlLocal.includes("qbit")
) {
addEditHomepageItem(id, "qBittorrent");
} else if (
name.includes("rtorrent") ||
url.includes("rtorrent") ||
urlLocal.includes("rtorrent")
) {
addEditHomepageItem(id, "rTorrent");
} else if (
name.includes("utorrent") ||
url.includes("utorrent") ||
urlLocal.includes("utorrent")
) {
addEditHomepageItem(id, "utorrent");
} else if (
name.includes("deluge") ||
url.includes("deluge") ||
urlLocal.includes("deluge")
) {
addEditHomepageItem(id, "Deluge");
} else if (
name.includes("ombi") ||
url.includes("ombi") ||
urlLocal.includes("ombi")
) {
addEditHomepageItem(id, "Ombi");
} else if (
name.includes("healthcheck") ||
url.includes("healthcheck") ||
urlLocal.includes("healthcheck")
) {
addEditHomepageItem(id, "HealthChecks");
} else if (
name.includes("jackett") ||
url.includes("jackett") ||
urlLocal.includes("jackett")
) {
addEditHomepageItem(id, "Jackett");
} else if (
name.includes("prowlarr") ||
url.includes("prowlarr") ||
urlLocal.includes("prowlarr")
) {
addEditHomepageItem(id, "Prowlarr");
} else if (
name.includes("unifi") ||
url.includes("unifi") ||
urlLocal.includes("unifi")
) {
addEditHomepageItem(id, "Unifi");
} else if (
name.includes("tautulli") ||
url.includes("tautulli") ||
urlLocal.includes("tautulli")
) {
addEditHomepageItem(id, "Tautulli");
}
}
function addEditHomepageItem(id, type) {
let html = '';
$("#" + id).html(html);
$("#" + id).attr("onclick", 'editHomepageItem("' + type + '")');
return false;
}
function buildCategoryEditor() {
organizrAPI2("GET", "api/v2/tabs")
.success(function (data) {
try {
var response = data.response;
} catch (e) {
organizrCatchError(e, data);
}
$("#categoryEditorTable").html(buildCategoryEditorItem(response.data));
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
/* END ORGANIZR API FUNCTIONS */
function buildLanguage(replace = false, newLang = null) {
var languageItems = "";
var currentLanguage = getCookie("organizrLanguage")
? getCookie("organizrLanguage")
: window.lang.currentLang;
var newLangCode = "";
$.each(languageList, function (i, v) {
if (newLang === v.language) {
newLangCode = v.code;
}
var active = v.code == currentLanguage ? "" : "";
languageItems +=
`
`
: "";
}
function pagination(c, m) {
var current = c,
last = m,
delta = 2,
left = current - delta,
right = current + delta + 1,
range = [],
rangeWithDots = [],
l;
for (let i = 1; i <= last; i++) {
if (i == 1 || i == last || (i >= left && i < right)) {
range.push(i);
}
}
for (let i of range) {
if (l) {
if (i - l === 2) {
rangeWithDots.push(l + 1);
} else if (i - l !== 1) {
rangeWithDots.push("...");
}
}
rangeWithDots.push(i);
l = i;
}
return rangeWithDots;
}
function buildRequestResult(
array,
media_type = null,
list = null,
page = null,
search = false
) {
var comments = typeof array.comments !== "undefined" ? true : false;
var comment = "";
var results = ``;
var buttons = ``;
var next = ``;
var tv = 0;
var movie = 0;
var total = 0;
var totalPages = array.total_pages;
var currentPage = page * 1;
var pagePrevious = page * 1 - 1;
var pageNext = page * 1 + 1;
var pageFirst = 1;
var pageLast = totalPages;
var previousHidden = currentPage == 1 ? "disabled" : "";
var nextHidden = currentPage == totalPages ? "disabled" : "";
var pageList = "";
let previousEnabled = pagePrevious !== 0;
let nextEnabled = pageNext <= totalPages;
if (array.results.length == 0) {
return '
No Results
';
}
$.each(array.results, function (i, v) {
media_type = v.media_type ? v.media_type : media_type;
if (media_type == "tv" || media_type == "movie") {
total = total + 1;
tv = media_type == "tv" ? tv + 1 : tv;
movie = media_type == "movie" ? movie + 1 : movie;
var bg =
v.poster_path !== null
? `https://image.tmdb.org/t/p/w300/` + v.poster_path
: "plugins/images/homepage/no-list.png";
var top = v.title
? v.title
: v.original_title
? v.original_title
: v.original_name
? v.original_name
: "";
var bottom = v.release_date
? v.release_date
: v.first_air_date
? v.first_air_date
: "";
if (comments) {
if (array.comments[media_type + ":" + v.id] !== null) {
comment = array.comments[media_type + ":" + v.id];
}
}
results +=
`
`;
return buttons + next + results + next;
}
function buildRequestOverseerrSeasons(array) {
var hasSeasons = typeof array.data.seasons !== "undefined";
if (hasSeasons) {
let seasons = array.data.seasons;
let id = array.data.id;
let SeasonItems = "";
$.each(seasons, function (i, v) {
if (v.seasonNumber !== 0) {
SeasonItems += `
${v.name}
${v.episodeCount}
`;
}
});
let html = `
Choose Seasons
Season
# Of Episodes
${SeasonItems}
`;
swal({
content: createElementFromHTML(html),
button: null,
className: "bg-org",
dangerMode: false,
});
}
}
function processOverseerrSeasons(el) {
let seasons = $(el).attr("data-seasons");
let id = $(el).attr("data-id");
overseerrActions(id, "add", "tv", seasons);
}
function processRequest(id, type) {
let service = activeInfo.settings.homepage.requests.service;
switch (service) {
case "ombi":
requestActions(id, "add", type);
return false;
case "overseerr":
if (
type === "tv" &&
activeInfo.settings.homepage.overseerr.userSelectTv === true
) {
organizrAPI2(
"GET",
"api/v2/homepage/overseerr/metadata/" + type + "/" + id
)
.success(function (data) {
try {
let response = data.response;
buildRequestOverseerrSeasons(response);
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr, "Overseerr Error");
});
} else {
requestActions(id, "add", type);
}
return false;
default:
organizrConsole(
"Request Function",
"Service for Processing not setup",
"error"
);
return false;
}
}
function requestActions(id = null, action = null, type = null, extra = null) {
let service = activeInfo.settings.homepage.requests.service;
switch (service) {
case "ombi":
ombiActions(id, action, type, extra);
break;
case "overseerr":
overseerrActions(id, action, type, extra);
break;
default:
organizrConsole(
"Request Function",
"Service for Request not setup",
"error"
);
return false;
}
}
//Overseerr Actions
function overseerrActions(id, action, type = null, extra = null) {
ajaxloader(".request-" + id + "-div", "in");
ajaxloader(".preloader-" + id, "in");
//$.magnificPopup.close();
messageSingle(
window.lang.translate("Submitting Action to Overseerr"),
"",
activeInfo.settings.notifications.position,
"#FFF",
"success",
"10000"
);
switch (action) {
case "add":
let seasons = extra !== null ? "/" + extra : "";
var method = "POST";
var apiUrl =
"api/v2/homepage/overseerr/requests/" + type + "/" + id + seasons;
var data = {};
break;
case "available":
case "pending":
case "unavailable":
case "approve":
var method = "POST";
var apiUrl =
"api/v2/homepage/overseerr/requests/" + type + "/" + id + "/" + action;
var data = {};
break;
case "deny":
var method = "PUT";
var apiUrl =
"api/v2/homepage/overseerr/requests/" + type + "/" + id + "/" + action;
var data = {};
break;
case "delete":
var method = "DELETE";
var apiUrl = "api/v2/homepage/overseerr/requests/" + type + "/" + id;
var data = {};
break;
default:
return false;
}
organizrAPI2(method, apiUrl, data)
.success(function (data) {
try {
let response = data.response;
if (action == "add") {
addTempRequest();
setTimeout(function () {
ajaxloader();
}, 2000);
}
messageSingle(
response.message,
"",
activeInfo.settings.notifications.position,
"#FFF",
"success",
"5000"
);
homepageRequests("overseerr");
cleanCloseSwal();
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
ajaxloader();
OrganizrApiError(xhr, "Overseerr Error");
});
}
//Ombi actions
function ombiActions(id, action, type, extra = null) {
var msg =
activeInfo.user.groupID <= 1
? 'Not Org Fault - Ask Ombi'
: "Connection Error to Request Server";
ajaxloader(".request-" + id + "-div", "in");
ajaxloader(".preloader-" + id, "in");
//$.magnificPopup.close();
messageSingle(
window.lang.translate("Submitting Action to Ombi"),
"",
activeInfo.settings.notifications.position,
"#FFF",
"success",
"10000"
);
switch (action) {
case "add":
var method = "POST";
var apiUrl = "api/v2/homepage/ombi/requests/" + type + "/" + id;
var data = {};
break;
case "available":
case "unavailable":
case "approve":
var method = "POST";
var apiUrl =
"api/v2/homepage/ombi/requests/" + type + "/" + id + "/" + action;
var data = {};
break;
case "deny":
var method = "PUT";
var apiUrl =
"api/v2/homepage/ombi/requests/" + type + "/" + id + "/" + action;
var data = {};
break;
case "delete":
var method = "DELETE";
var apiUrl = "api/v2/homepage/ombi/requests/" + type + "/" + id;
var data = {};
break;
default:
return false;
}
organizrAPI2(method, apiUrl, data)
.success(function (data) {
try {
let response = data.response;
if (action == "add") {
addTempRequest();
}
messageSingle(
response.message,
"",
activeInfo.settings.notifications.position,
"#FFF",
"success",
"5000"
);
homepageRequests("ombi");
ajaxloader();
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
ajaxloader();
OrganizrApiError(xhr, "Ombi Error");
});
}
function addTempRequest() {
let service = activeInfo.settings.homepage.requests.service;
let html = `
Adding Request
`;
$(".request-items-" + service)
.trigger("add.owl", [html, 0])
.trigger("refresh.owl");
setTimeout(function () {
ajaxloader(".request-adding", "in");
}, 100);
}
function cleanCloseSwal() {
let state = swal.getState().isOpen;
if (state === true) {
swal.close();
}
}
function doneTyping() {
let title = $("#request-input").val();
if (title == "") {
return false;
}
var page = $("#request-page").val() ? $("#request-page").val() : 1;
if (typeof searchTerm !== "undefined") {
if (searchTerm !== $("#request-input").val()) {
page = 1;
}
}
ajaxloader(".search-div", "in");
searchTerm = title;
$("#request-page").val(page);
requestSearch(title, page)
.success(function (data) {
$("#request-results").html(
buildRequestResult(data, "", title, page, true)
);
if (bowser.mobile !== true) {
$(".resultBox-inside").slimScroll({
height: "100%",
position: "right",
size: "5px",
color: "#dcdcdc",
});
}
$(".mfp-wrap").animate(
{
scrollTop: "0",
},
500
);
ajaxloader();
})
.fail(function (xhr) {
OrganizrApiError(xhr, "TMDB Error");
ajaxloader();
});
}
function requestList(list, type, page = 1) {
ajaxloader(".search-div", "in");
requestSearchList(list, page)
.success(function (data) {
if (typeof data.results !== "undefined") {
var results = data.results;
} else if (typeof data.items !== "undefined") {
var results = data.items;
}
$("#request-results").html(buildRequestResult(data, type, list, page));
if (bowser.mobile !== true) {
$(".resultBox-inside").slimScroll({
height: "100%",
position: "right",
size: "5px",
color: "#dcdcdc",
});
}
$(".mfp-wrap").animate(
{
scrollTop: "0",
},
500
);
ajaxloader();
})
.fail(function (xhr) {
OrganizrApiError(xhr, "TMDB Error");
ajaxloader();
});
}
function buildDownloaderItem(array, source, type = "none") {
var queue = "";
var count = 0;
var history = "";
switch (source) {
case "jdownloader":
if (array.content === false) {
queue =
'
`;
});
break;
case "sabnzbd":
if (array.content === false) {
queue =
'
Connection Error to ' +
source +
"
";
break;
}
if (array.content.queueItems.queue.paused) {
var state = ``;
var active = "grayscale";
} else {
var state = ``;
var active = "";
}
$(".sabnzbd-downloader-action").html(state);
if (array.content.queueItems.queue.slots.length == 0) {
queue =
'
';
}
$.each(array.content.queueItems, function (i, v) {
count = count + 1;
switch (v.status) {
case 7:
case "7":
var status = "No Peers";
break;
case 6:
case "6":
var status = "Seeding";
break;
case 5:
case "5":
var status = "Seeding Queued";
break;
case 4:
case "4":
var status = "Downloading";
break;
case 3:
case "3":
var status = "Queued";
break;
case 2:
case "2":
var status = "Checking Files";
break;
case 1:
case "1":
var status = "File Check Queued";
break;
case 0:
case "0":
var status = "Complete";
break;
default:
var status = "Complete";
}
var percent = Math.floor(v.percentDone * 100);
v.Category = v.Category !== "" ? v.Category : "Not Set";
queue +=
`
` +
v.name +
`
` +
status +
`
` +
v.downloadDir +
`
` +
humanFileSize(v.totalSize, true) +
`
` +
percent +
`%
`;
});
break;
case "rTorrent":
if (array.content === false) {
queue =
'
';
}
$.each(array.content.queueItems, function (i, v) {
count = count + 1;
switch (v.state) {
case "stalledDL":
var status = "No Peers";
break;
case "metaDL":
var status = "Getting Metadata";
break;
case "uploading":
var status = "Seeding";
break;
case "queuedUP":
var status = "Seeding Queued";
break;
case "downloading":
var status = "Downloading";
break;
case "queuedDL":
var status = "Queued";
break;
case "checkingDL":
case "checkingUP":
var status = "Checking Files";
break;
case "pausedDL":
var status = "Paused";
break;
case "pausedUP":
var status = "Complete";
break;
default:
var status = "Complete";
}
var percent = Math.floor(v.progress * 100);
var size = v.total_size != -1 ? humanFileSize(v.total_size, true) : "?";
queue +=
`
` +
v.name +
`
` +
status +
`
` +
v.save_path +
`
` +
size +
`
` +
percent +
`%
`;
});
break;
case "deluge":
if (array.content === false) {
queue =
'
` + v.name;
if (v.tracker_status != "")
queue +=
`
` +
v.tracker_status +
`
`;
queue +=
`
` +
v.state +
`
` +
size +
`
` +
download +
`
` +
upload +
`
` +
percent +
`%
`;
});
break;
default:
return false;
}
if (queue !== "") {
$("." + source + "-queue").html(queue);
}
if (history !== "") {
$("." + source + "-history").html(history);
}
$("#count-" + source).html(count);
}
function buildDownloader(source) {
var queueButton = "QUEUE";
var historyButton = "HISTORY";
switch (source) {
case "jdownloader":
var queue = true;
var history = false;
queueButton = "REFRESH";
break;
case "sabnzbd":
case "nzbget":
var queue = true;
var history = true;
break;
case "transmission":
case "qBittorrent":
case "deluge":
case "utorrent":
var queue = true;
break;
case "rTorrent":
case "sonarr":
case "radarr":
var queue = true;
var history = false;
queueButton = "REFRESH";
break;
default:
var queue = false;
var history = false;
}
var menu = `
`;
var listing = "";
var state = "";
var active = "";
var headerAlt = "";
var header = "";
//console.log(array);
//console.log(queueItems);
//console.log(historyItems);
//console.log(downloader);
if (queue) {
menu +=
`
";
if (activeInfo.settings.homepage.options.alternateHomepageHeaders) {
var headerAlt =
`
` +
state +
`
` +
menu +
`
`;
} else {
var header =
`
` +
state +
`
` +
menu +
`
`;
}
return (
`
` +
headerAlt +
`
` +
header +
`
` +
listing +
`
`
);
}
function buildDownloaderCombined(source) {
var first = $(".combinedDownloadRow").length == 0 ? true : false;
var active = first ? "active" : "";
var queueButton = "QUEUE";
var historyButton = "HISTORY";
switch (source) {
case "jdownloader":
var queue = true;
var history = false;
queueButton = "REFRESH";
break;
case "sabnzbd":
case "nzbget":
var queue = true;
var history = true;
break;
case "utorrent":
var queue = true;
break;
case "transmission":
case "qBittorrent":
case "deluge":
case "rTorrent":
case "sonarr":
case "radarr":
var queue = true;
var history = false;
queueButton = "REFRESH";
break;
default:
var queue = false;
var history = false;
}
var mainMenu = `
`;
var addToMainMenu =
`
`;
var listing = "";
var headerAlt = "";
var header = "";
var menu = `
`;
});
return metadata;
}
function buildYoutubeLink(title) {
if (title) {
var str = createRandomString(10);
return (
`
`
);
}
}
function buildPVRLink(href, ico = "", frame = "", showLink = true) {
if (href && showLink) {
var styleOverride = `width:55px;height:44px;background-image: url(${ico});background-repeat:no-repeat;background-size:25px;background-position:center;`;
if (frame) {
return `
`;
} else {
return `
`;
}
} else {
return `
`;
}
}
function buildCalendarMetadata(array) {
var metadata = "";
var genres = "";
var actors = "";
var rating = '';
var hasGenre = typeof array.genres !== "string" ? true : false;
if (hasGenre) {
$.each(array.genres, function (i, v) {
genres += '' + v + "";
});
}
if (array.ratings) {
var ratingRound = Math.ceil(array.ratings) * 10;
rating =
`
`;
}
var seconds = array.runtime / 1000; // or "2000"
seconds = parseInt(seconds); //because moment js dont know to handle number in string format
var format =
Math.floor(moment.duration(seconds, "seconds").asHours()) +
":" +
moment.duration(seconds, "seconds").minutes() +
":" +
moment.duration(seconds, "seconds").seconds();
metadata =
`
';
if (array["options"]["queries"]) {
stats += totalQueries(array["data"]);
}
if (array["options"]["blocked_count"]) {
stats += totalBlocked(array["data"]);
}
if (array["options"]["blocked_percent"]) {
stats += percentBlocked(array["data"]);
}
if (array["options"]["processing_time"]) {
stats += avgProcessingTime(array["data"]);
}
if (array["options"]["domain_count"]) {
stats += domainsBlocked(array["filters"]);
}
stats += "
";
} else {
for (var key in array["data"]) {
var data = array["data"][key];
obj = {};
obj[key] = data;
stats += '
';
if (array["options"]["queries"]) {
stats += totalQueries(array["data"]);
}
if (array["options"]["blocked_count"]) {
stats += totalBlocked(array["data"]);
}
if (array["options"]["blocked_percent"]) {
stats += percentBlocked(array["data"]);
}
if (array["options"]["processing_time"]) {
stats += avgProcessingTime(array["data"]);
}
if (array["options"]["domain_count"]) {
stats += domainsBlocked(array["filters"]);
}
stats += "
";
}
}
return stats;
}
function buildPiholeItem(array) {
var stats = `
`;
var length = Object.keys(array["data"]).length;
var combine = array["options"]["combine"];
var totalQueries = function (data) {
var card = `
Total queries (last 24 hours)
`;
for (var key in data) {
var e = data[key];
if (typeof e["FTLnotrunning"] == "undefined") {
if (length > 1 && !combine) {
card += `
(` + key + `)
`;
}
let value = "Error";
if (e.length == undefined) {
value = e["sum_queries"]
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
card +=
`
` +
value +
`
`;
}
}
card += `
`;
return card;
};
var totalBlocked = function (data) {
var card = `
Queries Blocked (last 24 hours)
`;
for (var key in data) {
var e = data[key];
if (typeof e["FTLnotrunning"] == "undefined") {
if (length > 1 && !combine) {
card += `
(${key})
`;
}
let value = "Error";
if (e.length == undefined) {
value = e["sum_blocked"]
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
card +=
`
` +
value +
`
`;
}
}
card += `
`;
return card;
};
var percentBlocked = function (data) {
var card = `
Percent Blocked (last 24 hours)
`;
for (var key in data) {
var e = data[key];
if (typeof e["FTLnotrunning"] == "undefined") {
if (length > 1 && !combine) {
card += `
(${key})
`;
}
let value = "Error";
if (e.length == undefined) {
value = e["percent_blocked"].toFixed(1);
}
card +=
`
` +
value +
`
`;
}
}
card += `
`;
return card;
};
var domainsBlocked = function (data) {
var card = `
Domains on Blocklist (last 24 hours)
`;
for (var key in data) {
var e = data[key];
if (typeof e["FTLnotrunning"] == "undefined") {
if (length > 1 && !combine) {
card += `
(${key})
`;
}
let value = "Error";
value = e["domains_being_blocked"]
.map(function (x) {
return `
`;
}
return card;
};
for (var key in services) {
cards += buildCard(key, services[key]);
}
return cards;
}
function buildPromPage(array) {
if (array === false) {
return "";
}
if (array.error != undefined) {
organizrConsole("PromPage Function", array.error, "error");
} else {
var html = `
`;
if (array["options"]["titleToggle"]) {
html +=
`
` +
array["options"]["title"] +
` :
`;
}
html +=
`
` +
buildPromPageItem(array) +
`
`;
}
return array ? html : "";
}
function homepagePromPage(timeout) {
var timeout =
typeof timeout !== "undefined"
? timeout
: activeInfo.settings.homepage.refresh.homepagePromPageRefresh;
organizrAPI2("GET", "api/v2/homepage/prompage/data")
.success(function (data) {
try {
let response = data.response;
document.getElementById("homepageOrderPromPage").innerHTML = "";
if (response.data !== null) {
buildUptimeKuma(response.data);
$("#homepageOrderPromPage").html(buildPromPage(response.data));
}
} catch (e) {
console.log(e);
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
let timeoutTitle = "PromPage-Homepage";
if (typeof timeouts[timeoutTitle] !== "undefined") {
clearTimeout(timeouts[timeoutTitle]);
}
timeouts[timeoutTitle] = setTimeout(function () {
homepagePromPage(timeout);
}, timeout);
delete timeout;
}
function homepageSpeedtest(timeout) {
var timeout =
typeof timeout !== "undefined"
? timeout
: activeInfo.settings.homepage.refresh.homepageSpeedtestRefresh;
organizrAPI2("GET", "api/v2/homepage/speedtest/data")
.success(function (data) {
try {
let response = data.response;
document.getElementById("homepageOrderSpeedtest").innerHTML = "";
if (response.data !== null) {
$("#homepageOrderSpeedtest").html(buildSpeedtest(response.data));
}
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
let timeoutTitle = "Speedtest-Homepage";
if (typeof timeouts[timeoutTitle] !== "undefined") {
clearTimeout(timeouts[timeoutTitle]);
}
timeouts[timeoutTitle] = setTimeout(function () {
homepageSpeedtest(timeout);
}, timeout);
delete timeout;
}
function buildSpeedtest(array) {
if (array === false) {
return "";
}
var html = `
`;
var current = array.data.current;
var average = array.data.average;
var maximum = array.data.maximum;
var minimum = array.data.minimum;
var options = array.options;
html += `
`;
if (options.titleToggle) {
html +=
`
` +
array["options"]["title"] +
` :
`;
}
html +=
`
Ping
` +
parseFloat(current.ping).toFixed(1) +
`
ms (current)
`;
if (average != undefined) {
html +=
`
` +
parseFloat(average.ping).toFixed(1) +
`
ms (average)
`;
}
if (maximum != undefined) {
html +=
`
` +
parseFloat(maximum.ping).toFixed(1) +
`
ms (maximum)
`;
}
if (minimum != undefined) {
html +=
`
` +
parseFloat(minimum.ping).toFixed(1) +
`
ms (minimum)
`;
}
html +=
`
Download
` +
parseFloat(current.download).toFixed(1) +
`
Mbit/s (current)
`;
if (average != undefined) {
html +=
`
` +
parseFloat(average.download).toFixed(1) +
`
Mbit/s (average)
`;
}
if (maximum != undefined) {
html +=
`
` +
parseFloat(maximum.download).toFixed(1) +
`
Mbit/s (maximum)
`;
}
if (minimum != undefined) {
html +=
`
` +
parseFloat(minimum.download).toFixed(1) +
`
Mbit/s (minimum)
`;
}
html +=
`
Upload
` +
parseFloat(current.upload).toFixed(1) +
`
Mbit/s (current)
`;
if (average != undefined) {
html +=
`
` +
parseFloat(average.upload).toFixed(1) +
`
Mbit/s (average)
`;
}
if (maximum != undefined) {
html +=
`
` +
parseFloat(maximum.upload).toFixed(1) +
`
Mbit/s (maximum)
`;
}
if (minimum != undefined) {
html +=
`
` +
parseFloat(minimum.upload).toFixed(1) +
`
Mbit/s (minimum)
`;
}
html += `
`;
return array ? html : "";
}
function buildNetdataItem(array) {
var html = `
`;
var buildEasyPieChart = function (e, i, size, easySize, display) {
return (
`
Approx. Total Print Time: " +
octoprintFormatTime(array.data.job.job.estimatedPrintTime) +
"
";
content +=
"
Print Time Left: " +
octoprintFormatTime(array.data.job.progress.printTimeLeft) +
"
";
}
if (array.data.settings.webcam.webcamEnabled) {
webcamUrl = array.data.settings.webcam.streamUrl;
if (webcamUrl[0] == "/") {
webcamUrl = array.data.url + webcamUrl;
}
}
if (webcamUrl) {
var webcamHtml =
`
`;
}
return (
css +
`
` +
headerAlt +
`
` +
header +
`
` +
content +
`
` +
webcamHtml +
`
`
);
}
function octoprintFormatTime(seconds) {
var format = "";
var days = Math.floor(moment.duration(seconds, "seconds").asDays());
var hours = Math.floor(moment.duration(seconds, "seconds").asHours());
var minutes = moment.duration(seconds, "seconds").minutes();
var seconds = moment.duration(seconds, "seconds").seconds();
if (days > 0) {
format += days + " " + octoprintPluralize("day", days) + " ";
}
if (hours > 0) {
format += hours + " " + octoprintPluralize("hour", hours) + " ";
}
if (minutes > 0) {
format += minutes + " " + octoprintPluralize("minute", minutes) + " ";
}
if (seconds > 0) {
format += seconds + " " + octoprintPluralize("second", seconds) + " ";
}
return format;
}
function octoprintPluralize(s, n) {
if (n > 1) {
return s + "s";
}
return s;
}
function pad(n, width, z) {
z = z || "0";
n = n + "";
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
// Thanks Swifty!
function PopupCenter(url, title, w, h) {
// Fixes dual-screen position Most browsers Firefox
var dualScreenLeft =
window.screenLeft != undefined ? window.screenLeft : window.screenX;
var dualScreenTop =
window.screenTop != undefined ? window.screenTop : window.screenY;
var width = window.innerWidth
? window.innerWidth
: document.documentElement.clientWidth
? document.documentElement.clientWidth
: screen.width;
var height = window.innerHeight
? window.innerHeight
: document.documentElement.clientHeight
? document.documentElement.clientHeight
: screen.height;
var left = width / 2 - w / 2 + dualScreenLeft;
var top = height / 2 - h / 2 + dualScreenTop;
var newWindow = window.open(
url,
title,
"scrollbars=yes, width=" +
w +
", height=" +
h +
", top=" +
top +
", left=" +
left
);
// Puts focus on the newWindow
if (window.focus) {
newWindow.focus();
}
return newWindow;
}
function getPlexHeaders() {
let plexTitle =
activeInfo.appearance.title == ""
? "Organizr"
: cleanClass(activeInfo.appearance.title);
return {
Accept: "application/json",
"X-Plex-Product": plexTitle,
"X-Plex-Version": "2.0",
"X-Plex-Client-Identifier": activeInfo.settings.misc.uuid,
"X-Plex-Model": "Plex OAuth",
"X-Plex-Platform": activeInfo.osName,
"X-Plex-Platform-Version": activeInfo.osVersion,
"X-Plex-Device": activeInfo.browserName,
"X-Plex-Device-Name": activeInfo.browserVersion,
"X-Plex-Device-Screen-Resolution":
window.screen.width + "x" + window.screen.height,
"X-Plex-Language": "en",
};
}
var plex_oauth_window = null;
const plex_oauth_loader =
"" +
'
' +
'
' +
'' +
" " +
"Redirecting to the login page..." +
"
" +
"
";
function closePlexOAuthWindow() {
if (plex_oauth_window) {
plex_oauth_window.close();
}
}
getPlexOAuthPin = function () {
var x_plex_headers = getPlexHeaders();
var deferred = $.Deferred();
$.ajax({
url: "https://plex.tv/api/v2/pins?strong=true",
type: "POST",
headers: x_plex_headers,
success: function (data) {
deferred.resolve({ pin: data.id, code: data.code });
},
error: function () {
closePlexOAuthWindow();
deferred.reject();
},
});
return deferred;
};
var polling = null;
function PlexOAuth(
successCallback,
errorCallback,
maxRetryCallback,
pollingCallback,
preFunction,
clientID = null
) {
if (typeof preFunction === "function") {
preFunction();
}
closePlexOAuthWindow();
plex_oauth_window = PopupCenter("", "Plex-OAuth", 600, 700);
$(plex_oauth_window.document.body).html(plex_oauth_loader);
getPlexOAuthPin().then(
function (data) {
var x_plex_headers = getPlexHeaders();
const pin = data.pin;
const code = data.code;
var oauth_params = {
clientID: x_plex_headers["X-Plex-Client-Identifier"],
"context[device][product]": x_plex_headers["X-Plex-Product"],
"context[device][version]": x_plex_headers["X-Plex-Version"],
"context[device][platform]": x_plex_headers["X-Plex-Platform"],
"context[device][platformVersion]":
x_plex_headers["X-Plex-Platform-Version"],
"context[device][device]": x_plex_headers["X-Plex-Device"],
"context[device][deviceName]": x_plex_headers["X-Plex-Device-Name"],
"context[device][model]": x_plex_headers["X-Plex-Model"],
"context[device][screenResolution]":
x_plex_headers["X-Plex-Device-Screen-Resolution"],
"context[device][layout]": "desktop",
code: code,
};
plex_oauth_window.location =
"https://app.plex.tv/auth/#!?" + encodeData(oauth_params);
polling = pin;
let maxPollCount = 120;
(function poll() {
maxPollCount--;
$.ajax({
url: "https://plex.tv/api/v2/pins/" + pin,
type: "GET",
headers: x_plex_headers,
success: function (data) {
if (data.authToken) {
polling = null;
closePlexOAuthWindow();
if (typeof successCallback === "function") {
successCallback("plex", data.authToken, clientID);
}
}
},
complete: function () {
if (maxPollCount <= 0) {
closePlexOAuthWindow();
if (typeof maxRetryCallback === "function") {
maxRetryCallback();
}
} else if (polling === pin) {
setTimeout(function () {
poll();
}, 1000);
if (typeof pollingCallback === "function") {
pollingCallback(maxPollCount);
}
}
},
timeout: 1000,
});
})();
},
function () {
closePlexOAuthWindow();
if (typeof errorCallback === "function") {
errorCallback();
}
}
);
}
function openOAuth(provider) {
// will actually fix this later
closePlexOAuthWindow();
plex_oauth_window = PopupCenter("", "OAuth", 600, 700);
$(plex_oauth_window.document.body).html(plex_oauth_loader);
plex_oauth_window.location = "api/v2/oauth/trakt";
}
function encodeData(data) {
return Object.keys(data)
.map(function (key) {
return [key, data[key]].map(encodeURIComponent).join("=");
})
.join("&");
}
function oAuthSuccess(type, token, id = null) {
switch (type) {
case "plex":
if (id) {
$(id).val(token);
$(id).change();
messageSingle(
"",
window.lang.translate("Grabbed Token - Please Save"),
activeInfo.settings.notifications.position,
"#FFF",
"success",
"5000"
);
} else {
$("#oAuth-Input").val(token);
$("#oAuthType-Input").val(type);
$("#login-username-Input").addClass("hidden");
$("#login-password-Input").addClass("hidden");
$("#oAuth-div").removeClass("hidden");
$(".login-button").first().trigger("click");
}
break;
default:
break;
}
}
function oAuthError() {
messageSingle(
"",
window.lang.translate("Error Connecting to oAuth Provider"),
activeInfo.settings.notifications.position,
"#FFF",
"error",
"5000"
);
}
function oAuthMaxRetry() {
messageSingle(
"",
window.lang.translate("Max Retry Error Connecting to oAuth Provider"),
activeInfo.settings.notifications.position,
"#FFF",
"error",
"5000"
);
}
function oAuthStart(type) {
switch (type) {
case "plex":
PlexOAuth(oAuthSuccess, oAuthError, oAuthMaxRetry, null, null);
break;
default:
break;
}
}
function oidcStart(provider) {
// Redirect in same window to OIDC provider
window.location.href =
"api/v2/oidc/" + encodeURIComponent(provider) + "/authorize";
}
function testOIDCConnection(provider) {
organizrAPI2(
"GET",
"api/v2/oidc/" + encodeURIComponent(provider) + "/test",
""
)
.success(function (data) {
if (data.response.result === "success") {
messageSingle(
"OIDC Test",
data.response.message || "Connection successful",
activeInfo.settings.notifications.position,
"#FFF",
"success",
"5000"
);
} else {
messageSingle(
"OIDC Test",
data.response.message || "Connection failed",
activeInfo.settings.notifications.position,
"#FFF",
"error",
"5000"
);
}
})
.fail(function (xhr) {
var msg = "Connection failed";
try {
var resp = JSON.parse(xhr.responseText);
msg = resp.response.message || msg;
} catch (e) {}
messageSingle(
"OIDC Test",
msg,
activeInfo.settings.notifications.position,
"#FFF",
"error",
"5000"
);
});
}
function clearAJAX(id = "all") {
if (id == "all") {
$.each(timeouts, function (i, v) {
clearTimeout(timeouts[i]);
});
} else if (id == "homepage") {
$.each(timeouts, function (i, v) {
if (i.indexOf("-Homepage") > 0) {
clearTimeout(timeouts[i]);
}
});
} else {
clearTimeout(timeouts[id]);
}
}
//Generate API
function generateCode() {
var code = "";
var possible = "abcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 20; i++)
code += possible.charAt(Math.floor(Math.random() * possible.length));
return code;
}
// uppercase word
function toUpper(str) {
return str
.toLowerCase()
.split(" ")
.map(function (word) {
return word[0].toUpperCase() + word.substr(1);
})
.join(" ");
}
// human filesize
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) {
return bytes + " B";
}
var units = si
? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
: ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + " " + units[u];
}
//youtube search
function youtubeSearch(searchQuery) {
return $.ajax({
url: "api/v2/homepage/youtube/" + searchQuery,
});
}
function youtubeCheck(title, link) {
youtubeSearch(title)
.success(function (data) {
var response = data.response;
if (response.data) {
inlineLoad();
var id = response.data.items["0"].id.videoId;
var div =
`
`;
$(".youtube-div").html(div);
$("." + link).trigger("click");
player = new Plyr("#player-" + link);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr, "YouTube API Error");
// Fallback: open YouTube search in a new tab/window
var q = "";
try {
q = decodeURIComponent(title);
} catch (e1) {
try {
q = unescape(title);
} catch (e2) {
q = title;
}
}
var url =
"https://www.youtube.com/results?search_query=" +
encodeURIComponent(q + " trailer");
window.open(url, "_blank");
});
}
function requestSearch(title, page = 1) {
return $.ajax({
url:
"https://api.themoviedb.org/3/search/multi?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"&query=" +
title +
"&page=" +
page +
"&include_adult=false",
});
}
function requestSearchList(list, page = 1) {
var url = "";
switch (list) {
case "top-movie":
url =
"https://api.themoviedb.org/3/movie/top_rated?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"®ion=US&page=" +
page;
break;
case "pop-movie":
url =
"https://api.themoviedb.org/3/movie/popular?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"®ion=US&page=" +
page;
break;
case "up-movie":
url =
"https://api.themoviedb.org/3/movie/upcoming?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"®ion=US&page=" +
page;
break;
case "theatre-movie":
url =
"https://api.themoviedb.org/3/movie/now_playing?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"®ion=US&page=" +
page;
break;
case "top-tv":
url =
"https://api.themoviedb.org/3/tv/top_rated?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"®ion=US&page=" +
page;
break;
case "pop-tv":
url =
"https://api.themoviedb.org/3/tv/popular?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"®ion=US&page=" +
page;
break;
case "today-tv":
url =
"https://api.themoviedb.org/3/tv/airing_today?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"®ion=US&page=" +
page;
break;
case "org-mod":
url =
"https://api.themoviedb.org/4/list/64438?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=" +
activeInfo.language +
"&page=" +
page;
break;
default:
}
return $.ajax({
url: url,
});
}
function requestNewID(id) {
return $.ajax({
url:
"https://api.themoviedb.org/3/tv/" +
id +
"/external_ids?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&language=en-US",
});
}
function getTmdbImages(id, type) {
return $.ajax({
url: `https://api.themoviedb.org/3/${type}/${id}/images?api_key=83cf4ee97bb728eeaf9d4a54e64356a1`,
});
}
function inlineLoad() {
$(".inline-popups").magnificPopup({
removalDelay: 500, //delay removal by X to allow out-animation
closeOnBgClick: true,
//closeOnContentClick: true,
callbacks: {
beforeOpen: function () {
this.st.mainClass = this.st.el.attr("data-effect");
this.st.focus = "#request-input";
},
close: function () {
if (typeof player !== "undefined") {
player.destroy();
}
},
},
midClick: true, // allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source.
});
}
//Import Users
function importUsers(type) {
$(".importUsersButton").attr("disabled", true);
messageSingle(
"",
window.lang.translate("Importing Users"),
activeInfo.settings.notifications.position,
"#FFF",
"success",
"5000"
);
organizrAPI2("POST", "api/v2/users/import/" + type, { type: type })
.success(function (data) {
try {
var response = data.response;
message(
"User Import",
response.message,
activeInfo.settings.notifications.position,
"#FFF",
"success",
"5000"
);
$(".importUsersButton").attr("disabled", false);
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr, "Import Error");
});
}
//Settings change auth
function changeAuth() {
var type = $("#authSelect").val();
var service = $("#authBackendSelect").val();
switch (service) {
case "plex":
$(".switchAuth").parent().parent().parent().hide();
$(".backendAuth").parent().parent().parent().show();
$(".plexAuth").parent().parent().parent().show();
break;
case "emby_local":
case "emby_connect":
case "emby_all":
$(".switchAuth").parent().parent().parent().hide();
$(".backendAuth").parent().parent().parent().show();
$(".embyAuth").parent().parent().parent().show();
break;
case "jellyfin":
$(".switchAuth").parent().parent().parent().hide();
$(".backendAuth").parent().parent().parent().show();
$(".jellyfinAuth").parent().parent().parent().show();
break;
case "ftp":
$(".switchAuth").parent().parent().parent().hide();
$(".backendAuth").parent().parent().parent().show();
$(".ftpAuth").parent().parent().parent().show();
break;
case "ldap":
$(".switchAuth").parent().parent().parent().hide();
$(".backendAuth").parent().parent().parent().show();
$(".ldapAuth").parent().parent().parent().show();
break;
default:
$(".switchAuth").parent().parent().parent().hide();
$(".backendAuth").parent().parent().parent().show();
}
if (type == "internal") {
$(".switchAuth").parent().parent().parent().hide();
}
}
function organizrSpecialSettings(array) {
//media search
if (
array.settings.homepage.search.enabled == true &&
typeof array.settings.homepage.search.type !== "undefined"
) {
var htmlDOM = `
`;
var searchBoxResults =
`
`;
$(htmlDOM).prependTo(".navbar-right");
$(searchBoxResults).appendTo($(".organizr-area"));
}
}
function checkLocalForwardStatus(array) {
if (
array.settings.login.enableLocalAddressForward == true &&
typeof array.settings.login.enableLocalAddressForward !== "undefined"
) {
if (
array.settings.login.wanDomain !== "" &&
array.settings.login.localAddress !== ""
) {
organizrConsole("Organizr Function", "Local Login Enabled");
organizrConsole("Organizr Function", "Local Login Testing...");
let remoteSite = array.settings.login.wanDomain;
let localSite = array.settings.login.localAddress;
try {
let currentURL = decodeURI(window.location.href);
let currentSite = window.location.host;
if (
activeInfo.settings.user.local &&
currentSite.indexOf(remoteSite) !== -1 &&
currentURL.indexOf("override") === -1
) {
organizrConsole(
"Organizr Function",
"Local Login Status: Local | Forwarding Now"
);
window.location = localSite;
} else {
organizrConsole(
"Organizr Function",
"Local Login Status: Not Local or Override was set - Ignoring Forward Request"
);
}
} catch (e) {
console.error(e);
}
}
}
}
function forceSearch(term) {
$.magnificPopup.close();
let tabInfo = findTab("api/v2/page/homepage", "access_url");
if (tabInformation[tabInfo.id]["loaded"]) {
if (tabInformation[tabInfo.id]["active"]) {
setTimeout(function () {
$("#newRequestButton").trigger("click");
$("#request-input").val(term);
doneTyping();
}, 500);
} else {
tabActions("click", tabInfo.id);
setTimeout(function () {
$("#newRequestButton").trigger("click");
$("#request-input").val(term);
doneTyping();
}, 1000);
}
} else {
tabActions("click", tabInfo.id);
setTimeout(function () {
$("#newRequestButton").trigger("click");
$("#request-input").val(term);
doneTyping();
}, 3000);
}
}
function splitPoster(str) {
var words = str.split(" ");
var newWord = "";
$.each(words, function (i, v) {
newWord += v + " ";
});
return newWord;
}
function buildMediaResults(array, source, term) {
if (array.content.length == 0) {
var none =
'
No Results for:
' +
term +
"
";
none +=
activeInfo.settings.homepage.ombi.enabled == true ||
activeInfo.settings.homepage.overseerr.enabled == true
? ``
: "";
return none;
}
var results = "";
var tv = 0;
var movie = 0;
var music = 0;
var total = 0;
$.each(array.content, function (i, v) {
total = total + 1;
tv = v.type == "tv" ? tv + 1 : tv;
movie = v.type == "movie" ? movie + 1 : movie;
music = v.type == "music" ? music + 1 : music;
var bg = v.imageURL;
var top = v.title;
var bottom = v.metadata.originallyAvailableAt;
results +=
`
`;
swal({
content: createElementFromHTML(div),
buttons: false,
className: "orgAlertTransparent",
});
pageLoad();
}
function checkToken(activate = false) {
if (typeof activeInfo !== "undefined") {
if (typeof activeInfo.settings.misc.uuid !== "undefined") {
var token = getCookie("organizr_token_" + activeInfo.settings.misc.uuid);
if (token) {
setTimeout(function () {
checkToken(true);
}, 5000);
} else {
if (activate) {
local(
"set",
"message",
"Token Expired|You have been logged out|error"
);
location.reload();
}
}
}
}
}
function objDiff(obj1, obj2) {
// Make sure an object to compare is provided
if (!obj2 || Object.prototype.toString.call(obj2) !== "[object Object]") {
return obj1;
}
//
// Variables
//
var diffs = {};
var key;
//
// Methods
//
/**
* Check if two arrays are equal
* @param {Array} arr1 The first array
* @param {Array} arr2 The second array
* @return {Boolean} If true, both arrays are equal
*/
var arraysMatch = function (arr1, arr2) {
// Check if the arrays are the same length
if (arr1.length !== arr2.length) return false;
// Check if all items exist and are in the same order
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) return false;
}
// Otherwise, return true
return true;
};
/**
* Compare two items and push non-matches to object
* @param {*} item1 The first item
* @param {*} item2 The second item
* @param {String} key The key in our object
*/
var compare = function (item1, item2, key) {
// Get the object type
var type1 = Object.prototype.toString.call(item1);
var type2 = Object.prototype.toString.call(item2);
// If type2 is undefined it has been removed
if (type2 === "[object Undefined]") {
diffs[key] = null;
return;
}
// If items are different types
if (type1 !== type2) {
diffs[key] = item2;
return;
}
// If an object, compare recursively
if (type1 === "[object Object]") {
var objDifference = objDiff(item1, item2);
if (Object.keys(objDifference).length > 1) {
diffs[key] = objDifference;
}
return;
}
// If an array, compare
if (type1 === "[object Array]") {
if (!arraysMatch(item1, item2)) {
diffs[key] = item2;
}
return;
}
// Else if it's a function, convert to a string and compare
// Otherwise, just compare
if (type1 === "[object Function]") {
if (item1.toString() !== item2.toString()) {
diffs[key] = item2;
}
} else {
if (item1 !== item2) {
diffs[key] = item2;
}
}
};
//
// Compare our objects
//
// Loop through the first object
for (key in obj1) {
if (obj1.hasOwnProperty(key)) {
compare(obj1[key], obj2[key], key);
}
}
// Loop through the second object and find missing items
for (key in obj2) {
if (obj2.hasOwnProperty(key)) {
if (!obj1[key] && obj1[key] !== obj2[key]) {
diffs[key] = obj2[key];
}
}
}
// Return the object of differences
return diffs;
}
function organizrConsole(subject, msg, type = "info") {
let color;
switch (type) {
case "error":
color = "#ed2e72";
break;
case "warning":
color = "#272361";
break;
default:
color = "#2cabe3";
break;
}
console.info(
"%c " + subject + " %c ".concat(msg, " "),
"color: white; background: " + color + "; font-weight: 700;",
"color: " + color + "; background: white; font-weight: 700;"
);
}
function organizrCatchError(e, data) {
organizrConsole("Organizr API Function", data, "warning");
orgErrorAlert(
"
" +
e +
'
Trace Log has been outputted to Browser Console
Output of last API call
' +
formatDebug(data)
);
console.trace();
return false;
}
function OrganizrApiError(xhr, secondaryMessage = null) {
let msg = "";
if (typeof xhr.responseJSON !== "undefined") {
msg = xhr.responseJSON.response.message;
} else if (typeof xhr.statusText !== "undefined") {
msg = xhr.statusText;
} else if (typeof xhr.responseText !== "undefined") {
msg = xhr.responseText;
} else {
msg = "Connection Error";
}
organizrConsole("Organizr API Function", msg, "error");
if (msg !== "abort") {
if (secondaryMessage) {
messageSingle(
secondaryMessage,
msg,
activeInfo.settings.notifications.position,
"#FFF",
"error",
"10000"
);
}
console.trace();
}
return false;
}
function checkForUpdates() {
if (
activeInfo.user.loggedin &&
activeInfo.user.groupID <= 1 &&
activeInfo.settings.misc.checkForUpdate
) {
updateCheck();
checkCommitLoad();
checkPluginUpdates();
}
}
function loadJavascript(script = null, defer = false) {
if (script) {
organizrConsole("JS Loader", script);
organizrConsole("JS Loader", "Checking if script is loaded...");
let loaded = $('script[src="' + script + '"]').length;
if (!loaded) {
organizrConsole("JS Loader", "Script is NOT loaded... Loading now...");
let head = document.getElementsByTagName("head")[0];
let scriptEl = document.createElement("script");
scriptEl.type = "text/javascript";
scriptEl.src = script;
scriptEl.defer = false;
head.appendChild(scriptEl);
} else {
organizrConsole("JS Loader", "Script already loaded");
}
}
}
function tabShit() {}
function msToTime(s) {
let pad = (n, z = 2) => ("00" + n).slice(-z);
let hours = pad((s / 3.6e6) | 0) !== "00" ? pad((s / 3.6e6) | 0) + ":" : "";
let mins = pad(((s % 3.6e6) / 6e4) | 0) + ":";
let secs = pad(((s % 6e4) / 1000) | 0);
let ms = pad(s % 1000, 3);
if (ms >= "500") {
secs = pad(parseFloat(secs) + 1, 2);
}
return hours + mins + secs;
}
function clickSettingsTab() {
let tabs = $(".allTabsList");
$.each(tabs, function (i, v) {
let tab = $(v);
if (tab.attr("data-url") == "api/v2/page/settings") {
tab.find("a").trigger("click");
}
});
}
function clickMenuItem(selector) {
if ($(selector).length >= 1) {
$(selector).click();
} else {
$("body").arrive(selector, { onceOnly: true }, function () {
$(selector).click();
});
}
}
function shortcut(selectors = "") {
let timeout = 200;
if (typeof selectors == "string") {
if (selectors == "") {
selectors = [];
} else {
switch (selectors) {
case "log-settings":
clickSettingsTab();
selectors = [
"#settings-main-system-settings-anchor",
"#settings-settings-main-anchor",
'a[href$="Logs"]',
];
break;
case "plugin-marketplace":
clickSettingsTab();
selectors = [
"#settings-main-plugins-anchor",
"#settings-plugins-marketplace-anchor",
];
break;
case "custom-cert":
clickSettingsTab();
selectors = [
"#settings-main-system-settings-anchor",
"#settings-settings-main-anchor",
'a[href$="Certificate"]',
];
break;
default:
clickSettingsTab();
selectors = ["#settings-main-system-settings-anchor"];
}
}
}
selectors.forEach(function (selector) {
timeout = timeout + 200;
setTimeout(function () {
clickMenuItem(selector);
}, timeout);
});
}
function getJournalMode() {
organizrAPI2("GET", "api/v2/database/journal")
.success(function (data) {
try {
let response = data.response;
$(".journal-mode").html(response.data.journal_mode);
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function setJournalMode(mode) {
messageSingle(
"Setting New Journal Mode",
"",
activeInfo.settings.notifications.position,
"#FFF",
"info",
"1500"
);
organizrAPI2("PUT", "api/v2/database/journal/" + mode, {})
.success(function (data) {
try {
getJournalMode();
let response = data.response;
message(
"Set New Journal Mode",
response.data.journal_mode,
activeInfo.settings.notifications.position,
"#FFF",
"success",
"5000"
);
} catch (e) {
organizrCatchError(e, data);
}
})
.fail(function (xhr) {
OrganizrApiError(xhr);
});
}
function toggleSideMenuClasses() {
$("#page-wrapper").toggleClass("sidebar-hidden");
$(".sidebar").toggleClass("sidebar-hidden");
$(".navbar").toggleClass("sidebar-hidden");
}
function sideMenuCollapsed() {
if (activeInfo.settings.misc.sideMenuCollapsed) {
toggleSideMenuClasses();
}
}
function toggleSideMenu() {
toggleSideMenuClasses();
$(".sidebar-head .open-close i")
.first()
.toggleClass("ti-menu ti-shift-left mouse");
$(".toggle-side-menu").toggleClass("hidden");
}
function toggleTopBarHamburger() {
toggleSideMenuClasses();
$(".sidebar-head .hide-menu.hidden-xs").text("Hide Menu");
$(".sidebar-head .open-close i")
.first()
.toggleClass("ti-menu ti-shift-left mouse");
$(".toggle-side-menu").toggleClass("hidden");
}
function toggleLogFilter(filter = "INFO") {
//choose-organizr-log
filter = filter.toUpperCase();
$.each($(".choose-organizr-log").children(), function (i, v) {
let url = $(v).val();
let newURL = updateUrlParameter(url, "filter", filter);
$(v).val(newURL);
});
$(".log-filter-text").text(filter);
$(".log-filter-text").text(filter);
let currentURL = organizrLogTable.ajax.url();
let updatedURL = updateUrlParameter(currentURL, "filter", filter);
organizrLogTable.ajax.url(updatedURL);
organizrLogTable.clear().draw().ajax.reload(null, false);
}
function updateUrlParameter(uri, key, value) {
// remove the hash part before operating on the uri
var i = uri.indexOf("#");
var hash = i === -1 ? "" : uri.substr(i);
uri = i === -1 ? uri : uri.substr(0, i);
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf("?") !== -1 ? "&" : "?";
if (value === null) {
// remove key-value pair if value is specifically null
uri = uri.replace(new RegExp("([?&]?)" + key + "=[^&]*", "i"), "");
if (uri.slice(-1) === "?") {
uri = uri.slice(0, -1);
}
// replace first occurrence of & by ? if no ? is present
if (uri.indexOf("?") === -1) uri = uri.replace(/&/, "?");
} else if (uri.match(re)) {
uri = uri.replace(re, "$1" + key + "=" + value + "$2");
} else {
uri = uri + separator + key + "=" + value;
}
return uri + hash;
}
function launch() {
console.info(
"https://docs.organizr.app/help/faq/migration-guide#version-2-0-greater-than-version-2-1"
);
organizrConsole(
"API V2 API",
"If you see a 404 Error for api/v2/launch below this line, you have not setup the new location block... See URL above this line",
"error"
);
organizrConnect("api/v2/launch")
.success(function (data) {
try {
let json = data.response;
if (json.data.user == false) {
location.reload();
}
currentVersion = json.data.version;
activeInfo = {
tabs: json.data.tabs,
categories: json.data.categories,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
offest: new Date().getTimezoneOffset(),
language: language(moment.locale(navigator.languages[0])),
browserVersion: bowser.name,
browserName: bowser.version,
mobile: bowser.mobile,
tablet: bowser.tablet,
osName: bowser.osname,
osVersion: bowser.osversion,
serverOS: json.data.status.os,
phpVersion: json.data.status.php,
token: json.data.user.token,
user: json.data.user,
plugins: json.data.plugins,
branch: json.data.branch,
sso: json.data.sso,
settings: json.data.settings,
appearance: json.data.appearance,
theme: json.data.theme,
style: json.data.style,
version: json.data.version,
};
// Add element to signal activeInfo Ready
$("#wrapper").after('');
console.info(
"%c Organizr %c ".concat(currentVersion, " "),
"color: white; background: #66D9EF; font-weight: 700; font-size: 24px; font-family: Monospace;",
"color: #66D9EF; background: white; font-weight: 700; font-size: 24px; font-family: Monospace;"
);
console.info(
"%c Status %c ".concat("Starting Up...", " "),
"color: white; background: #F92671; font-weight: 700;",
"color: #F92671; background: white; font-weight: 700;"
);
//local('set','initial',true);
//setTimeout(function(){ local('r','initial'); }, 300);
defineNotification();
checkMessage();
errorPage();
uriRedirect();
changeStyle(activeInfo.style);
//changeTheme(activeInfo.theme);
setSSO();
checkToken();
switch (json.data.status.status) {
case "wizard":
buildWizard();
buildLanguage("wizard");
break;
case "dependencies":
buildDependencyCheck(json);
break;
case "ok":
loadAppearance(json.data.appearance);
sideMenuCollapsed();
if (activeInfo.user.locked == 1) {
buildLockscreen();
} else {
userMenu(json);
categoryProcess(json);
tabProcess(json);
buildSplashScreen(json);
accountManager(json);
organizrSpecialSettings(json.data);
getPingList(json);
checkLocalForwardStatus(json.data);
checkForUpdates();
}
loadCustomJava(json.data.appearance);
if (getCookie("lockout")) {
$(".show-login").click();
setTimeout(function () {
$("div.login-box").block({
message: '
` + array.company_name + `
` + array.about + extraInfo + `