X-Git-Url: http://git.euphorik.ch/?p=pompage.git;a=blobdiff_plain;f=src%2Ffilms.rb;h=01dce5e22df637d98d8164aa7e3299240ea7eb3f;hp=a934dbb29dc948ffff8415e35125933ba3efaa4c;hb=2032fe6002667f4f349e6985dd01196b082c06f5;hpb=c967b07b58b4588996be0ebefa5a2d10e0663cf6 diff --git a/src/films.rb b/src/films.rb index a934dbb..01dce5e 100644 --- a/src/films.rb +++ b/src/films.rb @@ -1,4 +1,4 @@ -# Représente un ensemble de films +# coding: utf-8 require 'rexml/document' require 'thwait' @@ -8,58 +8,117 @@ require 'pays.rb' require 'genre.rb' require 'personne.rb' require 'constantes.rb' +require 'iconv' +# Représente un ensemble de films. class Films - def initialize(xmlFile) + def initialize(xmlFile, modClasse) @xmlFile = xmlFile + @modClasse = modClasse + # repertoire de base, par exemple C:/Divx/ @repBase = '' - # Les films indexés par leur titre + # Les films indexé par leur titre @films = {} - # Les films indexés par leur nom de fichier, deux fichiers différents peuvent pointer sur le même film + # Les films indexé par leur nom de fichier, deux fichiers différents peuvent pointer sur le même film @filmsFichier = {} - # Les films qui ont plusieurs réponses lors de la recherche, traités à la fin + # Les films qui ont plusieurs réponses lors de la recherche, traité à la fin @filmsPlusieursReponses = [] + # Les films qui n'ont aucune réponse après une recherche, traité à la fin + @filmsAucuneReponse = [] + + # permet de traiter facilement des groupes de thread @threadsWait = ThreadsWait::new @nbConn = 0 # le nombre de connexion + @mutexAjout = Mutex::new # mutex pour protéger l'ajout + @mutexId = Mutex::new # mutex pour protéger la génération d'id + # le prochain id disponible @idDisponible = 1 chargerFilms end + + def each + @films.each{|t,f| + yield f + } + end - # Lit un repertoire de manière recursive et va chercher les informations concernant le film sur le net + # Lit un repertoire de manière recursive et va chercher les informations concernant le film sur le net. def pomper(r) @repBase = r repPrecedant = Dir::getwd Dir::chdir(r) + t = Time::now + pomperR('.') # on attends que les threads se terminent @threadsWait.all_waits - # traite les films qui avaient plusieurs réponses lors de la recherche + puts "Pompage terminé, temps : #{Time::now - t} secondes" + + # traite les films qui avaient plusieurs réponses lors de la recherche # l'utilisateur doit faire un choix i = 1 @filmsPlusieursReponses.each{|f| puts puts "Plop, ya un conflit #{i} / #{@filmsPlusieursReponses.length} :" - if f.reglerConflitPlusieursReponses - ajouterFilm(f) + case f.reglerConflitPlusieursReponses + when 1 + ajouterFilm(f) + when 3 + break end i += 1 } + # traite les films qui n'avaient aucune réponse + i = 1 + @filmsAucuneReponse.each{|f| + puts + puts "Plop, Ce film n'a pas été trouvé #{i} / #{@filmsAucuneReponse.length} :" + case f.reglerConflitPlusieursReponses + when 1 + ajouterFilm(f) + when 3 + break + end + i += 1 + } + + # annonce à chaque module d'importation que c'est fini + @films.each{|t,f| + f.mod.finish + } + Dir::chdir(repPrecedant) end + # Mise à jour des films dans la BD. + # p1 string : un motif Regex correspondant à un ou plusieurs champs + def update(champ, titre) + @films.each{|t, f| + next if !f.titre.match(Regexp::new(titre, true)) + + ## si le film est complet on ne fait rien + if $force || f.url == nil || f.titre == '' || f.annee == nil || + f.realisateurs.empty? || f.acteurs.empty? || f.pays.empty? || + f.genres.empty? || f.synopsis == nil || !f.possedeImage? + + f.update(champ) + end + } + end + # Sauve les films dans un fichier XML def sauverFilms # le document @@ -73,154 +132,174 @@ class Films pi = REXML::Instruction.new("xml-stylesheet", "type=\"text/xsl\" href=\"../xsl/yopyop.xsl\"") racine.previous_sibling = pi - # on ajoute chaque film à la racine + # on ajoute chaque film à la racine @films.each{|nom, f| racine.add(f.getXml) } # sauve le document - docXml.write(File::new(@xmlFile, 'w'), 0) + docXml.write(File::new(@xmlFile, 'w'), 1) end private # Charge les films depuis le fichier XML def chargerFilms - # si le fichier n'existe pas il n'y a rien à charger + # si le fichier n'existe pas il n'y a rien à charger if !File.exists?(@xmlFile) return end - + racine = REXML::Document::new(File::new(@xmlFile)).root - racine.each_element{|e| + racine.elements.each("film"){|e| id = e.attribute('id').to_s.to_i - if id > @idDisponible + if id >= @idDisponible @idDisponible = id + 1 end - titre = e.get_elements('titre')[0].get_text + film = Film::new(nil, @modClasse::new) + film.id = id - fichiers = e.get_elements('fichiers')[0].get_elements('fichier') - annee = e.get_elements('annee')[0].get_text - duree = e.get_elements('duree')[0].get_text - critiquePresse = e.get_elements('critiquePresse')[0].get_text - critiqueSpectateur = e.get_elements('critiqueSpectateur')[0].get_text - synopsis = e.get_elements('synopsis')[0].get_elements('p') - budget = e.get_elements('budget')[0].get_text - realisateurs = e.get_elements('realisateurs')[0].get_elements('realisateur') - acteurs = e.get_elements('acteurs')[0].get_elements('acteur') - pays = e.get_elements('lespays')[0].get_elements('pays') - genres = e.get_elements('genres')[0].get_elements('genre') + film.titre = e.get_text('titre') + film.titre = film.titre.value if film.titre != nil - film = Film::new(fichiers[0].get_text.value) + print "#{film.titre}.. " + - film.titre = titre.value unless titre.nil? - film.id = id - fichiers.each{|e| - film.addFichier(e.get_text.value) - @filmsFichier[e.get_text.value] = film + film.url = e.get_text('url') + film.url = film.url.value if film.url != nil + + film.annee = e.get_text('annee') + film.annee = film.annee.value if film.annee != nil + + film.duree = e.get_text('duree') + film.duree = film.duree.value if film.duree != nil + + film.critiquePresse = e.get_text('critiquePresse') + film.critiquePresse = film.critiquePresse.value if film.critiquePresse != nil + + film.critiqueSpectateur = e.get_text('critiqueSpectateur') + film.critiqueSpectateur = film.critiqueSpectateur.value if film.critiqueSpectateur != nil + + film.budget = e.get_text('budget') + film.budget = film.budget.value if film.budget != nil + + e.elements.each('fichiers/fichier'){|f| + next if f.get_text == nil + film.addFichier(f.get_text.value) + @filmsFichier[f.get_text.value] = film } - film.annee = annee.value unless annee.nil? - acteurs.each{|e| - film.acteurs << Personne::ajouter(e.get_text.value) + + e.elements.each('realisateurs/realisateur'){|f| + film.realisateurs << Personne::ajouter(f.get_text.value) } - pays.each{|e| - film.pays << Pays::ajouter(e.get_text.value) + + e.elements.each('acteurs/acteur'){|f| + film.acteurs << Personne::ajouter(f.get_text.value) } - film.duree = duree.value unless duree.nil? - film.critiquePresse = critiquePresse.value unless critiquePresse.nil? - film.critiqueSpectateur = critiqueSpectateur.value unless critiqueSpectateur.nil? - genres.each{|e| - film.genres << Genre::ajouter(e.get_text.value) if e.get_text != nil + + e.elements.each('lespays/pays'){|f| + film.pays << Pays::ajouter(f.get_text.value) } + + e.elements.each('genres/genre'){|f| + film.genres << Genre::ajouter(f.get_text.value) + } + debut = true film.synopsis = "" - synopsis.each{|e| - film.synopsis += "\n" unless debut - film.synopsis += e.get_text.value if e.get_text != nil + e.elements.each('synopsis/p'){|f| + film.synopsis += "\n" unless debut + film.synopsis += f.get_text.value if f.get_text != nil debut = false - } - film.budget = budget.value unless budget.nil? + } + film.synopsis = nil if film.synopsis == "" + @films[film.titre] = film } end - # Retourne un nouvel id, utilisé lors de la création d'un nouveau film + # Retourne un nouvel id, utilisé alors de la création d'un nouveau film def getNewId id = @idDisponible @idDisponible += 1 return id end - # Ajoute un film + # Ajoute un film à l'ensemble des films. def ajouterFilm(film) if film.plusieursReponses? @filmsPlusieursReponses << film return end - # le film existe déjà + if film.nbReponses == 0 + @filmsAucuneReponse << film + return + end + if @films.has_key?(film.titre) - # le fichier n'est pas connu -> nième partie d'un film if !@filmsFichier.has_key?(film.fichiers[0]) - puts "[i] movie #{film.titre} has a another file part : #{film.fichiers[0]}" + puts "[i] Le film #{film.titre} possède une autre partie : #{film.fichiers[0]}" @films[film.titre].addFichier(film.fichiers[0]) @filmsFichier[film.fichiers[0]] = @films[film.titre] else - puts "[!] Duplicate movie : #{film.titre} (#{film.fichiers[0]})" + puts "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})" end else - puts "[i] movie added : #{film.titre} (#{film.fichiers[0]})" + puts "[i] Film ajouté : #{film.titre} (#{film.fichiers[0]})" @films[film.titre] = film @filmsFichier[film.fichiers[0]] = film end end - # Appelé par 'pomper'. Cette méthode est récursive. + # Appelé par 'pomper'. Cette méthode itère récursivement sur l'arborescence d'un repertoire. def pomperR(r) Dir::foreach(r){|f| next if f[0,1] == '.' fichier = (r == '.' ? '' : r + "/") + f if File::directory?(fichier) - litRepertoireR(fichier) + pomperR(fichier) else - # vérification de l'extension - /^.*?\.(.{3,4})$/ =~ fichier + #fichier = Iconv.iconv("UTF-8", "ISO-8859-1", fichier)[0] // sous windows il faut décommenter cette ligne + + # véfication de l'extension + /^.*?\.([^.]{3,4})$/ =~ fichier if !FILMS_EXTENSIONS.include?($1) next - end - - fichier = CGI::escapeHTML(fichier.unpack("C*").pack("U*")) - - # on skip si le film est déjàa dans la BD + end + + # on skip si le film est déjà dans la BD if film = @filmsFichier[fichier] - puts "[i] Already exists in DB : #{film.titre} (#{fichier})" + puts "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})" next end - - film = nil - # pour limiter le nombre de connexion simultanée + # pour limiter le nombre de connexion simultanée if @nbConn >= NB_CONN_MAX @threadsWait.next_wait end @nbConn += 1 @threadsWait.join_nowait( - Thread::new{ + Thread::start{ begin - film = Film::new(fichier).loadData - film.id = getNewId # on lui donne un nouvel ID + film = Film::new(fichier, @modClasse::new) + @mutexId.synchronize{ + film.id = getNewId # on lui donne un nouvel ID + } + + film.loadData # chargement de ses données - unless film.nil? # le film a été correctement construit + @mutexAjout.synchronize{ ajouterFilm(film) - end + } rescue Exception => e puts e.message puts e.backtrace - end + end @nbConn -= 1 } )