From 42307829be9c7600e40a4b69c09221da6d8dde09 Mon Sep 17 00:00:00 2001 From: Mohamed El Mahallawy Date: Wed, 18 Jan 2017 22:15:40 -0800 Subject: [PATCH] V2.2.0 (#84) * Create LICENSE.md * media models * Dump 14 * unneeded code * do not add db * Media content in API * submodule update * Time to move surah info into database (#79) * time to move surah info into database * retrun info wrt to language * surah infos * no more tafsir search * Segments and Surah info apis * Upgrade ruby to 2.3.1 * fixed specs and added check for audio availability (#81) --- .gitignore | 2 +- .travis.yml | 2 +- Dockerfile | 8 ++--- Gemfile | 4 +-- Gemfile.lock | 9 +++-- LICENSE.md | 21 ++++++++++++ .../concerns/language_detection.rb | 3 +- app/controllers/v2/ayahs_controller.rb | 1 + app/controllers/v2/surahs_controller.rb | 9 +++++ app/models/audio/file.rb | 22 ++++++------- app/models/content/resource.rb | 6 ---- app/models/content/surah_info.rb | 27 +++++++++++++++ app/models/media.rb | 5 +++ app/models/media/content.rb | 23 +++++++++++++ app/models/media/resource.rb | 17 ++++++++++ app/models/quran/ayah.rb | 9 +++-- app/models/quran/surah.rb | 7 ++++ app/models/search/query/indices.rb | 5 ++- config/routes.rb | 8 +++++ db | 2 +- docker/backend.quran.com | 2 +- lib/tasks/segments.rake | 33 +++++++++++++++++++ spec/controllers/v2/ayahs_controller_spec.rb | 2 +- spec/controllers/v2/surahs_controller_spec.rb | 12 +++++++ spec/models/content/surah_info_spec.rb | 17 ++++++++++ spec/models/media/content_spec.rb | 16 +++++++++ spec/models/media/resource_spec.rb | 17 ++++++++++ 27 files changed, 251 insertions(+), 38 deletions(-) create mode 100644 LICENSE.md create mode 100644 app/models/content/surah_info.rb create mode 100644 app/models/media.rb create mode 100644 app/models/media/content.rb create mode 100644 app/models/media/resource.rb create mode 100644 lib/tasks/segments.rake create mode 100644 spec/models/content/surah_info_spec.rb create mode 100644 spec/models/media/content_spec.rb create mode 100644 spec/models/media/resource_spec.rb diff --git a/.gitignore b/.gitignore index 29a3c537..f123ccf9 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,6 @@ config/deploy.rb vendor/cache vendor/bundle/ -db/structure.sql +db dump.rdb passenger.* diff --git a/.travis.yml b/.travis.yml index 0868a1e2..0cbd12e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ git: submodules: false rvm: - - 2.2.3 + - 2.3.1 cache: bundler diff --git a/Dockerfile b/Dockerfile index 79339f8c..b1d31794 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM phusion/passenger-customizable:0.9.17 +FROM phusion/passenger-customizable:0.9.19 # set correct environment variables ENV HOME /root @@ -7,14 +7,14 @@ ENV HOME /root CMD ["/sbin/my_init"] # customizing passenger-customizable image -RUN /pd_build/ruby2.2.sh +RUN /pd_build/ruby-2.3.*.sh RUN /pd_build/redis.sh ENV RAILS_ENV production # native passenger -RUN ruby2.2 -S passenger-config build-native-support -RUN setuser app ruby2.2 -S passenger-config build-native-support +RUN ruby2.3 -S passenger-config build-native-support +RUN setuser app ruby2.3 -S passenger-config build-native-support # nginx RUN rm /etc/service/nginx/down diff --git a/Gemfile b/Gemfile index f4c2bb5c..eb7d3468 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,12 @@ source 'https://rubygems.org' - +ruby '2.3.1' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' #gem 'rails', '4.1.1' gem 'rails', '4.2.6' # Use postgresql as the database for Active Record -gem 'pg', '~> 0.18.2' +gem 'pg', '~> 0.19.0' # See https://github.com/sstephenson/execjs#readme for more supported runtimes gem 'execjs' gem 'therubyracer', platforms: :ruby diff --git a/Gemfile.lock b/Gemfile.lock index 67b764c4..d3b9bed2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -178,7 +178,7 @@ GEM parallel (1.8.0) parallel_tests (2.5.0) parallel - pg (0.18.4) + pg (0.19.0) posix-spawn (0.3.11) prose (0.2.2) pry (0.9.12.6) @@ -344,7 +344,7 @@ DEPENDENCIES oj_mimic_json parallel parallel_tests - pg (~> 0.18.2) + pg (~> 0.19.0) prose pry-byebug pry-rails @@ -364,5 +364,8 @@ DEPENDENCIES whatlanguage zeus +RUBY VERSION + ruby 2.3.1 + BUNDLED WITH - 1.11.2 + 1.13.6 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..d932105e --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Quran.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/controllers/concerns/language_detection.rb b/app/controllers/concerns/language_detection.rb index 910c1c34..c45eba8e 100644 --- a/app/controllers/concerns/language_detection.rb +++ b/app/controllers/concerns/language_detection.rb @@ -22,7 +22,8 @@ module LanguageDetection :portuguese => :pt, :russian => :ru, :spanish => :es, - :swedish => :sv + :swedish => :sv, + :urdu => :ur } def indices_boost diff --git a/app/controllers/v2/ayahs_controller.rb b/app/controllers/v2/ayahs_controller.rb index 5bf3ebae..0fa5ac20 100644 --- a/app/controllers/v2/ayahs_controller.rb +++ b/app/controllers/v2/ayahs_controller.rb @@ -14,6 +14,7 @@ def index ayahs = Quran::Ayah .preload(glyphs: {word: [:corpus, :token]}) .preload(:text_tashkeel) + .preload(:media_content) .by_range(params[:surah_id], range[0], range[1]) ayahs.as_json_with_resources(ayahs, params) diff --git a/app/controllers/v2/surahs_controller.rb b/app/controllers/v2/surahs_controller.rb index 2a867574..121919cf 100644 --- a/app/controllers/v2/surahs_controller.rb +++ b/app/controllers/v2/surahs_controller.rb @@ -21,6 +21,15 @@ def show render json: surah end + api :GET, '/v2/surahs/:id/info', 'Get a details of specific Surah' + api_version '2.0' + param :id, :number + def info + surah_info = Quran::Surah.find(surah_params).get_surah_info_for_language(params[:lang]) + + render json: surah_info.as_json + end + private def surah_params diff --git a/app/models/audio/file.rb b/app/models/audio/file.rb index ee9d8647..b2f2ba53 100644 --- a/app/models/audio/file.rb +++ b/app/models/audio/file.rb @@ -2,16 +2,16 @@ # # Table name: audio.file # -# file_id :integer not null, primary key -# recitation_id :integer not null -# ayah_key :text not null -# format :text not null -# duration :float -# mime_type :text not null -# is_enabled :boolean default(TRUE), not null -# url :text -# segments :text -# encrypted_segments :text +# file_id :integer not null, primary key +# recitation_id :integer not null +# ayah_key :text not null +# format :text not null +# duration :float +# mime_type :text not null +# is_enabled :boolean default(TRUE), not null +# url :text +# segments :text is an Array +# segments_stats :json # class Audio::File < ActiveRecord::Base @@ -31,6 +31,6 @@ def as_json(options = {}) ayah = ayah_key.split(':')[1] - super(only: [:duration, :url, :encrypted_segments]) + super(only: [:duration, :url, :segments]) end end diff --git a/app/models/content/resource.rb b/app/models/content/resource.rb index 1d05a717..a763a821 100644 --- a/app/models/content/resource.rb +++ b/app/models/content/resource.rb @@ -62,12 +62,6 @@ def self.list_language_options .order("language.language_code") end - def self.trial - self.enabled.joins(:language) - .group(language: [:language_code]) - # .order("i18n.language.language_code") - end - def view_json as_json(only: [:name, :description, :is_available, :slug]).merge( language: language_code, diff --git a/app/models/content/surah_info.rb b/app/models/content/surah_info.rb new file mode 100644 index 00000000..0b9f59a0 --- /dev/null +++ b/app/models/content/surah_info.rb @@ -0,0 +1,27 @@ +# == Schema Information +# +# Table name: content.surah_infos +# +# id :integer not null, primary key +# language_code :string +# description :text +# surah_id :integer +# content_source :text +# short_description :text +# + +class Content::SurahInfo < ActiveRecord::Base + extend Content + + self.table_name = 'surah_infos' + self.primary_key = 'id' + + belongs_to :language, class_name: 'Locale::Language', foreign_key: 'language_code' + belongs_to :surah, class_name: 'Quran::Surah' + + validates :language, :surah, presence: true + + def as_json(options = {}) + super(options.merge(only: [:language_code, :description, :content_source, :short_description, :surah_id])) + end +end diff --git a/app/models/media.rb b/app/models/media.rb new file mode 100644 index 00000000..b3c51403 --- /dev/null +++ b/app/models/media.rb @@ -0,0 +1,5 @@ +module Media + include Schema + + Schema.schema_name('Media', 'media') +end diff --git a/app/models/media/content.rb b/app/models/media/content.rb new file mode 100644 index 00000000..6a9e9722 --- /dev/null +++ b/app/models/media/content.rb @@ -0,0 +1,23 @@ +# == Schema Information +# +# Table name: media.content +# +# resource_id :integer not null, primary key +# ayah_key :string primary key +# url :string +# created_at :datetime not null +# updated_at :datetime not null +# + +class Media::Content < ActiveRecord::Base + extend Media + + self.primary_keys = :resource_id, :ayah_key + + belongs_to :resource, class_name: 'Media::Resource' + belongs_to :ayah, class_name: 'Quran::Ayah', foreign_key: 'ayah_key' + + def as_json(options = {}) + super(include: :resource) + end +end diff --git a/app/models/media/resource.rb b/app/models/media/resource.rb new file mode 100644 index 00000000..cc10572e --- /dev/null +++ b/app/models/media/resource.rb @@ -0,0 +1,17 @@ +# == Schema Information +# +# Table name: media.resource +# +# resource_id :integer not null, primary key +# name :string +# url :string +# provider :string +# created_at :datetime not null +# updated_at :datetime not null +# + +class Media::Resource < ActiveRecord::Base + extend Media + + has_many :content +end diff --git a/app/models/quran/ayah.rb b/app/models/quran/ayah.rb index fbbe57da..d41681cd 100644 --- a/app/models/quran/ayah.rb +++ b/app/models/quran/ayah.rb @@ -29,6 +29,9 @@ class Quran::Ayah < ActiveRecord::Base has_many :lemmas, class_name: 'Quran::Lemma', through: :words has_many :roots, class_name: 'Quran::Root', through: :words + has_many :media_resources, class_name: 'Media::Resource', through: :media_content, source: :resource + has_many :media_content, class_name: 'Media::Content', foreign_key: 'ayah_key' + has_many :_tafsir_ayah, class_name: 'Content::TafsirAyah', foreign_key: 'ayah_key' has_many :tafsirs, class_name: 'Content::Tafsir', through: :_tafsir_ayah @@ -92,7 +95,7 @@ def self.as_json_with_resources(ayahs, options = {}) if audio_option = options[:audio] audio = Audio::File - .where(ayah_key: keys, recitation_id: audio_option, is_enabled: true) + .where(ayah_key: keys, recitation_id: audio_option, is_enabled: true, format: 'mp3') .order(:ayah_key) .group_by(&:ayah_key) end @@ -106,11 +109,11 @@ def self.as_json_with_resources(ayahs, options = {}) end ayahs.map do |ayah| - ayah_json = ayah.as_json + ayah_json = ayah.as_json(include: {media_content: {include: :resource}}) ayah_json.merge({ content: content_option && content[ayah.ayah_key] ? content[ayah.ayah_key] : [], - audio: audio_option ? audio[ayah.ayah_key].first : {}, + audio: audio_option && audio[ayah.ayah_key] ? audio[ayah.ayah_key].first : {}, }) end end diff --git a/app/models/quran/surah.rb b/app/models/quran/surah.rb index 5f9ac901..ef463129 100644 --- a/app/models/quran/surah.rb +++ b/app/models/quran/surah.rb @@ -21,6 +21,13 @@ class Quran::Surah < ActiveRecord::Base self.primary_key = 'surah_id' has_many :ayahs, class_name: 'Quran::Ayah', foreign_key: 'surah_id' + has_many :surah_infos, class_name: 'Content::SurahInfo' + + def get_surah_info_for_language(language_code) + language = Locale::Language.find_by_language_code(language_code) || Locale::Language.find('en') + + surah_infos.find_by(language: language) + end def name { diff --git a/app/models/search/query/indices.rb b/app/models/search/query/indices.rb index 28db6095..d009f8c8 100644 --- a/app/models/search/query/indices.rb +++ b/app/models/search/query/indices.rb @@ -4,8 +4,7 @@ module Indices def index_boost if @query.is_arabic? { - 'text-font' => 4, - 'tafsir' => 1 + 'text-font' => 4 } else if @indices_boost @@ -18,7 +17,7 @@ def index_boost def indices if @query.is_arabic? - ['text-font', 'tafsir'] + ['text-font'] else ['trans*', 'text-font'] end diff --git a/config/routes.rb b/config/routes.rb index 096422c8..73276eaa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,6 +7,10 @@ resources :surahs, only: [:index, :show], defaults: { format: 'json' } do resources :ayahs, only: [:index], defaults: { format: 'json' } + + member do + get :info + end end resources :options, only: [], defaults: { format: 'json' } do @@ -29,6 +33,10 @@ resources :surahs, only: [:index, :show], defaults: { format: 'json' } do resources :ayahs, only: [:index], defaults: { format: 'json' } + + member do + get :info + end end resources :options, only: [], defaults: { format: 'json' } do diff --git a/db b/db index f1572602..5dbfe0ac 160000 --- a/db +++ b/db @@ -1 +1 @@ -Subproject commit f15726020ae5df5f5990b0c642b7cd547772feb6 +Subproject commit 5dbfe0acb921cbc5454e86681b84de89cd553c93 diff --git a/docker/backend.quran.com b/docker/backend.quran.com index 1bb36401..a92982cf 100644 --- a/docker/backend.quran.com +++ b/docker/backend.quran.com @@ -8,7 +8,7 @@ server { location / { passenger_enabled on; passenger_user app; - passenger_ruby /usr/bin/ruby2.2; + passenger_ruby /usr/bin/ruby2.3; passenger_app_env production; passenger_max_request_queue_size 200; root /home/app/quran/public; diff --git a/lib/tasks/segments.rake b/lib/tasks/segments.rake new file mode 100644 index 00000000..84e59143 --- /dev/null +++ b/lib/tasks/segments.rake @@ -0,0 +1,33 @@ +# May need this if @cpfair changes the files. +# files = [ +# { recitation_id: 1, filename: 'Abdul_Basit_Mujawwad_128kbps.json' }, +# { recitation_id: 2, filename: 'Abdul_Basit_Murattal_64kbps.json' }, +# { recitation_id: 3, filename: 'Abdurrahmaan_As-Sudais_192kbps.json' }, +# { recitation_id: 4, filename: 'Abu_Bakr_Ash-Shaatree_128kbps.json' }, +# { recitation_id: 5, filename: 'Hani_Rifai_192kbps.json' }, +# { recitation_id: 7, filename: 'Husary_Muallim_128kbps.json' }, +# { recitation_id: 8, filename: 'Alafasy_128kbps.json' }, +# { recitation_id: 9, filename: 'Minshawy_Mujawwad_192kbps.json' }, +# { recitation_id: 10, filename: 'Minshawy_Murattal_128kbps.json' }, +# { recitation_id: 11, filename: 'Saood_ash-Shuraym_128kbps.json' }, +# { recitation_id: 12, filename: 'Mohammad_al_Tablaway_128kbps.json' }, +# { recitation_id: 13, filename: 'Husary_64kbps.json' }, +# ] +# +# +# Parallel.each(files, in_processes: 4, progress: 'Importing segments') do |file| +# begin +# puts file[:filename] +# json = Oj.load_file("../quran-align-data/#{file[:filename]}") +# audio_files = Audio::File.where(recitation_id: file[:recitation_id], segments: nil) +# +# json.each do |ayah_json| +# record = audio_files.find_by(ayah_key: "#{ayah_json['surah']}:#{ayah_json['ayah']}") +# record.update(segments: ayah_json["segments"], segments_stats: ayah_json["stats"]) +# end +# +# rescue Exception => e +# puts e.message +# puts e.backtrace.inspect +# end +# end diff --git a/spec/controllers/v2/ayahs_controller_spec.rb b/spec/controllers/v2/ayahs_controller_spec.rb index d012ce25..a4d8a5ac 100644 --- a/spec/controllers/v2/ayahs_controller_spec.rb +++ b/spec/controllers/v2/ayahs_controller_spec.rb @@ -9,7 +9,7 @@ context "getting surah #{id}" do before { get :index, { surah_id: id, from: 1, to: 30, content: [19], audio: 8 } } - it 'returns http success and returns corret number of ayahs' do + it 'returns http success and returns correct number of ayahs' do expect(response).to have_http_status(:success) if surah.ayat > 30 diff --git a/spec/controllers/v2/surahs_controller_spec.rb b/spec/controllers/v2/surahs_controller_spec.rb index 33e4f91d..6ca6b308 100644 --- a/spec/controllers/v2/surahs_controller_spec.rb +++ b/spec/controllers/v2/surahs_controller_spec.rb @@ -28,4 +28,16 @@ end end + describe 'GET #info' do + before { get :info, { id: 1 } } + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'returns information of first surah' do + expect(response_json['surah_id']).to eql(1) + end + end + end diff --git a/spec/models/content/surah_info_spec.rb b/spec/models/content/surah_info_spec.rb new file mode 100644 index 00000000..287e5189 --- /dev/null +++ b/spec/models/content/surah_info_spec.rb @@ -0,0 +1,17 @@ +# == Schema Information +# +# Table name: content.surah_details +# +# id :integer not null +# language_code :string +# description :text +# surah_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# + +require 'rails_helper' + +RSpec.describe Content::SurahInfo, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/media/content_spec.rb b/spec/models/media/content_spec.rb new file mode 100644 index 00000000..c40c4e14 --- /dev/null +++ b/spec/models/media/content_spec.rb @@ -0,0 +1,16 @@ +# == Schema Information +# +# Table name: media.content +# +# resource_id :integer not null, primary key +# ayah_key :string primary key +# url :string +# created_at :datetime not null +# updated_at :datetime not null +# + +require 'rails_helper' + +RSpec.describe Media::Content, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/media/resource_spec.rb b/spec/models/media/resource_spec.rb new file mode 100644 index 00000000..37515acd --- /dev/null +++ b/spec/models/media/resource_spec.rb @@ -0,0 +1,17 @@ +# == Schema Information +# +# Table name: media.resource +# +# resource_id :integer not null, primary key +# name :string +# url :string +# provider :string +# created_at :datetime not null +# updated_at :datetime not null +# + +require 'rails_helper' + +RSpec.describe Media::Resource, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end