quran 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/quran +87 -0
- data/lib/quran.rb +203 -0
- data/test/test_quran.rb +64 -0
- metadata +49 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 3f16d5355bc2fa0ee3f25669659dfb617c96336c
|
|
4
|
+
data.tar.gz: 2f741da1a905f1fd5a549035c1b100e376b4588c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f6696aac44dc080cd13ac4a9a4ab537ffc19a1874261f9224c3123e7f7d48ba25ba08328357eb8c545894addc325887f0c3bbede49e974edb38a55a53ef950b3
|
|
7
|
+
data.tar.gz: 66257e91cd7b2b94aa0aa44bb9955194d87b7ec951bce95b70d13a700c312ea40743d17d528fd377b7b24390986f2c0e995b1f073f62579bc39344ecd8bb2945
|
data/bin/quran
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'optparse'
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'quran'
|
|
5
|
+
|
|
6
|
+
quran = Quran.new ['en']
|
|
7
|
+
|
|
8
|
+
options = {:find => nil, :juz => nil, :search => nil}
|
|
9
|
+
|
|
10
|
+
first_argument = ARGV[0]
|
|
11
|
+
possible_commands = ['find', 'juz', 'search']
|
|
12
|
+
|
|
13
|
+
def get_chapter_and_verse(val)
|
|
14
|
+
chapter, verse = val.split(":")
|
|
15
|
+
ret = []
|
|
16
|
+
|
|
17
|
+
if not chapter.nil?
|
|
18
|
+
ret << chapter.to_i
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if not verse.nil? and not chapter.empty?
|
|
22
|
+
ret << verse.to_i
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
ret
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get_or_find_arg(options, option)
|
|
29
|
+
val = options[option]
|
|
30
|
+
if options[option].nil?
|
|
31
|
+
second_arg = ARGV[1]
|
|
32
|
+
if not second_arg.nil?
|
|
33
|
+
val = second_arg
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
val
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
parser = OptionParser.new do|opts|
|
|
41
|
+
opts.banner = "Usage: quran [command=['find', 'juz', 'search']] [options]"
|
|
42
|
+
|
|
43
|
+
opts.on('-f', '--find chapter_number:verse_number', 'Find {ChapterNumber}:{VerseNumber}') do |find|
|
|
44
|
+
options[:find] = find;
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
opts.on('-j', '--juz number', 'Juz Number') do |juz|
|
|
48
|
+
options[:juz] = juz;
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
opts.on('-s', '--search term', 'Search term or phrase') do |search|
|
|
52
|
+
options[:search] = search;
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
opts.on('-h', '--help', 'Displays Help') do
|
|
56
|
+
puts opts
|
|
57
|
+
exit
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if first_argument.nil? or not possible_commands.include? first_argument
|
|
61
|
+
puts opts
|
|
62
|
+
exit
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
parser.parse!
|
|
66
|
+
|
|
67
|
+
output = {}
|
|
68
|
+
# Check what first arg is. Depending on that call the appropriate method.
|
|
69
|
+
if first_argument == 'find'
|
|
70
|
+
val = get_or_find_arg(options, 'find')
|
|
71
|
+
chapter, verse = get_chapter_and_verse(val)
|
|
72
|
+
|
|
73
|
+
if chapter and verse
|
|
74
|
+
output = quran.get(chapter, verse)
|
|
75
|
+
elsif chapter
|
|
76
|
+
output = quran.get_chapter(chapter)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
elsif first_argument == 'juz'
|
|
80
|
+
val = get_or_find_arg(options, 'juz')
|
|
81
|
+
output = quran.juz(val.to_i)
|
|
82
|
+
elsif first_argument == 'search'
|
|
83
|
+
val = get_or_find_arg(options, 'search')
|
|
84
|
+
output = quran.search(val)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
puts JSON.pretty_generate(output)
|
data/lib/quran.rb
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# The Main Quran class that allows querying.
|
|
2
|
+
#
|
|
3
|
+
# @todo: I eventually want to have a Translator class that can
|
|
4
|
+
# abstract different translations once we can find them. That
|
|
5
|
+
# way, a user can query and retrive different translations and
|
|
6
|
+
# tafsirs of a verse.
|
|
7
|
+
#
|
|
8
|
+
# @author Zohaib Ahmed
|
|
9
|
+
# @since 0.0.1
|
|
10
|
+
class Quran
|
|
11
|
+
require "sqlite3"
|
|
12
|
+
|
|
13
|
+
# Initialize the Quran with the language(s) specified.
|
|
14
|
+
#
|
|
15
|
+
# @param langs [Array]
|
|
16
|
+
#
|
|
17
|
+
# @example
|
|
18
|
+
# quran = Quran.new ['en', 'ar']
|
|
19
|
+
def initialize(langs=['ar'])
|
|
20
|
+
db = SQLite3::Database.new "lib/qurandb"
|
|
21
|
+
db.results_as_hash = true
|
|
22
|
+
|
|
23
|
+
@chapters = construct_dict(db, 'chapters', 'id')
|
|
24
|
+
@languages = {}
|
|
25
|
+
@default_lang = langs[0]
|
|
26
|
+
|
|
27
|
+
possible_langs = ['en', 'ar', 'hi', 'uz', 'ur']
|
|
28
|
+
langs.each do |lang|
|
|
29
|
+
if possible_langs.include? lang
|
|
30
|
+
@languages[lang] = construct_dict(db, lang, 'chapter')
|
|
31
|
+
else
|
|
32
|
+
raise "The language you asked for isn't supported yet."
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
@juz = [
|
|
37
|
+
{:name => "Alif-Lam-Mim", :start_chapter => 1, :start_verse => 1, :end_chapter => 2, :end_verse => 141},
|
|
38
|
+
{:name => "Sayaqūl", :start_chapter => 2, :start_verse => 142, :end_chapter => 2, :end_verse => 252},
|
|
39
|
+
{:name => "Tilka -r-rusul", :start_chapter => 2, :start_verse => 253, :end_chapter => 3, :end_verse => 92},
|
|
40
|
+
{:name => "Lan Tana Lu", :start_chapter => 3, :start_verse => 93, :end_chapter => 4, :end_verse => 23},
|
|
41
|
+
{:name => "W-al-muḥṣanāt", :start_chapter => 4, :start_verse => 24, :end_chapter => 4, :end_verse => 147},
|
|
42
|
+
{:name => "Lā yuẖibbu-llāh", :start_chapter => 4, :start_verse => 148, :end_chapter => 5, :end_verse => 81},
|
|
43
|
+
{:name => "Wa ʾidha samiʿū", :start_chapter => 5, :start_verse => 82, :end_chapter => 6, :end_verse => 110},
|
|
44
|
+
{:name => "Wa law ʾannanā", :start_chapter => 6, :start_verse => 111, :end_chapter => 7, :end_verse => 87},
|
|
45
|
+
{:name => "Qāl al-malāʾ", :start_chapter => 7, :start_verse => 88, :end_chapter => 8, :end_verse => 40},
|
|
46
|
+
{:name => "W-aʿlamū", :start_chapter => 8, :start_verse => 41, :end_chapter => 9, :end_verse => 92},
|
|
47
|
+
{:name => "Yaʾtadhirūna", :start_chapter => 9, :start_verse => 93, :end_chapter => 11, :end_verse => 5},
|
|
48
|
+
{:name => "Wa mā min dābbah", :start_chapter => 11, :start_verse => 6, :end_chapter => 12, :end_verse => 52},
|
|
49
|
+
{:name => "Wa mā ʾubarriʾu", :start_chapter => 12, :start_verse => 53, :end_chapter => 14, :end_verse => 52},
|
|
50
|
+
{:name => "ʾAlif Lām Rāʾ", :start_chapter => 15, :start_verse => 1, :end_chapter => 16, :end_verse => 128},
|
|
51
|
+
{:name => "Subḥāna -lladhi", :start_chapter => 17, :start_verse => 1, :end_chapter => 18, :end_verse => 74},
|
|
52
|
+
{:name => "Qāla ʾa-lam", :start_chapter => 18, :start_verse => 75, :end_chapter => 20, :end_verse => 135},
|
|
53
|
+
{:name => "Aqtaraba li-n-nās", :start_chapter => 21, :start_verse => 1, :end_chapter => 22, :end_verse => 78},
|
|
54
|
+
{:name => "Qad ʾaflaḥa", :start_chapter => 23, :start_verse => 1, :end_chapter => 25, :end_verse => 20},
|
|
55
|
+
{:name => "Wa-qāla -lladhīna", :start_chapter => 25, :start_verse => 21, :end_chapter => 27, :end_verse => 55},
|
|
56
|
+
{:name => "Am-man khalaq", :start_chapter => 27, :start_verse => 56, :end_chapter => 29, :end_verse => 45},
|
|
57
|
+
{:name => "Utlu ma uhiya", :start_chapter => 29, :start_verse => 46, :end_chapter => 33, :end_verse => 30},
|
|
58
|
+
{:name => "Wa-man yaqnut", :start_chapter => 33, :start_verse => 31, :end_chapter => 36, :end_verse => 27},
|
|
59
|
+
{:name => "Wa-mā-liya", :start_chapter => 36, :start_verse => 28, :end_chapter => 39, :end_verse => 31},
|
|
60
|
+
{:name => "Fa-man ʾaẓlamu", :start_chapter => 39, :start_verse => 21, :end_chapter => 41, :end_verse => 46},
|
|
61
|
+
{:name => "ʾIlaihi yuraddu", :start_chapter => 41, :start_verse => 47, :end_chapter => 45, :end_verse => 37},
|
|
62
|
+
{:name => "Ḥāʾ Mīm", :start_chapter => 46, :start_verse => 1, :end_chapter => 51, :end_verse => 30},
|
|
63
|
+
{:name => "Qāla fa-mā khatbukum", :start_chapter => 51, :start_verse => 31, :end_chapter => 57, :end_verse => 29},
|
|
64
|
+
{:name => "Qad samiʿa -llāhu", :start_chapter => 58, :start_verse => 1, :end_chapter => 66, :end_verse => 12},
|
|
65
|
+
{:name => "Tabāraka -lladhi", :start_chapter => 67, :start_verse => 1, :end_chapter => 77, :end_verse => 50},
|
|
66
|
+
{:name => "Fa-man ʾaẓlamu", :start_chapter => 78, :start_verse => 1, :end_chapter => 114, :end_verse => 6}
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
return
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Initialize the Quran with the language(s) specified.
|
|
73
|
+
#
|
|
74
|
+
# @param chapter [String]
|
|
75
|
+
#
|
|
76
|
+
#
|
|
77
|
+
# @example
|
|
78
|
+
# quran = Quran.new ['en', 'ar']
|
|
79
|
+
def get(chapter, verse, lang=@default_lang)
|
|
80
|
+
if verse.nil?
|
|
81
|
+
raise "Verse does not exist."
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
if verse < 1
|
|
85
|
+
raise "Verse does not exist."
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
verses = @languages[lang][chapter]
|
|
89
|
+
|
|
90
|
+
if verses.nil?
|
|
91
|
+
raise "Chapter does not exist"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
row = verses[verse - 1]
|
|
95
|
+
|
|
96
|
+
if row.nil?
|
|
97
|
+
raise "Verse does not exist."
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
return row
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Get the contents of the entire chapter.
|
|
104
|
+
#
|
|
105
|
+
# @param chapter [Integer] the chapter number
|
|
106
|
+
# @param lang [String] the language for the content
|
|
107
|
+
#
|
|
108
|
+
# @return [Array] Array of hashes containing verses in the chapter
|
|
109
|
+
def get_chapter(chapter, lang=@default_lang)
|
|
110
|
+
return @languages[lang][chapter]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# Get the details for a particular Juz
|
|
115
|
+
#
|
|
116
|
+
# @param juz_number [Integer] the juz number
|
|
117
|
+
#
|
|
118
|
+
# @return [Hash] details of the Juz
|
|
119
|
+
def juz(juz_number)
|
|
120
|
+
return @juz[juz_number]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# Return a list of hashes containing the verses that the search term
|
|
125
|
+
# appears in.
|
|
126
|
+
#
|
|
127
|
+
# @todo Add support for other languages here.
|
|
128
|
+
# @todo Find a way to do more of a fuzzy search of a phrase as a term
|
|
129
|
+
# For example, the verse:
|
|
130
|
+
# "Allah does not impose upon any soul a duty but to the extent of its ability"
|
|
131
|
+
# should be returned if the term was "impose any soul"
|
|
132
|
+
#
|
|
133
|
+
# @param term [String] the search term
|
|
134
|
+
# @param lang [String] the language for the content
|
|
135
|
+
#
|
|
136
|
+
# @return [Array] Search results
|
|
137
|
+
def search(term, lang=@default_lang)
|
|
138
|
+
ret = []
|
|
139
|
+
(1..114).each do |chapter|
|
|
140
|
+
verses = get_chapter(chapter, lang)
|
|
141
|
+
|
|
142
|
+
verses.each do |v|
|
|
143
|
+
if v[lang].include? term
|
|
144
|
+
ret << v
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
return ret
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
# Construct a dict from a table in the db. The key is specified in key.
|
|
154
|
+
# The values will be a dict that contains the rest of the columns in the table.
|
|
155
|
+
#
|
|
156
|
+
# @param db [SQLite3]
|
|
157
|
+
# @param table [String]
|
|
158
|
+
# @param key [String]
|
|
159
|
+
#
|
|
160
|
+
# @return [Hash]
|
|
161
|
+
def construct_dict(db, table, key)
|
|
162
|
+
query_str = "SELECT * FROM #{table}"
|
|
163
|
+
final_hash = {}
|
|
164
|
+
db.execute(query_str) do |row|
|
|
165
|
+
hash_key = row[key]
|
|
166
|
+
# get all the values
|
|
167
|
+
vals = {}
|
|
168
|
+
row.keys.each do |other_key|
|
|
169
|
+
# if the other_key is a type string, take it, otherwise ignore.
|
|
170
|
+
if other_key.is_a? String
|
|
171
|
+
vals[other_key] = row[other_key]
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
if final_hash.has_key?(hash_key)
|
|
176
|
+
final_hash[hash_key] << vals
|
|
177
|
+
else
|
|
178
|
+
final_hash[hash_key] = [vals]
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
return final_hash
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
#
|
|
187
|
+
# Extending the Array class.
|
|
188
|
+
#
|
|
189
|
+
# @author [zohaibahmed]
|
|
190
|
+
#
|
|
191
|
+
class Array
|
|
192
|
+
# Search if search value is in string
|
|
193
|
+
# @param search_value [String]
|
|
194
|
+
# @param regex_format = '%s' [String]
|
|
195
|
+
#
|
|
196
|
+
# @return [type] [description]
|
|
197
|
+
def fuzzy_include?(search_value, regex_format = '%s')
|
|
198
|
+
inject(false) do |is_found, array_value|
|
|
199
|
+
is_found or !!(search_value =~ /#{regex_format % array_value}/)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
end
|
data/test/test_quran.rb
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'minitest/autorun'
|
|
2
|
+
require 'quran'
|
|
3
|
+
|
|
4
|
+
class QuranTest < MiniTest::Unit::TestCase
|
|
5
|
+
def setup
|
|
6
|
+
@q = Quran.new ['en']
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_get
|
|
10
|
+
# Get Valid Verses
|
|
11
|
+
assert_equal "In the name of Allah, the Beneficent, the Merciful.",
|
|
12
|
+
@q.get(1,1)['en']
|
|
13
|
+
|
|
14
|
+
assert_equal "And when there are present at the division the relatives and the orphans and the needy, give them (something) out of it and speak to them kind words.",
|
|
15
|
+
@q.get(4, 8)['en']
|
|
16
|
+
|
|
17
|
+
# Verse not found
|
|
18
|
+
assert_raises(RuntimeError) {
|
|
19
|
+
@q.get(2, -1)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# Chapter not found
|
|
23
|
+
assert_raises(RuntimeError) {
|
|
24
|
+
@q.get(300,200)['en']
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_get_chapter
|
|
29
|
+
assert_equal 7,
|
|
30
|
+
@q.get_chapter(1).length
|
|
31
|
+
|
|
32
|
+
assert_equal nil,
|
|
33
|
+
@q.get_chapter(444)
|
|
34
|
+
|
|
35
|
+
assert_equal nil,
|
|
36
|
+
@q.get_chapter(-2)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_juz
|
|
40
|
+
assert_equal "Sayaqūl",
|
|
41
|
+
@q.juz(1)[:name]
|
|
42
|
+
|
|
43
|
+
assert_equal 4,
|
|
44
|
+
@q.juz(5)[:start_chapter]
|
|
45
|
+
|
|
46
|
+
assert_equal nil,
|
|
47
|
+
@q.juz(66)
|
|
48
|
+
|
|
49
|
+
# Second last
|
|
50
|
+
assert_equal "Tabāraka -lladhi",
|
|
51
|
+
@q.juz(-2)[:name]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_search
|
|
55
|
+
assert_equal 15,
|
|
56
|
+
@q.search("happy").length
|
|
57
|
+
|
|
58
|
+
assert_equal 52,
|
|
59
|
+
@q.search("isa").length
|
|
60
|
+
|
|
61
|
+
assert_equal 0,
|
|
62
|
+
@q.search("potatoes").length
|
|
63
|
+
end
|
|
64
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: quran
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Zohaib Ahmed
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-02-07 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Ruby interface to the Quran.
|
|
14
|
+
email: zohaib@rocketfuse.com
|
|
15
|
+
executables:
|
|
16
|
+
- quran
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- lib/quran.rb
|
|
21
|
+
- test/test_quran.rb
|
|
22
|
+
- bin/quran
|
|
23
|
+
homepage: http://rubygems.org/gems/quran
|
|
24
|
+
licenses:
|
|
25
|
+
- MIT
|
|
26
|
+
metadata: {}
|
|
27
|
+
post_install_message:
|
|
28
|
+
rdoc_options: []
|
|
29
|
+
require_paths:
|
|
30
|
+
- lib
|
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
32
|
+
requirements:
|
|
33
|
+
- - '>='
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '0'
|
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
requirements: []
|
|
42
|
+
rubyforge_project:
|
|
43
|
+
rubygems_version: 2.0.14
|
|
44
|
+
signing_key:
|
|
45
|
+
specification_version: 4
|
|
46
|
+
summary: Gem for the Quran
|
|
47
|
+
test_files:
|
|
48
|
+
- test/test_quran.rb
|
|
49
|
+
has_rdoc:
|