Mon installation linux ********************** L'objectif est d'avoir le bureau linux le plus léger et optimal. .. warning:: si vous voulez utiliser picasa il ne faut pas être en 64bits .. note:: pour mon lenovo il faut rajouter des firmwares non free . Pour cela copier les deb sur une clé usb lors de l'installation. Vous pouvez trouver les firmwares sur http://pkgs.org/debian-wheezy/debian-backports-non-free-i386/firmware-realtek_0.41~bpo70+1_all.deb.html et http://pkgs.org/debian-wheezy/debian-backports-non-free-i386/firmware-brcm80211_0.41~bpo70+1_all.deb.html Après installation il faudra installer (de la source.list non-free firmware-linux-nonfree) et modifier la gestion de l'alimentation de la carte wifi (suivre tutorial https://wiki.debian.org/fr/wl) Pour cela nous allons installer **openbox**. Installation ------------ Nous réalisons d'abord une installation classique avec bureau(gnome) + ssh via l'utilisation de la fonction tasksel Puis nous réalisons les étapes suivantes - installation openbox .. code-block:: bash apt-get install openbox slim htop vim arandr gtk-theme-switch gtk2-engines obconf feh conky-all wbar lxappearance - lors de l'installation on choisit **slim** comme lanceur par défaut, on le vérifie par un .. code-block:: bash cat /etc/X11/default-display-manager - pour lancer par défaut openbox .. code-block:: bash echo "exec openbox-session" > /home/fraoustin/.xsession et voila nous avons maintenant un debian avec un bureau et un gestionnaire de connexion ultra-léger L'intérêt d'avoir installer gnome et d'avoir accès à des outils plus *friendly* pour le paramétrage réseau par exemple. le fichier **/etc/fstab**: .. code-block:: bash vi /etc/fstab .. code-block:: bash # ADD by FAO /dev/sdb1 /media/sdb1 ext3 defaults 0 0 0 192.168.1.17:/nfs/public/frederic /media/iomega nfs defaults 0 0 0 .. note:: l'utilisation du iomega peut nécessiter l'installation de nfs Configuration ------------- On va rajouter quelques éléments pour rendre le bureau opérationnel: - une gestion d'écran - un barre de lancement rapide (wbar) - un fond d'écran (feh) - un gestionnaire de donnée temps réel sur le bureau (conky) - faire que le lancement d'un terminal soit en plein écran Tout cela sera lancé au démarrage par openbox - on va maintenant régler le double écran .. code-block:: bash arandr enregistrer votre configuration dans $HOME/.screenlayout/myconfig.sh - on va paramétrer **wbar** (barre de lancement rapide et simple) .. code-block:: bash apt-get install wbar-config wbar-config exemple de contenu de wbar.dot .. code-block:: bash i: /usr/share/wbar/iconpack/wbar.osx/osxbarback.png c: wbar -bpress -above-desk -pos center -zoomf 1.3 -isize 72 -idist 4 -jumpf 1 -nanim 3 -balfa 25 t: /usr/share/wbar/iconpack/wbar.osx/font/16 i: /opt/firefox/browser/icons/mozicon128.png c: firefox t: firefox i: /usr/share/icons/gnome/32x32/apps/gnome-terminal.png c: x-terminal-emulator t: terminal i: /usr/share/icons/gnome/32x32/apps/libreoffice-writer.png c: libreoffice t: LibreOffice i: /home/fraoustin/.config/picasa3.png c: wine /home/fraoustin/.wine/drive_c/Program\ Files/Google/Picasa3/Picasa3.exe t: Picasa i: /opt/XnView/xnview.png c: xnview t: XnView i: /usr/share/vlc/lua/http/images/vlc-48.png c: vlc t: vlc i: /usr/share/icons/gnome/32x32/categories/gnome-system.png c: gnome-control-center t: Control Center - la configuration de conky ce fait via l'edition du fichier $HOME/.conkyrc .. code-block:: bash #Paramètres de la fenêtre own_window yes own_window_type desktop own_window_transparent yes #Paramètres de la police use_xft yes xftfont Courier new:size=9 #Paramètres de configuration update_interval 1 double_buffer yes alignment top_right ########################### ## Couleurs ########################### default_color ffffff default_shade_color 000000 default_outline_color 000000 color1 94c3e0 color2 dbe7ff TEXT #general ${color}${font pixelsize=12}${time %A %d %B %Y} ${color1}${font URW Chancery L:style=Medium Italic:pixelsize=34}${time %H:%M:%S}${font}${color} #ordinateur ${color2}${font URW Chancery L:style=Medium Italic:pixelsize=15}Ordinateur ${color2}${hr}${font} ${color}${execi 86400 lsb_release -si} : ${color1}${execi 86400 lsb_release -sr} ${execi 86400 lsb_release -sc} ${color}Linux : ${color1}$kernel $machine ${color}Uptime : ${color1}$uptime #systeme ${color2}${font URW Chancery L:style=Medium Italic:pixelsize=15}Informations Systeme ${color2}${hr}${font} ${color #656c75}${cpugraph 5e7b7b d8deeb} ${voffset -24}${alignc}${color1}${cpu cpu1}% ${color} RAM :${color1}$memperc% $mem /$memmax ${color #d8deeb}$membar ${color} Swap :${color1}$swapperc% $swap /$swapmax ${color #d8deeb}$swapbar ${color} Process :${color1}$processes ${alignr}${color}Running : ${color1}$running_processes #disque dur ${color2}${font URW Chancery L:style=Medium Italic:pixelsize=15}Disque Dur ${color2}${hr}${font} ${color}Racine : ${color1}${fs_used_perc /}% ${alignr}${fs_free /} ${color}${fs_bar 5,120 /} #reseau ${color2}${font URW Chancery L:style=Medium Italic:pixelsize=15}Reseau ${color2}${hr}${font} ${color} Down ${offset 45}${color1}${totaldown eth0} ${offset 8}${color}Up ${alignr}${color1}${totalup ethO} ${color #656c75}${downspeedgraph eth0 22,150 5e7b7b d8deeb} ${color #656c75}${upspeedgraph eth0 22,150 99c8e8 618094} ${offset 40}${voffset -21}${color1}${downspeedf eth0}k/s ${offset 190}${voffset -14}${color1}${upspeedf eth0}k/s #Divers ${color2}${font URW Chancery L:style=Medium Italic:pixelsize=15}Divers ${color2}${hr}${font} ${color #dbe7ff}Process PID %CPU %MEM${alignr} ${color #e09495} ${top name 1} ${top pid 1} ${alignc}${top cpu 1} ${top mem 1} ${color #e0d094} ${top name 2} ${top pid 2} ${alignc}${top cpu 2} ${top mem 2} ${color1} ${top name 3} ${top pid 3} ${alignc}${top cpu 3} ${top mem 3} ${color1} ${top name 4} ${top pid 4} ${alignc}${top cpu 4} ${top mem 4} ${color1} ${top name 5} ${top pid 5} ${alignc}${top cpu 5} ${top mem 5} - activation du clavier numérique .. code-block:: bash apt-get install numlockx numlockx on - on va maintenant créer le fichier **autostart** d'openbox .. code-block:: bash vi $HOME/.config/openbox/autostart il contient .. code-block:: bash $HOME/.screenlayout/myconfig.sh feh --bg-scale $HOME/Images/panther8ud.jpg wbar & conky numlockx on .. note:: penser à le rendre executable par un chmod +x pour configurer les menus d'openbox on lance .. code-block:: bash obmenu pour configurer l'apparence générale des fenêtres .. code-block:: bash obconf .. note:: le theme Onyx-black est plaisant pour configurer l'apparence générale du contenu des fenêtres .. code-block:: bash lxappearance .. note:: le theme industrial est plaisant Pour que le terminal soit en plein écran on peut ajouter à $HOME/.config/openbox/rc.xml les infos suivantes dans la parties applications .. code-block:: xml 0 0 true .. note:: on peut aussi jouer sur la taille de gnome-terminal par l'ajout dans menu.xml des paramètre --geometry longeurxlargeur Pour pouvoir déplacer les fenêtres via la touches Windows+Left on peut ajouter à $HOME/.config/openbox/rc.xml les infos suivantes dans la parties keyboard .. code-block:: xml le fichier .bashrc de root est composé ainsi .. code-block:: bash # You may uncomment the following lines if you want `ls' to be colorized: export LS_OPTIONS='--color=auto' eval "`dircolors`" alias ls='ls $LS_OPTIONS' alias ll='ls $LS_OPTIONS -lh' alias l='ls $LS_OPTIONS -lhA' # # Some more alias to avoid making mistakes: # alias rm='rm -i' # alias cp='cp -i' # alias mv='mv -i' #ADD by FAO alias vi='vim' PS1='\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$' export PYTHONSTARTUP=$HOME/.pythonrc export EDITOR=vim a été rajouté au fichier .bashrc de l'utilisateur .. code-block:: bash alias ll='ls $LS_OPTIONS -lh' alias l='ls $LS_OPTIONS -lhA' #ADD by FAO alias vi='vim' export PYTHONSTARTUP=$HOME/.pythonrc export EDITOR=vim il est possible d'ajouter une information proxy .. code-block:: bash export http_proxy=http://faoustin:password@proxy.myboite.fr:8080 export ftp_proxy=http://faoustin:password@proxy.myboite.fr:8080 .. note:: - on doit ajouter ces lignes dans le .bashrc si besoin - on utilise \ pour protéger certain caractère Python ------ le language ultime installation basique ~~~~~~~~~~~~~~~~~~~~ .. code-block:: bash apt-get install python-pip python-dev puis .. code-block:: bash pip install rst2pdf pip install bottle pip install sphinx pip install colorconsole pip install jinja2 installation de la dernière version python ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ il va falloir compiler python soit même .. code-block:: bash apt-get install build-essential libncursesw5-dev lib64readline-gplv2-dev libssl-dev libgdbm-dev libc6-dev libsqlite3-dev tk-dev puis on va télécharger les sources sur python.org http://www.python.org/download/releases et extraire l'archive .. code-block:: bash wget http://www.python.org/ftp/python/3.x/Python-3.x.tar.bz2 tar -xvf Python-3.xtar.bz2 cd Python-3.x maintenant on compille et on install python3 dans /opt/python3 .. code-block:: bash ./configure --prefix=/opt/python3 make sudo make install pour que les fichiers py utilise python3 penser à mettre .. code-block:: python #!/opt/python3/bin/python3 configuration de la console python ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ afin d'avoir une coloration et l'utilisation des tabulations dans une console python, nous créons le fichier $HOME/.pythonrc contenant .. code-block:: python try: import readline except ImportError #print "Module readline not available." pass else: # tabulation support import rlcompleter class TabCompleter(rlcompleter.Completer): """Completer that supports indenting""" def complete(self, text, state): if not text: return (' ', None)[state] else: return rlcompleter.Completer.complete(self, text, state) readline.set_completer(TabCompleter().complete) readline.parse_and_bind("tab: complete") import os, sys # Color Support class TermColors(dict): COLOR_TEMPLATES = ( ("Black" , "0;30"), ("Red" , "0;31"), ("Green" , "0;32"), ("Brown" , "0;33"), ("Blue" , "0;34"), ("Purple" , "0;35"), ("Cyan" , "0;36"), ("LightGray" , "0;37"), ("DarkGray" , "1;30"), ("LightRed" , "1;31"), ("LightGreen" , "1;32"), ("Yellow" , "1;33"), ("LightBlue" , "1;34"), ("LightPurple" , "1;35"), ("LightCyan" , "1;36"), ("White" , "1;37"), ("Normal" , "0"), ) NoColor = '' _base = '\001\033[%sm\002' def __init__(self): if os.environ.get('TERM') in ('xterm-color', 'xterm-256color', 'linux', 'screen', 'screen-256color', 'screen-bce', 'xterm'): self.update(dict([(k, self._base % v) for k,v in self.COLOR_TEMPLATES])) else: self.update(dict([(k, self.NoColor) for k,v in self.COLOR_TEMPLATES])) _c = TermColors() class Unbuffered: COLOR_TEMPLATES = { "default" : "\033[0m", # style "Bold" : "\033[1m", "Underline" : "\033[4m", "Blink" : "\033[5m", "Reverse" : "\033[7m", "Concealed" : "\033[8m", # couleur texte "Black" : "\033[30m", "Red" : "\033[31m", "Green" : "\033[32m", "Yellow" : "\033[33m", "Blue" : "\033[34m", "Magenta" : "\033[35m", "Cyan" : "\033[36m", "White" : "\033[37m", # couleur fond "on_black" : "\033[40m", "on_red" : "\033[41m", "on_green" : "\033[42m", "on_yellow" : "\033[43m", "on_blue" : "\033[44m", "on_magenta" : "\033[45m", "on_cyan" : "\033[46m", "on_white" : "\033[47m" } def __init__(self, stream, colorprint): if os.environ.get('TERM') in ('xterm-color', 'xterm-256color', 'linux', 'screen', 'screen-256color', 'screen-bce', 'xterm'): self.colorprint = self.COLOR_TEMPLATES[colorprint] else: self.colorprint = self.NoColor self.stream = stream self.line_buffering=False def write(self, data): self.stream.write(self.colorprint) self.stream.write(data) self.stream.write("\033[0m") self.stream.flush() def __getattr__(self, attr): return getattr(self.stream, attr) sys.stdout=Unbuffered(sys.stdout, 'Green') sys.stderr=Unbuffered(sys.stderr, 'Red') sys.stdin=Unbuffered(sys.stdin, 'Yellow') import sys # Enable Color Prompts sys.ps1 = '%s>>> %s' % (_c['Blue'], _c['Normal']) sys.ps2 = '%s... %s' % (_c['Red'], _c['Normal']) puis nous rajoutons dans notre $HOME/.bashrc .. code-block:: bash export PYTHONSTARTUP=$HOME/.pythonrc Configuration avancée --------------------- bash ~~~~ - modification du fichier .bashrc de l'utilisateur courant et de root (ajout d'un PS1 avec couleur rouge pour root) rsync ~~~~~ permet la sauvegarde sur un nas par exemple .. code-block:: bash apt-get install rsync exemple de scipt permettant une sauvegarde sur le serveur imoga (à monter sur /media/iomega) .. code-block:: bash #!/bin/bash # variable global SRC=/media/sdb1 DST=/media/iomega TEST_MOUNT="/media/iomega" BACKUP="NO" #YES OR NO BACKUP_DIR="$DST.backup/" OPTIONS="" echo "Backup start $(date)" # gestion backup JOUR=$(date +%Y-%m-%d) BACKUP_DIR_NOW="$BACKUP_DIR$JOUR/" if [ $BACKUP = "YES" ]; then if [ -d BACKUP_DIR_NOW ] then echo "$BACKUP_DIR_NOW existe deja !"; else echo "create dir $BACKUP_DIR_NOW" mkdir $BACKUP_DIR_NOW; fi OPTIONS="$OPTIONS --backup --backup-dir $BACKUP_DIR_NOW" fi # gestion point montage if [ ${#TEST_MOUNT} -gt 0 ]; then if grep -qs $TEST_MOUNT /proc/mounts; then echo $TEST_MOUNT "'s mounted" else echo "$TEST_MOUNT's not mounted" echo "load mount for $TEST_MOUNT" mount $TEST_MOUNT if grep -qs $TEST_MOUNT /proc/mounts; then echo "$TEST_MOUNT's mounted" else echo "$TEST_MOUNT's not available" /sbin/shutdown -h now exit fi fi fi # gestion rsync START=$(date +%s) echo "load rsync" rsync -av $SRC $DST $OPTIONS chmod -R a+w /media/iomega/sdb1/* chmod -R a+r /media/iomega/sdb1/* echo "end rsync" FINISH=$(date +%s) echo "total time: $(( ($FINISH-$START) / 60 )) minutes, $(( ($FINISH-$START) % 60 )) seconds" echo "Backup end $(date)" /sbin/shutdown -h now les prérequis de ce script: * avoir dans /etc/fstab une entrée pour le serveur iomega * avoir créé un fichier /var/log/backup.log avec des droits suffissants .. note:: il faudrait voir pour ajouter une procédure d'arrêt du NAS comme avec le DLINK Pour automatiser la tâche on peut la placer dans le crontab par exemple .. code-block:: bash contrab -e .. code-block:: bash 0 0 * * * /home/fraoustin/backup.sh >> /var/log/backup.log 2>&1 comme cela on a toutes les sorties vers backup.log mc ~~ permet d'avoir un explorateur en ligne de commande .. code-block:: bash apt-get install mc après avoir enregistré une première fois la configuration via le menu options de **mc** on peut aller modifier le fichier .config/mc/ini pour obtenir la transparence et un terme sombre .. code-block:: bash skin=dark [Colors] base_color=normal=,default:selected=black,lightgray:marked=yellow,default:markselect=,yellow:menu=,:menuhot=,:menusel=,:menuhotsel=,:dnormal=,:dfocus=,:dhotnormal=,:dhotfocus=,:input=,:reverse=,:executable=,default:directory=,default:link=,default:device=,default:special=,:core=,:helpnormal=,:helplink=,:helpslink=,:editnormal=,default: firefox ~~~~~~~ - modification du fichier /etc/apt/source.list ajout .. code-block:: bash deb http://http.debian.net/debian/ wheezy main contrib non-free - puis on lance .. code-block:: bash apt-get update - on télécharge firefox sur le site mozilla http://www.mozilla.org/fr/firefox/new/#download-fx - puis dans une console root .. code-block:: bash mkdir temp cd temp mv /home/fraoustin/Telechargement/firefox-29.0.tar.bz2 . tar -xvf firefox-29.0.tar.bz2 mkdir /opt/firefox29 cd firefox mv * /opt/firefox29 ln -s /opt/firefox29 /opt/firefox ln -s /opt/firefox/firefox-bin /usr/local/bin/firefox apt-get install flashplugin-nonfree on peut maintenant lancer firefox la mise à jour de flash est réalisée par l'action suivante .. code-block:: bash update-flashplugin-nonfree --install Chrome ~~~~~~ On peut télécharger les paquets debian sur google mais aussi ajouter comme source.list les paquets debian (plus simple pour les mises à jours) .. code-block:: bash wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - echo "deb https://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list apt-get install apt-transport-https apt-get update apt-get install google-chrome-stable Gthumb, totem, rhythmbox ~~~~~~~~~~~~~~~~~~~~~~~~~ gthumb est un gestionnaire de photo développé pour Gnome. il est simple et efficasse même si il lui manque des fonctionnalités comme les effets Holga. Totem, rhythmbox permettent de lire les vidéos et les fichiers audios .. code-blog:: bash apt-get install gthumb totem rhythmbox Il n'est parfois pas utile d'installer plus, en effet ces outils répondent à 90% des besoins classiques avec nautilus. Pour ajouter des radios dans rhythmbox, il faut editer le fichier .local/share/rhythmbox/rhythmdb.xml .. code-block:: xml France Inter Generic http://audio.scdn.arkena.com/11008/franceinter-midfi128.mp3 0 application/octet-stream France Info Generic http://audio.scdn.arkena.com/11006/franceinfo-midfi128.mp3 0 application/octet-stream France Musique Generic http://audio.scdn.arkena.com/11012/francemusique-midfi128.mp3 0 application/octet-stream France Culture Generic http://audio.scdn.arkena.com/11010/franceculture-midfi128.mp3 0 application/octet-stream TSF Jazz Generic http://broadcast.infomaniak.net:80/tsfjazz-high.mp3 0 application/octet-stream Picasa ~~~~~~ On va utilise Wine sur une architecture 64b l'installation de win nécessite quelques modifications .. code-block:: bash dpkg --print-architecture > amd64 dpkg --print-foreign-architectures > vide dpkg --add-architecture i386 dpkg --print-foreign-architectures > i386 apt-get update apt-get install wine ln -s /usr/lib/i386-linux-gnu/wine/bin/wineserver /usr/local/bin/wineserver on peut repartir sur une installation standard .. code-block:: bash su - root apt-get install wine cabextract winetricks libwine-cms:i386 exit rm -rf .wine ; WINEARCH=win32 wineboot ; wineserver -w winetricks ie8 wget http://dl.google.com/picasa/picasa39-setup.exe wine picasa39-setup.exe rm ./picasa39-setup.exe Google Sketchup ~~~~~~~~~~~~~~~ outil de dessin en 3D de chez google Il suffit de télécharger l'executable sur http://dl.google.com/sketchup/GoogleSketchUpWFR.exe et de le lancer avec wine Puis de le lancer .. code-block:: bash wine /home/fraoustin/.wine/drive_c/Program\ Files/Google/Google\ SketchUp\ 8/SketchUp.exe Si vous rencontrez l'erreur "SketchUp was unable to initialize OpenGL" , lancez cette commande dans un terminal: .. code-block:: bash wine regedit Dans l'Éditeur du registre, effectuez ces changements sous les clés : .. code-block:: bash HKEY_USERS/S-1-5-4/Software/Google/SketchUp8/GLConfig/Display modifier [HW_OK] à 1 .. note:: il existe un outil plus simple nommé sweethome3d qui existe dans les dépots debian XnView ~~~~~~ installation de XnvIewMP (on télécharge le deb depuis le site xnview) .. code-block:: bash su - root dpkg -i XnViewMP-linux-x64.deb Vlc ~~~ Afin d'obtenir la dernière version de vlc validé pour debian nous allons utiliser le backport - modification du fichier /etc/apt/source.list ajout .. code-block:: bash deb http://http.debian.net/debian/ wheezy-backports main - puis on lance .. code-block:: bash apt-get update apt-get -t wheezy-backports install vlc Libre Office ~~~~~~~~~~~~ Afin d'obtenir une des dernière version de libreoffice validé pour debian nous allons utiliser le backport - modification du fichier /etc/apt/source.list ajout .. code-block:: bash deb http://http.debian.net/debian/ wheezy-backports main - puis on lance .. code-block:: bash apt-get update apt-get -t wheezy-backports install libreoffice Conky avec méteo ~~~~~~~~~~~~~~~~ Exemple de conky optimisé avec info météo .. code-block:: bash ### Conky Display Settings # Update interval in seconds update_interval 2 # Create own window instead of using desktop (required in nautilus) own_window no #yes # Use pseudo transparency with own_window? own_window_transparent yes # Use double buffering (reduces flicker-maybe) double_buffer yes # If own_window is yes, these window manager hints may be used own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager # Force UTF8? note that UTF8 support required XFT override_utf8_locale yes # Utiliser Xft (polices lissées etc) use_xft yes xftalpha .1 override_utf8_locale yes # force UTF8 #police a utiliser : use_xft doit être a "yes" xftfont DejaVu Sans:size=10 # Tout le texte en majuscule uppercase no #position alignment tr # écart avec le bord x=gauche ou droit y= haut ou bas gap_x 15 gap_y 10 # je ne sais pas pourquoi # taille minimum_size 300 maximum_width 300 #desactiver cache image pour meteo imlib_cache_size 0 TEXT ${font DejaVu:style=BOLD:size=12}${time %a %d %b}$alignr${time %H:%M:%S} ${font DejaVu:style=Bold:size=12}Météo ${hr} ${font} #restaure la police par défaut ${texeci 60 ~/.config/weather/conkyweather.py -p "['location']['name']"} ${texeci 60 ~/.config/weather/conkyweather.py}°C ${texeci 60 ~/.config/weather/conkyweather.py -p "['current_conditions']['text']"} ${font DejaVu:style=Bold:size=12}Système ${hr} ${font}# restaure la police par défaut ${execi 86400 lsb_release -si} : ${execi 86400 lsb_release -sr} ${execi 86400 lsb_release -sc} Noyau : $sysname $kernel on $machine #/sys/class/hwmon/hwmon[n]/device/temp[n]_input ([n] est un chiffre) ${cpugraph cpu0 30,300 00ff00 ff0000 -t} ${voffset -32}${font DejaVu:style=Bold} CPU ${cpu}% ${font}$alignr${hwmon 1 temp 1}°C / ${hwmon 2 fan 1} RPM ${voffset 5}${font DejaVu:size=8}${top name 1} $alignr${offset -30}${top pid 1} $alignr${top cpu 1}% ${top name 2} $alignr${offset -30}${top pid 2} $alignr${top cpu 2}% ${top name 3} $alignr${offset -30}${top pid 3} $alignr${top cpu 3}% ${memgraph 30,300 00ff00 ff0000 -t} ${voffset -32}${font DejaVu:style=Bold} RAM $memperc% ${font}$alignr$mem / $memmax ${voffset 5}${font DejaVu:size=8}${top_mem name 1} $alignr${offset -30}${top_mem pid 1} $alignr${top_mem mem 1}% ${top_mem name 2} $alignr${offset -30}${top_mem pid 2} $alignr${top_mem mem 2}% ${top_mem name 3} $alignr${offset -30}${top_mem pid 3} $alignr${top_mem mem 3}% ${font DejaVu:style=Bold:size=12}Réseau ${hr} ${font DejaVu:size=8}eth0 $alignr ${addr eth0} wlan0 $alignr ${addr wlan0} ${downspeedgraph eth0 30,145 B1C5FF 002798 -t }$alignr${upspeedgraph eth0 30,145 FFC5B1 982700 -t} ${font DejaVu:style=Bold}${voffset -38}$alignc${offset -75}${downspeedf eth0} k/s ${font DejaVu:style=Bold}${voffset -19}$alignc${offset 85}${upspeedf eth0} k/s ${font DejaVu:size=8}${voffset -8}$alignc${offset -75}Download ${font DejaVu:size=8}${voffset -13}$alignc${offset 85}Upload ${font DejaVu:style=Bold:size=12}Données ${hr} ${font}# restaure la police par défaut ${voffset 5}${font}${color}/dev/sda $alignr${fs_bar 11,220 /} ${voffset -16}${offset 79}${font DejaVu:size=8}${color #000000} ${fs_used_perc /}% ${color}$alignr${fs_used /} / ${fs_size /} ${diskiograph_read /dev/sda 30,145 B1C5FF 002798 -t}$alignr${diskiograph_write /dev/sda 30,145 FFC5B1 982700 -t} ${font DejaVu:style=Bold}${voffset -38}$alignc${offset -75}${diskio_read /dev/sda} ${font DejaVu:style=Bold}${voffset -19}$alignc${offset 85}${diskio_write /dev/sda} ${font DejaVu:size=8}${voffset -8}$alignc${offset -75}Read ${font DejaVu:size=8}${voffset -13}$alignc${offset 85}Write ${voffset 5}${font}${color}/dev/sdb $alignr${fs_bar 11,220 /media/sdb1} ${voffset -16}${offset 79}${font DejaVu:size=8}${color #000000} ${fs_used_perc /media/sdb1}% ${color}$alignr${fs_used /media/sdb1} / ${fs_size /media/sdb1} ${diskiograph_read /dev/sdb 30,145 B1C5FF 002798 -t}$alignr${diskiograph_write /dev/sdb 30,145 FFC5B1 982700 -t} ${font DejaVu:style=Bold}${voffset -38}$alignc${offset -75}${diskio_read /dev/sdb} ${font DejaVu:style=Bold}${voffset -19}$alignc${offset 85}${diskio_write /dev/sdb} ${font DejaVu:size=8}${voffset -8}$alignc${offset -75}Read ${font DejaVu:size=8}${voffset -13}$alignc${offset 85}Write ${texeci 60 ~/.config/weather/conkyweather.py -p "['current_conditions']['icon']" -i ./.config/weather/now} ${image ~/.config/weather/now.png -p 240,55} .. note:: dans ce fichier .conkyrc la météo est mise à jour toutes les 60s ce qui peut être beaucoup Il faut ajouter le soft maison conkyweather .. code-block:: bash mkdir .config/weather ajouter le fichier .config/weather/conkyweather.py .. code-block:: python #!/usr/bin/python from optparse import OptionParser import sys import os, os.path import urllib2 import pywapi __version__ = '0.0.1' __author__ = 'Frederic Aoustin' __desc__ = 'get image weather' __prog__ = 'conkyweather' URL_ICON = "http://s.imwx.com/img/homepage/wx-icons-new/%s.png" URL_ICON_LARGE = "http://s.imwx.com/v.20131006.214956/img/wxicon/120/%s.png" def save_icon(dataf, name): output = open('%s.png' % name,'wb') output.write(dataf.read()) output.close() def get_icon(icon, name): if icon == '': icon = 1 save_icon(urllib2.urlopen(URL_ICON % icon), name) save_icon(urllib2.urlopen(URL_ICON_LARGE % icon), '%s_large' % name) if __name__ == '__main__': parser = OptionParser(version="%s %s" % (__prog__,__version__)) parser.description= __desc__ parser.epilog = __author__ parser.add_option("-d", "--debug", dest="debug", help="active trace in exception", default=False, action="store_true") parser.add_option("-l", "--location-id", dest="location", help ="location id of city for Weather.com ", default="FRXX1634", type="string") parser.add_option("-u", "--units", dest="units", help ="default metric", default="metric", type="string") parser.add_option("-i", "--icon", dest="icon", help ="type of element string/icon", default="", type="string") parser.add_option("-p", "--path", dest="path", help ="path of information", default="['current_conditions']['temperature']", type="string") (options, args) = parser.parse_args() try: weather = pywapi.get_weather_from_weather_com(options.location, options.units) if len(options.icon): get_icon(eval('weather%s' % options.path), options.icon) else: print(eval('weather%s' % options.path)) except Exception, e: if options.debug: print parser.error(e) parser.print_help() else: if not len(options.icons): print('?') sys.exit(1) ajouter le fichier .config/weather/pywapi.py .. code-block:: python #!/usr/bin/python # -*- coding: utf-8 -*- ### BEGIN LICENSE #Copyright (c) 2009 Eugene Kaznacheev #Copyright (c) 2013 Joshua Tasker #Permission is hereby granted, free of charge, to any person #obtaining a copy of this software and associated documentation #files (the "Software"), to deal in the Software without #restriction, including without limitation the rights to use, #copy, modify, merge, publish, distribute, sublicense, and/or sell #copies of the Software, and to permit persons to whom the #Software is furnished to do so, subject to the following #conditions: #The above copyright notice and this permission notice shall be #included in all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, #EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES #OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND #NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT #HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR #OTHER DEALINGS IN THE SOFTWARE. ### END LICENSE """ Fetches weather reports from Yahoo! Weather, Weather.com and NOAA """ __version__ = "0.3.8" try: # Python 3 imports from urllib.request import urlopen from urllib.parse import quote from urllib.parse import urlencode from urllib.error import URLError # needed for code to work on Python3 xrange = range unicode = str except ImportError: # Python 2 imports from urllib2 import urlopen from urllib import quote from urllib import urlencode from urllib2 import URLError import sys import re from math import pow from xml.dom import minidom import json try: from unidecode import unidecode except ImportError: pass GOOGLE_COUNTRIES_URL = 'http://www.google.com/ig/countries?output=xml&hl=%s' GOOGLE_CITIES_URL = 'http://www.google.com/ig/cities?output=xml&' + \ 'country=%s&hl=%s' YAHOO_WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss/%s_%s.xml' YAHOO_WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0' NOAA_WEATHER_URL = 'http://www.weather.gov/xml/current_obs/%s.xml' WEATHER_COM_URL = 'http://wxdata.weather.com/wxdata/weather/local/%s?' + \ 'unit=%s&dayf=5&cc=*' LOCID_SEARCH_URL = 'http://wxdata.weather.com/wxdata/search/search?where=%s' WOEID_SEARCH_URL = 'http://query.yahooapis.com/v1/public/yql' WOEID_QUERY_STRING = 'select line1, line2, line3, line4, ' + \ 'woeid from geo.placefinder where text="%s"' #WXUG_BASE_URL = 'http://api.wunderground.com/auto/wui/geo' #WXUG_FORECAST_URL = WXUG_BASE_URL + '/ForecastXML/index.xml?query=%s' #WXUG_CURRENT_URL = WXUG_BASE_URL + '/WXCurrentObXML/index.xml?query=%s' #WXUG_GEOLOOKUP_URL = WXUG_BASE_URL + '/GeoLookupXML/index.xml?query=%s' #WXUG_ALERTS_URL = WXUG_BASE_URL + '/AlertsXML/index.xml?query=%s' class WindUnits: """Class for available wind unit systems""" MPS = 1 MPH = 2 BEAUFORT = 3 KPH = 4 KNOTS = 5 def get_weather_from_weather_com(location_id, units = 'metric'): """Fetches weather report from Weather.com Parameters: location_id: A five digit US zip code or location ID. To find your location ID, use function get_loc_id_from_weather_com(). units: type of units. 'metric' for metric and 'imperial' for non-metric. Note that choosing metric units changes all the weather units to metric. For example, wind speed will be reported as kilometers per hour and barometric pressure as millibars. Returns: weather_data: a dictionary of weather data that exists in XML feed. """ location_id = quote(location_id) if units == 'metric': unit = 'm' elif units == 'imperial' or units == '': # for backwards compatibility unit = '' else: unit = 'm' # fallback to metric url = WEATHER_COM_URL % (location_id, unit) try: handler = urlopen(url) except URLError: return {'error': 'Could not connect to Weather.com'} if sys.version > '3': # Python 3 content_type = dict(handler.getheaders())['Content-Type'] else: # Python 2 content_type = handler.info().dict['content-type'] try: charset = re.search('charset\=(.*)', content_type).group(1) except AttributeError: charset = 'utf-8' if charset.lower() != 'utf-8': xml_response = handler.read().decode(charset).encode('utf-8') else: xml_response = handler.read() dom = minidom.parseString(xml_response) handler.close() try: weather_dom = dom.getElementsByTagName('weather')[0] except IndexError: error_data = {'error': dom.getElementsByTagName('error')[ 0].getElementsByTagName('err')[0].firstChild.data} dom.unlink() return error_data key_map = {'head':'units', 'ut':'temperature', 'ud':'distance', 'us':'speed', 'up':'pressure', 'ur':'rainfall', 'loc':'location', 'dnam':'name', 'lat':'lat', 'lon':'lon', 'cc':'current_conditions', 'lsup':'last_updated', 'obst':'station', 'tmp':'temperature', 'flik':'feels_like', 't':'text', 'icon':'icon', 'bar':'barometer', 'r':'reading', 'd':'direction', 'wind':'wind', 's':'speed', 'gust':'gust', 'hmid':'humidity', 'vis':'visibility', 'uv':'uv', 'i':'index', 'dewp':'dewpoint', 'moon':'moon_phase', 'hi':'high', 'low':'low', 'sunr':'sunrise', 'suns':'sunset', 'bt':'brief_text', 'ppcp':'chance_precip'} data_structure = {'head': ('ut', 'ud', 'us', 'up', 'ur'), 'loc': ('dnam', 'lat', 'lon'), 'cc': ('lsup', 'obst', 'tmp', 'flik', 't', 'icon', 'hmid', 'vis', 'dewp')} cc_structure = {'bar': ('r','d'), 'wind': ('s','gust','d','t'), 'uv': ('i','t'), 'moon': ('icon','t')} # sanity check, skip missing items try: for (tag, list_of_tags2) in data_structure.items(): for tag2 in list_of_tags2: if weather_dom.getElementsByTagName(tag)[0].childNodes.length == 0: data_structure[tag] = [] except IndexError: error_data = {'error': 'Error parsing Weather.com response. Full response: %s' % xml_response} return error_data try: weather_data = {} for (tag, list_of_tags2) in data_structure.items(): key = key_map[tag] weather_data[key] = {} for tag2 in list_of_tags2: key2 = key_map[tag2] try: weather_data[key][key2] = weather_dom.getElementsByTagName( tag)[0].getElementsByTagName(tag2)[0].firstChild.data except AttributeError: # current tag has empty value weather_data[key][key2] = unicode('') except IndexError: error_data = {'error': 'Error parsing Weather.com response. Full response: %s' % xml_response} return error_data if weather_dom.getElementsByTagName('cc')[0].childNodes.length > 0: cc_dom = weather_dom.getElementsByTagName('cc')[0] for (tag, list_of_tags2) in cc_structure.items(): key = key_map[tag] weather_data['current_conditions'][key] = {} for tag2 in list_of_tags2: key2 = key_map[tag2] try: weather_data['current_conditions'][key][key2] = cc_dom.getElementsByTagName( tag)[0].getElementsByTagName(tag2)[0].firstChild.data except AttributeError: # current tag has empty value weather_data['current_conditions'][key][key2] = unicode('') forecasts = [] if len(weather_dom.getElementsByTagName('dayf')) > 0: time_of_day_map = {'d':'day', 'n':'night'} for forecast in weather_dom.getElementsByTagName('dayf')[0].getElementsByTagName('day'): tmp_forecast = {} tmp_forecast['day_of_week'] = forecast.getAttribute('t') tmp_forecast['date'] = forecast.getAttribute('dt') for tag in ('hi', 'low', 'sunr', 'suns'): key = key_map[tag] try: tmp_forecast[key] = forecast.getElementsByTagName( tag)[0].firstChild.data except AttributeError: # if nighttime on current day, key 'hi' is empty tmp_forecast[key] = unicode('') for part in forecast.getElementsByTagName('part'): time_of_day = time_of_day_map[part.getAttribute('p')] tmp_forecast[time_of_day] = {} for tag2 in ('icon', 't', 'bt', 'ppcp', 'hmid'): key2 = key_map[tag2] try: tmp_forecast[time_of_day][ key2] = part.getElementsByTagName(tag2)[0].firstChild.data except AttributeError: # if nighttime on current day, keys 'icon' and 't' are empty tmp_forecast[time_of_day][key2] = unicode('') tmp_forecast[time_of_day]['wind'] = {} for tag2 in ('s', 'gust', 'd', 't'): key2 = key_map[tag2] tmp_forecast[time_of_day]['wind'][key2] = part.getElementsByTagName( 'wind')[0].getElementsByTagName(tag2)[0].firstChild.data forecasts.append(tmp_forecast) weather_data['forecasts'] = forecasts dom.unlink() return weather_data def get_weather_from_google(location_id, hl = ''): """Fetches weather report from Google. No longer functional, since Google discontinued their Weather API as of Sep 2012. Method retained for backwards compatibility. Returns: weather_data: a dictionary containing only the key 'error' """ weather_data = {'error': 'The Google Weather API has been ' + \ 'discontinued as of September 2012.'} return weather_data def get_countries_from_google(hl = ''): """Get list of countries in specified language from Google Parameters: hl: the language parameter (language code). Default value is empty string, in this case Google will use English. Returns: countries: a list of elements(all countries that exists in XML feed). Each element is a dictionary with 'name' and 'iso_code' keys. For example: [{'iso_code': 'US', 'name': 'USA'}, {'iso_code': 'FR', 'name': 'France'}] """ url = GOOGLE_COUNTRIES_URL % hl try: handler = urlopen(url) except URLError: return [{'error':'Could not connect to Google'}] if sys.version > '3': # Python 3 content_type = dict(handler.getheaders())['Content-Type'] else: # Python 2 content_type = handler.info().dict['content-type'] try: charset = re.search('charset\=(.*)', content_type).group(1) except AttributeError: charset = 'utf-8' if charset.lower() != 'utf-8': xml_response = handler.read().decode(charset).encode('utf-8') else: xml_response = handler.read() dom = minidom.parseString(xml_response) handler.close() countries = [] countries_dom = dom.getElementsByTagName('country') for country_dom in countries_dom: country = {} country['name'] = country_dom.getElementsByTagName( 'name')[0].getAttribute('data') country['iso_code'] = country_dom.getElementsByTagName( 'iso_code')[0].getAttribute('data') countries.append(country) dom.unlink() return countries def get_cities_from_google(country_code, hl = ''): """Get list of cities of necessary country in specified language from Google Parameters: country_code: code of the necessary country. For example 'de' or 'fr'. hl: the language parameter (language code). Default value is empty string, in this case Google will use English. Returns: cities: a list of elements(all cities that exists in XML feed). Each element is a dictionary with 'name', 'latitude_e6' and 'longitude_e6' keys. For example: [{'longitude_e6': '1750000', 'name': 'Bourges', 'latitude_e6': '47979999'}] """ url = GOOGLE_CITIES_URL % (country_code.lower(), hl) try: handler = urlopen(url) except URLError: return [{'error':'Could not connect to Google'}] if sys.version > '3': # Python 3 content_type = dict(handler.getheaders())['Content-Type'] else: # Python 2 content_type = handler.info().dict['content-type'] try: charset = re.search('charset\=(.*)', content_type).group(1) except AttributeError: charset = 'utf-8' if charset.lower() != 'utf-8': xml_response = handler.read().decode(charset).encode('utf-8') else: xml_response = handler.read() dom = minidom.parseString(xml_response) handler.close() cities = [] cities_dom = dom.getElementsByTagName('city') for city_dom in cities_dom: city = {} city['name'] = city_dom.getElementsByTagName( 'name')[0].getAttribute('data') city['latitude_e6'] = city_dom.getElementsByTagName( 'latitude_e6')[0].getAttribute('data') city['longitude_e6'] = city_dom.getElementsByTagName( 'longitude_e6')[0].getAttribute('data') cities.append(city) dom.unlink() return cities def get_weather_from_yahoo(location_id, units = 'metric'): """Fetches weather report from Yahoo! Weather Parameters: location_id: A five digit US zip code or location ID. To find your location ID, use function get_location_ids(). units: type of units. 'metric' for metric and 'imperial' for non-metric. Note that choosing metric units changes all the weather units to metric. For example, wind speed will be reported as kilometers per hour and barometric pressure as millibars. Returns: weather_data: a dictionary of weather data that exists in XML feed. See http://developer.yahoo.com/weather/#channel """ location_id = quote(location_id) if units == 'metric': unit = 'c' elif units == 'imperial' or units == '': # for backwards compatibility unit = 'f' else: unit = 'c' # fallback to metric url = YAHOO_WEATHER_URL % (location_id, unit) try: handler = urlopen(url) except URLError: return {'error': 'Could not connect to Yahoo! Weather'} if sys.version > '3': # Python 3 content_type = dict(handler.getheaders())['Content-Type'] else: # Python 2 content_type = handler.info().dict['content-type'] try: charset = re.search('charset\=(.*)', content_type).group(1) except AttributeError: charset = 'utf-8' if charset.lower() != 'utf-8': xml_response = handler.read().decode(charset).encode('utf-8') else: xml_response = handler.read() dom = minidom.parseString(xml_response) handler.close() weather_data = {} try: weather_data['title'] = dom.getElementsByTagName( 'title')[0].firstChild.data weather_data['link'] = dom.getElementsByTagName( 'link')[0].firstChild.data except IndexError: error_data = {'error': dom.getElementsByTagName('item')[ 0].getElementsByTagName('title')[0].firstChild.data} dom.unlink() return error_data ns_data_structure = { 'location': ('city', 'region', 'country'), 'units': ('temperature', 'distance', 'pressure', 'speed'), 'wind': ('chill', 'direction', 'speed'), 'atmosphere': ('humidity', 'visibility', 'pressure', 'rising'), 'astronomy': ('sunrise', 'sunset'), 'condition': ('text', 'code', 'temp', 'date') } for (tag, attrs) in ns_data_structure.items(): weather_data[tag] = xml_get_ns_yahoo_tag( dom, YAHOO_WEATHER_NS, tag, attrs ) weather_data['geo'] = {} try: weather_data['geo']['lat'] = dom.getElementsByTagName( 'geo:lat')[0].firstChild.data weather_data['geo']['long'] = dom.getElementsByTagName( 'geo:long')[0].firstChild.data except AttributeError: weather_data['geo']['lat'] = unicode() weather_data['geo']['long'] = unicode() weather_data['condition']['title'] = dom.getElementsByTagName( 'item')[0].getElementsByTagName('title')[0].firstChild.data weather_data['html_description'] = dom.getElementsByTagName( 'item')[0].getElementsByTagName('description')[0].firstChild.data forecasts = [] for forecast in dom.getElementsByTagNameNS(YAHOO_WEATHER_NS, 'forecast'): forecasts.append(xml_get_attrs(forecast,('day', 'date', 'low', 'high', 'text', 'code'))) weather_data['forecasts'] = forecasts dom.unlink() return weather_data def get_everything_from_yahoo(country_code, cities): """Get all weather data from yahoo for a specific country. Parameters: country_code: A four letter code of the necessary country. For example 'GMXX' or 'FRXX'. cities: The maximum number of cities for which to get data. Returns: weather_reports: A dictionary containing weather data for each city. """ city_codes = yield_all_country_city_codes_yahoo(country_code, cities) weather_reports = {} for city_c in city_codes: weather_data = get_weather_from_yahoo(city_c) if ('error' in weather_data): return weather_data city = weather_data['location']['city'] weather_reports[city] = weather_data return weather_reports def yield_all_country_city_codes_yahoo(country_code, cities): """Yield all cities codes for a specific country. Parameters: country_code: A four letter code of the necessary country. For example 'GMXX' or 'FRXX'. cities: The maximum number of cities to yield. Returns: country_city_codes: A generator containing the city codes. """ # cities stands for the number of available cities for i in range(1, cities + 1): yield ''.join([country_code, (4 - len(str(i))) * '0', str(i)]) def get_weather_from_noaa(station_id): """Fetches weather report from NOAA: National Oceanic and Atmospheric Administration (United States) Parameter: station_id: the ID of the weather station near the desired location To find your station ID, perform the following steps: 1. Open this URL: http://www.weather.gov/xml/current_obs/seek.php?state=az&Find=Find 2. Select the necessary state state. Click 'Find'. 3. Find the necessary station in the 'Observation Location' column. 4. The station ID is in the URL for the weather page for that station. For example if the weather page is http://weather.noaa.gov/weather/current/KPEO.html -- the station ID is KPEO. Another way to get the station ID: use the 'Weather.location2station' function of this library: http://code.google.com/p/python-weather/ Returns: weather_data: a dictionary of weather data that exists in XML feed. ( useful icons: http://www.weather.gov/xml/current_obs/weather.php ) """ station_id = quote(station_id) url = NOAA_WEATHER_URL % (station_id) try: handler = urlopen(url) except URLError: return {'error': 'Could not connect to NOAA'} if sys.version > '3': # Python 3 content_type = dict(handler.getheaders())['Content-Type'] else: # Python 2 content_type = handler.info().dict['content-type'] try: charset = re.search('charset\=(.*)', content_type).group(1) except AttributeError: charset = 'utf-8' if charset.lower() != 'utf-8': xml_response = handler.read().decode(charset).encode('utf-8') else: xml_response = handler.read() dom = minidom.parseString(xml_response) handler.close() data_structure = ('suggested_pickup', 'suggested_pickup_period', 'location', 'station_id', 'latitude', 'longitude', 'observation_time', 'observation_time_rfc822', 'weather', 'temperature_string', 'temp_f', 'temp_c', 'relative_humidity', 'wind_string', 'wind_dir', 'wind_degrees', 'wind_mph', 'wind_gust_mph', 'pressure_string', 'pressure_mb', 'pressure_in', 'dewpoint_string', 'dewpoint_f', 'dewpoint_c', 'heat_index_string', 'heat_index_f', 'heat_index_c', 'windchill_string', 'windchill_f', 'windchill_c', 'icon_url_base', 'icon_url_name', 'two_day_history_url', 'ob_url' ) weather_data = {} current_observation = dom.getElementsByTagName('current_observation')[0] for tag in data_structure: try: weather_data[tag] = current_observation.getElementsByTagName( tag)[0].firstChild.data except IndexError: pass dom.unlink() return weather_data def xml_get_ns_yahoo_tag(dom, ns, tag, attrs): """Parses the necessary tag and returns the dictionary with values Parameters: dom: DOM ns: namespace tag: necessary tag attrs: tuple of attributes Returns: a dictionary of elements """ element = dom.getElementsByTagNameNS(ns, tag)[0] return xml_get_attrs(element,attrs) def xml_get_attrs(xml_element, attrs): """Returns the list of necessary attributes Parameters: element: xml element attrs: tuple of attributes Returns: a dictionary of elements """ result = {} for attr in attrs: result[attr] = xml_element.getAttribute(attr) return result def wind_direction(degrees): """ Convert wind degrees to direction """ try: degrees = int(degrees) except ValueError: return '' if degrees < 23 or degrees >= 338: return 'N' elif degrees < 68: return 'NE' elif degrees < 113: return 'E' elif degrees < 158: return 'SE' elif degrees < 203: return 'S' elif degrees < 248: return 'SW' elif degrees < 293: return 'W' elif degrees < 338: return 'NW' def wind_beaufort_scale(value, wind_units = WindUnits.KPH): """Convert wind speed value to Beaufort number (0-12) The Beaufort wind force scale is an empirical measure that relates wind speed to observed conditions at sea or on land. Parameters: value: wind speed value to convert wind_units: unit system of value, defaults to km/h Returns: a string containing the Beaufort number from 0 to 12 """ if wind_units == WindUnits.BEAUFORT: return str(value) try: value = float(value) except ValueError: return '' if value < 0.0: return '' if wind_units == WindUnits.KPH: if value < 1: # Calm return '0' elif value <= 5.5: # Light air return '1' elif value <= 11: # Light breeze return '2' elif value <= 19: # Gentle breeze return '3' elif value <= 28: # Moderate breeze return '4' elif value <= 38: # Fresh breeze return '5' elif value <= 49: # Strong breeze return '6' elif value <= 61: # High wind, moderate gale, near gale return '7' elif value <= 74: # Gale, fresh gale return '8' elif value <= 88: # Strong gale return '9' elif value <= 102: # Storm, whole gale return '10' elif value <= 117: # Violent storm return '11' else: # Hurricane return '12' if wind_units == WindUnits.MPH: if value < 1: return '0' elif value <= 3: return '1' elif value <= 7: return '2' elif value <= 12: return '3' elif value <= 17: return '4' elif value <= 24: return '5' elif value <= 30: return '6' elif value <= 38: return '7' elif value <= 46: return '8' elif value <= 54: return '9' elif value <= 63: return '10' elif value <= 73: return '11' else: return '12' if wind_units == WindUnits.MPS: if value < 0.3: return '0' elif value <= 1.5: return '1' elif value <= 3.4: return '2' elif value <= 5.4: return '3' elif value <= 7.9: return '4' elif value <= 10.7: return '5' elif value <= 13.8: return '6' elif value <= 17.1: return '7' elif value <= 20.7: return '8' elif value <= 24.4: return '9' elif value <= 28.4: return '10' elif value <= 32.6: return '11' else: return '12' if wind_units == WindUnits.KNOTS: if value < 1: return '0' if value <= 3: return '1' if value <= 6: return '2' if value <= 10: return '3' if value <= 16: return '4' if value <= 21: return '5' if value <= 27: return '6' if value <= 33: return '7' if value <= 40: return '8' if value <= 47: return '9' if value <= 55: return '10' if value <= 63: return '11' else: return '12' def get_wind_direction(degrees): """ Same as wind_direction """ return wind_direction(degrees) def getText(nodelist): rc = "" for node in nodelist: if node.nodeType == node.TEXT_NODE: rc = rc + node.data return rc def get_location_ids(search_string): """Get location IDs for place names matching a specified string. Same as get_loc_id_from_weather_com() but different return format. Parameters: search_string: Plaintext string to match to available place names. For example, a search for 'Los Angeles' will return matches for the city of that name in California, Chile, Cuba, Nicaragua, etc as well as 'East Los Angeles, CA', 'Lake Los Angeles, CA', etc. Returns: location_ids: A dictionary containing place names keyed to location ID """ loc_id_data = get_loc_id_from_weather_com(search_string) if 'error' in loc_id_data: return loc_id_data location_ids = {} for i in xrange(loc_id_data['count']): location_ids[loc_id_data[i][0]] = loc_id_data[i][1] return location_ids def get_loc_id_from_weather_com(search_string): """Get location IDs for place names matching a specified string. Same as get_location_ids() but different return format. Parameters: search_string: Plaintext string to match to available place names. For example, a search for 'Los Angeles' will return matches for the city of that name in California, Chile, Cuba, Nicaragua, etc as well as 'East Los Angeles, CA', 'Lake Los Angeles, CA', etc. Returns: loc_id_data: A dictionary of tuples in the following format: {'count': 2, 0: (LOCID1, Placename1), 1: (LOCID2, Placename2)} """ # Weather.com stores place names as ascii-only, so convert if possible try: # search_string = unidecode(search_string.encode('utf-8')) search_string = unidecode(search_string) except NameError: pass url = LOCID_SEARCH_URL % quote(search_string) try: handler = urlopen(url) except URLError: return {'error': 'Could not connect to server'} if sys.version > '3': # Python 3 content_type = dict(handler.getheaders())['Content-Type'] else: # Python 2 content_type = handler.info().dict['content-type'] try: charset = re.search('charset\=(.*)', content_type).group(1) except AttributeError: charset = 'utf-8' if charset.lower() != 'utf-8': xml_response = handler.read().decode(charset).encode('utf-8') else: xml_response = handler.read() dom = minidom.parseString(xml_response) handler.close() loc_id_data = {} try: num_locs = 0 for loc in dom.getElementsByTagName('search')[0].getElementsByTagName('loc'): loc_id = loc.getAttribute('id') # loc id place_name = loc.firstChild.data # place name loc_id_data[num_locs] = (loc_id, place_name) num_locs += 1 loc_id_data['count'] = num_locs except IndexError: error_data = {'error': 'No matching Location IDs found'} return error_data finally: dom.unlink() return loc_id_data def get_where_on_earth_ids(search_string): """Get Yahoo 'Where On Earth' ID for the place names that best match the specified string. Same as get_woeid_from_yahoo() but different return format. Parameters: search_string: Plaintext string to match to available place names. Place can be a city, country, province, airport code, etc. Yahoo returns the 'Where On Earth' ID (WOEID) for the place name(s) that is the best match to the full string. For example, 'Paris' will match 'Paris, France', 'Deutschland' will match 'Germany', 'Ontario' will match 'Ontario, Canada', 'SFO' will match 'San Francisco International Airport', etc. Returns: where_on_earth_ids: A dictionary containing place names keyed to WOEID. """ woeid_data = get_woeid_from_yahoo(search_string) if 'error' in woeid_data: return woeid_data where_on_earth_ids = {} for i in xrange(woeid_data['count']): where_on_earth_ids[woeid_data[i][0]] = woeid_data[i][1] return where_on_earth_ids def get_woeid_from_yahoo(search_string): """Get Yahoo WOEID for the place names that best match the specified string. Same as get_where_on_earth_ids() but different return format. Parameters: search_string: Plaintext string to match to available place names. Place can be a city, country, province, airport code, etc. Yahoo returns the WOEID for the place name(s) that is the best match to the full string. For example, 'Paris' will match 'Paris, France', 'Deutschland' will match 'Germany', 'Ontario' will match 'Ontario, Canada', 'SFO' will match 'San Francisco International Airport', etc. Returns: woeid_data: A dictionary of tuples in the following format: {'count': 2, 0: (WOEID1, Placename1), 1: (WOEID2, Placename2)} """ ## This uses Yahoo's YQL tables to directly query Yahoo's database, e.g. ## http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.placefinder%20where%20text%3D%22New%20York%22 if sys.version > '3': # Python 3 encoded_string = search_string else: # Python 2 encoded_string = search_string.encode('utf-8') params = {'q': WOEID_QUERY_STRING % encoded_string, 'format': 'json'} url = '?'.join((WOEID_SEARCH_URL, urlencode(params))) try: handler = urlopen(url) except URLError: return {'error': 'Could not connect to server'} if sys.version > '3': # Python 3 content_type = dict(handler.getheaders())['Content-Type'] else: # Python 2 content_type = handler.info().dict['content-type'] try: charset = re.search('charset\=(.*)', content_type).group(1) except AttributeError: charset = 'utf-8' if charset.lower() != 'utf-8': json_response = handler.read().decode(charset).encode('utf-8') else: json_response = handler.read() handler.close() yahoo_woeid_result = json.loads(json_response) try: result = yahoo_woeid_result['query']['results']['Result'] except KeyError: # On error, returned JSON evals to dictionary with one key, 'error' return yahoo_woeid_result except TypeError: return {'error': 'No matching place names found'} woeid_data = {} woeid_data['count'] = yahoo_woeid_result['query']['count'] for i in xrange(yahoo_woeid_result['query']['count']): try: place_data = result[i] except KeyError: place_data = result name_lines = [place_data[tag] for tag in ['line1','line2','line3','line4'] if place_data[tag] is not None] place_name = ', '.join(name_lines) woeid_data[i] = (place_data['woeid'], place_name) return woeid_data def heat_index(temperature, humidity, units = 'metric'): """Calculate Heat Index for the specified temperature and humidity The formula below approximates the heat index in degrees Fahrenheit, to within ±1.3 °F. It is the result of a multivariate fit (temperature equal to or greater than 80°F and relative humidity equal to or greater than 40%) to a model of the human body. Heat Index = c_1 + (c_2 * T) + (c_3 * R) + (c_4 * T * R) + (c_5 * T^2) + (c_6 * R^2) + (c_7 * T^2 * R) + (c_8 * T * R^2) + (c_9 * T^2 * R^2) where: T = ambient dry-bulb temperature (in degrees Fahrenheit) R = relative humidity (percentage value between 0 and 100) Parameters: temperature: air temperature in specified units humidity: relative humidity (a percentage) at specified air temperature units: type of units. 'metric' for metric and 'imperial' for non-metric. Returns: heat_index: a numerical value representing the heat index in the temperature scale of the specified unit system. Returns None if the specified temperature is less than 80°F or the specified relative humidity is less than 40%. """ # fallback to metric if units != 'imperial' and units != '' and units != 'metric': units = 'metric' R = float(humidity) if units == 'imperial' or units == '': # for backwards compatibility T = float(temperature) elif units == 'metric': # Heat Index is calculated in F T = (float(temperature) * 9.0/5.0) + 32.0 # Heat Index is only valid for temp >= 80°F and humidity >= 40%) if (R < 40.0 or T < 80.0): return None Rsquared = pow(R, 2.0) Tsquared = pow(T, 2.0) # coefficients for calculation c = [None, -42.379, 2.04901523, 10.14333127, -0.22475541, -6.83783 * pow(10.0,-3.0), -5.481717 * pow(10.0,-2.0), 1.22874 * pow(10.0,-3.0), 8.5282 * pow(10.0,-4.0), -1.99 * pow(10.0,-6.0)] heat_index = ( c[1] + (c[2]* T) + (c[3]* R) + (c[4]* T * R) + (c[5]* Tsquared) + (c[6]* Rsquared) + (c[7]* Tsquared * R) + (c[8]* T * Rsquared) + (c[9]* Tsquared * Rsquared) ) # round to one decimal place if units == 'metric': return round(((heat_index - 32.0) * 5.0/9.0), 1) else: return round(heat_index, 1) et rendre le programme executable .. code-block:: bash chmod +x .config/weather/conkyweather.py Vim ~~~ .. code-block:: bash apt-get install vim puis mettre dans son HOME le fichier .vimrc .. code-block:: bash " general syn enable set number set autoindent set expandtab set nopaste set shiftwidth=4 set softtabstop=4 set tabstop=4 set visualbell t_vb= syntax on set ai "set hlsearch set nohlsearch set nobackup set nowritebackup " encoding set encoding=utf-8 set fileencoding=utf-8 " map copy/paste print "map :Exp map ggVG imap ggVG map y map "+x map p map "+gP imap "+gP map :w imap :w noremap :ha map u map r "remap autocomplete inoremap function! Load() if &filetype == "python" :! start cmd /k python "%" endif if &filetype == "dosbatch" :! start cmd /k "%" endif endfunction map :call Load() function! LoadDebug() if &filetype == "python" :! python -m pdb "%" endif endfunction map :call LoadDebug() function! LoadHelp() echo "Standard" echo "--------" echo "C-o :tabnew:Exp Open C-s :w Save" echo "C-n :tabnew New C-p :ha Print" echo "C-c \"+y Copy C-v \"+gP Paste" echo "C-x \"+x Cut C-a ggVG Select All" echo "C-z u Undo C-r r Redo" echo " :! cmd Send cmd C-x C-n Complete Word" echo " C-Space Complete Word" echo "C-g End File :q Quit Vi" echo " " echo "Tabulation" echo "----------" echo "C-o :tabnew:e . Open C-n :tabnew New" echo "C-Right :tabnext New Tab C-Left :tabprevious Previous Tab" echo " " echo "Other Shortcut" echo "--------------" echo "F2 Terminal F5 :e!% Reload" echo "F8 Load F6 Debugger" echo "F1 Help :shell Open shell in VI" echo "F4 Format" echo " " echo "Buffer" echo "------" echo " :ls Liste Buffer :b? Get Buffer ?" echo " :e# Next Buffer :bd del Buffer" echo "" echo "Windows" echo "-------" echo " :o Open in new Win :split New Win" echo " :vsplit new vertical C-w-w Change Win" echo "" echo "Search ,Indent..." echo "-----------------" echo " /???? Find ???? :%s/???/XXX/g replace ??? by XXX" echo " /\\c??? Find ???? no case" echo " :%!grep -iv ??? filter line with ??? :g/???/d delete all line with ???" echo " :sort sort rows :retab convert tab to spaces" echo " " echo " :> indent :< de-indent" echo " C-q C-d I-- Esc insert -- on all line" echo " " echo "Compare" echo "-------" echo " :vert diffsplit file2 comparaison with file2" echo " " echo "Syntax" echo "------" echo " :set syntax=??? active ??? syntax :syntax off turn off syntax" endfunction map :call LoadHelp() "fonction tab :command New tabnew noremap :tabnew noremap :tabnew noremap :tabnew:Exp noremap :tabnext noremap :tabprevious map v map v noremap v noremap v " open terminal function! Term() :!start x-terminal-emulator cd %:p:h endfunction :command TERM call Term() map :call Term() " format sql function! Format(synt) execute ":%!prettycode -s ".a:synt endfunction :command FORMAT call Format(b:current_syntax) map ggVG"+x:call Format(b:current_syntax) imap ggVG"+x:call Format(b:current_syntax) map :e!% set ruler color mycolor et ajouter dans le dossier color de vim, le fichier **mycolor.vim** .. code-block:: bash " local syntax file - set colors on a per-machine basis: " vim: tw=0 ts=4 sw=4 " Vim color file " inpired by: Ron Aaron hi clear if exists("syntax_on") syntax reset endif let g:colors_name = "mycolor" hi Normal ctermfg=White guifg=cyan guibg=black hi Comment term=bold ctermfg=DarkGrey guifg=#80a0ff hi Constant term=underline ctermfg=Magenta guifg=Magenta hi Character term=underline ctermfg=Green guifg=Green hi Special term=bold ctermfg=Magenta guifg=Red hi Identifier term=underline ctermfg=Cyan guifg=#40ffff cterm=bold hi Statement term=bold ctermfg=Yellow guifg=#aa4444 gui=bold hi PreProc term=underline ctermfg=Red guifg=#ff80ff hi Type term=underline ctermfg=LightGreen guifg=#60ff60 gui=bold hi Function term=bold ctermfg=cyan guifg=cyan hi Repeat term=underline ctermfg=Red guifg=white hi Operator ctermfg=Red guifg=Red hi Ignore ctermfg=black guifg=bg hi Error term=reverse ctermfg=White guibg=Red guifg=White hi Todo term=standout ctermfg=Black guifg=Blue guibg=Yellow " hi LineNr cterm=italic hi Excep ctermfg=brown " Common groups that link to default highlighting. " You can specify other highlighting easily. hi link String Character hi link Character Character hi link Number Constant hi link Boolean Constant hi link Float Number hi link Conditional Repeat hi link Label Statement hi link Keyword Statement hi link Exception Excep hi link Include PreProc hi link Define PreProc hi link Macro PreProc hi link PreCondit PreProc hi link StorageClass Type hi link Structure Type hi link Typedef Type hi link Tag Special hi link SpecialChar Special hi link Delimiter Special hi link SpecialComment Special hi link Debug Special Grisbi ~~~~~~ .. code-block:: bash apt-get install grisbi modification de wbar .. code-block:: bash vi .config/.wbar/dort.wbar .. code-block:: bash i: /usr/share/pixmaps/grisbi/grisbi.png c: grisbi t: Grisbi Music On Console ~~~~~~~~~~~~~~~~ on peut utiliser **moc** comme serveur de musique .. code-block:: bash apt-get install moc mocp pour rendre moc transparent il faut éditer .moc/config .. code-block:: bash XTermTheme = transparent-background MusicDir = "/home/fraoustin/Musique" Sort = FileName ReadTags = no ajout dans .bashrc d'un nouvel alias .. code-block:: bash alias music="mocp" pour la radio faire des fichiers m3u contenant par exemple .. code-block:: bash #EXTM3U #EXTINF:0,franceinter-32k.mp3 http://audio.scdn.arkena.com/11008/franceinter-midfi128.mp3 .. note:: pour avoir une liste complète des radios: http://doc.ubuntu-fr.org/liste_radio_france on peut gérer le volume de sortie via .. code-block:: bash alsamixer Quelques raccourcis utiles : En tapant "h" on obtient une liste des commandes disponible. (Malheureusement incomplète...) * mocp --> Lancer Moc * entrée --> demarrer la lecture * s --> stopper la lecture * n --> prochain morceau * b --> morceau précèdent * p ou espace --> pause * R --> repèter le morceau * o --> jouer un fichier sur le net * q --> fermer l'interface (mais le serveur tourne et continue à jouer) * mocp -x --> quitter le serveur en ligne de commande (sans le relancer dans la console) * Q --> Quitter tout Gestion des listes de lecture : * TAB --> permet de passer de la liste des répertoires à la playlist (et inversement) * a --> ajouter un morceau * A --> ajouter un répertoire * Ctrl+u --> ajouter une url * V --> sauver la liste script pour lancer un fichier sur le serveur .. code-block:: bash mocp -S mopc -c mopc -a file.m3u mopc -p Montage automatique des usb ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Même si on peut réaliser manuellement le montage de clé usb via .. code-block:: bash lsusb fdisk -l mount /dev/??? /media/!!! Il est possible d'installer un module qui va se charger de cela .. code-block:: bash apt-get install usbmount hal pmount Editez le fichier etc/usbmount/usbmount.conf .. code-block:: bash FS_MOUNTOPTIONS="-fstype=vfat,gid=floppy,dmask=0007,fmask=0117" .. warning:: afin d'augmenter la vitesse d'écriture il peut être utile de ne laisser dans les paramètres MOUNTOPTIONS que sync (sans noatime, ...) voir rien pour aller plus vite puis lancer .. code-block:: bash mount -a -o remount .. note:: parfois il faut mieux monter à la main les clés usb pour notamenent des problèmes de vitesses pour désactiver usbmount il suffit de placer dans /etc/usbmount/usbmount.conf la valeur 0 à la variable ENABLED gmrun ~~~~~ gmrun est un lanceur d'application gtk à la mode Windows+r .. code-block:: bash apt-get install gmrun gmrun On peut rajouter le raccourcit Windows+r dans le fichier .config/openbox/rc.xml .. code-block:: xml gmrun Roxterm ~~~~~~~ il faudrait voir le terminal roxterm (a voir car gère transparence) .. code-block:: bash su - root apt-get install roxterm Keepass2 ~~~~~~~~ .. code-block:: bash apt-get install keepass2 Virtualbox ~~~~~~~~~~ J'utilise la version non-ose disponible sur les dépôts de virtualbox .. code-block:: bash vi /etc/apt/sources.list.d/virtualbox.list Ajouter le contenu dans ce fichier .. code-block:: bash deb http://download.virtualbox.org/virtualbox/debian wheezy contrib puis lancer les commandes suivantes : .. code-block:: bash wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add - apt-get update apt-get install virtualbox-4.2 Grive ~~~~~ outil pour synchroniser un dossier avec google drive .. code-block:: bash apt-get install git cmake build-essential libgcrypt11-dev libjson0-dev apt-get install libcurl4-openssl-dev apt-get install libexpat1-dev libboost1.49-all-dev libboost-filesystem1.49-dev libboost-program-options-dev binutils-dev libyajl-dev apt-get install libqt4-dev qt4-dev-tools wget https://github.com/Grive/grive/archive/master.zip unzip master.zip cd grive-master cmake . make mkdir ~/googleDrive cp ~/grive/grive-master/grive ~/googleDrive cd ~/googleDrive ./grive -a #copier / coller url pour obtenir code #for test ./grive --dry-run #run ./grive .. note:: si vous avez installer vlc via backport on peut avoir un soucis avec libcurl4-openssl-dev dans ce cas faire un .. code-block:: bash apt-get install libp11-kit0=0.12-3 .. note:: si soucis voir https://github.com/Grive/grive/issues/168 Mutt ~~~~ utilitaire ligne de commande pour lire ces mails .. code-block:: bash apt-get install mutt mutt-patched il est possible de gérer les relations fichier/application via le fichier /etc/mailcap Screen ~~~~~~ utilitaire permettant de gérer plusieurs consoles en une seule et de pouvoirrécupérer un travail en cours sur un autre terminal .. code-block:: bash apt-get install screen On peut ajouter des alias au niveau du .bashrc .. code-block:: bash alias screenl="screen -list" alias screena="screen -S" alias screenr="srcreen -r" alias screend="screen -d" Calcurse ~~~~~~~~ Il s'agit d'un agenda en ligne de commande ... très utile même si aujourd'hui il n'y a pas de solution pour synchroniser avec google une méthode simple d'installation .. code-block:: bash apt-get install calcurse Mais cette méthode entraine une mauvaise gestion des accents. Pour régler ce problème il faut compiler et installer depuis les sources calcurse .. code-block:: bash wget http://calcurse.org/files/calcurse-3.1.4.tar.gz tar -xvf calcurse-3.1.4.tar.gz cd calcurse ./configure make make install Vous pouvez configurer calcurse via calcurse lui même ou via ~/.calcurse/conf (comme la séparation centrale, le premier jour de la semaine, ...) Apache ~~~~~~ .. code-block:: bash apt-get install apache2 on peut alors modifier /etc/hosts et /etc/apache2/site-availables pour ajouter son site perso MP3Gain ~~~~~~~ permet de gérer le volume sonore des fichiers mp3 .. code-block:: bash apt-get install mp3gain mp3gain -g 3 myfile*.mp3 Pour avoir une interface visuelle .. code-block:: bash apt-get install easymp3gain-gtk Sound-Juicer ~~~~~~~~~~~~ permet d'extraire au format mp3 ou ogg les cd audio .. code-block:: bash apt-get install sound-juicer gconf-editor pour améloirer la qualité de sortie des fichiers mp3 il faut lancer gconf-editor et dans la rubrique apps/sound-juicer/paranoia placer 255 Utilitaire ~~~~~~~~~~ pour les fichiers texte provenant de windows on a parfois des soucis avec des retours chariot .. code-block:: bash apt-get install dos2unix dos2unix file_windows.txt pour mettre à l'heure linux .. code-block:: bash date --set 18:40:34 date --set 2014-05-11 L'ensemble des fichier paramètre sont `ici `