Almost Useless Thunar custom action :)

Misko_2083

Member
Joined
Mar 15, 2015
Messages
306
Reaction score
18
Ovo je samo moj eksperiment za skladištenje Thunar custom akcija u jednu aplikaciju.

Ovo koristim za reprodukciju audio fajlova. Postavio sam još nekoliko komandi, pa u slučaju da je instaliran Clementine, Qmmp, SMPlayer i Soundconverter, ikone će se pojaviti. Slajder služi za podešavanje jačine zvuka (amixer sset Master).
Komanda za thunar je python3 /putanja/do/zoose-audio.py "%F"
Uputstvo je u samom fajlu.
I na kraju nemam pojma zašto sam ovo nazvao zoose. 🙂

zoose-audio.py

Code:
# Thunar custom actions launcher for the audio files
[HEADING=1]Milos Pavlovic 2015 [email protected][/HEADING]
[HEADING=1]Save this file to /usr/local/bin/zoose-audio.py or at your whish just remember to change the path in command[/HEADING]
[HEADING=1]Setting thunar custom action:[/HEADING]
[HEADING=1]Name: Audio options[/HEADING]
[HEADING=1]Description : Play Audio Files[/HEADING]
[HEADING=1]Command: python3 /usr/local/bin/zoose-audio.py “%F”[/HEADING]
[HEADING=1]File Pattern: *[/HEADING]
[HEADING=1]Appearance: Directories, Audio files[/HEADING]
[HEADING=1]This program is free software; you can redistribute it and/or modify[/HEADING]
[HEADING=1]it under the terms of the GNU General Public License as published by[/HEADING]
[HEADING=1]the Free Software Foundation; either version 2 of the License, or[/HEADING]
[HEADING=1](at your option) any later version.[/HEADING]
[HEADING=1]This program is distributed in the hope that it will be useful,[/HEADING]
[HEADING=1]but WITHOUT ANY WARRANTY; without even the implied warranty of[/HEADING]
[HEADING=1]MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the[/HEADING]
[HEADING=1]GNU General Public License for more details.[/HEADING]
[HEADING=1]You should have received a copy of the GNU General Public License[/HEADING]
[HEADING=1]along with this program; if not, write to the Free Software[/HEADING]
[HEADING=1]Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,[/HEADING]
[HEADING=1]MA 02110-1301, USA.[/HEADING]
zoose_icons=[
[“name”,“icon”,“command”],
[“Play with Audacious”,“audacious”,‘audacious’],
[“Enqueue in Audacious”,“audacious”,‘audacious -e’],
[“Play with Clementine”,“clementine”,‘clementine -l’],
[“Enqueue in Clementine”,“clementine”,‘clementine -a’],
[“Play with SMPlayer”,“smplayer”,‘smplayer’],
[“Enqueue in SMPlayer”,“smplayer”,‘smplayer -add-to-playlist’],
[“Play with VLC”,“vlc”,‘vlc’],
[“Play with Qmmp”,“qmmp”,‘qmmp’],
[“Enqueue in Qmmp”,“qmmp”,‘qmmp -e’],
[“Convert”,“soundconverter”,‘/usr/bin/soundconverter’],
[“Bulk Rename (Thunar)”,“thunar”,‘/usr/bin/thunar --bulk-rename’],
]

import os
import sys
import string
import subprocess
import shlex
from gi.repository import Gtk as gtk
from gi.repository.GdkPixbuf import Pixbuf
[HEADING=1]Which to identify wheather the program exists[/HEADING]
def which(program):
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
[CODE]    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            path = path.strip('"')
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file
    return None
class Startup:
Code:
def destroy(self, widget, data=None):
    # zoose mode
    gtk.main_quit()


