Quantcast
Channel: AFPy's Planet
Viewing all 3561 articles
Browse latest View live

[cubicweb] Brainomics / CrEDIBLE conference report

$
0
0

Cubicweb and the Brainomics project were presented last week at the CrEDIBLE workshop (October 2-4, 2013, Sophia-Antipolis) on "Federating distributed and heterogeneous biomedical data and knowledge". We would like to thank the organizers for this nice opportunity to show the features of CubicWeb and Brainomics in the context of biomedical data.

http://credible.i3s.unice.fr/lib/tpl/credible/images/credible.png

Workshop highlights

  • A short presentation of SHI3LD that defines data access based on conditions that are based on ASK request. The other part was a state of the art of Open data license, and the (poor) existence of licenses expressed in RDF. Future work seems to be an interesting combination of both SHI3LD and RDF-based licenses for data access.
  • MIDAS, an open-source software for sharing medical data. This project could be an interesting source of inspiration for the file sharing part of CubicWeb, even if the (really complicated in my opinion) case of large files downloads is not addressed for now.
  • Federated queries based on FedX - the optimization techniques based on source selection & exclusive groups seems a good approach for avoiding large data transfers and finding some (sub-)optimal ways to join the different data sources. This should be taken into account in the future work on the "FROM" clause in CubicWeb.
  • WebPIE/QueryPIE: a map-reduce-based approach for large-scale reasoning.

CubicWeb and Brainomics

The slides of the presentation can be download as a PDF or viewed on slideshare.

Some people seem confused on the RQL to SQL translation. This relies on a simple translation logic that is implemented in the rql2sql file. This is only an implementation trick, not so different from the one used in RDBMS-based triplestores that have to convert SPARQL into SQL.

RQL inference : there is no magic behind the RQL inference process. As opposed to triplestores that store RDF triples that contain their own schema, and thus cannot easily know the full data model in these triples without looking at all the triples, RQL relies on a relational database with an fixed (at a given moment) data model, thus allowing inference and simple checks. In particular, in this example, we want All the Cities of `Île de France` with more than 100 000 inhabitants ?, which is expressed in RQL:

Any X WHERE X region Y, X population > 100000,
            Y uri "http://fr.dbpedia.org/resource/Île-de-France"

and SPARQL:

select ?ville where {
?ville db-owl:region <http://fr.dbpedia.org/resource/Île-de-France> .
?ville db-owl:populationTotal ?population .
FILTER (?population > 100000)
}

Beside the fact that RQL is less verbose that SPARQL (syntax matters), the simplicity of RQL relies on the fact that it can automatically infer (similarly to SPARQL) that if X is related to Y by the region relation and has a population attribute, it should be a city. If city and district both have the region relation and a population attribute, the RQL inference allows to fetch them both transparently, otherwise one can be specific by using the is relation:

Any X WHERE X is City, X region Y, X population > 100000,
            Y uri "http://fr.dbpedia.org/resource/Île-de-France"

RQL also allows subqueries, union, full-text search, stored procedures, ... (see the doc).

These really interesting discussions convinced us that we should write a journal paper for detailing the theoretical and technical concepts behind RQL and the YAMS schema.


[hautefeuille] Pont filtrant sous OpenBSD

$
0
0

Pont filtrant sous OpenBSD

Introduction

L’objectif est de protéger une partie de mon réseau local d’autres machines du réseau local.

La mise en place d’un pont filtrant est la solution que j’ai retenue.

Cette solution permet également de faire des audits de trafic puisqu’une grande partie du trafic internet passera par ce pont filtrant.

Cette solution se base sur le système d’exploitation OpenBSD.

Configuration du système

Certains recommandent la même configuration que pour le routage.

On active donc dans /etc/sysctl.conf :

net.inet.ip.forwarding=1

On crée le fichier /etc/rc.conf.local :

pf=YES

Configuration des interfaces

Je dispose des interfaces suivantes sis0 et xl0. La carte sis0 est la patte tournée vers l’intérieur du réseau à protéger. La carte xl0 est la carte de la patte tournée vers le routeur (vers l’extérieur).

modem ---- routeur ---- switch ---- xl0 pont sis0 ---- switch safe

Créer les 2 fichiers /etc/hostname.sis0 et /etc/hostname.xl0.

Pour /etc/hostname.sis0 :

192.168.0.4 255.255.255.0

Pour /etc/hostname.xl0 :

up

On positionne une adresse ip statique sur la patte intérieure du réseau à protéger, cela permet d’accéder au pont filtrant.

Configuration du pont

On crée le fichier /etc/hostname.bridge0 :

add sis0
add xl0
up

Configuration de packet filter

La configuration du firewall est largement personnalisable en fonction des besoins de chacun. Je propose donc ici une configuration minimale du firewall.

L’important dans cette configuration est de laisser le trafic entrant et sortant libre sur l’interface interne du réseau à protéger. Le filtrage s’effectue sur la patte extérieure du pont filtrant.

Ici on laisse sortir le trafic du réseau protégé vers l’extérieur mais on empêche tout trafic étranger de pénétrer sur le réseau protégé. On autorise uniquement le ping.

On édite le fichier /etc/pf.conf :

lan_if = "sis0"
wan_if = "xl0"
pass in quick on $lan_if
pass out quick on $lan_if
block in log on $wan_if all
pass out quick on $wan_if all
pass in on $wan_if inet proto icmp

On reboot la machine pour prendre en compte les modifications effectuées.

Contrôle des règles

On peut également contrôler le trafic sur l’interface du routeur avec tcpdump pour vérifier la véracité des règles du firewall :

# tcpdump -enttti pflog0
# tcpdump -enttti pflog0 host 192.168.0.111
# tcpdump -enttti pflog0 host 192.168.0.17 and tcp port 25

[hautefeuille] Analyse de trafic : Nfdump, Nfsen, Netflow, fprobe et OpenBSD

$
0
0

Analyse de trafic : Nfdump, Nfsen, Netflow, fprobe et OpenBSD

Introduction

Dans un article précédent, j’ai mis en place un pont filtrant en vue de protéger une partie du réseau local d’autres machines du réseau local.

Ce pont filtrant va également me servir de collecteur de données réseau en vue d’une analyse de trafic.

Cet article va s’appuyer sur le protocole réseau Netflow et sur les outils suivants :

  • Nfsen pour la visualisation des données,
  • Nfdump pour la collecte des données,
  • Pflow, sonde OpenBSD,
  • fprobe, sonde pour Ubuntu et pour RaspberryPI.

Prérequis d’installation

Nfsen utilise un serveur web pour générer les données. J’utilise la version Apache par défaut fournie avec OpenBSD. J’utilise la version non chrootée et en SSL/TLS.

Le fichier /etc/rc.conf.local :

pf=YES
sendmail_flags=NO
smtpd_flags=""
httpd_flags="-u -DSSL"

Installation de Nfdump et Nfsen

Nfdump et Nfsen sont disponibles pour OpenBSD, soit sous forme de paquets binaires soit dans l’arbre des ports. L’installation est aisée et sans surprise.

pkg_add nfsen
pkg_add nfdump

Pour Nfsen il vous sera demandé d’exécuter un script Perl d’installation :

install-nfsen.pl /etc/nfsen.conf

On crée également la configuration pour le démarrage au boot :

if [ -x /usr/local/bin/nfsen ]; then
    echo -n ' nfsen enable'; /usr/local/bin/nfsen start
fi

Configuration de Nfsen et collecte de données

J’ai modifié les lignes suivantes dans le fichier /etc/nfsen.conf :

$MAIL_FROM   = 'nzo@hotmail.org';
$SMTP_SERVER = 'localhost';
%sources = (
 'raspberry' => { 'port' => '2055', 'col' => '#00ff00' },
 'openbsd' => { 'port' => '9995', 'col' => '#0000ff' },
 'ubuntu' => { 'port' => '9996', 'col' => '#ff0000' },
);

