MOD Restructuration des sources
[pompage.git] / src / film.rb
1 require 'rexml/document'
2 require 'net/http'
3 require 'thread'
4 require 'thwait'
5 require 'cgi'
6
7 require 'pays.rb'
8 require 'genre.rb'
9 require 'personne.rb'
10
11 require 'constantes.rb'
12
13 class Film
14 attr_accessor :titre, :fichier, :annee, :realisateurs, :acteurs, :pays, :duree, :critiquePresse, :critiqueSpectateur, :genres, :synopsis, :budget
15
16 # Les films indexés par leur titre
17 @@films = {}
18
19 # Les films indexés par leur nom de fichier
20 @@filmsFichier = {}
21
22 @@mutex = Mutex::new
23 @@threadsWait = ThreadsWait::new
24 @@nbConn = 0
25
26
27 # Lit un repertoire de manière recursive
28 def Film::litRepertoire(r)
29 Film::litRepertoireR(r)
30 # on attends que les threads se terminent
31 @@threadsWait.all_waits
32 end
33
34 # Charge les films contenus dans un fichier XML.
35 def Film::loadFilmsXml(xmlFile)
36 # si le fichier n'existe pas il n'y a rien à charger
37 if !File.exists?(xmlFile)
38 return
39 end
40
41 racine = REXML::Document::new(File::new(xmlFile)).root
42 racine.each_element{|e|
43 fichier = e.get_elements('fichier')[0].get_text
44 next if fichier == nil
45 titre = e.get_elements('titre')[0].get_text
46 annee = e.get_elements('annee')[0].get_text
47 duree = e.get_elements('duree')[0].get_text
48 critiquePresse = e.get_elements('critiquePresse')[0].get_text
49 critiqueSpectateur = e.get_elements('critiqueSpectateur')[0].get_text
50 synopsis = e.get_elements('synopsis')[0].get_text
51 budget = e.get_elements('budget')[0].get_text
52 realisateurs = e.get_elements('realisateur')
53 acteurs = e.get_elements('acteur')
54 pays = e.get_elements('pays')
55 genres = e.get_elements('genres')
56
57
58 film = Film::new(fichier.value)
59 film.titre = titre.value unless titre.nil?
60 film.annee = annee.value unless annee.nil?
61 realisateurs.each{|e|
62 film.realisateurs << Personne::ajouter(e.get_text.value)
63 }
64 acteurs.each{|e|
65 film.acteurs << Personne::ajouter(e.get_text.value)
66 }
67 pays.each{|e|
68 film.pays << Pays::ajouter(e.get_text.value)
69 }
70 film.duree = duree.value unless duree.nil?
71 film.critiquePresse = critiquePresse.value unless critiquePresse.nil?
72 film.critiqueSpectateur = critiqueSpectateur.value unless critiqueSpectateur.nil?
73 genres.each{|e|
74 film.genres << Genre::ajouter(e.get_text.value)
75 }
76 film.synopsis = synopsis.value unless synopsis.nil?
77 film.budget = budget.value unless budget.nil?
78 @@films[film.titre] = film
79 @@filmsFichier[film.fichier] = film
80 }
81 end
82
83 # Renvoie tous les films sous la forme d'un élement XML.
84 def Film::getFilmsXml
85 racine = REXML::Element::new('filmographie')
86 @@films.each{|nom, f|
87 racine.add(f.getXml)
88 }
89 return REXML::Document::new.add(racine)
90 end
91
92 private
93
94 def Film::filmsFactory(fichier)
95 /^.*?\.(.{3,4})$/ =~ fichier
96 if FILMS_EXTENSIONS.include?($1)
97 Film::new(fichier).loadData
98 end
99 end
100
101 def Film::litRepertoireR(r)
102 Dir::foreach(r){|f|
103 next if f == '.' or f == '..'
104 fichier = r + "/" + f
105 if File::directory?(fichier)
106 litRepertoireR(fichier)
107 else
108
109 #si le film n'existe pas déjà dans la liste
110 if film = @@filmsFichier[fichier]
111 puts "[i] Already exists in DB : #{film.titre} (#{film.fichier})"
112 next
113 end
114
115 film = nil
116 @@nbConn += 1
117 @@threadsWait.join_nowait(
118 Thread::new{
119 begin
120 @@mutex.lock if @@nbConn >= NB_CONN_MAX
121 #p @@nbConn
122 film = Film::filmsFactory(fichier)
123 unless film.nil?
124 if @@films.has_key?(film.titre)
125 puts "[!] Duplicate movie : #{film.titre} (#{film.fichier})"
126 else
127 puts "[i] movie added : #{film.titre} (#{film.fichier})"
128 @@films[film.titre] = film
129 @@filmsFichier[film.fichier] = film
130 end
131 end
132 @@nbConn -= 1
133 #p @@nbConn
134 @@mutex.unlock
135 rescue Exception => e
136 puts e.message
137 puts e.backtrace
138 end
139 }
140 )
141 end
142 }
143 end
144
145
146 def initialize(fichier)
147 @fichier = fichier
148 @titre = ''
149 @annee = nil
150 @realisateurs = []
151 @acteurs = []
152 @pays = []
153 @duree = nil
154 @critiquePresse = nil
155 @critiqueSpectateur = nil
156 @genres = []
157 @synopsis = nil
158 @budget = nil
159 @budgetUnite = 'euro'
160 end
161
162 public
163 #charge les informations du films à partir d'allocine.fr
164 def loadData
165 unless LOAD_DATA
166 @titre = @fichier
167 return self
168 end
169
170 connexionHttp = Net::HTTP::new('www.allocine.fr');
171
172 #extrait le nom à partire du nom du fichier
173 /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichier
174 #remplace undescores et points par des espaces
175 titre = $1.gsub(/[_\.]/, ' ')
176 #vire les espaces au début et à la fin
177 titre.strip!
178 #remplace les suites d'espaces par un seul
179 titre.gsub!(/ {2,}/,' ')
180 titre.gsub!(/\[.*?\]/,'')
181 titre.gsub!(/\(.*?\)/,'')
182 @titre = titre.dup
183
184 donneesHtml = nil
185 begin
186 reponse, donneesHtml = connexionHttp.get("/recherche/?motcle=#{CGI::escape(titre)}")
187 #si pas trouvé alors on enlève un mot à la fin
188 if /.*?Pas de résultats.*?/ =~ donneesHtml
189 /(.*?)[^ ]+?$/ =~ titre.strip
190 titre = $1
191 titre.strip!
192 else
193 break;
194 end
195 end while not titre.nil? and not titre.empty?
196
197 unless titre.nil? or titre.empty?
198 /<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">/ =~ donneesHtml
199 if $1
200 r, ficheHtml = connexionHttp.get("/film/fichefilm_gen_cfilm=#{$1}.html")
201
202 # Titre
203 /<title>(.*?)<\/title>/ =~ ficheHtml
204 @titre = $1 unless $1.nil?
205
206 #puts "Movie found : #{@titre} (#{@fichier})"
207
208 # Année
209 /<h4>Année de production : (\d+)<\/h4>/ =~ ficheHtml
210 @annee = $1.to_i unless $1.nil?
211
212 # Réalisateurs
213 /Réalisé par <a class="link1" href=".*?" target="">(.*?)<\/a>/ =~ ficheHtml
214 @realisateurs << Personne::ajouter($1) unless $1.nil?
215
216 # Acteurs
217 /Avec(.*)/ =~ ficheHtml
218 $1.scan(/<a class="link1" href="\/personne\/fichepersonne_gen_cpersonne=\d+\.html" target="">(.+?)<\/a>/m){|a|
219 @acteurs << Personne::ajouter(a[0]) unless a[0].nil?
220 } unless $1.nil?
221
222 # Pays
223 /^<h4>Film (.*?)\.<\/h4>/ =~ ficheHtml
224 $1.split(',').each{|pays|
225 @pays << Pays::ajouter(pays) unless pays.nil?
226 } unless $1.nil?
227
228 # Duree
229 /<h4>Durée : (\d+?)h (\d+?)min.<\/h4>/ =~ ficheHtml
230 @duree = $1.nil? ? $2.to_i : $1.to_i * 60 + $2.to_i
231
232 # Critique presse
233 /Presse<\/a> <img src=".*?etoile_(\d)\.gif"/ =~ ficheHtml
234 @critiquePresse = $1.to_i unless $1.nil?
235
236 # Critique spectateur
237 /Spectateurs<\/a> <img src=".*?etoile_(\d)\.gif"/ =~ ficheHtml
238 @critiqueSpectateur = $1.to_i unless $1.nil?
239
240 # Genre
241 /Genre : (.*)/ =~ ficheHtml
242 $1.scan(/<a href="\/film\/alaffiche_genre_gen_genre=.*?" class="link1">(.+?)<\/a>/m){|g|
243 @genres << Genre::ajouter(g[0]) unless g[0].nil?
244 } unless $1.nil?
245
246 # Synopsis
247 /Synopsis.*?<h4>(.+?)<\/h4>/m =~ ficheHtml
248 @synopsis = $1 unless $1.nil?
249
250 # Budget
251 /Budget<\/b> : (.+?) millions d'euros<\/h4>/ =~ ficheHtml
252 @budget = $1.to_i unless $1.nil?
253 else
254 puts "[!] Movie not found : #{@titre} (#{@fichier})"
255 end
256 end
257 self
258 end
259
260 def getXml
261 racine = REXML::Element::new('film')
262 racine.add(REXML::Element::new('fichier').add_text(@fichier))
263 racine.add(REXML::Element::new('titre').add_text(@titre))
264 racine.add(REXML::Element::new('annee').add_text(@annee.to_s))
265
266 @realisateurs.each{|r|
267 racine.add(REXML::Element::new('realisateur').add_text(r.nom))
268 }
269
270 @acteurs.each{|a|
271 racine.add(REXML::Element::new('acteur').add_text(a.nom))
272 }
273 @pays.each{|p|
274 racine.add(REXML::Element::new('pays').add_text(p.nom))
275 }
276 racine.add(REXML::Element::new('duree').add_text(@duree.to_s))
277
278 racine.add(REXML::Element::new('critiquePresse').add_text(@critiquePresse.to_s))
279 racine.add(REXML::Element::new('critiqueSpectateur').add_text(@critiqueSpectateur.to_s))
280 @genres.each{|g|
281 racine.add(REXML::Element::new('genre').add_text(g.nom))
282 }
283 racine.add(REXML::Element::new('synopsis').add_text(@synopsis))
284 budgetElement = REXML::Element::new('budget')
285 budgetElement.add_text(@budget.to_s)
286 budgetElement.add_attribute('unite', @budgetUnite)
287 racine.add(budgetElement)
288
289 racine
290 end
291 end
292