MOD Vitesse de la recherche
[pompage.git] / src / film.rb
index b795841..a282441 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
+require 'modules/allocine.rb'\r
 \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 élement XML.\r
-   def Film::getFilmsXml\r
-      racine = REXML::Element::new('filmographie')\r
-      @@films.each{|nom, f|\r
-         racine.add(f.getXml)\r
-      }\r
-      return REXML::Document::new.add(racine)\r
+class Film\r
+   \r
+   def Film::setModule(m)\r
+      @@module = m\r
    end\r
    \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
-            @@nbConn += 1    \r
-            @@threadsWait.join_nowait(\r
-               Thread::new{    \r
-                  begin\r
-                     @@mutex.lock if @@nbConn >= NB_CONN_MAX                     \r
-                     #p @@nbConn     \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
+   # toutes les données membres sont accessibles par défaut (écriture/lecture)\r
+   attr_accessor :id, :titre, :url, :fichiers, :annee, :realisateurs, :acteurs, :pays, :duree, :critiquePresse, :critiqueSpectateur, :genres, :synopsis, :budget\r
 \r
 \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)\r
    def initialize(fichier)\r
-      @fichier = fichier\r
+      @fichiers = [fichier] # le chemin des fichiers est relatif au repertoire de base\r
+           \r
+      @id = 0\r
       @titre = ''\r
       @annee = nil\r
       @realisateurs = []\r
       @titre = ''\r
       @annee = nil\r
       @realisateurs = []\r
@@ -157,134 +47,166 @@ private
       @synopsis = nil\r
       @budget = nil      \r
       @budgetUnite = 'euro'\r
       @synopsis = nil\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
-   #charge les informations du films à partir d'allocine.fr\r
-   def loadData\r
-      unless LOAD_DATA\r
-         @titre = @fichier\r
-         return self\r
-      end\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
-      connexionHttp = Net::HTTP::new('www.allocine.fr');\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
    \r
-      #extrait le nom à partire du nom du fichier\r
-      /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichier\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
+      \r
+      @@module.load(@choix[tabNoms[choix-1]], self)\r
+      \r
+      return 1\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
+      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
+      /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichiers[0]\r
       #remplace undescores et points par des espaces\r
       titre = $1.gsub(/[_\.]/, ' ')\r
       #remplace undescores et points par des espaces\r
       titre = $1.gsub(/[_\.]/, ' ')\r
-      #vire les espaces au début et à la fin\r
-      titre.strip!\r
       #remplace les suites d'espaces par un seul\r
       titre.gsub!(/ {2,}/,' ')\r
       titre.gsub!(/\[.*?\]/,'')\r
       titre.gsub!(/\(.*?\)/,'')\r
       #remplace les suites d'espaces par un seul\r
       titre.gsub!(/ {2,}/,' ')\r
       titre.gsub!(/\[.*?\]/,'')\r
       titre.gsub!(/\(.*?\)/,'')\r
+      titre.gsub!(/\{.*?\}/,'')\r
+      #vire les espaces au début et à la fin\r
+      titre.strip!\r
+      \r
       @titre = titre.dup\r
       \r
       @titre = titre.dup\r
       \r
-      donneesHtml = nil\r
-      begin\r
-         reponse, donneesHtml = connexionHttp.get("/recherche/?motcle=#{CGI::escape(titre)}")\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
-            # 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
-            /Réalisé par <a class="link1" href=".*?" target="">(.*?)<\/a>/ =~ ficheHtml\r
-            @realisateurs << Personne::ajouter($1) unless $1.nil?\r
-                        \r
-            # Acteurs\r
-            /Avec(.*)/ =~ ficheHtml\r
-            $1.scan(/<a class="link1" href="\/personne\/fichepersonne_gen_cpersonne=\d+\.html" target="">(.+?)<\/a>/m){|a|\r
-               @acteurs << Personne::ajouter(a[0]) unless a[0].nil? \r
-            } unless $1.nil?     \r
-                      \r
-            # Pays\r
-            /^<h4>Film (.*?)\.<\/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.<\/h4>/ =~ ficheHtml\r
-            @duree = $1.nil? ? $2.to_i : $1.to_i * 60 + $2.to_i\r
-            \r
-            # Critique presse\r
-            /Presse<\/a> <img src=".*?etoile_(\d)\.gif"/ =~ ficheHtml\r
-            @critiquePresse = $1.to_i unless $1.nil?\r
-                                    \r
-            # Critique spectateur\r
-            /Spectateurs<\/a> <img src=".*?etoile_(\d)\.gif"/ =~ ficheHtml\r
-            @critiqueSpectateur = $1.to_i unless $1.nil?\r
-            \r
-            # Genre\r
-            /Genre : (.*)/ =~ 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 = @@module.rechercherFilm(titre)\r
+      @nbReponses = reponses.size\r
+      \r
+      if @nbReponses == 1\r
+         @@module.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
-   def getXml   \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
       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
 \r
+      realisateurs = REXML::Element::new('realisateurs')      \r
       @realisateurs.each{|r|\r
       @realisateurs.each{|r|\r
-         racine.add(REXML::Element::new('realisateur').add_text(r.nom))\r
+         realisateurs.add(REXML::Element::new('realisateur').add_text(r.nom))\r
       }\r
       }\r
+      racine.add(realisateurs)\r
    \r
    \r
+      acteurs = REXML::Element::new('acteurs')  \r
       @acteurs.each{|a|\r
       @acteurs.each{|a|\r
-         racine.add(REXML::Element::new('acteur').add_text(a.nom))\r
+         acteurs.add(REXML::Element::new('acteur').add_text(a.nom))\r
       }\r
       }\r
+      racine.add(acteurs)      \r
+      \r
+      lespays = REXML::Element::new('lespays')\r
       @pays.each{|p|\r
       @pays.each{|p|\r
-         racine.add(REXML::Element::new('pays').add_text(p.nom))\r
+         lespays.add(REXML::Element::new('pays').add_text(p.nom))\r
       }      \r
       }      \r
+      racine.add(lespays) \r
+      \r
       racine.add(REXML::Element::new('duree').add_text(@duree.to_s))\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
       @genres.each{|g|\r
-         racine.add(REXML::Element::new('genre').add_text(g.nom))\r
+         genres.add(REXML::Element::new('genre').add_text(g.nom))\r
       }      \r
       }      \r
-      racine.add(REXML::Element::new('synopsis').add_text(@synopsis))\r
+      racine.add(genres) \r
+      \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
       budgetElement.add_attribute('unite', @budgetUnite)\r
       racine.add(budgetElement)\r
+      \r
+      racine.add(REXML::Element::new('url').add_text(@url))\r
 \r
       racine\r
    end\r
 \r
       racine\r
    end\r