def action(self, widget, event, data=None):
    if event.button==1:
       pathinfo=widget.get_path_at_pos(int(event.x),int(event.y))
       if pathinfo==None: return False
       pathnr=pathinfo[0] 
       comm=" %s" % str(sys.argv[1])
       execc="%s" % self.liststore[pathnr][2]
       command=self.liststore[pathnr][2] + comm
       if command=='':
           gtk.main_quit()
       subprocess.Popen(shlex.split(command), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
       gtk.main_quit()
       return True
    return False

def create_label(self):
    label = gtk.Label()
    label.set_markup("Select the action you whish to perform")
    label.set_line_wrap(True)
    label.set_size_request(740, -1)
    self.grid.attach(label, 0, 0, 2, 1)

def create_icons(self):
    # we make the icons
    self.liststore=gtk.ListStore(Pixbuf,str,str)
    self.iv=gtk.IconView(self.liststore)
    self.iv.set_pixbuf_column(0)
    self.iv.set_text_column(1)
    #self.iv.set_columns(3)
    self.iv.set_events(self.iv.get_events())
    self.iv.connect("button-press-event", self.action)

    sw = gtk.ScrolledWindow()
    sw.set_size_request(-1, 250)
    sw.add(self.iv)

    self.grid.attach(sw, 0, 1, 2, 1)
    it=gtk.IconTheme.get_default()
    first=True
    for line in zoose_icons:
        if first:
           first=False
           continue 
        try:
           if '/' in line[1]:
              pixbuf=Pixbuf.new_from_file(line[1]) # if the icon is a path load it from file
           else:
              pixbuf=it.load_icon(line[1],48,0)
        except:
           pixbuf=it.load_icon('gtk-stop',48,0)
        namen=(line[0])
        execc=line[2]
        chk = execc.split(' ')[0]
        if chk == "gksudo":
                chk = execc.split(' ')[1]
        elif chk == "gksu":
                chk = execc.split(' ')[1]
        checking = which(chk)
        chk = execc.split(' ')[0]
        if chk == "gksudo":
                chk = execc.split(' ')[1]
        elif chk == "gksu":
                chk = execc.split(' ')[1]
        checking = which(chk)
        if checking != None:
            self.liststore.append([ pixbuf,namen,line[2] ])

def create_label_two(self):
    # adjustment (initial value, min value, max value,
    # step increment - press cursor keys to see!,
    # page increment - click around the handle to see!,
    # page size - not used here)
    ad1 = gtk.Adjustment(0, 0, 100, 5, 10, 0)
    cmd = "/usr/bin/amixer sget Master | grep '\[' "
    result = os.popen(cmd)
    result = result.readline()
    find_start = result.find('[') + 1
    find_end = result.find('%]', find_start)
    audio_level = int(result[find_start])
    ad1. set_value(audio_level)
    # an horizontal scale
    self.h_scale = gtk.Scale(
        orientation=gtk.Orientation.HORIZONTAL, adjustment=ad1)
    # of integers (no digits)
    self.h_scale.set_digits(0)
    # that can expand horizontally if there is space in the grid (see
    # below)
    self.h_scale.set_hexpand(True)
    # that is aligned at the top of the space allowed in the grid (see
    # below)
    self.h_scale.set_valign(gtk.Align.START)

    # we connect the signal "value-changed" emitted by the scale with the callback
    # function scale_moved
    self.h_scale.connect("value-changed", self.scale_moved)

    self.grid.attach(self.h_scale, 1, 2, 1, 2)

# any signal from the scales is signaled to the label the text of which is
# changed
def scale_moved(self, event):
    val = "{0}".format(int(self.h_scale.get_value()))
    proc = subprocess.Popen('/usr/bin/amixer sset Master ' + str(val) + '%  2>&1 >/dev/null', shell=True, stdout=subprocess.PIPE)
    proc.wait()

def __init__(self):
    # create the window
    window = gtk.Window()
    self.window=window
    window.set_border_width(10)
    window.set_title('Audio File Actions')
    window.connect("destroy", self.destroy)
    window.set_border_width(5)
    window.set_position(1)
    window.set_resizable(False)
    self.grid = gtk.Grid()
    window.add(self.grid)
    window.set_size_request(740, 300)

    self.create_label()
    self.create_icons()
    self.create_label_two()

    it=gtk.IconTheme.get_default()
    try:
        window.set_icon(it.load_icon(gtk.STOCK_HOME, 64, 0))
    except:
        pass
    window.show_all()


def main(self):
    # Cliche init
    gtk.main()

I swear zoose this better work​

if name == “main”:
Code:
 app = Startup()
 app.main()
[/CODE]
 
Last edited:

Commander

Well-known member
Staff member
Joined
Jan 13, 2012
Messages
9,235
Reaction score
530
Šta još znaš da radiš da te odma uposlimo za gagijem na TRIOS-u? 🙂
 
Last edited:

Misko_2083

Member
Joined
Mar 15, 2015
Messages
306
Reaction score
18
Vladimir:
Šta još znaš da radiš da te odma uposlimo za gagijem na TRIOS-u? 🙂
U ovom trenutku rad na dva projekta bi bio previše za mene.
Već godinu dana sam u razvojnom timu jednog projekta. Hvala na ponudi. 🙂
 
Last edited:

Commander

Well-known member
Staff member
Joined
Jan 13, 2012
Messages
9,235
Reaction score
530
Ih… dobro izvini 🙂
 
Last edited:

Misko_2083

Member
Joined
Mar 15, 2015
Messages
306
Reaction score
18
Vladimir:
Ih… dobro izvini 🙂
Nema potrebe da se izvinjavate. 🙂
Izvinite što sam ovako upao na vaš forum. Zanimalo me je šta domaća distribucija može da ponudi i koji su njeni ciljevi.
 
Last edited:

Commander

Well-known member
Staff member
Joined
Jan 13, 2012
Messages
9,235
Reaction score
530
Uuuu nemoj to VI… nema potrebe za persiranjem na internetu 😉

Niko nije upao, najnormalnije si došao ovde na vrata odnosno login… nisam primetio u logovima apache2 da je neko upao 😃

Što se tiče ponude TRIOS-a mislim da si do sada i sam pročitao šta možemo i šta nudimo… jednistvenost 😉
 
Last edited:

Misko_2083

Member
Joined
Mar 15, 2015
Messages
306
Reaction score
18
Vladimir:
Uuuu nemoj to VI… nema potrebe za persiranjem na internetu 😉
Nema problema, možemo i na TI 🙂
Vladimir:
Niko nije upao, najnormalnije si došao ovde na vrata odnosno login… nisam primetio u logovima apache2 da je neko upao 😃
Pa ako ništa nije u logu onda mora da je istina 😃
Vladimir:
Što se tiče ponude TRIOS-a mislim da si do sada i sam pročitao šta možemo i šta nudimo… jednistvenost 😉
Pa, vi ljudi imate nekoliko dobrih ideja. TriOS će biti jedna od boljih distribucija sa naših prostora čim bude spreman. Debian Jessie je odličan izbor.

Da se vratimo na temu. 🙂
Imam par mojih bash scripti za Thunar. Nadam se da će nekome biti korisne.

Ovaj script će pročitati sve dozvole koje fajl ili direktorijum ima a zatim će se pojaviti zenity dijalog pomoću koga mogu da se izmene dozvole.

command: /usr/local/bin/permission.sh %f
Appearance conditions: sve

Code:
#!/bin/bash
[HEADING=1]Misko[/HEADING]
file="$@"

PERM="$(stat --printf=%a%A “$file”)"
USER_="${PERM:0:1}"

if [[ $USER_ = 7 ]]; then TF1=“TRUE”; TF2=“TRUE”; TF3=“TRUE”
fi
if [[ $USER_ = 6 ]]; then TF1=“TRUE”; TF2=“TRUE”; TF3=“FALSE”
fi
if [[ $USER_ = 5 ]]; then TF1=“TRUE”; TF2=“FALSE”; TF3=“TRUE”
fi
if [[ $USER_ = 4 ]]; then TF1=“TRUE”; TF2=“FALSE”; TF3=“FALSE”
fi
if [[ $USER_ = 3 ]]; then TF1=“FALSE”; TF2=“TRUE”; TF3=“TRUE”
fi
if [[ $USER_ = 2 ]]; then TF1=“FALSE”; TF2=“TRUE”; TF3=“FALSE”
fi
if [[ $USER_ = 1 ]]; then TF1=“FALSE”; TF2=“FALSE”; TF3=“TRUE”
fi
if [[ $USER_ = 0 ]]; then TF1=“FALSE”; TF2=“FALSE”; TF3=“FALSE”
fi

GRP_="${PERM:1:1}"
if [[ $GRP_ = 7 ]]; then TF4=“TRUE”; TF5=“TRUE”; TF6=“TRUE”
fi
if [[ $GRP_ = 6 ]]; then TF4=“TRUE”; TF5=“TRUE”; TF6=“FALSE”
fi
if [[ $GRP_ = 5 ]]; then TF4=“TRUE”; TF5=“FALSE”; TF6=“TRUE”
fi
if [[ $GRP_ = 4 ]]; then TF4=“TRUE”; TF5=“FALSE”; TF6=“FALSE”
fi
if [[ $GRP_ = 3 ]]; then TF4=“FALSE”; TF5=“TRUE”; TF6=“TRUE”
fi
if [[ $GRP_ = 2 ]]; then TF4=“FALSE”; TF5=“TRUE”; TF6=“FALSE”
fi
if [[ $GRP_ = 1 ]]; then TF4=“FALSE”; TF5=“FALSE”; TF6=“TRUE”
fi
if [[ $GRP_ = 0 ]]; then TF4=“FALSE”; TF5=“FALSE”; TF6=“FALSE”
fi

ALL_="${PERM:2:1}"
if [[ $ALL_ = 7 ]]; then TF7=“TRUE”; TF8=“TRUE”; TF9=“TRUE”
fi
if [[ $ALL_ = 6 ]]; then TF7=“TRUE”; TF8=“TRUE”; TF9=“FALSE”
fi
if [[ $ALL_ = 5 ]]; then TF7=“TRUE”; TF8=“FALSE”; TF9=“TRUE”
fi
if [[ $ALL_ = 4 ]]; then TF7=“TRUE”; TF8=“FALSE”; TF9=“FALSE”
fi
if [[ $ALL_ = 3 ]]; then TF7=“FALSE”; TF8=“TRUE”; TF9=“TRUE”
fi
if [[ $ALL_ = 2 ]]; then TF7=“FALSE”; TF8=“TRUE”; TF9=“FALSE”
fi
if [[ $ALL_ = 1 ]]; then TF7=“FALSE”; TF8=“FALSE”; TF9=“TRUE”
fi
if [[ $ALL_ = 0 ]]; then TF7=“FALSE”; TF8=“FALSE”; TF9=“FALSE”
fi

STAT_="${PERM:3:13}"
ans=$(zenity --height=450 --width=350 --list --text “File:\n${file##*/}\nPermissions:\n${STAT_}\nchange files permissions” --checklist --column “pick” --column “options” 
“$TF1” “user-read” “$TF2” “user-write” “$TF3” “user-exec” “$TF4” “group-read” “$TF5” “group-write” “$TF6” “group-exec” “$TF7” “all-read” “$TF8” “all-write” “$TF9” “all-exec” --separator=":")
if [ “$ans” != “” ]; then
searchuserread=“user-read”
searchuserwrite=“user-write”
searchuserexec=“user-exec”
user1=“0”
user2=“0”
user3=“0”
searchgroupread=“group-read”
searchgroupwrite=“group-write”
searchgroupexec=“group-exec”
group1=“0”
group2=“0”
group3=“0”
searchallread=“all-read”
searchallwrite=“all-write”
searchallexec=“all-exec”
all1=“0”
all2=“0”
all3=“0”
[CODE]case $ans in  *"$searchuserread"*)
    user1="4" ;;
esac

case $ans in  *"$searchuserwrite"*)
    user2="2" ;;
