Mon premier pitch en D1A en Mars 1994
Mot de passe :
Accueil | 
Résultat de la recherche pour Mai 2007
30/05/2007
Microsoft Surface, la table tactile de demain, aujourd'hui

Microsoft vient de dévoiler son nouveau projet, non pas un soft mais une table tactile, Surface. Il s'agit d'un écran de 30 pouces, capable d'interagir avec des objets communicants (appareil photo par exemple) grâce à des caméras infra rouges. Son interface utilisateur, très novatrice permet de manipuler des objets virtuels (photos, documents) mais également offre de nouveaux loisirs numériques (peinture par exemple).

Le site de Microsoft Surface montre bien les possibilités de ce produit tout droit issu des laboratoires de recherche de Microsoft.

Je suis toujours frappé par la capacité de Microsoft à mettre l'avenir à porter de main et surtout à transformer les résultats de leurs recherches au profit d'outils futuristes et surtout réalistes. Disponible fin 2007 à un prix réservé aux entreprises (Hotels, casinos...)

Microsoft Surface

Mots clés associés : Microsoft Surface Milan  | Lien permanent | Laissez le premier votre commentaire
Publiée dans la zone Technologies
29/05/2007
Starwars Clone wars, c'est pour 2008

Annoncé depuis longtemps, LucasFilm vient de livrer le trailer de la série télévisée Clone Wars qui sera diffusée aux Etats Unis en 2008. Se situant entre l'épisode II et III, vous retrouverez certains personnages connus comme le Général Grievous ou le Comte Dooku, mais également quelques autres tirés de la série animée.

Lire la bande annonce officielle.

 

Le résultat est assez bluffant. On y retrouve à la fois l'esprit du film et la touche graphique de la série animée qui a mon gout manquait sérieusement de rythme.

Mots clés associés : Starwars Clone wars  | Lien permanent | Laissez le premier votre commentaire
Publiée dans la zone Starwars
21/05/2007
Générer un flux RSS avec ASP.Net

Droit de diffusion:
L'ensemble ou partie de ce document ainsi que le code mis à disposition, ne peut être diffusé sur d'autres sites Web sans l'autorisation au préalable de son créateur.

Avant Propos :
Initié par Netscape, le rss est un moyen simple d’ouvrir le contenu de votre site autrement que par l’utilisation de XML WebServices. Ce tutoriel a trois objectifs :

  • Vous fournir gratuitement les sources du générateur de flux rss
  • Vous montrer comment il fonctionne
  • Découvrir surtout la simplicité par laquelle on génère un flux XML avec .net

N’hésitez pas à télécharger les sources. Ce tutoriel a été réalisé en Aout 2004 sur le Framework 1.1 et est toujours d'actualité avec le Framework 2.0. Plus trop avec le Framework 3.5 !!!

 

Sommaire:

1. Le constructeur de flux RSS
2. La génération du flux rss
3. En Savoir plus

1. Le constructeur de flux RSS

Le projet rss dispose de 3 structures qui permettent de construire proprement les données qu’attendent le flux rss.

enum_langue est une énumération de codes langues afin d’éviter l’insertion de données un peut trop exotiques.

struct_entete alimente les données de base du flux rss comme l’url du site, l’éditeur et éventuellement l’image d’accompagnement structurée dans struct_image.

struct_detail s’articule autour des publications à exposer.




La méthode builder va nous permettre de construire le flux rss qui sera exposé dans le Page.Response.Output de la page ASPX.



Ma méthode ConstruitRss fabrique le corps du flux XML.

WriteStartDocument() me permet de démarrer mon document XML.

WriteStartElement({MonElement}) construit un nœud sur lequel je peux ajouter un attribut avec WriteAttributString({MonAttribut},{SaValeur}).



La méthode AjoutePublication permet l’insertion d’un item rss. Les données sont passées dans la variable p_datas. On utilise toujours WriteStartElement() et WriteElementString() pour ajouter un nœud fils.

N’oublions pas le WriteEndElement() pour fermer le nœud.



Enfin, la méthode FinDuDocument() clôt les différents nœuds et le document XML.

2. La génération du flux rss

Le moment est venu de générer le flux rss.

Afin que votre flux soit accessible depuis l’url http://MonSite/rss, créer une page index.aspx qui devra être définit comme page par défaut du répertoire dans les paramètres IIS.

Pour la démonstration, nous avons créé une page rss.aspx. Commencez par supprimer toutes les données HTML de la page générée par VisualStudio.net.



Comme souvent, c’est dans le Page_Load que tout ce passe. Notez le codage du rss en ISO-8859-1 afin de tenir compte des caractères étendus utilisés dans la langue française.

On spécifie un retour de la requête sous forme text/xml.

J’alimente ensuite mes données dans ma structure d’entête. Je préfère utiliser une structure plutôt que de passer n arguments à ma méthode. Si par malheur vous aviez oublié de passer un argument, vous seriez obligé de modifier tous les appels. La structure s’avère plus souple dans le cadre de la maintenance de votre code source.

On créé alors une nouvelle instance de l’objet builder qui sera exposée en réponse http et on appelle la méthode ConstruitRss avec les données de l’entête.



Viens maintenant l’ajout des items ou publications. J’alimente toujours une structure, celle du détail et d’invoque la méthode AjoutePublication().

Ne surtout pas oublier la méthode FinDuDocument() qui va clôturer le flux rss.

Et c’est tout ! Votre flux rss est maintenant publié en un temps record.

3. En Savoir plus

RSS sur XML.FR
http://xmlfr.org/actualites/tech/000816-0001

