subs 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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