repoindex/web/js/packagemanagement.js

350 lines
18 KiB
JavaScript

var repoindex = (function(repoindex) {
repoindex.softwareUpgradeBackgroundColor = "#dfffdd";
repoindex.packageUpgradeBackgroundColor = "#dde3ff";
repoindex.downgradesBackgroundColor = "#ffeecb";
repoindex.orphanedPackageBackgroundColor = "#fdd";
var PackageEntry = {};
PackageEntry.prototype = new repoindex.Entry();
PackageEntry.prototype.constructor = PackageEntry;
PackageEntry = function(repoEntry, packageInfo, color) {
this.repoEntry = repoEntry; // might be undefined
repoindex.Entry.prototype.constructor.call(this, packageInfo);
// init row element
if(color) {
this.rowElement.style.backgroundColor = color;
}
this.rowElement.onclick = function() {
repoindex.pageManager.packageManager.showPackageInfoForIndex(this.entry.info.index);
};
this.initTableRow = function() {
var srcOnly = this.repoEntry && this.repoEntry.info.srcOnly;
var values = [srcOnly ? "n/a" : this.info.arch, this.info.repo, this.info.name, this.info.ver, this.info.desc, srcOnly ? "n/a" : this.info.bdate, this.info.flagdate];
for(var i = 0; i < 7; ++i) {
this.rowElement.addCell(repoindex.makeStr(values[i]));
}
};
this.initTableRow();
this.applyBasicInfo = function(info, noUpdate) {
if(info.repo) this.info.repo = info.repo;
if(info.name) this.info.name = info.name;
if(info.arch) this.info.arch = info.arch;
if(info.ver) this.info.ver = info.ver;
if(info.desc) this.info.desc = info.desc;
if(info.bdate) this.info.bdate = info.bdate;
if(info.flagdate) this.info.flagdate = info.flagdate;
this.info.basic = true;
if(!noUpdate) {
this.updateTableRow();
}
};
this.applyFullInfo = function(info, noUpdate) {
this.applyBasicInfo(info);
if(info.idate) this.info.idate = info.idate;
if(info.isize) this.info.isize = info.isize;
if(info.url) this.info.url = info.url;
if(info.isize) this.info.isize = info.isize;
if(info.lic) this.info.lic = info.lic;
if(info.grp) this.info.grp = info.grp;
if(info.prov) this.info.prov = info.prov;
if(info.optd) this.info.optd = info.optd;
if(info.deps) this.info.deps = info.deps;
if(info.requ) this.info.requ = info.requ;
if(info.conf) this.info.conf = info.conf;
if(info.repl) this.info.repl = info.repl;
if(info.pack) this.info.pack = info.pack;
if(info.expl) this.info.expl = info.expl;
if(info.scri) this.info.scri = info.scri;
if(info.sig) this.info.sig = info.sig;
if(info.file) this.info.file = info.file;
if(info.files) this.info.files = info.files;
this.info.full = true;
if(!noUpdate) {
this.updateTableRow();
}
};
};
repoindex.PackageEntryManager = {};
repoindex.PackageEntryManager.prototype = new repoindex.EntryManager();
repoindex.PackageEntryManager = function(pagination, repoEntries) {
repoindex.EntryManager.prototype.constructor.call(this, PackageEntry, document.getElementById("packages"), pagination, repoEntries);
this.entryName = "package";
this.entryNamePlural = "packages";
this.containerName = "repository";
this.containerNamePlural = "repositories";
this.getContainerQuantity = repoindex.entryManagerGetRepoQuantity;
this.createCustomEntry = function(color) {
return new PackageEntry(undefined, {}, color);
};
this.addEntry = function(repoEntry, packageName) {
var packageInfo = {
index: this.entries.length,
repo: repoEntry.info.name,
name: packageName,
received: false
};
var entry = new PackageEntry(repoEntry, packageInfo);
this.entries.push(entry);
return entry;
};
// handle a page selection
this.pagination.pageSelected = function(pageElement) {
var mgr = this.entryManager;
// remove elements from previously selected page
mgr.entryContainer.wipeChildren();
// if there is no page because there are no package entries, pageElement is null
if(pageElement) {
// show elements of selected page
var packageSelection = {}; // package selection for requesting package infos
var entriesRequired = false;
pageElement.forRange(function(i) {
var entry = mgr.filteredEntries[i];
entry.add(mgr.entryContainer);
if(!entry.info.basic) {
var repoArray = packageSelection[entry.info.repo];
if(!Array.isArray(repoArray)) {
packageSelection[entry.info.repo] = [{index: entry.info.index, name: entry.info.name}];
} else {
repoArray.push({index: entry.info.index, name: entry.info.name});
}
entriesRequired = true;
}
}, mgr.filteredEntries.length);
if(entriesRequired) {
var pkgEntries = repoindex.pageManager.packageManager.relevantEntries();
var useBasicPackageInfo = function(values) {
for(var i = 0; i < values.length; ++i) {
var info = values[i];
if(!info.error) {
if(info.index >= 0 && info.index < pkgEntries.length) {
var entry = pkgEntries[info.index];
entry.applyBasicInfo(info);
}
}
}
};
repoindex.alpmClient.requestBasicPackagesInfo(packageSelection, useBasicPackageInfo);
}
}
};
this.infoBox = document.getElementById("packages_info");
this.showPackageInfo = function(repo, name) {
var determineEntry = function() {
var res = repoindex.pageManager.packageManager.entries.filter(function(entry) {
return entry.info.repo === repo && entry.info.name === name;
});
if(res.length > 0) {
repoindex.pageManager.packageManager.showPackageInfoForIndex(res[0].info.index);
} else {
repoindex.pageManager.packageManager.showPackageNotFound(repo, name);
}
};
// basic repo info available?
if(repoindex.alpmClient.hasBasicRepoInfo) {
// yes -> can determine entry instantly
determineEntry();
} else {
// no -> request info, use callback to determine entry when info becomes available
repoindex.alpmClient.requestBasicRepoInfo(determineEntry);
}
};
this.showPackageInfoForIndex = function(entryIndex) {
// check whether specified entry index is valid
var entry = this.entryByIndex(entryIndex);
if(entry) {
var i = entry.info;
// show properties in "Package info" box
var setProperties = function() {
// -> basic package info
repoindex.setPackageNames("pkg_name", [i.name]);
repoindex.setText("pkg_repo", repoindex.makeStr(i.repo));
repoindex.setText("pkg_ver", repoindex.makeStr(i.ver));
repoindex.setText("pkg_desc", repoindex.makeStr(i.desc));
repoindex.setText("pkg_arch", repoindex.makeStr(i.arch));
repoindex.setText("pkg_bdate", repoindex.makeStr(i.bdate));
// -> full package info
if(i.url) {
repoindex.setLink("pkg_url", i.url, i.url, window.open);
} else {
repoindex.setText("pkg_url", "unknown");
}
repoindex.setText("pkg_lic", repoindex.makeArray(i.lic));
repoindex.setPackageNames("pkg_grp", repoindex.pack(i.grp), repoindex.Pages.Groups);
repoindex.setPackageNames("pkg_prov", repoindex.pkgNamesFromDeps(i.prov));
repoindex.setPackageNames("pkg_deps", repoindex.pkgNamesFromDeps(i.deps));
repoindex.setPackageNames("pkg_optd", repoindex.pkgNamesFromDeps(i.optd));
repoindex.setPackageNames("pkg_requ", repoindex.pack(i.requ));
repoindex.setPackageNames("pkg_conf", repoindex.pkgNamesFromDeps(i.conf));
repoindex.setPackageNames("pkg_repl", repoindex.pkgNamesFromDeps(i.repl));
repoindex.setText("pkg_isize", repoindex.makeDataSize(i.isize));
repoindex.setText("pkg_pack", repoindex.makeStr(i.pack));
repoindex.setText("pkg_idate", repoindex.makeStr(i.idate));
repoindex.setText("pkg_expl", i.repo === "local" ? (i.expl ? "explicitly installed" : "installed as dependency") : "-");
repoindex.setText("pkg_scri", repoindex.makeBool(i.scri));
repoindex.setText("pkg_sig", repoindex.makeArray(i.sig));
repoindex.setTree("pkg_files", repoindex.makeTree(i.files));
// -> update download buttons
var downloadPkgParams = {repo: i.repo, pkg: i.name, down: "pkg"};
repoindex.setDownloadButton("pkg_down", "package", repoindex.makeHash(repoindex.Pages.Packages, downloadPkgParams, true), function() {
repoindex.pageManager.denoteHash(repoindex.Pages.Packages, downloadPkgParams);
repoindex.pageManager.packageManager.showMirrorsForIndex(entryIndex);
});
var downloadSrcParams = {repo: i.repo, pkg: i.name, down: "src"};
repoindex.setDownloadButton("src_down", "source", repoindex.makeHash(repoindex.Pages.Packages, downloadSrcParams, true));
};
setProperties();
// use full package info (callback)
var pkgEntries = this.relevantEntries();
var useFullPackageInfo = function(values) {
// apply full info for all entries
for(var i = 0; i < values.length; ++i) {
var info = values[i];
if(!info.error) {
if(info.index >= 0 && info.index < pkgEntries.length) {
var entry = pkgEntries[info.index];
entry.applyFullInfo(info);
}
} else {
var errorMsg;
switch(info.error) {
case "na":
errorMsg = "The server can't find the requested (full) package info."
break;
default:
errorMsg = "The server can't deliver the requested (full) package info."
};
repoindex.pageManager.addError("Error: " + errorMsg);
}
}
// set properties (again) to actually show applied info
setProperties();
};
if(!i.full) {
// don't have the full package info yet -> request full package info
var packageSelection = {};
packageSelection[i.repo] = [{index: entryIndex, name: i.name}];
repoindex.alpmClient.requestFullPackagesInfo(packageSelection, useFullPackageInfo);
}
// set currentInfo (the pageManager needs this value to update the hash)
this.currentInfo = i;
// ensures, that the "Package Info" box (with the properties just set) is shown
repoindex.pageManager.showPackageInfo(true);
}
};
this.showMirrors = function(repo, name) {
var determineEntry = function() {
var res = repoindex.pageManager.packageManager.entries.filter(function(entry) {
return entry.info.repo === repo && entry.info.name === name;
});
// entry exists?
if(res.length > 0) {
// yes -> full package info available?
var i = res[0].info;
var showEntry = function() {
repoindex.pageManager.packageManager.showMirrorsForIndex(i.index);
};
if(i.full) {
// yes -> show entry instantly
showEntry();
} else {
// no -> request full info, use callback to show entry when info becomes available
//repoindex.alpmClient.requestFullPackagesInfo([{index: i.index, repo: i.repo, name: i.name}], showEntry());
var packageSelection = {};
packageSelection[i.repo] = [{index: entryIndex, name: i.name}];
repoindex.alpmClient.requestFullPackagesInfo(packageSelection, showEntry);
}
} else {
// no -> show error
repoindex.pageManager.packageManager.showPackageNotFound(repo, name);
}
};
// basic repo info available?
if(repoindex.alpmClient.hasBasicRepoInfo) {
// yes -> can determine entry instantly
determineEntry();
} else {
// no -> request info, use callback to determine entry when info becomes available
repoindex.alpmClient.requestBasicRepoInfo(determineEntry);
}
};
this.showMirrorsForIndex = function(entryIndex) {
var entry = this.entryByIndex(entryIndex);
if(entry) {
var info = entry.info;
repoindex.setText("title_mirror_selection", "Mirrors for package <i>" + repoindex.escapeHtml(info.name) + "</i>", true);
var listMirrorSelection = document.getElementById("list_mirror_selection");
listMirrorSelection.wipeChildren();
var repoEntries = repoindex.pageManager.repoManager.entries.filter(function(entry) {
return entry.info.name === info.repo;
});
var mirrorsAvailable = 0;
if(repoEntries.length > 0) {
var mirrors = repoEntries[0].info.servers;
if(mirrors.length > 0) {
for(var i = 0; i < mirrors.length; ++i) {
var liElement = document.createElement("li");
var aElement = document.createElement("a");
var url = mirrors[i] + "/" + info.file;
aElement.appendChild(document.createTextNode(url));
aElement.href = url;
aElement.onclick = function() {
window.open(this.href);
return false;
};
liElement.appendChild(aElement);
listMirrorSelection.appendChild(liElement);
}
mirrorsAvailable = 1;
}
}
}
if(mirrorsAvailable !== 1) {
// no mirrors available?
if(info.repo === "local" || info.repo === "LOCAL") {
// no surprise because its an package from the local database
mirrorsAvailable = -1;
} else if(info.repo === "aur" || info.repo === "AUR") {
// no surprise because its an AUR package
mirrorsAvailable = -2;
}
}
if(mirrorsAvailable === 1) {
repoindex.setText("status_mirror_selection", "Select a mirror:");
} else if(mirrorsAvailable === -1) {
repoindex.setText("status_mirror_selection", "The package belongs to the <i>local</i> database. Hence there are no mirrors available.", true);
} else if(mirrorsAvailable === -2) {
repoindex.setText("status_mirror_selection", "The package is from the <i>Arch Linux User Repository</i>. Hence there are no mirrors available.", true);
} else {
repoindex.setText("status_mirror_selection", "No mirrors available.");
}
$("#dlg_mirror_selection").modal("show");
};
this.showPackageNotFound = function(repo, name) {
repoindex.pageManager.msgboxCritical(
"Package not found",
"The package <i>" + repoindex.escapeHtml(name) + "</i> can not be found in the repository <i>" + repoindex.escapeHtml(repo) + "</i>.",
true);
};
}
return repoindex;
})(repoindex || {});