Fermer

août 12, 2020

Créer une application météo en ligne de commande à Deno


Si vous avez suivi nos articles d’introduction sur Deno, vous êtes probablement intéressé par la rédaction de votre premier programme. Dans cet article, nous allons passer en revue l'installation du runtime Deno et créer un programme météo en ligne de commande qui prendra un nom de ville comme argument et renverra les prévisions météo pour les prochaines 24 heures.

Pour écrire du code pour Deno, je recommande vivement Visual Studio Code avec le plugin officiel Deno . Pour rendre les choses un peu plus intéressantes, nous allons écrire l'application en TypeScript.

Installation de Deno

Tout d'abord, installons Deno localement afin que nous puissions commencer à écrire notre script. Le processus est simple, car il existe des scripts d'installation pour les trois principaux systèmes d'exploitation.

Windows

Sous Windows, vous pouvez installer Deno à partir de PowerShell:

 iwr https://deno.land/x/install/ install.ps1 -useb | iex

Linux

Depuis le terminal Linux, vous pouvez utiliser la commande suivante:

 curl -fsSL https://deno.land/x/install/install.sh | sh

macOS

Sur un Mac, Deno peut être installé avec Brew:

 brew install deno

Après l'installation

Une fois le processus d'installation terminé, vous pouvez vérifier que Deno a été correctement installé en exécutant la commande suivante:

 deno --version

Vous devriez maintenant voir quelque chose de similaire à ceci:

 deno 1.2.0
v8 8.5.216
dactylographié 3.9.2

Créons un dossier pour notre nouveau projet (dans votre dossier personnel, ou à l’endroit où vous souhaitez conserver vos projets de codage) et ajoutons un fichier index.ts :

 mkdir weather-app
application météo cd
code index.ts

Remarque: comme je l'ai mentionné ci-dessus, j'utilise VS Code pour ce didacticiel. Si vous utilisez un autre éditeur, remplacez la dernière ligne ci-dessus.

Obtenir une entrée utilisateur

Notre programme va récupérer les prévisions météorologiques pour une ville donnée, nous devrons donc accepter le nom de la ville comme un argument lorsque le programme est exécuté. Les arguments fournis à un script Deno sont disponibles sous Deno.args . Déconnectons cette variable de la console pour voir comment cela fonctionne:

 console.log (Deno.args);

Exécutez maintenant le script, avec la commande suivante:

 deno run index.ts --city London

Vous devriez voir la sortie suivante:

 [ "--city", "London" ]

Bien que nous puissions analyser nous-mêmes ce tableau d’arguments, la bibliothèque standard de Deno comprend un module appelé flags qui s'en chargera pour nous. Pour l'utiliser, il suffit d'ajouter une instruction import en haut de notre fichier:

 import {parse} de "https://deno.land/std@0.61.0/flags/mod.ts" ;

