You are not logged in.

#1 2011-01-20 02:04:06

jafar
Member
Registered: 2011-01-17
Posts: 5

php skript for better pacman -Su output

just wrote a little shell-skript in php.
when executed it does
- sudo pacman -Sy
- list packages
- [y/n] if yes -> sudo pacman -Su

the list packages looks like this:

NAME                       AGE    VERSION        DESCRIPTION
--------------------------------------------------------------------------------
cracklib(core)             2d05h  2.8.18-1       Password Checking Library
dmxproto(extra)            0d14h  2.3.1-1        X11 Distributed Multihead X ext
                                                 ension wire protocol
glibc(core)                3d14h  2.12.2-2       GNU C Library
gnupg2(extra)              2d05h  2.0.17-1       GNU Privacy Guard 2 - a PGP rep
                                                 lacement tool
upgrade? [y/N]:

I just did this because of the additional Information Age and Description.
I searched in the aur for something similar but couldnt find anything.

I was looking for displaying changelog for new packages, not for installed, but I couldnt come up with a solution,
from where the hell to get changelog infos.

So anyway heres the code, just wanted to share this.
Simply put it in a .sh file and execute like normal shell-script.
If someone knows a better script or something similar, please let me know.

#!/usr/bin/php
<?php

$maxlinelength = 120; // CHANGE THIS TO YOUR NEEDS, its the no. of maximum chars that fits in 1 line on your console

$return_var = -1;
system('sudo pacman -Sy >/dev/stdin', $return_var);
$packages = linux('pacman --print-format \'%n\' -Sup');

if (!is_array($packages) || count($packages) < 2)
{
    var_dump($packages);
    die('ERROR variable packages');
}

if (count($packages) == 2 && strpos($packages[1], 'there is nothing to do') !== false)
{
    die('no updates => happy day:)'."\n");
}

$table = array();
$table[] = array('NAME', 'AGE', 'VERSION', 'DESCRIPTION');
$table[] = 'line';

sort($packages);

$pacmanSi = explode("\n\n", implode("\n", linux('pacman -Si '.implode(' ', array_slice($packages,1)))));

for ($i = 1; $i < count($packages); $i++)
{
    $info = pacman_create_info_array(explode("\n", trim($pacmanSi[$i-1])));
    $row = array();
    $row[] = $info['name'].'('.$info['repository'].')';
    $row[] = convert_seconds_to_age(time() - @strtotime($info['build date']));
    $row[] = $info['version'];    
    $row[] = $info['description'];
    $table[] = $row;
}

print_shell_table($table, array('maxlinelength' => $maxlinelength));
echo "\n";
$prompt = prompt('upgrade? [y/N]: ');
if (strtolower($prompt) == 'y')
{
    system('sudo pacman -Su >/dev/stdin', $return_var);
}

function linux($command)
{
    $output = array();
    $return_var = -1;
    exec($command, $output, $return_var);
    #print "\n".$command."\n";#
    return $output;
}

function prompt($text)    
{
    echo $text;
    $line = trim(fgets(STDIN));
    return $line;
}
    
function convert_seconds_to_age($seconds)
{
    $days = floor($seconds / 86400);
    $seconds = $seconds - ($days * 86400);
    $hours = str_pad(strval(intval(round($seconds / 3600))),2,'0',STR_PAD_LEFT);
    return $days.'d'.$hours.'h';
}

function pacman_create_info_array($info)
{
    $arr = array();
    foreach ($info as $val)
    {
        $val = trim($val);
        if ($val == '') continue;
        $first = strtolower(trim(substr($val,0,strpos($val,':'))));
        $second = trim(substr($val,strpos($val,':') + 1));
        $arr[$first] = $second;
    }
    return $arr;
}