Je monitore donc le pont filtrant lui-même (openbsd), une raspberry et une station Ubuntu. Cette configuration correspond à celle de la collecte de données.

Configuration des sondes

Pour Ubuntu et Raspberry, j’utilise fprobe. L’installation se fait rapidement par un simple apt-get.

apt-get install fprobe

Le script d’installation lance un script de configuration. On configure l’interface de collecte, et la destination du collecteur (ici l’adresse ip du pont filtrant Openbsd).

Pour OpenBSD, on utilise le mécanisme Pflow inclus dans OpenBSD qui gère le protocole Netflow. Pflow et paquet filter sont fortement liés. On doit en premier lieu créer l’interface pflow :

Créer le fichier /etc/hostname.pflow0 :

flowsrc 127.0.0.1 flowdst 127.0.0.1:9995 pflowproto 5

On utilise l’outil Pflow directement dans la configuration du firewall comme ceci :

set state-defaults pflow
pass in on $wan_if inet proto icmp label client-icmp keep state (pflow)

Ce qui provoque la génération de données de trafic est la directive keep state (pflow).

Remarques

Je n’ai pas réussi à prendre en compte les données sur un routeur DD-WRT avec le firmware DD-WRT v24-sp2 malgré le fait que l’on puisse accéder à la configuration.

[hautefeuille] Serveur de courriels sous OpenBSD

$
0
0

Serveur de courriels sous OpenBSD

Introduction

On souhaite mettre en place un serveur délivrant les courriels aux utilisateurs locaux mais aussi permettant l’envoi de messages vers l’extérieur au moyen d’un relais.

OpenBSD utilise Sendmail par défaut, nous allons donc le remplacer par le serveur OpenSMTPD.

Configuration préliminaire

On sauvegarde le fichier /etc/mailer.conf :

# mv /etc/mailer.conf /etc/mailer.conf.default

On édite le fichier /etc/mailer.conf pour remplacer les références de Sendmail vers OpenSMTPD :

sendmail        /usr/sbin/smtpctl
send-mail       /usr/sbin/smtpctl
mailq           /usr/sbin/smtpctl
makemap         /usr/libexec/smtpd/makemap
newaliases      /usr/libexec/smtpd/makemap

Configuration des aliases

Editer /etc/mail/aliases et configurer cette section :

# Well-known aliases -- these should be filled in!
root:anyuser@hotmail.com
manager:anyuser@hotmail.com
dumper:anyuser@hotmail.com

Mettre à jour les aliases :

# newaliases

Préparation du fichier secret

Ce fichier contient les informations de connexion smtp de votre compte courriel qui sera utilisé en guise de relais.

# touch /etc/mail/secrets 
# chmod 640 /etc/mail/secrets 
# chown root:_smtpd /etc/mail/secrets 
# echo "victor victor:sratFfg5lm" > /etc/mail/secrets 
# makemap /etc/mail/secrets

Configuration de OpenSMTPD

Editer /etc/mail.smtpd.conf :

listen on lo0 
table aliases db:/etc/mail/aliases.db 
table secrets db:/etc/mail/secrets.db 
accept for local alias <aliases> deliver to mbox 
accept for any relay via tls+auth://victor@mail.gandi.net auth <secrets>

Vérification de la configuration

On peut vérifier la configuration du serveur :

# smtpd -n

Ou le lancer en mode debug :

# smtpd -dv

Démarrage au boot

Editer le fichier /etc/rc.conf.local :

sendmail_flags=NO
smtpd_flags=""

Utilitaire de monitoring

Quelques commandes utiles :

# smtpctl show queue
# smtpctl show stats

[logilab] Retrieve Quandl's Data and Play with a Pandas

$
0
0

This post deals with the Pandas Python library, the open and free access of timeseries datasets thanks to the Quandl website and how you can handle datasets with pandas efficiently.

http://www.logilab.org/file/186707/raw/scrabble_data.jpg http://www.logilab.org/file/186708/raw/pandas_peluche.jpg

Why this post?

There has been a long time that I want to play a little with pandas. Not an adorable black and white teddy bear but the well-known Python Data library based on Numpy. I would like to show how you can easely retrieve some numerical datasets from the Quandl website and its API, and handle these datasets with pandas efficiently trought its main object: the DataFrame.

Note that this blog post comes with a IPython Notebook which can be found at http://nbviewer.ipython.org/url/www.logilab.org/file/187482/raw/quandl-data-with-pandas.ipynb

You also can get it at http://hg.logilab.org/users/dag/blog/2013/quandl-data-pandas/ with HG.

Just do:

hg clone http://hg.logilab.org/users/dag/blog/2013/quandl-data-pandas/

and get the IPython Notebook, the HTML conversion of this Notebook and some related CSV files.

First Step: Get the Code

At work or at home, I use Debian. A quick and dumb apt-get install python-pandas is enough. Nevertheless, (1) I'm keen on having a fresh and bloody upstream sources to get the lastest features and (2) I'm trying to contribute a little to the project --- tiny bugs, writing some docs. So I prefer to install it from source. Thus, I pull, I do sudo python setup.py develop and a few Cython compiling seconds later, I can do:

import pandas as pd

For the other ways to get the library, see the download page on the official website or see the dedicated Pypi page.

Let's build 10 brownian motions and plotting them with matplotlib.

import numpy as np
pd.DataFrame(np.random.randn(120, 10).cumsum(axis=0)).plot()

I don't very like the default font and color of the matplotlib figures and curves. I know that pandas defines a "mpl style". Just after the import, you can write:

pd.options.display.mpl_style = 'default'
http://www.logilab.org/file/186714/raw/Ten-Brownian-Motions.png

Second Step: Have You Got Some Data Please ?

Maybe I'm wrong, but I think that it's sometimes a quite difficult to retrieve some workable numerial datasets in the huge amount of available data over the Web. Free Data, Open Data and so on. OK folks, where are they ? I don't want to spent my time to through an Open Data website, find some interesting issues, parse an Excel file, get some specific data, mangling them to get a 2D arrays of floats with labels. Note that pandas fits with these kinds of problem very well. See the IO part of the pandas documentation --- CSV, Excel, JSON, HDF5 reading/writing functions. I just want workable numerical data without making effort.

A few days ago, a colleague of mine talked me about Quandl, a website dedicated to find and use numerical datasets with timeseries on the Internet. A perfect source to retrieve some data and play with pandas. Note that you can access some data about economics, health, population, education etc. thanks to a clever API. Get some datasets in CSV/XML/JSON formats between this date and this date, aggregate them, compute the difference, etc.

Moreover, you can access Quandl's datasets through any programming languages, like R, Julia, Clojure or Python (also available plugins or modules for some softwares such as Excel, Stata, etc.). The Quandl's Python package depends on Numpy and pandas. Perfect ! I can use the module Quandl.py available on GitHub and query some datasets directly in a DataFrame.

Here we are, huge amount of data are teasing me. Next question: which data to play with?

Third Step: Give some Food to Pandas

I've already imported the pandas library. Let's query some datasets thanks to the Quandl Python module. An example inspired by the README from the Quandl's GitHub page project.

import Quandl
data = Quandl.get('GOOG/NYSE_IBM')
data.tail()

and you get:

              Open    High     Low   Close    Volume
Date
2013-10-11  185.25  186.23  184.12  186.16   3232828
2013-10-14  185.41  186.99  184.42  186.97   2663207
2013-10-15  185.74  185.94  184.22  184.66   3367275
2013-10-16  185.42  186.73  184.99  186.73   6717979
2013-10-17  173.84  177.00  172.57  174.83  22368939

