diff --git a/app/models/availability.rb b/app/models/availability.rb index b3b5aded9..8b44bb9aa 100644 --- a/app/models/availability.rb +++ b/app/models/availability.rb @@ -1,4 +1,10 @@ class Availability < ActiveRecord::Base + + # elastic initialisations + include Elasticsearch::Model + index_name 'fablab' + document_type 'availabilities' + has_many :machines_availabilities, dependent: :destroy has_many :machines, through: :machines_availabilities accepts_nested_attributes_for :machines, allow_destroy: true @@ -24,6 +30,17 @@ class Availability < ActiveRecord::Base validate :length_must_be_1h_minimum, unless: proc { end_at.blank? or start_at.blank? } validate :should_be_associated + ## elastic callbacks + after_save { AvailabilityIndexerWorker.perform_async(:index, self.id) } + after_destroy { AvailabilityIndexerWorker.perform_async(:delete, self.id) } + + # elastic mapping + settings do + mappings dynamic: 'true' do + indexes 'available_type', analyzer: 'simple' + end + end + def safe_destroy if available_type == 'machines' reservations = Reservation.where(reservable_type: 'Machine', reservable_id: machine_ids).joins(:slots).where('slots.availability_id = ?', id) diff --git a/app/models/project.rb b/app/models/project.rb index 36153f251..0c2caf996 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -52,8 +52,8 @@ class Project < ActiveRecord::Base ## elastic # callbacks - after_save { IndexerWorker.perform_async(:index, self.id) } - after_destroy { IndexerWorker.perform_async(:delete, self.id) } + after_save { ProjectIndexerWorker.perform_async(:index, self.id) } + after_destroy { ProjectIndexerWorker.perform_async(:delete, self.id) } # settings do diff --git a/app/workers/availability_indexer_worker.rb b/app/workers/availability_indexer_worker.rb new file mode 100644 index 000000000..622dad119 --- /dev/null +++ b/app/workers/availability_indexer_worker.rb @@ -0,0 +1,21 @@ +class AvailabilityIndexerWorker + include Sidekiq::Worker + sidekiq_options queue: 'elasticsearch', retry: true + + logger = Sidekiq.logger.level == Logger::DEBUG ? Sidekiq.logger : nil + client = Elasticsearch::Model.client + + def perform(operation, record_id) + logger.debug [operation, "ID: #{record_id}"] + + case operation.to_s + when /index/ + record = Availability.find(record_id) + client.index index: Availability.index_name, type: Availability.document_type, id: record.id, body: record.as_indexed_json + #puts record.as_indexed_json + when /delete/ + client.delete index: 'fablab', type: 'projects', id: record_id + else raise ArgumentError, "Unknown operation '#{operation}'" + end + end +end diff --git a/app/workers/indexer_worker.rb b/app/workers/project_indexer_worker.rb similarity index 74% rename from app/workers/indexer_worker.rb rename to app/workers/project_indexer_worker.rb index e08e21d3a..740184e0e 100644 --- a/app/workers/indexer_worker.rb +++ b/app/workers/project_indexer_worker.rb @@ -1,4 +1,4 @@ -class IndexerWorker +class ProjectIndexerWorker include Sidekiq::Worker sidekiq_options queue: 'elasticsearch', retry: true @@ -11,10 +11,9 @@ class IndexerWorker case operation.to_s when /index/ record = Project.find(record_id) - Client.index index: Project.index_name, type: Project.document_type, id: record.id, body: record.as_indexed_json - #puts record.as_indexed_json + Client.index index: Project.index_name, type: Project.document_type, id: record.id, body: record.to_json when /delete/ - Client.delete index: 'fablab', type: 'projects', id: record_id + Client.delete index: 'fablab', type: 'availabilities', id: record_id else raise ArgumentError, "Unknown operation '#{operation}'" end end diff --git a/lib/tasks/fablab.rake b/lib/tasks/fablab.rake index f2939c14e..0fae3524b 100644 --- a/lib/tasks/fablab.rake +++ b/lib/tasks/fablab.rake @@ -1,42 +1,42 @@ namespace :fablab do - #desc "Get all stripe plans and create in fablab app" - #task stripe_plan: :environment do - #Stripe::Plan.all.data.each do |plan| - #unless Plan.find_by_stp_plan_id(plan.id) - #group = Group.friendly.find(plan.id.split('-').first) - #if group - #Plan.create(stp_plan_id: plan.id, name: plan.name, amount: plan.amount, interval: plan.interval, group_id: group.id, skip_create_stripe_plan: true) - #else - #puts plan.name + " n'a pas été créé. [error]" - #end - #end - #end + # desc "Get all stripe plans and create in fablab app" + # task stripe_plan: :environment do + # Stripe::Plan.all.data.each do |plan| + # unless Plan.find_by_stp_plan_id(plan.id) + # group = Group.friendly.find(plan.id.split('-').first) + # if group + # Plan.create(stp_plan_id: plan.id, name: plan.name, amount: plan.amount, interval: plan.interval, group_id: group.id, skip_create_stripe_plan: true) + # else + # puts plan.name + " n'a pas été créé. [error]" + # end + # end + # end + # + # if Plan.column_names.include? "training_credit_nb" + # Plan.all.each do |p| + # p.update_columns(training_credit_nb: (p.interval == 'month' ? 1 : 5)) + # end + # end + # end - #if Plan.column_names.include? "training_credit_nb" - #Plan.all.each do |p| - #p.update_columns(training_credit_nb: (p.interval == 'month' ? 1 : 5)) - #end - #end - #end - - desc "Regenerate the invoices" + desc 'Regenerate the invoices' task :regenerate_invoices, [:year, :month] => :environment do |task, args| year = args.year || Time.now.year month = args.month || Time.now.month start_date = Time.new(year.to_i, month.to_i, 1) end_date = start_date.next_month puts "-> Start regenerate the invoices between #{I18n.l start_date, format: :long} in #{I18n.l end_date-1.minute, format: :long}" - invoices = Invoice.only_invoice.where("created_at >= :start_date AND created_at < :end_date", {start_date: start_date, end_date: end_date}).order(created_at: :asc) + invoices = Invoice.only_invoice.where('created_at >= :start_date AND created_at < :end_date', {start_date: start_date, end_date: end_date}).order(created_at: :asc) invoices.each(&:regenerate_invoice_pdf) - puts "-> Done" + puts '-> Done' end - desc "Cancel stripe subscriptions" + desc 'Cancel stripe subscriptions' task cancel_subscriptions: :environment do - Subscription.where("expired_at >= ?", Time.now.at_beginning_of_day).each do |s| + Subscription.where('expired_at >= ?', Time.now.at_beginning_of_day).each do |s| puts "-> Start cancel subscription of #{s.user.email}" s.cancel - puts "-> Done" + puts '-> Done' end end @@ -96,17 +96,50 @@ namespace :fablab do }';` end - desc "sync all/one project in elastic search index" + desc 'sync all/one project in ElasticSearch index' task :es_build_projects_index, [:id] => :environment do |task, args| - if Project.__elasticsearch__.client.indices.exists? index: 'fablab' - Project.__elasticsearch__.client.indices.delete index: 'fablab' + client = Project.__elasticsearch__.client + # create index if not exists + unless client.indices.exists? index: Project.index_name + client.indices.create Project.index_name end - Project.__elasticsearch__.client.indices.create index: Project.index_name, body: { settings: Project.settings.to_hash, mappings: Project.mappings.to_hash } + # delete doctype if exists + if client.indices.exists_type? index: Project.index_name, type: Project.document_type + client.indices.delete_mapping index: Project.index_name, type: Project.document_type + end + # create doctype + client.indices.put_mapping index: Project.index_name, type: Project.document_type, body: { settings: Project.settings.to_hash, mappings: Project.mappings.to_hash } + + # index requested documents if args.id - IndexerWorker.perform_async(:index, id) + ProjectIndexerWorker.perform_async(:index, id) else Project.pluck(:id).each do |project_id| - IndexerWorker.perform_async(:index, project_id) + ProjectIndexerWorker.perform_async(:index, project_id) + end + end + end + + desc 'sync all/one availabilities in ElasticSearch index' + task :es_build_availabilities_index, [:id] => :environment do |task, args| + client = Availability.__elasticsearch__.client + # create index if not exists + unless client.indices.exists? index: Availability.index_name + client.indices.create Availability.index_name + end + # delete doctype if exists + if client.indices.exists_type? index: Availability.index_name, type: Availability.document_type + client.indices.delete_mapping index: Availability.index_name, type: Availability.document_type + end + # create doctype + client.indices.put_mapping index: Availability.index_name, type: Availability.document_type, body: { settings: Availability.settings.to_hash, mappings: Availability.mappings.to_hash } + + # index requested documents + if args.id + AvailabilityIndexerWorker.perform_async(:index, id) + else + Availability.pluck(:id).each do |availability_id| + AvailabilityIndexerWorker.perform_async(:index, availability_id) end end end @@ -194,7 +227,7 @@ namespace :fablab do puts "\nUsers successfully notified\n\n" end - desc "generate fixtures from db" + desc 'generate fixtures from db' task generate_fixtures: :environment do Rails.application.eager_load! ActiveRecord::Base.descendants.reject { |c| c == ActiveRecord::SchemaMigration or c == PartnerPlan }.each do |ar_base|