git-svn-id: svn://euphorik.ch/pompage@35 02bbb61a-6d21-0410-aba0-cb053bdfd66a
[pompage.git] / src / film.rb
index 658b9d3..b56ad07 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 document XML.\r
-   def Film::getFilmsXml\r
-      racine = REXML::Element::new('filmographie')\r
-      docXml = REXML::Document::new\r
-      docXml.add(racine)\r
-      docXml.xml_decl().encoding = "UTF-8"   \r
-      docXml.xml_decl().dowrite \r
-      \r
-      @@films.each{|nom, f|\r
-         racine.add(f.getXml)\r
-      } \r
-      docXml\r
+class Film\r
+   \r
+   def Film::setModule(m)\r
+      @@module = m\r
    end\r
    \r
    end\r
    \r
-private\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
-   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
+   # 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
@@ -162,133 +47,163 @@ 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
+   # 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] : soit même\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 : true si le conflit à été résolu sinon false\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
+         choix = STDIN.gets\r
+         \r
+         if /A/i =~ choix\r
+            return true\r
+         elsif /B/i =~ choix\r
+            return false\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
+      @@module.load(@choix[tabNoms[choix-1]], self)\r
+      \r
+      return true\r
+   end\r
    \r
    \r
-      #extrait le nom à partire du nom du fichier\r
-      /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichier\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./ =~ 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
-            /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