OK, I'm not very familiar with this kind of data. Take a look at the Quandl website. After a dozen of minutes on the Quandl website, I found this OECD murder rates. This page shows current and historical murder rates (assault deaths per 100 000 people) for 33 countries from the OECD. Take a country and type:

uk_df = Quandl.get('OECD/HEALTH_STAT_CICDHOCD_TXCMILTX_GBR')

It's a DataFrame with a single column 'Value'. The index of the DataFrame is a timeserie. You can easily plot these data thanks to a:

uk_df.plot()
http://www.logilab.org/file/186711/raw/GBR-oecd-murder-rates.png

See the other pieces of code and using examples in the dedicated IPython Notebook. I also get data about unemployment in OECD for the quite same countries with more dates. Then, as I would like to compare these data, I must select similar countries, time-resample my data to have the same frequency and so on. Take a look. Any comment is welcomed.

So, the remaining content of this blog post is just a summary of a few interesting and useful pandas features used in the IPython notebook.

  • Using the timeseries as Index of my DataFrames
  • pd.concat to concatenate several DataFrames along a given axis. This function can deal with missing values if the Index of each DataFrame are not similar (this is my case)
  • DataFrame.to_csv and pd.read_csv to dump/load your data to/from CSV files. There are different arguments for the read_csv which deals with dates, mising value, header & footer, etc.
  • DateOffset pandas object to deal with different time frequencies. Quite useful if you handle some data with calendar or business day, month end or begin, quarter end or begin, etc.
  • Resampling some data with the method resample. I use it to make frequency conversion of some data with timeseries.
  • Merging/joining DataFrames. Quite similar to the "SQL" feature. See pd.merge function or the DataFrame.join method. I used this feature to align my two DataFrames along its Index.
  • Some Matplotlib plotting functions such as DataFrame.plot() and plot(kind='bar').

Conclusion

I showed a few useful pandas features in the IPython Notebooks: concatenation, plotting, data computation, data alignement. I think I can show more but this could be occurred in a further blog post. Any comments, suggestions or questions are welcomed.

The next 0.13 pandas release should be coming soon. I'll write a short blog post about it in a few days.

The pictures come from:

[carlchenet] Publication de Brebis 0.8, le vérificateur automatisé de sauvegarde

$
0
0
Suivez-moi aussi sur Identi.ca ou sur Twitter  Brebis, le vérificateur automatisé de sauvegarde, est désormais disponible en version 0.8. Les principaux apports de cette version sont un renforcement de la sécurité du processus de vérification avec : un nouveau paramètre "sha512" dans le fichier de configuration de Brebis, indiquant la somme de hachage du fichier qui contient la liste […]

[Biologeek] Questionnements identitaires

$
0
0

Pour prendre la mesure de ce qui est véritablement inné parmi les éléments de l'identité, il y a un jeu mental éminemment révélateur : imaginer un nourrisson que l'on retirerait de son milieu à l'instant même de sa naissance pour le placer dans un environnement différent ; comparer alors les diverses « identités » qu'il pourrait acquérir, les combats qu'il aurait à mener et ceux qui lui seraient épargnés… Est-il besoin de préciser qu'il n'aurait aucun souvenir de « sa » religion d'origine, ni de « sa » nation, ni de « sa » langue, et qu'il pourrait se retrouver en train de combattre avec acharnement ceux qui auraient dû être les siens ?

Tant il est vrai que ce qui détermine l'appartenance d'une personne à un groupe donné, c'est essentiellement l'influence d'autrui ; l'influence des proches — parents, compatriotes, coreligionnaires — qui cherchent à se l'approprier, et l'influence de ceux d'en face, qui s'emploient à l'exclure. Chacun d'entre nous doit se frayer un chemin entre les voies où on le pousse, et celles qu'on lui interdit et qu'on sème d'embûches sous ses pieds ; il n'est pas d'emblée lui-même, il ne se contente pas de « prendre conscience » de ce qu'il est, il devient ce qu'il est ; il ne se contente pas de « prendre conscience » de son identité, il l'acquiert pas à pas.

Les identités meurtrières, Amin Maalouf

Je me demande aujourd'hui de quelle façon est-ce qu'Il construira son identité ? J'ai déjà du mal à définir la mienne, est-ce que je me sens plus vietnamien que breton ? De quelle manière est-ce que mes voyages en Corse, au Québec ou au Japon ont façonné mon identité « génétiquement » définie ? Suis-je même français ? Est-ce que je suis ce que je dis, je pense, je débat, j'écris, je milite pour, je fuis ?

Plus qu'une carte d'identité, j'ai envie qu'Il puisse cartographier ses rencontres. Croiser des personnes, passer des soirées, des jours, des années avec. S'en inspirer, les faire changer et changer avec, se disputer, se retrouver. Échanger sur ses expériences, ses échecs, ses pépites. Se manquer, se lasser, se dépasser. La construction de son identité — ou plutôt de ses identités — passe surtout par une ouverture d'esprit et de cœur suffisante pour essayer de comprendre une autre (micro-)culture. Tu seras ce que tu auras la curiosité d'aller explorer.

[cyp] Le décorateur view_config de pyramid

$
0
0

Rappel

Pyramid utilise un système de routes prédéclarées dans le fichier __init__.py (voir précédent article sur les routes).

Les vues matchent ces routes et renvoient les paramètres aux moteurs de templates qui transforment en html (ou autre chose) et renvoient aux clients.

Les views

Par défaut, le fichier views.py rassemble les différentes vues :

from pyramid.view import view_config

@view_config(route_name='home', renderer='templates/home.pt')
def home(request):
    return {'project': 'foo'}

@view_config(route_name='controls', renderer='templates/controls.pt')
def controls(request):
    return {'status': 'ok',
            'values': [1, 2, 3]}

Les vues peuvent être éclatées dans plusieurs fichiers, peuvent être écrites sous forme de classes.

class ViewSample(object):
     def __init__(self, request):
         self._request = request

     @view_config(route_name='home', renderer='templates/home.pt')
     def home(self):
         return {'project': 'foo'}

     @view_config(route_name='controls', renderer='templates/controls.pt')
     def controls(request):
         return {'status': 'ok', 'values': [1, 2, 3]}

Une vue est une fonction décorée par view_config. La fonction prends en paramètre un objet request (abordé dans un prochain billet) qui correspond à la requête faite par l'utilisateur. La fonction retourne ou un objet Response (abordé dans un prochain billet : sans doute le même que request) ou objet manipulable par le moteur de rendu. Le décorateur view_config décrit le rendu de la vue et son appel.

@view_config

view_config peut prendre un grand nombre de paramètres :

  • accept,
  • attr,
  • check_csrf
  • containment,
  • context,
  • custom_predicates,
  • decorator,
  • effective_principals
  • header,
  • http_cache,
  • mapper,
  • match_param,
  • name,
  • path_info,
  • permission,
  • predicates
  • physical_path,
  • renderer,
  • request_method,
  • request_param,
  • request_type,
  • route_name,
  • wrapper,
  • xhr.

Soient 24 paramètres possibles... Je ne vais pas tous les détailler : j'ignore l'usage de certains et d'autres sont très pointus. Pour les plus curieux, la documentation de pyramid les détaille. Tous sont optionnels, il n'est donc pas nécéssaire de tous les spécifier sur une méthode.

La documenation de pyramid distingue deux types de paramètres à @view_config : les prédicats et les non prédicats.

Les non prédicats sont permission, attr, renderer, http_cache, wrapper, decorator et mapper. Mécaniquement, tous sont des prédicats.

route_name

route_name décrit quelle route est rendue par cette fonction. route_name corresponds au nom de la route rajouté dans le config.add_route du __init__.py. Plusieurs fonctions peuvent avoir le même route_name (voir plus bas.)

route_name est un prédicat : la fonction décorée par @view_config ne sera appelée que si la requête HTTP match cette route.