esac

case $ans in  *"$searchuserexec"*)
    user3="1" ;;
esac

case $ans in  *"$searchgroupread"*)
    group1="4" ;;
esac

case $ans in  *"$searchgroupwrite"*)
    group2="2" ;;
esac

case $ans in  *"$searchgroupexec"*)
    group3="1" ;;
esac

case $ans in  *"$searchallread"*)
    all1="4" ;;
esac

case $ans in  *"$searchallwrite"*)
    all2="2" ;;
esac

case $ans in  *"$searchallexec"*)
    all3="1" ;;
esac

u=$(($user1 + $user2 + $user3))
g=$(($group1 + $group2 + $group3))
a=$(($all1 + $all2 + $all3))
result="$u$g$a"
chmod $result "$file" || { zenity --error --text="An error occurred!\ncheck if you are allowed\nto change permissions\nof the selected file"; }
fi[/CODE]

Sledeći na redu je za proveru md5, sha-1 i sha-2 hash. Potrebno je instalirati pv, apt-get install pv

Code:
#!/bin/bash
[HEADING=1]Purpose: Thunar Custom Action. Calculates hashes.[/HEADING]
[HEADING=1]Usage: /usr/local/bin/checksum %f[/HEADING]
[HEADING=1]Author: Misko_2083[/HEADING]
[HEADING=1]Date: August, 2015[/HEADING]
[HEADING=1]Version: 1.3[/HEADING]
[HEADING=1]Licence GPLv2[/HEADING]
[HEADING=1]Dependancy: zenity or yad, pv[/HEADING]
file="$@"
[HEADING=1]Change next line from zenity to yad if you prefer[/HEADING]
DIALOG=“zenity”

