Qu'est ce qu'on se fait ch ... !

Aller au contenu | Aller au menu | Aller à la recherche

Accéder à des sites utilisant un certificat avec firefox 4

2294144289_a54db90ac5.jpg[1]

J'utilise depuis la première beta firefox 4. Ce dernier est excellent mais nécessite une petite adaptation pour accéder aux sites utilisant un certificat comme celui des impôts.

Je vais prendre pour exemple ce dernier. Si vous essayez de vous connecter à l'espace personnel avec un certificat, vous obtenez le message d'erreur suivant :

Selection_020.png

Après une recherche sur le bugzilla de firefox et sur le wiki, voici la configuration qu'il faut appliquer pour que cela fonctionne:

Selection_019.png

  • Entrer dans la barre d'adresse 'about:config'
  • Cliquer sur promis ...
  • Puis rentrer la clé 'security.ssl.allow'
  • Changer la valeur à true en cliquant sur la ligne

Redémarrez firefox et hop vous pouvez aller payer vos impôts :)

Dernier journée sur Porto

Chargement de la carte...

Et voila, les vacances tant attendues s'achèvent! Avec leur lot de bronzage et de kilos (beaucoup) en trop :)

Une vue de porto

Cette semaine sur Porto et ses environs m'a vraiment plu. D'abord les gens. Quand je suis parti de France, tout le monde m'a dit, ici tout le monde parle français et bien .... pas trop! Je suis parti avec toute ma petite famille à l'arrache, pensant que c'était vrai. Un guide de conversation franco-portugais fut rapidement indispensable.Néanmoins, en mixant quelques mots d'anglais, d'espagnol et de français, on arrivait à se faire comprendre dans les restaurants.

Concernant les autochtones, un des points que l'on m'avait dit était vrai : Les portugais sont serviables. Nous avons pris le train pour coimbra, et les enfants ont reçu de la nourriture pendant tout le trajet. Je crois qu'elles ont pris environ 1Kg / 100km :)

Ensuite, les paysages. Ils sont assez sympathiques. Nous n'avons pas beaucoup bougé de porto (barcelos et coimbra) mais nous avons pu néanmoins nous rendre compte des différents paysages. Ils sont souvent superbes.

Les plages sont également agréables. Le guide du routard conseille les plages du sud de porto. Nous sommes allés sur celles du nord. La première que nous avons essayé était bien protégée des courants par une digue mais n'était pas recouverte de sable mais de gravier! La seconde était plus agréable mais avec des vagues. J'oubliais, la température de l'eau en fait presque regretter le morbihan, tellement qu'elle est froide .

Enfin, en tout bon français qui se respecte, je vais parler de la bouffe. le guide du routard indique dans ses premières pages que les problèmes de santé majeurs au Portugal sont les maladies cardio-vasculaires. Et bien, je les crois!!! Les pastalaria sont légion. Les portugais mangent à toute heure des sandwichs énormes ou des pâtisseries qui sont aussi volumineuses que regorgeant de crème pâtissière ou de glaçage en tout genre.

Une vue de porto

Idem pour les restaurants. Ces derniers offrent la plupart du temps des plats énormes et bon marché (7€ pour une morue). Parmi les spécialités que j'ai gouté: les tripes,la petite française

et quelques spécialités de morue.[1]

Bref, je vous conseille vivement cette destination sauf, bien sûr, si vous faites un régime alimentaire strict ou que vous avez des problèmes de cholestérol :)

Notes

[1] Je ne les ai pas toutes goûtées, je vous rassure. il y en a plus de 365 :)

Dansons la samba avec le WDTV Live

Bon je sais le jeu de mots est des plus nazes douteux. Néanmoins, je vais tâcher d'expliquer le fonctionnement de mon dernier joujou dans mon réseau local et plus particulièrement avec mon os préféré debian ubuntu gnu/linux.

D'abord, voici l'engin : wdtv-live.jpg