function print_shell_table(&$arr, $options = array())
{
    if (!isset($options['maxlinelength'])) $options['maxlinelength'] = 5000;
    
    $start = 0;
    while (!is_array($arr[$start])) $start++;        
    $max_column_lengths = array();
    for ($i = 0; $i < count($arr[$start]); $i++)
        $max_column_lengths[$i] = 0;        
    
    for ($i = 0; $i < count($arr); $i++)
    {
        if (is_array($arr[$i]))
        {
            for ($j = 0; $j < count($arr[$i]); $j++)
            {
                if (strlen($arr[$i][$j]) > $max_column_lengths[$j])
                    $max_column_lengths[$j] = strlen($arr[$i][$j]);
            }
        }
    }

    $length_longestline = 0;
    for ($i = 0; $i < count($arr); $i++)
    {
        if (is_array($arr[$i]))
        {
            $length = 0;
            
            // loop while < count - 1 (all columns except last)
            for ($j = 0; $j < count($arr[$i]) - 1; $j++)
            {
                $arr[$i][$j] = str_pad($arr[$i][$j], $max_column_lengths[$j] + 2, ' ');
                $length += strlen($arr[$i][$j]);                
            }
            
            // last column
            if ($length + strlen($arr[$i][$j]) > $options['maxlinelength'])
            {
                if ($options['maxlinelength'] - $length > 0)
                    $arr[$i][$j] = str_split($arr[$i][$j], $options['maxlinelength'] - $length);
                else
                    $arr[$i][$j] = '';
                $length_longestline = $options['maxlinelength'];                
            }
            else
            {
                if ($length + strlen($arr[$i][$j]) > $length_longestline)
                    $length_longestline = $length + strlen($arr[$i][$j]);
            }            
        }
    }

    for ($i = 0; $i < count($arr); $i++)
    {
        if (is_array($arr[$i]))
        {
            $offset = 0;
            foreach ($arr[$i] as $val) 
            {
                // last column may be an array
                if (is_array($val))
                {
                    echo $val[0];
                    for ($j = 1; $j < count($val); $j++)
                    {
                        echo "\n";
                        echo str_repeat(' ', $offset);
                        echo ltrim($val[$j]);
                    }
                }
                else
                {
                    $offset += strlen($val);
                    echo $val;
                }
            }
            echo "\n";
        }
        elseif ($arr[$i] == 'line') echo str_repeat('-', $length_longestline)."\n";
    }
}
    
?>

Offline

#2 2011-01-20 04:55:07

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: php skript for better pacman -Su output

(echo "NAME(REPO)#BUILD DATE#VERSION#DESCRIPTION" && expac "%n(%r)#%b#%v#%d" -l'\n' -S $(pacman -Qqu)) | column -s "#" -t && sudo pacman -Su | tail -n1

;P


EDIT: This script is broken! Yeah, I can't write a simple loop, sorry. Left it here for all to see I'm dumb.
Use this one: https://bbs.archlinux.org/viewtopic.php … 79#p880979

#!/bin/bash

now=$(date "+%s")
for i in $(pacman -Qqu); do
  builddate=$(expac -t %s %b -S $i)
  sec=$(($now - $builddate))
  age=$(($sec/ 3600 / 24))
done

(echo "NAME(REPO)#AGE#VERSION#DESCRIPTION" && expac "%n(%r)#$age days#%v#%d" -l'\n' -S $(pacman -Qqu)) | column - s "#" -t
#sudo pacman -Su | tail -n1

Last edited by karol (2011-01-20 14:17:58)

Offline

#3 2011-01-20 12:23:16

jafar
Member
Registered: 2011-01-17
Posts: 5

Re: php skript for better pacman -Su output

well, I guess you have me beat:)

Offline

#4 2011-01-20 12:24:12

Alm
Member
Registered: 2010-09-15
Posts: 64

Re: php skript for better pacman -Su output

But we need to install expac ;P
So let's say that php script is a replacement for it.


See, you're unpacking.

Offline

#5 2011-01-20 13:01:15

FarmerF
Member
From: Netherlands
Registered: 2009-06-08
Posts: 76

Re: php skript for better pacman -Su output

Nice work. But how about an extra column with the currently installed version? I like to read up on the major updates of packages but don't care much for the bugfix details.

Example

