From Amarok Wiki

Deutsch | English | Français | Türkçe


Contents

Introduction

ScriptManager, le gestionnaire de scripts d'Amarok
ScriptManager, le gestionnaire de scripts d'Amarok

Développer un script pour Amarok permet d'ajouter des fonctionnalités supplémentaires sans toucher au code principal du lecteur. Les scripts sont similaires aux plugins, sauf qu'au lieu d'utiliser une API de plugin dédiée, ils utilisent l'interface DCOP d'Amarok pour communiquer. Cela rend possible l'écriture de scripts dans à peu près n'importe quel langage de programmation, comme Ruby, Python ou le bash. Le langage recommandé est Ruby, qui est facile à apprendre et très bien fourni pour les scripts Amarok. L'équipe d'Amarok sera heureuse de vous assister si vous avez des questions concernant la programmation en Ruby.

De plus, Amarok peut prévenir les scripts d'événements spéciaux et les faire réagir en adéquation. Ce système de notification sera détaillé plus loin.

Bindings

Les scripts les plus simples ne nécessitent aucune interaction avec l'utilisateur, tandis que d'autres possèdent une interface graphique plus évoluée, agissant telle une petite application indépendante. Pour programmer des interfaces graphiques dans le langage de votre choix, vous pouvez utiliser l'un des nombreux "bindings" que fournit KDE, comme par exemple la bibliothèque logicielle QtRuby, qui permet l'utilisation du "toolkit" Qt dans le langage Ruby. Cependant, il est important de noter que les utilisateurs finaux d'Amarok n'ont pas obligatoirement installé tous les bindings disponibles. Par conséquent, si vous décidez d'utiliser l'une de ces bibliothèques, il serait plus indiqué d'en utiliser une parmi les plus répandues, comme QtRuby ou PyQt.

La tâche incombant à votre script est de vérifier que tout module que vous souhaitez utiliser est bel et bien disponible. Dans le cas contraire, si une dépendance est insatisfaite, votre script devra gérer l'erreur et en informer l'utilisateur par le biais d'un message avec la commande "kdialog", afin qu'il comprenne pourquoi le script ne peut s'exécuter.

Note: didacticiel de kdialog

L'exemple suivant montre comment traiter une dépendance insatisfaite en Ruby :

begin
       require 'Korundum'
rescue LoadError
       error = 'Korundum (KDE bindings for ruby) from kdebindings v3.4 is required for this script.'
       `kdialog --sorry '#{error}'`
       exit
end

Serveur SVN (Subversion)

Le projet amaroK offre aux développeurs de scripts un compte SVN sur notre serveur. SVN est un système de gestion de version qui vous aidera grandement à développer vos programmes. Il vous permet d'annuler vos erreurs à n'importe quel moment, et il autorise plusieurs développeurs à collaborer sur un seul projet. Si vous souhaitez un compte, écrivez à notre mailing list amarok@kde.org.

Tutorial: Les Templates

amaroK fournit des templates en plusieurs langages dans le répertoire scripts/templates/. Vous pouvez utiliser ces scripts comme bases pour vos propres scripts, et les affubler des fonctions que vous souhaitez. Vous noterez que scripter est extrêmement simple : par exemple, si vous savez un peu programmer en Ruby, faire votre propre script ne devrait pas prendre trop de temps :)

TODO: Nous avons besoin de plus de templates ! Si vous en faites, merci de l'envoyer sur notre mailing list amarok@kde.org.

Contrôler Amarok avec DCOP

Les scripts peuvent contrôler Amarok en appelant l'une de ses fonctions DCOP. La façon la plus simple de le faire est d'utiliser l'utilitaire en ligne de commande "dcop", qui est inclus dans chaque distribution de KDE. Voici un exemple pour augmenter le volume principal :

 "dcop amarok player volumeUp"

La plupart des langages de scripts permettent d'éxécuter des programmes externes, avec une fonction comme exec(). De cette façon, "dcop" est invoqué facilement.

