ADD XML en UTF-8 (mais ca merde :()
[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 document XML.
84 def Film::getFilmsXml
85 racine = REXML::Element::new('filmographie')
86 docXml = REXML::Document::new
87 docXml.add(racine)
88 docXml.xml_decl().encoding = "UTF-8"
89 docXml.xml_decl().dowrite
90
91 @@films.each{|nom, f|
92 racine.add(f.getXml)
93 }
94 docXml
95 end
96
97 private
98
99 def Film::filmsFactory(fichier)
100 /^.*?\.(.{3,4})$/ =~ fichier
101 if FILMS_EXTENSIONS.include?($1)
102 Film::new(fichier).loadData
103 end
104 end
105
106 def Film::litRepertoireR(r)
107 Dir::foreach(r){|f|
108 next if f == '.' or f == '..'
109 fichier = r + "/" + f
110 if File::directory?(fichier)
111 litRepertoireR(fichier)
112 else
113
114 #si le film n'existe pas déjà dans la liste
115 if film = @@filmsFichier[fichier]
116 puts "[i] Already exists in DB : #{film.titre} (#{film.fichier})"
117 next
118 end
119
120 film = nil
121
122 @@nbConn += 1
123 @@threadsWait.join_nowait(
124 Thread::new{
125 begin
126 @@mutex.lock if @@nbConn >= NB_CONN_MAX
127 film = Film::filmsFactory(fichier)
128 unless film.nil?
129 if @@films.has_key?(film.titre)
130 puts "[!] Duplicate movie : #{film.titre} (#{film.fichier})"
131 else
132 puts "[i] movie added : #{film.titre} (#{film.fichier})"
133 @@films[film.titre] = film
134 @@filmsFichier[film.fichier] = film
135 end
136 end
137 @@nbConn -= 1
138 #p @@nbConn
139 @@mutex.unlock
140 rescue Exception => e
141 puts e.message
142 puts e.backtrace
143 end
144 }
145 )
146 end
147 }
148 end
149
150
151 def initialize(fichier)
152 @fichier = fichier
153 @titre = ''
154 @annee = nil
155 @realisateurs = []
156 @acteurs = []
157 @pays = []
158 @duree = nil
159 @critiquePresse = nil
160 @critiqueSpectateur = nil
161 @genres = []
162 @synopsis = nil
163 @budget = nil
164 @budgetUnite = 'euro'
165 end
166
167 public
168
169 # Charge les informations du films à partir d'allocine.fr
170 # ret [Film] : soit même
171 def loadData
172 unless LOAD_DATA
173 @titre = @fichier
174 return self
175 end
176
177 connexionHttp = Net::HTTP::new('www.allocine.fr');
178
179 #extrait le nom à partire du nom du fichier
180 /^.*?([^\/]*?)\.(.{3,4})$/ =~ @fichier
181 #remplace undescores et points par des espaces
182 titre = $1.gsub(/[_\.]/, ' ')
183 #vire les espaces au début et à la fin
184 titre.strip!
185 #remplace les suites d'espaces par un seul
186 titre.gsub!(/ {2,}/,' ')
187 titre.gsub!(/\[.*?\]/,'')
188 titre.gsub!(/\(.*?\)/,'')
189 @titre = titre.dup
190
191 donneesHtml = nil
192 begin
193 reponse, donneesHtml = connexionHttp.get("/recherche/?motcle=#{CGI::escape(titre)}")
194 #si pas trouvé alors on enlève un mot à la fin
195 if /.*?Pas de résultats.*?/ =~ donneesHtml
196 /(.*?)[^ ]+?$/ =~ titre.strip
197 titre = $1
198 titre.strip!
199 else
200 break;
201 end
202 end while not titre.nil? and not titre.empty?
203
204 unless titre.nil? or titre.empty?
205 /<a href="\/film\/fichefilm_gen_cfilm=(\d+)\.html" class="link1">/ =~ donneesHtml
206 if $1
207 r, ficheHtml = connexionHttp.get("/film/fichefilm_gen_cfilm=#{$1}.html")
208
209 # Titre
210 /<title>(.*?)<\/title>/ =~ ficheHtml
211 @titre = $1 unless $1.nil?
212
213 puts "Movie found : #{@titre} (#{@fichier})"
214
215 # Année
216 /<h4>Année de production : (\d+)<\/h4>/ =~ ficheHtml
217 @annee = $1.to_i unless $1.nil?
218
219 # Réalisateurs
220 /Réalisé par <a class="link1" href=".*?" target="">(.*?)<\/a>/ =~ ficheHtml
221 @realisateurs << Personne::ajouter($1) unless $1.nil?
222
223 # Acteurs
224 /Avec(.*)/ =~ ficheHtml
225 $1.scan(/<a class="link1" href="\/personne\/fichepersonne_gen_cpersonne=\d+\.html" target="">(.+?)<\/a>/m){|a|
226 @acteurs << Personne::ajouter(a[0]) unless a[0].nil?
227 } unless $1.nil?
228
229 # Pays
230 /^<h4>Film (.*?)\.<\/h4>/ =~ ficheHtml
231 $1.split(',').each{|pays|
232 @pays << Pays::ajouter(pays) unless pays.nil?
233 } unless $1.nil?
234
235 # Duree
236 /<h4>Durée : (\d+)h (\d+)min./ =~ ficheHtml
237 @duree = $1.nil? ? $2.to_i : $1.to_i * 60 + $2.to_i
238
239 # Critiques presse et spectateur
240 /Presse.*etoile_([012345]).*Spectateurs.*etoile_([012345])"/m =~ ficheHtml
241 @critiquePresse = $1.to_i unless $1.nil?
242 @critiqueSpectateur = $2.to_i unless $2.nil?
243
244 # Genre
245 /Genre : (.*)/ =~ ficheHtml
246 $1.scan(/<a href="\/film\/alaffiche_genre_gen_genre=.*?" class="link1">(.+?)<\/a>/m){|g|
247 @genres << Genre::ajouter(g[0]) unless g[0].nil?
248 } unless $1.nil?
249
250 # Synopsis
251 /Synopsis.*?<h4>(.+?)<\/h4>/m =~ ficheHtml
252 @synopsis = $1 unless $1.nil?
253
254 # Budget
255 /Budget<\/b> : (.+?) millions d'euros<\/h4>/ =~ ficheHtml
256 @budget = $1.to_i unless $1.nil?
257 else
258 puts "[!] Movie not found : #{@titre} (#{@fichier})"
259 end
260 end
261 self
262 end
263
264 def getXml
265 racine = REXML::Element::new('film')
266 racine.add(REXML::Element::new('fichier').add_text(@fichier))
267 racine.add(REXML::Element::new('titre').add_text(@titre))
268 racine.add(REXML::Element::new('annee').add_text(@annee.to_s))
269
270 @realisateurs.each{|r|
271 racine.add(REXML::Element::new('realisateur').add_text(r.nom))
272 }
273
274 @acteurs.each{|a|
275 racine.add(REXML::Element::new('acteur').add_text(a.nom))
276 }
277 @pays.each{|p|
278 racine.add(REXML::Element::new('pays').add_text(p.nom))
279 }
280 racine.add(REXML::Element::new('duree').add_text(@duree.to_s))
281
282 racine.add(REXML::Element::new('critiquePresse').add_text(@critiquePresse.to_s))
283 racine.add(REXML::Element::new('critiqueSpectateur').add_text(@critiqueSpectateur.to_s))
284 @genres.each{|g|
285 racine.add(REXML::Element::new('genre').add_text(g.nom))
286 }
287 racine.add(REXML::Element::new('synopsis').add_text(@synopsis))
288 budgetElement = REXML::Element::new('budget')
289 budgetElement.add_text(@budget.to_s)
290 budgetElement.add_attribute('unite', @budgetUnite)
291 racine.add(budgetElement)
292
293 racine
294 end
295 end
296