ADD Pompage des images ! :)
[pompage.git] / src / film.rb
index a7bcc54..309f686 100644 (file)
-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
-class Film\r
-   attr_accessor :titre, :fichier, :annee, :realisateurs, :acteurs, :pays, :duree, :critiquePresse, :critiqueSpectateur, :genres, :synopsis, :budget\r
-      \r
-   # Les films indexés par leur titre\r
-   @@films = {}\r
-   \r
-   # Les films indexés par leur nom de fichier\r
-   @@filmsFichier = {}\r
-\r
-   @@mutex = Mutex::new\r
-   @@threadsWait = ThreadsWait::new\r
-   @@nbConn = 0\r
-\r
+require 'modules/allocine.rb'\r
 \r
 \r
-   # Lit un repertoire de manière recursive\r
-   def Film::litRepertoire(r)\r
-      Film::litRepertoireR(r)\r
-      # on attends que les threads se terminent\r
-      @@threadsWait.all_waits\r
+# ajout de deux méthodes à la classe String\r
+class String\r
+   def virerBalisesHTML\r
+      return gsub(/<(.*?)>/, '')\r
    end\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
-         fichier = e.get_elements('fichier')[0].get_text\r
-         next if fichier == nil\r
-         titre = e.get_elements('titre')[0].get_text\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('realisateur')\r
-         acteurs = e.get_elements('acteur')\r
-         pays = e.get_elements('pays')\r
-         genres = e.get_elements('genres')\r
-         \r
-      \r
-         film = Film::new(fichier.value)\r
-         film.titre = titre.value unless titre.nil?\r
-         film.annee = annee.value unless annee.nil?\r
-         realisateurs.each{|e|\r
-            film.realisateurs << Personne::ajouter(e.get_text.value)\r
-         }        \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)\r
-         }\r
-         film.synopsis = synopsis.value unless synopsis.nil?\r
-         film.budget = budget.value unless budget.nil?\r
-         @@films[film.titre] = film\r
-         @@filmsFichier[film.fichier] = film\r
-      }   \r
+   def virerBalisesHTML!\r
+      gsub!(/<(.*?)>/, '')\r
    end\r
    end\r
+end\r
 \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
-      \r
-      # on ajoute chaque film à la racine\r
-      @@films.each{|nom, f|\r
-         racine.add(f.getXml)\r
-      } \r
+class Film\r
       \r
       \r
-      # revoie le document\r
-      docXml\r
-   end\r
-   \r
-private\r
-\r
-   def Film::filmsFactory(fichier)\r
-      /^.*?\.(.{3,4})$/ =~ fichier\r
-      if FILMS_EXTENSIONS.include?($1)\r
-         Film::new(fichier).loadData\r
-      end\r
-    end\r
-    \r
-   def Film::litRepertoireR(r)\r
-      Dir::foreach(r){|f|\r
-         next if f == '.' or f == '..'\r
-         fichier = r + "/" + f\r
-         if File::directory?(fichier)\r
-            litRepertoireR(fichier) \r
-         else\r
-         \r
-            #si le film n'existe pas déjà dans la liste\r
-            if film = @@filmsFichier[fichier]\r
-               puts "[i] Already exists in DB : #{film.titre} (#{film.fichier})"\r
-               next\r
-            end\r
-            \r
-            film = nil\r
-             \r
-            @@nbConn += 1    \r
-            @@threadsWait.join_nowait(\r
-               Thread::new{    \r
-                  begin\r
-                     @@mutex.lock if @@nbConn >= NB_CONN_MAX                     \r
-                     film = Film::filmsFactory(fichier)\r
-                     unless film.nil?\r
-                        if @@films.has_key?(film.titre)\r
-                           puts "[!] Duplicate movie : #{film.titre} (#{film.fichier})"\r
-                        else\r
-                           puts "[i] movie added : #{film.titre} (#{film.fichier})"\r
-                           @@films[film.titre] = film\r
-                           @@filmsFichier[film.fichier] = film\r
-                        end\r
-                     end\r
-                     @@nbConn -= 1\r
-                     #p @@nbConn\r
-                     @@mutex.unlock\r
-                  rescue  Exception => e\r
-                     puts e.message\r
-                     puts e.backtrace\r
-                  end\r
-               }\r
-            )\r
-         end\r
-      }\r
-    end\r
-\r
-   \r
-   def initialize(fichier)\r
-      #convertit le code latin-1 en UTF8\r
-      @fichier = fichier.unpack("C*").pack("U*")\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
+   # 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
            \r
