Outils pour utilisateurs

Outils du site


issue72:python

Table des matières

1

Last time, we started a project that would eventually use the TvRage module that we created the month before that. Now we will continue the project. This time we will be adding functionality to our program: tweaking the filename parse routine and adding two fields (TvRageId and Status) to the database. So, let’s jump right in. First, we will make the changes to our import lines. For those who are just joining us, I'll include the ones from last time (shown top right). The lines after ‘import re’ are the new ones for this time. The next thing we will do is rewrite the GetSeasonEpisode routine. We are going to throw out pretty much everything we did last month, and make it more flexible across the possible season/episode schemes. In this iteration, we will be able to support the following schemes… Series.S00E00 Series.s00e00 Series.S00E00.S00E01 Series.00×00 Series.S0000 Series.0x00

La dernière fois, nous avons commencé un projet qui finira par utiliser le module de TvRage que nous avons créé le mois d'avant. Nous allons maintenant poursuivre ce projet. Cette fois-ci, nous allons ajouter des fonctionnalités à notre programme : peaufiner la routine d'analyse de nom de fichier et ajouter deux champs (TvRageId et Etat) à la base de données. C'est parti !

Tout d'abord, nous modifierons nos lignes d'importation. Pour ceux qui viennent de nous rejoindre, je vais inclure celles de la dernière fois (en haut à droite).

Les lignes après « import re » sont nouvelles.

La chose suivante que nous allons faire est de réécrire la routine RecupereSaisonEpisode. Nous allons jeter à peu près tout ce que nous avons fait le mois dernier et le rendre plus souple à travers des schémas possibles de saisons/épisodes. Dans cette itération, nous serons en mesure de soutenir les schémas suivants :

Série.S00E00

Série.s00e00

Série.S00E00.S00E01

Série.00×00

Série.S0000

Série.0x00

2

We will also fix any ‘missing leading zero’ issues before we write to the database. Our first pattern tries to catch multi-episode files. There are various naming schemes, but the one we will support is similar to 'S01E03.S01E04'. We use the pattern string “(.*)\.s(\d{1,2})e(\d{1,2})\.s(\d{1,2})e(\d{1,2})”. This returns (hopefully) five groups which consist of: the series name (S[1]), season(S[2]), episode number 1 (S[3]), season (S[4]), and episode number 2 (S[5]). Remember that the parens create each group for returns. In the case above, we group anything from the first character up to the “.s”, then two numbers, skip the “e”, then two numbers, and repeat. So the filename “Monk.S01E05.S01E06.avi” returns the following groups… S[1] = Monk S[2] = 01 S[3] = 05 S[4] = 01 S[5] = 06

Nous allons également corriger les problèmes éventuels de « zéro initial manquant » avant d'écrire dans la base de données.

Notre premier motif essaie d'attraper les fichiers multi-épisodes. Il existe différents systèmes de nommage, mais celui que nous prenons en charge ressemble à « S01E03.S01E04 ». Nous utilisons le modèle de chaîne « (.*)\.s(\d{1,2})e(\d{1,2})\.s(\d{1,2})e(\d{1,2}) ». Cela retourne (espérons-le) cinq groupes qui sont : le nom de la série (S[1]), la saison (S[2]), le numéro du premier épisode (S[3]), la saison (S[4]), et le numéro du deuxième épisode (S[5]). Rappelez-vous que les parenthèses créent les groupes retournés. Dans le cas ci-dessus, nous regroupons tout à partir du premier caractère jusqu'au « .s », puis deux chiffres, on passe le « e », puis deux chiffres, puis on recommence. Ainsi, le nom de fichier “Monk.S01E05.S01E06.avi” renvoie les groupes suivants :

S[1] = Monk

S[2] = 01

S[3] = 05

S[4] = 01

S[5] = 06

3

We are using only groups S[1], S[2] and S[3] in this code, but you can see where we are going with this. If we find a match, we set a variable named “GoOn” to true. This allows us to know what we should do after we’ve fallen through the various If lines. So, next page (top right) is the code for the GetSeasonEpisode routine. When we get to this point, (next page, bottom left) we prepare the show name by removing any periods in the show name, and then pull the season and episode information from the various groups, and return them. For the season information, if we have a pattern like “S00E00”, the season number will have a leading zero. However if the pattern is like “xxx”, then the season is assumed to be the first character, and the trailing two are the episode. In order to be forward thinking, we want to make the season a two-digit number with a leading zero if needed. Next, in our MakeDatabase routine, we will change the create SQL statement to add the two new fields (next page, top). Again, the only thing that has changed from last time is the last two field definitions.

