+# Représente un ensemble de films\r
+\r
+require 'rexml/document'\r
+require 'thwait'\r
+\r
+require 'film.rb'\r
+require 'pays.rb'\r
+require 'genre.rb'\r
+require 'personne.rb'\r
+require 'constantes.rb'\r
+\r
+class Films\r
+ def initialize(xmlFile)\r
+ @xmlFile = xmlFile\r
+ \r
+ # repertoire de base, par exemple C:/Divx/\r
+ @repBase = '' \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 # le nombre de connexion\r
+ \r
+ # le prochain id disponible\r
+ @idDisponible = 1\r
+ \r
+ chargerFilms\r
+ end\r
+\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
+ Dir::chdir(r)\r
+ \r
+ pomperR('.')\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
+ ajouterFilm(f)\r
+ end\r
+ i += 1\r
+ }\r
+ \r
+ Dir::chdir(repPrecedant) \r
+ end\r
+ \r
+ # Sauve les films dans un fichier XML\r
+ def sauverFilms\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
+ # sauve le document\r
+ docXml.write(File::new(@xmlFile, 'w'), 0)\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
+ 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_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
+ \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
+ 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
+ debut = false\r
+ }\r
+ film.budget = budget.value unless budget.nil?\r
+ @films[film.titre] = film\r
+ }\r
+ end\r
+ \r
+ # Retourne un nouvel id, utilisé lors de la création d'un nouveau film\r
+ def getNewId\r
+ id = @idDisponible\r
+ @idDisponible += 1\r
+ return id\r
+ end \r
+ \r
+ # Ajoute un film\r
+ def 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
+ # Appelé par 'pomper'. Cette méthode est récursive.\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
+ 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
+ film = nil\r
+ \r
+ # pour limiter le nombre de connexion simultanée\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::new(fichier).loadData\r
+ film.id = getNewId # on lui donne un nouvel ID\r
+ \r
+ unless film.nil? # le film a été correctement construit\r
+ 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
+end
\ No newline at end of file