-# Représente un ensemble de films\r
+# coding: utf-8\r
\r
require 'rexml/document'\r
require 'thwait'\r
require 'genre.rb'\r
require 'personne.rb'\r
require 'constantes.rb'\r
+require 'iconv'\r
\r
+# Représente un ensemble de films.\r
class Films\r
- def initialize(xmlFile)\r
+ def initialize(xmlFile, modClasse)\r
@xmlFile = xmlFile\r
\r
+ @modClasse = modClasse\r
+ \r
# repertoire de base, par exemple C:/Divx/\r
@repBase = '' \r
\r
- # Les films indexés par leur titre\r
+ # Les films indexé 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
+ # Les films indexé 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
+ # Les films qui ont plusieurs réponses lors de la recherche, traité à la fin\r
@filmsPlusieursReponses = []\r
\r
+ # Les films qui n'ont aucune réponse après une recherche, traité à la fin\r
+ @filmsAucuneReponse = []\r
+\r
+ # permet de traiter facilement des groupes de thread\r
@threadsWait = ThreadsWait::new\r
@nbConn = 0 # le nombre de connexion\r
\r
+ @mutexAjout = Mutex::new # mutex pour protéger l'ajout\r
+ @mutexId = Mutex::new # mutex pour protéger la génération d'id\r
+ \r
# le prochain id disponible\r
@idDisponible = 1\r
\r
chargerFilms\r
end\r
+ \r
+ def each\r
+ @films.each{|t,f|\r
+ yield f\r
+ }\r
+ end\r
\r
- # Lit un repertoire de manière recursive et va chercher les informations concernant le film sur le net\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
+ t = Time::now\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
+ puts "Pompage terminé, temps : #{Time::now - t} secondes"\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
+ case f.reglerConflitPlusieursReponses\r
+ when 1\r
+ ajouterFilm(f) \r
+ when 3\r
+ break\r
end\r
i += 1\r
}\r
\r
+ # traite les films qui n'avaient aucune réponse\r
+ i = 1\r
+ @filmsAucuneReponse.each{|f|\r
+ puts\r
+ puts "Plop, Ce film n'a pas été trouvé #{i} / #{@filmsAucuneReponse.length} :"\r
+ case f.reglerConflitPlusieursReponses\r
+ when 1\r
+ ajouterFilm(f)\r
+ when 3\r
+ break\r
+ end\r
+ i += 1\r
+ }\r
+ \r
+ # annonce à chaque module d'importation que c'est fini\r
+ @films.each{|t,f|\r
+ f.mod.finish\r
+ }\r
+ \r
Dir::chdir(repPrecedant) \r
end\r
\r
+ # Mise à jour des films dans la BD.\r
+ # p1 string : un motif Regex correspondant à un ou plusieurs champs\r
+ def update(champ, titre)\r
+ @films.each{|t, f|\r
+ next if !f.titre.match(Regexp::new(titre, true))\r
+ \r
+ ## si le film est complet on ne fait rien\r
+ if $force || f.url == nil || f.titre == '' || f.annee == nil ||\r
+ f.realisateurs.empty? || f.acteurs.empty? || f.pays.empty? ||\r
+ f.genres.empty? || f.synopsis == nil || !f.possedeImage?\r
+ \r
+ f.update(champ)\r
+ end\r
+ }\r
+ end\r
+ \r
# Sauve les films dans un fichier XML\r
def sauverFilms\r
# le document\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
+ # on ajoute chaque film à la racine\r
@films.each{|nom, f|\r
racine.add(f.getXml)\r
} \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
+ # si le fichier n'existe pas il n'y a rien à charger\r
if !File.exists?(@xmlFile)\r
return\r
end\r
- \r
+ \r
racine = REXML::Document::new(File::new(@xmlFile)).root\r
- racine.each_element{|e| \r
+ racine.elements.each("film"){|e| \r
id = e.attribute('id').to_s.to_i\r
\r
- if id > @idDisponible\r
+ if id >= @idDisponible\r
@idDisponible = id + 1 \r
end\r
\r
- titre = e.get_elements('titre')[0].get_text\r
+ film = Film::new(nil, @modClasse::new)\r
+ film.id = id\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
+ film.titre = e.get_text('titre')\r
+ film.titre = film.titre.value if film.titre != nil\r
\r
- film = Film::new(fichiers[0].get_text.value)\r
+ print "#{film.titre}.. "\r
+\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
+ film.url = e.get_text('url')\r
+ film.url = film.url.value if film.url != nil\r
+\r
+ film.annee = e.get_text('annee')\r
+ film.annee = film.annee.value if film.annee != nil \r
+ \r
+ film.duree = e.get_text('duree')\r
+ film.duree = film.duree.value if film.duree != nil\r
+ \r
+ film.critiquePresse = e.get_text('critiquePresse')\r
+ film.critiquePresse = film.critiquePresse.value if film.critiquePresse != nil\r
+ \r
+ film.critiqueSpectateur = e.get_text('critiqueSpectateur')\r
+ film.critiqueSpectateur = film.critiqueSpectateur.value if film.critiqueSpectateur != nil\r
+ \r
+ film.budget = e.get_text('budget')\r
+ film.budget = film.budget.value if film.budget != nil\r
+ \r
+ e.elements.each('fichiers/fichier'){|f|\r
+ next if f.get_text == nil\r
+ film.addFichier(f.get_text.value)\r
+ @filmsFichier[f.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
+ e.elements.each('realisateurs/realisateur'){|f|\r
+ film.realisateurs << Personne::ajouter(f.get_text.value)\r
}\r
- pays.each{|e|\r
- film.pays << Pays::ajouter(e.get_text.value)\r
+ \r
+ e.elements.each('acteurs/acteur'){|f|\r
+ film.acteurs << Personne::ajouter(f.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
+ e.elements.each('lespays/pays'){|f|\r
+ film.pays << Pays::ajouter(f.get_text.value)\r
}\r
+ \r
+ e.elements.each('genres/genre'){|f|\r
+ film.genres << Genre::ajouter(f.get_text.value)\r
+ } \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
+ e.elements.each('synopsis/p'){|f|\r
+ film.synopsis += "\n" unless debut \r
+ film.synopsis += f.get_text.value if f.get_text != nil\r
debut = false\r
- }\r
- film.budget = budget.value unless budget.nil?\r
+ } \r
+ film.synopsis = nil if film.synopsis == ""\r
+ \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
+ # Retourne un nouvel id, utilisé alors 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
+ # Ajoute un film à l'ensemble des films.\r
def ajouterFilm(film)\r
if film.plusieursReponses?\r
@filmsPlusieursReponses << film\r
return\r
end\r
\r
- # le film existe déjà\r
+ if film.nbReponses == 0\r
+ @filmsAucuneReponse << film\r
+ return\r
+ end\r
+ \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
+ puts "[i] Le film #{film.titre} possède une autre partie : #{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
+ puts "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})"\r
end\r
else\r
- puts "[i] movie added : #{film.titre} (#{film.fichiers[0]})"\r
+ puts "[i] Film ajouté : #{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
+ # Appelé par 'pomper'. Cette méthode itère récursivement sur l'arborescence d'un repertoire.\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
+ pomperR(fichier) \r
else\r
\r
- # vérification de l'extension\r
- /^.*?\.(.{3,4})$/ =~ fichier\r
+ #fichier = Iconv.iconv("UTF-8", "ISO-8859-1", fichier)[0] // sous windows il faut décommenter cette ligne\r
+ \r
+ # véfication 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
+ end
+ \r
+ # on skip si le film est déjà dans la BD\r
if film = @filmsFichier[fichier]\r
- puts "[i] Already exists in DB : #{film.titre} (#{fichier})"\r
+ puts "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})"\r
next\r
end\r
- \r
- film = nil\r
\r
- # pour limiter le nombre de connexion simultanée\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
+ Thread::start{\r
begin \r
- film = Film::new(fichier).loadData\r
- film.id = getNewId # on lui donne un nouvel ID\r
+ film = Film::new(fichier, @modClasse::new)\r
+ @mutexId.synchronize{\r
+ film.id = getNewId # on lui donne un nouvel ID\r
+ }\r
+ \r
+ film.loadData # chargement de ses données\r
\r
- unless film.nil? # le film a été correctement construit\r
+ @mutexAjout.synchronize{\r
ajouterFilm(film)\r
- end\r
+ }\r
rescue Exception => e\r
puts e.message\r
puts e.backtrace\r
- end \r
+ end\r
@nbConn -= 1\r
}\r
)\r