app/controllers/admins_controller.rb
require 'delayed/command'
class AdminsController < ApplicationController
include CommonSweepers
RESTART_MSG = "Your settings have been updated. If you changed some settings e.g. search, you need to restart some processes.
Please see the buttons and explanations below."
before_filter :login_required
before_filter :is_user_admin_auth
def show
respond_to do |format|
format.html
end
end
def update_admins
admin_ids = params[:admins] || []
current_admins = Person.admins
admins = admin_ids.collect{|id| Person.find(id)}
current_admins.each{|ca| ca.is_admin = false}
admins.each{|a| a.is_admin = true}
(admins | current_admins).each do |admin|
admin.save!
end
redirect_to :action=>:show
end
def registration_form
respond_to do |format|
format.html
end
end
def tags
@tags=TextValue.all_tags.sort_by{|t| t.text}
end
def update_features_enabled
Seek::Config.public_seek_enabled= string_to_boolean(params[:public_seek_enabled] || true)
Seek::Config.events_enabled= string_to_boolean params[:events_enabled]
Seek::Config.jerm_enabled= string_to_boolean params[:jerm_enabled]
Seek::Config.email_enabled= string_to_boolean params[:email_enabled]
Seek::Config.pdf_conversion_enabled= string_to_boolean params[:pdf_conversion_enabled]
Seek::Config.delete_asset_version_enabled= string_to_boolean params[:delete_asset_version_enabled]
Seek::Config.forum_enabled= string_to_boolean params[:forum_enabled]
Seek::Config.set_smtp_settings 'address', params[:address]
Seek::Config.set_smtp_settings 'domain', params[:domain]
Seek::Config.set_smtp_settings 'authentication', params[:authentication]
Seek::Config.set_smtp_settings 'user_name', params[:user_name]
Seek::Config.set_smtp_settings 'password', params[:password]
Seek::Config.set_smtp_settings 'enable_starttls_auto',params[:enable_starttls_auto]=="1"
Seek::Config.solr_enabled= string_to_boolean params[:solr_enabled]
Seek::Config.jws_enabled= string_to_boolean params[:jws_enabled]
Seek::Config.jws_online_root= params[:jws_online_root]
Seek::Config.exception_notification_recipients = params[:exception_notification_recipients]
Seek::Config.exception_notification_enabled = string_to_boolean params[:exception_notification_enabled]
Seek::Config.hide_details_enabled= string_to_boolean params[:hide_details_enabled]
Seek::Config.activation_required_enabled= string_to_boolean params[:activation_required_enabled]
Seek::Config.google_analytics_tracker_id= params[:google_analytics_tracker_id]
Seek::Config.google_analytics_enabled= string_to_boolean params[:google_analytics_enabled]
Seek::Config.piwik_analytics_enabled= string_to_boolean params[:piwik_analytics_enabled]
Seek::Config.piwik_analytics_id_site= params[:piwik_analytics_id_site]
Seek::Config.piwik_analytics_url= params[:piwik_analytics_url]
Seek::Config.set_smtp_settings 'port', params[:port] if only_integer params[:port], 'port'
Seek::Util.clear_cached
update_redirect_to (only_integer params[:port], "port"),'features_enabled'
end
def update_home_settings
Seek::Config.project_news_enabled= string_to_boolean params[:project_news_enabled]
Seek::Config.project_news_feed_urls= params[:project_news_feed_urls]
Seek::Config.project_news_number_of_entries= params[:project_news_number_of_entries] if only_integer params[:project_news_number_of_entries], "#{t('project')} news items"
Seek::Config.community_news_enabled= string_to_boolean params[:community_news_enabled]
Seek::Config.community_news_feed_urls= params[:community_news_feed_urls]
Seek::Config.community_news_number_of_entries= params[:community_news_number_of_entries] if only_integer params[:community_news_number_of_entries], "community news items"
Seek::Config.home_description = params[:home_description]
begin
Seek::FeedReader.clear_cache
rescue e
logger.error "Error whilst attempting to clear feed cache #{e.message}"
end
update_redirect_to true,'home_settings'
end
def rebrand
respond_to do |format|
format.html
end
end
def update_rebrand
Seek::Config.project_name= params[:project_name]
Seek::Config.project_type= params[:project_type]
Seek::Config.project_link= params[:project_link]
Seek::Config.project_title= params[:project_title]
Seek::Config.project_long_name= params[:project_long_name]
Seek::Config.dm_project_name= params[:dm_project_name]
Seek::Config.dm_project_title= params[:dm_project_title]
Seek::Config.dm_project_link= params[:dm_project_link]
Seek::Config.application_name= params[:application_name]
Seek::Config.application_title= params[:application_title]
Seek::Config.header_image_enabled= string_to_boolean params[:header_image_enabled]
Seek::Config.header_image= params[:header_image]
Seek::Config.header_image_link= params[:header_image_link]
Seek::Config.header_image_title= params[:header_image_title]
Seek::Config.copyright_addendum_enabled= string_to_boolean params[:copyright_addendum_enabled]
Seek::Config.copyright_addendum_content= params[:copyright_addendum_content]
Seek::Config.noreply_sender= params[:noreply_sender]
update_redirect_to true,'rebrand'
end
def update_pagination
update_flag = true
Seek::Config.set_default_page "people",params[:people]
Seek::Config.set_default_page "projects", params[:projects]
Seek::Config.set_default_page "institutions", params[:institutions]
Seek::Config.set_default_page "investigations", params[:investigations]
Seek::Config.set_default_page "studies", params[:studies]
Seek::Config.set_default_page "assays", params[:assays]
Seek::Config.set_default_page "data_files", params[:data_files]
Seek::Config.set_default_page "models", params[:models]
Seek::Config.set_default_page "sops", params[:sops]
Seek::Config.set_default_page "publications", params[:publications]
Seek::Config.set_default_page "presentations", params[:presentations]
Seek::Config.set_default_page "events", params[:events]
Seek::Config.limit_latest= params[:limit_latest] if only_positive_integer params[:limit_latest], "latest limit"
update_redirect_to (only_positive_integer params[:limit_latest], 'latest limit'),'pagination'
end
def update_others
update_flag = true
if Seek::Config.tag_threshold.to_s != params[:tag_threshold] || Seek::Config.max_visible_tags.to_s!=params[:max_visible_tags]
expire_annotation_fragments
end
Seek::Config.site_base_host = params[:site_base_host] unless params[:site_base_host].nil?
#check valid email
Seek::Config.pubmed_api_email = params[:pubmed_api_email] if params[:pubmed_api_email] == '' || (check_valid_email params[:pubmed_api_email], "pubmed api email")
Seek::Config.crossref_api_email = params[:crossref_api_email] if params[:crossref_api_email] == '' || (check_valid_email params[:crossref_api_email], "crossref api email")
Seek::Config.bioportal_api_key = params[:bioportal_api_key]
Seek::Config.tag_threshold = params[:tag_threshold] if only_integer params[:tag_threshold], "tag threshold"
Seek::Config.max_visible_tags = params[:max_visible_tags] if only_positive_integer params[:max_visible_tags], "maximum visible tags"
Seek::Config.sabiork_ws_base_url = params[:sabiork_ws_base_url] unless params[:sabiork_ws_base_url].nil?
update_flag = (params[:pubmed_api_email] == '' ||(check_valid_email params[:pubmed_api_email], "pubmed api email")) && (params[:crossref_api_email] == '' || (check_valid_email params[:crossref_api_email], "crossref api email")) && (only_integer params[:tag_threshold], "tag threshold") && (only_positive_integer params[:max_visible_tags], "maximum visible tags")
update_redirect_to update_flag,'others'
end
def restart_server
command = "touch #{Rails.root}/tmp/restart.txt"
error = execute_command(command)
redirect_with_status(error, 'server')
end
def restart_delayed_job
error = nil
if Rails.env!="test"
begin
Seek::Workers.restart
#give it up to 5 seconds to start up, otherwise the page reloads too quickly and says it is not running
sleep(0.5)
pid = Daemons::PidFile.new("#{Rails.root}/tmp/pids","delayed_job.0")
x=0
while !pid.running? && (x<10)
sleep(0.5)
x+=1
end
rescue Exception=>e
error=e.message
if Seek::Config.exception_notification_enabled
ExceptionNotifier.notify_exception(e,:data=>{:message=>'Problem restarting delayed job'})
end
end
end
redirect_with_status(error, 'background tasks')
end
def edit_tag
if request.post?
@tag=TextValue.find(params[:id])
replacement_tags = []
params[:tags_autocompleter_selected_ids].each do |selected_id|
replacement_tags << TextValue.find(selected_id)
end unless params[:tags_autocompleter_selected_ids].nil?
params[:tags_autocompleter_unrecognized_items].select{|t| !t.blank?}.each do |item|
tag = TextValue.find_by_text(item)
tag = TextValue.create :text=>item if tag.nil?
replacement_tags << tag
end unless params[:tags_autocompleter_unrecognized_items].nil?
@tag.annotations.each do |a|
annotatable = a.annotatable
source = a.source
attribute_name = a.attribute.name
a.destroy unless replacement_tags.include?(@tag)
replacement_tags.each do |tag|
if annotatable.annotations_with_attribute_and_by_source(attribute_name, source).select{|a| a.value == tag}.blank?
new_annotation = Annotation.new :attribute_name=>attribute_name, :value=>tag, :annotatable => annotatable, :source => source
new_annotation.save!
end
end
end
@tag=TextValue.find(params[:id])
@tag.destroy if @tag.annotations.blank?
expire_annotation_fragments
redirect_to :action=>:tags
else
@tag=TextValue.find(params[:id])
@all_tags_as_json=TextValue.all.collect{|t| {'id'=>t.id, 'name'=>h(t.text)}}.to_json
respond_to do |format|
format.html
end
end
end
def delete_tag
tag=TextValue.find(params[:id])
if request.post?
tag.annotations.each do |a|
a.destroy
end
tag.destroy
flash.now[:notice]="Tag #{tag.text} deleted"
else
flash.now[:error]="Must be a post"
end
expire_annotation_fragments
redirect_to :action=>:tags
end
def get_stats
collection = []
type = nil
title = nil
@page=params[:id]
case @page
when "pals"
title = "PALs"
collection = Person.pals
type = "users"
when "admins"
title = "Administrators"
collection = Person.admins
type = "users"
when "invalid"
collection = {}
type = "invalid_users"
pal_role=ProjectRole.pal_role
collection[:pal_mismatch] = Person.all.select {|p| p.is_pal? != p.project_roles.include?(pal_role)}
collection[:duplicates] = Person.duplicates
collection[:no_person] = User.without_profile
when "not_activated"
title = "Users requiring activation"
collection = User.not_activated
type = "users"
when "projectless"
title = "Users not in a #{Seek::Config.project_name} #{t('project')}"
collection = Person.without_group.registered
type = "users"
when "contents"
type = "content_stats"
when "activity"
type = "activity_stats"
when "search"
type = "search_stats"
when "job_queue"
type = "job_queue"
when "auth_consistency"
type = "auth_consistency"
when "monthly_stats"
monthly_stats = get_monthly_stats
type = "monthly_statistics"
when "none"
type = "none"
end
respond_to do |format|
case type
when "invalid_users"
format.html { render :partial => "admins/invalid_user_stats_list", :locals => { :collection => collection} }
when "users"
format.html { render :partial => "admins/user_stats_list", :locals => { :title => title, :collection => collection} }
when "content_stats"
format.html { render :partial => "admins/content_stats", :locals => {:stats => Seek::ContentStats.generate} }
when "activity_stats"
format.html { render :partial => "admins/activity_stats", :locals => {:stats => Seek::ActivityStats.new} }
when "search_stats"
format.html { render :partial => "admins/search_stats", :locals => {:stats => Seek::SearchStats.new} }
when "job_queue"
format.html { render :partial => "admins/job_queue" }
when "auth_consistency"
format.html { render :partial => "admins/auth_consistency" }
when "monthly_statistics"
format.html { render :partial => "admins/monthly_statistics", :locals => {:stats => monthly_stats}}
when "none"
format.html { render :text=>"" }
end
end
end
def get_monthly_stats
first_month = User.all.sort_by(&:created_at).first.created_at
number_of_months_since_first = (Date.today.year * 12 + Date.today.month) - (first_month.year * 12 + first_month.month)
stats = {}
(0..number_of_months_since_first).each do |x|
time_range = (x.month.ago.beginning_of_month.to_date..x.month.ago.end_of_month.to_date)
registrations = User.where(:created_at => time_range).count
active_users = 0
User.all.each do |user|
active_users = active_users + 1 unless user.taverna_player_runs.where(:created_at => time_range, :saved_state => "finished").empty?
end
complete_runs = TavernaPlayer::Run.where(:created_at => time_range, :saved_state => "finished").count
stats[x.month.ago.beginning_of_month.to_i] = [registrations, active_users, complete_runs]
end
return stats
end
def test_email_configuration
smtp_hash_old = ActionMailer::Base.smtp_settings
smtp_hash_new = {:address => params[:address], :enable_starttls_auto => params[:enable_starttls_auto]=="1", :domain => params[:domain], :authentication => params[:authentication], :user_name => (params[:user_name].blank? ? nil : params[:user_name]), :password => (params[:password].blank? ? nil : params[:password])}
smtp_hash_new[:port] = params[:port] if only_integer params[:port], 'port'
ActionMailer::Base.smtp_settings = smtp_hash_new
raise_delivery_errors_setting = ActionMailer::Base.raise_delivery_errors
ActionMailer::Base.raise_delivery_errors = true
begin
Mailer.test_email(params[:testing_email]).deliver
render :update do |page|
page.replace_html "ajax_loader_position", "<div id='ajax_loader_position'></div>"
page.alert("test email is sent successfully to #{params[:testing_email]}")
end
rescue Exception => e
render :update do |page|
page.replace_html "ajax_loader_position", "<div id='ajax_loader_position'></div>"
page.alert("Fail to send test email, #{e.message}")
end
ensure
ActionMailer::Base.smtp_settings = smtp_hash_old
ActionMailer::Base.raise_delivery_errors = raise_delivery_errors_setting
end
end
private
def created_at_data_for_model model
x={}
start="1 Nov 2008"
x[Date.parse(start).jd]=0
x[Date.today.jd]=0
model.order(:created_at).each do |i|
date=i.created_at.to_date
day=date.jd
x[day] ||= 0
x[day]+=1
end
sorted_keys=x.keys.sort
(sorted_keys.first..sorted_keys.last).collect{|i| x[i].nil? ? 0 : x[i] }
end
def check_valid_email email_address, field
if email_address =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/
return true
else
flash[:error] = "Please input the correct #{field}"
return false
end
end
def only_integer input, field
begin
Integer(input)
return true
rescue
flash[:error] = "Please enter a valid number for the #{field}"
return false
end
end
def only_positive_integer input, field
begin
if Integer(input) > 0
return true
else
flash[:error] = "Please enter a valid positive number for the #{field}"
return false
end
rescue
flash[:error] = "Please enter a valid positive number for the #{field}"
return false
end
end
def string_to_boolean string
if string == '1'
return true
else
return false
end
end
def update_redirect_to flag, action
if flag
flash[:notice] = RESTART_MSG
expire_header_and_footer
redirect_to :action=>:show
else
redirect_to :action=> action.to_s
end
end
def execute_command(command)
return nil if Rails.env=="test"
begin
cl = Cocaine::CommandLine.new(command)
cl.run
return nil
rescue Cocaine::CommandNotFoundError => e
return "The command the restart the background tasks could not be found!"
rescue Exception => e
error = e.message
return error
end
end
def redirect_with_status(error, process)
if error.blank?
flash[:notice] = "The #{process} was restarted"
else
flash[:error] = "There is a problem with restarting the #{process}. #{error.gsub("Cocaine::", "")}"
end
redirect_to :action=>:show
end
end