Ce produit fonctionne très bien et s'intègre parfaitement dans un réseau via un port ethernet et boitiers CPL. Le protocole supporté est SAMBA. Avant toute chose, il convient de bien lire la doc relative à samba. Tout est dedans ! Cet article n'illustre que l'application avec le boitier WDTV.

Configuration du boitier en tant que disque dur réseau multimédia

Une fois installé un disque dur externe et le réseau activé, on peut accéder au boitier sans problème. Allez dans réseau et vous voyez apparaître l’icône suivante partage_reseau_tvlive.png

Il ne reste plus qu'à faire des copies de fichier via nautilus ...

Configuration en tant que client

Je peux aussi accéder directement au contenu de mon pc sans avoir à faire de copie depuis ce dernier. Il suffit de configurer le PC en serveur samba.

Exécuter la commande suivante :

$apt-get install samba smbfs  system-config-samba

Après aller dans le menu suivant

menu_samba.png











Puis sélectionner les répertoires à partager:

Configuration_du_serveur_Samba_016.png

Editer_un_partage_Samba_017.png

Pour ne pas trop me prendre la tête, j'ai mis les partages en lecture pour tous. Pas besoin de renseigner un identifiant/mot de passe coté boitier WD. Ce dernier me met quand même une mire d'identification que je renseigne avec le compte anonymous. On peut configurer le partage par ce menu :

Et me voila avec un beau disque dur multimédia réseau parfaitement intégré dans mon réseau local ! :D

Remarques :

  • On peut paramétrer le partage directement via le menu contextuel de nautilus
  • Pour la partie serveur, on peut installer un serveur UPNP tel que mediatomb.

Mon fichier .emacs

Me revoila sur emacs, le seul éditeur a voir une église secte. Je me lassais des éditeurs tels que gedit, geany ou notepad++ sous windows. A la différence d'il y a quelques années, je suis passé directement sur emacs et non xemacs. J'ai du créer un fichier de configuration pour avoir un comportement optimal ( pour moi )