En Ruby, c'est extrémement simple, il suffit de placer la commande entre ` ` (opérateur backtick) :

 artist = `dcop amarok player artist`

Voici un exemple en Python :

 import os
 os.system("dcop amarok player volumeDown")

Avec Python, il y a d'autres moyens de faire des appels DCOP. Vous pouvez utiliser le module dcop de pyKDE ou dcopext . A cause de certaines limitations (ex : vous ne pouvez appeler que amarok.contextbrowser.showLyrics(), pas amarok.contextbrowser.showLyrics(QString)), nous vous conseillons d'utiliser une version modifiée de dcopext. ici

 from dcopext import DCOPClient, DCOPApp
 import sys
 
 # créer un nouveau client DCOP:
 client = DCOPClient()
 
 # connecter le client au serveur DCOP local:
 client.attach()
 
 # créer un Objet DCOP Application pour parler à Amarok:
 amarok = DCOPApp('amarok', client)
 
 # Appeler une fonction DCOP:
 ok, artist = amarok.player.artist()
 
 # Amarok 1.4 et la version modifiée de dcopext:
 ok, void = amarok.contextbrowser.showLyrics(
     '<lyric artist="Foo" title="Bar" page_url="http://foobar.org">text</lyric>')

Si ok == True, l'appel a abouti.

Entrées du Menu Contextuel

Pour modifier le menu contextuel de la liste de lecture en y insérant vos propres entrées, procédez en appelant simplement la fonction dcop :

dcop amarok script addCustomMenuItem "MonScript" "MonAction"

Il est également facile de retirer cette même entrée :

dcop amarok script removeCustomMenuItem "MonScript" "MonAction"

Vérifiez bien que votre script intercepte les notifications concernant cette entrée, car cliquer dessus n'aura aucun effet en l'état. Pour cela, consultez le paragraphe concernant la notification customMenuClicked ci-dessous.

Notifications

Amarok émet des notifications d'événement à tous les scripts en cours d'exécution en écrivant sur leur canal d'entrée standard stdin. Par conséquent, chaque script doit constamment surveiller stdin et réagir de manière adaptée en fonction des événements possibles. Bien entendu, chaque script est libre d'ignorer les notifications qui ne lui sont pas d'utilité.

Voici par exemple comment analyser et gérer certaines notifications en provenance d'Amarok en langage Ruby :

loop do
    message = gets().chomp() #Lire le message sur stdin
    command = /[A-Za-z]*/.match( message ).to_s()

    case command
        when "configure"
            msg  = '"This script does not have configuration options."'
            `dcop amarok playlist popupMessage "#{msg}"`

        when "fetchLyrics" #Aller chercher les paroles d'une chanson
            args = message.split()

            artiste = args[1]
            titre  = args[2]

            paroles = fetchLyrics( artiste, titre ) # fonction définie par le script
            `dcop amarok script showLyrics "#{paroles}"`
    end
end

Voici les diverses notifications envoyées par Amarok :

  • configure
Indique au script d'afficher sa boîte de configuration. Il incombe au script de s'occuper de stocker et de recharger les préférences de l'utilisateur. Au démarrage d'Amarok, le répertoire de travail est celui où toutes les données doivent être placées.
Astuce: Quand votre script requiert d'être configuré pour fonctionner normalement, vous devriez afficher automatiquement l'interface de configuration lors de la première utilisation.
  • engineStateChange: {empty|idle|paused|playing}
Prévient d'un changement dans l'état du moteur (vide, inactif, en pause, ou bien en lecture).
  • trackChange
Prévient du démarrage d'une nouvelle piste. Le script peut alors utiliser des fonctions DCOP pour obtenir plus d'informations concernant le morceau; comme les métadonnées et la longueur.
  • volumeChange: {nouveauVolume}
Prévient d'un changement du niveau du volume principal. Le volume est un entier compris entre 0 et 100 inclus.