Remarque: les exemples dans la documentation pour les modules de bibliothèque standard vous donneront une URL non versionnée (comme https://deno.land/std/flags/mod.ts ), qui pointera toujours vers la dernière version du code. Il est recommandé de spécifier une version dans vos importations, pour vous assurer que votre programme ne sera pas interrompu par les futures mises à jour. *

Utilisons la fonction importée pour analyser le tableau d'arguments en quelque chose de plus utile:

 const args = analyser (Deno.args);

Nous allons également modifier le script pour déconnecter notre nouvelle variable args pour voir à quoi cela ressemble. Alors maintenant, votre code devrait ressembler à ceci:

 import {parse} from "https://deno.land/std@0.61.0/flags/mod.ts";

const args = parse (Deno.args);

console.log (args);

Maintenant, si vous exécutez le script avec le même argument que précédemment, vous devriez voir la sortie suivante:

 Download https://deno.land/std@0.61.0/flags/mod.ts
Téléchargez https://deno.land/std@0.61.0/_util/assert.ts
Vérifiez le fichier: ///home/njacques/code/weather-app/index.ts
{_: []ville: "London"}

Chaque fois que Deno exécute un script, il recherche de nouvelles instructions d'importation. Toutes les importations hébergées à distance sont téléchargées, compilées et mises en cache pour une utilisation future. La fonction parse nous a fourni un objet, qui a une propriété city contenant notre entrée.

Remarque: si vous devez retélécharger les importations pour un script pour n'importe quelle raison, vous pouvez exécuter deno cache --reload index.ts .

Nous devrions également ajouter une vérification pour l'argument city et quitter le programme avec un message d'erreur s'il n'est pas fourni:

 if (args.city === undefined) {
    console.error ("Aucune ville fournie");
    Deno.exit ();
}

Parlons de l'API météo

Nous allons obtenir nos données de prévision à partir de OpenWeatherMap . Vous devrez créer un compte gratuit pour obtenir une clé API. Nous utiliserons leur API de prévisions sur 5 jours en lui passant un nom de ville comme paramètre.

Ajoutons du code pour récupérer les prévisions et les déconnecter sur la console, pour voir ce que nous obtenons :

 import {analyse} de "https://deno.land/std@0.61.0/flags/mod.ts";

const args = parse (Deno.args);

if (args.city === undefined) {
    console.error ("Aucune ville fournie");
    Deno.exit ();
}

const apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

const res = attendre fetch (`https://api.openweathermap.org/data/2.5/forecast?q=$ {args.city} & units = metric & appid = $ {apiKey}`);
const data = attendre res.json ();

console.log (données);

Deno essaie de supporter un grand nombre d'API de navigateur lorsque cela est possible, donc ici nous pouvons utiliser fetch sans avoir à importer de dépendances externes. Nous utilisons également le support de niveau supérieur await : normalement, nous devrions envelopper tout code qui utilise await dans une fonction async mais TypeScript ne nous oblige pas à faire cela, ce qui rend le code un peu plus agréable.

Si vous essayez d'exécuter ce script maintenant, vous rencontrerez un message d'erreur:

 Vérifiez le fichier: /// home / njacques / code / météo-app / index.ts
erreur: Autorisation non interceptéeDenied: accès réseau à "https://api.openweathermap.org/data/2.5/forecast?q=London&units=metric&appid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", réexécutez avec l'indicateur --allow-net
    à unwrapResponse ($ deno $ / ops / dispatch_json.ts: 42: 11)
    à Object.sendAsync ($ deno $ / ops / dispatch_json.ts: 93: 10)
    à async fetch ($ deno $ / web / fetch.ts: 266: 27)
    à async index.ts: 12: 13

Par défaut, tous les scripts Deno sont exécutés dans un bac à sable sécurisé: ils n’ont pas accès au réseau, au système de fichiers ou à des éléments tels que les variables d’environnement. Les scripts doivent recevoir une autorisation explicite pour les ressources système auxquelles ils doivent accéder. Dans ce cas, le message d'erreur nous permet de savoir de quelle autorisation nous avons besoin et comment l'activer.

Appelons à nouveau le script, avec l'indicateur correct:

 deno run --allow-net index.ts - ville de Londres

Cette fois, nous devrions récupérer une réponse JSON de l'API:

 {
  morue: "200",
  message: 0,
  cnt: 40,
  liste: [
    {
      dt: 1595527200,
      main: {
        temp: 22.6,
        feels_like: 18.7,
        temp_min: 21.04,
        temp_max: 22.6,
        pressure: 1013,
        sea_level: 1013,
        grnd_level: 1011,
        humidity: 39,
        temp_kf: 1.56
      },
      weather: [ [Object]],
      nuages: {tous: 88},
      vent: {vitesse: 4,88, deg: 254},
      visibilité: 10000,
      pop: 0,
      sys: {pod: "d"},
      dt_txt: "2020-07-23 18:00:00"
    },
    ...
  ],
  ville: {
    identifiant: 2643743,
    nom: "Londres",
    coord: {lat: 51.5085, lon: -0.1257},
    pays: "GB",
    population: 1000000,
    fuseau horaire: 3600,
    lever du soleil: 1595477494,
    coucher du soleil: 1595534525
  }
}

Vous pouvez consulter tous les détails de ce qui est renvoyé dans la réponse mais ce qui nous intéresse principalement, c'est le tableau de données de prévision dans la liste . Chaque objet du tableau contient un horodatage ( dt ), un objet principal avec des détails sur les conditions atmosphériques (température, humidité, pression, etc.) et un météo tableau contenant un objet avec une description du temps prévu.

Nous allons parcourir le tableau principal pour obtenir l'heure, la température et les conditions météorologiques prévues. Commençons par limiter le nombre d'enregistrements pour couvrir une période de 24 heures uniquement. Les données de prévision dont nous disposons avec le plan gratuit ne sont disponibles que par intervalles de trois heures. Nous aurons donc besoin de huit enregistrements:

 const prévisions = data.list.slice (0, 8)

Nous allons cartographier chacun des éléments de prévision et renvoyer un tableau des données qui nous intéressent:

 const prévisions = data.list.slice (0, 8) .map (item => [
    item.dt,
    item.main.temp,
    item.weather[0] .description,
]);

Si nous essayons d'exécuter le script maintenant, nous obtiendrons une erreur de compilation (si vous utilisez un IDE comme VS Code, cette erreur s'affichera également lorsque vous tapez le code): Paramètre 'item' a implicitement un type 'any'.

