// EBook Columns // (c) 2020 Steve Banham var pathCalibre; var arrLines = []; var arrCache = []; var cacheResult = ""; var cachePath; var busyAbort = false; scriptName = "Ebook Columns"; scriptVersion = "1.5"; scriptDate = "15/6/2020"; scriptCopyright = "(c) 2020 Steve Banham"; scriptMinVersion = "12.20"; scriptDesc = "Display author, title, series, tags and year of ebooks in DOpus columns."; function OnInit(initData) { initData.name = scriptName; initData.version = scriptVersion; initData.copyright = scriptCopyright; initData.desc = scriptDesc; initData.default_enable = true; initData.min_version = scriptMinVersion; initData.url = "https://resource.dopus.com/t/ebook-columns/35114"; initData.config_desc = DOpus.Create.Map(); initData.config_groups = DOpus.Create.Map(); var configName = ""; configName = "directories"; initData.Config[configName] = ""; initData.config_desc(configName) = "String to show for any directory (Can be blank)."; configName = "non_ebook_files"; initData.Config[configName] = "---"; initData.config_desc(configName) = "String to show for non ebook files (Can be blank)."; configName = "series_show_index"; initData.Config[configName] = true; initData.config_desc(configName) = "Include the series index in the series column."; configName = "calibre_path"; initData.Config[configName] = "C:\\Program Files (x86)\\Calibre2"; initData.config_desc(configName) = "The path to your Calibre installation."; configName = "cache_path"; initData.Config[configName] = "/localappdata\\EbookColumns"; initData.config_desc(configName) = "Storage location for the cache file."; configName = "use_cache"; initData.Config[configName] = true; initData.config_desc(configName) = "Use a cache file to store ebook metadata to speed up future access."; var col = initData.AddColumn(); col.name = "EbookAuthor"; col.method = "onEbookCol"; col.label = "Ebook Author"; col.header = "Ebook Author"; col.autogroup = true; col.autorefresh = true; col.justify = "left"; col.multicol = true; var col = initData.AddColumn(); col.name = "EbookTitle"; col.method = "onEbookCol"; col.label = "Ebook Title"; col.header = "Ebook Title"; col.autogroup = true; col.autorefresh = true; col.justify = "left"; col.multicol = true; var col = initData.AddColumn(); col.name = "EbookSeries"; col.method = "onEbookCol"; col.label = "Ebook Series"; col.header = "Ebook Series"; col.autogroup = true; col.autorefresh = true; col.justify = "left"; col.multicol = true; var col = initData.AddColumn(); col.name = "EbookSeriesNum"; col.method = "onEbookCol"; col.label = "Ebook Series #"; col.header = "Ebook Series #"; col.autogroup = true; col.autorefresh = true; col.justify = "center"; col.multicol = true; var col = initData.AddColumn(); col.name = "EbookTags"; col.method = "onEbookCol"; col.label = "Ebook Tags"; col.header = "Ebook Tags"; col.autogroup = true; col.autorefresh = true; col.justify = "left"; col.multicol = true; var col = initData.AddColumn(); col.name = "EbookYear"; col.method = "onEbookCol"; col.label = "Ebook Year"; col.header = "Ebook Year"; col.autogroup = true; col.autorefresh = true; col.justify = "left"; col.multicol = true; } function onEbookCol(scriptColData) { var fso = new ActiveXObject("Scripting.FilesystemObject"); cachePath = DOpus.FSUtil.Resolve(Script.Config["cache_path"]); if (Script.Config["use_cache"] == true) { if (!DOpus.FSUtil.Exists(cachePath)) { if (!fso.CreateFolder(cachePath)) { DOpus.Output("Unable to create cache file, check settings."); return false; } } cachePath = cachePath + "\\EbookColumns.cache"; } pathCalibre = Script.Config["calibre_path"]; if (pathCalibre.substr(-1) == "\\") { pathCalibre = pathCalibre.substr(0, pathCalibre.length - 1); } if (scriptColData.item.is_dir) { scriptColData.columns("EbookAuthor").value = Script.Config["directories"]; scriptColData.columns("EbookTitle").value = Script.Config["directories"]; scriptColData.columns("EbookSeries").value = Script.Config["directories"]; scriptColData.columns("EbookSeriesNum").value = Script.Config["directories"]; scriptColData.columns("EbookTags").value = Script.Config["directories"]; scriptColData.columns("EbookYear").value = Script.Config["directories"]; return; } if (scriptColData.item.ext == ".epub" || scriptColData.item.ext == ".azw3" || scriptColData.item.ext == ".mobi"){ var itemHash = DOpus.FSUtil.Hash(scriptColData.item.realpath); if (Script.Config["use_cache"] == true) { if (readCache(scriptColData, itemHash)) { parseCache(scriptColData, itemHash); } else if (readCalibre(scriptColData)) { parseCalibre(scriptColData, itemHash); } } else { if (readCalibre(scriptColData)) { parseCalibre(scriptColData, itemHash); } } } else { scriptColData.columns("EbookAuthor").value = Script.Config["non_ebook_files"]; scriptColData.columns("EbookTitle").value = Script.Config["non_ebook_files"]; scriptColData.columns("EbookSeries").value = Script.Config["non_ebook_files"]; scriptColData.columns("EbookSeriesNum").value = Script.Config["non_ebook_files"]; scriptColData.columns("EbookTags").value = Script.Config["non_ebook_files"]; scriptColData.columns("EbookYear").value = Script.Config["non_ebook_files"]; } } function parseCalibre(scriptColData, itemHash) { for (i=0; i < arrLines.length; i ++) { if (arrLines[i].search("Author") > -1) { var strAuthor = arrLines[i].substring(22); var hasSortField = strAuthor.search("\\["); if (hasSortField > -1) { strAuthor = strAuthor.substring(0,hasSortField); } strAuthor = strAuthor.replace(/^\s+|\s+$/gm,''); } if (arrLines[i].search("Title") > -1) { if (arrLines[i].search("Title sort") == -1) { var strTitle = arrLines[i].substring(22); strTitle = strTitle.replace(/^\s+|\s+$/gm,''); } } if (arrLines[i].search("Series") > -1) { var strSeries = "-"; strSeries = arrLines[i].substring(22); var hasSeriesNum = strSeries.search("#"); if (hasSeriesNum > -1) { var strSeriesNum = "-"; strSeriesNum = strSeries.slice(hasSeriesNum); strSeries = strSeries.substring(0,hasSeriesNum); strSeriesNum = strSeriesNum.replace("#",""); } else { strSeriesNum = " "; } if (Script.Config["series_show_index"] == true) { strSeries = strSeries + " #" + strSeriesNum; } } if (arrLines[i].search("Tags") > -1) { var strTags = arrLines[i].substring(22); strTags = strTags.replace(/^\s+|\s+$/gm,''); } if (arrLines[i].search("Published") > -1) { var strYear = arrLines[i].substring(22,26); strYear = strYear.replace(/^\s+|\s+$/gm,''); } if (strAuthor == undefined) strAuthor = " "; scriptColData.columns("EbookAuthor").value = strAuthor; if (strTitle == undefined) strTitle = " "; scriptColData.columns("EbookTitle").value = strTitle; if (strSeries == undefined) strSeries = " "; scriptColData.columns("EbookSeries").value = strSeries; if (strSeriesNum == undefined) strSeriesNum = " "; scriptColData.columns("EbookSeriesNum").value = strSeriesNum; if (strTags == undefined) strTags = " "; scriptColData.columns("EbookTags").value = strTags; if (strYear == undefined) strYear = " "; scriptColData.columns("EbookYear").value = strYear; } if (Script.Config["use_cache"] == true) { var fso = new ActiveXObject("Scripting.FilesystemObject"); var cacheData = fso.OpenTextFile(cachePath, 8, true, 0); cacheData.WriteLine("[" + itemHash + "] Author=\"" + strAuthor + "\" Title=\"" + strTitle + "\" Series=\"" + strSeries + "\" Num=\"" + strSeriesNum + "\" Tags=\"" + strTags + "\" Year=\"" + strYear + "\""); cacheData.Close(); } } function parseCache(scriptColData, itemHash) { var authorStart = cacheResult.search("Author="); var titleStart = cacheResult.search("Title="); var seriesStart = cacheResult.search("Series="); var numStart = cacheResult.search("Num="); var tagsStart = cacheResult.search("Tags="); var yearStart = cacheResult.search("Year="); if (cacheResult.search("Author=")) { var strAuthor = cacheResult.substring(authorStart + 7, titleStart - 2); strAuthor = strAuthor.replace(/\"/g, ""); } else strAuthor = ""; if (cacheResult.search("Title=")) { var strTitle = cacheResult.substring(titleStart + 6, seriesStart - 2); strTitle = strTitle.replace(/\"/g, ""); } else strTitle = ""; if (cacheResult.search("Series=")) { var strSeries = cacheResult.substring(seriesStart + 7, numStart - 2); strSeries = strSeries.replace(/\"/g, ""); } else strSeries = ""; if (cacheResult.search("Num=")) { var strNum = cacheResult.substring(numStart + 4, tagsStart - 2); strNum = strNum.replace(/\"/g, ""); } else strNum = ""; if (cacheResult.search("Tags=")) { var strTags = cacheResult.substring(tagsStart + 5, yearStart - 2); strTags = strTags.replace(/\"/g, ""); } else strTags = ""; if (cacheResult.search("Year=")) { var strYear = cacheResult.substring(yearStart + 5); strYear = strYear.replace(/\"/g, ""); } else strYear = ""; if (strAuthor == undefined) strAuthor = " "; scriptColData.columns("EbookAuthor").value = strAuthor; if (strTitle == undefined) strTitle = " "; scriptColData.columns("EbookTitle").value = strTitle; if (strSeries == undefined) strSeries = " "; scriptColData.columns("EbookSeries").value = strSeries; if (strNum == undefined) strNum = " "; scriptColData.columns("EbookSeriesNum").value = strNum; if (strTags == undefined) strTags = " "; scriptColData.columns("EbookTags").value = strTags; if (strYear == undefined) strYear = " "; scriptColData.columns("EbookYear").value = strYear; } function readCache(scriptColData, itemHash) { var fso = new ActiveXObject("Scripting.FilesystemObject"); if (Script.Config["use_cache"] == true) { var cacheData = fso.OpenTextFile(cachePath, 1, true, 0); if (!cacheData.AtEndOfStream) { var content = cacheData.ReadAll(); arrCache = content.split(/\r\n|\n/); } cacheData.Close(); for (i=0; i < arrCache.length; i ++) { if (arrCache[i].search(itemHash) > -1) { cacheResult = String(arrCache[i]); return true; } } return false; } } function readCalibre(scriptColData){ var cmd = DOpus.Create.command; cmd.SetType("msdos"); cmd.SetModifier("runmode","hide"); var fso = new ActiveXObject("Scripting.FilesystemObject"); var tmpFolder = fso.GetSpecialFolder(2); var tmpName = fso.GetTempName(); var tmpFile = tmpFolder + "\\" + tmpName; cmd.RunCommand("\"" + pathCalibre + "\\ebook-meta.exe\" " + "\"" + scriptColData.item.realpath + "\"" + " > " + tmpFile); var tmpDataFile = fso.OpenTextFile(tmpFile, 1, 0); if (!tmpDataFile.AtEndOfStream) { var content = tmpDataFile.ReadAll(); arrLines = content.split(/\r\n|\n/); } tmpDataFile.Close(); cmd.RunCommand("DELETE NORECYCLE QUIET \"" + tmpFile + "\""); return true; } function OnScriptConfigChange() { Script.RefreshColumn("EbookAuthor"); Script.RefreshColumn("EbookTitle"); Script.RefreshColumn("EbookSeries"); Script.RefreshColumn("EbookSeriesNum") Script.RefreshColumn("EbookTags"); Script.RefreshColumn("EbookYear"); } function OnAboutScript(aboutData){ dlg = DOpus.Dlg; dlg.window = aboutData.window; dlg.title = scriptName + " " + scriptVersion; dlg.message = scriptName + " v" + scriptVersion + "\t\t\t\t" + scriptDate + "\n\n" + scriptDesc + "\n\n" + scriptCopyright; dlg.buttons = "Close"; dlg.icon = "info"; dlg.show; }