1 # Attention, le but de ce fichier n'est pas d'être le plus clair possible ^-^´´
3 require 'rexml/document'
13 require 'constantes.rb'
17 return gsub(/<(.*?)>/, '')
25 attr_accessor
:id, :titre, :fichiers, :annee, :realisateurs, :acteurs, :pays, :duree, :critiquePresse, :critiqueSpectateur, :genres, :synopsis, :budget
27 # repertoire de base, par exemple C:/Divx/
30 # Les films indexés par leur titre
33 # Les films indexés par leur nom de fichier, deux fichiers différents peuvent pointer sur le même film
36 # Les films qui ont plusieurs réponses lors de la recherche, traités à la fin
37 @
@filmsPlusieursReponses = []
39 @
@threadsWait = ThreadsWait
::new
42 # le prochain id disponible
45 # retourne un nouvel id, utilisé lors de la création d'un nouveau film
52 # Lit un repertoire de manière recursive
53 def Film
::litRepertoire(r
)
55 repPrecedant
= Dir
::getwd
58 Film
::litRepertoireR('.')
60 # on attends que les threads se terminent
61 @
@threadsWait.all_waits
63 # traite les films qui avaient plusieurs réponses lors de la recherche
64 # l'utilisateur doit faire un choix
66 @
@filmsPlusieursReponses.each
{|f
|
68 puts
"Plop, ya un conflit #{i} / #{@@filmsPlusieursReponses.length} :"
69 if f
.reglerConflitPlusieursReponses
75 Dir
::chdir(repPrecedant
)
78 # Charge les films contenus dans un fichier XML.
79 def Film
::loadFilmsXml(xmlFile
)
80 # si le fichier n'existe pas il n'y a rien à charger
81 if !File
.exists
?(xmlFile
)
85 racine
= REXML
::Document::new(File
::new(xmlFile
)).root
86 racine
.each_element
{|e
|
87 id
= e
.attribute('id').to_s
.to_i
89 if id
> @
@idDisponible
90 @
@idDisponible = id +
1
93 titre
= e
.get_elements('titre')[0].get_text
95 fichiers
= e
.get_elements('fichiers')[0].get_elements('fichier')
96 annee
= e
.get_elements('annee')[0].get_text
97 duree
= e
.get_elements('duree')[0].get_text
98 critiquePresse
= e
.get_elements('critiquePresse')[0].get_text
99 critiqueSpectateur
= e
.get_elements('critiqueSpectateur')[0].get_text
100 synopsis
= e
.get_elements('synopsis')[0].get_text
101 budget
= e
.get_elements('budget')[0].get_text
102 realisateurs
= e
.get_elements('realisateurs')[0].get_elements('realisateur')
103 acteurs
= e
.get_elements('acteurs')[0].get_elements('acteur')
104 pays
= e
.get_elements('lespays')[0].get_elements('pays')
105 genres
= e
.get_elements('genres')[0].get_elements('genre')
107 film
= Film
::new(fichiers
[0].get_text
.value
)
109 film
.titre
= titre
.value
unless titre
.nil?
112 film
.addFichier(e
.get_text
.value
)
113 @
@filmsFichier[e
.get_text
.value
] = film
115 film
.annee
= annee
.value
unless annee
.nil?
117 film
.acteurs
<< Personne
::ajouter(e
.get_text
.value
)
120 film
.pays
<< Pays
::ajouter(e
.get_text
.value
)
122 film
.duree
= duree
.value
unless duree
.nil?
123 film
.critiquePresse
= critiquePresse
.value
unless critiquePresse
.nil?
124 film
.critiqueSpectateur
= critiqueSpectateur
.value
unless critiqueSpectateur
.nil?
126 film
.genres
<< Genre
::ajouter(e
.get_text
.value
) if e
.get_text !
= nil
128 film
.synopsis
= synopsis
.value
unless synopsis
.nil?
129 film
.budget
= budget
.value
unless budget
.nil?
130 @
@films[film
.titre
] = film
134 # Renvoie tous les films sous la forme d'un document XML.
135 def Film
::getFilmsXml
137 docXml
= REXML
::Document::new
138 docXml
.xml_decl().encoding
= "UTF-8" # normalement UTF-8
139 docXml
.xml_decl().dowrite
141 # la racine du document
142 racine
= REXML
::Element::new('filmographie')
144 pi
= REXML
::Instruction.new("xml-stylesheet", "type=\"text/xsl\" href=\"../xsl/yopyop.xsl\"")
145 racine
.previous_sibling
= pi
147 # on ajoute chaque film à la racine
148 @
@films.each
{|nom
, f
|
158 def Film
::filmsFactory(fichier
)
159 Film
::new(fichier
).loadData
162 def Film
::litRepertoireR(r
)
164 next if f
[0,1] == '.'
165 fichier
= (r
== '.' ? '' : r +
"/") + f
166 if File
::directory?(fichier
)
167 litRepertoireR(fichier
)
170 # vérification de l'extension
171 /^.*?\.(.{3,4})$/ =~ fichier
172 if !FILMS_EXTENSIONS
.include?($1)
176 fichier
= CGI
::escapeHTML(fichier
.unpack("C*").pack("U*"))
178 # on skip si le film est déjàa dans la BD
179 if film
= @
@filmsFichier[fichier
]
180 puts
"[i] Already exists in DB : #{film.titre} (#{fichier})"
188 if @
@nbConn >= NB_CONN_MAX
189 @
@threadsWait.next_wait
193 @
@threadsWait.join_nowait(
196 film
= Film
::filmsFactory(fichier
)
197 unless film
.nil? # le film a été correctement construit
198 Film
::ajouterFilm(film
)
200 rescue Exception
=> e
211 def Film
::ajouterFilm(film
)
212 if film
.plusieursReponses
?
213 @
@filmsPlusieursReponses << film
217 # le film existe déjà
218 if @
@films.has_key
?(film
.titre
)
219 # le fichier n'est pas connu -> nième partie d'un film
220 if !@
@filmsFichier.has_key
?(film
.fichiers
[0])
221 puts
"[i] movie #{film.titre} has a another file part : #{film.fichiers[0]}"
222 @
@films[film
.titre
].addFichier(film
.fichiers
[0])
223 @
@filmsFichier[film
.fichiers
[0]] = @
@films[film
.titre
]
225 puts
"[!] Duplicate movie
: #{film.titre} (#{film.fichiers[0]})"
228 puts "[i
] movie added
: #{film.titre} (#{film.fichiers[0]})"
229 @@films[film.titre] = film
230 @@filmsFichier[film.fichiers[0]] = film
235 def initialize(fichier)
236 @fichiers = [fichier]
245 @critiquePresse = nil
246 @critiqueSpectateur = nil
250 @budgetUnite = 'euro'
253 @aPlusieursReponses = false
254 # mémorise les tuples {nom => id} dans le cas ou il y a plusieurs réponses
260 def plusieursReponses?
261 return @aPlusieursReponses
264 # demande à l'utilisateur de faire un choix
265 # ret : true si le conflit à été résolu sinon false
266 def reglerConflitPlusieursReponses
268 @aPlusieursReponses = false # pour faire les choses bien
270 puts " -> " + @fichiers[0]
271 puts
"Fais ton choix jeune padawan (un caractère et pas plus)"
272 tabNoms
= @idsAllocine.keys
280 puts
"A. Passer et l'ajouter"
291 if choix
> 0 && choix
<= tabNoms
.length
295 puts
"Choix pas bon !!
"
299 loadDepuisIdAllocine(@idsAllocine[tabNoms[choix-1]])
304 def addFichier(fichier)
305 if !@fichiers.include?(fichier
)
310 # Charge les informations du films à partir d'allocine.fr
314 @titre = @fichiers[0]
320 connexionHttp
= Net
::HTTP::new('www.allocine.fr')
322 #extrait le nom à partir du nom du fichier
323 /^.*?([^\/]*?)\
.(.{3,4})$/ =~
@fichiers[0]
324 #remplace undescores et points par des espaces
325 titre
= $1.gsub(/[_\.]/, ' ')
326 #remplace les suites d'espaces par un seul
327 titre
.gsub!
(/ {2,}/,' ')
328 titre
.gsub!
(/\[.*?\]/,'')
329 titre
.gsub!
(/\(.*?\)/,'')
330 titre
.gsub!
(/\{.*?\}/,'')
331 #vire les espaces au début et à la fin
339 reponse
, donneesHtml
= connexionHttp
.get("/recherche/?motcle=#{CGI::escape(titre.unpack("U*").pack("C*"))}")
340 rescue Exception
=> e
342 puts
"[!] Connexion lost
, retry.."
346 #convertit le code latin-1 en UTF8
347 donneesHtml = donneesHtml.unpack("C
*").pack("U
*")
349 #si pas trouvé alors on enlève un mot à la fin
350 if /.*?Pas de résultats.*?/ =~ donneesHtml || ! donneesHtml
.include?("<h3><b>Films <h4>")
351 /(.*?)[^ ]+?$/ =~ titre
.strip
357 end while not titre
.nil? and not titre
.empty
?
359 unless titre
.nil? or titre
.empty
?
361 #/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">/ =~ donneesHtml
362 #r = donneesHtml.scan(/<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">(.*?)<\/a>/)
363 r
= donneesHtml
.scan(/<a href="\/film\
/fichefilm_gen_cfilm=(\d+)\.html" class="link1">(.*?)<\/a
>(?:<\
/h4><h5 style="color: #666666"> (.*?)<\/h5
>){0,1}(?:<h4
><br \
/><\/h4
>){0,1}(?:<h4 style
="color: #666666"> de (.*?)<\
/h4>){0,1}(?:<h4 style="color: #666666"> avec (.*?)<\/h4
>){0,1}(?:<h4 style
="color: #666666"> 
;\
((.*?)\
)<\
/h4>){0,1}/)
366 @aPlusieursReponses = true
368 @idsAllocine[f
[1].virerBalisesHTML +
(f
[2] !
= nil ? " " + f
[2].virerBalisesHTML
: "") +
(f
[3] !
= nil ? " de " + f
[3].virerBalisesHTML
: "") +
(f
[4] !
= nil ? " avec " + f
[4].virerBalisesHTML
: "") +
(f
[5] !
= nil ? " (" + f
[5].virerBalisesHTML +
")" : "")] = f
[0]
371 loadDepuisIdAllocine(r
[0][0], connexionHttp
)
373 puts
"[!] Movie
not found
: #{@titre} (#{@fichier})"
380 def loadDepuisIdAllocine(id, connexionHttp = nil)
381 if (connexionHttp == nil)
382 connexionHttp = Net::HTTP::new('www.allocine.fr')
385 r, ficheHtml = connexionHttp.get("/film/fichefilm_gen_cfilm
=#{id}.html
")
387 #convertit le code latin-1 en UTF8
388 ficheHtml = ficheHtml.unpack("C
*").pack("U
*")
391 @url = "http
://www
.allocine
.fr
/film/fichefilm_gen_cfilm
=#{id}.html
"
394 /<title>(.*?)<\/title>/ =~ ficheHtml
395 @titre = $1 unless $1.nil?
397 puts "Movie found
: #{@titre} (#{@fichiers[0]})"
400 /<h4>Année de production : (\d+)<\
/h4
>/ =~ ficheHtml
401 @annee = $1 unless $1.nil?
404 /<h4>Réalisé par(.*?)<\/h4
>/ =~ ficheHtml
405 $1.scan(/<a class="link1" href=".*?">(.*?)<\/a
>/m
){|a
|
406 @realisateurs << Personne
::ajouter(a
[0]) unless a
[0].nil?
410 /<h4>Avec(.*?)<\/h4
>/ =~ ficheHtml
411 $1.scan(/<a class="link1" href="\/personne\
/fichepersonne_gen_cpersonne=\d+\.html">(.+?)<\/a
>/m
){|a
|
412 @acteurs << Personne
::ajouter(a
[0]) unless a
[0].nil?
416 /<h4>Film (.*?)\. <\/h4
>/ =~ ficheHtml
417 $1.split(',').each
{|pays
|
418 @pays << Pays
::ajouter(pays
) unless pays
.nil?
421 # Duree (capture des heures et des minutes séparement vue que c'est le bordel sur allocine
422 /<h4>Durée :(?:.*?)(\d+)h/ =~ ficheHtml
423 heure
= $1.nil? ? 0 : $1.to_i
425 /<h4>Durée :(?:.*?)(\d+)min/ =~ ficheHtml
426 min
= $1.nil? ? 0 : $1.to_i
428 @duree = heure
* 60 + min
430 # Critiques presse et spectateur
431 /Presse.*etoile_([012345]).*Spectateurs.*etoile_([012345])"/m
=~ ficheHtml
432 @critiquePresse = $1 unless $1.nil?
433 @critiqueSpectateur = $2 unless $2.nil?
436 /<h4>Genre : (.*?)<\/h4
>/ =~ ficheHtml
437 $1.scan(/<a href="\/film\
/alaffiche_genre_gen_genre=.*?" class="link1">(.+?)<\/a
>/m
){|g
|
438 @genres << Genre
::ajouter(g
[0]) unless g
[0].nil?
442 /Synopsis.*?<h4>(.*?)<\/h4
>/m
=~ ficheHtml
443 @synopsis = $1 unless $1.nil?
444 @synopsis.gsub!
(/<br\s*\/>|<br\s
*>/, "\n")
445 @synopsis.virerBalisesHTML!
448 /Budget<\/b
> : (.+
?) millions d
'euros<\/h4>/ =~ ficheHtml
449 @budget = $1 unless $1.nil?
454 # Renvoie un film sous la forme d'un élément XML de type REXML
457 racine
= REXML
::Element::new('film')
458 racine
.add_attribute('id', @id.to_s
)
460 fichiers
= REXML
::Element::new('fichiers')
462 fichiers
.add(REXML
::Element::new('fichier').add_text(f
))
466 racine
.add(REXML
::Element::new('titre').add_text(@titre))
467 racine
.add(REXML
::Element::new('annee').add_text(@annee))
469 realisateurs
= REXML
::Element::new('realisateurs')
470 @realisateurs.each
{|r
|
471 realisateurs
.add(REXML
::Element::new('realisateur').add_text(r
.nom
))
473 racine
.add(realisateurs
)
475 acteurs
= REXML
::Element::new('acteurs')
477 acteurs
.add(REXML
::Element::new('acteur').add_text(a
.nom
))
481 lespays
= REXML
::Element::new('lespays')
483 lespays
.add(REXML
::Element::new('pays').add_text(p
.nom
))
487 racine
.add(REXML
::Element::new('duree').add_text(@duree.to_s
))
489 racine
.add(REXML
::Element::new('critiquePresse').add_text(@critiquePresse))
490 racine
.add(REXML
::Element::new('critiqueSpectateur').add_text(@critiqueSpectateur))
492 genres
= REXML
::Element::new('genres')
494 genres
.add(REXML
::Element::new('genre').add_text(g
.nom
))
498 synopsisElement
= REXML
::Element::new('synopsis')
499 @synopsis.split("\n").each
{|s
|
501 synopsisElement
.add(REXML
::Element::new('p').add_text(s
))
503 racine
.add(synopsisElement
)
505 budgetElement
= REXML
::Element::new('budget')
506 budgetElement
.add_text(@budget)
507 budgetElement
.add_attribute('unite', @budgetUnite)
508 racine
.add(budgetElement
)
510 racine
.add(REXML
::Element::new('url').add_text(@url))