SEARCH

Enter your search query in the box above ^, or use the forum search tool.

You are not logged in.

#26 2011-07-14 20:51:50

Sector11
#!'er to BL'er
From: SR11 Cockpit
Registered: 2010-05-05
Posts: 15,667
Website

Re: the ultimate pipe menu thread

Offline

Be excellent to each other!

#27 2011-07-15 04:06:59

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: the ultimate pipe menu thread

case "$path" in    # only escape if string needs it
*\&*|*\<*|*\>*|*\"*|*\'*) pathe=$(sed "s/\&/\&amp;/g;s/</\&lt;/g;s/>/\&gt;/g;s/\"/\&quot;/g;s/'/\&apos;/g;") <<XXX
$path
XXX
;;
*)pathe=$path;;
esac

Offline

#28 2011-07-15 18:24:03

jmbarnes
#! Junkie
Registered: 2009-05-04
Posts: 250

Re: the ultimate pipe menu thread

Last edited by jmbarnes (2011-07-19 00:58:51)

Offline

#29 2011-09-08 22:57:50

h8uthemost
#! Junkie
Registered: 2011-08-09
Posts: 302

Re: the ultimate pipe menu thread

Just wanted to thanks anonymous for posting the MoC script. If I didn't read this thread I wouldn't have known about MoC. Just installed it and fired it up and works beautifully. Light and fast music player. Very cool. Just might end up dumping DeadBeef for this one.

The script will come in handy for a console based media player. Thanks anon.

Last edited by h8uthemost (2011-09-08 23:03:03)


We are a nice, friendly community here and I hope we stay that way.

Offline

#30 2011-10-26 14:34:18

jazzerit
New Member
Registered: 2011-10-26
Posts: 4

Re: the ultimate pipe menu thread

#!/bin/bash



##############################################################################
##############################################################################
##########CONFIGURATION#######################################################
##############################################################################
##############################################################################
filemanager='thunar '  #points to your favoured file manager. If this isn't working, try removing or deleting a space as applicable on this variable.
diskmanager='palimpsest --show-volume=' #points to your favoured disk manager. If this isn't working, try removing or deleting a space as applicable on this variable.
##############################################################################
showbin='true' #set as either true or false (defaults to true). Sets whether to link to the rubbish bin in the menu or not.
bincommand='thunar trash://' #the command to use to open the rubbish bin. Not needed if showbin=false.
##############################################################################
showeject='true' #set as either true or false (defaults to true). Sets whether to show an eject option for optical disks.
ejectcommand='eject -T' #points to the command to use for ejecting disks
##############################################################################
showdm='true' #set as either true or false (defaults to true). Sets whether to show a disk management option for block devices.
##############################################################################
mediaplayer='vlc' #sets the media player to be used. Bear in mind, the media player has to be able to accept block devices on the command line
showmp='true' #set as either true or false (defaults to true). Sets whether to show a media player in the optical disk menus
##############################################################################
##############################################################################
##########END CONFIGURATION###################################################
##############################################################################
##############################################################################




echo "<openbox_pipe_menu>" #start of pipemenu


