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 # repertoire de base, par exemple C:/Divx/
25 # Les films indexés par leur titre
28 # Les films indexés par leur nom de fichier, deux fichiers différents peuvent pointer sur le même film
31 # Les films qui ont plusieurs réponses lors de la recherche, traités à la fin
32 @
@filmsPlusieursReponses = []
34 @
@threadsWait = ThreadsWait
::new
37 # le prochain id disponible
40 # retourne un nouvel id, utilisé lors de la création d'un nouveau film
47 # Lit un repertoire de manière recursive
48 def Film
::litRepertoire(r
)
50 repPrecedant
= Dir
::getwd
53 Film
::litRepertoireR('.')
55 # on attends que les threads se terminent
56 @
@threadsWait.all_waits
58 # traite les films qui avaient plusieurs réponses lors de la recherche
59 # l'utilisateur doit faire un choix
61 @
@filmsPlusieursReponses.each
{|f
|
63 puts
"Plop, ya un conflit #{i} / #{@@filmsPlusieursReponses.length} :"
64 if f
.reglerConflitPlusieursReponses
70 Dir
::chdir(repPrecedant
)
73 # Charge les films contenus dans un fichier XML.
74 def Film
::loadFilmsXml(xmlFile
)
75 # si le fichier n'existe pas il n'y a rien à charger
76 if !File
.exists
?(xmlFile
)
80 racine
= REXML
::Document::new(File
::new(xmlFile
)).root
81 racine
.each_element
{|e
|
82 id
= e
.attribute('id').to_s
.to_i
84 if id
> @
@idDisponible
85 @
@idDisponible = id +
1
88 titre
= e
.get_elements('titre')[0].get_text
90 fichiers
= e
.get_elements('fichiers')[0].get_elements('fichier')
91 annee
= e
.get_elements('annee')[0].get_text
92 duree
= e
.get_elements('duree')[0].get_text
93 critiquePresse
= e
.get_elements('critiquePresse')[0].get_text
94 critiqueSpectateur
= e
.get_elements('critiqueSpectateur')[0].get_text
95 synopsis
= e
.get_elements('synopsis')[0].get_text
96 budget
= e
.get_elements('budget')[0].get_text
97 realisateurs
= e
.get_elements('realisateurs')[0].get_elements('realisateur')
98 acteurs
= e
.get_elements('acteurs')[0].get_elements('acteur')
99 pays
= e
.get_elements('lespays')[0].get_elements('pays')
100 genres
= e
.get_elements('genres')[0].get_elements('genre')
102 film
= Film
::new(fichiers
[0].get_text
.value
)
104 film
.titre
= titre
.value
unless titre
.nil?
107 film
.addFichier(e
.get_text
.value
)
108 @
@filmsFichier[e
.get_text
.value
] = film
110 film
.annee
= annee
.value
unless annee
.nil?
112 film
.acteurs
<< Personne
::ajouter(e
.get_text
.value
)
115 film
.pays
<< Pays
::ajouter(e
.get_text
.value
)
117 film
.duree
= duree
.value
unless duree
.nil?
118 film
.critiquePresse
= critiquePresse
.value
unless critiquePresse
.nil?
119 film
.critiqueSpectateur
= critiqueSpectateur
.value
unless critiqueSpectateur
.nil?
121 film
.genres
<< Genre
::ajouter(e
.get_text
.value
) if e
.get_text !
= nil
123 film
.synopsis
= synopsis
.value
unless synopsis
.nil?
124 film
.budget
= budget
.value
unless budget
.nil?
125 @
@films[film
.titre
] = film
129 # Renvoie tous les films sous la forme d'un document XML.
130 def Film
::getFilmsXml
132 docXml
= REXML
::Document::new
133 docXml
.xml_decl().encoding
= "UTF-8" # normalement UTF-8
134 docXml
.xml_decl().dowrite
136 # la racine du document
137 racine
= REXML
::Element::new('filmographie')
139 pi
= REXML
::Instruction.new("xml-stylesheet", "type=\"text/xsl\" href=\"../xsl/yopyop.xsl\"")
140 racine
.previous_sibling
= pi
142 # on ajoute chaque film à la racine
143 @
@films.each
{|nom
, f
|
153 def Film
::filmsFactory(fichier
)
154 Film
::new(fichier
).loadData
157 def Film
::litRepertoireR(r
)
159 next if f
[0,1] == '.'
160 fichier
= (r
== '.' ? '' : r +
"/") + f
161 if File
::directory?(fichier
)
162 litRepertoireR(fichier
)
165 # vérification de l'extension
166 /^.*?\.(.{3,4})$/ =~ fichier
167 if !FILMS_EXTENSIONS
.include?($1)
171 fichier
= CGI
::escapeHTML(fichier
.unpack("C*").pack("U*"))
173 # on skip si le film est déjàa dans la BD
174 if film
= @
@filmsFichier[fichier
]
175 puts
"[i] Already exists in DB : #{film.titre} (#{fichier})"
183 if @
@nbConn >= NB_CONN_MAX
184 @
@threadsWait.next_wait
188 @
@threadsWait.join_nowait(
191 film
= Film
::filmsFactory(fichier
)
192 unless film
.nil? # le film a été correctement construit
193 Film
::ajouterFilm(film
)
195 rescue Exception
=> e
206 def Film
::ajouterFilm(film
)
207 if film
.plusieursReponses
?
208 @
@filmsPlusieursReponses << film
212 # le film existe déjà
213 if @
@films.has_key
?(film
.titre
)
214 # le fichier n'est pas connu -> nième partie d'un film
215 if !@
@filmsFichier.has_key
?(film
.fichiers
[0])
216 puts
"[i] movie #{film.titre} has a another file part : #{film.fichiers[0]}"
217 @
@films[film
.titre
].addFichier(film
.fichiers
[0])
218 @
@filmsFichier[film
.fichiers
[0]] = @
@films[film
.titre
]
220 puts
"[!] Duplicate movie
: #{film.titre} (#{film.fichiers[0]})"
223 puts "[i
] movie added
: #{film.titre} (#{film.fichiers[0]})"
224 @@films[film.titre] = film
225 @@filmsFichier[film.fichiers[0]] = film
230 def initialize(fichier)
231 @fichiers = [fichier]
240 @critiquePresse = nil
241 @critiqueSpectateur = nil
245 @budgetUnite = 'euro'
248 @aPlusieursReponses = false
249 # mémorise les tuples {nom => id} dans le cas ou il y a plusieurs réponses
255 def plusieursReponses?
256 return @aPlusieursReponses
259 # demande à l'utilisateur de faire un choix
260 # ret : true si le conflit à été résolu sinon false
261 def reglerConflitPlusieursReponses
263 @aPlusieursReponses = false # pour faire les choses bien
266 puts "Fais ton choix jeune
padawan (un caractère et pas plus
)"
267 tabNoms = @idsAllocine.keys
275 puts
"A. Passer et l'ajouter"
286 if choix
> 0 && choix
<= tabNoms
.length
290 puts
"Choix pas bon !!
"
294 loadDepuisIdAllocine(@idsAllocine[tabNoms[choix-1]])
299 def addFichier(fichier)
300 if !@fichiers.include?(fichier
)
305 # Charge les informations du films à partir d'allocine.fr
309 @titre = @fichiers[0]
315 connexionHttp
= Net
::HTTP::new('www.allocine.fr')
317 #extrait le nom à partir du nom du fichier
318 /^.*?([^\/]*?)\
.(.{3,4})$/ =~
@fichiers[0]
319 #remplace undescores et points par des espaces
320 titre
= $1.gsub(/[_\.]/, ' ')
321 #remplace les suites d'espaces par un seul
322 titre
.gsub!
(/ {2,}/,' ')
323 titre
.gsub!
(/\[.*?\]/,'')
324 titre
.gsub!
(/\(.*?\)/,'')
325 titre
.gsub!
(/\{.*?\}/,'')
326 #vire les espaces au début et à la fin
334 reponse
, donneesHtml
= connexionHttp
.get("/recherche/?motcle=#{CGI::escape(titre.unpack("U*").pack("C*"))}")
335 rescue Exception
=> e
337 puts
"[!] Connexion lost
, retry.."
341 #convertit le code latin-1 en UTF8
342 donneesHtml = donneesHtml.unpack("C
*").pack("U
*")
344 #si pas trouvé alors on enlève un mot à la fin
345 if /.*?Pas de résultats.*?/ =~ donneesHtml || ! donneesHtml
.include?("<h3><b>Films <h4>")
346 /(.*?)[^ ]+?$/ =~ titre
.strip
352 end while not titre
.nil? and not titre
.empty
?
354 unless titre
.nil? or titre
.empty
?
356 #/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">/ =~ donneesHtml
357 #r = donneesHtml.scan(/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">(.*?)<\/a>/)
358 r
= donneesHtml
.scan(/<a href="\/film\
/fichefilm_gen_cfilm=(\d+)\.html" class="link1">(.*?)<\/a
>(?:<\
/h4><h5 style="color: #666666"> (.*?)<\/h5
>){0,1}/)
361 @aPlusieursReponses = true
363 @idsAllocine[f
[1].virerBalisesHTML +
(f
[2] !
= nil ? " " + f
[2].virerBalisesHTML
: "")] = f
[0]
366 loadDepuisIdAllocine(r
[0][0], connexionHttp
)
368 puts
"[!] Movie
not found
: #{@titre} (#{@fichier})"
375 def loadDepuisIdAllocine(id, connexionHttp = nil)
376 if (connexionHttp == nil)
377 connexionHttp = Net::HTTP::new('www.allocine.fr')
380 r, ficheHtml = connexionHttp.get("/film/fichefilm_gen_cfilm
=#{id}.html
")
382 #convertit le code latin-1 en UTF8
383 ficheHtml = ficheHtml.unpack("C
*").pack("U
*")
386 @url = "http
://www
.allocine
.fr
/film/fichefilm_gen_cfilm
=#{id}.html
"
389 /<title>(.*?)<\/title>/ =~ ficheHtml
390 @titre = $1 unless $1.nil?
392 puts "Movie found
: #{@titre} (#{@fichiers[0]})"
395 /<h4>Année de production : (\d+)<\
/h4
>/ =~ ficheHtml
396 @annee = $1 unless $1.nil?
399 /<h4>Réalisé par(.*?)<\/h4
>/ =~ ficheHtml
400 $1.scan(/<a class="link1" href=".*?">(.*?)<\/a
>/m
){|a
|
401 @realisateurs << Personne
::ajouter(a
[0]) unless a
[0].nil?
405 /<h4>Avec(.*?)<\/h4
>/ =~ ficheHtml
406 $1.scan(/<a class="link1" href="\/personne\
/fichepersonne_gen_cpersonne=\d+\.html">(.+?)<\/a
>/m
){|a
|
407 @acteurs << Personne
::ajouter(a
[0]) unless a
[0].nil?
411 /<h4>Film (.*?)\. <\/h4
>/ =~ ficheHtml
412 $1.split(',').each
{|pays
|
413 @pays << Pays
::ajouter(pays
) unless pays
.nil?
416 # Duree (capture des heures et des minutes séparement vue que c'est le bordel sur allocine
417 /<h4>Durée :(?:.*?)(\d+)h/ =~ ficheHtml
418 heure
= $1.nil? ? 0 : $1.to_i
420 /<h4>Durée :(?:.*?)(\d+)min/ =~ ficheHtml
421 min
= $1.nil? ? 0 : $1.to_i
423 @duree = heure
* 60 + min
425 # Critiques presse et spectateur
426 /Presse.*etoile_([012345]).*Spectateurs.*etoile_([012345])"/m
=~ ficheHtml
427 @critiquePresse = $1 unless $1.nil?
428 @critiqueSpectateur = $2 unless $2.nil?
431 /<h4>Genre : (.*?)<\/h4
>/ =~ ficheHtml
432 $1.scan(/<a href="\/film\
/alaffiche_genre_gen_genre=.*?" class="link1">(.+?)<\/a
>/m
){|g
|
433 @genres << Genre
::ajouter(g
[0]) unless g
[0].nil?
437 /Synopsis.*?<h4>(.+?)<\/h4
>/m
=~ ficheHtml
438 @synopsis = $1 unless $1.nil?
441 /Budget<\/b
> : (.+
?) millions d
'euros<\/h4>/ =~ ficheHtml
442 @budget = $1 unless $1.nil?
447 # Renvoie un film sous la forme d'un élément XML de type REXML
450 racine
= REXML
::Element::new('film')
451 racine
.add_attribute('id', @id.to_s
)
453 fichiers
= REXML
::Element::new('fichiers')
455 fichiers
.add(REXML
::Element::new('fichier').add_text(f
))
459 racine
.add(REXML
::Element::new('titre').add_text(@titre))
460 racine
.add(REXML
::Element::new('annee').add_text(@annee))
462 realisateurs
= REXML
::Element::new('realisateurs')
463 @realisateurs.each
{|r
|
464 realisateurs
.add(REXML
::Element::new('realisateur').add_text(r
.nom
))
466 racine
.add(realisateurs
)
468 acteurs
= REXML
::Element::new('acteurs')
470 acteurs
.add(REXML
::Element::new('acteur').add_text(a
.nom
))
474 lespays
= REXML
::Element::new('lespays')
476 lespays
.add(REXML
::Element::new('pays').add_text(p
.nom
))
480 racine
.add(REXML
::Element::new('duree').add_text(@duree.to_s
))
482 racine
.add(REXML
::Element::new('critiquePresse').add_text(@critiquePresse))
483 racine
.add(REXML
::Element::new('critiqueSpectateur').add_text(@critiqueSpectateur))
485 genres
= REXML
::Element::new('genres')
487 genres
.add(REXML
::Element::new('genre').add_text(g
.nom
))
491 racine
.add(REXML
::Element::new('synopsis').add_text(@synopsis))
492 budgetElement
= REXML
::Element::new('budget')
493 budgetElement
.add_text(@budget)
494 budgetElement
.add_attribute('unite', @budgetUnite)
495 racine
.add(budgetElement
)
497 racine
.add(REXML
::Element::new('url').add_text(@url))