Note: Cette notification a été ajoutée à partir d'Amarok 1.3.

  • customMenuClicked: {sousMenu nomEntrée chemins}
Lorsqu'une entrée personnalisée du menu contextuel de la liste de lecture est cliquée, spécifie une liste de chemins pour les pistes sélectionnées. Les informations sousMenu et nomEntrée sont aussi fournises, dans le cas où un script gère plusieurs entrées. L'insertion d'une nouvelle entrée dans le menu contextuel se fait en appelant la fonction DCOP dcop amarok script addCustomMenuItem( sousMenu nomEntrée ). L'opération inverse est dcop amarok script removeCustomMenuItem( sousMenu nomEntrée ).

Note: Cette notification a été ajoutée à partir d'Amarok 1.3.

  • fetchLyrics {artiste titre}
Indique une demande pour les paroles de la chanson en cours de lecture. Seuls les scripts de paroles reçoivent ces notifications. Pour déclarer un script parmi cette catégorie, il faut indiquer type=lyrics dans le Fichier Spec décrivant le script. cf. Le Fichier Spec ci-après.
Les chaînes artiste et titre sont en codage CGI, c'est-à-dire que les caractères spéciaux, tels que blancs, '?', '&', '=', '%' et autres, qu'on ne peut trouver dans une chaîne de requête CGI, sont représentés sous forme %xx, où xx correspond à la valeur du caractère en représentation hexadécimale. Il se peut également que les chaînes artiste et titre soient vides, ce qui signifie qu'il est possible qu'il n'y ait qu'une ou aucune chaîne fournie au script.
Quand des paroles ont été récupérées, elles doivent être transmises à Amarok par la méthode dcop amarok.contextbrowser.showLyrics(QString). Le paramètre passé à cette fonction doit respecter le format XML suivant :
 <lyric artist="nom_de_l'artiste" title="titre_de_la_chanson" page_url="http://url_fournisseur">
 texte texte texte
 
 texte texte texte
 ...
 </lyric>
Il est nécessaire d'échapper correctement tous les caractères ! Il est préférable d'utiliser une API XML spécialisée pour éviter de faire des erreurs, comme par exemple le module python xml.dom.
Si le script n'a pu trouver de résultat exact, mais seulement des suggestions, utilisez le format suivant :
 <suggestions page_url="http://url_fournisseur">
 <suggestion artist="nom_de_l'artiste" title="titre_de_la_chanson" url="http://url_des_paroles_suggérées" />
 ...
 </suggestions>
Quand aucun résultat n'a pu être trouvé :
<suggestions page_url="http://url_fournisseur">
</suggestions>
Si une erreur de communication avec le serveur a eu lieu avec le serveur de paroles, envoyez simplement une chaîne vide.

Note: Cette notification a été ajoutée à partir d'Amarok 1.4.

  • fetchLyricsByUrl {url}
Cette notification est envoyée lorsqu'une suggestion de paroles reçoit un clic. L'url est la même que celle de l'attribut url et est aussi codée CGI. En tout cas, pour des caractères comme 'ä'. Si vous n'avez pas besoin du codage spécial, vous pouvez le reconvertir.

Note: Cette notification a été ajoutée à partir d'Amarok 1.4.

  • transcode {url} {typeFichier}
Cette notification est envoyée quand une piste a besoin d'être codée dans un autre format afin de la transférer sur un lecteur portable. Seuls les scripts de type 'transcode' reçoivent ces notifications. Pour déclarer un script parmi cette catégorie, il faut indiquer type=transcode dans le Fichier Spec décrivant le script. cf. Le Fichier Spec ci-après.
Un tel script est alors dans l'obligation de répondre à la demande avec la méthode dcop amarok.mediabrowser.transcodingFinished(QString,QString), sinon le processus de transfert sera bloqué indéfiniment. Le premier paramètre est l'url passée au script pour le codage, le deuxième paramètre est l'url du fichier codé ou bien une chaîne vide, si une erreur est survenue.