Nous utilisons uniquement des groupes S[1], S[2] et S[3] dans ce code, mais vous pouvez comprendre nos objectifs. Si nous trouvons une correspondance, nous réglons une variable nommée “Continuer” à Vrai. Cela nous permet de savoir ce que nous devrions faire après que nous soyons passés à travers les différentes lignes If.

Ainsi, sur la page suivante (en haut à droite) se trouve le code de la routine RecupereSaisonEpisode.

Quand nous arrivons à ce point (page suivante, en bas à gauche) nous préparons le nom de l'émission en supprimant tous les points dans le nom de la série, puis extrayons les informations de la saison et de l'épisode des différents groupes, et les retournons. Pour l'information de saison, si nous avons un modèle comme « S00E00 », le numéro de saison aura un zéro. Mais si le modèle ressemble à « xxx », alors la saison est supposée être le premier caractère, et les deux suivants sont pour l'épisode. Afin d'être prévoyants, nous voulons que la saison soit un nombre à deux chiffres avec un zéro au début si nécessaire.

Ensuite, dans notre routine FabriquerBase, nous allons modifier l'instruction de création SQL pour ajouter les deux nouveaux champs (page suivante, en haut).

Encore une fois, la seule chose qui a changé depuis la dernière fois, ce sont les deux dernières définitions de champs.

4

In our WalkThePath routine, the only changes are the lines that actually insert into the database. This is to support the new structure. If you remember from last time, we pass the folder that holds our TV files to this routine. In my case, there are two folders, so it's set into a list and we use a for loop to pass each into the routine. As we go through the routine, we walk through each directory looking for files with extensions of .avi, .mkv, .mp4 and .m4v. When we find a file that matches, we send it to the GetSeasonEpisode routine. We then check to see if we already have it entered into the database, and, if not, we add it. I’m going to give you (top right) only part of the routine from last month. The two lines in black are the ones that are new this time. We are already over halfway done. Next are some support routines that work with our TvRage routine to fill in the database fields. Our first routine runs after the WalkThePath routine, and runs through the database, getting the series name and querying the TvRage server for the id number. Once we have that, we update the database, then use that id number to once again query TvRage to get the current status of the series. This status can be “New Series”, “Returning Series”, “Canceled”, “Ended” and “On Haitus”. The reason we want this information is that, when we go to check for new episodes, we don't want to bother with series that won't have any new episodes because they are cancelled. So, now we have the status and can write that to the database (above).

Dans notre routine ParcourirChemin, les seuls changements sont les lignes qui sont réellement insérées dans la base de données, ceci afin de supporter la nouvelle structure. Si vous vous souvenez de la dernière fois, nous passons le dossier qui contient les fichiers TV à cette routine. Dans mon cas, il y a deux dossiers, ils sont donc placés dans une liste et nous utilisons une boucle pour passer chacun à la routine. En cours de la routine, nous parcourons chaque répertoire à la recherche de fichiers avec des extensions .avi, .mkv, .mp4 et .m4v. Lorsque nous trouvons un fichier qui correspond, nous l'envoyons à la routine RecupereSaisonEpisode. Nous vérifions ensuite si nous l'avons déjà entré dans la base de données et, sinon, nous l'ajoutons. Je vais vous donner (en haut à droite) seulement une partie de la routine du mois dernier.

Les deux lignes en noir sont nouvelles.

Nous en sommes déjà à mi-chemin. Suivent quelques routines de support qui fonctionnent avec notre routine TvRage pour remplir les champs de la base. Notre première routine s'exécute après la routine ParcourirChemin, et parcourt la base de données pour obtenir le nom de la série et interroger le serveur de TvRage pour obtenir le numéro d'identification. Une fois que nous avons cela, nous mettons à jour la base de données, puis utilisons à nouveau le numéro d'identification sur TvRage pour obtenir l'état actuel de la série. Cet état peut être « New Series », « Returning Series », « Canceled », « Ended » et « On Haitus » (série nouvelle, de retour, annulée, terminée, en pause). La raison pour laquelle nous voulons cette information est que, lorsque nous allons vérifier les nouveaux épisodes, nous ne voulons pas nous embêter avec des séries qui n'auraient pas de nouveaux épisodes parce qu'elles sont annulées. Ainsi, nous en avons maintenant l'état et pouvons l'écrire dans la base de données (ci-dessus).

