# frozen_string_literal: true # ElasticSearch relative tasks namespace :fablab do namespace :es do desc '(re)Build ElasticSearch fablab base for stats' task build_stats: :environment do delete_stats_index create_stats_index create_stats_mappings add_event_filters end def delete_stats_index puts 'DELETE stats' `curl -XDELETE http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats` end def create_stats_index puts 'PUT index stats' `curl -XPUT http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats -d' { "settings" : { "index" : { "number_of_replicas" : 0 } } } '` end def create_stats_mappings %w[account event machine project subscription training user space].each do |stat| puts "PUT Mapping stats/#{stat}" `curl -XPUT http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats/#{stat}/_mapping -d ' { "properties": { "type": { "type": "string", "index" : "not_analyzed" }, "subType": { "type": "string", "index" : "not_analyzed" }, "date": { "type": "date" }, "name": { "type": "string", "index" : "not_analyzed" } } }';` end end desc 'add event filters to statistics' task add_event_filters: :environment do add_event_filters end def add_event_filters `curl -XPUT http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats/event/_mapping -d ' { "properties": { "ageRange": { "type": "string", "index" : "not_analyzed" }, "eventTheme": { "type": "string", "index" : "not_analyzed" } } }';` end desc 'add spaces reservations to statistics' task add_spaces: :environment do `curl -XPUT http://#{ENV['ELASTICSEARCH_HOST']}:9200/stats/space/_mapping -d ' { "properties": { "type": { "type": "string", "index" : "not_analyzed" }, "subType": { "type": "string", "index" : "not_analyzed" }, "date": { "type": "date" }, "name": { "type": "string", "index" : "not_analyzed" } } }';` end desc 'sync all/one project in ElasticSearch index' task :build_projects_index, [:id] => :environment do |_task, args| client = Project.__elasticsearch__.client # ask if we delete the index print 'Delete all projects in ElasticSearch index? (y/n) ' confirm = STDIN.gets.chomp if confirm == 'y' client.delete_by_query( index: Project.index_name, type: Project.document_type, conflicts: 'proceed', body: { query: { match_all: {} } } ) end # create index if not exists Project.__elasticsearch__.create_index! force: true unless client.indices.exists? index: Project.index_name # index requested documents if args.id ProjectIndexerWorker.perform_async(:index, id) else Project.pluck(:id).each do |project_id| ProjectIndexerWorker.perform_async(:index, project_id) end end end desc 'sync all/one availabilities in ElasticSearch index' task :build_availabilities_index, [:id] => :environment do |_task, args| client = Availability.__elasticsearch__.client # create index if not exists Availability.__elasticsearch__.create_index! force: true unless client.indices.exists? index: Availability.index_name # 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: Availability.mappings.to_hash # verify doctype creation was successful if client.indices.exists_type? index: Availability.index_name, type: Availability.document_type puts "[ElasticSearch] #{Availability.index_name}/#{Availability.document_type} successfully created with its mapping." # 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 else puts "[ElasticSearch] An error occurred while creating #{Availability.index_name}/#{Availability.document_type}. " \ 'Please check your ElasticSearch configuration.' puts "\nCancelling..." end end desc '(re)generate statistics in ElasticSearch for the past period. Use 0 to generate for today' task :generate_stats, [:period] => :environment do |_task, args| raise 'FATAL ERROR: You must pass a number of days (=> past period) OR a date to generate statistics' unless args.period days = date_to_days(args.period) puts "\n==> generating statistics for the last #{days} days <==\n" if days.zero? StatisticService.new.generate_statistic(start_date: DateTime.current.beginning_of_day, end_date: DateTime.current.end_of_day) else days.times.each do |i| StatisticService.new.generate_statistic(start_date: i.day.ago.beginning_of_day, end_date: i.day.ago.end_of_day) end end end def date_to_days(value) date = Date.parse(value.to_s) (DateTime.current.to_date - date).to_i rescue ArgumentError value.to_i end end end