(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(column-number-mode t)
 '(current-language-environment "Latin-1")
 '(show-paren-mode t)
 '(size-indication-mode t)
 '(uniquify-buffer-name-style (quote forward) nil (uniquify)))
(custom-set-faces
  ;; custom-set-faces was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 )

;; lilypond
(autoload 'LilyPond-mode "lilypond-mode")
(setq auto-mode-alist
      (cons '("\\.ly$" . LilyPond-mode) auto-mode-alist))

(add-hook 'LilyPond-mode-hook (lambda () (turn-on-font-lock)))

(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

; affichage des lignes
(global-linum-mode 1) 
(global-hl-line-mode 1)

;;
;; utf-8
;;
(setq locale-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

;;  	mode de suppression ( avec la touche DELETE )
(delete-selection-mode t)

Il ne me reste plus qu'une chose à résoudre sous windows la prise en compte des accents lors des copier coller vers emacs : ssse008.png

Créer et supprimer des services sous windows

Je vous vois déjà hurler : Putain il est devenu fou, il commence à mettre des billets liés à WINDOW$ sur son blog !!!

Mais bon, je galère à chaque fois sur le même sujet et il faut bien que je le note qq part et autant que cela serve à tout le monde ...

Dans un prompt CMD

Voici un exemple :

F:\temp>sc delete MonIDService
[SC] DeleteService SUCCESS

F:\temp>sc \\MonServeur create MonIDService binPath= "ma commande" DisplayName= "Display"
[SC] CreateService SUCCESS

warning.pngPour la création, il faut bien mettre un espace entre 'binPath=' et le chemin voulu !!

Utilisation des API Google

Dans le cadre de mon appli jsf sur gae, j'ai à interagir avec le service de calendrier google. Voici les actions que j'ai menées pour installer et faire fonctionner le bousin:

Installation du client GDATA dans le référentiel MAVEN

 $ mvn install:install-file -DgeneratePom=true -DgroupId=com.google.gdata -DartifactId=gdata-core
 -Dpackaging=jar -Dfile=gdata-core-1.0.jar -Dversion=1.0


$ mvn install:install-file -DgeneratePom=true -DgroupId=com.google.gdata -DartifactId=gdata-client
 -Dpackaging=jar -Dfile=gdata-client-1.0.jar -Dversion=1.0

 $ mvn install:install-file -DgeneratePom=true -DgroupId=com.google.gdata -DartifactId=gdata-calendar
 -Dpackaging=jar -Dfile=gdata-calendar-2.0.jar -Dversion=2.0



Ajout dans le fichier pom.xml

<dependency>
            <groupId>com.google.gdata</groupId>
            <artifactId>gdata-core</artifactId>
            <version>1.0</version>
        </dependency>
 
        <dependency>
            <groupId>com.google.gdata</groupId>
            <artifactId>gdata-client</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.gdata</groupId>
            <artifactId>gdata-calendar</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.collections</groupId>
            <artifactId>google-collections</artifactId>
            <version>1.0</version>
        </dependency>

Identification

La partie la plus subtile. Trois choix sont possibles, une authentification par token, par login/password et par openid. J'ai choisi de gérer le token car mon application va utiliser la gestion des comptes google.

J'ai choisi de créer une servlet qui fait les actions suivantes : Proposer une page qui redirige vers la connexion google, récupération du token et stockage en base pour chaque utilisateur.

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String tokenParameter = req.getParameter("token");
        if (tokenParameter == null) {
            req.getRequestDispatcher("/faces/retreiveToken.xhtml").forward(req, resp);
        } else {
            try {
//procedure google pour recuperer le token et le rendre permanent
                String onetimeUseToken = AuthSubUtil.getTokenFromReply(req.getQueryString());
                String sessionToken = AuthSubUtil.exchangeForSessionToken(onetimeUseToken, null);
                Logger.getLogger(TokenServlet.class.getName()).log(Level.INFO, "Token recupéré");
 
                UserManagedBean userManagedBean = (UserManagedBean) req.getSession(false).getAttribute("userManagedBean");
//assignation du token
                User user = userManagedBean.getUser(req);
                user.setToken(sessionToken);
//persistence
                BusinessService<User> userService = new BusinessServiceImpl<User>();
                userService.update(user, user.getId());
            } catch (GeneralSecurityException ex) {
                Logger.getLogger(TokenServlet.class.getName()).log(Level.SEVERE, null, ex);
            } catch (AuthenticationException ex) {
                Logger.getLogger(TokenServlet.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

La page de connexion est assez simple :

<ui:composition template="./standardtpl.xhtml">
            <ui:define name="content">
                <h:form prependId="false">
                    <p>MyApp needs access to your
                        Google Calendar account to read your Calendar feed. To authorize
                        MyApp to access your account,
                        <a href="#{userManagedBean.requestUrl}">Connexion sur google</a>
                    </p>
                </h:form>
            </ui:define>
        </ui:composition>

Le lien de connexion se crée de la manière suivante

public String getRequestUrl() {
        StringBuffer request = new StringBuffer(FacesContext.getCurrentInstance().getExternalContext().getRequestScheme()).append("://").append(FacesContext.getCurrentInstance().getExternalContext().getRequestServerName()).append(":").append(FacesContext.getCurrentInstance().getExternalContext().getRequestServerPort()).append("/tokenServlet");
        return AuthSubUtil.getRequestUrl(request.toString(),
                "http://www.google.com/calendar/feeds/",
                false,
                true);
 
    }

Conclusion

Je m'arrêterai la dans les exemples car la documentation est déjà bien détaillée sur ce sujet. Quoi qu'il en soit, je trouve que chez google, a défaut d'oeuvrer pour les données privées de ses utilisateurs, il savent très bien faire des API et les documenter :)

Seule limitation, la possibilité de faire des tests unitaires avec le token. La gestion du retour avec un proxy n'est pas possible (menfin à ce que j'ai vu ...)

spotify vs wine vs ubuntu 10.04 vs M-audio audiophile 24/96

Je sais ca fait beaucoup pour un combat. On se dirait presque dans expandables.

Quand vous installez wine et que vous voulez avoir le son pour écouter spotify ( en version gratuite ) par exemple avec votre superbe carte son m-audio audiophile 24/96, vous obtenez le mesage d'erreur suivant :

fixme:mixer:ALSA_MixerInit No master control found on M Audio Audiophile 24/96, disabling mixer

La solution réside dans Jack L'installation est assez simple

$sudo apt-get install jack-tools qjackctl alsa-tools

Après lancez qjackct en ligne de commande ou par le menu Applications> Son & Vidéo > JACK Control

J'ai mis la configuration ( très basique j'en conviens ) suivante :

Selection_011.png

Selection_012.png







Ensuite, cliquez sur "Connecter"

Selection_010.png

Puis sélectionnez system dans chaque panneau Selection_007.png

Vous devriez obtenir l'écran suivant :

Selection_008.png

Après dans un terminal lancez l'écran de configuration de wine :

$winecfg

Allez dans l'onglet Son et sélectionnez Jack comme moteur de son :

Selection_009.png

Et maintenant vous pouvez jouer à vos jeux favoris, écouter spotify ... mais le son passant par pulseaudio ne fonctionne malheureusement pas :-(

Si vous voulez avoir le son dans firefox ,rhythmbox, ou dans toute application utilisant pulseaudio, vous devrez malheureusement fermer l'outil JACK Control.

Write once , run everywhere ... sauf sur google app engine

Après la mise à jour des différents composants ( GAE #1.3.5 , primefaces 2.1RC1, ...) me voila reparti à re-développer une appli sur GAE. Après quelques galères tests unitaires, j'ai pu me rendre compte des nombreuses limitations à JPA / GAE.

Les requêtes

D'abord, seul JPA V1 est implémenté. Ça a l'air con comme ca, mais par exemple on ne peut pas utiliser les CriteriaQuery alors que l'API JDO fournie par Google fournit les Filter.Après , me direz vous, c'est pas l'extase, ca ne fait pas exactement la même chose, on peut coder directement les critères en JPQL. Mais voila dès que vous voulez faire des recherches un peu larges avec par exemple un formulaire de recherche à critères multiples, vous pouvez obtenir l'erreur suivante :

testcase: testFindLike(info.touret.mycellar.test.BottleTest):        Caused an ERROR
Problem with query <SELECT A FROM info.touret.winecellar.pojo.Bottle A WHERE A.name like 'BOUTEILLE%'  or A.vintage like '2001%'>: Or filters cannot be applied to multiple properties (found both name and vintage).
org.datanucleus.store.appengine.query.DatastoreQuery$UnsupportedDatastoreFeatureException: Problem with query <SELECT A FROM info.touret.winecellar.pojo.Bottle A WHERE A.name like 'BOUTEILLE%'  or A.vintage like '2001%'>: Or filters cannot be applied to multiple properties (found both name and vintage).
        at org.datanucleus.store.appengine.query.DatastoreQuery.addLeftPrimaryOrExpression(DatastoreQuery.java:1131)
        at org.datanucleus.store.appengine.query.DatastoreQuery.addLeftPrimaryExpression(DatastoreQuery.java:1105)
        at org.datanucleus.store.appengine.query.DatastoreQuery.addPrefix(DatastoreQuery.java:931)
        at org.datanucleus.store.appengine.query.DatastoreQuery.handleMatchesOperation(DatastoreQuery.java:891)
        at org.datanucleus.store.appengine.query.DatastoreQuery.addExpression(DatastoreQuery.java:864)
        at org.datanucleus.store.appengine.query.DatastoreQuery.addExpression(DatastoreQuery.java:835)

Un peu bête ...

Les jointures et fetching

Sur ce sujet, je me suis arraché les cheveux pas mal de temps. Exemple : ne Jointure OneToMany ne me ramenait pas du tout les entités en question lors d'un select. Que faire ?? Après quelques recherches sur la toile, je me suis rendu à l'évidence, que GAE ne gérait que les jointures via les clés primaires. Oubliez les belles jointures bi directionnelles et uni directionnelles JPA . L'insertion , la modification ne peut s'effectuer que par les clés primaires

Exemple avec une relation onetoone

@OneToOne(cascade = {CascadeType.REFRESH})
    private Key producer;

Mais il est possible de "hacker" la matrice en rajoutant un autre attribut à notre classe qui aurait la configuration suivante :

@OneToOne(cascade = {CascadeType.REFRESH})
    @Column(name = "producer", insertable = false, updatable = false)
    private Producer producerAlias;

Donc pour les insertions, suppressions, nous sommes obligés de passer par l'instance de la classe Key, par contre, une sélection passerait par l'alias. Cette manipulation permet de gérer la jointure ( avec fetch !) directement au niveau de la requête JPQL.

Exemple :

Query query = em.createQuery("select from Bottle b join b.producerAlias");

C'est un peu biaisé, mais bon ca simplifie la vie au niveau des requêtes.

Après, ce n'est que mon avis, je me suis trouvé pas mal obligé de dé-normaliser mes relations entre entités. Par exemple, je me suis mis dans l'idée de faire un nuage de tags. Bien au lieu de créer un pojo tag qui serai persisté directement dans big table, j'ai préféré créer un attribut tagline pour mon entité maître. Ca m'a pris moins de temps à créer. après va falloir que j'optimise les requêtes par une gestion de cache par exemple.

Conclusion :

Quand on développe sur GAE, il faut à mon avis bien penser aux contraintes de cette plateforme, surtout sur la persistance des données. Le développeur JAVAEE habitué à hibernate/jpa peut vite pédaler dans la choucroute au début. A mon avis ( et pas que ) JDO est à préférer. l'API semble connaître moins de limites.

Pas mal de plaintes on été faite à ce sujet. Je viens de voir un article sur une recherche full text. A voir ...

Et non je n'ai pas changé

Après quelques jours semaines mois passés à faire autre chose ... mais faut bien vivreeeee.... moi voila revenu sur mon projet de cellier numérique et regardez l'erreur maven que j'obtiens :

Copying webapp resources[D:\java\src\my-cellar\src\main\webapp]
------------------------------------------------------------------------
[ERROR]FATAL ERROR
------------------------------------------------------------------------
Negative time
------------------------------------------------------------------------
Trace
java.lang.IllegalArgumentException: Negative time
        at java.io.File.setLastModified(File.java:1258)
        at org.apache.maven.plugin.war.packaging.AbstractWarPackagingTask.copyFile(AbstractWarPackagingTask.java:295)
        at org.apache.maven.plugin.war.packaging.AbstractWarPackagingTask$1.registered(AbstractWarPackagingTask.java:150)

Si c'est pas un signe pour que je parte en week end....

J'aime pas le jazz mais ca j'aime bien.... (2)

Dans la série je n'aime pas le jazz, mais ca je trouve ca plutôt sympa: Kind of Blue de Miles Davis. Ce disque est un monument de la musique. Généralement, si vous rentrez dans un magasin de musique et que vous demandez à un vendeur un cd de jazz pour vous initier, s'il ne vous aiguille pas sur une compil, il y a de fortes chances qu'il vous tende ce cd.

Dans cet album, vous retrouverez pas mal de standards tels que "So What" ou "All Blues". Les musiciens accompagnant Miles Davis dans son quintet sont même devenus des légendes du Jazz ( John Coltrane, Bill Evans, Cannonball Aderley)

A écouter !!!

So What

All Blues

- page 1 de 25