npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@openagenda/sync-scripts

v4.0.5

Published

Pour commencer il faut créer un dossier pour accueillir notre paquet, par exemple:

Downloads

37

Readme

Prérequis

Pour commencer il faut créer un dossier pour accueillir notre paquet, par exemple:

mkdir sync-toulouse
cd sync-toulouse
yarn init -y

Ensuite il faut y ajouter la dépendance principale @openagenda/sync-scripts:

yarn add @openagenda/sync-scripts

Puis toutes les dépendances utiles en fonction du script, par exemple:

yarn add axios he sanitize-html lodash moment-timezone

Création des fichiers

La structure attendue est la suivante:

/
  config.js
  event.js
  index.js
  location.js
  run.js

config.js

"use strict";

module.exports = {
  agenda: {
      uid: 12345678
    },
    publicKey: 'dc70c13e0433737840e2b3f929dec79b',
    secretKey: '1a65e1e45defbb0911fb6f60c848453f',
    opencageKey: '0064ca2aab37b6ec21916f13a2dd1eb6',
    noBailOnInvalidImage: true,
    // downloadOnly: true,
    // simulate: true,
    // forceUpdate: true
};

Pendant les différentes phases de développement du script il sera possible d'utiliser les options downloadOnly, simulate et forceUpdate pour ne pas exécuter intégralement le script et se concentrer uniquement sur ce qui nous intéresse.

index.js

"use strict";

const log = require( '@openagenda/logs' )( 'sync-toulouse' );
const task = require( '@openagenda/sync-scripts' );
const OpenCage = require( '@openagenda/geocoder/Opencage' );
const event = require( './event' );
const location = require( './location' );
const config = require( './config' );

log.setConfig( {
  debug: {
    enable: true
  },
  token: config.insightOpsToken
} );

module.exports = async function syncTask() {
  const oaGeocoder = OpenCage( { key: config.opencageKey } );

  const stats = await task( {
    methods: {
      // list, map, getId, getUpdatedDate, postMap
      event: {
        ...event,
        map: event.map.bind(null, { oaGeocoder })
      },
      // get, map, getId, find
      location
    },
    directory: __dirname,
    log,
    ...config
  } );

  log( 'Stats: %j', stats );
};

C'est le fichier qui exporte la fonction de synchronisation, elle peut être appelée depuis un autre script ou depuis un CLI (run.js)

Paramétrages généraux

  • directory: la racine où sera stockée la base locale (dossier db) ainsi que les fichiers temporaires (dossier data)
  • agenda: objet contenant l'identifiant de l'agenda { uid }
  • noBailOnInvalidImage: lorsque un lien d'image invalide est fourni sur la source, celui ci n'interromp pas la synchro de l'événement par le script. Par défaut à false
  • defaultImageUrl: fournir une image par défaut lorsqu'aucune image n'est disponible en source

run.js

"use strict";

const synchronize = require( './index' );

synchronize();

C'est le point d'entrée du CLI, il peut être appelé avec la commande node run.

Il y a la possibilité d'utiliser des arguments ou des entrées utilisteurs avec yargs ou inquirer en modifiant un peu ce fichier. Pour utiliser plus rapidement les options downloadOnly, simulate ou forceUpdate par exemple.

event.list (event.js)

C'est la première fonction à créer, elle a pour but de récupérer page par page tous les événements de l'API distante.

"use strict";

const axios = require('axios');

const base = 'https://www.mairie-truc.fr/wp-json/wp/v2';

module.exports = async (query, offset = 0/*, limit = 10*/) => {
  const page = (offset / 10) + 1;
  let data;

  try {
    ({ data } = await axios.get(`${base}/evenement/?page=${page}`));
  } catch (e) {
    return [];
  }

  return data;
};

La fonction reçoit les arguments query, offset et limit et doit retourner un tableau d'événements.

event.map (event.js)

Cette fonction reçoit les événements bruts et doit retourner un objet qui contient les propriétés tel qu'elles sont attendues par l'API d'OpenAgenda (https://openagenda.zendesk.com/hc/fr/articles/115004460013--v2-agendas-agendaUid-events-post-Cr%C3%A9er-un-%C3%A9v%C3%A9nement)

L'objet contient une clé locations en plus pour y placer le ou les lieux de l'événements, aucun format n'est requis, le traitement du lieu se fera avec location.get et location.map:

locations: [
  { id: 1234 },
  /* ... */
]

