Skip to content

Commit

Permalink
Merge pull request #658 from quran/add-filter-by-range-api
Browse files Browse the repository at this point in the history
Add filter by range api
  • Loading branch information
osamasayed authored Apr 3, 2024
2 parents a2f86b4 + 6b287be commit b6b44ba
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 14 deletions.
4 changes: 4 additions & 0 deletions app/controllers/api/qdc/verses_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ module Api::Qdc
class VersesController < Api::V4::VersesController
before_action :init_presenter

def by_range
render partial: 'verses'
end

protected
def init_presenter
@presenter = Qdc::VersesPresenter.new(params, action_name)
Expand Down
45 changes: 32 additions & 13 deletions app/finders/qdc/verse_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,21 @@ def fix_verses_order(verses)
end

def fetch_verses_range(filter, mushaf: nil, words: false)
# both from and to could be ayah key or ayah ID(not ayah number)
params[:from] = get_ayah_id(params[:from])
params[:to] = get_ayah_id(params[:to])

if 'by_page' == filter
@results = fetch_by_page(mushaf: mushaf, words: words)
elsif 'by_juz' == filter
@results = fetch_by_juz(mushaf: mushaf)
if 'by_range' == filter
@results = fetch_by_range
else
@results = send("fetch_#{filter}")
# TODO: we need to validate from and to before passing it to get_ayah_id. Currently "from"=>"testFrom:1", "to"=>"testTo:5" gets converted to "from"=>6231, "to"=>6235. {@see fetch_by_range}
# both from and to could be ayah key or ayah ID(not ayah number)
params[:from] = get_ayah_id(params[:from])
params[:to] = get_ayah_id(params[:to])

if 'by_page' == filter
@results = fetch_by_page(mushaf: mushaf, words: words)
elsif 'by_juz' == filter
@results = fetch_by_juz(mushaf: mushaf)
else
@results = send("fetch_#{filter}")
end
end
end

Expand Down Expand Up @@ -210,10 +215,24 @@ def fetch_by_ruku
end

def fetch_by_range
# 1. make sure both from and to are present
raise(RestApi::RecordNotFound.new("From and to must be present.")) unless params[:from] && params[:to]
from_range = QuranUtils::VerseKey.new(params[:from])
from_verse_key_data = from_range.process_verse_key
to_range = QuranUtils::VerseKey.new(params[:to])
to_verse_key_data = to_range.process_verse_key
# 2. make sure from and to are in the format of 'chapter:verse' e.g. don't accept from=test&to=anotherTest
raise(RestApi::RecordNotFound.new("Verse key contains invalid data")) if from_verse_key_data.empty? || to_verse_key_data.empty?
# 3. make sure from and to have both chapter and verse. e.g. don't allow testFrom:1&to=testTo:5
raise(RestApi::RecordNotFound.new("Verse key contains invalid data")) unless from_verse_key_data.all? && to_verse_key_data.all?
params[:from] = get_ayah_id(params[:from])
params[:to] = get_ayah_id(params[:to])
# 4. make sure from and to Ids are not nil. Either can be nil if the verse key contains out of range values e.g. 1:8 or 500:1
raise(RestApi::RecordNotFound.new("Verse key contains out of range values")) if params[:from].nil? || params[:to].nil?
# 5. make sure from is smaller than to. An invalid range e.g. from=1:7&to=1:4
raise(RestApi::RecordNotFound.new("From should be smaller than to")) if params[:from] > params[:to]
from, to = get_ayah_range_to_load(params[:from], params[:to])

@results = rescope_verses('verse_index')
.where('verses.verse_index >= ? AND verses.verse_index <= ?', from, to)
@results = rescope_verses('verse_index').where('verses.verse_index >= ? AND verses.verse_index <= ?', from, to)
end

def load_words(word_translation_lang, mushaf)
Expand Down Expand Up @@ -309,4 +328,4 @@ def load_verse_to(default_to)
default_to
end
end
end
end
25 changes: 25 additions & 0 deletions app/lib/quran_utils/verse_key.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module QuranUtils
class VerseKey
include QuranUtils::StrongMemoize
VERSE_KEY_REGEX = /(?<chapter>\d+):?(?<verse>\d+)?/

def initialize(verse_key)
@verse_key = verse_key
end

def process_verse_key
strong_memoize :process_verse_key do
match = @verse_key.match(VERSE_KEY_REGEX)

return [] if match.nil?

chapter = match[:chapter]
verse = match[:verse]

[chapter, verse]
end
end
end
end
4 changes: 3 additions & 1 deletion app/presenters/qdc/mushaf_page_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ def look_up_filter
'by_hizb'
elsif params[:ruku_number].present?
'ruku_number'
elsif params[:from].present? && params[:to].present?
'by_range'
else
raise_404 "Look up filter is invalid, please provide a valid filter(chapter_number, juz_number, page_number, manzil_number, rub_el_hizb_number, hizb_number, ruku_number)"
end
end
end
end
end
end
1 change: 1 addition & 0 deletions config/routes/api/qdc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
get 'by_hizb/:hizb_number', action: 'by_hizb'
get 'by_ruku/:ruku_number', action: 'by_ruku'
get 'by_key/:verse_key', action: 'by_key'
get 'by_range', action: 'by_range'

get :filter

Expand Down

0 comments on commit b6b44ba

Please sign in to comment.