X-Git-Url: http://git.euphorik.ch/?p=pompage.git;a=blobdiff_plain;f=src%2Ffilms.rb;h=7b1e625fecb8bebdad08229820bc1a1fd28100c8;hp=01dce5e22df637d98d8164aa7e3299240ea7eb3f;hb=29dd69679e2fa7c1b9d5a28265ad03aeac0f13b9;hpb=aaba068e2c52c67ba79edb55b4332bea66fda75f diff --git a/src/films.rb b/src/films.rb index 01dce5e..7b1e625 100644 --- a/src/films.rb +++ b/src/films.rb @@ -1,309 +1,323 @@ -# coding: utf-8 - -require 'rexml/document' -require 'thwait' - -require 'film.rb' -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, modClasse) - @xmlFile = xmlFile - - @modClasse = modClasse - - # repertoire de base, par exemple C:/Divx/ - @repBase = '' - - # Les films indexé par leur titre - @films = {} - - # 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é à 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. - 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 - - 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} :" - 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 - docXml = REXML::Document::new - docXml.xml_decl().encoding = "UTF-8" # normalement UTF-8 - docXml.xml_decl().dowrite - - # la racine du document - racine = REXML::Element::new('filmographie') - docXml.add(racine) - pi = REXML::Instruction.new("xml-stylesheet", "type=\"text/xsl\" href=\"../xsl/yopyop.xsl\"") - racine.previous_sibling = pi - - # on ajoute chaque film à la racine - @films.each{|nom, f| - racine.add(f.getXml) - } - - # sauve le document - 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 - if !File.exists?(@xmlFile) - return - end - - racine = REXML::Document::new(File::new(@xmlFile)).root - racine.elements.each("film"){|e| - id = e.attribute('id').to_s.to_i - - if id >= @idDisponible - @idDisponible = id + 1 - end - - film = Film::new(nil, @modClasse::new) - film.id = id - - film.titre = e.get_text('titre') - film.titre = film.titre.value if film.titre != nil - - print "#{film.titre}.. " - - - 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 - } - - e.elements.each('realisateurs/realisateur'){|f| - film.realisateurs << Personne::ajouter(f.get_text.value) - } - - e.elements.each('acteurs/acteur'){|f| - film.acteurs << Personne::ajouter(f.get_text.value) - } - - 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 = "" - 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.synopsis = nil if film.synopsis == "" - - @films[film.titre] = film - } - end - - # 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 à l'ensemble des films. - def ajouterFilm(film) - if film.plusieursReponses? - @filmsPlusieursReponses << film - return - end - - if film.nbReponses == 0 - @filmsAucuneReponse << film - return - end - - if @films.has_key?(film.titre) - if !@filmsFichier.has_key?(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 "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})" - end - else - 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 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) - pomperR(fichier) - else - - #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 +# coding: utf-8 + +require 'rexml/document' +require 'thwait' + +require 'film.rb' +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, modClasse) + @xmlFile = xmlFile + + @modClasse = modClasse + + # repertoire de base, par exemple C:/Divx/ + @repBase = '' + + # Les films indexé par leur titre + @films = {} + + # 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é à 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. + 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 + + 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} :" + 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 + #puts self # print all files before saving in XML + + # le document + docXml = REXML::Document::new + docXml.xml_decl().encoding = "UTF-8" # normalement UTF-8 + docXml.xml_decl().dowrite + + # la racine du document + racine = REXML::Element::new('filmographie') + docXml.add(racine) + pi = REXML::Instruction.new("xml-stylesheet", "type=\"text/xsl\" href=\"../xsl/yopyop.xsl\"") + racine.previous_sibling = pi + + # on ajoute chaque film à la racine + @films.each{|nom, f| + racine.add(f.getXml) + } + + # sauve le document + docXml.write(File::new(@xmlFile, 'w')) + end + + def to_s + acc = "" + @films.each_value{|f| + acc += f.to_s + } + return acc + end + + private + + # Enlève les \n et espace au début et à la fin de 'texte' et retourne le résultat + def nettoyer_texte(texte) + texte =~ /^[\n ]*(.*?)[\n ]*$/ + return $1 + end + + # Charge les films depuis le fichier XML + def chargerFilms + # 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.elements.each("film"){|e| + id = e.attribute('id').to_s.to_i + + if id >= @idDisponible + @idDisponible = id + 1 + end + + film = Film::new(nil, @modClasse::new) + film.id = id + + film.titre = e.get_text('titre') + film.titre = nettoyer_texte(film.titre.value) if film.titre != nil + + print "#{film.titre}.. " + + film.url = e.get_text('url') + film.url = nettoyer_texte(film.url.value) if film.url != nil + + film.annee = e.get_text('annee') + film.annee = nettoyer_texte(film.annee.value) if film.annee != nil + + film.duree = e.get_text('duree') + film.duree = nettoyer_texte(film.duree.value) if film.duree != nil + + film.critiquePresse = e.get_text('critiquePresse') + film.critiquePresse = nettoyer_texte(film.critiquePresse.value) if film.critiquePresse != nil + + film.critiqueSpectateur = e.get_text('critiqueSpectateur') + film.critiqueSpectateur = nettoyer_texte(film.critiqueSpectateur.value) if film.critiqueSpectateur != nil + + film.budget = e.get_text('budget') + film.budget = nettoyer_texte(film.budget.value) if film.budget != nil + + e.elements.each('fichiers/fichier'){|f| + next if f.get_text == nil + film.addFichier(nettoyer_texte(f.get_text.value)) + @filmsFichier[nettoyer_texte(f.get_text.value)] = film + } + + e.elements.each('realisateurs/realisateur'){|f| + film.realisateurs << Personne::ajouter(nettoyer_texte(f.get_text.value)) + } + + e.elements.each('acteurs/acteur'){|f| + film.acteurs << Personne::ajouter(nettoyer_texte(f.get_text.value)) + } + + e.elements.each('lespays/pays'){|f| + film.pays << Pays::ajouter(nettoyer_texte(f.get_text.value)) + } + + e.elements.each('genres/genre'){|f| + film.genres << Genre::ajouter(nettoyer_texte(f.get_text.value)) + } + + debut = true + film.synopsis = "" + e.elements.each('synopsis/p'){|f| + film.synopsis += "\n" unless debut + film.synopsis += nettoyer_texte(f.get_text.value) if f.get_text != nil + debut = false + } + film.synopsis = nil if film.synopsis == "" + + @films[film.titre] = film + } + end + + # 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 à l'ensemble des films. + def ajouterFilm(film) + if film.plusieursReponses? + @filmsPlusieursReponses << film + return + end + + if film.nbReponses == 0 + @filmsAucuneReponse << film + return + end + + if @films.has_key?(film.titre) + if !@filmsFichier.has_key?(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 "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})" + end + else + puts "[i] Film ajouté : (#{film.id}) #{film.titre} (#{film.fichiers[0]}) #{film.id}" + @films[film.titre] = film + @filmsFichier[film.fichiers[0]] = film + end + end + + # 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) + pomperR(fichier) + else + #fichier = Iconv.iconv("UTF-8", "ISO-8859-1", fichier)[0] + + # véfication de l'extension + /^.*?\.([^.]{3,4})$/ =~ fichier + if !FILMS_EXTENSIONS.include?($1) + next end - - # on skip si le film est déjà dans la BD - if film = @filmsFichier[fichier] - puts "[!] Film déjà dans la BD : #{film.titre} (#{film.fichiers[0]})" - next - end - - # pour limiter le nombre de connexion simultanée - if @nbConn >= NB_CONN_MAX - @threadsWait.next_wait - end - - @nbConn += 1 - @threadsWait.join_nowait( - Thread::start{ - begin - film = Film::new(fichier, @modClasse::new) - @mutexId.synchronize{ - film.id = getNewId # on lui donne un nouvel ID - } - - film.loadData # chargement de ses données - - @mutexAjout.synchronize{ - ajouterFilm(film) - } - rescue Exception => e - puts e.message - puts e.backtrace - end - @nbConn -= 1 - } - ) - end - } - end -end \ No newline at end of file + + # on skip si le film est déjà dans la BD + if film = @filmsFichier[fichier] + puts "[!] Film déjà dans la BD : (#{film.id}) #{film.titre} (#{film.fichiers[0]})" + next + end + + # pour limiter le nombre de connexion simultanée + if @nbConn >= NB_CONN_MAX + @threadsWait.next_wait + end + + @nbConn += 1 + @threadsWait.join_nowait( + Thread::start{ + begin + film = Film::new(fichier, @modClasse::new) + @mutexId.synchronize{ + film.id = getNewId # on lui donne un nouvel ID + } + + film.loadData # chargement de ses données + + @mutexAjout.synchronize{ + ajouterFilm(film) + } + rescue Exception => e + puts e.message + puts e.backtrace + end + @nbConn -= 1 + } + ) + end + } + end +end