TypeScript nous demande de lui indiquer le type de variable qu'est item afin de savoir si nous faisons quelque chose avec lui qui pourrait causer une erreur lors de l'exécution. Ajoutons une interface, pour décrire la structure de item :

 interface ForecastItem {
    dt: chaîne;
    main: {temp: nombre; };
    météo: {description: string; } [];
}

Notez que nous ne décrivons pas toutes les propriétés de l'objet ici, seulement celles auxquelles nous allons réellement accéder. Dans notre situation, nous savons quelles propriétés nous voulons.

Ajoutons notre nouveau type à notre rappel map :

 const prévisions = data.list.slice (0, 8) .map (( item: ForecastItem) => [
    item.dt,
    item.main.temp,
    item.weather[0] .description,
]);

Si vous utilisez un IDE avec prise en charge de TypeScript, il devrait être en mesure de compléter automatiquement les propriétés de l'élément au fur et à mesure que vous tapez, grâce au type d'interface que nous avons fourni.

  • Créez un service class
  • Créer une interface pour la sortie

Formatage de la sortie

Maintenant que nous avons l'ensemble de données que nous voulons, examinons le formatage pour l'afficher à l'utilisateur.

Tout d'abord, transformons la valeur d'horodatage en une date lisible par l'homme. Si nous examinons la liste des modules tiers de Deno et recherchons «date», nous pouvons voir date-fns dans la liste. Nous pouvons utiliser le lien d'ici pour importer les fonctions que nous allons utiliser dans notre application Deno:

 import {fromUnixTime, format} depuis "https://deno.land/x/date_fns@v2.15.0/index .js ";

Nous pouvons maintenant passer l'horodatage via la fonction fromUnixTime pour obtenir un objet Date, puis passer cet objet au format afin d'obtenir une chaîne de date que nous voulons: [19659025] format (fromUnixTime (item.dt), "do LLL, k: mm", {})

La chaîne de formatage do LLL, k: mm nous donnera une date au format suivant: "24 juillet, 13:00".

Note: nous passons un objet vide comme troisième argument du format uniquement pour faire taire un avertissement IDE sur le nombre d'arguments attendu. Le code fonctionnera toujours bien sans lui.