RSS Reader, freeware développé sur le framework .net
http://www.rssreader.com
Mots clés associés : RSS ASP.Net c# Microsoft  | Lien permanent | Laissez le premier votre commentaire
Publiée dans la zone Tutoriels .Net
18/05/2007
Mes statistiques personnelles

J'ai enfin remis la main sur mes stats de baseball. J'ai eu l'occasion de jouer la plupart de ma carrière à Montigny le bretonneux (Mont) et au Paris Université Club (Puc).

Les trous indiquent que les données ne sont pas disponibles. J'aurai l'occasion plus tard de revenir sur chaque saison en détail. Stay tuned.

Batting

YR TEAM DIV G TAB AB R H 2B 3B HR RBI SAC BB HP K SB CS IO AVG OBP SLG
1989 Mont PHR 8 28 23 11 8 0 0 0 5 1 4 0 7 14 0 0 .348 .429 .348
1990 Mont PHR 8 31 30 12 16 5 0 0 13 0 1 0 5 16 0 0 .533 .548 .700
1991 Mont PHR 7 25 21 10 8 2 0 0 7 1 3 0 3 19 0 0 .381 .440 .476
1992 Puc                                        
1993 Puc                                        
1994 Mont D1A 7 14 10 2 0 0 0 0 1 2 2 0 3 1 0 0 .000 .143 .000
1994 Mont D2 8 27 24 5 9 1 0 0 6 1 1 1 6 3 1 0 .375 .407 .417
1995 Puc                                        
1996 Puc                                        
1997 Mont D1B 11 12 11 1 4 0 0 0 1 0 0 1 4 1 1 0 .364 .417 .364
1998 Mont D1B 7 20 17 3 4 1 0 0 1 0 0 2 5 0 1 0 .235 .300 .294
1999 Mont ELITE 1 1 1 0 1 1 0 0 1 0 0 0 0 0 0 0 1.000 1.000 2.000
2000 Mont eREG 2 4 3 2 1 0 0 0 0 0 0 1 1 0 0 0 .333 .500 .333
2001 Mont eREG 11 46 41 13 11 1 0 0 9 0 5 0 6 3 2 0 .268 .348 .293
2001 Mont N2 1 3 3 0 0 0 0 0 0 0 0 0 0 0 1 0 .000 .000 .000
                                           
      71 211 184 59 62 11 0 0 44 5 16 5 40 57 6 0 .337 .393 .397

Pitching

YR TEAM DIV G W L SV IP TAB AB R ER H 2B 3B HR SAC HP BB K ERA oAVG
1990 Mont PHR                                      
1991 Mont PHR                                      
1992 Puc                                        
1993 Puc                                        
1994 Mont D1A 5 0 3 0 14 105 61 35 27 17 4 2 1 0 2 42 9 17.36 .279
1994 Mont D2 7 4 2 0 37 189 152 45 24 31 7 1 0 0 1 36 40 5.79 .204
1995 Puc D1A 2 0 0 0 3.1 20 14 4 4 5 1 0 1 0 0 6 5 10.80 .357
1995 Puc D1B 2 0 1 1 8 31 22 7 3 5 2 0 0 3 3 3 7 3.38 .227
1996 Puc D1B 1 0 0 0 0 2 0 2 2 0 0 0 0 0 0 2 0   .000
1996 Puc D2 2 1 1 0 5 30 21 9 4 7 0 0 0 0 0 9 8 7.20 .333
1997 Mont D1B 16 4 6 1 63 341 272 88 39 76 12 9 5 0 2 67 47 5.60 .279
1998 Mont D1B 6 1 1 1 18 99 79 27 14 22 4 3 1 0 2 18 9 6.87 .278
1999 Mont ELITE 7 1 2 0 18 88 67 24 20 28 8 0 3 1 1 19 6 10.00 .418
2000 Mont eR 2 0 1 0 6.2 37 29 18 9 13 1 1 0 1 0 7 8 12.15 .448
2001 Mont eR 11 5 4 2 65 320 269 73 29 70 8 3 1 1 2 48 62 4.04 .260
2001 Mont N2 1 0 0 0 5 29 24 9 4 11 2 1 0 0 1 4 4 7.20 .458
      62 16 21 5 243 1291 1010 341 179 285 49 20 12 6 14 261 205 6.63 .282
Mots clés associés : Baseball Montigny Cougars  | Lien permanent | 1 Commentaire
Publiée dans la zone Laurent, joueur de baseball
17/05/2007
Mon Portail : CustomControl d'encadrement de vos formulaires et éléments

Les éléments graphiques du portail sont inclus dans un encadrement aux cotés arrondis. Cet encadrement peut prendre plusieurs couleurs et afin d'optimiser les développements j'ai réalisé un CustomControl très simple qui permet d'y inclure vos éléments. Nous allons donc voir comment ce CustomControl est utilisé dans l'interface graphique, ces implications au niveau des feuilles de style et la construction du CustomControl.

1. Utilisation du CustomControl

<elgee:Frame ID="FR12" runat="server" Couleur="jaune" Taille="275">

    <div class="billet_titre">Rechercher sur ce site</div><br />

    <div id="container_search_controls">

        <div id="google_search_form"></div>

        <div id="google_search_control"></div>

        <div id="live_search_container">

            <div id="live_search_query"></div>

            <div id="live_search_control"></div>   

        </div>

    </div>

</elgee:Frame>

Je prend l'exemple de la zone de recherche. Mon CustomControl s'appelle Frame et comme vous pouvez vous en rendre compte il inclut des éléments externes en son sein. Il dispose de 2 attributs, sa taille et la couleur à appliquer.

2. La gestion de l'apparence

