Demande d'aide avec la lecture de fichier JSON
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Demande d'aide avec la lecture de fichier JSON
Autres remarques :
• tu ouvres et fermes ta BDD par deux fois. pourquoi ne pas faire en sorte qu'elle ne le soit qu'une seule fois ?
• l'instruction SQL "PRAGMA auto_vacuum = FULL" n'est à utiliser qu'une seule fois, au moment de la création de la BDD. Chaque BDD possède dans sa structure des paramètres qui lui sont propres. Celui-ci en est un et, une fois défini, il devient persistant tant qu'il n'est pas modifié...
• tu ouvres et fermes ta BDD par deux fois. pourquoi ne pas faire en sorte qu'elle ne le soit qu'une seule fois ?
• l'instruction SQL "PRAGMA auto_vacuum = FULL" n'est à utiliser qu'une seule fois, au moment de la création de la BDD. Chaque BDD possède dans sa structure des paramètres qui lui sont propres. Celui-ci en est un et, une fois défini, il devient persistant tant qu'il n'est pas modifié...
Re: Demande d'aide avec la lecture de fichier JSON
Je suis tout a fait d'accord avec toi, mais ce code n'a pour but que de vérifier la faisabilité deDeux remarques :
1) Il y a un travail d'optimisation à faire : En effet, des portions de code sont redondantes
2) Le recours à une GUI détaillant le déroulement des processus (avec leurs résultats - réussite ou échec) serait un plussurtout si tu veux en faire un exécutable (lequel accélérerait également l'exécution du code)
a) création d'une ou plusieurs BD, je n'ai pas encore fait le choix
b) faire de multiples accès en lecture de la BD
c) éventuellement, enregistrer une donnée ou l'effacer
d) actualiser la base avec des données fraiches. Effacer les anciennes et écrire les nouvelles.
e) lire des données diverses sous forme de JSON pour soit les afficher, soit les enregistrer pour usage différé
Mon application "my player iptv" gére une vingtaine de playlists dont certaines contiennent 300.000 entrées
A ce jour, voici comment je procéde
a) je télécharge sur disque une fois par jour la playlist qui m'intéresse
b) je traite la playlist a l'aide de Map/List/Structure pour pouvoir utiliser la playlist a ma convenance, regarder une chaine, un film ou une série
c) je ferme l'application
d) je ré-ouvre l'application et je reprend le processus a la phase b)
C'est lourd et ça prend du temps, que se soit pour la lecture de la playlist et son traitement ou que se soit pour la création des menus
Mon souhait était de transposer tout cela dans une BD
Une fois le premier traitement terminé, la BD n'est pas modifiée, sinon lors d'une mise à jour de la playlist.
Donc gain de temps.
A ce jour, les playlists sont enregistrées dans des dossiers qui sont dédiés a cette playlist
Par exemple, pour la playlist Freebox, le dossier est ".\m3u\Freebox\playlist.m3u" relatif au dossier de l'application.
Maintenant, je pense télécharger en mémoire la playlist, la traiter en BD et l'enregistrer en playlist.db
Mon idée est de faire ça pour toutes les playlists, soit au total environ 20 BD playlist.db
Ceci afin de ne pas être obligé de travailler en multi-tables dans une BD unique.
Pour la partie JSON, ça ne concerne que la playlist Freebox.
Son but premier est de me donner une correspondance Nom de chaine/uuid afin de pouvoir accéder au guide TV de la chaine.
Dans l'interface de "my player iptv", un clic droit sur une chaine amène un menu contextuel avec 2 choix:
1) ajouter aux favoris ou retirer des favoris
2) afficher le guide TV de la chaine
Je sais maintenant grâce a toi que c'est possible, même si je n'en ai jamais douté.
Ton aide et tes conseils avisés sont les bienvenus, ainsi que toute suggestion d'améliorations du processus.
Je prends bien note de toute tes remarques et je modifie mon code en rapport.
J'ai du pain sur la planche avant que mon application iptv soit satisfaisante, du moins a mes yeux.
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Re: Demande d'aide avec la lecture de fichier JSON
J'ouvre par deux fois la BD pour simuler 2 actions différentes, mais effectivement, j'aurais pu le faire en une seule fois.Autres remarques :
• tu ouvres et fermes ta BDD par deux fois. pourquoi ne pas faire en sorte qu'elle ne le soit qu'une seule fois ?
• l'instruction SQL "PRAGMA auto_vacuum = FULL" n'est à utiliser qu'une seule fois, au moment de la création de la BDD. Chaque BDD possède dans sa structure des paramètres qui lui sont propres. Celui-ci en est un et, une fois défini, il devient persistant tant qu'il n'est pas modifié...
Je prend note pour "PRAGMA auto_vacuum = FULL"
A passer une seule fois au moment de la création de la BD (avant ou après création de la table. ?)
Une fois cette commande passée et inscrite dans les paramètres de la BD, suis-je obligé d'utiliser la commande "VACUUM" ou alors cette commande est automatique.
Si je dois la passer, quel est le moment le plus judicieux. ?
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Demande d'aide avec la lecture de fichier JSON
Je t'avouerai ne pas avoir tout bien compris le cheminement de ce que tu souhaites faire et la chaleur n'aide pas non plus !
Et quand tu parles de 'traitement', c'est le processus complet ? une partie du processus ?
Tu pourrais ensuite t'appuyer sur ce champ pour faire toutes sortes d'opérations (SELECT, UPDATE, DELETE, ...)
Après, dans ma logique "à moi", je crée la BDD, je mets à jour ses paramètres et ensuite, seulement, je crée les tables.
Le paramètre 'auto_vaccum=full' fera décroître automatiquement la taille en octets de ta BDD en libérant l'espace inutilisé à la suite de suppressions ou MàJ mais ne la défragmentera pas.
La commande 'vacuum' fera les deux, libération d'espace et défragmentation. L'intérêt de la défragmentation, tout comme pour un disque dur, est de rendre plus rapide l'accès aux données.
'vacuum' peut être lancée à n'importe quel moment. Toutefois, le moment idéal étant juste avant la fermeture BDD. Mais, tu peux aussi l'exécuter après de très grosses opérations de suppressions ou de MàJ de données. Cela rendra le 'vacuum' final moins long en temps d'exécution.