Pendant que nous y sommes, arrondissons la valeur de la température à une seule décimale et ajoutons un indicateur d'unités:

 `$ {item.main.temp .toFixed (1)} C`

Maintenant que nos données de prévision sont formatées et prêtes à être affichées, présentons-les à l'utilisateur dans un petit tableau soigné, en utilisant le module ascii_table :

 import AsciiTable de 'https: // deno.land/x/ascii_table/mod.ts ';

...

table const = AsciiTable.fromJSON ({
  title: `$ {data.city.name} Prévisions`,
  rubrique: [ 'Time', 'Temp', 'Weather'],
  lignes: prévision
})

console.log (table.toString ())

Enregistrez et exécutez le script, et maintenant nous devrions avoir bien formaté et présenté des prévisions pour la ville que nous avons choisie, pour les prochaines 24 heures:

 .---------------- ----------------------------.
| Prévisions de Londres |
| -------------------------------------------- |
| Temps | Temp | Météo |
| ----------------- | ------- | ------------------ |
| 23 juillet, 19h00 | 17,8C | pluie légère |
| 23 juillet, 22h00 | 16,8C | pluie légère |
| 24 juillet, 1h00 | 16,0C | nuages ​​cassés |
| 24 juillet, 4h00 | 15,6C | pluie légère |
| 24 juillet, 7h00 | 16,0C | nuages ​​cassés |
| 24 juillet, 10h00 | 18,3C | nuages ​​épars |
| 24 juillet, 13h00 | 20,2C | pluie légère |
| 24 juillet, 16h00 | 20,2C | pluie légère |
«--------------------------------------------»

Liste complète du code

C'est un script assez compact, mais voici la liste complète du code:

 import {parse} de "https://deno.land/std@0.61.0/flags/mod.ts ";
importer {
  fromUnixTime,
  format,
} depuis "https://deno.land/x/date_fns@v2.15.0/index.js";
importer AsciiTable depuis "https://deno.land/x/ascii_table/mod.ts";

const args = parse (Deno.args);

if (args.city === undefined) {
  console.error ("Aucune ville fournie");
  Deno.exit ();
}

const apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

const res = attendre la récupération (
  `https://api.openweathermap.org/data/2.5/forecast?q=$ {args.city} & units = metric & appid = $ {apiKey}`,
);
const data = attendre res.json ();

interface prévisionsItem {
  dt: chaîne;
  main: {temp: nombre};
  météo: {description: string} [];
}

const prévisions = data.list.slice (0, 8) .map ((item: ForecastItem) => [
  format(fromUnixTime(item.dt), "do LLL, k:mm", {}),
  `${item.main.temp.toFixed(1)}C`,
  item.weather[0] .description,
]);

table const = AsciiTable.fromJSON ({
  title: `$ {data.city.name} Prévisions`,
  rubrique: ["Time", "Temp", "Weather"],
  lignes: prévision,
});

console.log (table.toString ());

Résumé

Vous avez maintenant votre propre programme de ligne de commande Deno qui vous donnera les prévisions météorologiques pour les prochaines 24 heures. En suivant ce didacticiel, vous devriez maintenant savoir comment démarrer un nouveau programme, importer des dépendances depuis la bibliothèque standard et des tiers, et accorder des autorisations de script.

Donc, ayant eu le goût d'écrire des programmes pour Deno, où devriez-vous aller ensuite? Je vous recommande vivement de lire le manuel pour en savoir plus sur les différentes options de ligne de commande et les API intégrées, mais aussi de garder un œil sur SitePoint pour plus de contenu Deno!

Deno Foundations

Soyez au courant de Deno. Notre collection Deno Foundations vous aide à faire vos premiers pas dans le monde Deno et au-delà, et nous y ajoutons constamment. Nous vous apporterons les tutoriels dont vous avez besoin pour devenir un pro. Vous pouvez toujours vous référer à notre index mis à jour à la fin de notre introduction à Deno:

Deno Foundations




Source link