NAME                       AGE    VERSION  INSTALLED      DESCRIPTION
--------------------------------------------------------------------------------
cracklib(core)             2d05h  2.8.18-1  2.8.18-0     Password Checking Library
dmxproto(extra)            0d14h  2.3.1-1  2.2.1-1      X11 Distributed Multihead X ext
                                                 ension wire protocol
glibc(core)                3d14h  2.12.2-2  2.12.2-1     GNU C Library
gnupg2(extra)              2d05h  2.0.17-1 2.0.16-3       GNU Privacy Guard 2 - a PGP rep
                                                 lacement tool
upgrade? [y/N]:

If you could add that I'd be much obliged.

Offline

#6 2011-01-20 13:31:30

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: php skript for better pacman -Su output

Err, sorry folks, but my script is wrong. Of course Allan broke it ;-)

The age is set the same for all the packages ...

Offline

#7 2011-01-20 13:49:50

Allan
Pacman
From: Brisbane, AU
Registered: 2007-06-09
Posts: 11,487
Website

Re: php skript for better pacman -Su output

karol wrote:

Of course Allan broke it ;-)

yikes

Offline

#8 2011-01-20 14:11:42

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: php skript for better pacman -Su output

A new and better and working and showing currently installed (local) version too!

#!/bin/bash

main () {
  now=$(date "+%s")
  for i in $(pacman -Qqu); do
    builddate=$(expac -t %s %b -S $i)
    sec=$(($now - $builddate))
    age=$(($sec/ 3600 / 24))
    old=$(expac %v -Q $i)
    expac "%n(%r)#$age days#%v#$old #%d" -l'\n' -S $i
  done;
}

(echo "NAME(REPO)#AGE#VERSION#INSTALLED#DESCRIPTION" && main) | column -s "#" -t
#sudo pacman -Su | tail -n1

Last edited by karol (2011-01-20 14:19:44)

Offline

#9 2011-01-20 14:34:31

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: php skript for better pacman -Su output

heh, expac was the first thing that came to mind when I saw this too. 13k binary over installing php any day.

not sure why your script doesn't work for me, karol, but I hacked it up some more and this does work...

#!/bin/bash

declare -A updates
while read -r name ver; do
  updates[$name]="$ver"
done < <(pacman -Qu)

now=$(date +%s)

[[ ${updates[@]} ]] || exit 0

printf "%-20s %-5s %-30s %-s\n" "Name" "Age" "Version" "Description"
printf -- '-%.0s' {1..100}; echo
for name in "${!updates[@]}"; do
  localver=${updates[$name]}
  read -r builddate repo version desc < <(expac -St %s '%b %r %v %d' $name)
  age=$(( (now - builddate) / 3600 / 24 ))

  printf "%-20s %-5s %-30s %-s\n" "$name [$repo]" "${age}d" "$localver -> $version" "$desc"
done

Doesn't do folding of the description, but personally I'd just leave the description off.

Offline

#10 2011-01-20 14:45:44

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: php skript for better pacman -Su output

I knew you'd be using arrays and 'done < <(pacman -Qu)' but

  read -r builddate repo version desc < <(expac -St %s '%b %r %v %d' $name)
  age=$(( (now - builddate) / 3600 / 24 ))

I didn't expect. Really nice :-)
Learned something new again.

Offline

#11 2011-01-20 21:41:18

jafar
Member
Registered: 2011-01-17
Posts: 5

Re: php skript for better pacman -Su output

just a little update
- sorted by age now (switch -n for sort by name)
- old and new version are displayed
- major versionupgrades are colorized red and minor are (hopefully) cyan

your shell-skripts are nice, but too slow because they call expac for every single package.

ps: Always Rolling Can Hurt

#!/usr/bin/php
<?php

$maxlinelength = 120; // CHANGE THIS TO YOUR NEEDS, its the no. of maximum chars that fits in 1 line on your console

$return_var = -1;
system('sudo pacman -Sy >/dev/stdin', $return_var);

$packages = linux('pacman --print-format \'%n\' -Sup');
if (!is_array($packages) || count($packages) < 2)
{
    var_dump($packages);
    die('ERROR variable packages');
}