hash $DIALOG 2>/dev/null
if [ $? != 0 ]; then
echo “$DIALOG is not installed”
echo “apt-get install $DIALOG”
exit
fi

hash pv 2>/dev/null
if [ $? != 0 ]; then
echo “pv is not installed”
echo “apt-get install pv”
exit
fi
[HEADING=1]Check that the user didn’t select directory[/HEADING]
if [ -d “$file” ]; then
$DIALOG --error --text="’$file’ is a directory. Checksum cannot handle directories."
exit
fi
[HEADING=1]Check that the file exists[/HEADING]
if [ ! -f “$file” ]; then
$DIALOG --error --text=“Input error. ‘$file’ is not a valid file.”
exit
fi

MD5=([ICODE]echo "" | awk '{print "TRUE","MD5"}'[/ICODE])
SHA1=([ICODE]echo "" | awk '{print "FALSE","SHA-1", $0}'[/ICODE])
SHA224=([ICODE]echo "" | awk '{print "FALSE","SHA-224", $0}'[/ICODE])
SHA256=([ICODE]echo "" | awk '{print "FALSE","SHA-256", $0}'[/ICODE])
SHA384=([ICODE]echo "" | awk '{print "FALSE","SHA-384", $0}'[/ICODE])
SHA512=([ICODE]echo "" | awk '{print "FALSE","SHA-512", $0}'[/ICODE])

