feeds/app/controllers/admin/feeds_controller.rb

310 lines
9.7 KiB
Ruby

class Admin::FeedsController < OrbitAdminController
layout :compute_layout
helper_method :search_all_words
def compute_layout
if action_name== 'annc_content'
false
else
'back_end'
end
end
def index
@site_feeds = SiteFeed.all.group_by(&:remote_site_url)
@school_urls = @site_feeds.keys
redirect_to new_admin_feed_path and return if @site_feeds.count == 0
end
def settings
@setting = SiteFeedSetting.first
end
def update_settings
@setting = SiteFeedSetting.first
p = params.require(:site_feed_setting).permit!
@setting.update_attributes(p)
Thread.new do
sleep 3
content = "UNICORN_PID=\"`fuser tmp/pids/unicorn.sock tmp/sockets/unicorn.sock tmp/unicorn.sock` `cat tmp/pids/unicorn.pid `\" && kill -s USR2 $UNICORN_PID ; n=20; while (kill -0 $UNICORN_PID > /dev/null 2>&1) && test $n -ge 0; do printf '.' && sleep 1 && n=$(( $n - 1 )); done ; if test $n -lt 0; then kill -s TERM $UNICORN_PID; sleep 3; bundle exec unicorn_rails -c config/unicorn.rb -D -E #{Rails.env}; else kill -s QUIT $UNICORN_PID; fi"
system(content)
end
redirect_to admin_feeds_settings_path
end
def new
end
def annc_content
site_feed_annc = SiteFeedAnnc.where(id: params['feed_annc_id']).first
@annc = site_feed_annc.get_annc(params['annc_uid'].to_s) rescue {}
end
def process_annc
now_process = params['process']
annc_uid = params['annc_uid'].to_s
site_feed_annc = SiteFeedAnnc.where(id: params['feed_annc_id']).first
if !site_feed_annc.nil?
case now_process
when /is_top|is_hot/
cmd = now_process.split(':')
f = cmd[0]=='is_top' ? 'top_list' : 'hot_list'
if cmd[1] == 'enable'
if site_feed_annc[f].exclude?(annc_uid)
tmp = site_feed_annc.send(f)
tmp << annc_uid
site_feed_annc.update_attributes(f.to_sym => tmp)
end
else
if site_feed_annc[f].include?(annc_uid)
tmp = site_feed_annc.send(f)
tmp -= [annc_uid]
site_feed_annc.update_attributes(f.to_sym => tmp)
end
end
when /hidden|display/
if now_process == 'hidden'
if site_feed_annc[:hidden_annc].exclude?(annc_uid)
tmp = site_feed_annc.hidden_annc
tmp << annc_uid
site_feed_annc.update_attributes(:hidden_annc =>tmp)
end
else
if site_feed_annc[:hidden_annc].include?(annc_uid)
tmp = site_feed_annc.hidden_annc
tmp -= [annc_uid]
site_feed_annc.update_attributes(:hidden_annc =>tmp)
end
end
end
feeds_model = site_feed_annc.feeds_model
feeds_uid_field = site_feed_annc.feeds_uid_field
feeds_update_statuses_callback = site_feed_annc.feeds_update_statuses_callback
if feeds_model && feeds_uid_field
feeds_model = feeds_model.constantize
feeds_record = feeds_model.where(feeds_uid_field=>params['feed_annc_id']).first
if feeds_record
status_data = {}
cmd = now_process.split(':')
if now_process == "is_top"
status_data[:is_top] = (cmd[1] == 'enable')
elsif now_process == "is_hot"
status_data[:is_hot] = (cmd[1] == 'enable')
elsif status_data == "hidden"
status_data[:is_hidden] = true
elsif status_data == "display"
status_data[:is_hidden] = false
end
if feeds_update_statuses_callback
feeds_record.send(feeds_update_statuses_callback, status_data)
else
feeds_record.update(status_data)
end
end
end
end
render :plain => 'success'
end
def announcements
@filter_fields = {}
@filter_fields['feed.source'] = SiteFeed.all.pluck(:channel_title,:remote_site_url).collect do |a,b|
tp = (a.blank? || a[I18n.locale].blank?) ? b.gsub(/http:\/\/|https:\/\//,'').gsub(/\./,'-') : a[I18n.locale]
tp
end.uniq.map{|tp| {:title => tp,:id => tp}}
@filter_fields['feed.module_name'] = SiteFeed.all.map{|s| s.channel_key}.uniq.map do |key|
{:title => I18n.t("module_name.#{key}"),:id => key}
end
@max_content_count = 100
@page_no = params[:page].to_i
@page_no = 1 if @page_no==0
@skip_count = (@page_no-1)*@max_content_count
@module_name = params[:filters][:module_name].to_a rescue []
@module_name = SiteFeed.all.map{|s| s.channel_key}.uniq if @module_name == []
@all_feed_annc = SiteFeedAnnc.where(:channel_key.in => @module_name).order(id: 1).to_a rescue []
@source = params[:filters][:source] rescue []
@keywords = params[:keywords] rescue nil
if request.xhr?
render :partial => "announcements"
end
end
def get_category_list
app_key = params[:channel]
ma = ModuleApp.find_by_key(app_key) rescue nil
categories = []
if !ma.nil?
ma.categories.each do |category|
cat = {}
cat["title"] = category.title
cat["id"] = category.id.to_s
categories << cat
end
end
render :json => {"categories" => categories}.to_json
end
def get_channel_list
url = URI.decode(params['url']).chomp("/") + "/feeds/channel_lists"
uri = URI(URI.decode(url).encode)
res_net = http_request(uri) rescue nil
res = res_net ? res_net.body : nil
data = {}
if res_net && res_net['Content-Type'].split(";")[0]=="application/json"
data = JSON.parse(res) rescue {}
else
uri = URI(params['url'])
body = http_request(uri).body
links = get_rss_link(params['url'], body)
if links.length > 0
data = {channels: [{title: "Announcement",
key: "announcement",
url: params['url'],
feeds: links,
app_icon: "icons-megaphone"}]}
end
end
render :json => data.to_json
end
def get_feed_list
data_to_send = {}
if params['feeds']
data = {"feeds"=> JSON.parse(params[:feeds])}
else
url = params['url'].chomp("/") + params[:feed_list_url]
uri = URI.parse(url)
begin
res = http_request(uri)
res = res.code=='200' ? res.body : nil
rescue
res = nil
puts uri.to_s
puts uri.hostname
end
data = JSON.parse(res) rescue {}
end
data_to_send["feeds"] = []
Array(data["feeds"]).each do |feed|
sf = SiteFeed.find_by(:feed_uid => feed["uid"]) rescue nil
if !sf.nil?
feed["subscribed"] = true
else
feed["subscribed"] = false
end
data_to_send["feeds"] << feed
end
render :json => data_to_send.to_json
end
def channel_title
Thread.new do
site_feeds = SiteFeed.where(:remote_site_url => params["url"])
site_feeds.each do |sf|
sf.channel_title_translations = params["channel_title_translations"]
sf.instance_variable_set(:@skip_callback, true)
sf.save
sf.sync_data_to_annc
sf.update_channel_title
end
end
render :json => {"success" => true, "title" => params["channel_title_translations"][I18n.locale.to_s]}.to_json
end
def subscribe
site_feed = SiteFeed.new
uri = URI(params[:url])
site_feed.remote_site_url = uri.to_s[/\A.*(?=#{uri.path}\z)/]
site_feed.merge_with_category = params[:category]
site_feed.channel_name = params[:channel]
site_feed.channel_key = params[:channel_key]
site_feed.feed_uid = params[:feed][:uid]
site_feed.feed_name_translations = params[:feed][:title_translations]
site_feed.disabled = false
site_feed.feed_url = params[:feed][:url]
if params[:feed][:is_rss]
site_feed.is_rss = params[:feed][:is_rss]
end
uri = URI(site_feed.remote_site_url)
site_host = uri.host
other_site_feeds = SiteFeed.where(:remote_site_url=>/:\/\/#{::Regexp.escape(site_host)}/)
other_site_feed = other_site_feeds.first
site_feed.channel_title_translations = other_site_feed.channel_title_translations if other_site_feed
other_scheme = URI(other_site_feed.remote_site_url).scheme rescue nil
site_scheme = uri.scheme
if (['http','https'] & [other_scheme, site_scheme]).count == 2
if site_scheme == 'http'
site_feed.remote_site_url = site_feed.remote_site_url.sub('http://','https://')
else
remote_site_url = site_feed.remote_site_url
other_site_feeds.update_all(:remote_site_url=>remote_site_url)
site_feed_anncs = SiteFeedAnnc.where(:feed_id.in=>other_site_feeds.pluck(:id))
site_feed_anncs.update_all(:remote_site_url=>remote_site_url)
site_feed_anncs.each{|sfa| sfa.update_remote_site_url}
end
end
module_app = ModuleApp.where(:key=>site_feed.channel_key).first
if module_app.feeds_model
sync_fields_data = SiteFeed::ModuleAppSyncFields.map{|f| [f, module_app[f]] }.to_h
site_feed.update(sync_fields_data)
end
site_feed.save
render :json => {"success" => true}.to_json
end
def disable
feed = SiteFeed.find(params[:feed_id]) rescue nil
if !feed.nil?
feed.disabled = params[:disable]
feed.save
end
render :json => {"success" => true}.to_json
end
def unsubscribe
sf = SiteFeed.find_by(:feed_uid => params[:feed_uid]) rescue nil
if !sf.nil?
sf.destroy
end
render :json => {"success" => true}.to_json
end
def force_refresh
sf = SiteFeed.find_by(:feed_uid => params[:feed_uid]) rescue nil
if !sf.nil?
FeedModel::Cache.recreate_annc_cache(sf)
end
render :json => {"success" => true}.to_json
end
def search_all_words(target, word)
target = target.upcase
words = word.upcase.split(' ')
words.select { |value| target.include? value } == words
end
private
def http_request(uri, open_timeout=10)
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
open_timeout: open_timeout,read_timeout: 60,
verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
req = Net::HTTP::Get.new(uri)
req['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
http.request(req)
end
end
def get_rss_link(url, body)
html = Nokogiri::HTML(body)
html.search('.data_midlle_rss a').map{|v|
href = URI.join(url, v.attr('href')).to_s
uid = href.split("?n=")[-1]
title = v.text()
title_translations = I18n.available_locales.collect{|v| [v, title]}.to_h
{
url: href,
xml_url: href,
uid: uid,
title_translations: title_translations,
tags: title_translations,
is_rss: true
}
}
end
end