ADD Pompage des images ! :)
[pompage.git] / src / film.rb
index b8b3e07..309f686 100644 (file)
@@ -1,17 +1,16 @@
-# Attention, le but de ce fichier n'est pas d'être le plus clair possible ^-^´´\r
-\r
-require 'rexml/document'\r
-require 'net/http'\r
-require 'thread'\r
-require 'thwait'\r
-require 'cgi'\r
+# Représente un Film.\r
+# Permet de charger des données depuis allocine.fr\r
+# Permet d'effectuer des recherches depuis allocine.fr\r
+# TODO : rendre la classe indépendant de la source de donnée pour pouvoir utiliser d'autres sites comme par exemple imdb.com\r
 \r
 require 'pays.rb'\r
 require 'genre.rb'\r
 require 'personne.rb'\r
 \r
 require 'pays.rb'\r
 require 'genre.rb'\r
 require 'personne.rb'\r
-\r
 require 'constantes.rb'\r
 \r
 require 'constantes.rb'\r
 \r
+require 'modules/allocine.rb'\r
+\r
+# ajout de deux méthodes à la classe String\r
 class String\r
    def virerBalisesHTML\r
       return gsub(/<(.*?)>/, '')\r
 class String\r
    def virerBalisesHTML\r
       return gsub(/<(.*?)>/, '')\r
@@ -22,218 +21,15 @@ class String
 end\r
 \r
 class Film\r
 end\r
 \r
 class Film\r
-   attr_accessor :id, :titre, :fichiers, :annee, :realisateurs, :acteurs, :pays, :duree, :critiquePresse, :critiqueSpectateur, :genres, :synopsis, :budget\r
-      \r
-   # repertoire de base, par exemple C:/Divx/\r
-   @@repBase = ''   \r
       \r
       \r
-   # Les films indexés par leur titre\r
-   @@films = {}\r
-   \r
-   # Les films indexés par leur nom de fichier, deux fichiers différents peuvent pointer sur le même film\r
-   @@filmsFichier = {}\r
-   \r
-   # Les films qui ont plusieurs réponses lors de la recherche, traités à la fin\r
-   @@filmsPlusieursReponses = []\r
-\r
-   @@threadsWait = ThreadsWait::new\r
-   @@nbConn = 0\r
-   \r
-   # le prochain id disponible\r
-   @@idDisponible = 1\r
-   \r
-   # retourne un nouvel id, utilisé lors de la création d'un nouveau film\r
-   def Film::getNewId\r
-      id = @@idDisponible\r
-      @@idDisponible += 1\r
-      return id\r
-   end\r
+   # toutes les données membres sont accessibles par défaut (écriture/lecture)\r
+   attr_accessor :id, :titre, :url, :fichiers, :mod, :annee, :realisateurs, :acteurs, :pays, :duree, :critiquePresse, :critiqueSpectateur, :genres, :synopsis, :budget\r
 \r
 \r