selection=$($DIALOG --list --radiolist --height=300 --title=“Checksum” --text=“File: ${file##*/}\nPick the hash function.” --column=“Pick” --column=“Hash” “${MD5[@]}” “${SHA1[@]}” “${SHA224[@]}” “${SHA256[@]}” “${SHA384[@]}” “${SHA512[@]}”)
[HEADING=1]If Cancel is clicked then exit[/HEADING]
if [ $? != “0” ]; then
exit 0
fi
[HEADING=1]Creates a temp file to store the hash sum[/HEADING]
sum_temp=$(mktemp /tmp/XXXXXXXX)

echo $selection | grep “MD5” > /dev/null
if [ $? = 0 ];then
[HEADING=1]start calculating, awk ensures it never reaches 100 because auto-close kills the process if progress bar recevives 100 before writing the result[/HEADING]
[HEADING=1]md5[/HEADING]
( pv -n “$file” | md5sum 2>&1 | tee >(cut -d ’ ’ -f1 > $sum_temp) ) 2>&1 
| awk ‘{if ($1 <=90) print $0; else print 90; fflush(stdout)}’ 
| $DIALOG --progress --title=“MD5sum” --text=“Calculating MD5 for:\n${file##*/}” --percentage=0 --auto-close;
[CODE]# If Cancel is clicked
if [ $? = 1 ];then
    # Removes the tmp file
    rm $sum_temp;
            exit 0
    fi

#Displays results
sum=`cat $sum_temp`
$DIALOG --info --title="MD5sum" --text="MD5sum : $sum\nFile :          ${file##*/}" --no-wrap
fi

echo $selection | grep “SHA-1” > /dev/null
if [ $? = 0 ];then

sha1​

( pv -n “$file” | sha1sum 2>&1 | tee >(cut -d ’ ’ -f1 > $sum_temp) ) 2>&1
| awk ‘{if ($1 <=90) print $0; else print 90; fflush(stdout)}’
| $DIALOG --progress --title=“sha1sum” --text=“Calculating SHA1 for:\n${file##*/}” --percentage=0 --auto-close;
Code:
# If Cancel is clicked
if [ $? = 1 ];then
    # Removes the tmp file
    rm $sum_temp;
            exit 0
    fi


#Displays results
sum=`cat $sum_temp`
$DIALOG --info --title="SHA-1" --text="SHA-1: $sum\nFile :    ${file##*/}" --no-wrap
fi

echo $selection | grep “SHA-224” > /dev/null
if [ $? = 0 ];then

sha224​

( pv -n “$file” | sha224sum 2>&1 | tee >(cut -d ’ ’ -f1 > $sum_temp) ) 2>&1
| awk ‘{if ($1 <=90) print $0; else print 90; fflush(stdout)}’
| $DIALOG --progress --title=“sha224sum” --text=“Calculating SHA224 for:\n${file##*/}” --percentage=0 --auto-close;
Code:
# If Cancel is clicked
if [ $? = 1 ];then
    # Removes the tmp file
    rm $sum_temp;
            exit 0
    fi


#Displays results
sum=`cat $sum_temp`
$DIALOG --info --title="SHA-224" --text="SHA-224 : $sum\nFile :         ${file##*/}" --no-wrap
fi

echo $selection | grep “SHA-256” > /dev/null
if [ $? = 0 ];then
# sha256
( pv -n “$file” | sha256sum 2>&1 | tee >(cut -d ’ ’ -f1 > $sum_temp) ) 2>&1
| awk ‘{if ($1 <=90) print $0; else print 90; fflush(stdout)}’
| $DIALOG --progress --title=“sha256sum” --text=“Calculating SHA256 for:\n${file##*/}” --percentage=0 --auto-close;
Code:
# If Cancel is clicked
if [ $? = 1 ];then
    # Removes the tmp file
    rm $sum_temp;
            exit 0
    fi


#Displays results
sum=`cat $sum_temp`
$DIALOG --info --title="SHA-256" --text="SHA-256 : $sum\nFile :          ${file##*/}" --no-wrap
fi

echo $selection | grep “SHA-384” > /dev/null
if [ $? = 0 ];then
# sha384sum
( pv -n “$file” | sha384sum 2>&1 | tee >(cut -d ’ ’ -f1 > $sum_temp) ) 2>&1
| awk ‘{if ($1 <=90) print $0; else print 90; fflush(stdout)}’
| $DIALOG --progress --title=“sha384sum” --text=“Calculating SHA384 for:\n${file##*/}” --percentage=0 --auto-close;
Code:
# If Cancel is clicked
if [ $? = 1 ];then
    # Removes the tmp file
    rm $sum_temp;
            exit 0
    fi


#Displays results
sum=`cat $sum_temp`
$DIALOG --info --title="SHA-384" --text="SHA-384 : $sum\nFile :         ${file##*/}" --no-wrap
fi

echo $selection | grep “SHA-512” > /dev/null
if [ $? = 0 ];then
# sha512
( pv -n “$file” | sha512sum 2>&1 | tee >(cut -d ’ ’ -f1 > $sum_temp) ) 2>&1
| awk ‘{if ($1 <=90) print $0; else print 90; fflush(stdout)}’
| $DIALOG --progress --title=“sha512sum” --text=“Calculating SHA515 for:\n${file##*/}” --percentage=0 --auto-close;
Code:
# If Cancel is clicked
if [ $? = 1 ];then
    # Removes the tmp file
    rm $sum_temp;
            exit 0
    fi


#Displays results
sum=`cat $sum_temp`
$DIALOG --info --title="SHA-512" --text="SHA-512 : $sum\nFile :           ${file##*/}" --no-wrap
fi

#Cleanup
rm $sum_temp
exit 0[/CODE]
 
Last edited:
Top