Pour quelle raison/à quelles fins envisages-tu éventuellement la création de plusieurs BDD ?cage a écrit : a) création d'une ou plusieurs BD, je n'ai pas encore fait le choix
Là, je comprends pas ! Pourquoi ré-ouvrir ? C'est la même playlist ? Si oui ou si non, en quoi est-elle différente ?cage a écrit : d) je ré-ouvre l'application et je reprend le processus a la phase b)
Et quand tu parles de 'traitement', c'est le processus complet ? une partie du processus ?
Pourquoi ne pas envisager un champ supplémentaire dans ta table qui te permettrait de distinguer chacune des playlists ?cage a écrit : Mon idée est de faire ça pour toutes les playlists, soit au total environ 20 BD playlist.db
Ceci afin de ne pas être obligé de travailler en multi-tables dans une BD unique.
Tu pourrais ensuite t'appuyer sur ce champ pour faire toutes sortes d'opérations (SELECT, UPDATE, DELETE, ...)
Peu importe, l'idéal étant que cela soit fait avant toute opération de suppression ou de MàJ.cage a écrit : Je prend note pour "PRAGMA auto_vacuum = FULL"
A passer une seule fois au moment de la création de la BD (avant ou après création de la table. ?)
Après, dans ma logique "à moi", je crée la BDD, je mets à jour ses paramètres et ensuite, seulement, je crée les tables.
Oui et non !cage a écrit : Une fois cette commande passée et inscrite dans les paramètres de la BD, suis-je obligé d'utiliser la commande "VACUUM" ou alors cette commande est automatique.
Le paramètre 'auto_vaccum=full' fera décroître automatiquement la taille en octets de ta BDD en libérant l'espace inutilisé à la suite de suppressions ou MàJ mais ne la défragmentera pas.
La commande 'vacuum' fera les deux, libération d'espace et défragmentation. L'intérêt de la défragmentation, tout comme pour un disque dur, est de rendre plus rapide l'accès aux données.
'vacuum' peut être lancée à n'importe quel moment. Toutefois, le moment idéal étant juste avant la fermeture BDD. Mais, tu peux aussi l'exécuter après de très grosses opérations de suppressions ou de MàJ de données. Cela rendra le 'vacuum' final moins long en temps d'exécution.
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Demande d'aide avec la lecture de fichier JSON
Notes sur ton code :
peut être remplacé par
Là aussi tu peux te servir de SetDatabaseXxxx()
Note : Pour information, toutes les valeurs définies par des SetDatabaseXxxx() sont remises à 0 dès la première utilisation d'un DatabaseQuery ou DatabaseUpdate. Ainsi :
Toutes les portions de code de ce type peuvent placées à l'intérieur d'une procédure.
Il te suffit ensuite de retourner la valeur JSON pour savoir si tu peux continuer à travailler avec l'arbre JSON ou non.
Code : Tout sélectionner
CheckDatabaseUpdate(OUT, #QUERY_DELETE_TABLE)
CheckDatabaseUpdate(OUT, #QUERY_CREATE_TABLE)
Code : Tout sélectionner
CheckDatabaseUpdate(OUT, "DELETE * FROM Database")
Code : Tout sélectionner
CheckDatabaseQuery(DB, #QUERY_SELECT_TABLE+"'%TF1%'")
Code : Tout sélectionner
#QUERY_SELECT_TABLE="SELECT UUID,NAME FROM DATABASE WHERE NAME LIKE ?" ; (ou %?% si vraiment nécessaire)
[...]
SetDatabaseString(DB,0,"TF1")
CheckDatabaseUpdate(DB,#QUERY_SELECT_TABLE)
Code : Tout sélectionner
SetDatabaseString(DB,0,"TF1")
CheckDatabaseQuery(DB,"SELECT * FROM Database WHERE Name=?") ; Récupérera tous les enregistrements où Name=TF1
FinishDatabaseQuery(DB)
CheckDatabaseQuery(DB,"SELECT * FROM Database WHERE Name=?") ; Récupérera tous les enregistrements où Name est un champ vide puisqu'il n'y pas eu de SetDataseString entre les deux 'SELECT'
Code : Tout sélectionner
*TamponJSON = ReceiveHTTPMemory(url$)
If *TamponJSON
JSON = CatchJSON(#PB_Any, *TamponJSON, MemorySize(*TamponJSON))
If JSON
ChaineJSON$ = ComposeJSON(JSON)
; ------- !!!! IMPORTANT !!!! ----------
; Remplacer les valeurs true et false pour qu'elles puissent être récupérées via la structure DATAS_GUIDE
ChaineJSON$=ReplaceAllString(ChaineJSON$,": true," ,":1,",#PB_String_NoCase)
ChaineJSON$=ReplaceAllString(ChaineJSON$,":true," ,":1,",#PB_String_NoCase)
ChaineJSON$=ReplaceAllString(ChaineJSON$,": false,",":0,",#PB_String_NoCase)
ChaineJSON$=ReplaceAllString(ChaineJSON$,":false," ,":0,",#PB_String_NoCase)
; --------------------------------------
JSON = ParseJSON(#PB_Any, ChaineJSON$, #PB_JSON_NoCase)
Else
Debug "Echec lors de l'analyse des données JSON"
EndIf
FreeMemory(*TamponJSON)
Else
Debug "Echec de la réception en mémoire du fichier JSON"
EndIf
Il te suffit ensuite de retourner la valeur JSON pour savoir si tu peux continuer à travailler avec l'arbre JSON ou non.
Dernière modification par boddhi le jeu. 24/août/2023 21:58, modifié 2 fois.
Re: Demande d'aide avec la lecture de fichier JSON
Oui, c'est la même playlist, donc la seule différence, c'est que j'ai fermé l'application.Là, je comprends pas ! Pourquoi ré-ouvrir ? C'est la même playlist ? Si oui ou si non, en quoi est-elle différente ?
Comme la liste de toute les chaines est chargée dans une ListIconGadget(), il faut bien que je relise la playlist pour alimenter la ListIconGadget()
Une fois cette playlist (fichier playlist.m3u) transposé en DB, a chaque démarrage de mon application, lecture de la BD et insertion dans la ListIconGadget()
Ce sera beaucoup plus rapide.
Question de facilité, il y a beaucoup de disparité dans les playlists et j'ai du m'adapter a chacune.Pour quelle raison/à quelles fins envisages-tu éventuellement la création de plusieurs BDD ?
Je peux passer de fichier a BD chaque playlist en prenant mon temps pour le faire.
Et au final, peut-être tout mettre dans la même BD.
Déjà, chaque table porte le nom de la playlist en fonction du fournisseur (AUMALE,FREEBOX,JOURNALSAT,PLEX,PLUTO,RADIOS,RAKUTEN,SAMSUNG,TVCLUB) et bien d'autres.
Je n'aurais aucun mal donc a toutes les enregistrer dans la même BD.
Le traitement de la playlist, hors le fait de la télécharger pour avoir les dernières mis à jour, c'estEt quand tu parles de 'traitement', c'est le processus complet ? une partie du processus ?
a) la lire ligne a ligne pour en retirer les informations telles que "NomDeChaine" ou "NomDeFilm" ou "NomDeSérie" et les liens externes associés et mettre tout ça en forme dans des List/MAp a l'aide de structures
b) créer tout les menus qui donnent accès a ces chaines/films/séries
c) afficher dans la ListIconGadget() la liste Live (Chaines en live)
Ensuite, on a le choix d'afficher les films ou les séries ou les chaines.
Un clic sur le titre d'une colonne de la ListIconGadget() permet de trier en ascendant/descendant
Tout cela grâce au List/MAp crées précédemment.
C'est pour cela que je veux tout passer en BD, car 1 requête SQL bien ficelée, et le tour est joué.
Me reste aussi a voir comment je gère les chaines mises en favoris lors d'une mise à jour de la playlist.
Aujourd'hui, c'est géré dans un fichier favoris.txt dans chaque dossier des playlists
Autrement, Ok pour la commande "VACUUM"
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Demande d'aide avec la lecture de fichier JSON
J'ai peut-être (même probablement) sauté un wagon... mais pourquoi ne pas alimenter la BDD et la ListIconGadget en même temps que l'analyse de l'arbre JSON ?cage a écrit : Oui, c'est la même playlist, donc la seule différence, c'est que j'ai fermé l'application.
Comme la liste de toute les chaines est chargée dans une ListIconGadget(), il faut bien que je relise la playlist pour alimenter la ListIconGadget()
Une fois cette playlist (fichier playlist.m3u) transposé en DB, a chaque démarrage de mon application, lecture de la BD et insertion dans la ListIconGadget()
Genre :
Code : Tout sélectionner
If ExamineJSONMembers(jsonObjectValue) ; si il contient des membres
While NextJSONMember(jsonObjectValue)
AddElement(CHAINES())
With CHAINES()
\NomCanal=JSONMemberKey(jsonObjectValue)
ExtractJSONStructure(JSONMemberValue(jsonObjectValue),\DonneesChaine,DATAS_CHAINE)
; /////////////////////////////////////
; Ici
CheckDatabaseUpdate(DB,...........)
AddGadgetItem(ListIcon,...........)
; /////////////////////////////////////
EndWith
Wend
EndIf
Re: Demande d'aide avec la lecture de fichier JSON
Lest playlists sont au format m3u sous cette forme (ce n'est pas du JSON)J'ai peut-être (même probablement) sauté un wagon... mais pourquoi ne pas alimenter la BDD et la ListIconGadget en même temps que l'analyse de l'arbre JSON ?
Je prends l'exemple de la Freebox qui est très simple par rapport a d'autres playlists
Code : Tout sélectionner
#EXTM3U
#EXTINF:0,1 - TF1 (TNT)
rtsp://mafreebox.freebox.fr/fbxdvb/stream?tsid=6&nid=8442&sid=1537&frontend=1
#EXTINF:0,2 - France 2 (bas débit)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=201&flavour=ld
#EXTINF:0,2 - France 2 (auto)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=201
#EXTINF:0,2 - France 2 (HD)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=201&flavour=hd
#EXTINF:0,2 - France 2 (standard)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=201&flavour=sd
#EXTINF:0,2 - France 2 (TNT)
rtsp://mafreebox.freebox.fr/fbxdvb/stream?tsid=1&nid=8442&sid=257&frontend=1
#EXTINF:0,3 - France 3 (auto)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=202
#EXTINF:0,3 - France 3 (HD)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=202&flavour=hd
#EXTINF:0,3 - France 3 (standard)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=202&flavour=sd
#EXTINF:0,3 - France 3 (bas débit)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=202&flavour=ld
#EXTINF:0,3 - F3 Paris Ile-de-France (TNT)
rtsp://mafreebox.freebox.fr/fbxdvb/stream?tsid=1&nid=8442&sid=273&frontend=1
#EXTINF:0,4 - CANAL+ (TNT)
rtsp://mafreebox.freebox.fr/fbxdvb/stream?tsid=3&nid=8442&sid=769&frontend=1
#EXTINF:0,4 - CANAL+ (TNT)
rtsp://mafreebox.freebox.fr/fbxdvb/stream?tsid=3&nid=8442&sid=778&frontend=1
#EXTINF:0,5 - France 5 (auto)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=203
#EXTINF:0,5 - France 5 (HD)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=203&flavour=hd
#EXTINF:0,5 - France 5 (standard)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=203&flavour=sd
#EXTINF:0,5 - France 5 (TNT)
rtsp://mafreebox.freebox.fr/fbxdvb/stream?tsid=4&nid=8442&sid=1045&frontend=1
#EXTINF:0,6 - M6 (TNT)
rtsp://mafreebox.freebox.fr/fbxdvb/stream?tsid=4&nid=8442&sid=1025&frontend=1
#EXTINF:0,7 - Arte (HD)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=204&flavour=hd
#EXTINF:0,7 - Arte (standard)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=204&flavour=sd
#EXTINF:0,7 - Arte (bas débit)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=204&flavour=ld
#EXTINF:0,7 - Arte (auto)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=204
#EXTINF:0,7 - Arte (TNT)
rtsp://mafreebox.freebox.fr/fbxdvb/stream?tsid=4&nid=8442&sid=1031&frontend=1
#EXTINF:0,8 - C8 (standard)
rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=372&flavour=sd
La lecture se fait en séquentiel, Nom de la chaine, URL de la chaine puis Nom de la chaine, URL de la chaine et ainsi de suite.
Donc il faut associer chaque chaine a son URL plus un index d'ordre pour pouvoir faire un tri sur chaque titre de colonne.
Le JSON est particulier a la Freebox et donne uniquement des infos sur les chaines et ne sert que pour le guide TV
Quand on clique sur le nom d'une chaine, elle s'ouvre dans le player de son choix (vlc par exemple)
La BD n'est créé qu'une fois par jour, mais pour Freebox, une fois par semaine suffit largement, la liste change rarement.
Donc, si tous les jours je lance l'application, il faut bien que je remplisse la ListIconGadget() avec les infos des chaines.
D’où, je suis obligé de relire la playlist sauf si je la transpose en BD. Dans ce cas, une seule requête SQL suffit pour documenter la ListIconGadget()
Rapidité et simplicité.
Pour la BD de la Freebox, 2 tables sont nécessaires, une que je nomme CHAINES pour enregistrer les infos JSON et l'autre FREEBOX pour enregistrer toutes les informations de la playlist.
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Re: Demande d'aide avec la lecture de fichier JSON
Un exemple un peu plus compliqué d'une playlist au format m3u
Il y a plus de travail pour parser cette playlist qui est complétement différente de celle de la Freebox.
cage
Code : Tout sélectionner
#EXTM3U
#EXTINF:-1 tvg-id="TF1.fr" tvg-name="FR - TF 1" tvg-logo="http://logo.protv.cc/picons-dino/logos/tf1hd.png" group-title="|EU| FRANCE GENERAL",FR - TF 1
http://line.premium-dino.com:80/Username/Password/543147
#EXTINF:-1 tvg-id="M6.fr" tvg-name="FR - M6" tvg-logo="http://logo.protv.cc/picons-dino/logos/m6hd.png" group-title="|EU| FRANCE GENERAL",FR - M6
http://line.premium-dino.com:80/Username/Password/543159
#EXTINF:-1 tvg-id="France2.fr" tvg-name="FR - FRANCE 2" tvg-logo="http://logo.protv.cc/picons-dino/logos/france2hd.png" group-title="|EU| FRANCE GENERAL",FR - FRANCE 2
http://line.premium-dino.com:80/Username/Password/543149
#EXTINF:-1 tvg-id="France3.fr" tvg-name="FR - FRANCE 3" tvg-logo="http://logo.protv.cc/picons-dino/logos/france3hd.png" group-title="|EU| FRANCE GENERAL",FR - FRANCE 3
http://line.premium-dino.com:80/Username/Password/543151
#EXTINF:-1 tvg-id="France4.fr" tvg-name="FR - FRANCE 4" tvg-logo="http://logo.protv.cc/picons-dino/logos/france4.png" group-title="|EU| FRANCE GENERAL",FR - FRANCE 4
http://line.premium-dino.com:80/Username/Password/543153
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Demande d'aide avec la lecture de fichier JSON
Avec des StringField(), c'est un jeu d'enfant !cage a écrit : Un exemple un peu plus compliqué d'une playlist au format m3u


Re: Demande d'aide avec la lecture de fichier JSON
Procédure simplifiée pour lire une playlist genre playlist Freebox
cage
Code : Tout sélectionner
Structure CHAINES
INDEX.s
GENRE.s
MEDIA.s
TITRE.s
GROUP.s
SERIE.s
PAYS.s
REFID.s
EndStructure
Global NewList LISTE.CHAINES()
Procedure lecture_playlist()
IN = ReadFile(#PB_Any, PLAYLIST.s)
If IN
;;; === LECTURE PLAYLIST ===
While Eof(IN) = 0
entry$ = Trim(ReadString(IN))
If entry$ = #Null$
Continue
EndIf
begin$ = UCase(Left(entry$,7))
Select begin$
Case "#EXTINF"
I+1
VRAI_CHANNEL+1
title$ = #Null$
If FindString(entry$,"--") Or
FindString(entry$,"**") Or
FindString(entry$,"==") Or
FindString(entry$,"++") Or
FindString(entry$,"##") Or
FindString(entry$,"- -")
VRAI_CHANNEL-1
FAUX_CHANNEL+1
Continue
EndIf
title$ = StringField(entry$,2,",")
title$ = Trim(title$)
title$ = UCase(title$)
title$ = replaceAllString(title$,Space(2),Space(1))
fra$ = "FR:"
foo$ = "FR:"
pay$ = #Empty$
If Left(title$, 3) = foo$
pay$ = fra$
title$ = Trim(StringField(title$, 2, foo$))
title$ = fra$ + " " + title$
EndIf
foo$ = "|FR|"
If Left(title$, 4) = foo$
pay$ = fra$
title$ = Trim(StringField(title$, 2, foo$))
title$ = fra$ + " " + title$
EndIf
foo$ = "[FR]"
If Left(title$, 4) = foo$
pay$ = fra$
title$ = Trim(StringField(title$, 2, foo$))
title$ = fra$ + " " + title$
EndIf
foo$ = "FR -"
If Left(title$, 4) = foo$
pay$ = fra$
title$ = Trim(StringField(title$, 2, foo$))
title$ = fra$ + " " + title$
EndIf
If FindString(title$, "_")
title$ = ReplaceString(title$, "_", " ")
EndIf
title$ = replaceAllString(title$,Space(2),Space(1))
Case "HTTP://", "HTTPS:/", "RTSP://"
LAST_CHANNEL+1
If title$ = #Null$
Continue
EndIf
LIVE+1
N = CountString(entry$, "/")
refid$ = Str(LAST_CHANNEL)
lastid$ = StringField(entry$, N+1, "/")
N = 6
Select fournisseur$
Case #FREEBOX : refid$ = RSet(refid$ ,3,"0") : N=3
Case #TVCLUB : refid$ = lastid$ : N=2
Default : refid$ = RSet(refid$ ,6,"0")
EndSelect
;;; ====== LISTE() ======
AddElement(LISTE())
LISTE()\INDEX = RSet(Str(I),N,"0")
LISTE()\GENRE = #live
LISTE()\MEDIA = entry$
LISTE()\TITRE = title$
LISTE()\REFID = refid$
EndSelect
;;; === FIN LECTURE PLAYLIST ===
Wend
CloseFile(IN)
EndIf ; If IN
EndProcedure
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Demande d'aide avec la lecture de fichier JSON
Comme tous les chemins mènent à Rome et pour le fun, voici ma proposition d'analyse de ton fichier Freebox avec utilisation des StringField()cage a écrit : Procédure simplifiée pour lire une playlist genre playlist Freebox
Code : Tout sélectionner
EnableExplicit
Structure INFOSCHAINE
Nom.s
Groupe.s
Langue.s
UrlChaine.s
UrlLogo.s
UrlVideo.s
EndStructure
;
NewList Chaines.INFOSCHAINE()
Define.s ChaineM3U,LigneFichier
Define.a LigneDonneeOk,FichierValide
Define.l NoLigneFichier,NbLignesDonnees
;
#Fichier=""
CompilerIf #Fichier=""
MessageRequester("Erreur","La constante 'Fichier' n'a pas reçu de nom de fichier !",#PB_MessageRequester_Error)
End
CompilerEndIf
If ReadFile(0,#Fichier,#PB_UTF8)
While Not Eof(0)
LigneFichier=Trim(ReadString(0))
NoLigneFichier+1
If LigneFichier
If UCase(LigneFichier)="#EXTM3U" And NbLignesDonnees=0
FichierValide=#True
Else
If Not FichierValide
Debug "Fichier non valide"
Break
EndIf
Select UCase(StringField(LigneFichier,1,":"))
Case "#EXTINF"
If Not LigneDonneeOk
NbLignesDonnees+1
AddElement(Chaines())
With Chaines()
\UrlChaine=StringField(StringField(LigneFichier,2,"tvg-id="+Chr(34)),1,Chr(34))
LigneDonneeOk=Bool(\UrlChaine<>"")
If LigneDonneeOk
\UrlLogo=StringField(StringField(LigneFichier,2,"tvg-logo="+Chr(34)),1,Chr(34))
\Groupe=StringField(StringField(LigneFichier,2,"group-title="+Chr(34)),1,Chr(34))
\Nom=StringField(StringField(LigneFichier,2,","),1,Chr(34))
\Langue=StringField(\Nom,1," - ")
\Nom=StringField(\Nom,2," - ")
EndIf
EndWith
EndIf
If Not LigneDonneeOk
Debug "Ligne n° "+NoLigneFichier+" : Mauvais format de ligne, Url vidéo attendue !"
EndIf
Case "HTTP","HTTPS","RSTP"
If LigneDonneeOk
With Chaines()
\UrlVideo=LigneFichier
Debug "Nom chaîne : "+\Nom+#LF$+"Groupe : "+\Groupe+#LF$+"Langue : "+\Langue+#LF$+"Url chaîne : "+\UrlChaine+#LF$+"Url logo : "+\UrlLogo+#LF$+"Url vidéo : "+\UrlVideo
Debug "*********************************************************"
EndWith
LigneDonneeOk=#False
Else
Debug "Ligne n° "+NoLigneFichier+" : Mauvais format de ligne, #EXTINF attendu !"
EndIf
EndSelect
EndIf
EndIf
Wend
CloseFile(0)
Debug ""+NbLignesDonnees+" ligne(s) de données de chaînes traitée(s)"
Else
Debug "Erreur système : "+GetLastError_()
EndIf
Re: Demande d'aide avec la lecture de fichier JSON
Bonjour,
Je suis entrain de travailler sur ton code pour améliorer ma lecture des playlist.m3U qui date de plusieurs années maintenant.
J'ai mis sur mon site 3 fichiers playlist.m3u différents pour tester le code.
Télécharger playlist-dino.7z
Télécharger playlist-freebox.7z
Télécharger playlist-maroc.7z
Ces playlists sont modifiées et ne sont pas donc pas utilisables en l'état.
Seule la playlist Freebox est vraie mais non utilisable si on est pas chez Free.
Je posterais ici mon code fait a partir du tien dès qu'il sera assez avancé.
Je trouve vraiment très plaisant et très instructif notre échange.
Comme quoi le JSON ouvre des portes.
cage
Comme promis, voici le code
Reste encore a l'améliorer et certainement a l'optimiser.
Des idées ?
cage
Je suis entrain de travailler sur ton code pour améliorer ma lecture des playlist.m3U qui date de plusieurs années maintenant.
J'ai mis sur mon site 3 fichiers playlist.m3u différents pour tester le code.
Télécharger playlist-dino.7z
Télécharger playlist-freebox.7z
Télécharger playlist-maroc.7z
Ces playlists sont modifiées et ne sont pas donc pas utilisables en l'état.
Seule la playlist Freebox est vraie mais non utilisable si on est pas chez Free.
Je posterais ici mon code fait a partir du tien dès qu'il sera assez avancé.
Je trouve vraiment très plaisant et très instructif notre échange.
Comme quoi le JSON ouvre des portes.
cage
Comme promis, voici le code
Code : Tout sélectionner
EnableExplicit
SetCurrentDirectory(GetPathPart(ProgramFilename()))
#films = "Films"
#live = "Live"
#series = "Séries"
#inconnu = "Inconnu"
Structure INFOSCHAINE
Index.l ; index de la vidéo dans l'ordre d'apparition dans la playlist
Nom.s ; nom de la vidéo a afficher (nom du live, film ou série)
Genre.s ; live, film ou série
Serie.s ; titre de la série
Groupe.s ; group-title, nom du groupe d'appartenance de la vidéo
Langue.s ;
URLVideo.s ; contenu de la ligne commençant par http:,https:,rtsp:
;ces données concernent le guide des programmes et peuvent êtres absentes
TVGId.s ; tvg-id
TVGLogo.s ; tvg-logo
TVGName.s ; tvg-name
EndStructure
;
NewList Chaines.INFOSCHAINE()
Define.s LigneFichier,Genre, Serie, NomVideo
Define.a LigneDonneeOk,FichierValide
Define NoLigneFichier,NbLignesDonnees,NbCommas,Index
Define IN
;
Global LIVE, FILMS, SERIES
Global LAST_CHANNEL=0
Global VRAI_CHANNEL=0
Global FAUX_CHANNEL=0
;
Global regex_nulle,regex_genre, regex_serie
;
; Sélectionner une playist pour commencer
;#PLAYLIST$ = "playlist-dino.m3u"
;#PLAYLIST$ = "playlist-freebox.m3u"
;#PLAYLIST$ = "playlist-maroc.m3u"
CompilerIf Not Defined(PLAYLIST$, #PB_Constant)
#PLAYLIST$=#Empty$
MessageRequester("Erreur","La constante 'PLAYLIST' n'a pas reçu de nom de fichier !",#PB_MessageRequester_Error)
End
CompilerEndIf
IN=ReadFile(#PB_Any,#PLAYLIST$,#PB_UTF8)
If IN
Define HeureDebut=Date()
Index=0
LigneDonneeOk=#False
ClearList(Chaines())
; commenter la ligne suivante pour garder toutes les vidéos
regex_nulle=CreateRegularExpression(#PB_Any, "([*]{3}|[#]{3}|[=]{3}|[-]{3}|[+]{3}|- -)")
; permet d'extraire le genre des vidéos (live, films ou séries)
regex_genre=CreateRegularExpression(#PB_Any, "(?i)(/live/|/movie/|/series/)")
; permet d'extraire les numéros saison/épisode d'une série
regex_serie=CreateRegularExpression(#PB_Any, " S.. E..")
While Not Eof(IN)
LigneFichier=Trim(ReadString(IN))
NoLigneFichier+1
;If NoLigneFichier > 20 : Break : EndIf
If LigneFichier
Select UCase(StringField(LigneFichier,1,":"))
Case "#EXTINF"
LAST_CHANNEL+1
If regex_nulle
NbCommas=CountString(LigneFichier,",")
NomVideo=StringField(LigneFichier,NbCommas+1,",")
If ExamineRegularExpression(regex_nulle, NomVideo)
If NextRegularExpressionMatch(regex_nulle)
Debug NomVideo
FAUX_CHANNEL+1
NoLigneFichier+1
LigneDonneeOk=#False
; on ne tiendra pas compte de la ligne qui suit
ReadString(IN)
Continue
EndIf
EndIf
EndIf ; If regex_nulle
If Not LigneDonneeOk
Index+1
NbLignesDonnees+1
VRAI_CHANNEL+1
;La première ligne commence par #EXTINF: (durée) [attributs], (titre).
;Les paramètres requis sont : durée et titre.
;Dans le cas d’une chaine TV, la durée doit toujours être à 0 ou -1.
;Les attributs ne sont pas obligatoires, voici la liste des attributs pris en charge:
;tvg-shift - décalage horaire du guide TV
;tvg-id - ?
;tvg-name - identifiant du guide TV
;tvg-logo - logo de la chaîne (url)
;audio-track - piste audio de la chaîne, si supportée.
; - Saisir le code langue au format ISO 639-2,
; vous pouvez utiliser plusieurs codes séparés par une virgule (ex:"eng, rus, fre").
; - Le premier élément de la liste sera la langue définie par défaut.
;aspect-ratio - définit le ratio d’image (peut ne pas être disponible pour certains modèles TV).
; - Valeurs disponibles: 16:9, 3:2, 4:3, 1,85:1, 2,39:1
;Exemples:
;#EXTINF:0,1 - TF1 (TNT)
;#EXTINF:-1,FR: TF1 FHD
;#EXTINF:-1 tvg-id="CLUB1." tvg-name="Club 1" tvg-logo="1.png" group-title="tvclub" ,Club 1
;#EXTINF:-1 tvg-id="TF1.fr" tvg-name="|FR| TF1" tvg-logo="TF1.png" group-title="FRANCE TNT",|FR| TF1
;#EXTINF:-1 tvg-id="TF1.fr" tvg-name="FR - TF 1" tvg-logo="tf1hd.png" group-title="|EU| FRANCE GENERAL",FR - TF 1
AddElement(Chaines())
With Chaines()
\Nom = NomVideo
If \Nom = #Empty$ : \Nom = #inconnu : EndIf
LigneDonneeOk=Bool(\Nom<>"")
If LigneDonneeOk
\Index = index
\TVGId =StringField(StringField(LigneFichier,2,"tvg-id=" +#DQUOTE$),1,#DQUOTE$)
;\TVGLogo=StringField(StringField(LigneFichier,2,"tvg-logo=" +#DQUOTE$),1,#DQUOTE$)
\TVGName=StringField(StringField(LigneFichier,2,"tvg-name=" +#DQUOTE$),1,#DQUOTE$)
\Groupe =StringField(StringField(LigneFichier,2,"group-title="+#DQUOTE$),1,#DQUOTE$)
;il n'est pas évident d'extraire la langue car il n'y a pas de format normalisé
\Langue =StringField(\TVGName,1," - ") ; a traiter différemment ???
EndIf
EndWith
EndIf
If Not LigneDonneeOk
Debug "Ligne n° "+NoLigneFichier+" : Mauvais format de ligne, Nom vidéo attendue !"
Debug LigneFichier
Debug "\Nom="+Chaines()\Nom
EndIf
Case "HTTP","HTTPS","RTSP"
If LigneDonneeOk
Chaines()\Genre=#Empty$
If regex_genre
If ExamineRegularExpression(regex_genre, LigneFichier)
If NextRegularExpressionMatch(regex_genre)
Select RegularExpressionMatchString(regex_genre)
Case "/live/" : Chaines()\Genre = #live : LIVE+1
Case "/movie/" : Chaines()\Genre = #films : FILMS+1
Case "/series/" : Chaines()\Genre = #series : SERIES+1
If regex_serie
If ExamineRegularExpression(regex_serie, Chaines()\Nom)
If NextRegularExpressionMatch(regex_serie)
Serie = ReplaceString(Chaines()\Nom, RegularExpressionMatchString(regex_serie), #Null$)
Serie = Trim(Serie)
Chaines()\Serie=Serie
EndIf
EndIf
EndIf
Default : Chaines()\Genre = #live : LIVE+1
EndSelect
EndIf
EndIf
EndIf
If Chaines()\Genre = #Empty$
Chaines()\Genre = #live : LIVE+1
EndIf
With Chaines()
\UrlVideo=LigneFichier
If \Nom = #inconnu
\Nom = \Genre+"::"+RSet(Str(NoLigneFichier),6,"0")
Debug \Nom
Debug \URLVideo
EndIf
EndWith
With Chaines()
\UrlVideo=LigneFichier
; Positionner afficher=#True uniquement sur des petites playlists
Define afficher=#False
If afficher
Debug RSet("",80,"-")+#CRLF$
Debug "Index : " +\Index+#CRLF$+
"Nom : " +\Nom+#CRLF$+
"Genre : " +\Genre+#CRLF$+
"Série : " +\Serie+#CRLF$+
"Groupe : " +\Groupe+#CRLF$+
"Langue : " +\Langue+#CRLF$+
"TVGId : " +\TVGId+#CRLF$+
"TVGName : " +\TVGName+#CRLF$+
"TVGLogo : " +\TVGLogo+#CRLF$+
"Url vidéo : " +\UrlVideo+#CRLF$
EndIf
EndWith
LigneDonneeOk=#False
Else
Debug "Ligne n° "+NoLigneFichier+" : Mauvais format de ligne, #EXTINF attendu !"
Debug LigneFichier
EndIf
EndSelect
EndIf
Wend
Debug VRAI_CHANNEL
ClearList(Chaines())
If IsRegularExpression(regex_nulle)
FreeRegularExpression(regex_nulle)
EndIf
If IsRegularExpression(regex_genre)
FreeRegularExpression(regex_genre)
EndIf
If IsRegularExpression(regex_serie)
FreeRegularExpression(regex_serie)
EndIf
CloseFile(IN)
Define HeureFin=Date()
Define text$,W=60
text$=RSet("",W,"-")+#CRLF$
text$+"Nombre de lignes du fichier de chaînes traitées : "+Str(NoLigneFichier)+#CRLF$
text$+"Nombre de lignes du fichier de données traitées : "+Str(NbLignesDonnees)+#CRLF$
text$+RSet("",W,"-")+#CRLF$
text$+"Tous les liens : "+LAST_CHANNEL+#CRLF$
text$+"Liens valides : "+VRAI_CHANNEL+#CRLF$
text$+"Liens non valides : "+FAUX_CHANNEL+#CRLF$
text$+RSet("",W,"-")+#CRLF$
text$+"Nombre de live : "+LIVE+#CRLF$
text$+"Nombre de films : "+FILMS+#CRLF$
text$+"Nombre de séries : "+SERIES+#CRLF$
text$+"Nombre total l+f+s : "+Str(LIVE+FILMS+SERIES)+#CRLF$
text$+RSet("",W,"-")+#CRLF$
text$+"Durée de traitement : "+Str((HeureFin-HeureDebut))+" secondes"+#CRLF$
text$+RSet("",W,"-")+#CRLF$
text$+"Terminé. Appuyez sur [Entrée]"
Else
Debug "Erreur système : "+GetLastError_()
EndIf
OpenConsole()
PrintN(text$)
Input()
CloseConsole()
End
; Ressources
;https://fr.wikipedia.org/wiki/M3U
;https://docs.fileformat.com/fr/audio/m3u/
;https://ss-iptv.com/fr/users/documents/m3u
Des idées ?
cage
Dernière modification par cage le dim. 27/août/2023 1:03, modifié 2 fois.
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Re: Demande d'aide avec la lecture de fichier JSON
Bonjour,
Je viens de mettre mon code dans le post précédent.
cage
Je viens de mettre mon code dans le post précédent.
cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
-
- Messages : 604
- Inscription : lun. 26/avr./2010 16:14
- Localisation : S 48° 52' 31'' / O 123° 23' 33''
Re: Demande d'aide avec la lecture de fichier JSON
Salut,
Le code de ton projet avance bien
Pertinent le recours aux expressions régulières pour gérer les types de données selon les fichiers.
Peut-être l'as-tu déjà fait et en rapport avec nos précédents échanges, il te reste maintenant à implémenter l'alimentation de ta BDD dans ta boucle de lecture des données.
Le code de ton projet avance bien

Pertinent le recours aux expressions régulières pour gérer les types de données selon les fichiers.
Peut-être l'as-tu déjà fait et en rapport avec nos précédents échanges, il te reste maintenant à implémenter l'alimentation de ta BDD dans ta boucle de lecture des données.