1 require 'rexml/document'
11 require 'constantes.rb'
15 return self.gsub(/<(.*?)>/, '')
20 attr_accessor
:id, :titre, :fichiers, :annee, :realisateurs, :acteurs, :pays, :duree, :critiquePresse, :critiqueSpectateur, :genres, :synopsis, :budget
22 # Les films indexés par leur titre
25 # Les films indexés par leur nom de fichier, deux fichiers différents peuvent pointer sur le même film
28 # Les films qui ont plusieurs réponses lors de la recherche, traités à la fin
29 @
@filmsPlusieursReponses = []
32 @
@threadsWait = ThreadsWait
::new
35 # le prochain id disponible
38 # retourne un nouvel id, utilisé lors de la création d'un nouveau film
45 # Lit un repertoire de manière recursive
46 def Film
::litRepertoire(r
)
47 Film
::litRepertoireR(r
)
48 # on attends que les threads se terminent
49 @
@threadsWait.all_waits
51 # traite les films qui avaient plusieurs réponses lors de la recherche
52 # l'utilisateur doit faire un choix
53 @
@filmsPlusieursReponses.each
{|f
|
54 if f
.reglerConflitPlusieursReponses
60 # Charge les films contenus dans un fichier XML.
61 def Film
::loadFilmsXml(xmlFile
)
62 # si le fichier n'existe pas il n'y a rien à charger
63 if !File
.exists
?(xmlFile
)
67 racine
= REXML
::Document::new(File
::new(xmlFile
)).root
68 racine
.each_element
{|e
|
69 id
= e
.attribute('id').to_s
.to_i
71 if id
> @
@idDisponible
72 @
@idDisponible = id +
1
75 titre
= e
.get_elements('titre')[0].get_text
77 fichiers
= e
.get_elements('fichiers')[0].get_elements('fichier')
78 annee
= e
.get_elements('annee')[0].get_text
79 duree
= e
.get_elements('duree')[0].get_text
80 critiquePresse
= e
.get_elements('critiquePresse')[0].get_text
81 critiqueSpectateur
= e
.get_elements('critiqueSpectateur')[0].get_text
82 synopsis
= e
.get_elements('synopsis')[0].get_text
83 budget
= e
.get_elements('budget')[0].get_text
84 realisateurs
= e
.get_elements('realisateurs')[0].get_elements('realisateur')
85 acteurs
= e
.get_elements('acteurs')[0].get_elements('acteur')
86 pays
= e
.get_elements('lespays')[0].get_elements('pays')
87 genres
= e
.get_elements('genres')[0].get_elements('genre')
89 film
= Film
::new(fichiers
[0].get_text
.value
)
91 film
.titre
= titre
.value
unless titre
.nil?
94 film
.addFichier(e
.get_text
.value
)
95 @
@filmsFichier[e
.get_text
.value
] = film
97 film
.annee
= annee
.value
unless annee
.nil?
99 film
.acteurs
<< Personne
::ajouter(e
.get_text
.value
)
102 film
.pays
<< Pays
::ajouter(e
.get_text
.value
)
104 film
.duree
= duree
.value
unless duree
.nil?
105 film
.critiquePresse
= critiquePresse
.value
unless critiquePresse
.nil?
106 film
.critiqueSpectateur
= critiqueSpectateur
.value
unless critiqueSpectateur
.nil?
108 film
.genres
<< Genre
::ajouter(e
.get_text
.value
) if e
.get_text !
= nil
110 film
.synopsis
= synopsis
.value
unless synopsis
.nil?
111 film
.budget
= budget
.value
unless budget
.nil?
112 @
@films[film
.titre
] = film
116 # Renvoie tous les films sous la forme d'un document XML.
117 def Film
::getFilmsXml
119 docXml
= REXML
::Document::new
120 docXml
.xml_decl().encoding
= "UTF-8" # normalement UTF-8
121 docXml
.xml_decl().dowrite
123 # la racine du document
124 racine
= REXML
::Element::new('filmographie')
126 pi
= REXML
::Instruction.new("xml-stylesheet", "type=\"text/xsl\" href=\"../xsl/yopyop.xsl\"")
127 racine
.previous_sibling
= pi
129 # on ajoute chaque film à la racine
130 @
@films.each
{|nom
, f
|
140 def Film
::filmsFactory(fichier
)
141 Film
::new(fichier
).loadData
144 def Film
::litRepertoireR(r
)
146 next if f
== '.' or f
== '..'
147 fichier
= r +
"/" + f
148 if File
::directory?(fichier
)
149 litRepertoireR(fichier
)
152 # vérification de l'extension
153 /^.*?\.(.{3,4})$/ =~ fichier
154 if !FILMS_EXTENSIONS
.include?($1)
158 fichier
= CGI
::escapeHTML(fichier
.unpack("C*").pack("U*"))
160 # on skip si le film est déjàa dans la BD
161 if film
= @
@filmsFichier[fichier
]
162 puts
"[i] Already exists in DB : #{film.titre} (#{fichier})"
171 @
@threadsWait.join_nowait(
174 @
@mutex.lock
if @
@nbConn >= NB_CONN_MAX
175 film
= Film
::filmsFactory(fichier
)
176 unless film
.nil? # le film a été correctement construit
177 Film
::ajouterFilm(film
)
181 rescue Exception
=> e
191 def Film
::ajouterFilm(film
)
192 if film
.plusieursReponses
?
193 @
@filmsPlusieursReponses << film
197 # le film existe déjà
198 if @
@films.has_key
?(film
.titre
)
199 # le fichier n'est pas connu -> nième partie d'un film
200 if !@
@filmsFichier.has_key
?(film
.fichiers
[0])
201 puts
"[i] movie #{film.titre} has a another file part : #{film.fichiers[0]}"
202 @
@films[film
.titre
].addFichier(film
.fichiers
[0])
203 @
@filmsFichier[film
.fichiers
[0]] = @
@films[film
.titre
]
205 puts
"[!] Duplicate movie
: #{film.titre} (#{film.fichiers[0]})"
208 puts "[i
] movie added
: #{film.titre} (#{film.fichiers[0]})"
209 @@films[film.titre] = film
210 @@filmsFichier[film.fichiers[0]] = film
215 def initialize(fichier)
216 @fichiers = [fichier]
225 @critiquePresse = nil
226 @critiqueSpectateur = nil
230 @budgetUnite = 'euro'
233 @aPlusieursReponses = false
234 # mémorise les tuples {nom => id} dans le cas ou il y a plusieurs réponses
240 def plusieursReponses?
241 return @aPlusieursReponses
244 # demande à l'utilisateur de faire un choix
245 # ret : true si le conflit à été résolu sinon false
246 def reglerConflitPlusieursReponses
248 @aPlusieursReponses = false # pour faire les choses bien
251 puts "Plop
, ya un conflit
: #{@fichiers[0]}"
252 puts "Fais ton choix jeune
padawan (un caractère et pas plus
)"
253 tabNoms = @idsAllocine.keys
261 puts
"A. Passer et l'ajouter"
272 if choix
> 0 && choix
<= tabNoms
.length
276 puts
"Choix pas bon !!
"
280 loadDepuisIdAllocine(@idsAllocine[tabNoms[choix-1]])
285 def addFichier(fichier)
286 if !@fichiers.include?(fichier
)
291 # Charge les informations du films à partir d'allocine.fr
295 @titre = @fichiers[0]
301 connexionHttp
= Net
::HTTP::new('www.allocine.fr')
303 #extrait le nom à partir du nom du fichier
304 /^.*?([^\/]*?)\
.(.{3,4})$/ =~
@fichiers[0]
305 #remplace undescores et points par des espaces
306 titre
= $1.gsub(/[_\.]/, ' ')
307 #remplace les suites d'espaces par un seul
308 titre
.gsub!
(/ {2,}/,' ')
309 titre
.gsub!
(/\[.*?\]/,'')
310 titre
.gsub!
(/\(.*?\)/,'')
311 titre
.gsub!
(/\{.*?\}/,'')
312 #vire les espaces au début et à la fin
320 reponse
, donneesHtml
= connexionHttp
.get("/recherche/?motcle=#{CGI::escape(titre.unpack("U*").pack("C*"))}")
321 rescue Exception
=> e
323 puts
"[!] Connexion lost
, retry.."
327 #convertit le code latin-1 en UTF8
328 donneesHtml = donneesHtml.unpack("C
*").pack("U
*")
330 #si pas trouvé alors on enlève un mot à la fin
331 if /.*?Pas de résultats.*?/ =~ donneesHtml || ! donneesHtml
.include?("<h3><b>Films <h4>")
332 /(.*?)[^ ]+?$/ =~ titre
.strip
338 end while not titre
.nil? and not titre
.empty
?
340 unless titre
.nil? or titre
.empty
?
342 #/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">/ =~ donneesHtml
343 #r = donneesHtml.scan(/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">(.*?)<\/a>/)
344 r
= donneesHtml
.scan(/<a href="\/film\
/fichefilm_gen_cfilm=(\d+)\.html" class="link1">(.*?)<\/a
>(?:<\
/h4><h5 style="color: #666666"> (.*?)<\/h5
>){0,1}/)
347 @aPlusieursReponses = true
349 @idsAllocine[f
[1].virerBalisesHTML +
(f
[2] !
= nil ? " " + f
[2].virerBalisesHTML
: "")] = f
[0]
352 loadDepuisIdAllocine(r
[0][0], connexionHttp
)
354 puts
"[!] Movie
not found
: #{@titre} (#{@fichier})"
361 def loadDepuisIdAllocine(id, connexionHttp = nil)
362 if (connexionHttp == nil)
363 connexionHttp = Net::HTTP::new('www.allocine.fr')
366 r, ficheHtml = connexionHttp.get("/film/fichefilm_gen_cfilm
=#{id}.html
")
368 #convertit le code latin-1 en UTF8
369 ficheHtml = ficheHtml.unpack("C
*").pack("U
*")
372 @url = "http
://www
.allocine
.fr
/film/fichefilm_gen_cfilm
=#{id}.html
"
375 /<title>(.*?)<\/title>/ =~ ficheHtml
376 @titre = $1 unless $1.nil?
378 puts "Movie found
: #{@titre} (#{@fichiers[0]})"
381 /<h4>Année de production : (\d+)<\
/h4
>/ =~ ficheHtml
382 @annee = $1.to_i
unless $1.nil?
385 /<h4>Réalisé par(.*?)<\/h4
>/ =~ ficheHtml
386 $1.scan(/<a class="link1" href=".*?">(.*?)<\/a
>/m
){|a
|
387 @realisateurs << Personne
::ajouter(a
[0]) unless a
[0].nil?
391 /<h4>Avec(.*?)<\/h4
>/ =~ ficheHtml
392 $1.scan(/<a class="link1" href="\/personne\
/fichepersonne_gen_cpersonne=\d+\.html">(.+?)<\/a
>/m
){|a
|
393 @acteurs << Personne
::ajouter(a
[0]) unless a
[0].nil?
398 /<h4>Film (.*?)\. <\/h4
>/ =~ ficheHtml
399 $1.split(',').each
{|pays
|
400 @pays << Pays
::ajouter(pays
) unless pays
.nil?
404 /<h4>Durée : (\d+)h (\d+)min./ =~ ficheHtml
405 @duree = $1.nil? ? $2.to_i
: $1.to_i
* 60 +
$2.to_i
407 # Critiques presse et spectateur
408 /Presse.*etoile_([012345]).*Spectateurs.*etoile_([012345])"/m
=~ ficheHtml
409 @critiquePresse = $1.to_i
unless $1.nil?
410 @critiqueSpectateur = $2.to_i
unless $2.nil?
413 /<h4>Genre : (.*?)<\/h4
>/ =~ ficheHtml
414 $1.scan(/<a href="\/film\
/alaffiche_genre_gen_genre=.*?" class="link1">(.+?)<\/a
>/m
){|g
|
415 @genres << Genre
::ajouter(g
[0]) unless g
[0].nil?
419 /Synopsis.*?<h4>(.+?)<\/h4
>/m
=~ ficheHtml
420 @synopsis = $1 unless $1.nil?
423 /Budget<\/b
> : (.+
?) millions d
'euros<\/h4>/ =~ ficheHtml
424 @budget = $1.to_i unless $1.nil?
429 # Renvoie un film sous la forme d'un élément XML de type REXML
432 racine
= REXML
::Element::new('film')
433 racine
.add_attribute('id', @id.to_s
)
435 fichiers
= REXML
::Element::new('fichiers')
437 fichiers
.add(REXML
::Element::new('fichier').add_text(f
))
441 racine
.add(REXML
::Element::new('titre').add_text(@titre))
442 racine
.add(REXML
::Element::new('annee').add_text(@annee.to_s
))
444 realisateurs
= REXML
::Element::new('realisateurs')
445 @realisateurs.each
{|r
|
446 realisateurs
.add(REXML
::Element::new('realisateur').add_text(r
.nom
))
448 racine
.add(realisateurs
)
450 acteurs
= REXML
::Element::new('acteurs')
452 acteurs
.add(REXML
::Element::new('acteur').add_text(a
.nom
))
456 lespays
= REXML
::Element::new('lespays')
458 lespays
.add(REXML
::Element::new('pays').add_text(p
.nom
))
462 racine
.add(REXML
::Element::new('duree').add_text(@duree.to_s
))
464 racine
.add(REXML
::Element::new('critiquePresse').add_text(@critiquePresse.to_s
))
465 racine
.add(REXML
::Element::new('critiqueSpectateur').add_text(@critiqueSpectateur.to_s
))
467 genres
= REXML
::Element::new('genres')
469 genres
.add(REXML
::Element::new('genre').add_text(g
.nom
))
473 racine
.add(REXML
::Element::new('synopsis').add_text(@synopsis))
474 budgetElement
= REXML
::Element::new('budget')
475 budgetElement
.add_text(@budget.to_s
)
476 budgetElement
.add_attribute('unite', @budgetUnite)
477 racine
.add(budgetElement
)
479 racine
.add(REXML
::Element::new('url').add_text(@url))