Créer un raccourcisseur d'URL avec Flask et MySQL

HTMLHTMLBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Ce projet vous guide dans la création d'un service de raccourcissement d'URL simple à l'aide de Flask et de MySQL. Vous allez apprendre à configurer une base de données, à concevoir une interface web et à implémenter des fonctionnalités pour raccourcir les URL, rechercher des URL par étiquette et afficher des statistiques. Le projet est adapté aux débutants et offre une vue d'ensemble approfondie du développement web avec Python et de la gestion de bases de données.

Le projet est basé sur https://github.com/highoncarbs/shorty, qui est originalement licencié sous la licence MIT.

👀 Aperçu

Convertir l'URL avec ou sans suffixe personnalisé, Rechercher des URL par étiquette, Accéder au lien :

Voir des informations sur le système d'exploitation et la plateforme utilisée pour accéder au lien :

🎯 Tâches

Dans ce projet, vous allez apprendre :

  • Comment connecter une application Flask à une base de données MySQL
  • Comment créer et gérer un schéma de base de données MySQL pour stocker des informations sur les URL
  • Comment implémenter des pages web frontales à l'aide de HTML et de CSS pour interagir avec le backend
  • Comment gérer les données de formulaire et les requêtes dans Flask pour créer des URL raccourcies
  • Comment développer une fonctionnalité pour rediriger les utilisateurs d'une URL raccourcie vers l'URL d'origine
  • Comment créer une fonctionnalité d'analyse simple pour suivre l'utilisation des URL, y compris les comptages de clics et des informations de base sur le navigateur/plateforme
  • Comment concevoir une gestion d'erreurs conviviale et des pages 404 personnalisées pour une meilleure expérience utilisateur

🏆 Réalisations

Après avoir terminé ce projet, vous serez capable de :

  • Effectuer des opérations de base avec MySQL, y compris la création de bases de données et de tables, l'insertion de données et la requêtage
  • Comprendre les bases de Flask, y compris la routage, la gestion des requêtes et le rendu de modèles
  • Travailler avec des formulaires HTML et traiter des données dans une application Flask
  • Appliquer des principes de conception frontale de base et utiliser CSS pour créer une interface web attrayante visuellement
  • Implémenter une analyse simple pour recueillir et afficher des données sur l'utilisation des URL
  • Implémenter les meilleures pratiques en matière de gestion d'erreurs dans les applications web pour améliorer la fiabilité et l'expérience utilisateur

Configurer l'environnement du projet

Tout d'abord, nous devons configurer notre environnement de projet dans le terminal. Cela implique d'installer le package Python requis pour la connectivité MySQL et de démarrer le service MySQL. Une fois le service démarré, nous allons créer une base de données et une table pour stocker nos URL.

Installer PyMySQL :

pip install PyMySQL==1.1.0

Démarrer le service MySQL et vous connecter à la console MySQL :

sudo service mysql start
mysql -u root

Dans la console MySQL, exécutez les commandes suivantes pour créer la base de données et la table :

Créer la base de données :

CREATE DATABASE IF NOT EXISTS SHORTY;
USE SHORTY;

Créer la table :

CREATE TABLE IF NOT EXISTS WEB_URL
(
    ID             INT AUTO_INCREMENT,
    URL            VARCHAR(512),
    S_URL          VARCHAR(80),
    TAG            VARCHAR(80),
    COUNTER        INT DEFAULT 0,
    CHROME         INT DEFAULT 0,
    FIREFOX        INT DEFAULT 0,
    SAFARI         INT DEFAULT 0,
    OTHER_BROWSER  INT DEFAULT 0,
    ANDROID        INT DEFAULT 0,
    IOS            INT DEFAULT 0,
    WINDOWS        INT DEFAULT 0,
    LINUX          INT DEFAULT 0,
    MAC            INT DEFAULT 0,
    OTHER_PLATFORM INT DEFAULT 0,
    PRIMARY KEY (ID)
);

Cette instruction SQL crée une table nommée WEB_URL dans la base de données SHORTY, conçue pour stocker des informations relatives aux URL raccourcies et à certaines statistiques associées.

  • CREATE TABLE IF NOT EXISTS WEB_URL : Cette commande crée une nouvelle table nommée WEB_URL seulement si elle n'existe pas déjà dans la base de données. Cela évite les erreurs lorsqu'on exécute le script plusieurs fois.
  • ID INT AUTO_INCREMENT : Cette colonne est désignée comme clé primaire de la table et est configurée pour s'incrémenter automatiquement avec chaque nouvelle entrée. Cela signifie que chaque fois qu'un nouveau record est ajouté, MySQL lui attribuera automatiquement un ID unique, en incrémentant de 1 par rapport au dernier.
  • URL VARCHAR(512) : Cette colonne stocke les URL d'origine qui sont raccourcies. Le type de données VARCHAR(512) signifie qu'elle peut stocker des chaînes de longueur variable, jusqu'à 512 caractères.
  • S_URL VARCHAR(80) : Cette colonne est pour la chaîne de l'URL raccourcie, avec une longueur maximale de 80 caractères.
  • TAG VARCHAR(80) : Cette colonne est destinée à stocker des étiquettes associées aux URL pour la catégorisation ou la recherche, avec une longueur maximale de 80 caractères.
  • COUNTER INT DEFAULT 0 : Cette colonne entière est probablement utilisée pour suivre le nombre de fois qu'une URL raccourcie a été consultée. Elle est initialisée à 0 lors de la création d'un nouveau record.
    Les plusieurs colonnes suivantes sont conçues pour stocker des données de statistiques pour les URL raccourcies :
  • CHROME, FIREFOX, SAFARI, OTHER_BROWSER : Ces colonnes sont utilisées pour suivre le nombre de visites provenant de différents navigateurs web. Chacune est une colonne entière initialisée à 0.
  • ANDROID, IOS, WINDOWS, LINUX, MAC, OTHER_PLATFORM : De manière similaire aux colonnes de navigateurs, celles-ci sont destinées à suivre les visites provenant de différents systèmes d'exploitation/plateformes, chaque colonne étant initialisée à 0.
  • PRIMARY KEY (ID) : Cette partie de l'instruction spécifie que la colonne ID est la clé primaire de la table. Une clé primaire est un identifiant unique pour chaque enregistrement de la table, garantissant qu'aucun deux enregistrements n'ont le même ID.

Cette structure de table permet de stocker, de récupérer et d'analyser des données sur les URL raccourcies, y compris avec quelle fréquence elles sont consultées, à partir de quels navigateurs et de quels systèmes d'exploitation.

Pour quitter la console MySQL, vous pouvez exécuter la commande suivante :

EXIT;

Créer le modèle de page d'accueil

La page d'accueil est là où les utilisateurs interagiront avec le raccourcisseur d'URL. Nous utiliserons HTML et le langage de gabarit de Flask pour créer un contenu dynamique.

Dans templates/index.html, ajoutez le code HTML suivant :

<!doctype html>
<html>
  <head>
    <title>Shorty</title>
    <!-- Ajoutez l'image SVG locale lors de l'hébergement. -->
    <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
    <link rel="stylesheet" type="text/css" href="../static/skeleton.css" />
    <link rel="stylesheet" type="text/css" href="../static/normalize.css" />
    <link rel="stylesheet" type="text/css" href="../static/main.css" />
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:300,400,700,900"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="container  main_header">
      <h3 align="left"><a href="{{url_for('index')}}">Shorty</a></h3>
      <p>Un service de raccourcissement d'URL très simple.</p>
    </div>

    <div class="u-full-width shorty">
      <div class="container"></div>
    </div>
  </body>