5

We will pause here in our code and look at the SQL query we are using. It’s a bit different from anything we’ve done before. The string is: SELECT DISTINCT series FROM TvShows WHERE tvrageid = -1 Which says, give me just one instance of the series name, no matter how many of them I have, where the field tvrageid is equal to “-1”. If, for example, we have 103 episodes of Doctor Who 2005. By using the Distinct, I will get back only one record, assuming that we haven’t gotten a TvRageID yet. for x in SeriesCursor.execute(sqlstring): seriesname = x[0] searchname = string.capwords(x[0],“ ”)

Nous allons nous arrêter ici dans notre code pendant un instant pour regarder la requête SQL que nous utilisons. C'est un peu différent de tout ce que nous avons fait auparavant. La chaîne est :

SELECT DISTINCT Serie FROM EmissionsTV WHERE tvrageid = -1

Ce qui dit : donne-moi un seul exemple du nom de la série, peu importe combien il y en a, où le champ tvrageid vaut « -1 ». Si, par exemple, nous avons 103 épisodes de Doctor Who 2005, en utilisant le Distinct, je vais recevoir un seul enregistrement, en supposant que nous n'avons pas encore obtenu un TvRageID.

  for x in CurseurSerie.execute(requetesql):
      nomSerie = x[0]
      NomATrouver = string.capwords(x[0]," ")

6

We are using the capwords routine from the string library to change the series name (x[0]) to a “proper case” from the all-uppercase we currently store the show name in. We do this because TvRage expects something other that all-uppercase entries, and we won’t get the results we are looking for. So the series name “THE MAN FROM UNCLE” will be converted to “The Man From Uncle”. We use that in the call to our TvRage Library FindIdByName. This gets the list of matching shows, and displays them for us to pick the best one. Once we pick one, we update the database with the id number and then call the GetShowStatus routine to get the current show status from TvRage (bottom right). The UpdateDatabase routine (top) simply uses the series name as the key to update all the records with the proper TvRage ID. GetShowStatus (above) is also very simple. We call the GetShowInfo routine from the TvRage library by passing the id that we just got to TvRage – to get the series information. If you remember, there is a lot of information provided about the series from TvRage, but all we are concerned about at this point is the show status. Since everything is returned in a dictionary, we just look for the [‘Status’] key. Once we have it, we update the database with that and move on.

Nous utilisons la routine capwords de la bibliothèque string pour changer le nom de la série (x[0]) « de façon correcte » puisque nous stockons les noms des émissions en majuscules. Nous faisons cela parce que TvRage s'attend à recevoir quelque chose d'autre que des seules majuscules et nous n'obtiendrons pas les résultats que nous recherchons. Ainsi, le nom de la série « THE MAN FROM UNCLE » sera converti en « The Man From Uncle ». Nous utilisons cela dans l'appel à la fonction TrouverIdParNom de notre bibliothèque TvRage. Cela récupère la liste des émissions correspondantes et les affiche pour qu'on choisisse la meilleure. Une fois que nous en avons choisi une, nous mettons à jour la base de données avec le numéro d'identification, puis appelons la routine RecupererEtatEmission pour obtenir le statut en cours depuis TvRage (en bas à droite).

La routine MettreAJourBase (en haut) utilise simplement le nom de la série comme clé pour mettre à jour tous les enregistrements avec l'ID approprié de TvRage.

RecupererEtatEmission (ci-dessus) est également très simple. Nous appelons la routine TrouveInfoEmission de la bibliothèque TvRage en passant l'id que nous venons de récupérer de TvRage pour obtenir l'information sur la série. Si vous vous souvenez, TvRage fournit beaucoup d'informations sur la série, mais tout ce qui nous intéresse à ce stade est l'état de l'émission. Puisque tout est retourné dans un dictionnaire, il nous suffit de chercher la clé ['Etat']. Une fois que nous l'avons, nous mettons à jour la base de données avec, puis passons à autre chose.

7