On se basera donc sur une feuille de style. En se basant sur la valeur de l'attribut Couleur, on déclinera l'ensemble des éléments nécessaires au rendu graphique de l'encadrement.

.jaune_haut_gauche      {border-style: none; width:12px; height:21px; background-image: url(/App_themes/default/pics/box/jaune/haut_gauche.png);background-repeat: no-repeat; line-height:0; font-size:0;}

.jaune_haut             {border-style: none; height:21px; background-image: url(/App_themes/default/pics/box/jaune/haut.png);background-repeat: repeat-x; line-height:0; font-size:0;}

.jaune_haut_droite      {border-style: none; width:14px; height:21px; background-image: url(/App_themes/default/pics/box/jaune/haut_droite.png);background-repeat: no-repeat; line-height:0; font-size:0;}

.jaune_gauche           {border-style: none; width:12px; background-image: url(/App_themes/default/pics/box/jaune/gauche.png);background-repeat: repeat-y; line-height:0; font-size:0;}

.jaune_contenu          {border-style: none; background-color: #FFFFCC;}

.jaune_droite           {border-style: none; width:14px; background-image: url(/App_themes/default/pics/box/jaune/droite.png);background-repeat: repeat-y; line-height:0; font-size:0;}

.jaune_bas_gauche {border-style: none; width:12px; height:21px; background-image: url(/App_themes/default/pics/box/jaune/bas_gauche.png);background-repeat: no-repeat; line-height:0; font-size:0;}

.jaune_bas              {border-style: none; height:21px; background-image: url(/App_themes/default/pics/box/jaune/bas.png);background-repeat: repeat-x; line-height:0; font-size:0;}

.jaune_bas_droite {border-style: none; width:14px; height:21px; background-image: url(/App_themes/default/pics/box/jaune/bas_droite.png);background-repeat: no-repeat; line-height:0; font-size:0;}

Il y a donc une classe pour chaque coin de l'encadrement, pour chaque coté et le contenu. La règle de nommage consiste à commencer par le nom de la couleur, suivi de sa localisation. Comme vous le voyez, j'ai choisi un format PNG, qui gère mieux la transparence que le GIF. Mais attention aux surprises sur les navigateurs de type IE6 qui ne gère pas la transparence du format PNG.

3. Le code du CustomControl

Dans les attributs de la classe du CustomControl on définit la propriété par défaut et l'apparence coté designer en indiquant le nom du tag, ici Frame. Ne pas oublier les accesseurs publiques des propriétés.

   [DefaultProperty("Taille"), ControlValueProperty("Taille"), PersistChildren(true), ParseChildren(false),

   ToolboxData("<{0}:Frame runat=server></{0}:Frame>"), PersistenceModeAttribute(PersistenceMode.InnerProperty),

 Designer(typeof(System.Web.UI.Design.ContainerControlDesigner))]

    public partial class Frame : System.Web.UI.WebControls.WebControl

    {

        public int Taille

        {

            get { return _taille; }

            set { _taille = value; }

        }

        public string Couleur

        {

            get { return _couleur; }

            set { _couleur = value; }

        }

        private string _couleur = "blanc";

        private int _taille = 200;

        int _width = 0;

Il est ensuite nécessaire de surcharger les deux méthodes RenderBeginTag et RenderEndTag pour ajouter notre code. Vous noterez que la taille fournie au CustomControl est la taille totale, à laquelle je retire 26, car mes deux bordures ont 13 pixels de large. J'opte plutôt pour une table, plus fiable qu'un DIV dans ce cadre là.  

        public override void RenderBeginTag(HtmlTextWriter writer)

        {

            base.RenderBeginTag(writer);

            //Controls.Clear();

            _width = _taille - 26;

writer.AddStyleAttribute(HtmlTextWriterStyle.Width, _taille.ToString() + "px");

            writer.AddAttribute("cellpadding", "0");

            writer.AddAttribute("cellspacing", "0");

            writer.AddAttribute("border","0");

            writer.RenderBeginTag("table");     // Table container

            writer.RenderBeginTag("tr");        // TR de la premiere ligne

            writer.AddAttribute("class", _couleur + "_haut_gauche");

            writer.RenderBeginTag("td");

            writer.RenderEndTag();

            writer.AddAttribute("class", _couleur + "_haut");

writer.AddStyleAttribute(HtmlTextWriterStyle.Width, _width.ToString());

            writer.RenderBeginTag("td");

            writer.RenderEndTag();

            writer.AddAttribute("class", _couleur + "_haut_droite");

            writer.RenderBeginTag("td");

            writer.RenderEndTag();

writer.RenderEndTag();          // Fin du TR de la premiere ligne

            writer.RenderBeginTag("tr");        // TR de la seconde ligne

            writer.AddAttribute("class", _couleur + "_gauche");

            writer.RenderBeginTag("td");

            writer.RenderEndTag();

            writer.AddAttribute("class", _couleur + "_contenu");

writer.AddStyleAttribute(HtmlTextWriterStyle.Width, _width.ToString());

            writer.RenderBeginTag("td");

        }

        public override void RenderEndTag(HtmlTextWriter writer)

        {

            writer.RenderEndTag();

            writer.AddAttribute("class", _couleur + "_droite");

            writer.RenderBeginTag("td");

            writer.RenderEndTag();

writer.RenderEndTag();          // Fin du TR de la seconde ligne

            writer.RenderBeginTag("tr");        // TR de la troisieme ligne

            writer.AddAttribute("class", _couleur + "_bas_gauche");

            writer.RenderBeginTag("td");

            writer.RenderEndTag();

            writer.AddAttribute("class", _couleur + "_bas");

writer.AddStyleAttribute(HtmlTextWriterStyle.Width, _width.ToString());

            writer.RenderBeginTag("td");

            writer.RenderEndTag();

            writer.AddAttribute("class", _couleur + "_bas_droite");

            writer.RenderBeginTag("td");

            writer.RenderEndTag();

writer.RenderEndTag();          // Fin du TR de la premiere ligne

            writer.RenderEndTag();          // Fin de la table

            base.RenderEndTag(writer);

        }

    }  

Le tour est joué, votre CustomControl d'encadrement est fait. Reste plus qu'a jouer sur le panel de couleurs disponibles dans les feuilles de styles. Pour plus de fiabilité, on peut s'appuyer sur une énumération pour la liste des couleurs.

Mots clés associés : ASP.Net Tutoriel CustomControl Microsoft c#  | Lien permanent | Laissez le premier votre commentaire
Publiée dans la zone Technologies
16/05/2007
Mon Portail : Architecture globale

Nous allons voir ici l'architecture du portail en détail en insistant sur les principes de fonctionnement. La complexité des fichiers de paramétrage de SharePoint (qui soit dit en passant fait bien plus de choses que mon portail) a été une source d'inspiration pour concevoir l'architecture de cette application. Je vais donc vous expliquer comment les données sont hiérarchisées avec l'implication sur l'interface graphique, le modèle de paramétrage des différents espaces pour finir sur les multiples capacités de personnalisation du portail.

1.Hiérarchie des données

1.1. Un SiteMap issue de la base de données

J'ai décidé de m'appuyer sur un SiteMap pour la hierarchisation de mes informations, stocké en base. Un SqlSiteMapProvider a été utilisé pour obtenir les informations qui s'étalent sur 3 niveaux :

  • Niveau 0, la home page
  • Niveau 1, les espaces principaux
  • Niveau 2, les sous espaces

Structure du siteMap

 

Chaque élément de publication sera alors disposé dans un élément de niveau 2 obligatoirement. Les ID des espaces sont des entiers classés, c'est à dire qu'une requête en classant par ID vous donne automatiquement l'arborescence sans avoir à faire de la récursivité, gourmande en ressources. Le défaut est l'impossibilité de déplacer le moindre élément, contrainte que j'ai accepté dans ce développement.

L'ID du SiteMap ne sert qu'a simplifier le rendu. Chaque espace et sous espace dispose d'un raccourci. Ici le nom du raccourci est ACTIVITE.

L'interface graphique, au niveau de la navigation est alors générée automatiquement. Les zones à gauche et à droite de la liste des espaces de niveau 2 sont disposés dans un fichier de paramétrage. Il s'agit d'un fichier XML qui décrit les données à afficher à gauche et à droite en fonction du raccourci d'un espace de niveau 1.

Extrait du fichier XML

1.2. Le pilotage de la zone de navigation

C'est au niveau de la classe qui dévire de MasterPage que le calcul de la localisation dans l'application se fait. En fonction de l'Url, l'application saura si elle se trouve sur la HOMEPAGE ou dans un espace de niveau 1 ou 2 connu. En fonction de l'espace de niveau 0 ou 1, l'application affichera automatiquement la bonne zone de navigation par défaut. Une variable de contexte est disponible également pour qu'au niveau du code on sache exactement dans quelle zone on se trouve. Cette donnée est vitale car elle permet d'afficher les bonnes données au bon endroit.

1.3.Le raccourci en cours, clé de la variation du contenu

C'est une variable d'environnement, disponible dans les classes dérivées de MasterPage, Page et UserControl qui permet coté serveur de savoir dans quelle espace on se trouve. La hiérarchie est ici respectée. Dans un espace de niveau 2, le plus bas, on ne disposera que des éléments de contenu de ce niveau. Par contre, dans un espace de niveau 1, on restitue l'ensemble des données de niveau 2 qui lui sont dépendants. Au niveau 0, sur la home page, c'est l'ensemble des données de niveau 2 qui est restitué.

1.4. La hierarchie conservée dans le contenu

Au sein de chaque espace, la hiérarchie du contenu est conservée au niveau des nuages de mots clés, du flux rss, des flux externes et des billets.

2. Le paramétrage des espaces

Comme je vous l'ai expliqué précédemment, chaque espace dispose d'une signature. Pour chaque signature, on trouvera un fichier XML de configuration qui lui est propre. Ce fichier décrit les UserControls à afficher et leurs localisations

2.1. La MasterPage, coeur de la disposition

On utilise ici la nouveauté du Framework 2.0 qu'est la masterPage. Schématiquement, il y a 4 zones dans la page :

  • Le haut de l'interface
  • Le contenu, au centre
  • La zone de droite
  • Le bas de page

Chaque zone est en fait un ContentPlaceHolder dans lequel les contrôles de base sont incorporés. Pour chaque zone, on dispose en plus de deux autres ContentPlaceHolder qui permettent d'intégrer dynamiquerment des UserControls dynamiquement. Dans les faits, la plupart des pages est vide, et c'est le paramétrage des espaces qui détermine le contenu.

2.2. Le fichier XML de paramétrage de l'espace

Lorsqu'une page est appelée, une variable de contexte détermine l'espace en cours et la signature de la page. Par défaut, il y a 4 signatures :

  • DEFAUT, c'est à dire la page récapitulative
  • VOIR, lorsque l'on visualise un billet particulier
  • TAG, pour le résultat d'une recherche par mot clé
  • ARCHIVES, lorsque l'on demande les publications d'un mois donné

Etant donné qu'il existe un fichier de paramétrage XML par espace, il est alors chargé dynamiquement puis désérialisé. Cela permet ensuite en fonction de la signature disponible dans le contexte, de charger dans chaque zone les UserControls adéquates. Il est aussi possible d'ajouter du code statique au dessus de la barre de navigation, personnalisant un peu plus le portail. Le thème peut aussi être affecté à l'espace. Il est indiqué dans la table du SiteMap et sera automatiquement appliqué. Il s'agit ici ni plus ni moins de l'exploitation de la notion de Theming d'ASP.Net 2.0.

Fichier XML de paramétrage d'un espace

Il est possible de passer des paramètres au UserControl non pas via une Interface mais via une Collection d'objets. La seule contrainte est de faire dériver tous ces UserControls de Business.Page.UserControl. Dans l'exemple ci dessus, sur la page principale de mon espace et dans la zone de droite, je charge 5 UserControls que je place avant ou après les contrôles standards de ma page définis dans le default.aspx.

2.3. La réécriture d'URL

L'application se limite donc à 6 pages ASPX ! Une page par signature, plus la homepage et les flux rss du site. Tout cela est fait grâce à l'implémentation du module UrlRewriter, légèrement retouché pour fonctionner avec Ajax. La réécriture transforme un chemin en arguments dans la requete HTTP vers une page destinatrice. Les efforts ont été fait pour veiller à la sécurité des données issues de l'interprétation de la réécriture d'Url. J'ai trouvé un autre module de réécriture qui m'a l'air plutôt complet.

3. Des capacités de personnalisation entières

3.1. La notion de liste

Restant fidèle à SharePoint, j'ai conservé cette notion de liste. Une liste est un ensemble d'informations ordonnées, comme un album de photos, un flux rss, un billet. Une table unique regroupe ces listes, simplifiant grandement la couche d'accès aux données et permettant une grande évolutivité.

3.2. Le module de lecture de flux RSS

Le portail dispose d'un module AJAX permettant la lecture d'un flux RSS externe, transformé via une feuille XSL. Pensant au départ faire la transformation coté client, je suis vite tombé sur les contraintes de sécurité et de CrossSiteScripting. La transformation est générée coté serveur et renvoyée ensuite au client.

3.3. Intégration de pages personnalisées

Il est bien entendu possible d'ajouter ces propres pages. Il suffit à l'initialisation de définir manuellement la signature et l'espace ! Vous aurez la possibilité d'ajouter une nouvelle signature à votre fichier de configuration pour que votre page charge dynamiquement des contrôles. Les pages spécifiques sont placés dans un chemin particulier (/specific) pour conserver la cohérence applicative.

3.4. L'interaction sur les META tags

Les META tags sont bien entendu alimentés sur le portail. Un certain nombre de UserControls interagissent sur les contenu des tags :

UserControls keywords description
Nuage de mots clés ajoute les mots clés x
Résultat de la recherche par tag x Modifie la description
Résultat de la recherche par archive x Modifie la description

4. Les sources

Les sources sont utilisables et modifiables gratuitement pour toute personne physique. Faites moi part de votre souhait d'obtenir les sources. Je me ferai un plaisir de vous les faire parvenir. Pour les entreprises, me consulter par email.

 

Mots clés associés : Microsoft c# ASP.Net Portail  | Lien permanent | Laissez le premier votre commentaire
Publiée dans la zone Technologies
14/05/2007
Stadeo.tv, la bonne idée, mais un business model plutôt risqué

Stadeo.tv, la chaîne des sports délaissés par les grands diffuseurs a été lancée ce week end avec un match de baseball du championnat de France Elite de très bon niveau. J'ai toujours fait partie de ceux qui ralaient de ne jamais voir de baseball dans les grands medias. Les temps ont changé : NASN est diffusée sur le bouquet Canal Satellite avec des commentaires en VO, mlb.com propose une multitude d'abonnements pour visionner des rencontres via internet en excellente qualité.

Premières impressions de Stadeo.tv : D'abord, le player a télécharger ! Plutôt surpris de ne pas utiliser un player "standard" de type RealPlayer ou Windows Media Player. Une qualité pleine écran plutôt moyenne, des commentaires qui tiennent la route, une réalisation plutôt bonne avec de bons ralentis mais un manque cruel d'images en infield, là ou se joue vraiment le baseball. On ne peut pas tout avoir et c'est je pense une question de moyens.

Stadeo était donc gratuit ce week end et il vous en coutera près de 8 € pour visualiser un match !!! C'est là que tout le business model tombe à l'eau. A titre de comparaison, un mois d'abonnement sur mlb.com coute 15 $ pour une bonne centaine de rencontres et une tripotée de caméras qui sont prètent à prendre sous tous les angles les home runs de Barry Bonds !!!

Aujourd'hui, la qualité du baseball français est au rendez vous, il n'y a pas de doute. Mais je connais peu de monde prêt a payer aussi cher. Une étude du Cabinet Forrester prévoit un pic des ventes de films et d'émissions sur les sites de videos en ligne payants pour 2007. La tendance est au gratuit et cela se confirme déjà. YouTube intègre de la pub dans ces videos, et l'arrivée prochaine de Joost tendrait à révolutionner les pratiques. Les 45 millions de dollars levés par Joost devraient aider.

L'avenir est donc au gratuit et j'ai peur que l'aventure Stadeo.tv soit éphémère. Selon Forrester, toujours, 9% des adultes ont achetés pour une moyenne de 14$ de videos sur Internet en 2006. Avec à la louche une populations de 10 000 personnes sensibles au baseball, ça fait une cible et un potentiel de revenus assez limité, bien que stadeo propose également la diffusion de football américain et de hockey.

Le modèle idéal serait de proposer un portail de rencontres sportives, dont la réalisation serait faite par les utilisateurs eux mêmes. Un portail mélant trucs et astuces de montage videos, vente de matériel, dépots des matches locaux, ouverture sur Joost...Voilà une belle idée de portail communautaire, financé par les revenus des ventes de matériel vidéo, de la pub et pourquoi pas de véritables rencontres produites par des professionnels...

Pour ceux que Joost intéresse, j'ai quelques invitations. Laissez moi un commentaire. Je ferai mon possible pour vous les envoyer.

Mots clés associés : Joost Stadeo Baseball VOD  | Lien permanent | 1 Commentaire
Publiée dans la zone Technologies
10/05/2007
Tutoriel : Mashup LiveSearch / GoogleSearch avec ASP.Net 2.0 et Ajax 1.0

Il y a quelques semaines, j'ai intégré GoogleSearch dans mon site grâce à son API. Le rendu est plutôt sympa et efficace, tout du moins pour les pages qui sont référencées par Google. Microsoft propose lui aussi son API pour le moteur de recherche Live.com. De mon esprit curieux, sort un mash-up plutôt inattendu avec les deux frères ennemis, d'où l'envie de marier les deux plutôt de que faire 2 zones de recherches.

Ce mini tutoriel vous présentera la manière dont ce mashup a été réalisé sur mon site internet avec :

  • Les pré requis
  • La création du WebService d'interrogation de MSN Live Search
  • Le code behind nécessaire
  • L'implémentation de GoogleSearch et de LiveSearch en Javascript

Les sources, libres de droits sont disponibles en téléchargement.

Les pré requis

1. Pour démarrer, vous devez référencer le WebService de recherche MSN sur http://soap.search.msn.com/webservices.asmx?wsdl

2. Votre Web.Config, doit contenir les éléments nécessaires à l'utilisation d'ASP.Net AJAX 1.0.

3. Quatre variables ont été mises dans le Web.Config à savoir :

4. Référencer la feuille de style de Google dans la page ASPX :

    <link href="http://www.google.com/uds/css/gsearch.css" type="text/css" rel="stylesheet"/>

5. votre page ASPX doit contenir un ScriptManager :

<asp:ScriptManager ID="ScriptManager1" runat="server" />

6. Votre fichier CSS doit absolument avoir le code suivant pour éviter d'avoir 2 zones de formulaires Google :

.gsc-control form.gsc-search-box   {display : none;}

 

Le WebService d'interrogation de MSN Live Search

Le webservice est localisé dans le fichier App_Code/WebService.cs. Pour que mon WebService soit accessible via mon javascript client, ne pas oublier de mettre l'attribut System.Web.Script.Services.ScriptService

 

[System.Web.Script.Services.ScriptService]

[WebService(Namespace = "http://www.laurentgeffroy.com/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class WebService : System.Web.Services.WebService {

Pour la WebMethod, il faut également affecter l'attribut System.Web.Script.Services.ScriptMethod. L'utilisation est plutôt simple. On créé une nouvelle instance du WebService MSNSearchService auquel on affecte une requete. La requête est initialisée avec l'objet SearchRequest et les propriétés Query. La Query est modifiée pour limiter les recherches sur un domaine particulier. C'est également dans SearchRequest que vous affecterez la AppKey fournie.

Les résultats sont placés dans mes propres classes. Il est je pense possible d'utiliser directement le sourceResponse.Results comme valeur de retour. Mon but était de limiter la quantité de données à retourner au script coté client.

Votre WebService est construit ! Le voici en détail :

    [WebMethod(Description = "Récupère le résultat de la recherche sur le site actuel")]

    [System.Web.Script.Services.ScriptMethod]

    public LiveSearch.Resultats MsnLiveSearch(string p_search)

    {

        // Variable de retour

        LiveSearch.Resultats v_result = new LiveSearch.Resultats();

 

        // Nouvelle instance du WebService

        MSNSearchService _search = new MSNSearchService();

 

        SearchRequest _searchRequest = new SearchRequest();

        SearchResponse _searchResponse;

        Result[] sourceResults;

 

        try

        {

            SourceRequest[] _sr = new SourceRequest[1];

 

            // Recherche uniquement sur le Web

            _sr[0] = new SourceRequest();

            _sr[0].Source = SourceType.Web;

 

            // Construction de la recherche

            _searchRequest.Query = "site:" + ConfigurationManager.AppSettings["SiteWeb"] + " " + p_search;

            _searchRequest.Requests = _sr;

 

            // Fourniture du LiveAppID et de la culture

            _searchRequest.AppID = ConfigurationManager.AppSettings["LiveAppID"];

            _searchRequest.CultureInfo = "FR-fr";

 

            // Invocation et récupération du résultat

            _searchResponse = _search.Search(_searchRequest);

 

            foreach (SourceResponse sourceResponse in _searchResponse.Responses)

            {

                sourceResults = sourceResponse.Results;

 

                foreach (Result sourceResult in sourceResults)

                {

                    // Met les résultat dans mon propre objet

                    LiveSearch.Resultat _resultat = new LiveSearch.Resultat();

 

                    if ((sourceResult.Title != null) && (sourceResult.Title != String.Empty))

                        _resultat.Titre = sourceResult.Title;

 

                    if ((sourceResult.Description != null) && (sourceResult.Description != String.Empty))

                        _resultat.Description = sourceResult.Description;

 

                    if ((sourceResult.Url != null) && (sourceResult.Url != String.Empty))

                        _resultat.Url = sourceResult.Url;

 

                    v_result.Add(_resultat);

                }

            }

        }

        catch (Exception et)

        {

        }

        finally

        {

            sourceResults = null;

            _searchResponse = null;

            _searchRequest = null;

            _search = null;

 

        }

        return v_result;

    }

Le code-behind de votre page

Il est nécessaire de référencer le script Javascript de Google qui contient l'API Ajax. Il est bien entendu possible de le mettre en dur dans le code de la manière suivante :

        <asp:ScriptManager ID="ScriptManager1" runat="server">

            <Scripts>

                <asp:ScriptReference Path="http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=maclé" />

            </Scripts>

        </asp:ScriptManager>

La même chose, en code managé :

ScriptReference SRef = new ScriptReference();

SRef.Path = "http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=" + ConfigurationManager.AppSettings["GoogleApiKey"];

ScriptManager1.Scripts.Add(SRef);

On fournira également deux variables pour fournir au code Javacript le domaine de filtrage et le nom du site Web.

// Filtrage du site Web au niveau de la recherche

_restrictedDomain = ConfigurationManager.AppSettings["SiteWeb"];

// Nom du site Web

_siteName = ConfigurationManager.AppSettings["SiteNom"];

 

Le Javascript client

Avant de regarder en détail le javascript, attardons nous sur les div nécessaires pour la construction et la restitution des données :

            <div class="titre">Rechercher sur ce site</div><br />

            <div id="container_search_controls">

                <div id="google_search_form"></div>

                <div id="google_search_control"></div>

                <div id="live_search_container">

                    <div id="live_search_query"></div>

                    <div id="live_search_control"></div>   

                </div>

            </div>

  • google_search_for disposera de l'input de saisie et du bouton
  • google_search_control accueillera les résultats de la recherche
  • live_search_query sera initialisé avec le résumé de la recherche sur live.com
  • live_search_control comprendra les résultats obtenus sur live.com

 

On initialise deux variables issues du Code behind avec le domaine de recherche et le nom du site. Ma fonction LoadGoogleSearch créé une nouvelle instance de mon MyGoogleSearch qui construit l'interface. LoadGoogleSearch sera lancée plus loin.

        var _searchDomain = '<%= _restrictedDomain %>';

        var _siteName = '<%= _siteName %>';

 

                     

        function LoadGoogleSearch()

        {

            new MyGoogleSearch();

        }

MyGoogleSearch définit donc le contenu de mon interface. Il est nécessaire de passer par un GSearchForm si vous voulez intercepter le Submit et récupérer les données saisies dans l'input. On utilisera le setOnSubmitCallback pour intercepter le submit du formulaire et intégrer nos propres traitements. Les restrictions de recherche et apparances sont à initialiser dans l'instance de GwebSearch et GsearcherOptions .

        function MyGoogleSearch()

        {

            // Formulaire de saisie

            var sFormDiv = document.getElementById("google_search_form");

            // Zone de résultat

            var resultDiv = document.getElementById("google_search_control");

 

            this.searchControl = new GSearchControl();

            this.searchForm = new GSearchForm(true, sFormDiv);

 

            // Sur le submit

            this.searchForm.setOnSubmitCallback(this, MyGoogleSearch.prototype.onSubmit);

            this.searchForm.setOnClearCallback(this, MyGoogleSearch.prototype.onClear);

 

            var searcher = new GwebSearch();

            var options = new GsearcherOptions();

 

            // Limite la recherche au domaine

            searcher.setSiteRestriction(_searchDomain);

           

            // Personnalise le label de résultat

            searcher.setUserDefinedLabel(_siteName);

           

            // Ouvre le résultat

            options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);

            // Résultat long

            this.searchControl.setResultSetSize(GSearch.LARGE_RESULTSET);

            // Liens vers une nouvelle page

            this.searchControl.setLinkTarget(GSearch.LINK_TARGET_BLANK);           

            // Ajoute le Searcher

            this.searchControl.addSearcher(searcher, options);

           

            // Construit l'interface

            this.searchControl.draw(resultDiv);

 

        }

La fonction interceptant le submit de la recherche Google lance donc ma requête sur Google et sur Live.com gràce à la fonction LiveSearchBuilder en prenant soin de récupérer la chaine saisie. Le rendu des réponses de Google est fait automatiquement par l'API Ajax de ce dernier.

        MyGoogleSearch.prototype.onSubmit = function(form) {

            var query = form.input.value;

            if (query && query!= "")

            {

                // Exécute la recherche

                this.searchControl.execute(query);

                // Lance la recherche Live

                LiveSearchBuilder(query);

            }

            return false;

        } 

Ma fonction LiveSearchBuilder() nettoye d'abord un éventuel résultat précédent. On utilisera ensuite le Framework Ajax pour consommer notre WebService qui récupère la réponse dans OnMsnLiveSucceeded().

        function LiveSearchBuilder(p_query)

        {

            var _objC = document.getElementById("live_search_query");

            _objC.style.visibility = "visible";

           

            var _obj = document.getElementById("live_search_control");

           

            if (_obj != null)

            {

                // Efface le résultat précédent           

                if (_obj.childNodes.length > 0)

                {

                    for(x=0; x < _obj.childNodes.length; x++)

                    {

                        _obj.removeChild(_obj.childNodes[x]);

                    }

                }

               

            }

 

            // Invoque le WebService

            Sys.Net.WebServiceProxy.invoke("webservice.asmx",

                                            "MsnLiveSearch",

                                            false,

                                            { p_search : p_query},

                                            OnMsnLiveSucceeded,           

                                            OnMsnLiveFailed,

                                            null);

        }

 

La fonction OnMsnLiveSucceeded() récupère la réponse du WebService dans result et fait le rendu dans l'interface.

       

        // Si la requete à fonctionné

        function OnMsnLiveSucceeded(result, eventArgs)

        {

            // Affiche les résultats

            var out = document.getElementById("live_search_control");

             

            var i = 0;

            if (result.length > 0)

            {

                var _output = document.createElement("div");

               

  

                if (result.length > 1)                            

                    document.getElementById("live_search_query").innerHTML = result.length + " résultats sur LIVE.COM";

                else

                    document.getElementById("live_search_query").innerHTML = result.length + " résultat sur LIVE.COM";

                  

                for(i=0; i< result.length; i++)

                {

                    var _link = document.createElement("a");

                    _link.href = result[i].Url;

                    _link.target = "_blank";

                    _link.innerHTML = result[i].Titre;

                   

                    _output.appendChild(_link);

                   

                    var _desc = document.createElement("div");

                    _desc.className = "live_description";

                    _desc.innerHTML = result[i].Description;

                   

                    _output.appendChild(_desc);

                }

                out.appendChild(_output);

            }

            else

            {

                document.getElementById("live_search_query").innerHTML = "Aucun résultat sur LIVE.COM";

            }

           

        }

Enfin, ce morceau de code construit la zone de recherche :

        GSearch.setOnLoadCallback(LoadGoogleSearch);

Ne reste plus qu'a lancer votre page default.aspx...

Pour en savoir plus

Mots clés associés : Google LiveSearch Microsoft Ajax ASP.Net  | Lien permanent | Laissez le premier votre commentaire
Publiée dans la zone Tutoriels .Net
09/05/2007
Microsoft se moque du "révolutionnaire" iPhone d'Apple avec son oPhone

Début Juin, les américains auront le loisir de se ruiner en achetant le téléphone portable le plus cher du monde : l'iPhone sort dans quelques semaines et Microsoft a décidé de répliquer à Apple sur l'aspect révolutionnaire de l'iPhone avec le oPhone.


Video: Microsoft's oPhone

Pour ceux qui ne l'auront pas encore remarqué, l'IPhone n'est rien d'autre qu'un PDA avec une interface plutôt réussie. Les premiers tests de l'IPhone ont montré une légère faiblesse coté autonomie.

Un spécialiste dans l'industrie du mobile m'avouait que tous les opérateurs se battent pour le proposer. Non pas pour en vendre, mais pour l'avoir. Ca fait classe disons de proposer à la vente l'iPhone. Ca fera rentrer du monde dans la boutique...

Mots clés associés : Microsoft oPhone Apple iPhone  | Lien permanent | Laissez le premier votre commentaire
Publiée dans la zone Technologies
03/05/2007
Terrains de Baseball et Softball de France : La carte

J'ai décidé d'héberger sur mon site la carte des terrains de baseball et softball de France. Pour cela, je m'appuie sur la très sympathique API de GoogleMaps.

4 choses à voir ensemble :

1. La géolocalisation d'un terrain : 

L'objectif est de fournir aux acteurs du baseball et du softball en France une carte précise des terrains. Que votre zone soit couverte finement par GoogleMaps ou pas, peu importe. En mode Carte, il sera très facile à vos visiteurs de préparer son voyage. Rendez vous sur cette page. Zoomez sur la carte, trouvez votre terrain. Cliquez alors sur la zone que vous avez géolocalisée. Si vous vous êtes trompés, recliquez sur le marqueur pour l'effacer.

Dès que c'est ok, remplissez le formulaire. Je le validerai rapidement.

2. La visualisation sur laurentgeffroy.com

La page suivante restitue les terrains qui ont été validés.

3. La visualisation sur GoogleEarth

Cliquez sur le fichier kml pour ouvrir GoogleEarth et naviguer avec le client riche.

4. L'intégration sur votre propre site

Le code Javascript suivant est copier dans votre propre site web et profitez de la carte dans votre propre application. N'oubliez pas de récupérer votre APIKey GoogleMaps pour l'utilisée avec votre domaine.

 

<html>
   <head>
      <script src="http://maps.google.com/maps?file=api&amp;v=2.x&amp;key={MON API KEY GOOGLE DEPENDANTE DU DOMAINE}" type="text/javascript"></script>
   </head>
   <body> 

<div id="google_map_viewer"></div>

<script type="text/javascript">
    //<![CDATA[
    var hauteur = '400px';
    var largeur = '400px';
    document.getElementById("google_map_viewer").style.width = largeur;
    document.getElementById("google_map_viewer").style.height= hauteur;
    var map;
    var geoXml = new GGeoXml("http://www.laurentgeffroy.com/params/GoogleMaps/5dfbdc88-d9f2-411f-a92d-e9f338ec0d93.kml");

    function GoogleMarkerLoader()
    {
   
        if (GBrowserIsCompatible()) {
            map = new GMap2(document.getElementById("google_map_viewer"));
            map.addControl(new GLargeMapControl());
            map.addControl(new GMapTypeControl());
           
            // Centre au milieu de la France
            var point = new GLatLng(47.129951,0.878906);
            map.setCenter(point, 6);
            map.addOverlay(geoXml);
        }
    }
   
    setTimeout("GoogleMarkerLoader()", 1000);
    //]]>
</script>


             
   </body>
</html>

Mots clés associés : Google Maps Baseball  | Lien permanent | Laissez le premier votre commentaire
Publiée dans la zone Baseball [FR]
Le profil Facebook de Laurent GEFFROY
Rechercher sur ce site

Accès aux Archives

 
fermer la fenetre