diff --git a/app/controllers/feeds_controller.rb b/app/controllers/feeds_controller.rb new file mode 100644 index 0000000..df8e7dd --- /dev/null +++ b/app/controllers/feeds_controller.rb @@ -0,0 +1,83 @@ +class FeedsController < ApplicationController + skip_before_action :verify_authenticity_token + def notify_change + feed = SiteFeed.where(:feed_uid=>params[:uid]).first + feed_annc = SiteFeedAnnc.where(:feed_id=>feed.id).first + if feed_annc + locales = Site.first.in_use_locales rescue I18n.available_locales + site_root_url = Site.first.root_url rescue "" + main_directory = File.join("#{Rails.root}","public","site_feeds") + feed_directory = File.join(main_directory.to_s, feed.id.to_s) + feed_data = JSON.parse(File.read(File.join(feed_directory.to_s, feed.feed_uid + ".json"))) + channel_key_pluralize = feed_annc.channel_key.pluralize + if params[:type] == 'create' + locales.each do |locale| + trans = {} + locale = locale.to_s + trans[locale] = {} + I18n.with_locale(locale) do + trans[locale]['top'] = I18n.t(:top) + trans[locale]['hot'] = I18n.t(:hot) + trans[locale]['more_plus'] = I18n.t("feed.more") + end + locale_sym = locale.to_sym + params[:data].each do |a| + a = JSON.parse(a) + postdate = Time.parse(a["postdate"]) + insert_idx = 0 + if postdate + insert_idx = feed_annc[:all_contents_for_feed][locale_sym].index{|aa| aa["postdate"] <= postdate} + insert_idx = 0 if insert_idx.nil? + end + feed_annc.all_contents_for_feed_will_change! + feed_annc[:all_contents_for_feed][locale_sym].insert(insert_idx, feed_annc.process_tmp(a,locale,trans,site_root_url)) + feed_data[channel_key_pluralize].insert(insert_idx, a) + end + end + feed_annc.instance_variable_set(:@skip_callback, true) + feed_annc.save! + elsif params[:type] == 'update' + locales.each do |locale| + trans = {} + locale = locale.to_s + trans[locale] = {} + I18n.with_locale(locale) do + trans[locale]['top'] = I18n.t(:top) + trans[locale]['hot'] = I18n.t(:hot) + trans[locale]['more_plus'] = I18n.t("feed.more") + end + locale_sym = locale.to_sym + params[:data].each do |a| + a = JSON.parse(a) + feed_annc[:all_contents_for_feed][locale_sym].each_with_index do |aa, i| + if aa["id"] == a["id"] + feed_annc.all_contents_for_feed_will_change! + feed_annc[:all_contents_for_feed][locale_sym][i] = feed_annc.process_tmp(a,locale,trans,site_root_url) + feed_data[channel_key_pluralize][i] = a + break + end + end + end + end + feed_annc.instance_variable_set(:@skip_callback, true) + feed_annc.save! + elsif params[:type] == 'destroy' + locales.each do |locale| + locale_sym = locale.to_sym + feed_annc.all_contents_for_feed_will_change! + feed_annc[:all_contents_for_feed][locale_sym].reject!{|a| params[:data].include?(a["id"]) } + feed_data[channel_key_pluralize].reject!{|a| params[:data].include?(a["id"]) } + end + feed_annc.instance_variable_set(:@skip_callback, true) + feed_annc.save! + end + feed_data = feed_data.to_json + FileUtils.mkdir_p(feed_directory) if !File.exists?(feed_directory) + File.open(File.join(feed_directory.to_s,feed.feed_uid + ".json"),"w") do |file| + feed_data.force_encoding("utf-8") + file.write(feed_data) + end + end + render :json => {success: true} + end +end \ No newline at end of file diff --git a/app/models/site_feed.rb b/app/models/site_feed.rb index 330b8c8..0b4574d 100644 --- a/app/models/site_feed.rb +++ b/app/models/site_feed.rb @@ -10,11 +10,13 @@ class SiteFeed field :disabled, type: Boolean, default: false field :feed_url field :feed_uid + field :enable_notify, type: Boolean, default: false require 'feed_model/cache' require 'fileutils' include FeedModel::Cache Category.send(:include,FeedModel::Cache) after_create do + self.add_notify crontab_list = `crontab -l`.split("\n") rescue [] site_root = Rails.root.to_s if crontab_list.select{|s| s.include?(site_root) && s.include?("feeds_module:make_cache")} == [] @@ -22,6 +24,7 @@ class SiteFeed end end before_destroy do + self.remove_notify tmp = SiteFeedAnnc.where(feed_id: self.id) main_directory = File.join("#{Rails.root}","public","site_feeds") feed_directory = File.join(main_directory.to_s, self.id.to_s) @@ -83,4 +86,38 @@ class SiteFeed def channel_title_for_cache !self[:channel_title].to_s.empty? ? self[:channel_title] : I18n.t("feed.source") end + def add_notify + unless self.enable_notify + root_url = Site.first.root_url rescue "" + if root_url.present? + uri = URI(self.remote_site_url) + http_req = Net::HTTP.new(uri.host, uri.port) + if self.remote_site_url.include?('https') + http_req.use_ssl = true + end + http_req.open_timeout = 10 + request = Net::HTTP::Post.new("/xhr/#{self.channel_key.pluralize}/feed_add_remote/#{self.feed_uid}", 'Content-Type' => 'application/json') + request.body = {"url"=>root_url}.to_json + response = http_req.request(request) + self.update(:enable_notify=>true) + end + end + end + def remove_notify + if self.enable_notify + root_url = Site.first.root_url rescue "" + if root_url.present? + uri = URI(self.remote_site_url) + http_req = Net::HTTP.new(uri.host, uri.port) + if self.remote_site_url.include?('https') + http_req.use_ssl = true + end + http_req.open_timeout = 10 + request = Net::HTTP::Post.new("/xhr/#{self.channel_key.pluralize}/feed_remove_remote/#{self.feed_uid}", 'Content-Type' => 'application/json') + request.body = {"url"=>root_url}.to_json + response = http_req.request(request) + self.update(:enable_notify=>false) + end + end + end end \ No newline at end of file diff --git a/app/models/site_feed_annc.rb b/app/models/site_feed_annc.rb index 882827c..82b9b8d 100644 --- a/app/models/site_feed_annc.rb +++ b/app/models/site_feed_annc.rb @@ -22,10 +22,138 @@ class SiteFeedAnnc Array(self[:all_contents_for_feed][I18n.locale.to_s]).select{|v| v['id']==annc_uid}[0] rescue {} end before_save do - if self.top_list_changed? || self.hot_list_changed? || self.hidden_annc_changed? || self.category_title_changed? - self[:all_contents_for_feed] = self.cache_annc + unless @skip_callback + if self.top_list_changed? || self.hot_list_changed? || self.hidden_annc_changed? || self.category_title_changed? + self[:all_contents_for_feed] = self.cache_annc + end end end + def process_tmp(a, locale=nil, trans=nil, site_root_url=nil) + cat = self[:category_title] + locale = I18n.locale.to_s if locale.nil? + if trans.nil? + trans = {} + locales.each do |locale| + locale = locale.to_s + trans[locale] = {} + I18n.with_locale(locale) do + trans[locale]['top'] = I18n.t(:top) + trans[locale]['hot'] = I18n.t(:hot) + trans[locale]['more_plus'] = I18n.t("feed.more") + end + end + end + if site_root_url.nil? + site_root_url = Site.first.root_url rescue "" + end + tmp = a.deep_dup + tmp[:is_hidden] = self.hidden_annc.include?(tmp['id']) + if self.channel_key == "announcement" + tmp["postdate"] = tmp["postdate"].blank? ? nil : tmp["postdate"].to_time + tmp['statuses'] = [] + if self[:top_list].count == 0 || self[:top_list].exclude?(tmp['id']) + tmp[:is_top] = false + else + tmp[:is_top] = true + tmp['statuses'] << { + "status" => trans[locale]['top'], + "status-class" => "status-top" + } + end + if self[:hot_list].count == 0 || self[:top_list].exclude?(tmp['id']) + tmp[:is_hot] = false + else + tmp[:is_hot] = true + tmp['statuses'] << { + "status" => trans[locale]['hot'], + "status-class" => "status-hot" + } + end + tmp["category"] = cat + tmp["source_url"] = self.remote_site_url + + tmp["source-site"] = self.remote_site_url + tmp["source-site-title"] = (self[:channel_title][locale] rescue "") + tmp["params"] = tmp["params"].to_s + "_" + self.feed_id.to_s + "h" + if !tmp["source-site-title"].blank? + tmp['statuses'] << { + "status" => "#{tmp["source-site-title"]}", + "status-class" => "status-source" + } + end + + files = tmp["bulletin_files"].collect{|bf| { "file_url" => bf["url"], "file_title" => (bf["title_translations"][locale].blank? ? File.basename(bf["url"]) : bf["title_translations"][locale] rescue '') }} rescue [] + links = tmp["bulletin_links"].map{|link| { "link_url" => link["url"], "link_title" => (link["title_translations"][locale].blank? ? link["url"] : link["title_translations"][locale]) } } rescue [] + tmp["bulletin_links"] = links + tmp["bulletin_files"] = files + tmp["title"] = tmp["title_translations"][locale] + tmp["subtitle"] = tmp["subtitle_translations"][locale] + tmp["source-site-link"] = tmp["source-site"] + tmp["source-site"] = "#{tmp["source-site-title"]}" + tmp["link_to_show"] = !tmp["external_link"].blank? ? tmp["external_link"] : nil + tmp["target"] = (site_root_url.blank? || tmp["link_to_show"].blank?) ? '_blank' : (tmp["link_to_show"].include?(site_root_url) ? '_self' : '_blank') + tmp["img_src"] = tmp["image"]["thumb"] || "/assets/announcement-default.jpg" + tmp["img_src"] = "/assets/announcement-default.jpg" if tmp["img_src"] == "" + tmp["img_description"] = tmp["image_description_translations"][locale] + tmp["more"] = trans[locale]['more_plus'] + tmp["view_count"] = "" + else + tmp['statuses'] = [] + if self[:top_list].count == 0 || self[:top_list].exclude?(tmp['id']) + tmp[:is_top] = false + else + tmp[:is_top] = true + tmp['statuses'] << { + "status" => trans[locale]['top'], + "status-class" => "status-top" + } + end + if self[:hot_list].count == 0 || self[:top_list].exclude?(tmp['id']) + tmp[:is_hot] = false + else + tmp[:is_hot] = true + tmp['statuses'] << { + "status" => trans[locale]['hot'], + "status-class" => "status-hot" + } + end + tmp["category"] = cat + tmp["source-site"] = self.remote_site_url + tmp["source-site-title"] = (self[:channel_title][locale] rescue "") + tmp["params"] = tmp["params"].to_s + "_" + self.feed_id.to_s + "h" + tmp['statuses'] << { + "status" => "#{tmp["source-site-title"]}", + "status-class" => "status-source" + } + tmp["source-site-link"] = tmp["source-site"] + tmp["source-site"] = "#{tmp["source-site-title"]}" + tmp["target"] = "_self" + tmp["more"] = trans[locale]['more_plus'] + tmp["view_count"] = "" + new_tmp = {} + tmp.each do |key,value| + if key.include? "_translations" + new_tmp[key.sub("_translations","")] = value[locale].to_s rescue "" + elsif key.include?("date") || key.include?("Date") + new_tmp[key] = DateTime.parse(value) rescue nil + else + if value.class == Hash + value.each do |sub_k,sub_v| + if sub_k.include? "_translations" + new_tmp[key][sub_k.sub("_translations","")] = sub_v[locale].to_s rescue "" + else + new_tmp[key][sub_k] = sub_v + end + end + else + new_tmp[key] = value + end + end + end + tmp = BSON::Document.new(new_tmp) + end + return tmp + end def cache_annc(force_refresh=false,locales=nil,trans=nil) feed = SiteFeed.find(self.feed_id) anns = feed.get_annc(force_refresh) @@ -50,112 +178,7 @@ class SiteFeedAnnc locales.each do |locale| locale = locale.to_s data_for_locale = anns.collect do |a| - tmp = a.deep_dup - tmp[:is_hidden] = self.hidden_annc.include?(tmp['id']) - if self.channel_key == "announcement" - tmp["postdate"] = tmp["postdate"].blank? ? nil : tmp["postdate"].to_time - tmp['statuses'] = [] - if self[:top_list].count == 0 || self[:top_list].exclude?(tmp['id']) - tmp[:is_top] = false - else - tmp[:is_top] = true - tmp['statuses'] << { - "status" => trans[locale]['top'], - "status-class" => "status-top" - } - end - if self[:hot_list].count == 0 || self[:top_list].exclude?(tmp['id']) - tmp[:is_hot] = false - else - tmp[:is_hot] = true - tmp['statuses'] << { - "status" => trans[locale]['hot'], - "status-class" => "status-hot" - } - end - tmp["category"] = cat - tmp["source_url"] = self.remote_site_url - - tmp["source-site"] = self.remote_site_url - tmp["source-site-title"] = (self[:channel_title][locale] rescue "") - tmp["params"] = tmp["params"].to_s + "_" + self.feed_id.to_s + "h" - if !tmp["source-site-title"].blank? - tmp['statuses'] << { - "status" => "#{tmp["source-site-title"]}", - "status-class" => "status-source" - } - end - - files = tmp["bulletin_files"].collect{|bf| { "file_url" => bf["url"], "file_title" => (bf["title_translations"][locale].blank? ? File.basename(bf["url"]) : bf["title_translations"][locale] rescue '') }} rescue [] - links = tmp["bulletin_links"].map{|link| { "link_url" => link["url"], "link_title" => (link["title_translations"][locale].blank? ? link["url"] : link["title_translations"][locale]) } } rescue [] - tmp["bulletin_links"] = links - tmp["bulletin_files"] = files - tmp["title"] = tmp["title_translations"][locale] - tmp["subtitle"] = tmp["subtitle_translations"][locale] - tmp["source-site-link"] = tmp["source-site"] - tmp["source-site"] = "#{tmp["source-site-title"]}" - tmp["link_to_show"] = !tmp["external_link"].blank? ? tmp["external_link"] : nil - tmp["target"] = (site_root_url.blank? || tmp["link_to_show"].blank?) ? '_blank' : (tmp["link_to_show"].include?(site_root_url) ? '_self' : '_blank') - tmp["img_src"] = tmp["image"]["thumb"] || "/assets/announcement-default.jpg" - tmp["img_description"] = tmp["image_description_translations"][locale] - tmp["more"] = trans[locale]['more_plus'] - tmp["view_count"] = "" - else - tmp['statuses'] = [] - if self[:top_list].count == 0 || self[:top_list].exclude?(tmp['id']) - tmp[:is_top] = false - else - tmp[:is_top] = true - tmp['statuses'] << { - "status" => trans[locale]['top'], - "status-class" => "status-top" - } - end - if self[:hot_list].count == 0 || self[:top_list].exclude?(tmp['id']) - tmp[:is_hot] = false - else - tmp[:is_hot] = true - tmp['statuses'] << { - "status" => trans[locale]['hot'], - "status-class" => "status-hot" - } - end - tmp["category"] = cat - tmp["source-site"] = self.remote_site_url - tmp["source-site-title"] = (self[:channel_title][locale] rescue "") - tmp["params"] = tmp["params"].to_s + "_" + self.feed_id.to_s + "h" - tmp['statuses'] << { - "status" => "#{tmp["source-site-title"]}", - "status-class" => "status-source" - } - tmp["source-site-link"] = tmp["source-site"] - tmp["source-site"] = "#{tmp["source-site-title"]}" - tmp["target"] = "_self" - tmp["more"] = trans[locale]['more_plus'] - tmp["view_count"] = "" - new_tmp = {} - tmp.each do |key,value| - if key.include? "_translations" - new_tmp[key.sub("_translations","")] = value[locale].to_s rescue "" - elsif key.include?("date") || key.include?("Date") - new_tmp[key] = DateTime.parse(value) rescue nil - else - if value.class == Hash - value.each do |sub_k,sub_v| - if sub_k.include? "_translations" - new_tmp[key][sub_k.sub("_translations","")] = sub_v[locale].to_s rescue "" - else - new_tmp[key][sub_k] = sub_v - end - end - else - new_tmp[key] = value - end - end - end - tmp = BSON::Document.new(new_tmp) - end - tmp + tmp = process_tmp(a, locale, trans, site_root_url) end cache_data[locale.to_s] = data_for_locale end diff --git a/config/routes.rb b/config/routes.rb index 06b8d45..1d9db93 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,6 +16,7 @@ Rails.application.routes.draw do end SiteFeedAnnc.where(:feed_id.nin=>SiteFeed.all.pluck(:id)).destroy SiteFeed.each do |site_feed| + site_feed.add_notify count = SiteFeedAnnc.where(feed_id: site_feed.id).count if count>1 SiteFeedAnnc.where(feed_id: site_feed.id).limit(count-1).destroy @@ -61,5 +62,5 @@ Rails.application.routes.draw do post "/feeds/force_refresh", to: 'feeds#force_refresh' end end - + post "/xhr/feeds/notify_change" => "feeds#notify_change" end