###############
#block devices#
###############
list=$(ls /sys/block | grep -v sr0 | grep -v scd0 | grep -v ram* | grep -v loop* | grep -v fd* | while read line; do ls /dev | grep -e "$line"; done)
devs=$(echo "$list" | while read line; do blkid /dev/$line; done)
echo "$devs" | while read line; do
  device=${line%%:*}
  devline=$(mount | grep $device)
  devlinepass1=${devline##/dev/*on }
  mountpoint=${devlinepass1%% type *}
  devlinepass1=
  devline=
  if [ -n "$mountpoint" ]; then
    echo "<menu id=\"$device\" label=\"$device mounted at $mountpoint\">"
    echo "<item label=\"open in file manager\"><action name=\"Execute\"><execute>$filemanager\"$mountpoint\"</execute></action></item>"
    if [ ! "$showdm" = "false" ]; then
      echo "<item label=\"open in disk utility\"><action name=\"Execute\"><execute>$diskmanager$device</execute></action></item>"
    fi
    echo "</menu>"
  fi
done


###############
#optical disks#
###############
ls /sys/block | grep -e 'sr\|scd' | while read optdisks; do
  line=$(udisks --show-info /dev/$optdisks | grep -e "has media:" | column -t | grep -w 1)
  if [ -n "$line" ]; then
    media1=$(udisks --show-info /dev/$optdisks | grep -e "media:" | column -t | grep -v rotational | grep -v "has" | column -t | tr '_' ' ')
    media=${media1##media:}
    echo "<separator/>"
    echo "<menu id=\"device\" label=\"$media\">"
        if [ ! "$showmp" = "false" ]; then
            echo "<item label=\"Open in VLC\"><action name=\"Execute\"><execute>$mediaplayer \"/dev/$optdisks\"</execute></action></item>"
        fi
    echo "<item label=\"Open in file manager\"><action name=\"Execute\"><execute>$filemanager\"/media/cdrom0\"</execute></action></item>"
    if [ ! "$showeject" = "false" ]; then
      echo "<item label=\"eject disk\"><action name=\"Execute\"><execute>$ejectcommand</execute></action></item>"
    fi
    echo "</menu>"
  fi
done


##############
#loop devices#
##############
mount | grep -e "/dev/loop[[:digit:]]" | while read line; do
device=${line// on*}
infodmp=$(udisks --show-info $device | grep -e "filename" | tr -s ' ')
source1=${infodmp//*filename: }
name=$(basename "$source1")
source=$(dirname "$source1" | head -c 30)...
pass1=${line//$device on }
mountpoint=${pass1// type*}
  if [ -n "$mountpoint" ]; then
    echo "<separator/>"
    echo "<menu id=\"$source\" label=\"$source on $mountpoint\">"
        echo "<separator label=\"$name ($device)\" />"
    echo "<item label=\"Open in file manager\"><action name=\"Execute\"><execute>$filemanager\"$mountpoint\"</execute></action></item>"
    echo "<item label=\"Open source directory in file manager\"><action name=\"Execute\"><execute>$filemanager\"$source\"</execute></action></item>"
    echo "</menu>"
  fi
done

#############
#rubbish bin#
#############
if [ ! "$showbin" = "false" ]; then
  echo "<separator/>"
  echo "<item label=\"Rubbish bin\"><action name=\"Execute\"><execute>$bincommand</execute></action></item>"
fi


echo "</openbox_pipe_menu>" #end of pipemenu

Last edited by jazzerit (2011-10-29 14:37:13)

Offline

#31 2011-11-30 11:04:35

jelloir
#! CrunchBanger
From: Outside the garden wall
Registered: 2009-08-21
Posts: 212

Re: the ultimate pipe menu thread

Offline

#32 2012-01-23 19:20:15

jmad2011
#! Junkie
From: newton falls ohio
Registered: 2011-12-25
Posts: 344

Re: the ultimate pipe menu thread

#!/usr/bin/env python
#
# Author: Ben Holroyd <holroyd.ben@gmail.com>
# License: GPL 3.0+
#
# This script requires python-mpd
#
# Usage:
# Put an entry in ~/.config/openbox/menu.xml:
# <menu id="mpd" label="MPD" execute="~/.config/openbox/scripts/ompb.py" />
#
import mpd, os, sys, socket
mpdport = 6600
musicfolder ='/home/ben/music/'
filelist = True  #potentially slow and unwieldy with a large collection of music
playlist = True #same for this
program = sys.argv[0]

client = mpd.MPDClient()  
try:
    client.connect("localhost", mpdport)    
except socket.error:
    print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    print "<openbox_pipe_menu>"
    print "  <item label=\"MPD not running, click to start\">"
    print "    <action name=\"Execute\"><execute>mpd</execute></action>"
    print "  </item>"
    print "</openbox_pipe_menu>"
    sys.exit(0)    

song = client.currentsong()                      
stats = client.stats()
status = client.status() 

def play():
    if status['state'] == "stop" or status['state'] == "pause":
        client.play()
    elif status['state'] == "play":
        client.pause()
    
def volume(vol):
    if vol == "up":
        client.setvol(int(status['volume'])+10)
    elif vol == "down":
        client.setvol(int(status['volume'])-10)
           
try:
    if (sys.argv[1] == "play"):       play()
    elif (sys.argv[1] == "stop"):     client.stop()
    elif (sys.argv[1] == "prev"):     client.previous()
    elif (sys.argv[1] == "next"):     client.next()
    elif (sys.argv[1] == "add"):      client.add(sys.argv[2]); client.play()
    elif (sys.argv[1] == "clear"):    client.clear()
    elif (sys.argv[1] == "volume"):   volume(sys.argv[2])
    elif (sys.argv[1] == "playlist"): 
        client.delete(client.playlist().index(sys.argv[2]))
    elif sys.argv[1] == "random":
        client.random(int(not int(client.status()['random'])and True or False))
    elif sys.argv[1] == "repeat":
        client.repeat(int(not int(client.status()['repeat'])and True or False))
except IndexError:
    pass

def item_entry(indent, label, option = '', song = ''):
    """label = label on menu, option = play/pause/stop etc, song = path to song  """
    print "%s<item label=\"%s\">"%(indent, label)
    print "%s  <action name=\"Execute\"><execute>%s %s '%s'</execute></action>" % (indent, program, option, song)
    print "%s</item>" % (indent)
    
def file_walk(dir,indent):
    """ walks through music directory building a menu to view albums"""
    files = os.listdir(dir)
    files.sort()
    for file in files:
        path = os.path.join(dir,file)
        if os.path.isdir(path):
            print "%s<menu id=\"%s\" label=\"%s\">"%(indent, file, file)
            item_entry(indent+'  ','Add all to playlist','add' ,path.replace(musicfolder,''))
            print "%s  <separator />" % indent
            file_walk(path,indent+'  ')
            print "%s</menu>" % indent
        else:
            item_entry(indent,file,'add',path.replace(musicfolder,''))          
    indent = indent[2:]

def track_info(label):
    print "  <menu id=\"%s\" label=\"%s\">"%(label,label)
    print "    <item label=\"Artist: %s\"/>" % song['artist']
    print "    <item label=\"Album: %s\"/>" % song['album']
    print "    <item label=\"Tracklength: %.2f\"/>" % ((int(song['time'])/60)+(int(song['time'])%60.0/100))  
    print "    <item label=\"Track: %s\"/>" % song['track']
    print "    <item label=\"filetype: %s\"/>" % song['file'][song['file'].rfind('.')+1:]
    #print "    <item label=\"Genre: %s\"/>" % song['genre']
    print "  </menu>"


print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
print "<openbox_pipe_menu>"
if status['state'] != "stop":
    track_info("Playing: %s - " % song['artist'])
    track_info(song['title'])
    print "  <separator />"
print "  <item label=\"Status: %s\"/>" % {'play':'Playing','pause':'Paused','stop':'Stopped'}[status['state']]    
print "  <separator />"
item_entry('  ', 'Play/Pause', 'play')    
item_entry('  ', 'Stop', 'stop')
item_entry('  ', 'Prev', 'prev')
item_entry('  ', 'Next', 'next')
print "  <separator />"
if filelist == True:
    print "  <menu id=\"Albums\" label=\"Albums\">"
    file_walk(musicfolder,'  ')
    print "  </menu>"
    print "  <separator />"
if playlist == True:
    print "  <menu id=\"Playlist\" label=\"Playlist\">"
    print "    <item label=\"Click to remove from playlist\"/>"
    print "    <separator />"
    for entries in client.playlist():
        item_entry('    ', entries, 'playlist', entries)
    print "  </menu>"
    print "  <separator />"
item_entry('  ', 'Clear Playlist', 'clear')
item_entry('  ', 'Random %s' % (int(status['random']) and '[On]' or '[Off]'), 'random')    
item_entry('  ', 'Repeat %s' % (int(status['repeat']) and '[On]' or '[Off]'), 'repeat')    
print "  <menu id=\"volume\" label=\"Volume [%s]\">" % (int(status['volume']) > 0 and status['volume']+'%' or 'mute') 
item_entry('    ', 'Volume + 10\% ', 'volume up')
item_entry('    ', 'Volume - 10\%', 'volume down')
print "  </menu>"
print "  <separator />"
print "  <menu id=\"stats\" label=\"Database Stats\">"
print "    <item label=\"Artists in database: %s\"/>" % stats['artists']
print "    <item label=\"Albums in database: %s\"/>" % stats['albums']
print "    <item label=\"Songs in database: %s\"/>" % stats['songs']
print "  </menu>"
print "</openbox_pipe_menu>"

Say your prayer's,Eat your vitamins....AND WHAT YOU GONNA DO BROTHA

Offline

#33 2012-07-03 14:30:06

nabu
Member
Registered: 2011-03-30
Posts: 27

Re: the ultimate pipe menu thread

Can anyone please post the menu.xml from the Statler latest buid - I did overwrite with an older one and now I have entries that don't fit the system. Or if enyone knows how to extract the file from usb installer I would appreciate it.

Thanks

Offline

#34 2012-07-03 16:05:13

pvsage
Internal Affairs
From: North Carolina
Registered: 2009-10-18
Posts: 13,970

Re: the ultimate pipe menu thread

Look in /etc/skel - you should find default user files there, including menu.xml.

Offline

#35 2012-07-03 22:44:50

nabu
Member
Registered: 2011-03-30
Posts: 27

Re: the ultimate pipe menu thread

Offline

#36 2012-11-05 02:57:23

mosesgunn
#! CrunchBanger
Registered: 2012-10-20
Posts: 133

Re: the ultimate pipe menu thread

jmad2011 - I'm getting a similar error.

benj1 - could it be something in the code?

Offline

#37 2012-11-07 15:40:11

mosesgunn
#! CrunchBanger
Registered: 2012-10-20
Posts: 133

Re: the ultimate pipe menu thread

Offline

#38 2012-11-23 16:47:16

sohaeb
New Member
Registered: 2012-11-12
Posts: 9

Re: the ultimate pipe menu thread

Can you guys update this thread ? for example mdp is not woking form and the batter script is also not working.

Offline

#39 2013-08-19 21:31:14

jpope
#! Junkie
From: USA
Registered: 2009-09-20
Posts: 282
Website

Re: the ultimate pipe menu thread

Last edited by jpope (2013-08-20 17:09:03)

Offline

#40 2013-09-10 02:19:02

mw
New Member
Registered: 2013-09-09
Posts: 7

Re: the ultimate pipe menu thread

#!/usr/bin/env python
#
# Author: Ben Holroyd <holroyd.ben@gmail.com>
# License: GPL 3.0+
#
# This script requires python-mpd
#
# Usage:
# Put an entry in ~/.config/openbox/menu.xml:
# <menu id="mpd" label="MPD" execute="~/.config/openbox/scripts/ompb.py" />
#
import mpd, os, sys, socket
mpdport = 6600
musicfolder ='/home/ben/music/'
filelist = True  #potentially slow and unwieldy with a large collection of music
playlist = True #same for this
program = sys.argv[0]

client = mpd.MPDClient()  
try:
    client.connect("localhost", mpdport)    
except socket.error:
    print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    print "<openbox_pipe_menu>"
    print "  <item label=\"MPD not running, click to start\">"
    print "    <action name=\"Execute\"><execute>mpd</execute></action>"
    print "  </item>"
    print "</openbox_pipe_menu>"
    sys.exit(0)    

song = client.currentsong()                      
stats = client.stats()
status = client.status() 

def play():
    if status['state'] == "stop" or status['state'] == "pause":
        client.play()
    elif status['state'] == "play":
        client.pause()
    
def volume(vol):
    if vol == "up":
        client.setvol(int(status['volume'])+10)
    elif vol == "down":
        client.setvol(int(status['volume'])-10)
           
try:
    if (sys.argv[1] == "play"):       play()
    elif (sys.argv[1] == "stop"):     client.stop()
    elif (sys.argv[1] == "prev"):     client.previous()
    elif (sys.argv[1] == "next"):     client.next()
    elif (sys.argv[1] == "add"):      client.add(sys.argv[2]); client.play()
    elif (sys.argv[1] == "clear"):    client.clear()
    elif (sys.argv[1] == "volume"):   volume(sys.argv[2])
    elif (sys.argv[1] == "playlist"): 
        client.delete(client.playlist().index(sys.argv[2]))
    elif sys.argv[1] == "random":
        client.random(int(not int(client.status()['random'])and True or False))
    elif sys.argv[1] == "repeat":
        client.repeat(int(not int(client.status()['repeat'])and True or False))
except IndexError:
    pass

def item_entry(indent, label, option = '', song = ''):
    """label = label on menu, option = play/pause/stop etc, song = path to song  """
    print "%s<item label=\"%s\">"%(indent, label)
    print "%s  <action name=\"Execute\"><execute>%s %s '%s'</execute></action>" % (indent, program, option, song)
    print "%s</item>" % (indent)
    
def file_walk(dir,indent):
    """ walks through music directory building a menu to view albums"""
    files = os.listdir(dir)
    files.sort()
    for file in files:
        path = os.path.join(dir,file)
        if os.path.isdir(path):
            print "%s<menu id=\"%s\" label=\"%s\">"%(indent, file, file)
            item_entry(indent+'  ','Add all to playlist','add' ,path.replace(musicfolder,''))
            print "%s  <separator />" % indent
            file_walk(path,indent+'  ')
            print "%s</menu>" % indent
        else:
            item_entry(indent,file,'add',path.replace(musicfolder,''))          
    indent = indent[2:]

def track_info(label):
    print "  <menu id=\"%s\" label=\"%s\">"%(label,label)
    print "    <item label=\"Artist: %s\"/>" % song['artist']
    print "    <item label=\"Album: %s\"/>" % song['album']
    print "    <item label=\"Tracklength: %.2f\"/>" % ((int(song['time'])/60)+(int(song['time'])%60.0/100))  
    print "    <item label=\"Track: %s\"/>" % song['track']
    print "    <item label=\"filetype: %s\"/>" % song['file'][song['file'].rfind('.')+1:]
    #print "    <item label=\"Genre: %s\"/>" % song['genre']
    print "  </menu>"


print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
print "<openbox_pipe_menu>"
if status['state'] != "stop":
    track_info("Playing: %s - " % song['artist'])
    track_info(song['title'])
    print "  <separator />"
print "  <item label=\"Status: %s\"/>" % {'play':'Playing','pause':'Paused','stop':'Stopped'}[status['state']]    
print "  <separator />"
item_entry('  ', 'Play/Pause', 'play')    
item_entry('  ', 'Stop', 'stop')
item_entry('  ', 'Prev', 'prev')
item_entry('  ', 'Next', 'next')
print "  <separator />"
if filelist == True:
    print "  <menu id=\"Albums\" label=\"Albums\">"
    file_walk(musicfolder,'  ')
    print "  </menu>"
    print "  <separator />"
if playlist == True:
    print "  <menu id=\"Playlist\" label=\"Playlist\">"
    print "    <item label=\"Click to remove from playlist\"/>"
    print "    <separator />"
    for entries in client.playlist():
        item_entry('    ', entries, 'playlist', entries)
    print "  </menu>"
    print "  <separator />"
item_entry('  ', 'Clear Playlist', 'clear')
item_entry('  ', 'Random %s' % (int(status['random']) and '[On]' or '[Off]'), 'random')    
item_entry('  ', 'Repeat %s' % (int(status['repeat']) and '[On]' or '[Off]'), 'repeat')    
print "  <menu id=\"volume\" label=\"Volume [%s]\">" % (int(status['volume']) > 0 and status['volume']+'%' or 'mute') 
item_entry('    ', 'Volume + 10\% ', 'volume up')
item_entry('    ', 'Volume - 10\%', 'volume down')
print "  </menu>"
print "  <separator />"
print "  <menu id=\"stats\" label=\"Database Stats\">"
print "    <item label=\"Artists in database: %s\"/>" % stats['artists']
print "    <item label=\"Albums in database: %s\"/>" % stats['albums']
print "    <item label=\"Songs in database: %s\"/>" % stats['songs']
print "  </menu>"
print "</openbox_pipe_menu>"

Offline

#41 2013-11-03 18:53:58

Yajmon#!
New Member
Registered: 2013-11-03
Posts: 7

Re: the ultimate pipe menu thread

#! /usr/bin/python
import socket
import sys

def debugMarker():
	#this function can be added to any built in action to assist debugging (it shows the window type&name as well as a bastardised Address)
	#e.g. [vlc,Vlc],[AAACAAAP]				any suggestions for the simplest unique object?
	pass

#You can call python (prog) to see what the root menu looks like
#You can call python (prog) AAACAAAP to see what the menu for a given window looks like (look up the code via the first call or by putting the debug marker somewhere appropriate)
#You can call python (prog) AAACAAAP .... to try an action for a given window


#****************************************Space to Customize*********************************
#   (remember don't get rid of alternative method till certain it works [at the moment some task names will break it!!!])

# Actions are in the form of a list containing (Name, {Action})
# actions include WM messages-the atom name to be sent to _NET_WM_STATE_
# 			and   KY messages- a list of key presses (the keycode and modifiers are converted to Hexadecimal starting at 'A')
#Known keycodes
# AK="1" BA="7" CA="o" CH="s" DA="'" DN="/" EB=" "

def MakeListOfActions():
	builtInActions={}
	#This gets called for all actions
	builtInActions[None]= [debugMarker,("Focus","CM0+_NET_ACTIVE_WINDOW"),("Maximize","CM2+_NET_WM_STATE+_NET_WM_STATE_MAXIMIZED_VERT+_NET_WM_STATE_NET_WM_STATE_MAXIMIZED_HORZ"),
	("Maximize V","CM2+_NET_WM_STATE+_NET_WM_STATE_MAXIMIZED_VERT"),("Maximize H","CM2+_NET_WM_STATE+_NET_WM_STATE_MAXIMIZED_HORZ"),
	("Shade","CM2+_NET_WM_STATE+_NET_WM_STATE_SHADED"),("Minimize","CM0+WM_CHANGE_STATE"),
	]
	#******Change here*********
	builtInActions["Vlc"]=[("Play","KYEBAAAA"),("Stop","KYCHAAAA"),("Next","KYDJAAAA"),("Prev","KYCBAAAA")]
	builtInActions["Geany"]=[]
	return builtInActions




#************************************FUNCTIONAL BIT OF THE PROGRAM*********************************


#tries to get rid of anything that makes openbox cry
def filterUnicode(string):
	specialChars="\"'&<>"
	result=""
	i=0	
	while i<len(string):
		if ord(string[i])<32:
			if ord(string[i])==27:i=i+2 #escape character
			i=i+1
		elif string[i] in specialChars:
			result+="&#"+str(ord(string[i]))+";"
			i=i+1
		elif ord(string[i])>128+64:
			#give up skip to end
			val=ord(string[i])
			msb=128			
			while msb&val!=0: msb=msb/2		#search for break in continious bits
			val=val%msb
			i=i+1
			while i<len(string) and ord(string[i])>127:
				val=val*64+ord(string[i])%64
				i=i+1
			result+="&#"+str(val)+";"
		elif ord(string[i])>128:
			result+="&#"+str(ord(string[i]))+";"
			i=i+1
		else:
			result+=string[i]
			i=i+1
	return result

#This is a condensed utility class to connect to an X-Server and do minimal set of actions neccessary
class LXServerQuery:
	def __init__(this):
		this.rootID=None #set in try connect
		this.socket=None #set in try connect
		this.tryConnect()
		this.atomCache={}

	#converts 300,4 to "/0/0/255/45"
	def numberToCharList(this,number,size):
		result=""
		for i in range(0,size):
			result=chr(number%256)+result
			number=number/256
		return result
	#reverts the above
	def charListToNumber(this,number):
		return reduce(lambda y,x:y*256+ord(x),number,0)
	#converts "/5/6 to "EF" for easy transmission
	def charListToAlphaList(this, orig):
		result=""
		for c in orig:
			result=result+chr(ord(c)/16+65)+chr(ord(c)%16+65)
		return result
	#and back again
	def alphaListToCharList(this,orig):
		result=""
		for i in range(0, len(orig),2):
			result=result+chr(16*(ord(orig[i])-65)+ord(orig[i+1])-65)
		return result		
	#Connects to the X Server (anything not required tried to be stripped out)
	#Compare message to that defined
	def tryConnect(this):
			i=0
			this.socket=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
			this.socket.connect('/tmp/.X11-unix/X'+str(i))
			openingMessage="B"+chr(0)+chr(0)+chr(11)+chr(0)*8		
			this.socket.send(openingMessage)
			message=this.getMessage()
			if message[0]!=chr(1): return None
			lenVendor=ord(message[24])*256+ord(message[25])
			if (lenVendor%4)!=0:
				paddedV=lenVendor-(lenVendor%4)+4
			else:
				paddedV=lenVendor
			screenCount=ord(message[28])
			numFormats=ord(message[29])
			
			screenIndex=40+paddedV+8*numFormats
			this.rootID=message[screenIndex:screenIndex+4]
	#waits for a message back from the XServer
	def getMessage(this):
			message=""
			while message=="":
				try:
					message=message+this.socket.recv(10000)
				except Exception:
					pass #message unchanged, continue waiting
			if message[0]==chr(0):
				print "Error Message Received: Error="+str(ord(message[1]))+"@"+str(map(ord,message[4:8]))
			return message

	#This returns the 4 character 'ATOM' that represents a instruction
	def getEWMHkey(this,key):
		if key in this.atomCache: return this.atomCache[key]
		if(len(key)%4!=0):
			message=key+chr(0)*(4-len(key)%4)
		else:
			message=key
		message=chr(0)+chr(len(key))+chr(0)+chr(0)+message
		message=chr(16)+chr(1)+chr(0)+chr(1+len(message)/4)+message
		this.socket.send(message)
		message=this.getMessage()
		this.atomCache[key]=message[8:12]
		return message[8:12]

	#Sends a message to find a property, returns the length, the format, and the data
	def getProperty(this,window,key):
		message=window    #root num
		message=message+key
		message=message+chr(0)*4	#no fixed type
		message=message+chr(0)*4	#no offset
		message=message+chr(0)*3+chr(255)	#no length limit
		message=chr(20)+chr(0)+chr(0)+chr(6)+message		   #op 20 get property 6*4 bytes
		this.socket.send(message)
		result=this.getMessage()
		length=this.charListToNumber(result[16:20])
		return (length, ord(result[1]), result[32:32+length*ord(result[1])/8])
	#wraps an event in a client message
	def sendEvent(this,destWindow, propogate,mask, event):			
			this.socket.send(chr(25)+chr(propogate)+chr(0)+chr(11)+destWindow+this.numberToCharList(mask,4)+event)		
				
	def close(this):
		this.socket.close()



#This is used when called with a given window and argument
class WindowCommand:
	#Gets the action and tells it to do something
	def __init__(this,window,action):		
			query=LXServerQuery()
			window=query.alphaListToCharList(window)
			print action[0:2]
			if action[0:2]=="CM":
				print "HERE"
				data0=int(action[2])
				actions=action[4:].split("+")
				if len(actions)==3:
					this.sendStateEvent(query, window, data0,query.getEWMHkey(actions[0]), query.getEWMHkey(actions[1]), query.getEWMHkey(actions[2]))
				elif len(actions)==2:
					this.sendStateEvent(query, window, data0,query.getEWMHkey(actions[0]),query.getEWMHkey(actions[1]), chr(0)*4)					
				elif len(actions)==1:
					this.sendStateEvent(query, window, data0,query.getEWMHkey(actions[0]),chr(0)*4,chr(0)*4)					
			elif action[0:2]=="KY":
				for i in range(2,len(action),7):					
					#send key press event format "KKMMMM "
					this.sendKeyEvent(query, window,query.alphaListToCharList(action[i:i+2]),query.alphaListToCharList(action[i+2:i+6]))
	#I think this section is doing things in the wrongish way as can't minimize, etc...
	def sendStateEvent(this, query, targetWindow, data0,m1, p1, p2):
		event=chr(33)+chr(32)+chr(0)+chr(0)+targetWindow+m1
		event=event+chr(0)*3+chr(data0)+p1+p2+chr(0)*4
		event=event+chr(0)*4
		query.sendEvent(query.rootID,0,0x00180000,event) #Structure Notify Redirect
		print "Sent client message"
	def sendKeyEvent(this, query, targetWindow, keyCode, keyMod):
		event=keyCode+chr(0)+chr(0)
		event=event+chr(0)*4+query.rootID+targetWindow+chr(0)*4+chr(0)*4+chr(0)*4+keyMod+chr(1)+chr(0)
		query.sendEvent(targetWindow,1,1,chr(2)+event) #key down
		query.sendEvent(targetWindow,1,2,chr(3)+event) #key up
		
#This is used when called with a given window it provides a pipe menu to Do Stuff
class WindowOptions:
		#calculates the options could prob improve later
		def __init__(this, programLocation, window):	
			this.programLocation=programLocation
			this.builtInActions=MakeListOfActions()
			this.printablewindow=window
			query=LXServerQuery()
			this.window=query.alphaListToCharList(window)
			this.actionNames=[]+this.builtInActions[None]
			programtype=query.getProperty(this.window, query.getEWMHkey("WM_CLASS"))[2].split(chr(0))
			if len(programtype)>1 :				
				if programtype[1] in this.builtInActions:
					this.actionNames=this.actionNames+this.builtInActions[programtype[1]]
			if debugMarker in this.actionNames:
					this.actionNames=this.actionNames+[(",".join(programtype),"Test"),(window,"")]
					this.actionNames.remove(debugMarker)
		#produces the openbox menu
		def toMenu(this):
			result= '<openbox_pipe_menu>\n'
			for aname in this.actionNames:				
					result=result+"			<item label='"+aname[0]+"'>\n"
					result=result+"				<action name='Execute'><command>"
					result=result+this.programLocation+" "+this.printablewindow+" "+aname[1]+""
					result=result+"</command></action>\n"
					result=result+"			</item>\n"
			result=result+ '</openbox_pipe_menu>'
			return result
			
			


#This is used when called with no arguments it provides a pipe menu of all windows
class Task:
	def __init__(this,window,query):
		this.window=window
		this.name=filterUnicode(query.getProperty(window, query.getEWMHkey("WM_NAME"))[2])
		this.icon=query.getProperty(window, query.getEWMHkey("_NET_WM_ICON_NAME"))[2]
		this.desktop=ord(query.getProperty(window, query.getEWMHkey("_NET_WM_DESKTOP"))[2][3]) #fails if more than 254 desktops	(not likely)
		this.printableWindow=query.charListToAlphaList(this.window)
	def __str__(this):
		return this.toMenu(0,sys.argsv[0])
	#produces pipe menu fragment
	def toMenu(this,uid,programLocation):
		result="		<menu id='/Taskbar/"+str(uid)+"' label='"+this.name+"'  execute='"+programLocation+" "+this.printableWindow+"'>\n"
		result=result+"		</menu>\n"
		return result

class TaskList:
	def __init__(this, programLocation):
		query=LXServerQuery()
		this.programLocation=programLocation
		this.desktopnames,this.tasks=this.getWindowList(query)
	#gets active tasks and puts them into desktops
	def getWindowList(this,query):
		desktopnames=query.getProperty(query.rootID,query.getEWMHkey("_NET_DESKTOP_NAMES"))[2]
		desktopnames=map(filterUnicode,desktopnames.split('\0'))[:-1]
		tasks=[]
		windowIDs=query.getProperty(query.rootID,query.getEWMHkey("_NET_CLIENT_LIST_STACKING"))[2]
		for i in range(0,len(windowIDs),4):			
			tasks.append(Task(windowIDs[i:i+4],query))
		return desktopnames,tasks
	#produces pipe menu
	def toMenu(this):
		result= '<openbox_pipe_menu>\n'
		uid=0
		for i,desktop in enumerate(this.desktopnames):
			result=result+"	<menu id='/TaskbarDesktop/"+desktop+"' label='D"+desktop+"'>\n"
			for item in this.tasks:
				if item.desktop==i or item.desktop==255:
					result=result+item.toMenu(uid,this.programLocation)
					uid=uid+1
			result=result+"	</menu>\n"
		result=result+ '</openbox_pipe_menu>'
		return result

if len(sys.argv)==1:
	t=TaskList(sys.argv[0],)
	print t.toMenu()
elif len(sys.argv)==2:
	w=WindowOptions(sys.argv[0],sys.argv[1])
	print w.toMenu()
elif len(sys.argv)==3:
	w=WindowCommand(sys.argv[1],sys.argv[2])
else:
	print "Odd number of arg",sys.argv

Last edited by Yajmon#! (2013-11-13 22:11:26)

Offline

#42 2013-11-26 01:39:55

cloverskull
#! Junkie
Registered: 2013-10-26
Posts: 377

Re: the ultimate pipe menu thread

Hey guys, I made a playonlinux game launcher pipe menu, code follows:

#!/bin/bash
#       polmenu.sh - a playonlinux game launcher for openbox
#
#
# path to your PlayOnLinux shortcuts folder, assumes $HOME/
pol_shortcuts_folder=.PlayOnLinux/shortcuts/

# command to launch playonlinux software
pol_launcher_command='playonlinux --run'

function generate_pol_menu {

ls ~/$pol_shortcuts_folder | while read; do

        echo '<item label="'"${REPLY}"'">'
        echo -n '<action name="Execute"><execute>'
        echo -n "$pol_launcher_command '${REPLY}'"
        echo '</execute></action>'
        echo '</item>'
   done

}

echo '<openbox_pipe_menu>'

generate_pol_menu

echo '</openbox_pipe_menu>'

Cheers!

Offline

#43 2013-11-29 10:06:48

cloverskull
#! Junkie
Registered: 2013-10-26
Posts: 377

Re: the ultimate pipe menu thread

And as a follow-up, I wrote one that (for me) gets a lot more use.  This one parses your scummvmrc file (~/.scummvmrc) and makes a pipemenu.  Code follows.

#!/bin/bash
#       openbox_scummvm_pipemenu.sh
#       initially created 2013 - Ryan Fantus
#
# assumes your scummvmrc file is ~/.scummvmrc and your scummvm launcher is /usr/local/bin/scummvm
# I noticed a bug with unescaped ampersands (&) cropping up in Sam & Max, so I replaced it with "and".

scumm_launcher=/usr/local/bin/scummvm
scumm_rc=~/.scummvmrc

function generate_scummvm_menu {

  while read line
  do
        if [[ $line == "["* ]]; then                    # test for an open bracket, see ~/.scummvmrc for why
                if [[ $line != "[scummvm]" ]]; then     # but skip the [scummvm] bracket
                        scumm_description=''            # and here make sure we find [game] followed by
                        while [[ $scumm_description != "description"* ]]; do    # description= text
                                read scumm_description
                        done
                        echo -n '<item label="'
                        echo -n $scumm_description | sed s/'description='/\/g | tr -d '\"' | sed s/'&'/'and'\/g
                        echo '">'
                        echo -n '<action name="Execute"><execute>'
                        echo -n "$scumm_launcher '${line}'" | tr -d "[]"
                        echo '</execute></action>'
                        echo '</item>'
                fi
        fi
  done < $scumm_rc

}

echo '<openbox_pipe_menu>'

# First, we'll create a launcher specifically for ScummVM

echo '<item label="ScummVM">'
echo -n '<action name="Execute"><execute>'
echo -n "$scumm_launcher"
echo '</execute></action>'
echo '</item>'
echo '<separator/>'

generate_scummvm_menu

echo '</openbox_pipe_menu>'

Cheers again!

Offline

#44 2014-01-03 19:53:06

gomer
New Member
Registered: 2014-01-03
Posts: 1

Re: the ultimate pipe menu thread

I am trying to come up with a pipemenu but having issues sorting out how to make something like this happen

CustomMainCategory/
├── subCat1
│   ├── subsubCat1
│   │   ├── subsubsubCat1
│   │   │   └── Tool1
│   │   └── Tool1
│   ├── Tool1
│   └── Tool2
└── subCat2
    ├── Tool1
    └── Tool2

Also what would my categorty line look like? Would it be similar to this if I want it in subCat1 only?

Categories=SubCat1;

I have been able to get CustomMainCategory to display, but cant sort out the submenu portions. I have tried messing with schema.pl but dont think I am getting it yet. Thanks for your time and help on this.

Last edited by gomer (2014-01-03 19:56:29)

Offline

#45 2014-11-14 23:38:31

uriel1998
Member
From: Dayton, OH
Registered: 2012-02-10
Posts: 49
Website

Re: the ultimate pipe menu thread

#!/bin/bash

########################################################################
# Credits, blame, etc
########################################################################
#	searchraw - a surfraw launcher for openbox

#   Base from openbox_playonlinux_pipemenu by Ryan Fantus
#	https://github.com/ryanfantus/openbox_playonlinux_pipemenu

#	Helpful solutions
#   http://stackoverflow.com/questions/5998066/bash-script-variable-content-as-a-command-to-run
#   http://www.cyberciti.biz/faq/awk-find-and-replace-fields-values/
# 	


########################################################################
# Usage
########################################################################

# Call this script by itself to generate an openbox menu with all elvi
# that are on the system and to search them with a popup text box.
# Call with -d to pop up (optional) few elvi to use, or to use the 
# default, and search with a popup text box.  
# Call with -d and an elvi to pop up a text box to search.

########################################################################
# Requires
########################################################################

# * Surfraw - http://surfraw.alioth.debian.org
# * Openbox (Sort of.  This is way overblown if you're not using OB.)
# * zenity or a replacement like matedialog or wenity.

########################################################################
# Configuration
########################################################################

# Default elvii.  SPECIFY ONE HERE
default_elvii="google"

# Do you want a popup if no elvii are specified?
popup="TRUE"

# What elvii should be presented in the Zenity combobox?  These should
# be in a single line, space separated.
# DO NOT INCLUDE THE DEFAULT ELVII HERE unless you want repeats
custom_elvii="scholar stack github wayback wikipedia"

########################################################################
# Generate list of elvii for OB
########################################################################

function generate_elvi_menu {

sr -elvi | while read; do
		elvi_cmd=$(echo "${REPLY}" | awk '{print $1}')
		# The long description chokes my install of OB
		elvi_dsc=$(echo "${REPLY}" | awk '{print $1}')
		echo -n '<item label="'"$elvi_dsc"'">'
		echo -n '<action name="Execute"><execute>'
		echo -n "$0 -d $elvi_cmd"
		echo '</execute></action>'
		echo '</item>'
	done

}

########################################################################
# Write the Menu				
########################################################################
function write_ob_menu {

echo '<openbox_pipe_menu>'
generate_elvi_menu
echo '</openbox_pipe_menu>'

}

# Are we being launched directly?
if [ "$1" == "-d" ]; then
	# When being launched directly, what elvii should be presented/used?
	if [ "$2" == "" ]; then 
		if [ "$popup" == "TRUE" ]; then
			buildinglist=" $default_elvii $custom_elvii"
			elvii_list=$(echo "$buildinglist" | awk '{ gsub(" "," FALSE "); print }')
			choicecmdline="zenity --timeout 30 --list  --text 'Elvi to use?' --radiolist  --column 'Pick' --column 'Elvi' $elvii_list"
			echo "$choicecmdline"
			read
			elvi=$(eval "$choicecmdline")
#			elvi=$(zenity --timeout 30 --list  --text "Elvi to use?" --radiolist  --column "Pick" --column "Elvi" TRUE google FALSE scholar FALSE stack FALSE github FALSE wayback FALSE wikipedia)
		else
			elvi="$default_elvii"
		fi	
	else
		elvi="$2"
	fi

	szAnswer=$(zenity --entry --title "search" --text "Search what?" --entry-text "") 
	if [ "$szAnswer" != "" ]; then
		sr_command="sr -g $elvi $szAnswer"
		eval "$sr_command"
	fi
else
	write_ob_menu
fi

Offline

#46 2014-11-15 20:48:41

olminator
New Member
Registered: 2014-11-15
Posts: 6

Re: the ultimate pipe menu thread

I made one that lists all thunar bookmarks (listed in ~/.gtk-bookmarks):

#!/usr/bin/env sh

echo '<openbox_pipe_menu>'

cat ~/.gtk-bookmarks | while read line; do
  dir=`echo $line | sed 's/[ ][^ ]*$//' | sed 's/file:\/\///'`
  name=`echo $line | sed 's/^.*\s//'`
  echo '<menu execute="/usr/bin/cb-places-pipemenu '$dir'" label="'$name'" id="'$name'"/>'
done

echo '</openbox_pipe_menu>'

and another one that lists google chrome bookmarks (written in coffeescript... but quite easy to translate):

#!/usr/bin/env coffee
fs = require 'fs'
_ = require 'underscore'

bookmarks = JSON.parse fs.readFileSync "#{process.env.HOME}/.config/google-chrome/Default/Bookmarks", 'utf8'
roots = [
  bookmarks.roots.bookmark_bar
  bookmarks.roots.other
]

bookmarks = [].concat bookmarks.roots.bookmark_bar.children, bookmarks.roots.other.children

print = ->
  console.log.apply console, arguments

htmlentities = (str) ->
  str.replace /&/g, '\&amp;'
    .replace /"/g, '\&quot;'
    .replace /</g, '\&lt;'
    .replace />/g, '\&gt;'

printBookmark = (bookmark) ->
  if bookmark.children
    # print menu
    print '<menu id="chrome-bookmark-' + bookmark.id + '" label="' + bookmark.name + '">'
    _.each bookmark.children, (bookmark) ->
      printBookmark bookmark
    print '</menu>'
  else
    return if bookmark.url.match /^javascript/
    # print item
    print '<item id="chrome-bookmark-' + bookmark.id + '" label="' + (htmlentities bookmark.name) + '">'
    print '<action name="Execute">'
    print '<command>'
    print 'x-www-browser \'' + (htmlentities encodeURI bookmark.url) + '\''
    print '</command>'
    print '</action>'
    print '</item>'

print '<openbox_pipe_menu>'

_.each roots, (root) ->
  print '<separator label="' + root.name + '"/>'

  _.each root.children, (bookmark) ->
    printBookmark bookmark

print '</openbox_pipe_menu>'

Last edited by olminator (2014-11-15 20:51:43)

Offline

Board footer

Powered by FluxBB

Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.
Server: bleh

Debian Logo