Note: Cette notification a été ajoutée à partir d'Amarok 1.4.



Fin de la traduction


Accéder aux Données du Script

amaroK scripts are run in the directory ~/.kde/share/apps/amarok/scripts-data/ so any configuration files etc. should be written to that directory. But if for instance in the above example you needed to include somemodule.rb, for Ruby you would need to do something like the following:

SAVEDIR = Dir.pwd
Dir.chdir(File.dirname( File.expand_path(__FILE__) ))
require 'somemodule.rb'

SAVEDIR will contain the scripts-data directory for use when a file should be written out. The key with the above is the Ruby constant __FILE__ which returns the filename of the currently running script; other languages should have similar functionality.

In python you can simply import any modul placed in the same folder as the scriptfile. Python searches that folder, not the current one. But if you whant to get that folder to e.g. read some files packed to your script (like images etc.) you can use this:

 import os
 
 scriptfolder, scriptfile = os.path.split( __file__ )

Terminaison du Script

Before amaroK exits, or when the user stops a script with the ScriptManager, amaroK sends the SIGTERM signal to the script process. This signal can be caught in order to do cleanup work, like removing context menu entries, or saving data and configuration settings.

Here is an example in Ruby:

 def cleanup()
     puts( "Script was terminated." )
     `dcop amarok script removeCustomMenuItem #{scriptName} #{actionName}`
 end
 
 
 trap( "SIGTERM" ) { cleanup() }

Or in python:

 import signal
 
 def cleanup(signum, frame):
    print 'Script was terminated.'
    amarok.script.removeCustomMenuItem(scriptName, actionName)
 
 signal.signal(signale.SIGTERM, cleanup)

Empaquetage

amaroK's ScriptManager is able to install script packages that the user has downloaded from a web server. Packages are just normal tarballs (.tar), optionally compressed with bzip2 (.bz2). The file name extension must be .amarokscript.*, for example myscript.amarokscript.tar.bz2.

The tarball's content must be organized as follows:

myscript/
   README
   COPYING
   myscript.rb (executable)
   myscript.spec (amaroK 1.4 feature)
   somemodule.rb
   foo.png
   ...

NOTE: As of amarok 1.3.4 the README supports simple HTML tags, so that the document can be formatted nicely. We display this in a KAboutDialog widget. Also if the COPYING file is included a License tab is added to the KAboutDialog showing the contents of the COPYING file. The License tab does not support HTML syntax however.

Le Fichier Spec

(This is a new feature in amaroK 1.4)

A spec(ification) file can be added to the script folder to provide additional information about the script. It is basically a simple INI style text file, just like most UNIX configuration files. The following key/value properties are currently supported:

name = <name of the script>
type = {generic|lyrics|transcode}

When the spec file is missing or the "name" attribute is not specified, the script's filename will be used as the name. The spec file must have the same basename as the executable script file, but with the extension ".spec". Example: "myscript.spec".

For scripts of type lyrics and transcode, amaroK will take care that only one script of each type is running simultaneously.

Lyrics-plugins may have follwoing additional properties defined (note the [Lyrics]-section):

 [Lyrics]
 add_url = <http://url.to/add/lyrics/page/of/the/lyrics/service>
 site = <name of the lyrics-service>
 site_url = <http://url.of/the/lyrics/service>

Permissions

The main script must have executable (+x) permissions set, while additional modules which the script loads must not be executable. To preserve the file permissions in the tarball, you should use tar with the -p flag:

tar -cf myscript.amarokscript.tar -p myscript

Please note that amaroK will not be able to install the script if the permissions are not correctly set.

Distribution

When the package is finished, you can upload it to kde-apps.org, and add the link to the Wiki (Scripts). For the kde-apps entry you should use the amaroK Scripts category. Do not use this category if your script is not installable via amaroK's Script Manager.