MOD Le fichier film.rb et divisé en film.rb et films.rb pour une meilleure lecture
[pompage.git] / src / films.rb
1 # Représente un ensemble de films
2
3 require 'rexml/document'
4 require 'thwait'
5
6 require 'film.rb'
7 require 'pays.rb'
8 require 'genre.rb'
9 require 'personne.rb'
10 require 'constantes.rb'
11
12 class Films
13 def initialize(xmlFile)
14 @xmlFile = xmlFile
15
16 # repertoire de base, par exemple C:/Divx/
17 @repBase = ''
18
19 # Les films indexés par leur titre
20 @films = {}
21
22 # Les films indexés par leur nom de fichier, deux fichiers différents peuvent pointer sur le même film
23 @filmsFichier = {}
24
25 # Les films qui ont plusieurs réponses lors de la recherche, traités à la fin
26 @filmsPlusieursReponses = []
27
28 @threadsWait = ThreadsWait::new
29 @nbConn = 0 # le nombre de connexion
30
31 # le prochain id disponible
32 @idDisponible = 1
33
34 chargerFilms
35 end
36
37 # Lit un repertoire de manière recursive et va chercher les informations concernant le film sur le net
38 def pomper(r)
39 @repBase = r
40 repPrecedant = Dir::getwd
41 Dir::chdir(r)
42
43 pomperR('.')
44
45 # on attends que les threads se terminent
46 @threadsWait.all_waits
47
48 # traite les films qui avaient plusieurs réponses lors de la recherche
49 # l'utilisateur doit faire un choix
50 i = 1
51 @filmsPlusieursReponses.each{|f|
52 puts
53 puts "Plop, ya un conflit #{i} / #{@filmsPlusieursReponses.length} :"
54 if f.reglerConflitPlusieursReponses
55 ajouterFilm(f)
56 end
57 i += 1
58 }
59
60 Dir::chdir(repPrecedant)
61 end
62
63 # Sauve les films dans un fichier XML
64 def sauverFilms
65 # le document
66 docXml = REXML::Document::new
67 docXml.xml_decl().encoding = "UTF-8" # normalement UTF-8
68 docXml.xml_decl().dowrite
69
70 # la racine du document
71 racine = REXML::Element::new('filmographie')
72 docXml.add(racine)
73 pi = REXML::Instruction.new("xml-stylesheet", "type=\"text/xsl\" href=\"../xsl/yopyop.xsl\"")
74 racine.previous_sibling = pi
75
76 # on ajoute chaque film à la racine
77 @films.each{|nom, f|
78 racine.add(f.getXml)
79 }
80
81 # sauve le document
82 docXml.write(File::new(@xmlFile, 'w'), 0)
83 end
84
85 private
86
87 # Charge les films depuis le fichier XML
88 def chargerFilms
89 # si le fichier n'existe pas il n'y a rien à charger
90 if !File.exists?(@xmlFile)
91 return
92 end
93
94 racine = REXML::Document::new(File::new(@xmlFile)).root
95 racine.each_element{|e|
96 id = e.attribute('id').to_s.to_i
97
98 if id > @idDisponible
99 @idDisponible = id + 1
100 end
101
102 titre = e.get_elements('titre')[0].get_text
103
104 fichiers = e.get_elements('fichiers')[0].get_elements('fichier')
105 annee = e.get_elements('annee')[0].get_text
106 duree = e.get_elements('duree')[0].get_text
107 critiquePresse = e.get_elements('critiquePresse')[0].get_text
108 critiqueSpectateur = e.get_elements('critiqueSpectateur')[0].get_text
109 synopsis = e.get_elements('synopsis')[0].get_elements('p')
110 budget = e.get_elements('budget')[0].get_text
111 realisateurs = e.get_elements('realisateurs')[0].get_elements('realisateur')
112 acteurs = e.get_elements('acteurs')[0].get_elements('acteur')
113 pays = e.get_elements('lespays')[0].get_elements('pays')
114 genres = e.get_elements('genres')[0].get_elements('genre')
115
116 film = Film::new(fichiers[0].get_text.value)
117
118 film.titre = titre.value unless titre.nil?
119 film.id = id
120 fichiers.each{|e|
121 film.addFichier(e.get_text.value)
122 @filmsFichier[e.get_text.value] = film
123 }
124 film.annee = annee.value unless annee.nil?
125 acteurs.each{|e|
126 film.acteurs << Personne::ajouter(e.get_text.value)
127 }
128 pays.each{|e|
129 film.pays << Pays::ajouter(e.get_text.value)
130 }
131 film.duree = duree.value unless duree.nil?
132 film.critiquePresse = critiquePresse.value unless critiquePresse.nil?
133 film.critiqueSpectateur = critiqueSpectateur.value unless critiqueSpectateur.nil?
134 genres.each{|e|
135 film.genres << Genre::ajouter(e.get_text.value) if e.get_text != nil
136 }
137 debut = true
138 film.synopsis = ""
139 synopsis.each{|e|
140 film.synopsis += "\n" unless debut
141 film.synopsis += e.get_text.value if e.get_text != nil
142 debut = false
143 }
144 film.budget = budget.value unless budget.nil?
145 @films[film.titre] = film
146 }
147 end
148
149 # Retourne un nouvel id, utilisé lors de la création d'un nouveau film
150 def getNewId
151 id = @idDisponible
152 @idDisponible += 1
153 return id
154 end
155
156 # Ajoute un film
157 def ajouterFilm(film)
158 if film.plusieursReponses?
159 @filmsPlusieursReponses << film
160 return
161 end
162
163 # le film existe déjà
164 if @films.has_key?(film.titre)
165 # le fichier n'est pas connu -> nième partie d'un film
166 if !@filmsFichier.has_key?(film.fichiers[0])
167 puts "[i] movie #{film.titre} has a another file part : #{film.fichiers[0]}"
168 @films[film.titre].addFichier(film.fichiers[0])
169 @filmsFichier[film.fichiers[0]] = @films[film.titre]
170 else
171 puts "[!] Duplicate movie : #{film.titre} (#{film.fichiers[0]})"
172 end
173 else
174 puts "[i] movie added : #{film.titre} (#{film.fichiers[0]})"
175 @films[film.titre] = film
176 @filmsFichier[film.fichiers[0]] = film
177 end
178 end
179
180 # Appelé par 'pomper'. Cette méthode est récursive.
181 def pomperR(r)
182 Dir::foreach(r){|f|
183 next if f[0,1] == '.'
184 fichier = (r == '.' ? '' : r + "/") + f
185 if File::directory?(fichier)
186 litRepertoireR(fichier)
187 else
188
189 # vérification de l'extension
190 /^.*?\.(.{3,4})$/ =~ fichier
191 if !FILMS_EXTENSIONS.include?($1)
192 next
193 end
194
195 fichier = CGI::escapeHTML(fichier.unpack("C*").pack("U*"))
196
197 # on skip si le film est déjàa dans la BD
198 if film = @filmsFichier[fichier]
199 puts "[i] Already exists in DB : #{film.titre} (#{fichier})"
200 next
201 end
202
203 film = nil
204
205 # pour limiter le nombre de connexion simultanée
206 if @nbConn >= NB_CONN_MAX
207 @threadsWait.next_wait
208 end
209
210 @nbConn += 1
211 @threadsWait.join_nowait(
212 Thread::new{
213 begin
214 film = Film::new(fichier).loadData
215 film.id = getNewId # on lui donne un nouvel ID
216
217 unless film.nil? # le film a été correctement construit
218 ajouterFilm(film)
219 end
220 rescue Exception => e
221 puts e.message
222 puts e.backtrace
223 end
224 @nbConn -= 1
225 }
226 )
227 end
228 }
229 end
230 end