ADD Nouveaux films
[pompage.git] / src / films.rb
index 59f4af7..01dce5e 100644 (file)
@@ -1,4 +1,4 @@
-# Représente un ensemble de films\r
+# coding: utf-8\r
 \r
 require 'rexml/document'\r
 require 'thwait'\r
@@ -10,10 +10,13 @@ require 'personne.rb'
 require 'constantes.rb'\r
 require 'iconv'\r
 \r
+# Représente un ensemble de films.\r
 class Films\r
-   def initialize(xmlFile)\r
+   def initialize(xmlFile, modClasse)\r
       @xmlFile = xmlFile\r
       \r
+      @modClasse = modClasse\r
+      \r
       # repertoire de base, par exemple C:/Divx/\r
       @repBase = ''   \r
          \r
@@ -26,20 +29,29 @@ class Films
       # Les films qui ont plusieurs réponses lors de la recherche, traité à la fin\r
       @filmsPlusieursReponses = []\r
 \r
-      # Les films qui ont plusieurs réponses lors de la recherche, traité à la fin\r
+      # Les films qui n'ont aucune réponse après une recherche, traité à la fin\r
       @filmsAucuneReponse = []\r
 \r
       # permet de traiter facilement des groupes de thread\r
       @threadsWait = ThreadsWait::new\r
       @nbConn = 0 # le nombre de connexion\r
       \r
+      @mutexAjout = Mutex::new # mutex pour protéger l'ajout\r
+      @mutexId = Mutex::new # mutex pour protéger la génération d'id\r
+      \r
       # le prochain id disponible\r
       @idDisponible = 1\r
       \r
       chargerFilms\r
    end\r
+   \r
+   def each\r
+      @films.each{|t,f|\r
+         yield f\r
+      }\r
+   end\r
 \r
-   # Lit un repertoire de manière recursive et va chercher les informations concernant le film sur le net\r
+   # Lit un repertoire de manière recursive et va chercher les informations concernant le film sur le net.\r
    def pomper(r)\r
       @repBase = r\r
       repPrecedant = Dir::getwd\r
@@ -54,31 +66,59 @@ class Films
       \r
       puts "Pompage terminé, temps : #{Time::now - t} secondes"\r
       \r
-      # traite les films qui avaient plusieurs réponses lors de la recherche\r
+      # traite les films qui avaient plusieurs réponses lors de la recherche\r
       # l'utilisateur doit faire un choix\r
       i = 1\r
       @filmsPlusieursReponses.each{|f|\r
          puts\r
          puts "Plop, ya un conflit #{i} / #{@filmsPlusieursReponses.length} :"\r
-         if f.reglerConflitPlusieursReponses\r
-            ajouterFilm(f)\r
+         case f.reglerConflitPlusieursReponses\r
+            when 1\r
+               ajouterFilm(f)            \r
+            when 3\r
+               break\r
          end\r
          i += 1\r
       }\r
       \r
+      # traite les films qui n'avaient aucune réponse\r
       i = 1\r
       @filmsAucuneReponse.each{|f|\r
          puts\r
-         puts "Plop, Ce film n'a pas été trouvé{i} / #{@filmsAucuneReponse.length} :"\r
-         if f.reglerConflitPlusieursReponses\r
-            ajouterFilm(f)\r
+         puts "Plop, Ce film n'a pas été trouvé #{i} / #{@filmsAucuneReponse.length} :"\r
+         case f.reglerConflitPlusieursReponses\r
+            when 1\r
+               ajouterFilm(f)\r
+            when 3\r
+               break\r
          end\r
          i += 1\r
       }\r
       \r
+      # annonce à chaque module d'importation que c'est fini\r
+      @films.each{|t,f|\r
+         f.mod.finish\r
+      }\r
+      \r
       Dir::chdir(repPrecedant)      \r
    end\r
    \r
+   # Mise à jour des films dans la BD.\r
+   # p1 string : un motif Regex correspondant à un ou plusieurs champs\r
+   def update(champ, titre)\r
+      @films.each{|t, f|\r
+         next if !f.titre.match(Regexp::new(titre, true))\r
+                  \r
+         ## si le film est complet on ne fait rien\r
+         if $force || f.url == nil || f.titre == '' || f.annee == nil ||\r
+            f.realisateurs.empty? || f.acteurs.empty? || f.pays.empty? ||\r
+            f.genres.empty? || f.synopsis == nil || !f.possedeImage?\r
+            \r
+            f.update(champ)\r
+         end\r
+      }\r
+   end\r
+   \r
    # Sauve les films dans un fichier XML\r
    def sauverFilms\r
       # le document\r