</html>

Voici un aperçu de ses composants clés :

  • Icônes Google Material : La balise <link> importe la bibliothèque d'icônes Google Material, permettant d'utiliser des icônes prédéfinies pour une interface utilisateur plus attrayante.
  • Clipboard.js : La balise <script> inclut la bibliothèque Clipboard.js, une bibliothèque JavaScript populaire pour copier du contenu dans le presse-papiers. Cela peut être utile pour un raccourcisseur d'URL, permettant aux utilisateurs de copier facilement les URL raccourcies.
  • Feuilles de style : Le modèle se connecte à plusieurs fichiers CSS pour la mise en forme :
    • skeleton.css : Un cadre CSS léger qui fournit une mise en forme de base et un système de grille responsive.
    • normalize.css : Réinitialise les styles par défaut du navigateur pour maintenir une mise en forme cohérente sur différents navigateurs.
    • main.css : Contient des styles personnalisés spécifiques au service "Shorty".
  • Polices Google : Une autre balise <link> importe la famille de polices "Roboto" de Google Fonts, offrant une variété de graisses de police pour la conception de la typographie.
  • Dans le <body>, une div avec la classe container main_header est utilisée pour créer une section d'en-tête, qui inclut :
    • Un titre (<h3>) contenant un lien (<a>) qui redirige vers la page d'accueil, facilité par la fonction url_for de Flask, générant dynamiquement l'URL pour la route 'index'.
    • Un paragraphe (<p>) décrivant le service comme "Un service de raccourcissement d'URL très simple."
✨ Vérifier la solution et pratiquer

Implémenter le raccourcissement d'URL et la recherche basée sur des étiquettes

Dans cette étape, nous allons améliorer l'interface web en intégrant deux fonctionnalités clés : le raccourcissement d'URL et la recherche d'URL basée sur des étiquettes. Cela permettra aux utilisateurs non seulement de raccourcir les URL, mais également d'organiser et de récupérer facilement les URL en utilisant des étiquettes.

Raccourcissement d'URL

Tout d'abord, nous allons créer un formulaire sur la page d'accueil où les utilisateurs peuvent saisir l'URL qu'ils souhaitent raccourcir. Des champs optionnels pour les suffixes personnalisés et les étiquettes permettront de créer des URL raccourcies personnalisées et de les catégoriser pour une gestion plus facile.

Ajoutez le code suivant à templates/index.html :

<!-- Bloc de recherche d'URL -->
<div class="search_url_block">
  <form method="post" action="/search" name="search_tag_block">
    <input
      type="text"
      name="search_url"
      placeholder="Rechercher des étiquettes "
    />
    <button type="submit" class="button-primary search_url_btn" value="Search">
      Rechercher
    </button>
  </form>
</div>
<!-- fin du bloc -->

Le premier bloc de code ajoute un formulaire conçu pour rechercher des URL par leurs étiquettes associées :

  • search_url_block : Ce conteneur contient le formulaire de recherche, le rendant en tant que section distincte sur la page pour une meilleure organisation et mise en forme.
  • <form> : Définit un formulaire qui envoie une requête POST à l'endpoint /search lorsque le bouton de recherche est cliqué. Ce formulaire est nommé search_tag_block pour identification.
  • <input> : Un champ de saisie de texte où les utilisateurs peuvent saisir les étiquettes qu'ils souhaitent rechercher. L'attribut placeholder fournit un indice à l'utilisateur sur le but du champ.
  • <button> : Un bouton de soumission qui lance la soumission du formulaire. La classe button-primary ajoute probablement une mise en forme spécifique définie dans le CSS.

Recherche basée sur des étiquettes

Pour compléter la fonctionnalité de raccourcissement d'URL, nous allons également implémenter une fonctionnalité qui permet aux utilisateurs de rechercher des URL par étiquettes. Cette fonctionnalité sera intégrée dans le modèle d'accueil, en fournissant un formulaire simple où les utilisateurs peuvent saisir des étiquettes pour trouver les URL correspondantes.

Ajoutez le code suivant à templates/index.html :

<!-- Bloc d'entrée d'URL -->
<form method="post" action="" name="generate_block">
  <div class="row">
    <input type="text" name="url_input" placeholder="Entrez l'URL" />
    <input
      type="text"
      name="url_custom"
      placeholder="Entrez le suffixe personnalisé"
    />
    <input type="text" name="url_tag" placeholder="Étiquetez l'URL" />
    <button class="button-primary generate">Générer</button>
  </div>
</form>
<!-- fin du bloc -->

Le second bloc de code présente un formulaire pour que les utilisateurs raccourcissent des URL, avec des champs supplémentaires pour la personnalisation :

  • Le formulaire complet est emballé dans un élément <form> avec method="post" et un attribut action non spécifié. Cela signifie que les données du formulaire seront envoyées via une requête POST à l'URL actuelle lorsque le bouton de génération est cliqué.
  • À l'intérieur du formulaire, un <div> avec la classe row aide probablement à la mise en page et à l'alignement, en veillant à ce que les champs d'entrée et le bouton soient correctement organisés.
  • Trois éléments <input type="text"> sont fournis pour différents buts :
    • Le premier champ d'entrée est pour que les utilisateurs entrent l'URL d'origine qu'ils souhaitent raccourcir.
    • Le second permet un suffixe personnalisé optionnel pour l'URL raccourcie, permettant aux utilisateurs de personnaliser leurs liens courts.
    • Le troisième champ est destiné aux étiquettes, permettant aux utilisateurs de catégoriser ou d'ajouter des étiquettes descriptives à leurs URL raccourcies pour une récupération et une gestion plus faciles.
  • Un <button> avec la classe button-primary et le texte "Générer" sert de bouton de soumission du formulaire. En cliquant sur ce bouton, les données sont envoyées au serveur pour créer une URL raccourcie avec les informations fournies.

Ces améliorations améliorent considérablement l'expérience utilisateur en offrant plus de fonctionnalités que le simple raccourcissement d'URL. La possibilité de rechercher des URL par étiquettes permet une gestion et une récupération efficaces des liens raccourcis, tandis que l'option d'ajouter des suffixes personnalisés et des étiquettes permet la personnalisation et la catégorisation des URL. Cette configuration utilise des formulaires HTML pour collecter les entrées de l'utilisateur, qui seront ensuite traitées par l'application Flask côté serveur pour effectuer les actions souhaitées.

✨ Vérifier la solution et pratiquer

Gérer les erreurs et afficher les URL raccourcies

Dans cette étape, nous nous concentrons sur l'amélioration de l'expérience utilisateur en gérant les messages d'erreur et en affichant les URL raccourcies.

Gérer les erreurs

Tout d'abord, nous ajoutons une fonctionnalité pour afficher des messages d'erreur aux utilisateurs. Cela est crucial pour fournir des informations lorsqu'il y a un problème, par exemple lorsqu'un utilisateur soumet une URL invalide ou une étiquette qui n'existe pas. Une gestion correcte des erreurs rend l'application plus robuste et conviviale.

Ajoutez le code suivant à templates/index.html :

<!-- Bloc d'affichage d'erreur -->
{% if error!= '' %}
<p class="error_disp">{{error}}</p>
{% endif %} {% if shorty_url %}
<!-- fin du bloc-->

