[SoaS] sugar coating
tom-ipp
develop at tom-ipp.info
Tue Jul 27 15:11:24 EDT 2010
Hi,
I wrote a small script in python which lets me "sugarcoat" linux
application for sugar.
In fact, you call the script with the name of an installed program (need
the .desktop file) and it returns an activity directory -> an icon
appears in the home view to launch that program.
The -l option will return you the programs installed
in /usr/share/applications
It looks for an svg icon, if not found the icon of the journal activity
is used.
It is based around the famous library libsugarize.so and the script
found here :
http://wiki.sugarlabs.org/go/Running_Linux_Applications_Under_Sugar
Tested with fedora 13, for the application cheese, fedora-abe and
fedora-supertux.
You put the script simpleSugarCoater.py in your home directory, with the
libsugarize.so.
Morally, the sugar coating is not the best thing to promote the sugar
platform. BUT we can't wait for the supertux developer to sugarize their
application and we all need supertux. So...
Comments welcomed.
Sincerely.
Thomas
The script:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# build activity directory for launching linux application from sugar
# GNU General Public License v.3
# Author : Thomas Jacoviac
# Contact : develop at tom-ipp.info
#
import os
import shutil
import sys
import getopt
import xdg.DesktopEntry
import xdg.IconTheme
import xdg.BaseDirectory
import mimetypes
# == Declarations ==
activityPath = os.path.join(os.path.expanduser("~"), "Activities") #By
default, the directory will be created in the user's Activities
directory
defaultIcon =
"/usr/share/icons/sugar/scalable/apps/activity-journal.svg" # By
default, this icon will be used for the application
# == Internal functions ==
def sugarCoat(binary):
global activityPath
global defaultIcon
iconName, execString = parseDesktopFile(binary) #Retrieve icon and
exec from desktop file
iconPath = locateIcon(iconName)
createActivityDir(os.path.join(activityPath, binary + ".activity"))
# Create activity directory tree
createInfoFile(activityPath, binary) # Create info file
shutil.copy(iconPath, os.path.join(activityPath, binary +
".activity", "activity", "icon.svg")) # Copy icon to activity directory
if createLauncherFile(activityPath, binary, execString):
sys.exit("Error with launcher creation") #Create launcher
# Copy libsugarize.so in activity directory
#TODO: More versatile location for distributing libsugarize.so
shutil.copy("libsugarize.so", os.path.join(activityPath, binary +
".activity", "lib", "libsugarize.so"))
def parseDesktopFile(binary):
dirs = xdg.BaseDirectory.xdg_data_dirs
for dir in dirs:
if os.path.isfile(os.path.join(dir + "/applications/" + binary +
".desktop")):
desktopFileContent = xdg.DesktopEntry.DesktopEntry(filename
= os.path.join(dir + "/applications/" + binary + ".desktop"))
execString = desktopFileContent.getExec()
iconName = desktopFileContent.getIcon()
return iconName, execString
sys.exit("No .desktop file for this application")
def locateIcon(iconName):
global defaultIcon
iconPath = xdg.IconTheme.getIconPath(iconName, None, None, ["svg"])
#Get iconPath with xdg
#TODO: Use xdg to magically find type, mimetypes is based on
filename suffix
if mimetypes.guess_type(iconPath)[0] != "image/svg+xml": # Check if
icon is svg file
#From
http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
#apps should look in $HOME/.icons, /usr/share/icons
and /usr/share/pixmaps (in that order)
dirs = [os.path.expanduser("~/.icons"), "/usr/share/icons",
"/usr/share/pixmaps"]
for dir in dirs:
for root, ds, files in os.walk(dir):
for file in files:
if mimetypes.guess_type(file)[0] == "image/svg+xml":
if os.path.splitext(file)[0] == iconName:
iconPath = os.path.join(root, file)
return iconPath
return defaultIcon # If no svg icon found, use default icon
def createLauncherFile(activityPath, binary, execString):
launcherFile = open(os.path.join(activityPath, binary + ".activity",
"bin", "launcher.sh"), "w")
launcherFile.write("#!/bin/sh\n")
launcherFile.write("# from
http://wiki.sugarlabs.org/go/Running_Linux_Applications_Under_Sugar\n")
launcherFile.write("\n")
launcherFile.write("while [ -n \"$2\" ] ; do\n")
launcherFile.write(" case \"$1\" in\n")
launcherFile.write(" -b | --bundle-id) export
SUGAR_BUNDLE_ID=\"$2\" ;;\n")
launcherFile.write(" -a | --activity-id) export
SUGAR_ACTIVITY_ID=\"$2\" ;;\n")
launcherFile.write(" -o | --object-id) export
SUGAR_OBJECT_ID=\"$2\" ;;\n")
launcherFile.write(" -u | --uri) export SUGAR_URI=
\"$2\" ;;\n")
launcherFile.write(" *) echo unknown argument $1 $2 ;;\n")
launcherFile.write(" esac\n")
launcherFile.write(" shift;shift\n")
launcherFile.write("done\n")
launcherFile.write("export LD_PRELOAD=
\"$SUGAR_BUNDLE_PATH/lib/libsugarize.so\"\n")
launcherFile.write("export NET_WM_NAME=\"" + binary + "\"\n")
launcherFile.write("exec " + execString + "\n")
launcherFile.close
launcherFile.flush() #For xo creation we need to ensure that file is
written on disk
os.fsync(launcherFile.fileno()) #idem
os.chmod(os.path.join(activityPath, binary + ".activity", "bin",
"launcher.sh"), 0755)
def createActivityDir(directory):
if not os.path.isdir(directory) : os.makedirs(directory)
if not os.path.isdir(os.path.join(directory, "activity")):
os.mkdir(os.path.join(directory, "activity"))
if not os.path.isdir(os.path.join(directory, "bin")):
os.mkdir(os.path.join(directory, "bin"))
if not os.path.isdir(os.path.join(directory, "lib")):
os.mkdir(os.path.join(directory, "lib"))
return
def createInfoFile(activityPath, appName):
infoFile = open(os.path.join(activityPath, appName + ".activity",
"activity", "activity.info"), "w")
infoFile.write("[Activity]\n")
infoFile.write("name = " + appName + "\n")
infoFile.write("activity_version = 1\n")
infoFile.write("service_name = info.tom-ipp.sugar." + appName +
"\n")
infoFile.write("license = GPLv3\n")
infoFile.write("icon = icon\n")
infoFile.write("exec = launcher.sh\n")
infoFile.write("show_launcher = yes\n")
infoFile.close()
return
# == Man page for the script ==
def usage():
print "----------------- Usage
----------------------------------------"
print "sugarCoater.py create an activity directory, including
launcher,"
print "for a standard linux application"
print "Usage: sugarCoater [options] application"
print "-h --help Prints this"
print "-l --list Lists applications installed"
# == Main function ==
def main(argv):
try:
opts, command = getopt.getopt(argv, "hl", ["help", "list"])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
if opt in ("-l", "--list"):
listApps = []
for app in sorted(os.listdir("/usr/share/applications/")):
if os.path.splitext(app)[1] == ".desktop":
listApps.append(os.path.splitext(app)[0])
print os.path.splitext(app)[0]
sys.exit()
if not command:
print "You need to provide the application you want to
sugarcoat."
print "Use -l or --list option to look in your's
$XDG_DATA_DIRS :"
print xdg.BaseDirectory.xdg_data_dirs
sys.exit(2)
sugarCoat(command[0])
if __name__ == "__main__":
main(sys.argv[1:])
More information about the SoaS
mailing list