@@ -98,72 +138,84 @@ class Films
       } \r
       \r
       # sauve le document\r
-      docXml.write(File::new(@xmlFile, 'w'), 0)\r
+      docXml.write(File::new(@xmlFile, 'w'), 1)\r
    end   \r
    \r
    private\r
       \r
    # Charge les films depuis le fichier XML\r
    def chargerFilms\r
-      # si le fichier n'existe pas il n'y a rien à charger\r
+      # si le fichier n'existe pas il n'y a rien à charger\r
       if !File.exists?(@xmlFile)\r
          return\r
       end\r
-      \r
+            \r
       racine = REXML::Document::new(File::new(@xmlFile)).root\r
-      racine.each_element{|e|       \r
+      racine.elements.each("film"){|e| \r
          id = e.attribute('id').to_s.to_i\r
        \r
-         if id > @idDisponible\r
+         if id >= @idDisponible\r
             @idDisponible = id + 1   \r
          end\r
          \r
-         titre = e.get_elements('titre')[0].get_text\r
-         url = e.get_elements('url')[0].get_text         \r
-         fichiers = e.get_elements('fichiers')[0].get_elements('fichier')\r
-         annee = e.get_elements('annee')[0].get_text\r
-         duree = e.get_elements('duree')[0].get_text\r
-         critiquePresse = e.get_elements('critiquePresse')[0].get_text\r
-         critiqueSpectateur = e.get_elements('critiqueSpectateur')[0].get_text\r
-         synopsis = e.get_elements('synopsis')[0].get_elements('p')\r
-         budget = e.get_elements('budget')[0].get_text  \r
-         realisateurs = e.get_elements('realisateurs')[0].get_elements('realisateur')\r
-         acteurs = e.get_elements('acteurs')[0].get_elements('acteur')\r
-         pays = e.get_elements('lespays')[0].get_elements('pays')\r
-         genres = e.get_elements('genres')[0].get_elements('genre')\r
+         film = Film::new(nil, @modClasse::new)\r
+         film.id = id\r
          \r
-         film = Film::new(fichiers[0].get_text.value)\r
+         film.titre = e.get_text('titre')\r
+         film.titre = film.titre.value if film.titre != nil\r
          \r
-         film.id = id\r
-         film.titre = titre.value unless titre.nil?\r
+         print "#{film.titre}.. "\r
+\r
+         \r
+         film.url = e.get_text('url')\r
+         film.url = film.url.value if film.url != nil\r
+\r
+         film.annee = e.get_text('annee')\r
+         film.annee = film.annee.value if film.annee != nil         \r
+         \r
+         film.duree = e.get_text('duree')\r
+         film.duree = film.duree.value if film.duree != nil\r
+         \r
+         film.critiquePresse = e.get_text('critiquePresse')\r
+         film.critiquePresse = film.critiquePresse.value if film.critiquePresse != nil\r
          \r
-         film.url = url.value unless url.nil?\r
+         film.critiqueSpectateur = e.get_text('critiqueSpectateur')\r
+         film.critiqueSpectateur = film.critiqueSpectateur.value if film.critiqueSpectateur != nil\r
          \r
-         fichiers.each{|e|\r
-            film.addFichier(e.get_text.value)\r
-            @filmsFichier[e.get_text.value] = film\r
+         film.budget = e.get_text('budget')\r
+         film.budget = film.budget.value if film.budget != nil\r
+         \r
+         e.elements.each('fichiers/fichier'){|f|\r
+            next if f.get_text == nil\r
+            film.addFichier(f.get_text.value)\r
+            @filmsFichier[f.get_text.value] = film\r
          }\r
-         film.annee = annee.value unless annee.nil?\r
-         acteurs.each{|e|\r
-            film.acteurs << Personne::ajouter(e.get_text.value)\r
+         \r
+         e.elements.each('realisateurs/realisateur'){|f|\r
+            film.realisateurs << Personne::ajouter(f.get_text.value)\r
          }\r
-         pays.each{|e|\r
-            film.pays << Pays::ajouter(e.get_text.value)\r
+         \r
+         e.elements.each('acteurs/acteur'){|f|\r
+            film.acteurs << Personne::ajouter(f.get_text.value)\r
          }\r
-         film.duree = duree.value unless duree.nil?\r
-         film.critiquePresse = critiquePresse.value unless critiquePresse.nil?\r
-         film.critiqueSpectateur = critiqueSpectateur.value unless critiqueSpectateur.nil?\r
-         genres.each{|e|\r
-            film.genres << Genre::ajouter(e.get_text.value) if e.get_text != nil\r
+         \r
+         e.elements.each('lespays/pays'){|f|\r
+            film.pays << Pays::ajouter(f.get_text.value)\r
          }\r
+         \r
+         e.elements.each('genres/genre'){|f|\r
+            film.genres << Genre::ajouter(f.get_text.value)\r
+         }       \r
+         \r
          debut = true\r
          film.synopsis = ""\r
-         synopsis.each{|e|\r
-            film.synopsis += "\n" unless debut\r
-            film.synopsis += e.get_text.value if e.get_text != nil\r
+         e.elements.each('synopsis/p'){|f|\r
+            film.synopsis += "\n" unless debut            \r
+            film.synopsis += f.get_text.value if f.get_text != nil\r
             debut = false\r
-         }\r
-         film.budget = budget.value unless budget.nil?\r
+         }                  \r
+         film.synopsis = nil if film.synopsis == ""\r
+                  \r
          @films[film.titre] = film\r
       }\r
    end\r
@@ -175,7 +227,7 @@ class Films
       return id\r
    end   \r
    \r
-   # Ajoute un film\r
+   # Ajoute un film à l'ensemble des films.\r
    def ajouterFilm(film)\r
       if film.plusieursReponses?\r
          @filmsPlusieursReponses << film\r
@@ -188,45 +240,42 @@ class Films
       end\r
       \r
       if @films.has_key?(film.titre)\r
-         # le fichier n'est pas connu -> nième partie d'un film\r
          if !@filmsFichier.has_key?(film.fichiers[0])\r
-            puts "[i] movie #{film.titre} has a another file part : #{film.fichiers[0]}"\r
+            puts "[i] Le film #{film.titre} possède une autre partie : #{film.fichiers[0]}"\r
             @films[film.titre].addFichier(film.fichiers[0])\r
             @filmsFichier[film.fichiers[0]] = @films[film.titre]                     \r
          else\r
-            puts "[!] Duplicate movie : #{film.titre} (#{film.fichiers[0]})"\r
+            puts "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})"\r
          end\r
       else\r
-         puts "[i] movie added : #{film.titre} (#{film.fichiers[0]})"\r
+         puts "[i] Film ajouté : #{film.titre} (#{film.fichiers[0]})"\r
          @films[film.titre] = film\r
          @filmsFichier[film.fichiers[0]] = film\r
       end\r
    end\r
    \r
-   # Appelé par 'pomper'. Cette méthode est récursive.\r
+   # Appelé par 'pomper'. Cette méthode itère récursivement sur l'arborescence d'un repertoire.\r
    def pomperR(r)\r
       Dir::foreach(r){|f|\r
          next if f[0,1] == '.'\r
          fichier = (r == '.' ? '' : r + "/") + f\r
          if File::directory?(fichier)\r
-            litRepertoireR(fichier) \r
+            pomperR(fichier) \r
          else\r
             \r
+            #fichier = Iconv.iconv("UTF-8", "ISO-8859-1", fichier)[0] // sous windows il faut décommenter cette ligne\r
+                        \r
             # véfication de l'extension\r
-            /^.*?\.(.{3,4})$/ =~ fichier\r
+            /^.*?\.([^.]{3,4})$/ =~ fichier\r
             if !FILMS_EXTENSIONS.include?($1)\r
                next\r
-            end\r
-            \r
-            fichier = CGI::escapeHTML(Iconv.iconv("UTF-8", "ISO-8859-1", fichier)[0])\r
-            \r
+            end
+                                    \r
             # on skip si le film est déjà dans la BD\r
             if film = @filmsFichier[fichier]\r
-               puts "[i] Already exists in DB : #{film.titre} (#{fichier})"\r
+               puts "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})"\r
                next\r
             end\r
-            \r
-            film = nil\r
              \r
             # pour limiter le nombre de connexion simultanée\r
             if @nbConn >= NB_CONN_MAX\r
@@ -235,14 +284,18 @@ class Films
              \r
             @nbConn += 1    \r
             @threadsWait.join_nowait(\r
-               Thread::new{\r
+               Thread::start{\r
                   begin                  \r
-                     film = Film::new(fichier).loadData\r
-                     film.id = getNewId # on lui donne un nouvel ID\r
+                     film = Film::new(fichier, @modClasse::new)\r
+                     @mutexId.synchronize{\r
+                        film.id = getNewId # on lui donne un nouvel ID\r
+                     }\r
+                     \r
+                     film.loadData # chargement de ses données\r
                      \r
-                     unless film.nil? # le film a été correctement construit\r
+                     @mutexAjout.synchronize{\r
                         ajouterFilm(film)\r
-                     end\r
+                     }\r
                   rescue Exception => e\r
                      puts e.message\r
                      puts e.backtrace\r