subs 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +55 -0
- data/Rakefile +1 -0
- data/bin/subs +286 -0
- data/lib/subs/language.rb +538 -0
- data/lib/subs/providers/open_subtitles.rb +142 -0
- data/lib/subs/providers/provider.rb +58 -0
- data/lib/subs/providers/sub_db.rb +80 -0
- data/lib/subs/sub_rip_time.rb +47 -0
- data/lib/subs/version.rb +4 -0
- data/lib/subs.rb +192 -0
- data/subs.gemspec +32 -0
- metadata +120 -0
@@ -0,0 +1,538 @@
|
|
1
|
+
module Subs
|
2
|
+
|
3
|
+
class Language
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
attr_reader :alpha3
|
7
|
+
attr_reader :alpha2
|
8
|
+
|
9
|
+
def initialize(name, alpha3, alpha2 = nil)
|
10
|
+
@name = name
|
11
|
+
@alpha3 = alpha3
|
12
|
+
@alpha2 = alpha2
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
other.is_a?(Language) && @alpha3 == other.alpha3
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
@alpha3.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from_name(name)
|
24
|
+
return nil if name.nil?
|
25
|
+
result = database.find { |_, v| v.name.casecmp(name).zero? }
|
26
|
+
return result.last if result
|
27
|
+
name = name.downcase
|
28
|
+
database.find_all { |_, v| v.name.downcase.include?(name) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.from_alpha3(code)
|
32
|
+
database[code.to_sym]
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.from_alpha2(code)
|
36
|
+
code = code.to_sym
|
37
|
+
database.values.find { |language| code == language.alpha2 }
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.database
|
41
|
+
@database ||= {
|
42
|
+
aar: Language.new("Afar", :aar, :aa),
|
43
|
+
abk: Language.new("Abkhazian", :abk, :ab),
|
44
|
+
ace: Language.new("Achinese", :ace),
|
45
|
+
ach: Language.new("Acoli", :ach),
|
46
|
+
ada: Language.new("Adangme", :ada),
|
47
|
+
ady: Language.new("adyghé", :ady),
|
48
|
+
afa: Language.new("Afro-Asiatic", :afa),
|
49
|
+
afh: Language.new("Afrihili", :afh),
|
50
|
+
afr: Language.new("Afrikaans", :afr, :af),
|
51
|
+
ain: Language.new("Ainu", :ain),
|
52
|
+
aka: Language.new("Akan", :aka, :ak),
|
53
|
+
akk: Language.new("Akkadian", :akk),
|
54
|
+
alb: Language.new("Albanian", :alb, :sq),
|
55
|
+
ale: Language.new("Aleut", :ale),
|
56
|
+
alg: Language.new("Algonquian", :alg),
|
57
|
+
alt: Language.new("Southern Altai", :alt),
|
58
|
+
amh: Language.new("Amharic", :amh, :am),
|
59
|
+
ang: Language.new("Old English", :ang),
|
60
|
+
apa: Language.new("Apache", :apa),
|
61
|
+
ara: Language.new("Arabic", :ara, :ar),
|
62
|
+
arc: Language.new("Aramaic", :arc),
|
63
|
+
arg: Language.new("Aragonese", :arg, :an),
|
64
|
+
arm: Language.new("Armenian", :arm, :hy),
|
65
|
+
arn: Language.new("Araucanian", :arn),
|
66
|
+
arp: Language.new("Arapaho", :arp),
|
67
|
+
art: Language.new("Artificial", :art),
|
68
|
+
arw: Language.new("Arawak", :arw),
|
69
|
+
asm: Language.new("Assamese", :asm, :as),
|
70
|
+
ast: Language.new("Asturian", :ast, :at),
|
71
|
+
ath: Language.new("Athapascan", :ath),
|
72
|
+
aus: Language.new("Australian ", :aus),
|
73
|
+
ava: Language.new("Avaric", :ava, :av),
|
74
|
+
ave: Language.new("Avestan", :ave, :ae),
|
75
|
+
awa: Language.new("Awadhi", :awa),
|
76
|
+
aym: Language.new("Aymara", :aym, :ay),
|
77
|
+
aze: Language.new("Azerbaijani", :aze, :az),
|
78
|
+
bad: Language.new("Banda", :bad),
|
79
|
+
bai: Language.new("Bamileke", :bai),
|
80
|
+
bak: Language.new("Bashkir", :bak, :ba),
|
81
|
+
bal: Language.new("Baluchi", :bal),
|
82
|
+
bam: Language.new("Bambara", :bam, :bm),
|
83
|
+
ban: Language.new("Balinese", :ban),
|
84
|
+
baq: Language.new("Basque", :baq, :eu),
|
85
|
+
bas: Language.new("Basa", :bas),
|
86
|
+
bat: Language.new("Baltic", :bat),
|
87
|
+
bej: Language.new("Beja", :bej),
|
88
|
+
bel: Language.new("Belarusian", :bel, :be),
|
89
|
+
bem: Language.new("Bemba", :bem),
|
90
|
+
ben: Language.new("Bengali", :ben, :bn),
|
91
|
+
ber: Language.new("Berber", :ber),
|
92
|
+
bho: Language.new("Bhojpuri", :bho),
|
93
|
+
bih: Language.new("Bihari", :bih, :bh),
|
94
|
+
bik: Language.new("Bikol", :bik),
|
95
|
+
bin: Language.new("Bini", :bin),
|
96
|
+
bis: Language.new("Bislama", :bis, :bi),
|
97
|
+
bla: Language.new("Siksika", :bla),
|
98
|
+
bnt: Language.new("Bantu", :bnt),
|
99
|
+
bos: Language.new("Bosnian", :bos, :bs),
|
100
|
+
bra: Language.new("Braj", :bra),
|
101
|
+
bre: Language.new("Breton", :bre, :br),
|
102
|
+
btk: Language.new("Batak", :btk),
|
103
|
+
bua: Language.new("Buriat", :bua),
|
104
|
+
bug: Language.new("Buginese", :bug),
|
105
|
+
bul: Language.new("Bulgarian", :bul, :bg),
|
106
|
+
bur: Language.new("Burmese", :bur, :my),
|
107
|
+
byn: Language.new("Blin", :byn),
|
108
|
+
cad: Language.new("Caddo", :cad),
|
109
|
+
cai: Language.new("Central American Indian", :cai),
|
110
|
+
car: Language.new("Carib", :car),
|
111
|
+
cat: Language.new("Catalan", :cat, :ca),
|
112
|
+
cau: Language.new("Caucasian", :cau),
|
113
|
+
ceb: Language.new("Cebuano", :ceb),
|
114
|
+
cel: Language.new("Celtic", :cel),
|
115
|
+
cha: Language.new("Chamorro", :cha, :ch),
|
116
|
+
chb: Language.new("Chibcha", :chb),
|
117
|
+
che: Language.new("Chechen", :che, :ce),
|
118
|
+
chg: Language.new("Chagatai", :chg),
|
119
|
+
chi: Language.new("Chinese", :chi, :zh),
|
120
|
+
chk: Language.new("Chuukese", :chk),
|
121
|
+
chm: Language.new("Mari", :chm),
|
122
|
+
chn: Language.new("Chinook jargon", :chn),
|
123
|
+
cho: Language.new("Choctaw", :cho),
|
124
|
+
chp: Language.new("Chipewyan", :chp),
|
125
|
+
chr: Language.new("Cherokee", :chr),
|
126
|
+
chu: Language.new("Church Slavic", :chu, :cu),
|
127
|
+
chv: Language.new("Chuvash", :chv, :cv),
|
128
|
+
chy: Language.new("Cheyenne", :chy),
|
129
|
+
cmc: Language.new("Chamic", :cmc),
|
130
|
+
cop: Language.new("Coptic", :cop),
|
131
|
+
cor: Language.new("Cornish", :cor, :kw),
|
132
|
+
cos: Language.new("Corsican", :cos, :co),
|
133
|
+
cpe: Language.new("Creoles and pidgins, English based", :cpe),
|
134
|
+
cpf: Language.new("Creoles and pidgins, French-based", :cpf),
|
135
|
+
cpp: Language.new("Creoles and pidgins, Portuguese-based", :cpp),
|
136
|
+
cre: Language.new("Cree", :cre, :cr),
|
137
|
+
crh: Language.new("Crimean Tatar", :crh),
|
138
|
+
crp: Language.new("Creoles and pidgins", :crp),
|
139
|
+
csb: Language.new("Kashubian", :csb),
|
140
|
+
cus: Language.new("Cushitic", :cus),
|
141
|
+
cze: Language.new("Czech", :cze, :cs),
|
142
|
+
dak: Language.new("Dakota", :dak),
|
143
|
+
dan: Language.new("Danish", :dan, :da),
|
144
|
+
dar: Language.new("Dargwa", :dar),
|
145
|
+
day: Language.new("Dayak", :day),
|
146
|
+
del: Language.new("Delaware", :del),
|
147
|
+
den: Language.new("Slave (Athapascan)", :den),
|
148
|
+
dgr: Language.new("Dogrib", :dgr),
|
149
|
+
din: Language.new("Dinka", :din),
|
150
|
+
div: Language.new("Divehi", :div, :dv),
|
151
|
+
doi: Language.new("Dogri", :doi),
|
152
|
+
dra: Language.new("Dravidian", :dra),
|
153
|
+
dua: Language.new("Duala", :dua),
|
154
|
+
dum: Language.new("Dutch, Middle (ca.1050-1350)", :dum),
|
155
|
+
dut: Language.new("Dutch", :dut, :nl),
|
156
|
+
dyu: Language.new("Dyula", :dyu),
|
157
|
+
dzo: Language.new("Dzongkha", :dzo, :dz),
|
158
|
+
efi: Language.new("Efik", :efi),
|
159
|
+
egy: Language.new("Egyptian (Ancient)", :egy),
|
160
|
+
eka: Language.new("Ekajuk", :eka),
|
161
|
+
elx: Language.new("Elamite", :elx),
|
162
|
+
eng: Language.new("English", :eng, :en),
|
163
|
+
enm: Language.new("English, Middle (1100-1500)", :enm),
|
164
|
+
epo: Language.new("Esperanto", :epo, :eo),
|
165
|
+
est: Language.new("Estonian", :est, :et),
|
166
|
+
ewe: Language.new("Ewe", :ewe, :ee),
|
167
|
+
ewo: Language.new("Ewondo", :ewo),
|
168
|
+
fan: Language.new("Fang", :fan),
|
169
|
+
fao: Language.new("Faroese", :fao, :fo),
|
170
|
+
fat: Language.new("Fanti", :fat),
|
171
|
+
fij: Language.new("Fijian", :fij, :fj),
|
172
|
+
fil: Language.new("Filipino", :fil),
|
173
|
+
fin: Language.new("Finnish", :fin, :fi),
|
174
|
+
fiu: Language.new("Finno-Ugrian", :fiu),
|
175
|
+
fon: Language.new("Fon", :fon),
|
176
|
+
fre: Language.new("French", :fre, :fr),
|
177
|
+
frm: Language.new("French, Middle (ca.1400-1600)", :frm),
|
178
|
+
fro: Language.new("French, Old (842-ca.1400)", :fro),
|
179
|
+
fry: Language.new("Frisian", :fry, :fy),
|
180
|
+
ful: Language.new("Fulah", :ful, :ff),
|
181
|
+
fur: Language.new("Friulian", :fur),
|
182
|
+
gaa: Language.new("Ga", :gaa),
|
183
|
+
gay: Language.new("Gayo", :gay),
|
184
|
+
gba: Language.new("Gbaya", :gba),
|
185
|
+
gem: Language.new("Germanic", :gem),
|
186
|
+
geo: Language.new("Georgian", :geo, :ka),
|
187
|
+
ger: Language.new("German", :ger, :de),
|
188
|
+
gez: Language.new("Geez", :gez),
|
189
|
+
gil: Language.new("Gilbertese", :gil),
|
190
|
+
gla: Language.new("Gaelic", :gla, :gd),
|
191
|
+
gle: Language.new("Irish", :gle, :ga),
|
192
|
+
glg: Language.new("Galician", :glg, :gl),
|
193
|
+
glv: Language.new("Manx", :glv, :gv),
|
194
|
+
gmh: Language.new("German, Middle High (ca.1050-1500)", :gmh),
|
195
|
+
goh: Language.new("German, Old High (ca.750-1050)", :goh),
|
196
|
+
gon: Language.new("Gondi", :gon),
|
197
|
+
gor: Language.new("Gorontalo", :gor),
|
198
|
+
got: Language.new("Gothic", :got),
|
199
|
+
grb: Language.new("Grebo", :grb),
|
200
|
+
grc: Language.new("Greek, Ancient (to 1453)", :grc),
|
201
|
+
ell: Language.new("Greek", :ell, :el),
|
202
|
+
grn: Language.new("Guarani", :grn, :gn),
|
203
|
+
guj: Language.new("Gujarati", :guj, :gu),
|
204
|
+
gwi: Language.new("Gwich´in", :gwi),
|
205
|
+
hai: Language.new("Haida", :hai),
|
206
|
+
hat: Language.new("Haitian", :hat, :ht),
|
207
|
+
hau: Language.new("Hausa", :hau, :ha),
|
208
|
+
haw: Language.new("Hawaiian", :haw),
|
209
|
+
heb: Language.new("Hebrew", :heb, :he),
|
210
|
+
her: Language.new("Herero", :her, :hz),
|
211
|
+
hil: Language.new("Hiligaynon", :hil),
|
212
|
+
him: Language.new("Himachali", :him),
|
213
|
+
hin: Language.new("Hindi", :hin, :hi),
|
214
|
+
hit: Language.new("Hittite", :hit),
|
215
|
+
hmn: Language.new("Hmong", :hmn),
|
216
|
+
hmo: Language.new("Hiri Motu", :hmo, :ho),
|
217
|
+
hrv: Language.new("Croatian", :hrv, :hr),
|
218
|
+
hun: Language.new("Hungarian", :hun, :hu),
|
219
|
+
hup: Language.new("Hupa", :hup),
|
220
|
+
iba: Language.new("Iban", :iba),
|
221
|
+
ibo: Language.new("Igbo", :ibo, :ig),
|
222
|
+
ice: Language.new("Icelandic", :ice, :is),
|
223
|
+
ido: Language.new("Ido", :ido, :io),
|
224
|
+
iii: Language.new("Sichuan Yi", :iii, :ii),
|
225
|
+
ijo: Language.new("Ijo", :ijo),
|
226
|
+
iku: Language.new("Inuktitut", :iku, :iu),
|
227
|
+
ile: Language.new("Interlingue", :ile, :ie),
|
228
|
+
ilo: Language.new("Iloko", :ilo),
|
229
|
+
ina: Language.new("Interlingua (International Auxiliary Language Asso", :ina, :ia),
|
230
|
+
inc: Language.new("Indic", :inc),
|
231
|
+
ind: Language.new("Indonesian", :ind, :id),
|
232
|
+
ine: Language.new("Indo-European", :ine),
|
233
|
+
inh: Language.new("Ingush", :inh),
|
234
|
+
ipk: Language.new("Inupiaq", :ipk, :ik),
|
235
|
+
ira: Language.new("Iranian", :ira),
|
236
|
+
iro: Language.new("Iroquoian", :iro),
|
237
|
+
ita: Language.new("Italian", :ita, :it),
|
238
|
+
jav: Language.new("Javanese", :jav, :jv),
|
239
|
+
jpn: Language.new("Japanese", :jpn, :ja),
|
240
|
+
jpr: Language.new("Judeo-Persian", :jpr),
|
241
|
+
jrb: Language.new("Judeo-Arabic", :jrb),
|
242
|
+
kaa: Language.new("Kara-Kalpak", :kaa),
|
243
|
+
kab: Language.new("Kabyle", :kab),
|
244
|
+
kac: Language.new("Kachin", :kac),
|
245
|
+
kal: Language.new("Kalaallisut", :kal, :kl),
|
246
|
+
kam: Language.new("Kamba", :kam),
|
247
|
+
kan: Language.new("Kannada", :kan, :kn),
|
248
|
+
kar: Language.new("Karen", :kar),
|
249
|
+
kas: Language.new("Kashmiri", :kas, :ks),
|
250
|
+
kau: Language.new("Kanuri", :kau, :kr),
|
251
|
+
kaw: Language.new("Kawi", :kaw),
|
252
|
+
kaz: Language.new("Kazakh", :kaz, :kk),
|
253
|
+
kbd: Language.new("Kabardian", :kbd),
|
254
|
+
kha: Language.new("Khasi", :kha),
|
255
|
+
khi: Language.new("Khoisan", :khi),
|
256
|
+
khm: Language.new("Khmer", :khm, :km),
|
257
|
+
kho: Language.new("Khotanese", :kho),
|
258
|
+
kik: Language.new("Kikuyu", :kik, :ki),
|
259
|
+
kin: Language.new("Kinyarwanda", :kin, :rw),
|
260
|
+
kir: Language.new("Kirghiz", :kir, :ky),
|
261
|
+
kmb: Language.new("Kimbundu", :kmb),
|
262
|
+
kok: Language.new("Konkani", :kok),
|
263
|
+
kom: Language.new("Komi", :kom, :kv),
|
264
|
+
kon: Language.new("Kongo", :kon, :kg),
|
265
|
+
kor: Language.new("Korean", :kor, :ko),
|
266
|
+
kos: Language.new("Kosraean", :kos),
|
267
|
+
kpe: Language.new("Kpelle", :kpe),
|
268
|
+
krc: Language.new("Karachay-Balkar", :krc),
|
269
|
+
kro: Language.new("Kru", :kro),
|
270
|
+
kru: Language.new("Kurukh", :kru),
|
271
|
+
kua: Language.new("Kuanyama", :kua, :kj),
|
272
|
+
kum: Language.new("Kumyk", :kum),
|
273
|
+
kur: Language.new("Kurdish", :kur, :ku),
|
274
|
+
kut: Language.new("Kutenai", :kut),
|
275
|
+
lad: Language.new("Ladino", :lad),
|
276
|
+
lah: Language.new("Lahnda", :lah),
|
277
|
+
lam: Language.new("Lamba", :lam),
|
278
|
+
lao: Language.new("Lao", :lao, :lo),
|
279
|
+
lat: Language.new("Latin", :lat, :la),
|
280
|
+
lav: Language.new("Latvian", :lav, :lv),
|
281
|
+
lez: Language.new("Lezghian", :lez),
|
282
|
+
lim: Language.new("Limburgan", :lim, :li),
|
283
|
+
lin: Language.new("Lingala", :lin, :ln),
|
284
|
+
lit: Language.new("Lithuanian", :lit, :lt),
|
285
|
+
lol: Language.new("Mongo", :lol),
|
286
|
+
loz: Language.new("Lozi", :loz),
|
287
|
+
ltz: Language.new("Luxembourgish", :ltz, :lb),
|
288
|
+
lua: Language.new("Luba-Lulua", :lua),
|
289
|
+
lub: Language.new("Luba-Katanga", :lub, :lu),
|
290
|
+
lug: Language.new("Ganda", :lug, :lg),
|
291
|
+
lui: Language.new("Luiseno", :lui),
|
292
|
+
lun: Language.new("Lunda", :lun),
|
293
|
+
luo: Language.new("Luo (Kenya and Tanzania)", :luo),
|
294
|
+
lus: Language.new("lushai", :lus),
|
295
|
+
mac: Language.new("Macedonian", :mac, :mk),
|
296
|
+
mad: Language.new("Madurese", :mad),
|
297
|
+
mag: Language.new("Magahi", :mag),
|
298
|
+
mah: Language.new("Marshallese", :mah, :mh),
|
299
|
+
mai: Language.new("Maithili", :mai),
|
300
|
+
mak: Language.new("Makasar", :mak),
|
301
|
+
mal: Language.new("Malayalam", :mal, :ml),
|
302
|
+
man: Language.new("Mandingo", :man),
|
303
|
+
mao: Language.new("Maori", :mao, :mi),
|
304
|
+
map: Language.new("Austronesian", :map),
|
305
|
+
mar: Language.new("Marathi", :mar, :mr),
|
306
|
+
mas: Language.new("Masai", :mas),
|
307
|
+
may: Language.new("Malay", :may, :ms),
|
308
|
+
mdf: Language.new("Moksha", :mdf),
|
309
|
+
mdr: Language.new("Mandar", :mdr),
|
310
|
+
men: Language.new("Mende", :men),
|
311
|
+
mga: Language.new("Irish, Middle (900-1200)", :mga),
|
312
|
+
mic: Language.new("Mi'kmaq", :mic),
|
313
|
+
min: Language.new("Minangkabau", :min),
|
314
|
+
mis: Language.new("Miscellaneous", :mis),
|
315
|
+
mkh: Language.new("Mon-Khmer", :mkh),
|
316
|
+
mlg: Language.new("Malagasy", :mlg, :mg),
|
317
|
+
mlt: Language.new("Maltese", :mlt, :mt),
|
318
|
+
mnc: Language.new("Manchu", :mnc),
|
319
|
+
mni: Language.new("Manipuri", :mni, :ma),
|
320
|
+
mno: Language.new("Manobo", :mno),
|
321
|
+
moh: Language.new("Mohawk", :moh),
|
322
|
+
mol: Language.new("Moldavian", :mol, :mo),
|
323
|
+
mon: Language.new("Mongolian", :mon, :mn),
|
324
|
+
mos: Language.new("Mossi", :mos),
|
325
|
+
mwl: Language.new("Mirandese", :mwl),
|
326
|
+
mul: Language.new("Multiple", :mul),
|
327
|
+
mun: Language.new("Munda", :mun),
|
328
|
+
mus: Language.new("Creek", :mus),
|
329
|
+
mwr: Language.new("Marwari", :mwr),
|
330
|
+
myn: Language.new("Mayan", :myn),
|
331
|
+
myv: Language.new("Erzya", :myv),
|
332
|
+
nah: Language.new("Nahuatl", :nah),
|
333
|
+
nai: Language.new("North American Indian", :nai),
|
334
|
+
nap: Language.new("Neapolitan", :nap),
|
335
|
+
nau: Language.new("Nauru", :nau, :na),
|
336
|
+
nav: Language.new("Navajo", :nav, :nv),
|
337
|
+
nbl: Language.new("Ndebele, South", :nbl, :nr),
|
338
|
+
nde: Language.new("Ndebele, North", :nde, :nd),
|
339
|
+
ndo: Language.new("Ndonga", :ndo, :ng),
|
340
|
+
nds: Language.new("Low German", :nds),
|
341
|
+
nep: Language.new("Nepali", :nep, :ne),
|
342
|
+
new: Language.new("Nepal Bhasa", :new),
|
343
|
+
nia: Language.new("Nias", :nia),
|
344
|
+
nic: Language.new("Niger-Kordofanian", :nic),
|
345
|
+
niu: Language.new("Niuean", :niu),
|
346
|
+
nno: Language.new("Norwegian Nynorsk", :nno, :nn),
|
347
|
+
nob: Language.new("Norwegian Bokmal", :nob, :nb),
|
348
|
+
nog: Language.new("Nogai", :nog),
|
349
|
+
non: Language.new("Norse, Old", :non),
|
350
|
+
nor: Language.new("Norwegian", :nor, :no),
|
351
|
+
nso: Language.new("Northern Sotho", :nso),
|
352
|
+
nub: Language.new("Nubian", :nub),
|
353
|
+
nwc: Language.new("Classical Newari", :nwc),
|
354
|
+
nya: Language.new("Chichewa", :nya, :ny),
|
355
|
+
nym: Language.new("Nyamwezi", :nym),
|
356
|
+
nyn: Language.new("Nyankole", :nyn),
|
357
|
+
nyo: Language.new("Nyoro", :nyo),
|
358
|
+
nzi: Language.new("Nzima", :nzi),
|
359
|
+
oci: Language.new("Occitan", :oci, :oc),
|
360
|
+
oji: Language.new("Ojibwa", :oji, :oj),
|
361
|
+
ori: Language.new("Oriya", :ori, :or),
|
362
|
+
orm: Language.new("Oromo", :orm, :om),
|
363
|
+
osa: Language.new("Osage", :osa),
|
364
|
+
oss: Language.new("Ossetian", :oss, :os),
|
365
|
+
ota: Language.new("Turkish, Ottoman (1500-1928)", :ota),
|
366
|
+
oto: Language.new("Otomian", :oto),
|
367
|
+
paa: Language.new("Papuan", :paa),
|
368
|
+
pag: Language.new("Pangasinan", :pag),
|
369
|
+
pal: Language.new("Pahlavi", :pal),
|
370
|
+
pam: Language.new("Pampanga", :pam),
|
371
|
+
pan: Language.new("Panjabi", :pan, :pa),
|
372
|
+
pap: Language.new("Papiamento", :pap),
|
373
|
+
pau: Language.new("Palauan", :pau),
|
374
|
+
peo: Language.new("Persian, Old (ca.600-400 B.C.)", :peo),
|
375
|
+
per: Language.new("Persian", :per, :fa),
|
376
|
+
phi: Language.new("Philippine", :phi),
|
377
|
+
phn: Language.new("Phoenician", :phn),
|
378
|
+
pli: Language.new("Pali", :pli, :pi),
|
379
|
+
pol: Language.new("Polish", :pol, :pl),
|
380
|
+
pon: Language.new("Pohnpeian", :pon),
|
381
|
+
por: Language.new("Portuguese", :por, :pt),
|
382
|
+
pra: Language.new("Prakrit", :pra),
|
383
|
+
pro: Language.new("Provençal, Old (to 1500)", :pro),
|
384
|
+
pus: Language.new("Pushto", :pus, :ps),
|
385
|
+
que: Language.new("Quechua", :que, :qu),
|
386
|
+
raj: Language.new("Rajasthani", :raj),
|
387
|
+
rap: Language.new("Rapanui", :rap),
|
388
|
+
rar: Language.new("Rarotongan", :rar),
|
389
|
+
roa: Language.new("Romance", :roa),
|
390
|
+
roh: Language.new("Raeto-Romance", :roh, :rm),
|
391
|
+
rom: Language.new("Romany", :rom),
|
392
|
+
run: Language.new("Rundi", :run, :rn),
|
393
|
+
rup: Language.new("Aromanian", :rup),
|
394
|
+
rus: Language.new("Russian", :rus, :ru),
|
395
|
+
sad: Language.new("Sandawe", :sad),
|
396
|
+
sag: Language.new("Sango", :sag, :sg),
|
397
|
+
sah: Language.new("Yakut", :sah),
|
398
|
+
sai: Language.new("South American Indian", :sai),
|
399
|
+
sal: Language.new("Salishan", :sal),
|
400
|
+
sam: Language.new("Samaritan Aramaic", :sam),
|
401
|
+
san: Language.new("Sanskrit", :san, :sa),
|
402
|
+
sas: Language.new("Sasak", :sas),
|
403
|
+
sat: Language.new("Santali", :sat),
|
404
|
+
scc: Language.new("Serbian", :scc, :sr),
|
405
|
+
scn: Language.new("Sicilian", :scn),
|
406
|
+
sco: Language.new("Scots", :sco),
|
407
|
+
sel: Language.new("Selkup", :sel),
|
408
|
+
sem: Language.new("Semitic", :sem),
|
409
|
+
sga: Language.new("Irish, Old (to 900)", :sga),
|
410
|
+
sgn: Language.new("Sign", :sgn),
|
411
|
+
shn: Language.new("Shan", :shn),
|
412
|
+
sid: Language.new("Sidamo", :sid),
|
413
|
+
sin: Language.new("Sinhalese", :sin, :si),
|
414
|
+
sio: Language.new("Siouan", :sio),
|
415
|
+
sit: Language.new("Sino-Tibetan", :sit),
|
416
|
+
sla: Language.new("Slavic", :sla),
|
417
|
+
slo: Language.new("Slovak", :slo, :sk),
|
418
|
+
slv: Language.new("Slovenian", :slv, :sl),
|
419
|
+
sma: Language.new("Southern Sami", :sma),
|
420
|
+
sme: Language.new("Northern Sami", :sme, :se),
|
421
|
+
smi: Language.new("Sami languages", :smi),
|
422
|
+
smj: Language.new("Lule Sami", :smj),
|
423
|
+
smn: Language.new("Inari Sami", :smn),
|
424
|
+
smo: Language.new("Samoan", :smo, :sm),
|
425
|
+
sms: Language.new("Skolt Sami", :sms),
|
426
|
+
sna: Language.new("Shona", :sna, :sn),
|
427
|
+
snd: Language.new("Sindhi", :snd, :sd),
|
428
|
+
snk: Language.new("Soninke", :snk),
|
429
|
+
sog: Language.new("Sogdian", :sog),
|
430
|
+
som: Language.new("Somali", :som, :so),
|
431
|
+
son: Language.new("Songhai", :son),
|
432
|
+
sot: Language.new("Sotho, Southern", :sot, :st),
|
433
|
+
spa: Language.new("Spanish", :spa, :es),
|
434
|
+
srd: Language.new("Sardinian", :srd, :sc),
|
435
|
+
srr: Language.new("Serer", :srr),
|
436
|
+
ssa: Language.new("Nilo-Saharan", :ssa),
|
437
|
+
ssw: Language.new("Swati", :ssw, :ss),
|
438
|
+
suk: Language.new("Sukuma", :suk),
|
439
|
+
sun: Language.new("Sundanese", :sun, :su),
|
440
|
+
sus: Language.new("Susu", :sus),
|
441
|
+
sux: Language.new("Sumerian", :sux),
|
442
|
+
swa: Language.new("Swahili", :swa, :sw),
|
443
|
+
swe: Language.new("Swedish", :swe, :sv),
|
444
|
+
syr: Language.new("Syriac", :syr, :sy),
|
445
|
+
tah: Language.new("Tahitian", :tah, :ty),
|
446
|
+
tai: Language.new("Tai", :tai),
|
447
|
+
tam: Language.new("Tamil", :tam, :ta),
|
448
|
+
tat: Language.new("Tatar", :tat, :tt),
|
449
|
+
tel: Language.new("Telugu", :tel, :te),
|
450
|
+
tem: Language.new("Timne", :tem),
|
451
|
+
ter: Language.new("Tereno", :ter),
|
452
|
+
tet: Language.new("Tetum", :tet),
|
453
|
+
tgk: Language.new("Tajik", :tgk, :tg),
|
454
|
+
tgl: Language.new("Tagalog", :tgl, :tl),
|
455
|
+
tha: Language.new("Thai", :tha, :th),
|
456
|
+
tib: Language.new("Tibetan", :tib, :bo),
|
457
|
+
tig: Language.new("Tigre", :tig),
|
458
|
+
tir: Language.new("Tigrinya", :tir, :ti),
|
459
|
+
tiv: Language.new("Tiv", :tiv),
|
460
|
+
tkl: Language.new("Tokelau", :tkl),
|
461
|
+
tlh: Language.new("Klingon", :tlh),
|
462
|
+
tli: Language.new("Tlingit", :tli),
|
463
|
+
tmh: Language.new("Tamashek", :tmh),
|
464
|
+
tog: Language.new("Tonga (Nyasa)", :tog),
|
465
|
+
ton: Language.new("Tonga (Tonga Islands)", :ton, :to),
|
466
|
+
tpi: Language.new("Tok Pisin", :tpi),
|
467
|
+
tsi: Language.new("Tsimshian", :tsi),
|
468
|
+
tsn: Language.new("Tswana", :tsn, :tn),
|
469
|
+
tso: Language.new("Tsonga", :tso, :ts),
|
470
|
+
tuk: Language.new("Turkmen", :tuk, :tk),
|
471
|
+
tum: Language.new("Tumbuka", :tum),
|
472
|
+
tup: Language.new("Tupi", :tup),
|
473
|
+
tur: Language.new("Turkish", :tur, :tr),
|
474
|
+
tut: Language.new("Altaic", :tut),
|
475
|
+
tvl: Language.new("Tuvalu", :tvl),
|
476
|
+
twi: Language.new("Twi", :twi, :tw),
|
477
|
+
tyv: Language.new("Tuvinian", :tyv),
|
478
|
+
udm: Language.new("Udmurt", :udm),
|
479
|
+
uga: Language.new("Ugaritic", :uga),
|
480
|
+
uig: Language.new("Uighur", :uig, :ug),
|
481
|
+
ukr: Language.new("Ukrainian", :ukr, :uk),
|
482
|
+
umb: Language.new("Umbundu", :umb),
|
483
|
+
und: Language.new("Undetermined", :und),
|
484
|
+
urd: Language.new("Urdu", :urd, :ur),
|
485
|
+
uzb: Language.new("Uzbek", :uzb, :uz),
|
486
|
+
vai: Language.new("Vai", :vai),
|
487
|
+
ven: Language.new("Venda", :ven, :ve),
|
488
|
+
vie: Language.new("Vietnamese", :vie, :vi),
|
489
|
+
vol: Language.new("Volapük", :vol, :vo),
|
490
|
+
vot: Language.new("Votic", :vot),
|
491
|
+
wak: Language.new("Wakashan", :wak),
|
492
|
+
wal: Language.new("Walamo", :wal),
|
493
|
+
war: Language.new("Waray", :war),
|
494
|
+
was: Language.new("Washo", :was),
|
495
|
+
wel: Language.new("Welsh", :wel, :cy),
|
496
|
+
wen: Language.new("Sorbian", :wen),
|
497
|
+
wln: Language.new("Walloon", :wln, :wa),
|
498
|
+
wol: Language.new("Wolof", :wol, :wo),
|
499
|
+
xal: Language.new("Kalmyk", :xal),
|
500
|
+
xho: Language.new("Xhosa", :xho, :xh),
|
501
|
+
yao: Language.new("Yao", :yao),
|
502
|
+
yap: Language.new("Yapese", :yap),
|
503
|
+
yid: Language.new("Yiddish", :yid, :yi),
|
504
|
+
yor: Language.new("Yoruba", :yor, :yo),
|
505
|
+
ypk: Language.new("Yupik", :ypk),
|
506
|
+
zap: Language.new("Zapotec", :zap),
|
507
|
+
zen: Language.new("Zenaga", :zen),
|
508
|
+
zha: Language.new("Zhuang", :zha, :za),
|
509
|
+
znd: Language.new("Zande", :znd),
|
510
|
+
zul: Language.new("Zulu", :zul, :zu),
|
511
|
+
zun: Language.new("Zuni", :zun),
|
512
|
+
rum: Language.new("Romanian", :rum, :ro),
|
513
|
+
pob: Language.new("Portuguese (BR)", :pob, :pb),
|
514
|
+
mne: Language.new("Montenegrin", :mne, :me),
|
515
|
+
zht: Language.new("Chinese (traditional)", :zht, :zt),
|
516
|
+
zhe: Language.new("Chinese bilingual", :zhe, :ze),
|
517
|
+
pom: Language.new("Portuguese (MZ)", :pom, :pm),
|
518
|
+
ext: Language.new("Extremaduran", :ext, :ex)
|
519
|
+
}
|
520
|
+
end
|
521
|
+
|
522
|
+
ENGLISH = database[:eng]
|
523
|
+
SPANISH = database[:spa]
|
524
|
+
FRENCH = database[:fre]
|
525
|
+
ITALIAN = database[:ita]
|
526
|
+
SWEDISH = database[:swe]
|
527
|
+
TURKISH = database[:tur]
|
528
|
+
RUSSIAN = database[:rus]
|
529
|
+
GREEK = database[:ell]
|
530
|
+
DUTCH = database[:dut]
|
531
|
+
PORTUGUESE = database[:por]
|
532
|
+
CHINESE = database[:chi]
|
533
|
+
JAPANESE = database[:jpn]
|
534
|
+
GERMAN = database[:ger]
|
535
|
+
ARABIC = database[:ara]
|
536
|
+
ROMANIAN = database[:rum]
|
537
|
+
end
|
538
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Subs
|
2
|
+
class OpenSubtitles < Provider
|
3
|
+
|
4
|
+
include HashSearcher
|
5
|
+
include LoginProvider
|
6
|
+
include FilenameSearcher
|
7
|
+
include IMDbSearcher
|
8
|
+
include CredentialProvider
|
9
|
+
|
10
|
+
def initialize(username = nil, password = nil)
|
11
|
+
require 'xmlrpc/client'
|
12
|
+
super('OpenSubtitles.org', URI('https://api.opensubtitles.org:443/xml-rpc'), 'subs2')
|
13
|
+
@client = XMLRPC::Client.new2(@uri)
|
14
|
+
Subs.log.debug { "Connected to #{@name.blue} using token '#{@token}'" } if login(username, password)
|
15
|
+
if block_given?
|
16
|
+
yield self
|
17
|
+
logout
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def login(username = nil, password = nil)
|
22
|
+
password = Digest::MD5.hexdigest(password) if username && password
|
23
|
+
begin
|
24
|
+
response = @client.call(:LogIn, username || '', password || '', 'en', @user_agent)
|
25
|
+
code = response['code'].to_i
|
26
|
+
if code == 501
|
27
|
+
Subs.log.error { 'Server is currently under maintenance, try again later,'.yellow }
|
28
|
+
elsif code == 401
|
29
|
+
Subs.log.warn { "Failed to login to #{@name.blue}" }
|
30
|
+
end
|
31
|
+
@token = response['token']
|
32
|
+
return @token && @token.size > 0
|
33
|
+
rescue
|
34
|
+
Subs.log.error { "Failed to connect to #{@name.blue}" }
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def logout
|
40
|
+
@client.call(:LogOut, @token) rescue nil
|
41
|
+
Subs.log.debug { "Disconnected from #{@name.blue}" }
|
42
|
+
end
|
43
|
+
|
44
|
+
def process_result(io, result)
|
45
|
+
return false unless super
|
46
|
+
begin
|
47
|
+
# Use a string buffer for downloaded data to eliminate need for storing compressed file on disk
|
48
|
+
StringIO.open do |buffer|
|
49
|
+
open(result.data, "rb") { |src| buffer.write(src.read) }
|
50
|
+
buffer.seek(0, IO::SEEK_SET)
|
51
|
+
# Read the buffer and copy the decompressed GZIP stream to the output stream
|
52
|
+
gz = Zlib::GzipReader.new(buffer)
|
53
|
+
io.write(gz.read)
|
54
|
+
gz.close
|
55
|
+
end
|
56
|
+
Subs.log.debug { 'Success'.green }
|
57
|
+
return true
|
58
|
+
rescue
|
59
|
+
Subs.log.debug { 'Failed'.red }
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def compute_hash(path)
|
65
|
+
hash = File.size(path)
|
66
|
+
File.open(path, 'rb') do |io|
|
67
|
+
hash += io.read(65536).unpack('Q*').sum
|
68
|
+
io.seek(-65536, IO::SEEK_END)
|
69
|
+
hash += io.read(65536).unpack('Q*').sum
|
70
|
+
end
|
71
|
+
(hash & 0xFFFFFFFFFFFFFFFF).to_s(16).rjust(16, '0')
|
72
|
+
end
|
73
|
+
|
74
|
+
def hash_search(path, *languages)
|
75
|
+
unless File.exist?(path)
|
76
|
+
Subs.log.error { "Cannot search, cannot find '#{path}'" }
|
77
|
+
return []
|
78
|
+
end
|
79
|
+
lang = languages.map(&:alpha3).join(',')
|
80
|
+
hash = compute_hash(path)
|
81
|
+
Subs.log.debug { "Searching #{@name.blue} by hash using '#{hash}'" }
|
82
|
+
size = File.size(path)
|
83
|
+
params = { moviehash: hash, moviebytesize: size, sublanguageid: lang }
|
84
|
+
search(path, params)
|
85
|
+
end
|
86
|
+
|
87
|
+
def filename_search(path, *languages)
|
88
|
+
unless File.exist?(path)
|
89
|
+
Subs.log.error { "Cannot search, cannot find '#{path}'" }
|
90
|
+
return []
|
91
|
+
end
|
92
|
+
movie = fuzzy_search(path)
|
93
|
+
return [] unless movie
|
94
|
+
imdb_search(path, movie.imdb, *languages)
|
95
|
+
end
|
96
|
+
|
97
|
+
def imdb_search(path, imdb_id, *languages)
|
98
|
+
lang = languages.map(&:alpha3).join(',')
|
99
|
+
Subs.log.debug { "Searching #{@name.blue} by IMDb ID using '#{imdb_id}'" }
|
100
|
+
params = { imdbid: imdb_id, sublanguageid: lang }
|
101
|
+
search(path, params)
|
102
|
+
end
|
103
|
+
|
104
|
+
def search(path, *criteria)
|
105
|
+
@limit ||= { limit: 10 }
|
106
|
+
results = []
|
107
|
+
begin
|
108
|
+
response = @client.call(:SearchSubtitles, @token, criteria, @limit)
|
109
|
+
if response['status'] == '200 OK'
|
110
|
+
response['data'].each do |result|
|
111
|
+
name = result['SubFileName']
|
112
|
+
language = Subs::Language.from_alpha3(result['SubLanguageID'])
|
113
|
+
link = result['SubDownloadLink']
|
114
|
+
results << Subs::SearchResult.new(@name, self.class, name, language, path, link)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
Subs.log.debug { "Found #{results.size.to_s.light_blue} result(s)." }
|
118
|
+
return results
|
119
|
+
rescue
|
120
|
+
Subs.log.error { "An error occurred processing request." }
|
121
|
+
return []
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def fuzzy_search(query)
|
126
|
+
q = File.exist?(query) ? File.basename(query) : query
|
127
|
+
Subs.log.debug { "Performing fuzzy search using '#{q}'" }
|
128
|
+
begin
|
129
|
+
response = @client.call(:GuessMovieFromString, @token, [query])
|
130
|
+
result = response['data'].first.last['BestGuess']
|
131
|
+
name = result['MovieName']
|
132
|
+
year = result['MovieYear'].to_i
|
133
|
+
imdb = result['IDMovieIMDB']
|
134
|
+
Subs.log.debug { 'Success'.green }
|
135
|
+
return Subs::Movie.new(name, year, imdb)
|
136
|
+
rescue
|
137
|
+
Subs.log.debug { "Failed".red }
|
138
|
+
return nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|