from pyramid.view import view_config


@view_config(route_name='home', renderer='json')
def home(request):
    return {'func': 'home'}

@view_config(route_name='foo', renderer='json')
def foo(request):
    return {'func': 'foo'}

@view_config(renderer='json')
def default(request):
    return {'func': 'default'}

Les fonctions home et foo seront appelées quand les routes home et foo seront matchées. défault ne sera jamais appelée. route_name est bien optionnel car il y a d'autre moyen de matcher une fonction mais dans les faits, il est vraiment nécéssaire : les cas où route_name n'est pas utilisé sont un peu plus compliqués et on verra peut être ça une autre fois.

Il est possible d'avoir plusieurs fois le décorateur view_config sur une même fonction.

Imaginons le fichier __init__.py suivant :

from pyramid.config import Configurator

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    config = Configurator(settings=settings)
    config.add_route('home', '/')
    config.add_route('foo', '/foo')
    config.add_route('baz', '/baz')

    config.scan()
    return config.make_wsgi_app()

et le fichier views.py suivant :

from pyramid.view import view_config


@view_config(route_name='home', renderer='json')
def home(request):
    return {'func': 'home'}

@view_config(route_name='foo', renderer='json')
@view_config(route_name='baz', renderer='json')
def default(request):
    return {'func': 'default'}

La méthode default matchera les route foo et baz :

$ curl  http://0.0.0.0:6543/ && echo
{"func": "home"}
$ curl  http://0.0.0.0:6543/foo && echo
{"func": "default"}
$ curl  http://0.0.0.0:6543/baz && echo
{"func": "default"}

renderer

renderer décrit le rendu utilisé lors de l'appel. Par défaut, pyramid est[1] livré avec trois moteurs de rendu : string, json et chameleon. D'autres moteurs sont disponibles tel que mako, genshi, jinja2 ou même un moteur maison.

[1]était serait plus juste. Depuis la version 1.5 de pyramid, chameleon n'est plus livré par défaut dans pyramid. Cependant, il reste celui utilisé par pcreate pour créer les templates ou exemple d'application.

Le renderer json transforme la réponse en json ; la réponse doit donc être une chaine de caractères, une liste, un tuple, un dictionnaire ou une combinaison des précédents.

string retourne la représentation str du return.

Différence entre string et json :

from pyramid.view import view_config


@view_config(route_name='fooString', renderer="string")
def fooString(request):
    return ["fooString"]

@view_config(route_name='fooJSON', renderer="json")
def fooJson(request):
    return ["fooJson"]

Les retours seront :

$ curl -i http://0.0.0.0:6543/foo/string && echo
HTTP/1.1 200 OK
Content-Length: 9
Content-Type: text/plain; charset=UTF-8
Date: Mon, 11 Nov 2013 11:17:25 GMT
Server: waitress

['fooString']
$ curl -i http://0.0.0.0:6543/foo/json && echo
HTTP/1.1 200 OK
Content-Length: 9
Content-Type: application/json; charset=UTF-8
Date: Mon, 11 Nov 2013 11:17:28 GMT
Server: waitress

["fooJson"]

Il est important de noter le changment de Content-Type selon le moteur de rendu.

renderer peut aussi prendre un chemin vers un template tel que templates/foo.pt. l'extention .pt signifie page template et indique que le moteur de rendu ici est chameleon. Les rendus chameleon prennent en paramètre des dictionnaires pouvant contenir des objets. Content-Type sera du HTML

Si le paramètre renderer est absent, il faut renvoyer un objet Response.

from pyramid.view import view_config

@view_config(route_name='baz')
def baz(request):
    request.response.body = 'baz'
    return request.response

Et la réponse renvoyée au client ne contiendra que baz :

$ curl  http://0.0.0.0:6543/baz && echo
baz

Request et Response feront l'oject d'un prochain billet (vraiment faut que je le fasse). Comme dans un prochain billet, je montrerais comment rajouter un moteur de rendu à pyramid.

Pyramid peut avoir plusieurs moteurs de rendu simultanément : certaines fonctions peuvent utiliser mako et d'autres chameleon ou json.

request_method

Le paramètre corresponds request_method aux verbes HTTP utilisés pour acceder à la page :

  • GET,
  • POST,
  • PUT,
  • DELETE,
  • HEAD.

NB : Les exemples suivant sont en JSON avec curl, ils s'appliquent tous aussi bien avec un rendu HTML et un navigateur. curl et JSON sont juste ici pour la facilité d'écriture.

from pyramid.view import view_config


@view_config(route_name='baz', renderer='json', request_method='GET')
def get(request):
    return 'GET'

@view_config(route_name='baz', renderer='json', request_method='POST')
def post(request):
    return 'POST'

@view_config(route_name='baz', renderer='json', request_method='HEAD')
def head(request):
    return 'HEAD'

@view_config(route_name='baz', renderer='json', request_method='PUT')
def put(request):
    return 'PUT'

@view_config(route_name='baz', renderer='json', request_method='DELETE')
def delete(request):
    return 'DELETE'

Ce qui donnera avec curl:

$ curl  -XGET http://0.0.0.0:6543/baz && echo
"GET"
$ curl  -XPOST http://0.0.0.0:6543/baz && echo
"POST"
$ curl  -XHEAD http://0.0.0.0:6543/baz && echo
curl: (18) transfer closed with 5 bytes remaining to read
$ curl  -XPUT http://0.0.0.0:6543/baz && echo
"PUT"
$ curl  -XDELETE http://0.0.0.0:6543/baz && echo
"DELETE"

Pour HEAD, c'est un non sens de renvoyer une valeur dans le body d'où l'erreur de curl.

request_method peut être également une liste de méthode acceptées :

from pyramid.view import view_config


@view_config(route_name='baz', renderer='json', request_method='GET')
def get(request):
    return 'GET'

@view_config(route_name='baz', renderer='json', request_method=['POST', 'PUT'])
def post(request):
    return 'POST or PUT'
$ curl  -XGET http://0.0.0.0:6543/baz && echo
"GET"
$ curl  -XPOST http://0.0.0.0:6543/baz && echo
"POST or PUT"
$ curl  -XPUT http://0.0.0.0:6543/baz && echo
"POST or PUT"

On aurait pu également écrire:

@view_config(route_name='baz', renderer='json', request_method='POST')
@view_config(route_name='baz', renderer='json', request_method='PUT')
def post(request):
    return 'POST or PUT'

Sans le paramètre request_method, la vue s'écrirait :

@view_config(route_name='baz', renderer='json')
def baz(request):
    if request.method in ['POST', 'PUT']:
        return 'POST or PUT'
    elif request.method == 'GET':
        return 'GET'

    return '???' #TODO: ici généré une 404
$ curl  -XGET http://0.0.0.0:6543/baz && echo
"GET"
$ curl  -XPUT http://0.0.0.0:6543/baz && echo
"POST or PUT"
$ curl  -XPOST http://0.0.0.0:6543/baz && echo
"POST or PUT"
$ curl  -XDELETE http://0.0.0.0:6543/baz && echo
"???"

Si on ne définit pas toutes les request_method, certains verbes vont générer des 404 (ce qui peut être un comportement légitime).

from pyramid.view import view_config


@view_config(route_name='baz', renderer='json', request_method='GET')
def get(request):
    return 'GET'

@view_config(route_name='baz', renderer='json', request_method='POST')
def post(request):
    return 'POST'