Si un événement ne doit pas être repris ou doit être supprimé event.map peut retourner null.

map(event, formSchema, oaLocations)

Arguments:

  • event: item provenant du résultat de event.list
  • formSchema: le schema de l'agenda, pour définir les champs personnalisés
  • oaLocations: les lieux actuellement définits sur l'agenda, chargés en début d'execution du script

location.get (location.js)

location.get est là pour compléter un lieu provenant de event.map si nécessaire.

get(locationId, eventLocation)

Arguments:

  • locationId: l'identifiant fourni par la méthode location.getId
  • eventLocation: item provenant de l'array .locations défini dans event.map

location.map (location.js)

location.map est là pour transformer un lieu fraichement récupéré en lieu OpenAgenda (https://openagenda.zendesk.com/hc/fr/articles/115003242794--v1-locations-post-Cr%C3%A9ation-et-mise-%C3%A0-jour-de-lieux)

map(input, eventLocation)

Arguments:

  • input: donnée fournie par location.get
  • eventLocation: donnée correspondante fournie dans un item de .locations généré par event.map

event.getId (event.js)

Doit retourner un identifiant d'événément, il peut être partagé entre plusieurs événements qui sont en fait le même mais à différents lieux.

getId(event)

Arguments

  • event: item provenant du résultat de event.list

event.getUpdatedDate (event.js)

Doit retourner la dernière date de modification ou new Date(). Fonctionne avec un objet Date ou une chaine de caractères compatible avec moment-js

getUpdatedDate(event)

Arguments:

  • event: fourni par event.list

location.getId (location.js)

Doit retourner un identifiant de lieu unique utilisé par la suite par location.map

getId(eventLocation)

Arguments:

  • eventLocation: fourni par event.map, un item de .locations

location.find (location.js)

Son rôle est de trouver le lieu eventLocation dans oaLocations et de le retourner ou retourner null pour provoquer la création d'un nouveau lieu sur l'agenda.

find(oaLocations, eventLocation)

Arguments:

  • OALocations: les lieux actuellement définits sur l'agenda, chargés en début d'execution du script
  • eventLocation: fourni par event.map, un item de .locations

event.postMap (event.js)

Cette fonction n'est pas obligatoire, dans le cas où elle est présente elle est appellée une fois que tous les événements sont mappés et les horaires regroupés. Les horaires sont regroupés dans le même événement lorsque qu'on a des ids identiques pour l'événement et pour le lieu.

Exemple de cas d'usage: si une source de donnée défini un horaire par événement, plusieurs événements de la source peuvent correspondre à un même événement OA qui réunit une multitude d'horaires.

Au moment de l'appel, la concatenation des horaires a déjà eu lieu. event.postMap peut alors servir pour qualifier certaines valeurs additionnelles en évaluant l'intégralité des horaires concaténés.

Toulouse Métropole a une notion d'"Evénement ponctuel": si un événmeent se déroule sur une période de moins de 8 jours, la valeur doit être "vraie".

postMap(event, formSchema)

Arguments:

  • event: l'événement fourni par event.map
  • formSchema: le schema de l'agenda, pour définir les champs personnalisés

Supprimer des entrées générées par le script

Cerner les événements concernés par un where sur event & review_article

... where ra.review_id=13115 and e.owner_id=27554 and e.created_at > '2018-03-21' and e.created_at < '2018-03-22' and e.store='{"customFields":{"entreelibre":[]}}'
  1. Virer les références agenda_event:

    delete ae from agenda_event as ae left join event as e on ae.event_uid=e.uid left join review_article as ra on e.id=ra.event_id where ra.review_id=13115 and e.owner_id=27554 and e.created_at > '2018-03-21' and e.created_at < '2018-03-22' and e.store='{"customFields":{"entreelibre":[]}}'

  2. Virer les références event_2:

    delete e2 from event_2 as e2 left join event as e on e2.uid=e.uid left join review_article as ra on e.id=ra.event_id where ra.review_id=13115 and e.owner_id=27554 and e.created_at > '2018-03-21' and e.created_at < '2018-03-22' and e.store='{"customFields":{"entreelibre":[]}}'

  3. Virer les références event:

    delete e from event as e left join review_article as ra on e.id=ra.event_id where ra.review_id=13115 and e.owner_id=27554 and e.created_at > '2018-03-21' and e.created_at < '2018-03-22' and e.store='{"customFields":{"entreelibre":[]}}'

Faire un legacySync de l'agenda