We are almost done with our code. We finally add one line to our main routine from last month (in black, below) to call the “WalkTheDatabase” routine after we are done getting all our filenames. Again, I’m going to give you only part of the Main routine, just so you can find the correct place to put the new line. That’s all our code. Let’s mentally go over what happens when we run the program. First, we create the database if it doesn’t exist. Next, we walk through the predefined paths, looking for files that have any one of the following extensions: .AVI, .MKV, .M4V, .MP4 When we find one, we go through and try to parse the filename looking for a series name, Season number, and episode number. We take that information and put it into a database, if it does not already exist there.

Nous avons presque terminé notre code. Nous ajoutons pour finir une ligne à notre routine principale du mois dernier (en noir ci-dessous) pour appeler la routine ParcourirBase après avoir récupéré tous les noms de fichiers. Encore une fois, je vais vous donner seulement une partie de la routine Main, juste pour que vous puissiez trouver le bon endroit pour mettre la nouvelle ligne.

C'est terminé pour le code. Examinons mentalement ​​ce qui arrive quand nous exécutons le programme.

Tout d'abord, nous créons la base de données si elle n'existe pas.

Ensuite, nous parcourons les chemins prédéfinis, à la recherche de fichiers qui ont une des extensions suivantes :

.AVI, .MKV, .M4V, .MP4

Lorsque nous en trouvons un, nous essayons d'analyser le nom du fichier à la recherche d'un nom de série, d'un numéro de saison et d'un numéro d'épisode. Nous prenons cette information et la mettons dans une base de données, si elle n'y existe pas déjà.

8

Once we are through looking for files, we query the database looking for series names that don’t have a TvRage ID associated with them. We then will query the TvRage API and ask for matching files to gather that ID. Each series will go through that step once. The following screenshot shows the options for, in this case, the tv series Midsomer Murders. I entered (in this case) 1, which associates that series with the TvRage ID 4466. That’s entered into the database, and we then use that ID to request the current status for the series, again from TvRage. In this case, we got back “Returning Series”. This is then entered into the database and we move on. While doing the initial “run” into the database, it will take a while and require your attention, because each and every series needs to ask about the ID number match. The good news is that this has to be done only once. If you are “somewhat normal”, you won’t have that many to deal with. I had 157 different series to do, so it took a little while. Since I was careful when I set up my filenames (checking TvRage and TheTvDB.com for the proper wording of the series name), the majority of the searches were the #1 option. Just to let you know, over half of the TV series that I have either ended or have been canceled. That should tell you something about the age group I fall in. The full code is, as always, available on PasteBin at http://pastebin.com/MeuGyKpX Next time we will continue with the integration with TvRage. Until then have a great month!

Après avoir recherché les fichiers, nous interrogeons la base de données à la recherche de noms de séries pour lesquelles il n'y a pas d'ID TvRage associé. Nous interrogeons alors l'API TvRage et demandons des fichiers correspondants pour trouver cet ID. Chaque série va passer par cette étape une fois. La capture d'écran ci-dessous montre les options pour, dans ce cas, la série « Midsomer Murders ».

J'ai saisi (dans ce cas) 1, qui associe cette série avec l'ID TvRage 4466. Il est entré dans la base de données, et nous utilisons alors cet ID pour demander l'état actuel de la série, toujours sur TvRage. Dans ce cas, on nous renvoie « Returning Series ». L'état est alors entré dans la base de données et nous continuons.

Le passage initial dans la base de données prendra un certain temps et nécessitera votre attention, parce que chaque série doit poser des questions sur le numéro d'identification correspondant. La bonne nouvelle est que ceci n'est fait qu'une seule fois. Si vous êtes « normal », vous n'en aurez pas tant que ça à traiter. J'ai eu 157 séries différentes à passer et il a donc fallu un peu de temps. Comme j'ai été prudent lorsque j'ai saisi mes noms de fichiers (en vérifiant sur TvRage et TheTvDB.com pour avoir la formulation correcte du nom de la série), la majorité des réponses a été l'option n° 1.

Juste pour votre information, plus de la moitié des séries télévisées que j'ai sont terminées ou ont été annulées. Cela devrait vous donner une idée de mon âge approximatif.

Le code complet est, comme toujours, disponible sur Pastebin : http://pastebin.com/DgwmTMHr [NdT: code traduit par l'équipe francophone. Pour le code original, voir http://pastebin.com/MeuGyKpX.]

La prochaine fois, nous continuerons l'intégration avec TvRage. D'ici là, passez un bon mois !

issue72/python.txt · Dernière modification : 2013/08/25 15:46 de auntiee