Ce bloc est conçu pour fournir des informations à l'utilisateur si une erreur se produit pendant le processus de raccourcissement d'URL :

  • {% if error!= '' %} : C'est une instruction conditionnelle utilisant la syntaxe de gabarit de Flask, Jinja2. Elle vérifie si la variable error n'est pas vide. La variable error est supposée être transmise depuis le backend Flask vers le modèle. Si un message d'erreur existe, la condition est évaluée à True.
  • <p class="error_disp">{{error}}</p> : Lorsque la condition est True, cet élément de paragraphe est affiché, affichant le message d'erreur contenu dans la variable error. La classe error_disp est probablement utilisée pour la mise en forme du message d'erreur, pour le rendre visuellement distinct et attirer l'attention de l'utilisateur.
  • {% endif %} : Cette instruction ferme le bloc conditionnel. Si la variable error est vide, rien de ce bloc n'est affiché sur la page.

Afficher les URL raccourcies

Deuxièmement, après qu'une URL a été raccourcie avec succès, nous affichons l'URL raccourcie à l'utilisateur. Cela implique de créer une section sur la page d'accueil qui affiche dynamiquement l'URL raccourcie après la soumission du formulaire, complétée d'un bouton pour copier dans le presse-papiers pour une diffusion facile.

Ajoutez le code suivant à templates/index.html :

<!-- Bloc d'affichage du générateur d'URL -->
<div class="gen_block">
  <p class="gen_url">
    L'URL Shorty est
    <b><a id="short-url" href="{{shorty_url}}">{{shorty_url}}</a></b>
  </p>
  <button
    class="button-primary copy-btn"
    data-clipboard-action="copy"
    data-clipboard-target="#short-url"
  >
    Copier
  </button>
</div>
{% endif %}
<!-- fin du bloc -->