if (count($packages) == 2 && strpos($packages[1], 'there is nothing to do') !== false)
{
    die('no updates => happy day:)'."\n");
}

$table = array();
$table[] = array('NAME', 'AGE', 'VERSION', 'DESCRIPTION');
$table[] = 'line';

sort($packages);

$pacmanSi = explode("\n\n", implode("\n", linux('pacman -Si '.implode(' ', array_slice($packages,1)))));
$pacmanQi = explode("\n\n", implode("\n", linux('pacman -Qi '.implode(' ', array_slice($packages,1)))));

$download_size = 0;
$installed_size = 0;
$tmptable = array();
for ($i = 1; $i < count($packages); $i++)
{
    $info = pacman_create_info_array(explode("\n", trim($pacmanSi[$i-1])));
    $infoQi = pacman_create_info_array(explode("\n", trim($pacmanQi[$i-1])));
    
    $download_size += intval(intval(trim(str_replace(array('K','.'),'',$info['download size'])).'0') * 1.024);
    $installed_size += intval(intval(trim(str_replace(array('K','.'),'',$info['installed size'])).'0') * 1.024);
    
    $versioncolor = '';
    $checkversion = check_which_version_upgrade($infoQi['version'],$info['version']);
     
    $ageseconds = time() - @strtotime($info['build date']);
    $row = array();
    $row[] = $info['name'].'('.$info['repository'].')';
    $row[] = convert_seconds_to_age($ageseconds);
    if ($checkversion == 'major') $row[] = termcolored($infoQi['version'].' -> '.$info['version'], 'LIGHT_RED');
    elseif ($checkversion == 'minor') $row[] = termcolored($infoQi['version'].' -> '.$info['version'], 'LIGHT_CYAN');
    else $row[] = $infoQi['version'].' -> '.$info['version'];    
    $row[] = $info['description'];
    $tmptable[$ageseconds] = $row;
}

if (strpos(implode(' ', array_slice($argv,1)), '-n') === false)
    krsort($tmptable, SORT_NUMERIC);
foreach ($tmptable as $val) $table[] = $val;

print_shell_table($table, array('maxlinelength' => $maxlinelength));
echo "\n";
echo 'Targets             : '.intval(count($packages) - 1)."\n";
echo 'Total Download Size : '.Bytes_intToString($download_size)."\n";
echo 'Total Installed Size: '.Bytes_intToString($installed_size)."\n";
echo "\n";
$prompt = prompt('upgrade? [y/N]: ');
if (strtolower($prompt) == 'y')
{
    system('sudo pacman -Su>/dev/stdin', $return_var);
}

function Bytes_intToString($bytes)
{
    if ($bytes == 0) return '0,00 B';
            
    $s = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
   $e = floor(log($bytes)/log(1024));
           
    return sprintf('%.2f '.$s[$e], ($bytes/pow(1024, floor($e))));    
}
        
// returns major,minor,mini
function check_which_version_upgrade($old,$new)
{
    $old = explode('.', str_replace('-','.',$old));    
    $new = explode('.', str_replace('-','.',$new));
    if ($old[0] != $new[0]) return 'major';
    $longest = count($old);
    if (count($new) > $longest) $longest = count($new);
    if ($longest == 3) return 'mini';
    if ($old[1] != $new[1]) return 'minor';
    return 'mini';
}

function linux($command)

{

    $output = array();

    $return_var = -1;

    exec($command, $output, $return_var);

    #print "\n".$command."\n";#

    return $output;

}

function prompt($text)    
{
    echo $text;
    $line = trim(fgets(STDIN));
    return $line;
}
    
function convert_seconds_to_age($seconds)
{
    $days = floor($seconds / 86400);
    $seconds = $seconds - ($days * 86400);
    $hours = str_pad(strval(intval(round($seconds / 3600))),2,'0',STR_PAD_LEFT);
    return $days.'d'.$hours.'h';
}

