Updated paths
This commit is contained in:
3
source/SlackPack/install/doinst.sh
Normal file
3
source/SlackPack/install/doinst.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
ln -sf /usr/local/emhttp/plugins/SlackPack/scripts/packagemanager /usr/sbin/packagemanager
|
||||
chmod +0755 /usr/sbin/packagemanager
|
19
source/SlackPack/install/slack-desc
Normal file
19
source/SlackPack/install/slack-desc
Normal file
@ -0,0 +1,19 @@
|
||||
# HOW TO EDIT THIS FILE:
|
||||
# The "handy ruler" below makes it easier to edit a package description.
|
||||
# Line up the first '|' above the ':' following the base package name, and
|
||||
# the '|' on the right side marks the last column you can put a character in.
|
||||
# You must make exactly 11 lines for the formatting to be correct. It's also
|
||||
# customary to leave one space after the ':' except on otherwise blank lines.
|
||||
|
||||
|-----handy-ruler------------------------------------------------------|
|
||||
SlackPack: Slackware Packages Unraid Plugin
|
||||
SlackPack:
|
||||
SlackPack: Unraid plugin wrapper for slackware packages, for advanced
|
||||
SlackPack: users. Use at your own risk. Not officially supported by LimeTech.
|
||||
SlackPack:
|
||||
SlackPack: Supports: apr, apt-util, bwm-ng, cpio, git, iftop, inotify, iotop,
|
||||
SlackPack: iperf, kbd, lftp, lshw, neon, p7zip, perl, python, readline, screen,
|
||||
SlackPack: sshfs-fuse, strace, subversion, unrar, utempter, vim
|
||||
SlackPack:
|
||||
SlackPack: https://github.com/damnoodle/Unraid-SlackPack
|
||||
SlackPack:
|
@ -0,0 +1,3 @@
|
||||
**Slackware Packages**
|
||||
|
||||
Go to SlackPack in Settings to install extra CLI packages for advanced users. Use at your own risk. Not officially supported by LimeTech. Contains: iftop, iotop, screen, lshw, kbd, unrar, bwm-ng, strace, git, lftp, subversion, python, sshfs, iperf, p7zip...60+ packages
|
@ -0,0 +1,47 @@
|
||||
Icon="dropbox"
|
||||
Menu="UserPreferences"
|
||||
Title="Slack Pack"
|
||||
Tag="dropbox"
|
||||
---
|
||||
<link type="text/css" rel="stylesheet" href="<?=autov('/plugins/SlackPack/css/tablesorter.css');?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?=autov('/plugins/SlackPack/css/tablesorter-'.(($display['theme'] == 'white' || $display['theme'] == 'azure') ? 'white' : 'black').'.css');?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?=autov('/webGui/styles/jquery.switchbutton.css');?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?=autov('/plugins/SlackPack/css/SlackPack.css');?>">
|
||||
<style>
|
||||
table.tablesorter tbody tr:nth-child(odd) {
|
||||
background-color: #<?=($display['theme'] == 'white' || $display['theme'] == 'azure') ? 'F0F0F0' : '212421';?>;
|
||||
}
|
||||
table.tablesorter tbody tr:nth-child(even) {
|
||||
background-color: #<?=($display['theme'] == 'white' || $display['theme'] == 'azure') ? 'e4e2e4' : '1b1d1b';?>;
|
||||
}
|
||||
</style>
|
||||
|
||||
<form markdown="1" id="package_form" name="package_settings" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" id="include" name="#include" value="/plugins/SlackPack/include/ClearConfig.php"/>
|
||||
|
||||
<div class="wrapper">
|
||||
<table class="tablesorter hover-highlight" id="tblPackages">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="filter-name" data-placeholder="Search..."> Name </th>
|
||||
<th class="filter-version" data-placeholder="by status"> Status </th>
|
||||
<th class="sorter-metric filter-false" data-placeholder="by size" data-metric-name-full="byte|Byte|BYTE" data-metric-name-abbr="b|B"> Size </th>
|
||||
<th class="filter-downloaded" data-placeholder="by download"> Downloaded </th>
|
||||
<th class="filter-installed" data-placeholder="by install"> Installed </th>
|
||||
<th class="filter-plugins" data-placeholder="Search..."> Plugins </th>
|
||||
<th class="parser-false filter-false" nowrap="nowrap"><input class="uninstallpkg" type="checkbox"><input class="checkall" type="checkbox"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<input onclick="packageQuery(1)" value="Check for Updates" type="button"><input class="reset" type="button" title="reset filters" value="Reset Filters">
|
||||
: <input id="btnApply" type="button" value="Apply"><input type="button" value="Done" onClick="done()">
|
||||
<input type="hidden" name="#file" value="SlackPack/SlackPack.cfg">
|
||||
</form>
|
||||
|
||||
<script src="<?=autov('/plugins/SlackPack/js/jquery.tablesorter.combined.min.js');?>"></script>
|
||||
<script src="<?=autov('/plugins/SlackPack/js/parser-metric.min.js');?>"></script>
|
||||
<script type="text/javascript" src="<?=autov('/webGui/javascript/jquery.switchbutton.js');?>"></script>
|
||||
<script type="text/javascript" src="<?=autov('/plugins/SlackPack/js/jquery.SlackPack.js');?>"></script>
|
@ -0,0 +1,21 @@
|
||||
.package {
|
||||
cursor: pointer;
|
||||
}
|
||||
#package_form {
|
||||
margin-top: -10px;
|
||||
}
|
||||
.switch-button-label.off {
|
||||
color: inherit;
|
||||
}
|
||||
.uptodate {
|
||||
color:#44B012;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.updateready, .update {
|
||||
white-space:nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
.uninstalled, .installed {
|
||||
white-space:nowrap;
|
||||
cursor: inherit;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/* header */
|
||||
.tablesorter .headerSortUp,
|
||||
.tablesorter .tablesorter-headerSortUp,
|
||||
.tablesorter .tablesorter-headerAsc,
|
||||
.tablesorter .headerSortDown,
|
||||
.tablesorter .tablesorter-headerSortDown,
|
||||
.tablesorter .tablesorter-headerDesc {
|
||||
background-color:#212421;
|
||||
}
|
||||
/* filter widget */
|
||||
.tablesorter .tablesorter-filter-row {
|
||||
background-color: #101010;
|
||||
}
|
||||
.tablesorter .tablesorter-filter-row td {
|
||||
background-color: #1b1d1b;
|
||||
border-bottom: #101010 1px solid;
|
||||
}
|
||||
/* filters */
|
||||
.tablesorter input.tablesorter-filter,
|
||||
.tablesorter select.tablesorter-filter {
|
||||
background-color: #1b1d1b;
|
||||
border: 1px solid #101010;
|
||||
color: #808080;
|
||||
}
|
||||
.tablesorter-headerRow {
|
||||
background-color: #1b1d1b;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/* header */
|
||||
.tablesorter .headerSortUp,
|
||||
.tablesorter .tablesorter-headerSortUp,
|
||||
.tablesorter .tablesorter-headerAsc,
|
||||
.tablesorter .headerSortDown,
|
||||
.tablesorter .tablesorter-headerSortDown,
|
||||
.tablesorter .tablesorter-headerDesc,
|
||||
.tablesorter .tablesorter-filter-row,
|
||||
.tablesorter-headerRow,
|
||||
.tablesorter tr.even > td {
|
||||
background-color: #e4e2e4;
|
||||
}
|
||||
|
||||
.tablesorter .tablesorter-filter-row td {
|
||||
background-color: #e4e2e4;
|
||||
border-bottom: #F0F0F0 1px solid;
|
||||
}
|
||||
/* filters */
|
||||
.tablesorter input.tablesorter-filter,
|
||||
.tablesorter select.tablesorter-filter {
|
||||
background-color: #F0F0F0;
|
||||
border: 1px solid #e4e2e4;
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
.tablesorter .fa {
|
||||
margin:0 0 2px 2px;
|
||||
width: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* header */
|
||||
.tablesorter {
|
||||
font-family:arimo;
|
||||
margin:0 0 15px 0;
|
||||
}
|
||||
.tablesorter .header,
|
||||
.tablesorter .tablesorter-header {
|
||||
background-position: center right;
|
||||
background-repeat: no-repeat;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
.tablesorter .headerSortUp,
|
||||
.tablesorter .tablesorter-headerSortUp,
|
||||
.tablesorter .tablesorter-headerAsc {
|
||||
background-image: url(/webGui/images/sort-asc.png);
|
||||
}
|
||||
.tablesorter .headerSortDown,
|
||||
.tablesorter .tablesorter-headerSortDown,
|
||||
.tablesorter .tablesorter-headerDesc {
|
||||
background-image: url(/webGui/images/sort-desc.png);
|
||||
}
|
||||
|
||||
/* tbody */
|
||||
.tablesorter td {
|
||||
padding:4px 20px 4px 6px;
|
||||
vertical-align:middle;
|
||||
text-align:justify;
|
||||
}
|
||||
tablesorter tbody tr.tr_last td{
|
||||
padding:8px 20px 8px 6px;
|
||||
}
|
||||
|
||||
/* filter widget */
|
||||
.tablesorter .tablesorter-filter-row td {
|
||||
line-height: normal;
|
||||
text-align: center; /* center the input */
|
||||
-webkit-transition: line-height 0.1s ease;
|
||||
-moz-transition: line-height 0.1s ease;
|
||||
-o-transition: line-height 0.1s ease;
|
||||
transition: line-height 0.1s ease;
|
||||
}
|
||||
/* optional disabled input styling */
|
||||
.tablesorter .tablesorter-filter-row .disabled {
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* filters */
|
||||
.tablesorter input.tablesorter-filter,
|
||||
.tablesorter select.tablesorter-filter {
|
||||
width: 95%;
|
||||
height: auto;
|
||||
margin: 2px auto;
|
||||
padding: 2px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-transition: height 0.1s ease;
|
||||
-moz-transition: height 0.1s ease;
|
||||
-o-transition: height 0.1s ease;
|
||||
transition: height 0.1s ease;
|
||||
}
|
||||
/* rows hidden by filtering (needed for child rows) */
|
||||
.tablesorter .filtered {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* pager wrapper, div */
|
||||
.tablesorter-pager {
|
||||
padding: 5px;
|
||||
}
|
||||
/* pager wrapper, in thead/tfoot */
|
||||
td.tablesorter-pager {
|
||||
background-color: #e6eeee;
|
||||
margin: 0; /* needed for bootstrap .pager gets a 18px bottom margin */
|
||||
}
|
||||
/* pager navigation arrows */
|
||||
.tablesorter-pager img {
|
||||
vertical-align: middle;
|
||||
margin-right: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* pager output text */
|
||||
.tablesorter-pager .pagedisplay {
|
||||
padding: 0 5px 0 5px;
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
.tablesorter-pager select {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-width: 40px;
|
||||
max-width: 40px;
|
||||
}
|
||||
/*** css used when "updateArrows" option is true ***/
|
||||
/* the pager itself gets a disabled class when the number of rows is less than the size */
|
||||
.tablesorter-pager.disabled {
|
||||
display: none;
|
||||
}
|
||||
/* hide or fade out pager arrows when the first or last row is visible */
|
||||
.tablesorter-pager .disabled {
|
||||
/* visibility: hidden */
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* HOVER ROW highlight colors */
|
||||
table.hover-highlight tbody > tr:hover > td, /* override tablesorter theme row hover */
|
||||
table.hover-highlight tbody > tr.odd:hover > td,
|
||||
table.hover-highlight tbody > tr.even:hover > td {
|
||||
background-color: #9FC2E6;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* ************************************************* */
|
||||
/* **** No need to modify the definitions below **** */
|
||||
/* ************************************************* */
|
||||
.hover-highlight td:hover::after, .hover-highlight th:hover::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 999em;
|
||||
left: 0;
|
||||
top: -555em;
|
||||
z-index: -1;
|
||||
}
|
||||
/* required styles */
|
||||
.hover-highlight {
|
||||
overflow: hidden;
|
||||
}
|
||||
.hover-highlight td, .hover-highlight th {
|
||||
position: relative;
|
||||
outline: 0;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
// clear config every time to remove old package settings
|
||||
$keys = [];
|
||||
?>
|
@ -0,0 +1,46 @@
|
||||
<?
|
||||
// Download a file from given url
|
||||
function get_file_from_url($file, $url) {
|
||||
$chfile = fopen($file, 'w');
|
||||
$ch = curl_init();
|
||||
$ch_vers = curl_version();
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
//curl_setopt($ch, CURLOPT_TIMEOUT, 3600);
|
||||
curl_setopt($ch, CURLOPT_NOPROGRESS, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'curl/'.$ch_vers['version']);
|
||||
//curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress_bar');
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FILE, $chfile);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($chfile);
|
||||
}
|
||||
|
||||
// get a json array of the contents of gihub repo
|
||||
function get_content_from_github($repo, $file) {
|
||||
$ch = curl_init();
|
||||
$ch_vers = curl_version();
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json', 'Content-Type: application/json']);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'curl/'.$ch_vers['version']);
|
||||
curl_setopt($ch, CURLOPT_URL, $repo);
|
||||
$content = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if (!empty($content) && (!is_file($file) || $content != file_get_contents($file)))
|
||||
file_put_contents($file, $content);
|
||||
}
|
||||
|
||||
// Compare the github sha1 value of a file
|
||||
function file_check_sha1($file, $sha1) {
|
||||
$size = filesize($file);
|
||||
$contents = file_get_contents($file);
|
||||
|
||||
// create a sha1 like github does
|
||||
$str = "blob ".$size."\0".$contents;
|
||||
$sha1_file = sha1($str);
|
||||
|
||||
return ($sha1_file == $sha1);
|
||||
}
|
||||
?>
|
@ -0,0 +1,82 @@
|
||||
<?
|
||||
require_once '/usr/local/emhttp/plugins/SlackPack/include/SlackPackHelpers.php';
|
||||
require_once '/usr/local/emhttp/plugins/SlackPack/include/DownloadHelpers.php';
|
||||
|
||||
// Only download repo update if the current one is 1 hour old or more
|
||||
if (!file_exists($repo_file) || !empty($_GET['force']) || (filemtime($repo_file) < (time() - 3600))) {
|
||||
get_content_from_github($pkg_repo, $repo_file);
|
||||
get_content_from_github($pkg_desc, $desc_file);
|
||||
$pkgs_desc_array = file_exists($desc_file) ? json_decode(file_get_contents($desc_file), true) : [];
|
||||
$pkgs_github_array = file_exists($repo_file) ? json_decode(file_get_contents($repo_file), true) : [];
|
||||
}
|
||||
|
||||
$pkgs_array = [];
|
||||
|
||||
foreach ($pkgs_github_array as $pkg_github) {
|
||||
$pkg_nameArray = explode('-', $pkg_github['name']); // split package name into array
|
||||
|
||||
// strip md5 files
|
||||
if(!strpos(end($pkg_nameArray),'.md5')) {
|
||||
|
||||
$pkg_name = $pkg_nameArray[0];
|
||||
|
||||
if (sizeof($pkg_nameArray) > 4) { //if package name has a subset get it
|
||||
for ($ii = 1; $ii < sizeof($pkg_nameArray)-3; $ii++) {
|
||||
$pkg_name .= '-'.$pkg_nameArray[$ii];
|
||||
}
|
||||
}
|
||||
|
||||
$pkg_version = $pkg_nameArray[sizeof($pkg_nameArray) - 3]; // get package version
|
||||
|
||||
$pkg_nver = $pkg_name.'-'.str_replace('.', '_', $pkg_version); // add underscored version to package name
|
||||
|
||||
$pkg_pattern = '/^'.$pkg_name.'-[0-9].*/'; // search pattern for packages
|
||||
|
||||
// check all plugins for package dependency
|
||||
$plugins = [];
|
||||
exec("cd /boot/config/plugins ; find *.plg | xargs grep '${pkg_name}-${pkg_version}' -sl",$plugins);
|
||||
$pkg_plgs = '--';
|
||||
if ($plugins){
|
||||
foreach ($plugins as $plugin){
|
||||
$pkg_plgs .= pathinfo($plugin, PATHINFO_FILENAME).', ';
|
||||
}
|
||||
$pkg_plgs = substr($pkg_plgs, 2, -2);
|
||||
}
|
||||
|
||||
// get package preference from config file
|
||||
$pkg_set = "no";
|
||||
foreach ($pkg_cfg as $pkg_key => $pkg_line) {
|
||||
if (preg_match('/^'.$pkg_name.'.*/',$pkg_key)){
|
||||
if(sizeof(array_diff(explode('-', $pkg_key), explode('-', $pkg_name))) < 2 ){
|
||||
$pkg_set = $pkg_line;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pkg = [
|
||||
'name' => $pkg_github['name'], // add full package name
|
||||
'pkgname' => $pkg_name, // add package name only
|
||||
'pkgnver' => $pkg_nver, // add package name with underscored version
|
||||
'pkgversion' => $pkg_version, // add package name with raw version
|
||||
'size' => format_size($pkg_github['size'], 1, '?'), // add package size
|
||||
'installed' => !empty(preg_grep($pkg_pattern, $pkgs_installed)) ? 'yes' : 'no', // checks if package name is installed
|
||||
'installeq' => in_array(pathinfo($pkg_github['name'], PATHINFO_FILENAME), $pkgs_installed) ? 'yes' : 'no', // checks if package installed equals github exactly
|
||||
'downloaded' => !empty(preg_grep($pkg_pattern, $pkgs_downloaded)) ? 'yes' : 'no', // checks if package name is downloaded
|
||||
'downloadeq' => in_array($pkg_github['name'], $pkgs_downloaded) ? 'yes' : 'no', // checks if package downloaded equals github exactly
|
||||
'config' => $pkg_set, // install preference
|
||||
'plugins' => $pkg_plgs, // plugins dependency on package
|
||||
'desc' => $pkgs_desc_array[$pkg_name]
|
||||
];
|
||||
|
||||
$pkgs_array[] = $pkg;
|
||||
}
|
||||
}
|
||||
|
||||
$return = [
|
||||
'packages' => $pkgs_array,
|
||||
'empty' => empty($pkgs_downloaded)
|
||||
];
|
||||
|
||||
echo json_encode($return);
|
||||
?>
|
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
$plg_path = '/boot/config/plugins/SlackPack/'; // plugin path
|
||||
$os_version = strtok(parse_ini_file('/etc/unraid-version')['version'], '.') . '.' . strtok('.');
|
||||
$pkg_path = $plg_path."packages/$os_version/"; // package path
|
||||
if (!is_dir($pkg_path))
|
||||
mkdir($pkg_path);
|
||||
|
||||
$pkg_desc = 'https://raw.githubusercontent.com/damnoodle/Unraid-SlackPack/master/packages/packages-desc';
|
||||
$pkg_repo = "https://api.github.com/repos/damnoodle/Unraid-SlackPack/contents/packages/$os_version";
|
||||
|
||||
$desc_file = $pkg_path.'packages-desc';
|
||||
$repo_file = $pkg_path.'packages.json';
|
||||
$config_file = $plg_path.'SlackPack.cfg';
|
||||
|
||||
// get package configs
|
||||
$pkg_cfg = file_exists($config_file) ? parse_ini_file($config_file) : [];
|
||||
|
||||
// get array of downloaded packages
|
||||
$pkgs_downloaded = is_dir($pkg_path) ? array_diff(scandir($pkg_path, 1), ['.', '..','packages.json','packages-desc']) : [];
|
||||
|
||||
// get array of all installed packages
|
||||
$pkgs_installed = array_diff(scandir("/var/log/packages", 1), ['.', '..']);
|
||||
|
||||
$pkgs_desc_array = file_exists($desc_file) ? json_decode(file_get_contents($desc_file), true) : [];
|
||||
|
||||
$pkgs_github_array = file_exists($repo_file) ? json_decode(file_get_contents($repo_file), true) : [];
|
||||
|
||||
function logger($output, $quiet = false) {
|
||||
exec('echo '.escapeshellarg($output).' 2>&1 | logger -tslackpack');
|
||||
if (!$quiet) {
|
||||
echo "\n".$output." \n";
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
function format_size($value, $decimals, $unit = '?') {
|
||||
if ($value == '')
|
||||
return 'unknown';
|
||||
|
||||
/* Autodetect unit that's appropriate */
|
||||
if ($unit == '?') {
|
||||
if ($value >= 1099511627776)
|
||||
$unit = 'T';
|
||||
else
|
||||
if ($value >= (1 << 30))
|
||||
$unit = 'G';
|
||||
else
|
||||
if ($value >= (1 << 20))
|
||||
$unit = 'M';
|
||||
else
|
||||
if ($value >= (1 << 10))
|
||||
$unit = 'K';
|
||||
else
|
||||
$unit = 'B';
|
||||
}
|
||||
|
||||
$unit = strtoupper($unit);
|
||||
|
||||
switch ($unit) {
|
||||
case 'T': return number_format($value / (float)1099511627776, $decimals).' TB';
|
||||
case 'G': return number_format($value / (float)(1 << 30), $decimals).' GB';
|
||||
case 'M': return number_format($value / (float)(1 << 20), $decimals).' MB';
|
||||
case 'K': return number_format($value / (float)(1 << 10), $decimals).' KB';
|
||||
case 'B': return $value.' B';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
?>
|
@ -0,0 +1,190 @@
|
||||
$(function(){
|
||||
// tablesorter options
|
||||
$('#tblPackages').tablesorter({
|
||||
sortList: [[0,0]],
|
||||
widgets: ['saveSort', 'filter', 'stickyHeaders', 'zebra'],
|
||||
widgetOptions: {
|
||||
stickyHeaders_filteredToTop: true,
|
||||
stickyHeaders_attachTo: null,
|
||||
stickyHeaders_offset: ($('#header').css("position") === "fixed") ? '90' : '0',
|
||||
filter_hideEmpty: true,
|
||||
filter_liveSearch: true,
|
||||
filter_saveFilters: true,
|
||||
filter_reset: '.reset',
|
||||
filter_functions: {
|
||||
'.filter-version': true,
|
||||
'.filter-downloaded': true,
|
||||
'.filter-installed': true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// "uninstall package" switch and cookie
|
||||
$('.uninstallpkg')
|
||||
.switchButton({
|
||||
labels_placement: 'right',
|
||||
on_label: 'unInstall',
|
||||
off_label: 'unInstall',
|
||||
checked: $.cookie('slackpack_packages_uninstall') == '--uninstall'
|
||||
})
|
||||
.change(function () {
|
||||
$.cookie('slackpack_packages_uninstall', $('.uninstallpkg')[0].checked ? '--uninstall' : '', { expires: 3650 });
|
||||
});
|
||||
|
||||
// select all packages switch
|
||||
$('.checkall')
|
||||
.switchButton({
|
||||
labels_placement: 'right',
|
||||
on_label: 'Select All',
|
||||
off_label: 'Select All',
|
||||
checked: $.cookie('slackpack_checkall') == 'yes'
|
||||
})
|
||||
.change(function () {
|
||||
var myval = $(this)[0].checked;
|
||||
$.cookie('slackpack_checkall', myval ? 'yes' : 'no', { expires: 3650 });
|
||||
$('#tblPackages tbody td:visible .pkgcheckbox').switchButton({checked: myval});
|
||||
});
|
||||
|
||||
$('#btnApply').click(Apply);
|
||||
|
||||
packageQuery();
|
||||
});
|
||||
|
||||
//list all available packages in a table
|
||||
function packageQuery(force) {
|
||||
$('#tblPackages tbody').html("<tr><td colspan='6'><br><i class='fa fa-spinner fa-spin icon'></i><em>Please wait, retrieving plugin information ...</em></td><tr>");
|
||||
$.getJSON('/plugins/SlackPack/include/PackageQuery.php', {force: force}, function(data) {
|
||||
$('#tblPackages tbody').empty();
|
||||
var Ready;
|
||||
var Count = 0;
|
||||
var len = data.packages.length, i = 0;
|
||||
for (i; i < len; i++) {
|
||||
var Update;
|
||||
var Downloaded = data.packages[i].downloaded;
|
||||
var DownloadEQ = data.packages[i].downloadeq;
|
||||
var Installed = data.packages[i].installed;
|
||||
var InstallEQ = data.packages[i].installeq;
|
||||
if (DownloadEQ == Downloaded && InstallEQ == Installed){
|
||||
if (Installed == "yes"){
|
||||
if (Downloaded == "no")
|
||||
Update = "<span ><i class='installed fa fa-check-circle'></i> installed</span>";
|
||||
else
|
||||
Update = "<span><i class='uptodate fa fa-check'></i> up-to-date </span>";
|
||||
}else{
|
||||
Update = "<span><i class='uninstalled fa fa-info-circle'></i> uninstalled </span>";
|
||||
}
|
||||
}else{
|
||||
Update = "<span ><a class='update'><i class='updateready fa fa-cloud-download'></i> update ready </a></span>";
|
||||
Ready = true;
|
||||
}
|
||||
|
||||
if (DownloadEQ != Downloaded)
|
||||
Downloaded = 'old';
|
||||
|
||||
var Checked = "";
|
||||
if (data.packages[i].config == "yes"){
|
||||
Checked = "checked";
|
||||
Count++;
|
||||
}
|
||||
|
||||
$('#tblPackages tbody').append("<tr>"+
|
||||
"<td class='package' title='"+data.packages[i].desc+"'>"+data.packages[i].name+"</td>"+ // package name
|
||||
"<td>"+Update+"</td>"+ // package status
|
||||
"<td>"+data.packages[i].size+"</td>"+ // package size
|
||||
"<td>"+Downloaded+"</td>"+ // package downloaded
|
||||
"<td>"+Installed+"</td>"+ // package installed
|
||||
"<td>"+data.packages[i].plugins+"</td>"+ // package dependents
|
||||
"<td><input class='pkgcheckbox' id='"+data.packages[i].pkgname+"' type='checkbox' "+Checked+">"+
|
||||
"<input class='pkgvalue' type='hidden' id='"+data.packages[i].pkgname+"_value' name='"+data.packages[i].pkgnver+"' value='"+data.packages[i].config+"'></td>"+
|
||||
"</tr>");
|
||||
}
|
||||
if (Ready)
|
||||
$('#btnApply').prop('disabled', false);
|
||||
|
||||
// attach switch buttons to every package checkbox all at once
|
||||
$('.pkgcheckbox')
|
||||
.switchButton({
|
||||
labels_placement: 'right',
|
||||
on_label: 'On',
|
||||
off_label: 'Off'
|
||||
})
|
||||
.change(function() {
|
||||
$(this).parent().parent().find('.pkgvalue').val(this.checked ? "yes": "no");
|
||||
if (this.checked)
|
||||
checkDepends();
|
||||
$('#btnApply').prop("disabled", false);
|
||||
});
|
||||
|
||||
// attach submit to update ready
|
||||
$('.update').click(Apply);
|
||||
|
||||
// restore filters
|
||||
var lastSearch = $('#tblPackages')[0].config.lastSearch;
|
||||
$('#tblPackages').trigger('update')
|
||||
.trigger('search', [lastSearch]);
|
||||
|
||||
if (data.empty == true && Count > 0) {
|
||||
swal({
|
||||
title:'Downloaded Packages Missing!',
|
||||
text:'You either changed Unraid versions or deleted your downloaded packages. Click Download or the Apply button below to download and install your selected packages.',
|
||||
type:'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#00AA00",
|
||||
confirmButtonText: 'Download',
|
||||
closeOnConfirm: true,},
|
||||
function(isConfirm) {
|
||||
$('#btnApply').prop('disabled', false);
|
||||
if(isConfirm)
|
||||
Apply();
|
||||
else
|
||||
$('html, body').animate({
|
||||
scrollTop: $("#btnApply").offset().top
|
||||
}, 2000);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function Apply() {
|
||||
checkDepends();
|
||||
var Arg2 = (typeof $.cookie('slackpack_packages_uninstall') === 'undefined') ? '' : '&arg2='+$.cookie('slackpack_packages_uninstall');
|
||||
$.post('/update.php', $('#package_form').serializeArray(), function() {
|
||||
openBox('/plugins/SlackPack/scripts/packagemanager&arg1=--download'+ Arg2,
|
||||
'Package Manager', 600, 900, true);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function checkDepends() {
|
||||
if ($('#screen')[0].checked) {
|
||||
$('#utempter').switchButton({checked: true});
|
||||
$('#utempter', '.pkgvalue').val('yes');
|
||||
$('#ncurses-terminfo').switchButton({checked: true});
|
||||
$('#ncurses-terminfo', '.pkgvalue').val('yes');
|
||||
}
|
||||
if ($('#tmux')[0].checked) {
|
||||
$('#ncurses-terminfo').switchButton({checked: true});
|
||||
$('#ncurses-terminfo', '.pkgvalue').val('yes');
|
||||
}
|
||||
if ($('#expect')[0].checked) {
|
||||
$('#tcl').switchButton({checked: true});
|
||||
$('#tcl', '.pkgvalue').val('yes');
|
||||
}
|
||||
if ($('#iotop')[0].checked) {
|
||||
$('#python').switchButton({checked: true});
|
||||
$('#python', '.pkgvalue').val('yes');
|
||||
}
|
||||
if ($('#vim')[0].checked) {
|
||||
$('#perl').switchButton({checked: true});
|
||||
$('#perl', '.pkgvalue').val('yes');
|
||||
}
|
||||
if ($('#borgbackup')[0].checked) {
|
||||
$('#python3').switchButton({checked: true});
|
||||
$('#python3', '.pkgvalue').val('yes');
|
||||
$('#python-setuptools').switchButton({checked: true});
|
||||
$('#python-setuptools', '.pkgvalue').val('yes');
|
||||
$('#llfuse').switchButton({checked: true});
|
||||
$('#llfuse', '.pkgvalue').val('yes');
|
||||
}
|
||||
}
|
2
source/SlackPack/usr/local/emhttp/plugins/SlackPack/js/jquery.tablesorter.combined.min.js
vendored
Normal file
2
source/SlackPack/usr/local/emhttp/plugins/SlackPack/js/jquery.tablesorter.combined.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
source/SlackPack/usr/local/emhttp/plugins/SlackPack/js/parser-metric.min.js
vendored
Normal file
2
source/SlackPack/usr/local/emhttp/plugins/SlackPack/js/parser-metric.min.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/*! Parser: metric */
|
||||
!function(e){"use strict";var t={"Y|Yotta|yotta":[1e24,Math.pow(1024,8)],"Z|Zetta|zetta":[1e21,Math.pow(1024,7)],"E|Exa|exa":[1e18,Math.pow(1024,6)],"P|Peta|peta":[1e15,Math.pow(1024,5)],"T|Tera|tera":[1e12,Math.pow(1024,4)],"G|Giga|giga":[1e9,Math.pow(1024,3)],"M|Mega|mega":[1e6,Math.pow(1024,2)],"k|Kilo|kilo":[1e3,1024],"h|hecto":[100,100],"da|deka":[10,10],"d|deci":[.1,.1],"c|centi":[.01,.01],"m|milli":[.001,.001],"µ|micro":[1e-6,1e-6],"n|nano":[1e-9,1e-9],"p|pico":[1e-12,1e-12],"f|femto":[1e-15,1e-15],"a|atto":[1e-18,1e-18],"z|zepto":[1e-21,1e-21],"y|yocto":[1e-24,1e-24]},a=/^[b|bit|byte|o|octet]/i;e.tablesorter.addParser({id:"metric",is:function(){return!1},format:function(o,r,i,c){var n,m,p,d,s="m|meter",h=e.tablesorter.formatFloat(o.replace(/[^\w,. \-()]/g,""),r),f=r.config.$headerIndexed[c],l=f.data("metric");if(l||(n=(f.attr("data-metric-name")||s).split("|"),p=f.attr("data-metric-name-full")||"",d=f.attr("data-metric-name-abbr")||"",l=[p||n[1]||n[0].substring(1),d||n[0]],m=a.test(l.join("")),l[2]=new RegExp("(\\d+)(\\s+)?([Zz]etta|[Ee]xa|[Pp]eta|[Tt]era|[Gg]iga|[Mm]ega|kilo|hecto|deka|deci|centi|milli|micro|nano|pico|femto|atto|zepto|yocto)("+((""===p?"":p+"|"+d)||(m?l[0].toLowerCase()+"|"+l[0].toUpperCase():l[0])+"|"+(m?l[1].toLowerCase()+"|"+l[1].toUpperCase():l[1]))+")"),l[3]=new RegExp("(\\d+)(\\s+)?(Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)("+(d||(m?l[1].toLowerCase()+"|"+l[1].toUpperCase():l[1]))+")"),f.data("metric",l)),n=o.match(l[2])||o.match(l[3]))for(s in t)if(n[3].match(s))return m=a.test(n[4])?1:0,h*t[s][m];return h},type:"numeric"})}(jQuery);
|
171
source/SlackPack/usr/local/emhttp/plugins/SlackPack/scripts/packagemanager
Executable file
171
source/SlackPack/usr/local/emhttp/plugins/SlackPack/scripts/packagemanager
Executable file
@ -0,0 +1,171 @@
|
||||
#!/usr/bin/php -q
|
||||
<?php
|
||||
$debug = FALSE;
|
||||
$prog = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
$usage = <<<EOF
|
||||
|
||||
Process package files in SlackPack config. Download and install,
|
||||
delete and uninstall, based on the config value and [options].
|
||||
|
||||
Usage: packagemanager [options]
|
||||
|
||||
-d, --download download missing packages selected
|
||||
-r, --delete delete packages not selected
|
||||
-q, --quiet supress all packages progress
|
||||
-u, --uninstall uninstall packages not selected
|
||||
-v, --verbose print all packages progress
|
||||
--help display this help and exit
|
||||
--version output version information and exit
|
||||
--debug turn on debugging
|
||||
|
||||
EOF;
|
||||
|
||||
$shortopts = "dquv";
|
||||
$longopts = [
|
||||
"debug",
|
||||
"download",
|
||||
"help",
|
||||
"quiet",
|
||||
"uninstall",
|
||||
"verbose",
|
||||
"version"
|
||||
];
|
||||
$args = getopt($shortopts, $longopts);
|
||||
|
||||
if (array_key_exists("help", $args)) {
|
||||
echo $usage;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (array_key_exists("version", $args)) {
|
||||
echo "Package Manager Version: 1.2\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$argd = (array_key_exists("d", $args) || array_key_exists("download", $args));
|
||||
$argq = (array_key_exists("q", $args) || array_key_exists("quiet", $args));
|
||||
$argu = (array_key_exists("u", $args) || array_key_exists("uninstall", $args));
|
||||
$argv = (array_key_exists("v", $args) || array_key_exists("verbose", $args));
|
||||
$debug = array_key_exists("debug", $args);
|
||||
|
||||
require_once '/usr/local/emhttp/plugins/SlackPack/include/SlackPackHelpers.php';
|
||||
require_once '/usr/local/emhttp/plugins/SlackPack/include/DownloadHelpers.php';
|
||||
|
||||
/* debug */
|
||||
function debug($m){
|
||||
global $prog, $debug;
|
||||
if($debug){
|
||||
$STDERR = fopen('php://stderr', 'w+');
|
||||
fwrite($STDERR, $m.PHP_EOL);
|
||||
fclose($STDERR);
|
||||
}
|
||||
}
|
||||
|
||||
logger('Processing Packages...');
|
||||
|
||||
$pkg_find = '';
|
||||
|
||||
foreach ($pkg_cfg as $pkg_name => $pkg_pref) { // get preferences for each package
|
||||
$pkg_cmd = '';
|
||||
$pkg_msg = '';
|
||||
$pkg_name = str_replace('_', '.', $pkg_name); // replace "_" with "." in package names
|
||||
$pkg_pattern = '/^'.$pkg_name.'.-*/'; // search pattern for packages
|
||||
$pkg_install_status = !empty(preg_grep($pkg_pattern, $pkgs_installed)); // check install status
|
||||
$pkg_download_status = !empty(preg_grep($pkg_pattern, $pkgs_downloaded)); // check package download status
|
||||
$pkg_online_status = !empty(preg_grep($pkg_pattern, $pkgs_github_array));
|
||||
$pkg_find .= " ! -name '".$pkg_name."*'";
|
||||
|
||||
$pkg_matches = array_filter($pkgs_github_array, function($a) use ($pkg_pattern) {
|
||||
return preg_grep($pkg_pattern, $a);
|
||||
});
|
||||
|
||||
$pkg_gitname = array_values($pkg_matches)[0]['name'];
|
||||
$pkg_file = $pkg_path.$pkg_gitname;
|
||||
$pkg_url = array_values($pkg_matches)[0]['download_url'];
|
||||
$pkg_sha1 = array_values($pkg_matches)[0]['sha'];
|
||||
|
||||
//check if plugin is dependent on package
|
||||
$plugins = [];
|
||||
exec("cd /boot/config/plugins ; find *.plg | xargs grep '$pkg_name' -sl",$plugins);
|
||||
if ($plugins){
|
||||
$plg_msg = "$pkg_name used by plugin: ";
|
||||
foreach ($plugins as $plugin){
|
||||
$plg_msg .= pathinfo($plugin, PATHINFO_FILENAME).", ";
|
||||
}
|
||||
logger(substr($plg_msg, 0, -2));
|
||||
}
|
||||
|
||||
// if package is selected to be installed
|
||||
if ($pkg_pref == 'yes') {
|
||||
// if executing from the wegui check status and download if necessary
|
||||
if ($argd) {
|
||||
if (!$pkg_download_status) { //if package is not downloaded
|
||||
|
||||
logger('Downloading '.$pkg_gitname.' package...', $argq);
|
||||
|
||||
get_file_from_url($pkg_file, $pkg_url);
|
||||
|
||||
if (file_check_sha1($pkg_file, $pkg_sha1)){
|
||||
logger($pkg_gitname.' package download sucessful!', $argq);
|
||||
}else{
|
||||
if (file_exists($pkg_file))
|
||||
unlink($pkg_file);
|
||||
logger($pkg_gitname.' package download failed!', $argq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$pkg_install_status) { // if package is not installed
|
||||
$pkg_msg = 'Installing';
|
||||
$pkg_cmd = 'upgradepkg --install-new '.$pkg_path.$pkg_name.'* 2>&1';
|
||||
}
|
||||
|
||||
} elseif ($pkg_pref == 'no' && $pkg_download_status && $argu) {
|
||||
if($plugins){
|
||||
logger("$pkg_name in use by another plugin, not uninstalled.",$argq);
|
||||
}else{
|
||||
$pkg_msg = 'Uninstalling and deleting';
|
||||
$pkg_cmd = 'removepkg '.$pkg_path.$pkg_name.'* 2>&1; rm '.$pkg_path.$pkg_name.'* 2>&1';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($pkg_cmd)) {
|
||||
logger("$pkg_msg $pkg_name package...");
|
||||
shell_exec($pkg_cmd);
|
||||
}else{
|
||||
if ($pkg_pref == 'yes'){
|
||||
if (file_exists($pkg_file)){
|
||||
if (file_check_sha1($pkg_file, $pkg_sha1)){
|
||||
$pkg_msg = 'package up to date, checksum ok.';
|
||||
}else{
|
||||
if(!is_dir($pkg_file))
|
||||
unlink($pkg_file);
|
||||
$pkg_msg = 'checksum failed! package deleted.';
|
||||
}
|
||||
}else{
|
||||
$pkg_msg = ' package missing!';
|
||||
}
|
||||
|
||||
logger($pkg_name." $pkg_msg", $argq);
|
||||
}
|
||||
}
|
||||
}
|
||||
logger('Cleaning up packages...');
|
||||
|
||||
$cmd = "find ".$pkg_path." -type f ! -name 'packages.json' ! -name 'packages-desc'".$pkg_find." -delete 2>&1";
|
||||
shell_exec($cmd);
|
||||
|
||||
logger('All packages processed...');
|
||||
|
||||
/* print variable */
|
||||
$defined_vars = get_defined_vars();
|
||||
|
||||
//remove vars from array to save
|
||||
unset($defined_vars['pkgs_desc_array'],$defined_vars['pkgs_github_array']);
|
||||
|
||||
foreach (array("_GET","_POST","_COOKIE","_FILES","argv","argc","_SERVER") as $i)
|
||||
unset($defined_vars[$i]);
|
||||
|
||||
debug("\nDECLARED VARIABLES:\n".print_r($defined_vars, true));
|
||||
unset($defined_vars);
|
||||
?>
|
Reference in New Issue
Block a user