Ce bloc est affiché lorsqu'une URL a été raccourcie avec succès et fournit un moyen pour les utilisateurs de copier facilement l'URL raccourcie :

  • {% if shorty_url %} : Une autre instruction conditionnelle qui vérifie si la variable shorty_url existe et n'est pas vide. Cette variable devrait contenir l'URL raccourcie générée par le service.
  • <p class="gen_url"> : Ce paragraphe affiche un message indiquant l'URL raccourcie. À l'intérieur, <a id="short-url" href="{{shorty_url}}">{{shorty_url}}</a> crée un hyperlien avec l'URL raccourcie comme texte de lien et l'attribut href, permettant aux utilisateurs de cliquer dessus directement.
  • <button> : Ce bouton est conçu pour copier l'URL raccourcie dans le presse-papiers pour une diffusion facile. Il utilise des classes pour la mise en forme (button-primary) et la fonctionnalité (copy-btn). L'attribut data-clipboard-action spécifie l'action à effectuer (copier), et data-clipboard-target indique l'élément cible à copier (le lien d'URL raccourcie). Cette configuration suppose l'intégration de Clipboard.js (ou d'une bibliothèque similaire) pour gérer la fonction de copie.
  • {% endif %} : Ferme le bloc conditionnel pour afficher l'URL raccourcie et le bouton de copie. Si shorty_url n'est pas défini ou est vide, cette section ne sera pas affichée.

Ces améliorations contribuent considérablement à l'utilisabilité du service de raccourcissement d'URL. Les messages d'erreur fournissent des informations essentielles, guidant les utilisateurs à corriger les erreurs ou en informant des problèmes, tandis que l'affichage des URL raccourcies avec une fonction de copie simple permet une expérience transparente dans la création et la diffusion des liens raccourcis.

✨ Vérifier la solution et pratiquer

Lister et gérer les URL raccourcies

La dernière étape consiste à créer une section qui liste toutes les URL raccourcies stockées dans la base de données, ainsi que leur URL d'origine, le nombre de clics qu'elles ont reçus et des liens vers des analyses détaillées. Cette fonctionnalité permet aux utilisateurs de visualiser et de gérer leurs URL raccourcies en un seul endroit, rendant l'application plus fonctionnelle et conviviale.

Ajoutez le code suivant à templates/index.html :

        <!-- Bloc de liste d'URL -->
        {% if not error %}
        {% if not shorty_url %}
        <!-- Ajoutez le cas de liste vide -> 'Wow. Tellement vide!' -->
        <div style="overflow-x:auto;">
            <div class="table_list u-full-width">
                <table>
                    <thead>
                    <tr>
                        <th>URL d'origine</th>
                        <th>URL raccourcie</th>
                        <th>Clics</th>
                        <th>Infos</th>
                    </tr>
                    </thead>

                    <tbody>
                    {% for url in table %}
                    <tr>
                        <td style="padding-left: 5px;">{{url[1]}}</td>
                        <td><a href="{{host+url[2]}}">{{ host+url[2]}}</a></td>
                        <td style="text-align: center;">{{url[4]}}</td>
                        <td id="info"><a href=" {{url_for('analytics',short_url=url[2])}} "><i class="material-icons">info_outline</i></a>
                        </td>
                    </tr>

                    {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
        {% endif %}
        {% endif %}
    </div>
</div>
<script type="text/javascript">
    var clipboard = new Clipboard('.copy-btn');
</script>
</html>

Ce code est conçu pour lister toutes les URL raccourcies stockées dans la base de données, en fournissant des informations telles que l'URL d'origine, l'URL raccourcie, le nombre de clics et des liens vers des analyses plus détaillées. Voici une présentation détaillée de ses composants :

  • Le bloc commence par une conditionnelle {% if not error %} pour s'assurer que la liste n'est affichée que lorsqu'il n'y a pas d'erreur. Cela contribue à maintenir une interface utilisateur propre, surtout lorsqu'il est nécessaire d'afficher des messages d'erreur.
  • Une autre conditionnelle {% if not shorty_url %} vérifie si une nouvelle URL raccourcie n'a pas été générée juste avant. Cette condition peut être utilisée pour empêcher la liste d'être affichée immédiatement après qu'une nouvelle URL a été raccourcie, en concentrant l'attention de l'utilisateur sur l'URL raccourcie nouvellement créée.
  • Un style overflow-x:auto; est appliqué à un div pour s'assurer que le tableau est défilable horizontalement sur les écrans plus petits, améliorant la réactivité et l'utilisabilité.
  • L'élément table est structuré avec une section thead définissant les en-têtes de colonne pour "URL d'origine", "URL raccourcie", "Clics" et "Infos". Cette disposition aide les utilisateurs à comprendre les données présentées.
  • La section tbody est dynamiquement remplie de données en utilisant une boucle Flask/Jinja2 : {% for url in table %}. Cette boucle itère sur une collection d'URLs (table) passée depuis le backend Flask, affichant les données de chaque URL dans une nouvelle ligne de tableau (<tr>).
  • Dans chaque ligne, l'URL d'origine est affichée dans une cellule (<td>) avec un peu de marge pour l'esthétique. L'URL raccourcie est présentée comme un lien cliquable (<a>), construit en ajoutant le chemin raccourci (url[2]) au nom d'hôte (host), qui devrait également être passé depuis le backend.
  • La colonne "Clics" montre le nombre de fois que l'URL raccourcie a été consultée, centrée pour une meilleure lisibilité.
  • La colonne "Infos" contient un lien vers la page d'analyse pour chaque URL raccourcie. Ce lien est généré en utilisant la fonction url_for de Flask, en créant dynamiquement une URL vers la route d'analyse avec l'URL raccourcie comme paramètre. Un icône (<i class="material-icons">info_outline</i>) du jeu d'icônes Google Material est utilisée pour représenter visuellement le lien d'analyse.
  • La balise {% endfor %} ferme la boucle, s'assurant qu'une ligne est créée pour chaque URL dans la collection table.
  • Les blocs conditionnels sont fermés avec les balises {% endif %}.
  • En bas, une balise <script> initialise Clipboard.js pour la classe .copy-btn, qui pourrait avoir été utilisée dans les sections précédentes (par exemple, pour copier l'URL raccourcie). Ce script s'assure que tout élément avec la classe copy-btn aura la fonctionnalité de copie dans le presse-papiers activée, en utilisant la bibliothèque Clipboard.js.

Cette dernière étape complète la fonctionnalité du service de raccourcissement d'URL "Shorty" en offrant aux utilisateurs une vue d'ensemble complète de leurs URL raccourcies, facilitant la gestion et l'analyse de leurs liens. L'intégration du rendu de données dynamiques avec Flask/Jinja2, combinée à une conception soignée de l'interface utilisateur, assure une expérience utilisateur conviviale.

✨ Vérifier la solution et pratiquer

Créer le modèle de page de recherche

Pour permettre aux utilisateurs de rechercher des URL par étiquettes, nous aurons besoin d'une page de recherche.

Dans templates/search.html, ajoutez le code HTML suivant :

<!DOCTYPE html>
<html>
<head>
    <title>Shorty</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
          rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="../static/skeleton.css">
    <link rel="stylesheet" type="text/css" href="../static/normalize.css">
    <link rel="stylesheet" type="text/css" href="../static/main.css">
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,700,900" rel="stylesheet">
</head>
<body>
<div class="container main_header">
    <h3 align="left"><a href="{{url_for('index')}}">Shorty</a></h3>
    <p>Un service de raccourcissement d'URL ultra simple.</p>
</div>
<!-- Résultats de recherche  -->
<div class=" container search_header">
    <h4>Résultats de recherche pour : <b> {{ search_tag }} <b></h4>

    <div style="overflow-x:auto;">
        <div class="table_list u-full-width">
            <table>
                <thead>
                <tr>
                    <th>URL d'origine</th>
                    <th>URL raccourcie</th>
                    <th>Clics</th>
                    <th>Infos</th>

                </tr>
                </thead>

                <tbody>
                {% for url in table %}
                <tr>
                    <td style="padding-left: 5px;">{{url[1]}}</td>
                    <td><a href="{{ host+url[2]}}">{{host+url[2]}}</a></td>
                    <td style="text-align: center;">{{url[4]}}</td>
                    <td id="info"><a href=" {{url_for('analytics',short_url=url[2])}} "><i class="material-icons">info_outline</i></a>
                    </td>
                </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>

Ce code crée un modèle pour la page des résultats de recherche dans le service de raccourcissement d'URL "Shorty". Cette page est conçue pour afficher les résultats d'une recherche d'URL par étiquettes effectuée par un utilisateur. Voici une présentation détaillée du modèle :

  • Dans le <body>, la section d'en-tête (<div class="container main_header">) est similaire à celle de la page d'accueil, offrant un aspect et une sensation cohérents. Elle inclut le nom du service ("Shorty") comme un lien cliquable qui redirige vers la page d'accueil ({{url_for('index')}}) et une courte description du service.
  • La section <div class="container search_header"> introduit la zone des résultats de recherche, commençant par un en-tête (<h4>) qui affiche dynamiquement l'étiquette utilisée pour la recherche ({{ search_tag }}).
  • Les résultats sont présentés dans un tableau à l'intérieur d'un div stylisé pour le défilement horizontal (overflow-x:auto;), assurant une accessibilité sur des appareils à écran plus petit.
  • La structure du tableau (<table>) est composée de sections d'en-tête (<thead>) et de corps (<tbody>). L'en-tête définit les colonnes pour "URL d'origine", "URL raccourcie", "Clics" et "Infos", similaire à la liste affichée sur la page d'accueil.
  • Le corps du tableau est rempli dynamiquement en utilisant une boucle ({% for url in table %}), qui itère sur une collection d'URLs (table) passée depuis le backend Flask. Chaque itération crée une nouvelle ligne (<tr>) dans le tableau pour une URL :
    • L'URL d'origine est affichée avec un peu de marge pour une meilleure lisibilité.
    • L'URL raccourcie est présentée comme un lien cliquable, construit en ajoutant le chemin raccourci au nom d'hôte, les deux étant insérés dynamiquement en utilisant la syntaxe de gabarit de Flask.
    • La colonne "Clics" montre combien de fois l'URL raccourcie a été consultée, le texte étant centré pour plus de clarté.
    • La colonne "Infos" fournit un lien vers des analyses détaillées pour chaque URL, en utilisant la fonction url_for de Flask pour générer dynamiquement l'URL et une icône (<i class="material-icons">info_outline</i>) pour la représentation visuelle.

Ce modèle de résultats de recherche améliore le service "Shorty" en permettant aux utilisateurs de trouver et de gérer efficacement les URL en fonction des étiquettes, offrant une expérience utilisateur fluide et intuitive. L'utilisation cohérente de styles et d'éléments de mise en page de la page d'accueil assure une conception cohérente tout au long de l'application.

✨ Vérifier la solution et pratiquer

Créer le modèle de page d'analyse

La page d'analyse affichera des informations détaillées sur l'utilisation d'une URL raccourcie, y compris les statistiques de clics, de navigateur et de plateforme.

Dans templates/data.html, ajoutez le code HTML suivant :

<!doctype html>
<html>
  <head>
    <title>Shorty</title>

    <!-- Ajoutez l'image SVG locale lors de l'hébergement. -->
    <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />

    <link rel="stylesheet" type="text/css" href="../static/skeleton.css" />
    <link rel="stylesheet" type="text/css" href="../static/normalize.css" />
    <link rel="stylesheet" type="text/css" href="../static/main.css" />
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:300,400,700,900"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="container  main_header">
      <h3 align="left"><a href="{{url_for('index')}}">Shorty</a></h3>
      <p>Un service de raccourcissement d'URL ultra simple.</p>
    </div>
    <div class=" container modal-content">
      <!-- Index du tableau -> 
      navigateur : 
          CHROME,
          FIREFOX,
          SAFARI,
          AUTRE_NAVIGATEUR,
      plateforme:
          ANDROID,
          IOS,
          WINDOWS,
          LINUX,
          MAC,
          AUTRE_PLATEFORME
       -->
      <div class="url_info">
        <h4>
          Données d'analyse pour :
          <a href="{{host+info[1]}}">{{'localhost/'+info[1]}}</a>
        </h4>
        <p>
          URL d'origine :
          <a style="text-decoration: none" href="{{info[0]}}">{{info[0]}}</a>
        </p>
      </div>
      <div class="data_block">
        <div class="browser_list">
          <h4>Navigateur</h4>
          <table>
            <thead>
              <tr>
                <th>Chrome</th>
                <th>Firefox</th>
                <th>Safari</th>
                <th>Autres navigateurs</th>
              </tr>
            </thead>

            <tbody>
              <tr>
                <td style="padding-left: 5px;">{{browser[0]}}</td>
                <td>{{browser[1]}}</td>
                <td>{{browser[2]}}</td>
                <td>{{browser[3]}}</td>
              </tr>
            </tbody>
          </table>
        </div>
        <div class="platform_list">
          <h4>Plateforme</h4>
          <table>
            <thead>
              <tr>
                <th>Android</th>
                <th>IOS</th>
                <th>Windows</th>
                <th>Linux</th>
                <th>Mac</th>
                <th>Autres plateformes</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td style="padding-left: 5px;">{{platform[0]}}</td>
                <td>{{platform[1]}}</td>
                <td>{{platform[2]}}</td>
                <td>{{platform[3]}}</td>
                <td>{{platform[4]}}</td>
                <td>{{platform[5]}}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </body>
</html>

Ce code inclut des informations sur le nombre de clics, l'utilisation des navigateurs et la distribution des plateformes. Voici une présentation de sa structure et de ses composants :

  • Un div avec les classes container modal-content encapsule les informations d'analyse, stylisées comme un modal ou un bloc de contenu distinct au sein de la page.
  • Le div url_info présente :
    • Un en-tête <h4> indiquant que les données suivantes concernent l'analyse d'une URL raccourcie spécifique. L'URL raccourcie est affichée comme un lien cliquable, construit en utilisant les variables host et info[1], où info[1] contient le chemin raccourci.
    • Un paragraphe (<p>) montrant l'URL d'origine comme un lien cliquable, facilitant l'accès au contenu original.
  • Deux sections distinctes, browser_list et platform_list, contiennent chacune un tableau affichant respectivement les statistiques d'utilisation des navigateurs et des plateformes :
    • La section browser_list inclut un tableau avec des en-têtes pour Chrome, Firefox, Safari et Autres navigateurs. La section <tbody> affiche les statistiques correspondantes, extraites du tableau browser variable passée au modèle.
    • De même, la section platform_list a un tableau pour l'utilisation des plateformes, avec des en-têtes pour Android, iOS, Windows, Linux, Mac et Autres plateformes. Les statistiques d'utilisation sont affichées dans le corps du tableau, issues de la variable tableau platform.
  • Les tableaux utilisent <thead> pour les en-têtes et <tbody> pour les données réelles, assurant un HTML sémantique et facilitant la mise en forme et l'accessibilité.
  • Les cellules de données (<td>) à l'intérieur des tableaux affichent les comptes respectifs pour chaque navigateur et chaque plateforme, alignés et stylisés pour une meilleure lisibilité.

Ce modèle communique efficacement les données d'analyse à l'utilisateur, offrant des informations sur la manière dont l'URL raccourcie est consultée, y compris les navigateurs et les plateformes utilisées par le public. La disposition propre, combinée à la séparation claire des données en sections distinctes, facilite la compréhension et l'interprétation des performances de l'URL par les utilisateurs.

✨ Vérifier la solution et pratiquer

Créer le modèle de page 404

Une page 404 personnalisée améliore l'expérience utilisateur en fournissant un message d'erreur plus utile lorsqu'une URL raccourcie n'est pas trouvée.

Dans templates/404.html, ajoutez le code HTML suivant :

<!doctype html>
<html>
  <head>
    <title>Shorty</title>

    <!-- Ajoutez l'image SVG locale lors de l'hébergement. -->
    <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />

    <link rel="stylesheet" type="text/css" href="../static/skeleton.css" />
    <link rel="stylesheet" type="text/css" href="../static/normalize.css" />
    <link rel="stylesheet" type="text/css" href="../static/main.css" />
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:300,400,700,900"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="lost">
      <h2>Hey, semble que vous soyez perdu!</h2>
    </div>
  </body>
</html>

Ce modèle de page 404 personnalisée communique efficacement aux utilisateurs que la page qu'ils cherchent n'existe pas, tout en maintenant un ton légèrement amusant.

✨ Vérifier la solution et pratiquer

Concepter l'interface web

Ensuite, nous allons concevoir l'interface web. Commencez par créer le fichier CSS principal pour styliser notre application.

Dans static/main.css, ajoutez le code CSS suivant pour styliser les éléments HTML :

html {
  border-top: 5px solid #d9edf7;
}
body {
  font-family: "Roboto", sans-serif;
  margin-top: 50px;
  margin-bottom: 0;
}
h3 {
  padding: 0;
  margin: 0;
}
h3 a {
  font-weight: 700;
  text-decoration: none;
  color: black;
}
h3 a:hover {
  color: grey;
  transition: 0.2s all;
}
/** En-tête principal */
.main_header {
  margin-bottom: 20px;
}
/* Bloc de recherche d'URL */
.search_url_block {
  padding: 15px;
  background-color: #d9edf7;
  color: #31708f;
  border-radius: 5px;
  margin-bottom: 10px;
}
form {
  margin: 0;
}

.search_header {
  margin-top: 20px;
}

.material-icons {
  padding: 5px;
  padding-top: 7px;
  opacity: 0.7;
}

.material-icons:hover {
  opacity: 1;
}
/* Bloc de génération d'URL */

.gen_block {
  margin-top: 10px;
  padding: 15px;
  background-color: #dff0d8;
  color: #2b542c;
  border-radius: 5px;
  width: auto;
  font-size: 20px;
}
/* Affichage d'erreur */
.error_disp {
  padding: 15px;
  border-radius: 5px;
  background-color: #fcf8e3;
  color: #b84442;
  width: auto;
  font-size: 20px;
  margin-top: 10px;
}

/* Bloc d'affichage du tableau*/

.table_list {
  padding-top: 10px;
  margin-top: 40px;
  border-top: 2px solid lightgrey;
}
table {
  font-size: 20px;
  width: 100%;
}
thead {
  font-weight: 700;
  padding: 2px;
}
tbody {
  font-weight: 400;
}
th {
  padding: 5px;
}
td {
  padding: 5px;
}
tr {
  padding: 5px;
}
tbody tr:hover {
  background-color: #f5f5f5;
  transition: 0.1s all ease-out;
}

/* Bloc d'analyse*/
.url_info {
  margin-top: 10px;
  padding: 15px;
  background-color: #d9edf7;
  color: #31708f;
  border-radius: 5px;
  margin-bottom: 10px;
}
.url_info h4,
p {
  margin: 0;
  padding: 0;
}
.data_block {
  margin-top: 20px;
}

/* 404. Perdu*/
.lost {
  margin-top: 20px;
}
.lost h2 {
  font-weight: 700;
  font-size: 40px;
  text-align: center;

  color: #31708f;
}
.lost p {
  font-weight: 400;
  font-size: 20px;
  text-align: center;
}

La conception globale utilise une combinaison de couleurs d'arrière-plan, de couleurs de texte et de mises en page pour créer une interface propre et moderne, facile à naviguer. L'utilisation du bord arrondi sur divers éléments donne à l'interface un aspect plus doux et accueillant, tandis que les effets au survol améliorent l'interactivité. L'utilisation cohérente de la police Roboto maintient un aspect cohérent tout au long de l'application.

✨ Vérifier la solution et pratiquer

Fonctions de connexion et d'opération de la base de données

Des fonctions utilitaires géreront les connexions à la base de données, les validations d'URL, la mise à jour des compteurs de navigateur et de plateforme, et la génération de jetons aléatoires pour les URL raccourcies.

Connexion à la base de données

Tout d'abord, vous configurerez la connexion à la base de données en utilisant pymysql. Cela est crucial pour permettre à votre application Flask d'interagir avec la base de données MySQL.

Dans utils.py, ajoutez le code Python suivant :

from urllib.parse import urlparse
import random
import string

import pymysql


db_config = {
    "host": "localhost",
    "user": "root",
    "password": "",
    "db": "SHORTY"
}


def get_db_connection() -> pymysql.Connection:
    """Crée et renvoie une nouvelle connexion à la base de données."""
    return pymysql.connect(**db_config)
  • La bibliothèque pymysql est utilisée pour se connecter à la base de données MySQL. Cette bibliothèque permet aux applications Python d'interagir avec les bases de données MySQL en utilisant une API simple.
  • Le dictionnaire db_config contient les paramètres de connexion à la base de données tels que l'hôte, l'utilisateur, le mot de passe et le nom de la base de données. Ces paramètres sont importés à partir d'un module config séparé, probablement pour une meilleure sécurité et modularité. En gardant les paramètres de configuration séparés, il est plus facile d'effectuer des ajustements sans modifier la base du code principal.
  • La fonction get_db_connection() crée et renvoie une nouvelle connexion à la base de données en utilisant la fonction pymysql.connect(**db_config). La syntaxe **db_config est utilisée pour déballer le dictionnaire en arguments clés.

Fonctions d'opération de la base de données

Après avoir établi une connexion à la base de données, l'étape suivante consiste à créer des fonctions qui effectuent des opérations sur la base de données. Cela inclut la liste des données pour une URL raccourcie donnée et la mise à jour des compteurs en fonction de l'utilisation des navigateurs et des plateformes.

Dans utils.py, ajoutez le code Python suivant :

def list_data(shorty_url: str) -> tuple:
    """
    Prend une URL raccourcie en entrée.
    Renvoie le compteur, le navigateur, les statistiques de plateforme.
    """
    with get_db_connection() as conn, conn.cursor() as cursor:

        su = [shorty_url]
        info_sql = "SELECT URL, S_URL, TAG FROM WEB_URL WHERE S_URL = %s; "
        counter_sql = "SELECT COUNTER FROM WEB_URL WHERE S_URL = %s; "
        browser_sql = "SELECT CHROME, FIREFOX, SAFARI, OTHER_BROWSER FROM WEB_URL WHERE S_URL = %s;"
        platform_sql = "SELECT ANDROID, IOS, WINDOWS, LINUX, MAC, OTHER_PLATFORM FROM WEB_URL WHERE S_URL = %s;"

        cursor.execute(info_sql, su)
        info_fetch = cursor.fetchone()
        cursor.execute(counter_sql, su)
        counter_fetch = cursor.fetchone()
        cursor.execute(browser_sql, su)
        browser_fetch = cursor.fetchone()
        cursor.execute(platform_sql, su)
        platform_fetch = cursor.fetchone()

    return info_fetch, counter_fetch, browser_fetch, platform_fetch

def update_counters(cursor: pymysql.Connection, short_url: str, browser_dict: dict, platform_dict: dict) -> None:
    """Met à jour les compteurs de navigateur et de plateforme dans la base de données pour l'URL raccourcie donnée."""
    counter_sql = """UPDATE WEB_URL SET COUNTER = COUNTER + 1,
                     CHROME = CHROME + %s, FIREFOX = FIREFOX + %s, SAFARI = SAFARI + %s, OTHER_BROWSER = OTHER_BROWSER + %s,
                     ANDROID = ANDROID + %s, IOS = IOS + %s, WINDOWS = WINDOWS + %s, LINUX = LINUX + %s, MAC = MAC + %s, OTHER_PLATFORM = OTHER_PLATFORM + %s
                     WHERE S_URL = %s;"""
    cursor.execute(counter_sql, (browser_dict['chrome'], browser_dict['firefox'], browser_dict['safari'], browser_dict['other'],
                                 platform_dict['android'], platform_dict['iphone'], platform_dict[
                                     'windows'], platform_dict['linux'], platform_dict['macos'], platform_dict['other'],
                                 short_url))
  • La fonction list_data(shorty_url) est conçue pour récupérer diverses informations de la table WEB_URL pour une URL raccourcie donnée (shorty_url). Elle établit une connexion à la base de données et exécute quatre requêtes SQL pour extraire l'URL d'origine, l'étiquette associée, le compteur d'accès, les statistiques de navigateur et de plateforme. Chaque requête est exécutée séparément, et les résultats sont extraits et renvoyés.
  • La fonction update_counters(cursor, short_url, browser_dict, platform_dict) met à jour le compteur d'accès, les statistiques de navigateur et de plateforme pour une URL raccourcie donnée dans la base de données. Cette fonction prend un curseur de base de données, l'URL raccourcie et deux dictionnaires contenant les comptes pour chaque navigateur et chaque plateforme en arguments. Elle construit une instruction SQL UPDATE pour incrémenter les compteurs pour l'URL raccourcie en fonction des données fournies. La fonction suppose que les informations sur le navigateur et la plateforme ont été déterminées avant d'appeler cette fonction, et que ces informations sont passées en tant que dictionnaires (browser_dict et platform_dict), avec des clés correspondant aux colonnes de la table WEB_URL.

Ceci est un modèle typique pour les applications web utilisant Flask et MySQL, où des fonctions utilitaires sont définies pour les opérations de base de données courantes. Ces fonctions peuvent ensuite être importées et utilisées dans toute l'application pour interagir avec la base de données, en isolant l'accès direct à la base de données et les requêtes SQL de la logique principale de l'application.

✨ Vérifier la solution et pratiquer

Implémenter des fonctions utilitaires non liées à la base de données

Enfin, implémentez des fonctions utilitaires qui ne sont pas en interaction avec la base de données. Cela inclut la génération de jetons aléatoires pour les URL raccourcies et la validation des URL.

Dans utils.py, ajoutez le code Python suivant :

def random_token(size: int = 6) -> str:
    """
    Génère une chaîne aléatoire de 6 caractères, utilisez l'argument size
    pour modifier la taille du jeton.
    Renvoie un jeton valide de la taille souhaitée,
    *la valeur par défaut est de 6 caractères
    """
    BASE_LIST = string.digits + string.ascii_letters

    token = ''.join((random.choice(BASE_LIST)) for char in range(size))
    return token


def url_check(url: str) -> bool:
    """
    Attend une chaîne en argument.
    Renvoie True si l'URL est valide, sinon False.
    Pour plus de détails, consultez urlparse.
    """
    try:
        result = urlparse(url)
        if all([result.scheme, result.netloc]):
            return True
        else:
            return False
    except:
        return False
  • La fonction random_token génère une chaîne aléatoire qui sert de jeton pour créer des URL raccourcies. Par défaut, elle crée un jeton de 6 caractères, mais cela peut être ajusté avec l'argument size.
    • Elle utilise une combinaison de chiffres (string.digits) et de lettres (string.ascii_letters) comme liste de base pour générer le jeton.
    • Le jeton est généré en sélectionnant aléatoirement des caractères dans la BASE_LIST pour le nombre de fois spécifié par le paramètre size. Cela est fait à l'aide d'une compréhension de liste et de random.choice(), qui sélectionne un élément aléatoire dans la séquence spécifiée.
    • Le jeton généré est ensuite renvoyé sous forme de chaîne. Ce jeton peut être utilisé comme identifiant de l'URL raccourcie.
  • La fonction url_check valide une URL donnée pour s'assurer qu'elle est dans un format correct.
    • Elle utilise la fonction urlparse du module urllib.parse pour analyser l'URL donnée en composants.
    • La fonction vérifie si l'URL a à la fois un schéma (comme http, https) et un netloc (emplacement réseau, par exemple www.example.com). Ces deux éléments sont des composants essentiels pour qu'une URL soit considérée comme valide.
    • Si les deux composants sont présents, la fonction renvoie True, indiquant que l'URL est valide. Si l'un ou l'autre est manquant, ou si une exception se produit lors de l'analyse (par exemple, si l'entrée n'est pas une chaîne), la fonction renvoie False.
    • Cette validation est importante pour s'assurer que seule les URL valides sont traitées et stockées par l'application.

Ces fonctions utilitaires sont essentielles pour le service de raccourcissement d'URL, en fournissant des capacités essentielles pour générer des identifiants uniques pour les URL raccourcies et pour s'assurer que seule les URL valides sont acceptées par le système.

✨ Vérifier la solution et pratiquer

Initialiser et implémenter la route d'index

Enfin, nous allons construire le cœur de notre service de raccourcissement d'URL - l'application Flask.

Commencez par configurer la route d'index. Cette route servira la page principale et gérera les requêtes GET et POST. Lors d'une requête GET, elle affichera toutes les URL raccourcies. Lors d'une requête POST, elle acceptera une nouvelle URL à raccourcir, générera un jeton unique et la sauvera dans la base de données.

Dans app.py, ajoutez le code Python suivant :

from flask import Flask, request, redirect, render_template, make_response

from utils import get_db_connection, list_data, random_token, update_counters, url_check


app = Flask(__name__)


@app.route('/', methods=['GET', 'POST'])
def index():
    with get_db_connection() as conn, conn.cursor() as cursor:
        ## Récupérez toutes les données pour afficher sur l'index
        cursor.execute("SELECT * FROM WEB_URL;")
        result_all_fetch = cursor.fetchall()

        if request.method == 'POST':
            og_url = request.form.get('url_input')
            custom_suff = request.form.get('url_custom', '')
            tag_url = request.form.get('url_tag', '')

            token_string = random_token() if not custom_suff else custom_suff

            if og_url and url_check(og_url):
                cursor.execute(
                    "SELECT S_URL FROM WEB_URL WHERE S_URL = %s FOR UPDATE", (token_string,))
                if cursor.fetchone() is None:
                    cursor.execute(
                        "INSERT INTO WEB_URL(URL, S_URL, TAG) VALUES(%s, %s, %s)", (og_url, token_string, tag_url))
                    conn.commit()
                    return render_template('index.html', shorty_url=f"{shorty_host}{token_string}")
                else:
                    error = "Le suffixe personnalisé existe déjà. Veuillez utiliser un autre suffixe ou le laisser vide pour en générer un aléatoire."
            else:
                error = "URL invalide fournie. Veuillez entrer une URL valide."

            return render_template('index.html', table=result_all_fetch, host=shorty_host, error=error)

        return render_template('index.html', table=result_all_fetch, host=shorty_host)

La fonction index dans app.py configure la fonctionnalité principale du service de raccourcissement d'URL en utilisant Flask, un micro framework web écrit en Python. Cette fonction définit comment la route d'index (/) de l'application se comporte et traite les requêtes GET et POST. Voici une explication détaillée du code :

Configuration de Flask

  • L'application Flask est initialisée avec app = Flask(__name__).
  • Le décorateur @app.route('/', methods=['GET', 'POST']) spécifie que la fonction index gère les requêtes à l'URL racine (/) et accepte les méthodes GET et POST.

Gestion des requêtes GET

  • Lorsque la fonction reçoit une requête GET, elle se connecte à la base de données en utilisant la fonction utilitaire get_db_connection() et extrait tous les enregistrements de la table WEB_URL. Cela permet d'afficher toutes les URL raccourcies sur la page d'index.
  • Les enregistrements extraits sont passés à la fonction render_template, ainsi que l'URL de l'hôte (shorty_host), pour afficher le modèle index.html. Ce modèle contient probablement un tableau ou une liste pour afficher chaque URL raccourcie et ses détails.

Gestion des requêtes POST

  • Pour les requêtes POST, généralement envoyées à partir d'un formulaire sur la page d'index, la fonction extrait l'URL d'origine (og_url), un suffixe personnalisé optionnel (custom_suff) et une étiquette optionnelle (tag_url) des données du formulaire.
  • Elle génère ensuite un jeton aléatoire pour l'URL raccourcie en utilisant random_token() à moins qu'un suffixe personnalisé ne soit fourni. Ce jeton (ou suffixe personnalisé) sert d'identifiant unique pour l'URL raccourcie.
  • Avant de continuer, la fonction valide l'URL d'origine en utilisant url_check(og_url). Si l'URL est valide et que le jeton/suffixe est unique (n'est pas déjà dans la base de données), un nouvel enregistrement est inséré dans la table WEB_URL avec l'URL d'origine, le jeton/suffixe comme URL raccourcie et l'étiquette.
  • Si l'opération est réussie, la fonction réaffiche le modèle index.html, en affichant l'URL raccourcie nouvellement créée (shorty_url) ainsi que tous les enregistrements existants.
  • Si le jeton/suffixe existe déjà dans la base de données ou si l'URL d'origine est invalide, un message d'erreur est défini et le modèle index.html est affiché avec le message d'erreur et les enregistrements existants.

Gestion des erreurs et affichage des modèles

  • La fonction render_template est utilisée de manière répétée pour afficher le modèle index.html, en passant divers paramètres tels que la liste de tous les enregistrements (table), l'URL de base de l'hôte pour les liens raccourcis (host), l'URL raccourcie nouvellement créée (shorty_url) et tout message d'erreur (error). Cette fonction facilite l'affichage de contenu dynamique dans Flask en interpolant des variables Python dans des modèles HTML.

Cette application Flask sert de backend pour le service de raccourcissement d'URL, en gérant les interactions avec la base de données, la validation des URL et la génération de jetons, tout en générant dynamiquement des pages web en fonction des interactions de l'utilisateur et du contenu de la base de données.

✨ Vérifier la solution et pratiquer

Implémenter la route de redirection et la route d'analyse

Route de redirection

Ensuite, créez une route pour gérer la redirection d'une URL raccourcie vers l'URL d'origine. Cette route capture toute URL raccourcie, la recherche dans la base de données et redirige l'utilisateur vers l'URL d'origine.

Ajoutez le code suivant à app.py :

@app.route('/<short_url>')
def reroute(short_url):
    with get_db_connection() as conn, conn.cursor() as cursor:
        platform = request.user_agent.platform or 'other'
        browser = request.user_agent.browser or 'other'
        browser_dict = {'firefox': 0, 'chrome': 0,'safari': 0, 'other': 0}
        platform_dict = {'windows': 0, 'iphone': 0,
                         'android': 0, 'linux': 0,'macos': 0, 'other': 0}

        ## Incrémente les compteurs de navigateur et de plateforme
        browser_dict[browser] = browser_dict.get(browser, 0) + 1
        platform_dict[platform] = platform_dict.get(platform, 0) + 1

        cursor.execute(
            "SELECT URL FROM WEB_URL WHERE S_URL = %s;", (short_url,))
        try:
            new_url = cursor.fetchone()[0]
            update_counters(cursor, short_url, browser_dict, platform_dict)
            conn.commit()
            return redirect(new_url)
        except Exception:
            return render_template('404.html'), 404
  • Le décorateur @app.route('/<short_url>') crée une route dynamique qui correspond à tout segment de chemin suivant l'URL racine. Ce segment (short_url) est passé à la fonction reroute en tant qu'argument.
  • À l'intérieur de la fonction, elle établit une connexion à la base de données et initialise des dictionnaires pour suivre le navigateur et la plateforme à partir de laquelle la requête a été initiée. L'agent utilisateur de Flask (request.user_agent) est utilisé pour déterminer le navigateur et la plateforme.
  • Elle exécute ensuite une requête SQL pour trouver l'URL d'origine associée à la short_url donnée. Si elle est trouvée, elle met à jour les compteurs pour le navigateur et la plateforme dans la base de données en utilisant la fonction update_counters.
  • Après avoir validé les modifications dans la base de données, la fonction utilise la fonction redirect de Flask pour envoyer l'utilisateur à l'URL d'origine.
  • Si la short_url n'est pas trouvée dans la base de données, ou si une autre exception se produit, la fonction affiche une page d'erreur 404 en utilisant render_template('404.html').

Route d'analyse

Créez une route d'analyse qui affiche des informations détaillées sur une URL raccourcie spécifique, telles que le nombre de fois qu'elle a été consultée et les plateformes et navigateurs à partir desquels elle a été consultée.

Ajoutez le code suivant à app.py :

@app.route('/analytics/<short_url>')
def analytics(short_url):
    info_fetch, counter_fetch, browser_fetch, platform_fetch = list_data(
        short_url)
    return render_template("data.html", host=shorty_host, info=info_fetch, counter=counter_fetch, browser=browser_fetch, platform=platform_fetch)
  • Le décorateur @app.route('/analytics/<short_url>') définit une route pour accéder aux analyses sur une URL raccourcie spécifique. La short_url est capturée à partir du chemin d'URL et passée à la fonction analytics.
  • La fonction appelle list_data(short_url), qui interroge la base de données pour obtenir des informations sur l'URL raccourcie, y compris le nombre de fois qu'elle a été consultée et la répartition des accès sur différents navigateurs et plateformes.
  • Les données extraites (info_fetch, counter_fetch, browser_fetch, platform_fetch) sont ensuite passées à la fonction render_template avec l'URL de l'hôte (shorty_host) pour afficher le modèle data.html. Ce modèle présente probablement les données d'analyse sous une forme conviviale pour l'utilisateur, telles que des tableaux ou des graphiques.

Ces routes étendent la fonctionnalité du service de raccourcissement d'URL, permettant non seulement de rediriger les utilisateurs d'URLs raccourcies vers leurs destinations d'origine, mais également de fournir des informations sur la manière dont ces URLs raccourcies sont utilisées, y compris les comptes d'accès et les types de dispositifs et de navigateurs à partir desquels les liens sont consultés. Ces informations peuvent être précieuses pour comprendre la portée et l'impact des URLs partagées.

✨ Vérifier la solution et pratiquer

Implémenter la route de recherche et exécuter l'application

Route de recherche

Configurez une route de recherche pour permettre aux utilisateurs de trouver des URL raccourcies par étiquettes. Cette route gère les requêtes GET et POST, affichant respectivement un formulaire de recherche et traitant les requêtes de recherche.

Ajoutez le code suivant à app.py :

@app.route('/search', methods=['GET', 'POST'])
def search():
    s_tag = request.form.get('search_url', '')
    if not s_tag:
        return render_template('index.html', error="Veuillez entrer un terme de recherche.")

    with get_db_connection() as conn, conn.cursor() as cursor:
        cursor.execute("SELECT * FROM WEB_URL WHERE TAG = %s", (s_tag,))
        search_tag_fetch = cursor.fetchall()
        return render_template('search.html', host=shorty_host, search_tag=s_tag, table=search_tag_fetch)
  • Le décorateur @app.route('/search', methods=['GET', 'POST']) configure la route à /search, gérant les requêtes GET et POST. Alors que la requête GET peut être utilisée pour afficher un formulaire de recherche, la requête POST traite les données du formulaire soumises par les utilisateurs.
  • À l'intérieur de la fonction search, request.form.get('search_url', '') tente de récupérer le terme de recherche à partir des données du formulaire soumises. Le deuxième paramètre ('') est la valeur par défaut si 'search_url' n'est pas trouvé, rendant le terme de recherche une chaîne vide dans de tels cas.
  • Si aucun terme de recherche n'est fourni (not s_tag), la fonction redirige l'utilisateur vers la page d'index avec un message d'erreur indiquant qu'un terme de recherche est requis.
  • Si un terme de recherche est fourni, la fonction se connecte à la base de données et exécute une requête SQL pour trouver tous les enregistrements dans la table `WEB_URL où la colonne TAG correspond au terme de recherche fourni. Cela permet aux utilisateurs de trouver toutes les URL raccourcies associées à une étiquette particulière.
  • Les résultats de cette requête (search_tag_fetch) sont ensuite passés à la fonction render_template, ainsi que l'URL de l'hôte (shorty_host) et le terme de recherche (s_tag), pour afficher le modèle search.html. Ce modèle affiche probablement les résultats sous forme de liste ou de tableau, permettant aux utilisateurs de voir tous les enregistrements correspondants et de peut-être interagir avec eux (par exemple, accéder aux URL d'origine, consulter les analyses).

Exécuter l'application

Enfin, ajoutez le code pour exécuter votre application Flask. Cela inclut la définition de l'hôte et du port sur lequel l'application doit écouter, ainsi que la spécification des variables d'environnement.

Ajoutez le code suivant en bas de app.py :

shorty_host = "https://****.labex.io/"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

Remarque : Vous devriez remplacer l'URL dans shorty_host par l'URL de l'environnement actuel. Vous pouvez la trouver en basculant vers l'onglet Web 8080, et l'URL devrait se terminer par /.

URL de l'onglet Web 8080

Maintenant, vous pouvez exécuter le projet en utilisant la commande suivante :

python app.py

Basculer vers l'onglet "Web 8080" et recharger la page web pour voir les effets suivants.

Convertir l'URL avec/ sans suffixe personnalisé, Rechercher des URL par étiquette, Accéder au lien :

Voir les informations sur le système d'exploitation et la plateforme utilisée pour accéder au lien :

✨ Vérifier la solution et pratiquer

Sommaire

Félicitations pour avoir terminé le projet de raccourcissement d'URL! Cet outil simplifie la diffusion d'URL longues en créant des liens plus courts et plus faciles à gérer. Cependant, il y a quelques considérations importantes à garder à l'esprit :

  1. Longueur de l'URL de base : Si l'URL de base du raccourcisseur lui-même est longue, les URL raccourcies résultantes peuvent ne pas être aussi courtes que prévu (comme dans le projet). La longueur totale de l'URL raccourcie inclut l'URL de base, ce qui peut limiter l'efficacité du raccourcisseur. Pour obtenir les URL les plus concises, envisagez d'utiliser une URL de base ou un nom de domaine plus court pour votre service.

  2. Restrictions d'incorporation de site web : Vous pourriez rencontrer des problèmes comme "Refusé d'afficher 'https://scholar.google.com/' dans une trame car il a défini 'X-Frame-Options' sur'sameorigin'." Cet erreur se produit car certains sites web utilisent l'en-tête HTTP X-Frame-Options pour empêcher leur contenu d'être affiché dans des iframes sur d'autres domaines, renforçant la sécurité contre les attaques de "clickjacking". Lorsqu'un site définit cet en-tête sur sameorigin, il restreint l'incorporation aux iframes qui partagent la même origine. Ce n'est pas une limitation du raccourcisseur d'URL mais une mesure de sécurité mise en œuvre par le site de destination. Pour une redirection sans heurt, il est préférable d'utiliser les URL raccourcies comme liens directs plutôt que de les incorporer dans des iframes.

Ces considérations mettent en évidence l'équilibre entre la commodité et la sécurité dans le développement web et l'importance de la sensibilisation des utilisateurs pour une utilisation optimale des outils.