-   # Lit un repertoire de manière recursive\r
-   def Film::litRepertoire(r)\r
-      @@repBase = r\r
-      repPrecedant = Dir::getwd\r
-      Dir::chdir(r)\r
-      \r
-      Film::litRepertoireR('.')\r
-      \r
-      # on attends que les threads se terminent\r
-      @@threadsWait.all_waits\r
-      \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
-            Film::ajouterFilm(f)\r
-         end\r
-         i += 1\r
-      }\r
-      \r
-      Dir::chdir(repPrecedant)      \r
-   end\r
-   \r
-   # Charge les films contenus dans un fichier XML.\r
-   def Film::loadFilmsXml(xmlFile)\r
-      # si le fichier n'existe pas il n'y a rien à charger\r
-      if !File.exists?(xmlFile)\r
-         return\r
-      end\r
-      \r
-      racine = REXML::Document::new(File::new(xmlFile)).root\r
-      racine.each_element{|e|       \r
-         id = e.attribute('id').to_s.to_i\r
-       \r
-         if id > @@idDisponible\r
-            @@idDisponible = id + 1   \r
-         end\r
-         \r
-         titre = e.get_elements('titre')[0].get_text\r
-         \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_text\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
-         \r
-         film = Film::new(fichiers[0].get_text.value)\r
-         \r
-         film.titre = titre.value unless titre.nil?\r
-         film.id = id\r
-         fichiers.each{|e|\r
-            film.addFichier(e.get_text.value)\r
-            @@filmsFichier[e.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
-         pays.each{|e|\r
-            film.pays << Pays::ajouter(e.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
-         film.synopsis = synopsis.value unless synopsis.nil?\r
-         film.budget = budget.value unless budget.nil?\r
-         @@films[film.titre] = film\r
-      }\r
-   end\r
-\r
-   # Renvoie tous les films sous la forme d'un document XML.\r
-   def Film::getFilmsXml\r
-      # le document\r
-      docXml = REXML::Document::new\r
-      docXml.xml_decl().encoding = "UTF-8"  # normalement UTF-8\r
-      docXml.xml_decl().dowrite\r
-            \r
-      # la racine du document\r
-      racine = REXML::Element::new('filmographie')\r
-      docXml.add(racine)\r
-      pi = REXML::Instruction.new("xml-stylesheet", "type=\"text/xsl\" href=\"../xsl/yopyop.xsl\"")\r
-      racine.previous_sibling = pi\r
-      \r
-      # on ajoute chaque film à la racine\r
-      @@films.each{|nom, f|\r
-         racine.add(f.getXml)\r
-      } \r
-      \r
-      # revoie le document\r
-      docXml\r
-   end\r
-   \r
-private\r
-\r
-   def Film::filmsFactory(fichier)\r
-      Film::new(fichier).loadData\r
-   end\r
-    \r
-   def Film::litRepertoireR(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
-         else\r
-            \r
-            # vérification de l'extension\r
-            /^.*?\.(.{3,4})$/ =~ fichier\r
-            if !FILMS_EXTENSIONS.include?($1)\r
-               next\r
-            end\r
-            \r
-            fichier = CGI::escapeHTML(fichier.unpack("C*").pack("U*"))\r
-            \r
-            # on skip si le film est déjàa dans la BD\r
-            if film = @@filmsFichier[fichier]\r
-               puts "[i] Already exists in DB : #{film.titre} (#{fichier})"\r
-               next\r
-            end\r
-            \r
-            #p fichier\r
-            \r
-            film = nil\r
-             \r
-            if @@nbConn >= NB_CONN_MAX\r
-               @@threadsWait.next_wait\r
-            end\r
-             \r
-            @@nbConn += 1    \r
-            @@threadsWait.join_nowait(\r
-               Thread::new{\r
-                  begin                  \r
-                     film = Film::filmsFactory(fichier)                     \r
-                     unless film.nil? # le film a été correctement construit\r
-                        Film::ajouterFilm(film)\r
-                     end\r
-                  rescue Exception => e\r
-                     puts e.message\r
-                     puts e.backtrace\r
-                  end      \r
-                  @@nbConn -= 1\r
-               }\r
-            )\r
-         end\r
-      }\r
-   end\r
-   \r
-   def Film::ajouterFilm(film)\r
-      if film.plusieursReponses?\r
-         @@filmsPlusieursReponses << film\r
-         return\r
-      end\r
-      \r
-      # le film existe déjà\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
-            @@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
-         end\r
-      else\r
-         puts "[i] movie added : #{film.titre} (#{film.fichiers[0]})"\r
-         @@films[film.titre] = film\r
-         @@filmsFichier[film.fichiers[0]] = film\r
-      end\r
-   end\r
-      \r
-   \r
-   def initialize(fichier)\r
-      @fichiers = [fichier]\r
+   # Constructeur. N'entreprend aucune action (chargement), crée juste un film vide.\r
+   # p1 [String] : le fichier correspondant au film\r
+   def initialize(fichier, mod)\r
+      @fichiers = [fichier] # le chemin des fichiers est relatif au repertoire de base\r
+      @mod = mod\r
            \r
       @id = 0\r
       @titre = ''\r
            \r
       @id = 0\r
       @titre = ''\r
@@ -249,27 +45,31 @@ private
       @budget = nil      \r
       @budgetUnite = 'euro'\r
       @url\r
       @budget = nil      \r
       @budgetUnite = 'euro'\r
       @url\r
+            \r
+      @nbReponses = 0\r
       \r
       \r
-      @aPlusieursReponses = false\r
-      # mémorise les tuples {nom => id} dans le cas ou il y a plusieurs réponses\r
-      @idsAllocine = {}\r
+      # mémorise les tuples {nom => id} dans le cas ou il y a plusieurs choix de films après une recherche\r
+      @choix = {}\r
    end\r
 \r
    end\r
 \r
-public \r
-\r
+   # Est-ce qu'il y a eu plusieurs réponses pour ce film lors de la cherche sur le net ?\r
    def plusieursReponses?\r
    def plusieursReponses?\r
-      return @aPlusieursReponses\r
+      return @nbReponses > 1\r
+   end    \r
+\r
+   # Est-ce qu'il y a eu plusieurs réponses pour ce film lors de la cherche sur le net ?\r
+   def nbReponses\r
+      return @nbReponses\r
    end \r
    \r
    end \r
    \r
-   # demande à l'utilisateur de faire un choix\r
-   # ret : true si le conflit à été résolu sinon false\r
+   # Demande à l'utilisateur de faire un choix.\r
+   # ret : 1 si le conflit à été résolu, 2 si le film est à ignorer, 3 si tout les films sont à ignorer\r
    def reglerConflitPlusieursReponses\r
    def reglerConflitPlusieursReponses\r
-      \r
-      @aPlusieursReponses = false # pour faire les choses bien\r
+      @nbReponses = 1\r
       \r
       puts " -> " + @fichiers[0]\r
       puts "Fais ton choix jeune padawan (un caractère et pas plus)"\r
       \r
       puts " -> " + @fichiers[0]\r
       puts "Fais ton choix jeune padawan (un caractère et pas plus)"\r
-      tabNoms = @idsAllocine.keys\r
+      tabNoms = @choix.keys\r
       choix = 1\r
       loop do \r
          i = 1\r
       choix = 1\r
       loop do \r
          i = 1\r
@@ -279,12 +79,15 @@ public
          }\r
          puts "A. Passer et l'ajouter"\r
          puts "B. Ignorer"\r
          }\r
          puts "A. Passer et l'ajouter"\r
          puts "B. Ignorer"\r
+         puts "C. Tout ignorer"\r
          choix = STDIN.gets\r
          \r
          if /A/i =~ choix\r
          choix = STDIN.gets\r
          \r
          if /A/i =~ choix\r
-            return true\r
+            return 1\r
          elsif /B/i =~ choix\r
          elsif /B/i =~ choix\r
-            return false\r
+            return 2\r
+         elsif /C/i =~ choix\r
+            return 3\r
          end\r
          \r
          choix = choix.to_i\r
          end\r
          \r
          choix = choix.to_i\r
@@ -296,11 +99,12 @@ public
          end\r
       end\r
       \r
          end\r
       end\r
       \r
-      loadDepuisIdAllocine(@idsAllocine[tabNoms[choix-1]])\r
+      @mod.load(@choix[tabNoms[choix-1]], self)\r
       \r
       \r
-      return true\r
+      return 1\r
    end\r
    \r
    end\r
    \r
+   # Ajoute un fichier comme faisant partie du film\r
    def addFichier(fichier)\r
       if !@fichiers.include?(fichier)\r
          @fichiers << fichier\r
    def addFichier(fichier)\r
       if !@fichiers.include?(fichier)\r
          @fichiers << fichier\r
@@ -309,16 +113,7 @@ public
 \r
    # Charge les informations du films à partir d'allocine.fr\r
    # ret [Film]\r
 \r
    # Charge les informations du films à partir d'allocine.fr\r
    # ret [Film]\r
-   def loadData\r
-      unless LOAD_DATA\r
-         @titre = @fichiers[0]\r
-         return self\r
-      end\r
-      \r
-      @id = Film::getNewId\r
-\r
-      connexionHttp = Net::HTTP::new('www.allocine.fr')\r
-   \r
+   def loadData   \r
       #extrait le nom à partir du nom du fichier\r
       /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichiers[0]\r
       #remplace undescores et points par des espaces\r
       #extrait le nom à partir du nom du fichier\r
       /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichiers[0]\r
       #remplace undescores et points par des espaces\r
@@ -333,128 +128,24 @@ public
       \r
       @titre = titre.dup\r
       \r
       \r
       @titre = titre.dup\r
       \r
-      donneesHtml = nil\r
-      begin\r
-         begin\r
-            reponse, donneesHtml = connexionHttp.get("/recherche/?motcle=#{CGI::escape(titre.unpack("U*").pack("C*"))}")\r
-         rescue Exception => e\r
-            p e\r
-            puts "[!] Connexion lost, retry.."\r
-            retry\r
-         end\r
-         \r
-         #convertit le code latin-1 en UTF8\r
-         donneesHtml = donneesHtml.unpack("C*").pack("U*")\r
-         \r
-         #si pas trouvé alors on enlève un mot à la fin\r
-         if /.*?Pas de résultats.*?/ =~ donneesHtml || ! donneesHtml.include?("<h3><b>Films <h4>")\r
-            /(.*?)[^ ]+?$/ =~ titre.strip\r
-            titre = $1\r
-            titre.strip!\r
-         else\r
-            break;\r
-         end\r
-      end while not titre.nil? and not titre.empty?\r
+      unless LOAD_DATA\r
+         return self\r
+      end\r
       \r
       \r
-      unless titre.nil? or titre.empty?\r
-            \r
-         #/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">/ =~ donneesHtml\r
-         #r = donneesHtml.scan(/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">(.*?)<\/a>/)\r
-         r = donneesHtml.scan(/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">(.*?)<\/a>(?:<\/h4><h5 style="color: #666666">&nbsp;(.*?)<\/h5>){0,1}(?:<h4><br \/><\/h4>){0,1}(?:<h4 style="color: #666666"> de (.*?)<\/h4>){0,1}(?:<h4 style="color: #666666">&nbsp;avec (.*?)<\/h4>){0,1}(?:<h4 style="color: #666666">&nbsp;\((.*?)\)<\/h4>){0,1}/)\r
-         \r
-         if r.length > 1\r
-            @aPlusieursReponses = true\r
-            r.each{|f|\r
-               @idsAllocine[f[1].virerBalisesHTML + (f[2] != nil ? " " + f[2].virerBalisesHTML : "") + (f[3] != nil ? " de " + f[3].virerBalisesHTML : "") + (f[4] != nil ? " avec " + f[4].virerBalisesHTML : "") + (f[5] != nil ? " (" + f[5].virerBalisesHTML + ")" : "")] = f[0]\r
-            }\r
-         elsif r.length == 1\r
-            loadDepuisIdAllocine(r[0][0], connexionHttp) \r
-         else\r
-            puts "[!] Movie not found : #{@titre} (#{@fichier})"\r
-         end\r
+      reponses = @mod.rechercherFilm(titre)\r
+      @nbReponses = reponses.size\r
+      \r
+      if @nbReponses == 1\r
+         @mod.load(reponses.values[0], self)\r
+      else\r
+         @choix = reponses   \r
       end\r
       end\r
+\r
       self\r
    end\r
    \r
       self\r
    end\r
    \r
-private\r
-   def loadDepuisIdAllocine(id, connexionHttp = nil)\r
-      if (connexionHttp == nil)\r
-         connexionHttp = Net::HTTP::new('www.allocine.fr')\r
-      end\r
-         \r
-      r, ficheHtml = connexionHttp.get("/film/fichefilm_gen_cfilm=#{id}.html") \r
-      \r
-      #convertit le code latin-1 en UTF8\r
-      ficheHtml = ficheHtml.unpack("C*").pack("U*")\r
-\r
-      #url\r
-      @url = "http://www.allocine.fr/film/fichefilm_gen_cfilm=#{id}.html"\r
-      \r
-      # Titre\r
-      /<title>(.*?)<\/title>/ =~ ficheHtml\r
-      @titre = $1 unless $1.nil?\r
-      \r
-      puts "Movie found : #{@titre} (#{@fichiers[0]})"\r
-      \r
-      # Année\r
-      /<h4>Année de production : (\d+)<\/h4>/ =~ ficheHtml\r
-      @annee = $1 unless $1.nil?\r
-      \r
-      # Réalisateurs\r
-      /<h4>Réalisé par(.*?)<\/h4>/ =~ ficheHtml\r
-      $1.scan(/<a class="link1" href=".*?">(.*?)<\/a>/m){|a|\r
-        @realisateurs << Personne::ajouter(a[0]) unless a[0].nil?\r
-      } unless $1.nil?\r
-      \r
-      # Acteurs\r
-      /<h4>Avec(.*?)<\/h4>/ =~ ficheHtml\r
-      $1.scan(/<a class="link1" href="\/personne\/fichepersonne_gen_cpersonne=\d+\.html">(.+?)<\/a>/m){|a|\r
-         @acteurs << Personne::ajouter(a[0]) unless a[0].nil? \r
-      } unless $1.nil? \r
-                \r
-      # Pays\r
-      /<h4>Film (.*?)\.&nbsp;<\/h4>/ =~ ficheHtml\r
-      $1.split(',').each{|pays|\r
-         @pays << Pays::ajouter(pays) unless pays.nil?\r
-      } unless $1.nil? \r
-      \r
-      # Duree (capture des heures et des minutes séparement vue que c'est le bordel sur allocine\r
-      /<h4>Durée :(?:.*?)(\d+)h/ =~ ficheHtml\r
-      heure = $1.nil? ? 0 : $1.to_i\r
-      \r
-      /<h4>Durée :(?:.*?)(\d+)min/ =~ ficheHtml\r
-      min = $1.nil? ? 0 : $1.to_i\r
-         \r
-      @duree = heure * 60 + min\r
-      \r
-      # Critiques presse et spectateur\r
-      /Presse.*etoile_([012345]).*Spectateurs.*etoile_([012345])"/m =~ ficheHtml\r
-      @critiquePresse = $1 unless $1.nil?\r
-      @critiqueSpectateur = $2 unless $2.nil?\r
-      \r
-      # Genre\r
-      /<h4>Genre : (.*?)<\/h4>/ =~ ficheHtml\r
-      $1.scan(/<a href="\/film\/alaffiche_genre_gen_genre=.*?" class="link1">(.+?)<\/a>/m){|g|\r
-         @genres << Genre::ajouter(g[0]) unless g[0].nil?\r
-      } unless $1.nil?     \r
-      \r
-      # Synopsis            \r
-      /Synopsis.*?<h4>(.*?)<\/h4>/m =~ ficheHtml\r
-      unless $1.nil\r
-      {\r
-         @synopsis = $1\r
-         @synopsis.gsub!(/<br\s*\/>|<br\s*>/, "\n")\r
-         @synopsis.virerBalisesHTML!\r
-      }\r
-      \r
-      # Budget       \r
-      /Budget<\/b> : (.+?) millions d'euros<\/h4>/ =~ ficheHtml\r
-      @budget = $1 unless $1.nil?\r
-   end     \r
-      \r
-public\r
-   \r
-   # Renvoie un film sous la forme d'un élément XML de type REXML\r
+   # Renvoie un film sous la forme d'un élément XML .\r
+   # ret [REXML::Element] : un element xml <film>\r
    def getXml\r
       \r
       racine = REXML::Element::new('film')\r
    def getXml\r
       \r
       racine = REXML::Element::new('film')\r
@@ -499,10 +190,12 @@ public
       racine.add(genres) \r
       \r
       synopsisElement = REXML::Element::new('synopsis')\r
       racine.add(genres) \r
       \r
       synopsisElement = REXML::Element::new('synopsis')\r
-      @synopsis.split("\n").each{|s|\r
-         next if s =~ /^\s*$/\r
-         synopsisElement.add(REXML::Element::new('p').add_text(s))\r
-      }\r
+      unless @synopsis.nil?\r
+         @synopsis.split("\n").each{|s|\r
+            next if s =~ /^\s*$/\r
+            synopsisElement.add(REXML::Element::new('p').add_text(s))\r
+         }\r
+      end         \r
       racine.add(synopsisElement)\r
       \r
       budgetElement = REXML::Element::new('budget')\r
       racine.add(synopsisElement)\r
       \r
       budgetElement = REXML::Element::new('budget')\r