+      @id = 0\r
       @titre = ''\r
       @annee = nil\r
       @realisateurs = []\r
       @titre = ''\r
       @annee = nil\r
       @realisateurs = []\r
@@ -171,22 +45,77 @@ private
       @budget = nil      \r
       @budgetUnite = 'euro'\r
       @url\r
       @budget = nil      \r
       @budgetUnite = 'euro'\r
       @url\r
+            \r
+      @nbReponses = 0\r
+      \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
+   # Est-ce qu'il y a eu plusieurs réponses pour ce film lors de la cherche sur le net ?\r
+   def plusieursReponses?\r
+      return @nbReponses > 1\r
+   end    \r
 \r
 \r
-   # Charge les informations du films à partir d'allocine.fr\r
-   # ret [Film]\r
-   def loadData\r
-      unless LOAD_DATA\r
-         @titre = @fichier\r
-         return self\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
+   # 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
+      @nbReponses = 1\r
+      \r
+      puts " -> " + @fichiers[0]\r
+      puts "Fais ton choix jeune padawan (un caractère et pas plus)"\r
+      tabNoms = @choix.keys\r
+      choix = 1\r
+      loop do \r
+         i = 1\r
+         tabNoms.each{|n|\r
+           puts "#{i}. #{n}"\r
+           i += 1\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
+            return 1\r
+         elsif /B/i =~ choix\r
+            return 2\r
+         elsif /C/i =~ choix\r
+            return 3\r
+         end\r
+         \r
+         choix = choix.to_i\r
+         if choix > 0 && choix <= tabNoms.length\r
+            break;\r
+         else\r
+            puts\r
+            puts "Choix pas bon !!"\r
+         end\r
       end\r
       end\r
-\r
-      connexionHttp = Net::HTTP::new('www.allocine.fr');\r
+      \r
+      @mod.load(@choix[tabNoms[choix-1]], self)\r
+      \r
+      return 1\r
+   end\r
    \r
    \r
+   # Ajoute un fichier comme faisant partie du film\r
+   def addFichier(fichier)\r
+      if !@fichiers.include?(fichier)\r
+         @fichiers << fichier\r
+      end\r
+   end\r
+\r
+   # Charge les informations du films à partir d'allocine.fr\r
+   # ret [Film]\r
+   def loadData   \r
       #extrait le nom à partir du nom du fichier\r
       #extrait le nom à partir du nom du fichier\r
-      /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichier\r
+      /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichiers[0]\r
       #remplace undescores et points par des espaces\r
       titre = $1.gsub(/[_\.]/, ' ')\r
       #remplace les suites d'espaces par un seul\r
       #remplace undescores et points par des espaces\r
       titre = $1.gsub(/[_\.]/, ' ')\r
       #remplace les suites d'espaces par un seul\r
@@ -199,98 +128,37 @@ public
       \r
       @titre = titre.dup\r
       \r
       \r
       @titre = titre.dup\r
       \r
-      donneesHtml = nil\r
-      begin\r
-         reponse, donneesHtml = connexionHttp.get("/recherche/?motcle=#{CGI::escape(titre)}")\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\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
-         /<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">/ =~ donneesHtml\r
-         if $1\r
-            r, ficheHtml = connexionHttp.get("/film/fichefilm_gen_cfilm=#{$1}.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=#{$1}.html"\r
-            \r
-            # Titre\r
-            /<title>(.*?)<\/title>/ =~ ficheHtml\r
-            @titre = $1 unless $1.nil?\r
-            \r
-            puts "Movie found : #{@titre} (#{@fichier})"\r
-            \r
-            # Année\r
-            /<h4>Année de production : (\d+)<\/h4>/ =~ ficheHtml\r
-            @annee = $1.to_i 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
-                      \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\r
-            /<h4>Durée : (\d+)h (\d+)min./ =~ ficheHtml\r
-            @duree = $1.nil? ? $2.to_i : $1.to_i * 60 + $2.to_i\r
-            \r
-            # Critiques presse et spectateur\r
-            /Presse.*etoile_([012345]).*Spectateurs.*etoile_([012345])"/m =~ ficheHtml\r
-            @critiquePresse = $1.to_i unless $1.nil?\r
-            @critiqueSpectateur = $2.to_i 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
-            @synopsis = $1 unless $1.nil?\r
-            \r
-            # Budget       \r
-            /Budget<\/b> : (.+?) millions d'euros<\/h4>/ =~ ficheHtml\r
-            @budget = $1.to_i unless $1.nil?\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
-   # 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
    def getXml\r
+      \r
       racine = REXML::Element::new('film')\r
       racine = REXML::Element::new('film')\r
-      racine.add(REXML::Element::new('fichier').add_text(@fichier))\r
+      racine.add_attribute('id', @id.to_s)\r
+      \r
+      fichiers = REXML::Element::new('fichiers')\r
+      @fichiers.each{|f|\r
+         fichiers.add(REXML::Element::new('fichier').add_text(f))  \r
+      }\r
+      racine.add(fichiers)      \r
+      \r
       racine.add(REXML::Element::new('titre').add_text(@titre))\r
       racine.add(REXML::Element::new('titre').add_text(@titre))\r
-      racine.add(REXML::Element::new('annee').add_text(@annee.to_s))\r
+      racine.add(REXML::Element::new('annee').add_text(@annee))\r
 \r
       realisateurs = REXML::Element::new('realisateurs')      \r
       @realisateurs.each{|r|\r
 \r
       realisateurs = REXML::Element::new('realisateurs')      \r
       @realisateurs.each{|r|\r
@@ -312,8 +180,8 @@ public
       \r
       racine.add(REXML::Element::new('duree').add_text(@duree.to_s))\r
 \r
       \r
       racine.add(REXML::Element::new('duree').add_text(@duree.to_s))\r
 \r
-      racine.add(REXML::Element::new('critiquePresse').add_text(@critiquePresse.to_s))\r
-      racine.add(REXML::Element::new('critiqueSpectateur').add_text(@critiqueSpectateur.to_s))\r
+      racine.add(REXML::Element::new('critiquePresse').add_text(@critiquePresse))\r
+      racine.add(REXML::Element::new('critiqueSpectateur').add_text(@critiqueSpectateur))\r
       \r
       genres = REXML::Element::new('genres')\r
       @genres.each{|g|\r
       \r
       genres = REXML::Element::new('genres')\r
       @genres.each{|g|\r
@@ -321,9 +189,17 @@ public
       }      \r
       racine.add(genres) \r
       \r
       }      \r
       racine.add(genres) \r
       \r
-      racine.add(REXML::Element::new('synopsis').add_text(@synopsis))\r
+      synopsisElement = REXML::Element::new('synopsis')\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
       budgetElement = REXML::Element::new('budget')\r
-      budgetElement.add_text(@budget.to_s)\r
+      budgetElement.add_text(@budget)\r
       budgetElement.add_attribute('unite', @budgetUnite)\r
       racine.add(budgetElement)\r
       \r
       budgetElement.add_attribute('unite', @budgetUnite)\r
       racine.add(budgetElement)\r
       \r