$ curl  -XGET http://0.0.0.0:6543/baz && echo
"GET"
$ curl  -XPOST http://0.0.0.0:6543/baz && echo
"POST"
$curl  -XPUT -v http://0.0.0.0:6543/baz >/dev/null && echo
* About to connect() to 0.0.0.0 port 6543 (#0)
*   Trying 0.0.0.0...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 0.0.0.0 (0.0.0.0) port 6543 (#0)
> PUT /baz HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 0.0.0.0:6543
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Content-Length: 61026
< Content-Type: text/html; charset=UTF-8
< Date: Mon, 11 Nov 2013 11:36:21 GMT
< Server: waitress
<
{ [data not shown]
100 61026  100 61026    0     0  2436k      0 --:--:-- --:--:-- --:--:-- 2483k
* Connection #0 to host 0.0.0.0 left intact

Dans l'absolu, on peut utiliser ses propres verbes même si cela me parait une mauvaise idée[2] :

@view_config(route_name='baz', renderer='json', request_method='FOO')
def foo(request):
    return 'FOO'
$ curl  -XFOO  http://0.0.0.0:6543/baz  && echo
"FOO"
[2]sans compter qu'il faut que les reverses proxy, les serveurs WSGI acceptent ces nouveaux verbes. Dans une optique webservice REST, les verbes webdav, par contre, peuvent être utiles.

Pour faire un webservice REST, cornice est une bonne surcouche à pyramid qui permet de gagner du temps.

Pour finir, pyramid 1.5 a introduit not_ qui est utilisable dans request_method :

from pyramid.view import view_config
from pyramid.config import not_


@view_config(route_name='baz', renderer='json', request_method=not_('POST'))
def post(request):
    return 'not POST'
$ curl  -XGET  http://0.0.0.0:6543/baz  && echo
"not POST"
$ curl  -XPUT  http://0.0.0.0:6543/baz  && echo
"not POST"
$ curl  -XPOST  -v http://0.0.0.0:6543/baz  > /dev/null && echo
* About to connect() to 0.0.0.0 port 6543 (#0)
*   Trying 0.0.0.0...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 0.0.0.0 (0.0.0.0) port 6543 (#0)
> POST /baz HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 0.0.0.0:6543
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Content-Length: 61416
< Content-Type: text/html; charset=UTF-8
< Date: Mon, 11 Nov 2013 12:04:00 GMT
< Server: waitress
<
{ [data not shown]
100 61416  100 61416    0     0  4355k      0 --:--:-- --:--:-- --:--:-- 4613k
* Connection #0 to host 0.0.0.0 left intact

accept

accept liste les types mimes de réponses acceptées par le client :
application/json, application/xml, text/html...
from pyramid.view import view_config

@view_config(route_name='baz', renderer='json', accept='application/json')
def baz(request):
    return 'baz'

@view_config(route_name='baz', renderer='string', accept='application/xml')
def bazxml(request):
    return '<foo>baz</foo>'
$ curl -H "Accept: application/xml" http://0.0.0.0:6543/baz   && echo
<foo>baz</foo>
$ curl -H "Accept: application/json" http://0.0.0.0:6543/baz   && echo
"baz"

Attention ! Cela ne se spécifie pas le content type de la réponse ! il faut le faire explicitement ou via le moteur de rendu.

@view_config(route_name='baz', renderer='string', accept='application/xml')
def bazxml(request):
    request.response.content_type = 'application/xml'
    return '<foo>baz</foo>'

Le client peut passer un Accept sous la forme d'un mimetype ou sous la forme text/* ou */*.

from pyramid.view import view_config

@view_config(route_name='baz', renderer='json', accept='application/json')
def baz(request):
    return 'baz'

@view_config(route_name='baz', renderer='string', accept='text/xml')
def bazxml(request):
    return '<foo>baz</foo>'
$ curl -H "Accept: application/json" http://0.0.0.0:6543/baz   && echo
"baz"
$ curl -H "Accept: application/*" http://0.0.0.0:6543/baz   && echo
"baz"
$ curl -H "Accept: text/*" http://0.0.0.0:6543/baz   && echo
<foo>baz</foo>
$ curl -H "Accept: */*" http://0.0.0.0:6543/baz   && echo
"baz"
$ curl -H "Accept: */*" http://0.0.0.0:6543/baz   && echo

Le premier accept qui match est retourné. Si accept est absent, il n'y a pas de discrimination sur ce header HTTP.

http_cache

http_cache positionne dans les headers de la réponse la durée du cache coté client. La valeur du paramètre peut être un entier positif ou nul qui est le temps en secondes, un timedelta ou un tuple donc le premier paramètre est un entier ou un timedelta et le second un dictionnaire sur la politique du cache.

from datetime import timedelta
from pyramid.view import view_config


@view_config(route_name='baz', renderer='json', http_cache=2)
def baz(request):
    return 'baz'

@view_config(route_name='foo', renderer='json', http_cache=timedelta(days=1))
def foo(request):
    return 'foo'

@view_config(route_name='bar', renderer='json', http_cache=(4, {'public': True}))
def bar(request):
    return 'bar'
"baz"
$ curl -i http://0.0.0.0:6543/foo && echo
HTTP/1.1 200 OK
Cache-Control: max-age=86400
Content-Length: 5
Content-Type: application/json; charset=UTF-8
Date: Mon, 11 Nov 2013 13:47:14 GMT
Expires: Tue, 12 Nov 2013 13:47:14 GMT
Server: waitress

"foo"

$ curl -i http://0.0.0.0:6543/bar && echo
HTTP/1.1 200 OK
Cache-Control: max-age=4, public
Content-Length: 5
Content-Type: application/json; charset=UTF-8
Date: Mon, 11 Nov 2013 13:52:55 GMT
Expires: Mon, 11 Nov 2013 13:52:59 GMT
Server: waitress

"bar"

match_param

match_param est un prédicat sur le contenu du path.

Soit le fichier __init__.py suivant :

from pyramid.config import Configurator

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    config = Configurator(settings=settings)
    config.add_route('foo', '/foo/{baz}')
    config.scan()
    return config.make_wsgi_app()

et le fichier views correspondant :

from pyramid.view import view_config


@view_config(route_name='foo', renderer='json', match_param='baz=foo')
def foo(request):
    return 'foo'

@view_config(route_name='foo', renderer='json', match_param='baz=bar')
def bar(request):
    return 'bar'

Ce qui donne lors des appels :

$ curl http://0.0.0.0:6543/foo/bar && echo
"bar"
$ curl http://0.0.0.0:6543/foo/foo && echo
"foo"

permission

permission liste les permissions pour acceder à la vue. Cela rentre dans les authentifications et les permissions de pyramid qui fera l'objet d'un billet dédié.

Combinaison des paramêtres

Après cette longue liste partielle de paramètres, l'intéret est de les combiner pour offrir une granularité fine pour les réponses.

@view_config(name="home", accept='application/json', renderer='json')
def repJson(request):
    """réponse en json"""
    return {'foo': 'bar'}

@view_config(name="home", request_method='GET', renderer='templates/home.pt')
def repGet(request):
    return {'params': 'foo'}

@view_config(name="home", request_method='POST', renderer='templates/home.pt')
def repPost(request):
    return {'params': 'bar'}

@view_config(name="home", request_method='PUT', renderer='templates/homeput.pt')
def repPut(request):
    return {'params': 'baz'}

Dans cet exemple, la même route home peut répondre selon les combinaisons de quatre manières différentes en utilisant s'il le faut différents rendus.

Ajout de paramètres

Si la liste ne suffit pas, il est possible de créer ses propres prédicats.

Il n'y a pas d'interface au sens ZCA[4] mais la classe doit respecter la signature suivante :

[4]yep y aura un billet sur la ZCA et pyramid s'en sert un peu. Ce n'est pas nécessaire pour comprendre les entrailles de pyramid mais ça peut aider.
class Predicate(object):
   def __init__(self, val, config):
       pass

   def text(self):
       return 'une signature'

   phash = text

   def __call__(self, context, request):
       return True # retourne un booléen

Exemple de prédicat sur le jour de la semaine.

class DayPredicate(object):
      _choice = {'monday': 0,
                 'thursday': 1,
                 'wedesnday': 2,
                 'thuesday' : 3,
                 'friday': 4,
                 'saturday': 5,
                 'sunday': 6}

      def __init__(self, val, config):
          self._val = val
          self._numVal = self._choice[val]

      def text(self):
          return 'predicat on %s' % self._val

      phash = text

      def __call__(self, context, request):
          return datetime.datetime.today().weekday() == self._numVal

Ajout du prédicat à pyramid:

config.add_view_predicate('day', DayPredicate)

et enfin l'utilisation.

@view_config(route_name='foo', renderer='json', day='monday')
def monday(request):
    return 'monday'

@view_config(route_name='foo', renderer=json', day='sunday')
def sunday(request):
    return 'sunday'

Ce qui donnera :

$ curl http://0.0.0.0:6543/foo && echo
"monday"

Une autre approche est d'utiliser le paramètre custom_predicate de view_config.

@view_config(route_name='foo', renderer='json', custom_predicate=(DayPredicate('monday', None), ))
def monday(request):
    return 'monday'

@view_config(route_name='foo', renderer='json', custom_predicate=(DayPredicate('sunday', None), ))
def sunday(request):
    return 'sunday'

Des usages plus pertinents seraient des prédicats logged ou admin pour filtrer si l'utilisateur est loggé ou admin.

C'est tout pour aujourd'hui

Le décorateur @view_config avec sa granularité et son extensibilité est une des choses que j'aime beaucoup dans pyramid.


[cubicweb] Logilab's roadmap for CubicWeb on November 8th, 2013

$
0
0

The Logilab team holds a roadmap meeting every two months to plan its CubicWeb development effort. Here is the report about the Nov 8th, 2013 meeting. The previous report posted to the blog was the september 2013 roadmap.

Version 3.17

This version is stable and maintained (cubicweb 3.17.11 is upcoming).

Version 3.18

This version was supposed to be released in september or october, but is stalled at the integration stage. All open tickets were moved to 3.19 and existing patches that are not ready to be merged will be more aggressively delayed to 3.19. The goal is to release 3.18 as soon as possible.

For details read list of tickets for CubicWeb 3.18.0.

Version 3.19

This version will probably be published early next year (read january or february 2014). it is planned to include a heavy refactoring that modifies sessions and sources to lay the path for CubicWeb 4.

For details read list of tickets for CubicWeb 3.19.0.

Squareui

Logilab is now developping all its new projects based on Squareui (and Bootstrap 3.0). Squareui can be considered as a usable beta, but not as feature-complete.

Logilab is looking for a UX designer to work on the general ergonomy of CubicWeb. Read the job offer.

Mid-term goals

The mid-term goals include better REST support (Representational State Transfer), complete WSGI (Python's Web Server Gateway Interface) and the FROM clause for RQL queries (to reinvent db federation outside of the core).

On the front-end side, it would be nice to be able to improve forms, maybe with client-side javascript and better support for a "json on server, js in browser" separation of concerns.

Cubes

A cube oauth was contributed in large part by Unlish, a startup that is using CubicWeb to implement its service.

A cube vcwiki is being developed by Logilab, to manage the content of a wiki with a version control system (built with the cube vcsfile).

Last but not least

As already said on the mailing list, other developers and contributors are more than welcome to share their own goals in order to define a roadmap that best fits everyone's needs.

Logilab's next roadmap meeting will be held at the beginning of january 2014.

[carlchenet] Yarn : Scénarios d’exécutions de programmes en ligne de commandes

$
0
0
Suivez-moi aussi sur Identi.ca ou sur Twitter  Ceux qui me suivent sur Twitter auront peut-être vu passer un tweet au sujet de Yarn, logiciel fort sympathique que j’ai vraiment découvert le week-end dernier à la Mini-Debconf UK à Cambridge. Yarn permet de définir des scénarios d’exécutions de programmes en ligne de commande. Le scénario ainsi écrit sera ensuite joué et le […]

[Biologeek] Téléphone stupide

$
0
0

Plus les conflits deviennent sophistiqués, plus les gens restés frustres ont leur chances, car ils sont hors normes.

Le Commando Hubert, Claude Derungs

Après 5 ans d'iPhone, j'ai décidé de retourner à un téléphone qui ne sait faire que téléphoner. Plusieurs raisons à cela :

  • la mise à jour d'iOS a anticipé le décès de mon ancien modèle, faisant de moi un potentiel iDiot de plus ;
  • la possibilité d'être tracé en permanence dans mes échanges, mes déplacements et mes instants de vie s'est vue être confirmée ;
  • la volonté de retrouver un peu d'attention pour mes interlocuteurs et le monde qui m'entoure.

J'aurais bien tenté le fait de ne plus avoir de téléphone du tout mais c'est une période à laquelle j'avais besoin d'être joignable rapidement. Deux semaines plus tard, différentes choses se sont produites :

  • je suis moins stressé, je prends le temps de lire mes mails quand je suis à la maison dans un contexte mieux contrôlé (et du coup je prends plus de temps à y répondre aussi) ;
  • je n'envoie quasi plus de SMS tellement la tâche est fastidieuse, l'ergonomie d'un téléphone stupide est désastreuse et n'a pas évoluée depuis le Nokia 3210… c'est même pire j'ai l'impression ;
  • j'utilise Twitter comme un media vraiment asynchrone ce qui n'était plus vraiment le cas depuis qu'il était dans ma poche ;
  • je n'ai plus peur de le faire tomber ou de me le faire voler, ce n'était pas vraiment une peur mais plutôt une attention, les données et l'accès à ce téléphone n'ont aucune valeur à mes yeux ;
  • j'anticipe beaucoup plus mes déplacements et mes rendez-vous ;
  • je suis halluciné par l'autonomie que peut avoir un téléphone stupide, de l'ordre de la semaine ou plus et par sa légèreté.

Cela dit, je crois discerner un schéma chez tous les gens qui ont un problème pour donner une part raisonnable à leur vie privée : ils sont jeunes et n’ont pas forcément de famille.

Le temps de vivre, Stéphane Deschamps

Peut-être est-ce l'approche de la vieillesse la fondation d'une famille qui change un peu mes priorités ou alors la fatigue des sens que m'apportait un smartphone. Toujours est-il que cela me fait du bien. Je retrouve la conscience perdue du monde qui m'entoure. J'échange quelques regards amusés et complices avec les seules personnes qui n'ont pas les yeux rivés sur leurs petits écrans.

Our contemporary reluctance to talk on the phone comes from the painful switch from a visual world into a seemingly exotic audile one.

The Latency of Dialogue, Bryan Summersett

J'ai également envie de réintroduire de la latence dans mon usage du Web. Peut-être aussi un moyen de réfléchir à ce que pourrait être une approche offline-first de mon travail et de mes publications.

[hautefeuille] Tmux, multiplexeur de terminaux

$
0
0

Tmux, multiplexeur de terminaux

Installation sous Linux

Dans un terminal en root :

# sudo apt-get install tmux

Fichier de configuration de Tmux

Editer le fichier /home/user/.tmux.conf :

# UTF-8
set-option -g status-utf8 on
set-window-option -g utf8 on

# Set 256-colour terminal
set -g default-terminal "screen-256color"

# Number of lines held in window history
set -g history-limit 1000

# Set status bar
set -g status-bg black
set -g status-fg white
set -g status-interval 60
set -g status-left-length 30
set -g status-left '#[fg=green](#S) #(whoami)@#H#[default]'

# Highlight active window
setw -g window-status-current-bg blue

# Set window notifications
setw -g monitor-activity on
set -g visual-activity on

# Automatically set window title
setw -g automatic-rename on

# Use mouse to select pane
set -g mouse-select-pane on

# Mode-keys style for copy mode
setw -g mode-keys vi

# Default session
new -d -s "MaSession"

Les commandes disponibles

L’aide des touches

[Ctrl+b]+?

Nouvelle fenêtre

[Ctrl+b]+c

Fenêtre suivante

[Ctrl+b]+n

Fenêtre 2

[Ctrl+b]+2

Liste de fenêtres

[Ctrl+b]+w

Division verticale

[Ctrl+b]+%

Division horizontale

[Ctrl+b]+"

Annuler la division des fenêtres

[Ctrl+b]+!

Naviguer dans les panneaux divisés

[Ctrl+b]+up (down, left or right)

Organisation automatique des fenêtres

[Ctrl+b]+space

Détacher Tmux

[Ctrl+b]+d

Rattacher Tmux après détachement

# tmux attach

Envoyer des commandes aux serveurs distants

[Ctrl+b][Ctrl+b]+c

Commandes par le shell

Quelques exemples :

# tmux kill-window -t :1
# tmux new-window \; split-window -d
# tmux new-session -d 'vi /etc/passwd' \; split-window -d \; attach
# tmux refresh-client -t/dev/ttyp2
# tmux rename-session -tfirst newname
# tmux set-window-option -t:0 monitor-activity on
# tmux new-window ; split-window -d

[hautefeuille] Commandes Unix utiles et pratiques

$
0
0

Commandes Unix utiles et pratiques

Copie récursive avec tar

(cd /source && tar cfp - . ) | (cd /cible && tar xvpf -)

Obtenir des informations sur la partition

dumpe2fs -h /dev/hda3

Différences sur des sorties de commandes

diff<(command1)<(command2)

Recherche de root kits

rkhunter -c

chkrootkit

Conversion de flv vers avi avec mencoder

mencoder video.flv -ovc lavc -oac pcm -lavcopts vcodec=mpeg4 -o video.avi

Conversion flv vers mp3

ffmpeg -i fichier.flv -vn -ar 44100 -ac 2 -ab 192 -f mp3 fichierfin.mp3

Trier les répertoires par taille

du -sh * | sort -nr

du -s * | sort -rnk 1

Détection des ports ouverts

nmap -T 3 192.168.1.1

Détection de l’OS

nmap -O 192.168.1.1

Ecrire le résultat d’un scan dans un fichier

nmap -sS -sV -O 192.168.0.0/24 > output.txt

Analyse de trafic avec tcpdump

tcpdump -enttti pflog0

tcpdump -enttti pflog0 host 192.168.0.111

tcpdump -enttti pflog0 host 192.168.0.17 and tcp port 25

Sniff du port 80

ngrep -d "eth0" -t "^(GET|POST)" "tcp and port 80"

Dump d’une base MySQL

mysqldump --add-drop-table -h localhost -u USERNAME -p DATABASENAME | bzip2 -c > machine.sql.bz2

Restauration d’une base MySQL

zip2 -d machine.sql.bz2

mysql -h localhost -u USERNAME -p DATABASENAME < machine.sql

Tester la vitesse de lecture du disque

hdparm -Tt /dev/sdc

Démarrer un serveur en Python

python -m SimpleHTTPServer 8080

Créer un patch sur un fichier

diff -uN file file.new > mypatch

Créer un patch sur un dossier

diff -ruN directory/ directory.new/ > mypatch

Appliquer un patch sur un fichier

patch < mypatch

Appliquer un patch sur un dossier

patch -R < mypatch

Observer un répertoire

watch ls

Observer les connexions

watch -n1 -d 'netstat -an | grep ESTABLISHED'

Effacement définitif d’un fichier

shred -f -v -z -u myfile

Création d’un tunnel ssh

ssh - tunnel ssh user@serveur -C -N -D 8080

Créer une image sur le réseau avec netcat

Sur l’hôte :

nc -l -p 2000 > image.dsk

Sur le PC

dd if=/dev/sda | nc hote 2000

Email en ligne de commande

echo | mutt -s "bkprooter" -a siteCUSTOM.tgz -- robert@aol.com

Screencast

recordmydesktop -x 0 -y 0 --width=1920 --height=1080 --fps=25

Créer un transfert de données entre 2 flux TCP avec SOCAT

socat TCP4-LISTEN:www TCP4:www.domain.org:www

Ecrire dans un fichier les données reçues sur un port

socat -u TCP4-LISTEN:3334,reuseaddr,fork OPEN:/tmp/in.log,creat,append

Générer les clés SSH

ssh-keygen -t rsa

Puis

antec $ scp ~/.ssh/id_rsa.pub votrelogin@xyz.org:~/.ssh/id_rsa.pub.tmp

antec $ ssh votrelogin@xyz.org

shoota $ cat ~/.ssh/id_rsa.pub.tmp >>~/.ssh/authorized_keys

shoota $ rm ~/.ssh/id_rsa.pub.tmp

Les options courantes de MOUNT

-a : Monter tous les systèmes de fichier déclarés dans le fichier /etc/fstab

-t : Précise le type de fichier à monter

-o : Ajouter une option.

Options adjointes à les plus fréquentes :

auto : Permet d’être monté par -a

async : Les entrées/sorties sur le système de fichiers seront asynchrones

defaults : Utilise les options rw, suid, dev, exec, auto, nouser, et async.

dev : Interprète les fichiers spéciaux de périphériques du système présent dans /dev/

exec : Permet l’exécution de fichiers binaires du système monté

noauto : Empêche d’être monté avec -a

nodev : Ne pas interpréter les fichiers spéciaux de périphériques du système

noexec : Empêche l’exécution de fichiers binaires du système monté

nouser : Ne pas autoriser d’autres utilisateurs que root (ou sudo) à monter le système de fichiers (comportement par défaut)

ro : Monte le système en lecture seule

rw : Monte le système en lecture et écriture

suid : Prend en compte les bits SetUID ou SetGID du système monté

user : Permet aux utilisateurs ordinaires à monter et démonter le système de fichiers (implique noexec, nosuid, et nodev sauf si surchargées)

Les raccourcis du mode console

Déplacement

Ctrl + a : aller au début de la ligne

Ctrl + e : aller à la fin de la ligne

Alt + b : se déplacer mot par mot dans la ligne de commande en arrière (b pour backward)

Alt + f : se déplacer mot par mot dans la ligne de commande en avant (f pour forward)

Ctrl + xx : positionner le curseur au début du mot ou à la fin

Ctrl + XL : position 69 (moyen, moyen…)

Couper / Coller

Ctrl + k : couper la chaîne du curseur jusqu’à la fin de la ligne

Ctrl + u : couper la chaîne du curseur jusqu’au début de la ligne

Ctrl + w : couper le mot avant le curseur

Ctrl + y : coller une chaîne

Modification

Ctrl + t : inverser la position des deux caractères avant le curseur

Alt + shift + t : inverser la position des deux mots avant le curseur

Alt + shift + c : mettre une lettre en majuscule

Alt + shift + l : mettre un mot en minuscule (l pour lowercase)

Alt + shift + u : mettre un mot en majuscule (u pour uppercase)

Alt + shift + . : réécrire le paramètre de la dernière commande

Divers

Ctrl + l : effacer le contenu de l’écran

Ctrl + _ : annuler la dernière modification

Ctrl + c : arrêter la commande en cours

Ctrl + z : interrompt temporairement un processus, qui peut être relancé avec la commande fg (au premier plan) ou bg (en arrière-plan)

Ctrl + d : quitter le shell en cours

Ctrl + r : permet de rechercher une commande dans l’historique de la console

[hautefeuille] Bluetooth Debian et casque audio

$
0
0

Bluetooth Debian et casque audio

Installez en premier :

apt-get install bluez-utils bluez-alsa

Dans un fichier .asoundrc :

pcm.bluetooth {
        type bluetooth
        device "XX:XX:XX:XX:XX:XX"
        profile "auto"
}

L’adresse MAC est récupérée par la commande suivante :

sudo hcitool scan

Puis sous mplayer :

mplayer -ao alsa:device=bluetooth /home/calagan/celinedion.mp3

Sous VLC en éditant :

~/.config/vlc/vlcrc

Remplacer :

alsa-audio-device=default

Par :

alsa-audio-device=bluetooth

[hautefeuille] Faire passer ses requêtes DNS dans le proxy socks avec Firefox

$
0
0

Faire passer ses requêtes DNS dans le proxy socks avec Firefox

Si vous êtes chez Free par exemple et que celui-ci vous bride sur les services de vidéos en streaming, vous avez certainement configuré un proxy socks afin d’outrepasser ce bridage.

Pour faire passer toutes vos requêtes DNS de navigation à travers le proxy, si vous utilisez Firefox, modifiez dans about:config :

network.proxy.socks_remote_dns=True

Il semble que le navigateur Chrome le fasse par défaut.


[hautefeuille] Générateur de blog Pelican, Markdown et code

$
0
0

Générateur de blog Pelican, Markdown et code

Pour résoudre le problème des caractères accentués non pris en compte lors de la publication de code sous Pelican, il suffit d’ajouter dans son settings.py pour le Markdown :

MD_EXTENSIONS = ['codehilite(css_class=highlight, guess_lang=False)', 'extra']

Source

[Biologeek] Agilité et efficacité

$
0
0

Cet ouvrage est un instrument. Il a été conçu comme tel — et en vue de mener des luttes. Comme tout instrument, il faut le pratiquer. Et comme tout instrument, il devrait instruire ceux qui le pratiquent : à travers leurs pratiques, l'instrument tend à instruire un aspect du monde que ses praticiens ont en commun et surtout font en commun.

Ceux qui pratiquent le piano, par exemple (ce qui s'appelle jouer du piano), instruisent la musicalité du monde sur le registre spécifique ouvert par cette lutherie — à travers eux, le piano et son art deviennent, s'individuent et font le monde plutôt que l'immonde. Et dans la mesure où un instrument doit être pratiqué, il faut apprendre à s'en servir : jouer du piano nécessite d'apprendre la musique.

Pharmacologie du Front National, Bernard Stiegler.

Le débat pratique vs. culture qui anime la scène agiliste ces derniers temps est induit par un rapport mal accepté à l'efficacité. Beaucoup de personnes se sont lancées dans des pratiques agiles dans le but clairement affiché d'améliorer leurs performances (l'intervention d'Alain Fontaine, président de la cellule d'innovation chez Airbus à Lift France était assez caricaturale en ce sens). Et l'on peut facilement interpréter ces principes sous l'angle de la compétition et du capitalisme :

Or, je vois nombre de prescriptions dans ces principes: "en livrant rapidement et régulièrement", "satisfaire le client", "avantage compétitif au client", "Livrez fréquemment", "une préférence pour les plus courts", "quotidiennement", "plus efficace". Ces prescriptions concernent le rythme de développement ainsi que l'efficacité. Il s'agit notamment de compétitivité.

Il en ressort que l'agilité est donc une manière d'être efficace dans la course économique. Souscrire au manifeste agile revient donc à s'assujettir à cette course. Pas vraiment une libération, donc.

Software craftsmanship, agilité, Oranadoz

Pour moi le manifeste agile était un premier jet, un brouillon, et ne doit pas être suivi comme un plan mais adapté à la situation et aux personnes présentes. C'est la raison pour laquelle je ne me formalise pas de sa rédaction maladroite, il a fait son temps et a été très utile pour amorcer un changement mais il est temps de s'en affranchir et de le dépasser.

Qu'est-ce que l'on a appris en jouant la musique de l'agilité ?

Qu'il fallait du bien-être et que le curseur performance/rythme soutenable est difficile à trouver et change en fonction des personnes et de leurs contextes. Nous évoluons dans un système complexe dirait Pablo citant Edgar Morin.

Qu'il fallait du sens pour entretenir la motivation dans la durée et se sentir utile dans son travail au-delà de la technique. Les techniciens se transformant en virtuoses (artistes sans inspiration) dépérissent tôt ou tard.

Qu'il fallait du fun pour apprendre à collaborer — ou du moins à se connaître dans un premier temps — ce qui est rarement le cas dans la sphère du travail. « Connaissons-nous nous-même » aurait pu énoncer un Socrate moderne. Les jeux sérieux sont une première approche mais d'autres pratiques devraient permettre d'introduire du fun au quotidien de façon appliquée.

Qu'il fallait de la mixité pour pouvoir échanger entre domaines, entre entreprises, entre équipes, entre pays, entre cultures. La consanguinité des codeurs blancs trentenaires est malsaine et réductrice. Tous les domaines ont leurs pépites de collaboration, toutes les équipes on des moments de fun. Il suffit de savoir les raconter, les reproduire et les diffuser.

Est-ce que l'agilité est en contradiction avec l'artisanat ?

Se réclamer artisan et souscrire au manifeste pour un développement agile est alors paradoxal. L'artisan applique son savoir-faire, fait évoluer ses pratiques et ses outils notamment par une réflexion sur son métier, son activité. Utiliser un outil le prive d'une partie de son savoir-faire. Il doit donc toujours penser aux savoir-faire qu'il souhaite conserver, pour pouvoir les faire évoluer, et ceux qu'il accepte de déléguer à des outils, au risque d'en être dépendant.

Or, le rythme prescrit par le manifeste pour un développement agile encourage à gagner du temps, donc l'automatisation par laquelle le développeur perd des savoir-faire, sans forcément avoir le temps de choisir ceux qu'il veut garder ou non.

Pour moi le savoir-faire est orthogonal au savoir-collaborer, l'addition des deux pouvant mener au savoir faire ensemble. Je ne pense pas que l'on puisse arriver à une collaboration efficace à court terme et la délégation de ses outils signe la perte de son approche artisanale. Pour pouvoir combiner les deux, il faut avoir une vision à long terme. Accepter l'inefficacité, accepter la réappropriation des savoirs, tout en arrivant à survivre et à évoluer. C'est ce que l'on tente de faire avec scopyleft, expérience après expérience.

[logilab] A retrospective of 10 years animating the pylint free software projet

[afpyro] AFPyro à Lyon - le 25 septembre 2013

$
0
0

Un Afpyro aura lieu le mercredi 25 septembre à partir de 19h à l’Antre Autre - 11 rue Terme - 69001 Lyon.

Cette soirée de rentrée sera l’occasion de faire un apéro commun avec l’antenne locale de l’AFUP. Deux présentations seront donc faites : Python pour les développeurs PHP, et la présentation jumelle, Php pour les développeurs Python.

L’Antre Autre est un lieu où nous pouvons discuter autour d’un verre, et, pour ceux qui le souhaitent, prendre un repas.

Pour se rendre à l’Antre Autre :
  • en métro : arrêt Hôtel de Ville
  • en bus : lignes C13 et C18 arrêt Mairie du 1er ou lignes 19, C14 et C3 à l’arrêt Terreaux
  • en vélo’v : stations Place Sathonay, Carmélites Burdeau, Place de la paix

[afpyro] AFPyro à Paris, Mercredi 9 Octobre

$
0
0

Contexte

C’est l’AFPyro de rentrée. Un chouilla en retard. Venez vous raconter vos vacances!

Quand ?

Le Mercredi 9 Octobre à partir de 19h.

Où ?

La Grosse Caisse au 160 rue Montmartre, dans le 2ème arrondissement de Paris.

Voyez la carte Google

Viewing all 3561 articles
Browse latest View live