function pacman_create_info_array($info)
{
    $arr = array();
    foreach ($info as $val)
    {
        $val = trim($val);
        if ($val == '') continue;
        $first = strtolower(trim(substr($val,0,strpos($val,':'))));
        $second = trim(substr($val,strpos($val,':') + 1));
        $arr[$first] = $second;
    }
    return $arr;
}


function termcolored($text, $color="NORMAL", $back=1){
    static $_colors = array(
        'LIGHT_RED'      => "[1;31m",
        'LIGHT_GREEN'     => "[1;32m",
        'YELLOW'         => "[1;33m",
        'LIGHT_BLUE'     => "[1;34m",
        'MAGENTA'     => "[1;35m",
        'LIGHT_CYAN'     => "[1;36m",
        'WHITE'         => "[1;37m",
        'NORMAL'         => "[0m",
        'BLACK'         => "[0;30m",
        'RED'         => "[0;31m",
        'GREEN'         => "[0;32m",
        'BROWN'         => "[0;33m",
        'BLUE'         => "[0;34m",
        'CYAN'         => "[0;36m",
        'BOLD'         => "[1m",
        'UNDERSCORE'     => "[4m",
        'REVERSE'     => "[7m",
    );
    
    #foreach ($_colors as $key => $val)
    #    echo chr(27)."$val$key".chr(27)."[0m\n";
    
    $out = $_colors["$color"];
    if($out == ""){ $out = "[0m"; }
    if($back){
        return chr(27)."$out$text".chr(27)."[0m";#.chr(27);
    }else{
        echo chr(27)."$out$text".chr(27)."[0m";#.chr(27);
    }//fi
}// end function

function print_shell_table(&$arr, $options = array())
{
    if (!isset($options['maxlinelength'])) $options['maxlinelength'] = 5000;
    
    $start = 0;
    while (!is_array($arr[$start])) $start++;        
    $max_column_lengths = array();
    for ($i = 0; $i < count($arr[$start]); $i++)
        $max_column_lengths[$i] = 0;        
    
    for ($i = 0; $i < count($arr); $i++)
    {
        if (is_array($arr[$i]))
        {
            for ($j = 0; $j < count($arr[$i]); $j++)
            {
                if (strlen($arr[$i][$j]) > $max_column_lengths[$j])
                    $max_column_lengths[$j] = strlen($arr[$i][$j]);
            }
        }
    }

    $length_longestline = 0;
    for ($i = 0; $i < count($arr); $i++)
    {
        if (is_array($arr[$i]))
        {
            $length = 0;
            
            // loop while < count - 1 (all columns except last)
            for ($j = 0; $j < count($arr[$i]) - 1; $j++)
            {
                $arr[$i][$j] = str_pad($arr[$i][$j], $max_column_lengths[$j] + 2, ' ');
                $length += strlen($arr[$i][$j]);                
            }
            
            // last column
            if ($length + strlen($arr[$i][$j]) > $options['maxlinelength'])
            {
                if ($options['maxlinelength'] - $length > 0)
                    $arr[$i][$j] = str_split($arr[$i][$j], $options['maxlinelength'] - $length);
                else
                    $arr[$i][$j] = '';
                $length_longestline = $options['maxlinelength'];                
            }
            else
            {
                if ($length + strlen($arr[$i][$j]) > $length_longestline)
                    $length_longestline = $length + strlen($arr[$i][$j]);
            }            
        }
    }

    for ($i = 0; $i < count($arr); $i++)
    {
        if (is_array($arr[$i]))
        {
            $offset = 0;
            foreach ($arr[$i] as $val) 
            {
                // last column may be an array
                if (is_array($val))
                {
                    echo $val[0];
                    for ($j = 1; $j < count($val); $j++)
                    {
                        echo "\n";
                        echo str_repeat(' ', $offset);
                        echo ltrim($val[$j]);
                    }
                }
                else
                {
                    $offset += strlen($val);
                    echo $val;
                }
            }
            echo "\n";
        }
        elseif ($arr[$i] == 'line') echo str_repeat('-', $length_longestline)."\n";
    }
}
    
?>

Offline

Board footer

Powered by FluxBB