Edit for other plugins which need feed feature.

This commit is contained in:
BoHung Chiu 2022-05-22 18:36:26 +08:00
parent f8fcefa0c1
commit ae6601ccd7
8 changed files with 228 additions and 73 deletions

View File

@ -74,6 +74,31 @@ class Admin::FeedsController < OrbitAdminController
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 :text => 'success'
end
@ -170,7 +195,9 @@ class Admin::FeedsController < OrbitAdminController
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)
sf.save
sf.sync_data_to_annc
end
render :json => {"success" => true, "title" => params["channel_title_translations"][I18n.locale.to_s]}.to_json
end
@ -185,6 +212,9 @@ class Admin::FeedsController < OrbitAdminController
site_feed.feed_name_translations = params[:feed][:title_translations]
site_feed.disabled = false
site_feed.feed_url = params[:feed][:url]
module_app = ModuleApp.where(:key=>site_feed.channel_key).first
sync_fields_data = SiteFeed::ModuleAppSyncFields.map{|f| [f, module_app[f]] }.to_h
site_feed.update(sync_fields_data)
site_feed.save
render :json => {"success" => true}.to_json
end

View File

@ -4,51 +4,79 @@ class FeedsController < ApplicationController
feed = SiteFeed.where(:feed_uid=>params[:uid]).first
feed_annc = SiteFeedAnnc.where(:feed_id=>feed.id).first
if feed_annc
feeds_model = feed.feeds_model
if feeds_model.present?
feeds_model = feeds_model.constantize
end
feed_id = feed.id
feeds_uid_field = feed.feeds_uid_field rescue nil
feeds_update_callback = feed.feeds_update_callback rescue nil
feeds_time_field = feed.feeds_time_field
feeds_finish_callback = feed.feeds_finish_callback
category_id = feed.merge_with_category
can_create_record = feeds_model && feeds_uid_field && feeds_update_callback
locales = Site.first.in_use_locales rescue I18n.available_locales
locales.map!{|l| l.to_s}
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'
trans = {}
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"])
end
params[:data].each do |a|
a = JSON.parse(a)
a["category_id"] = category_id
locales.each do |locale|
locale_sym = locale.to_sym
time_field_value = Time.parse(a[feeds_time_field]) rescue a[feeds_time_field]
insert_idx = 0
if postdate
insert_idx = feed_annc[:all_contents_for_feed][locale_sym].index{|aa| aa["postdate"] <= postdate}
if time_field_value
insert_idx = feed_annc[:all_contents_for_feed][locale_sym].index{|aa| aa[feeds_time_field] <= time_field_value}
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
if can_create_record
record = feeds_model.where(feeds_uid_field=>a["id"], :site_feed_id=>feed_id).first
if record.nil?
record = feeds_model.new
record.instance_variable_set(:@skip_callback, true)
record[feeds_uid_field] = a["id"]
record[:site_feed_id] = feed_id
record.save
record.instance_variable_set(:@skip_callback, true)
end
record.send(feeds_update_callback, a)
end
end
feed_annc.instance_variable_set(:@skip_callback, true)
feed_annc.save!
elsif params[:type] == 'update'
trans = {}
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)
end
params[:data].each do |a|
a = JSON.parse(a)
a["category_id"] = category_id
locales.each do |locale|
locale_sym = locale.to_sym
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!
@ -58,6 +86,18 @@ class FeedsController < ApplicationController
end
end
end
if can_create_record
record = feeds_model.where(feeds_uid_field=>a["id"], :site_feed_id=>feed_id).first
if record.nil?
record = feeds_model.new
record.instance_variable_set(:@skip_callback, true)
record[feeds_uid_field] = a["id"]
record[:site_feed_id] = feed_id
record.save
record.instance_variable_set(:@skip_callback, true)
end
record.send(feeds_update_callback, a)
end
end
feed_annc.instance_variable_set(:@skip_callback, true)
feed_annc.save!
@ -70,6 +110,9 @@ class FeedsController < ApplicationController
end
feed_annc.instance_variable_set(:@skip_callback, true)
feed_annc.save!
if can_create_record
feeds_model.where(feeds_uid_field.to_sym.in =>params[:data].map{|a| a["id"]}, :site_feed_id=>feed_id).destroy
end
end
feed_data = feed_data.to_json
FileUtils.mkdir_p(feed_directory) if !File.exists?(feed_directory)
@ -77,6 +120,9 @@ class FeedsController < ApplicationController
feed_data.force_encoding("utf-8")
file.write(feed_data)
end
if feeds_finish_callback
feeds_model.send(feeds_finish_callback, params[:type])
end
end
render :json => {success: true}
end

View File

@ -1,6 +1,7 @@
class SiteFeed
include Mongoid::Document
include Mongoid::Timestamps
ModuleAppSyncFields = ["feeds_model", "feeds_uid_field", "feeds_update_callback", "feeds_time_field", "feeds_finish_callback", "feeds_update_statuses_callback"]
field :remote_site_url
field :merge_with_category
field :channel_name
@ -10,6 +11,12 @@ class SiteFeed
field :disabled, type: Boolean, default: false
field :feed_url
field :feed_uid
field :feeds_model
field :feeds_uid_field
field :feeds_update_callback
field :feeds_time_field, type: String, default: "postdate"
field :feeds_finish_callback
field :feeds_update_statuses_callback
field :enable_notify, type: Boolean, default: false
require 'feed_model/cache'
require 'fileutils'
@ -33,7 +40,25 @@ class SiteFeed
tmp.destroy
end
end
after_save do
unless @skip_callback
self.sync_data_to_annc
end
end
scope :enabled, ->{where(:disabled => false)}
def sync_data_to_annc(site_feed_annc=nil)
category_title = self.category[:title] rescue {}
tmp_channel_title = self.channel_title_for_cache
clone_fields =["channel_key", "merge_with_category", "remote_site_url", "feeds_model", "feeds_uid_field", "feeds_update_callback", "feeds_time_field", "feeds_update_statuses_callback"]
(site_feed_annc ? [site_feed_annc] : SiteFeedAnnc.where(:feed_id=>self.id)).each do |tmp|
clone_fields.each do |f|
tmp.send("#{f}=", self.send(f))
end
tmp[:feed_name] = self[:feed_name]
tmp.category_title = category_title
tmp.channel_title = tmp_channel_title
end
end
def get_annc(force_refresh=false)
main_directory = File.join("#{Rails.root}","public","site_feeds")
feed_directory = File.join(main_directory.to_s, self.id.to_s)

View File

@ -13,10 +13,17 @@ class SiteFeedAnnc
field :merge_with_category
field :remote_site_url
field :channel_title
field :feeds_model
field :feeds_model
field :feeds_uid_field
field :feeds_update_callback
field :feeds_time_field, type: String, default: "postdate"
field :feeds_finish_callback
field :feeds_update_statuses_callback
#I18n.available_locales.each do |locale|
# index({ "all_contents_for_feed.#{locale}.is_hidden"=> -1,
# "all_contents_for_feed.#{locale}.is_top"=> -1,
# "all_contents_for_feed.#{locale}.postdate"=> -1}, { unique: false, background: true, name: "cache_#{locale}" })
# "all_contents_for_feed.#{locale}.#{self.feeds_time_field}"=> -1}, { unique: false, background: true, name: "cache_#{locale}" })
#end
def get_annc(annc_uid)
Array(self[:all_contents_for_feed][I18n.locale.to_s]).select{|v| v['id']==annc_uid}[0] rescue {}
@ -49,7 +56,6 @@ class SiteFeedAnnc
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
@ -98,6 +104,31 @@ class SiteFeedAnnc
tmp["more"] = trans[locale]['more_plus']
tmp["view_count"] = ""
else
new_tmp = {}
tmp.each do |key,value|
key = key.to_s
if key.include? "_translations"
new_tmp[key] = value
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
new_tmp[key] = {}
value.each do |sub_k,sub_v|
if sub_k.include? "_translations"
new_tmp[key][sub_k] = sub_v
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)
tmp['statuses'] = []
if self[:top_list].count == 0 || self[:top_list].exclude?(tmp['id'])
tmp[:is_top] = false
@ -130,27 +161,10 @@ class SiteFeedAnnc
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
feeds_time_field = self.feeds_time_field
if feeds_time_field
tmp[feeds_time_field] = tmp[feeds_time_field].blank? ? nil : tmp[feeds_time_field].to_time
end
return tmp
end
@ -158,6 +172,7 @@ class SiteFeedAnnc
feed = SiteFeed.find(self.feed_id)
anns = feed.get_annc(force_refresh)
cat = self[:category_title]
feeds_time_field = self.feeds_time_field
if locales.nil?
locales = Site.first.in_use_locales rescue I18n.available_locales
end
@ -189,6 +204,11 @@ class SiteFeedAnnc
locale = I18n.locale.to_s
max_len = ((max_len.to_i < 0 rescue true) ? 0 : max_len.to_i)
if max_len > 0
module_app = ModuleApp.where(:key=>channel_key).first
feeds_time_field = module_app.feeds_time_field rescue nil
if feeds_time_field.nil?
feeds_time_field = 'postdate'
end
match_cond = {"channel_key"=>channel_key}
if !merge_with_category.blank? && merge_with_category.exclude?('all')
match_cond["merge_with_category"] = {"$in"=>merge_with_category}
@ -200,7 +220,7 @@ class SiteFeedAnnc
{"$match"=>match_cond},
{"$project"=>{"data"=>"$all_contents_for_feed.#{locale}"}},
{"$unwind"=>"$data"},
{"$sort"=>{"data.is_hidden"=>-1,"data.is_top"=>-1,"data.postdate"=>-1}},
{"$sort"=>{"data.is_hidden"=>-1,"data.is_top"=>-1,"data.#{feeds_time_field}"=>-1}},
{"$match"=>{"data.is_hidden"=>{"$ne"=>true},
"data.postdate"=>{"$lte"=>Time.now},
"data.title" => {"$gt"=>""}

View File

@ -8,13 +8,38 @@
width: 50%;
}
</style>
<% available_locales = Site.first.in_use_locales rescue I18n.available_locales %>
<div class="subtitle">
<%= "#{t('subtitle')}(#{available_locales.collect{|v| t(v)}.join('/')})" %>:
<%= available_locales.collect{|v| "<div class=\"block\">#{@annc['subtitle_translations'][v]}</div>"}.join(' / ').html_safe %>
</div>
<br>
<div class="content">
<%= "#{t('content')}(#{available_locales.collect{|v| t(v)}.join('/')})" %>:
<%= available_locales.collect{|v| "<div class=\"block\">#{@annc['text_translations'][v]}</div>"}.join(' / ').html_safe %>
</div>
<%
available_locales = Site.first.in_use_locales rescue I18n.available_locales
localize_keys = @annc.keys.select{|k| k.include?("_translations") && !k.include?("image")}
trans_first = localize_keys & ['title_translations','subtitle_translations','text_translations']
trans_keys = trans_first + (localize_keys - trans_first)
%>
<% trans_keys.each_with_index do |kt, i| %>
<% k = kt.sub("_translations",'') %>
<%= "#{t(k)}(#{available_locales.collect{|v| t(v)}.join('/')})".html_safe %>:
<%= available_locales.collect{|v| "<div class=\"block\">#{@annc[kt][v] rescue ''}</div>"}.join(' / ').html_safe %>
<br>
<% end %>
<%
file_field = @annc.keys.select{|k| k.include?("files")}[0]
can_display_files = false
locale = I18n.locale.to_s
if file_field && @annc[file_field].count != 0
files = @annc[file_field]
file_title_field = files[0].keys.select{|k| k.include?('title') || k.include?('name')}[0]
file_title_field_localize = file_title_field && file_title_field.include?('_translations')
file_url_field = files[0].keys.select{|k| k.include?('url')}[0]
can_display_files = file_title_field && file_url_field
end
%>
<% if file_field %>
<%= t('file_') %>:
<% if can_display_files %>
<div class="block">
<% files.each do |file| %>
<% file_title = file_title_field_localize ? file[file_title_field][locale] : file[file_title_field] %>
<a href="<%= file[file_url_field] %>" title="<%= file_title %>"><%= file_title %></a>
<% end %>
</div>
<% end %>
<% end %>

View File

@ -26,19 +26,24 @@ Rails.application.routes.draw do
if tmp.nil?
tmp = SiteFeedAnnc.new(feed_id: site_feed.id)
end
tmp[:feed_name] = site_feed[:feed_name]
tmp.merge_with_category = site_feed.merge_with_category
tmp.channel_key = site_feed.channel_key
tmp.category_title = site_feed.category[:title] rescue {}
tmp.remote_site_url = site_feed.remote_site_url
tmp.channel_title = site_feed.channel_title_for_cache
site_feed.sync_data_to_annc(tmp)
tmp.all_contents_for_feed = tmp.cache_annc(false,locales,trans)
tmp.save
if site_feed.feeds_model && site_feed.feeds_finish_callback
feeds_model = site_feed.feeds_model.constantize
feeds_model.send(site_feed.feeds_finish_callback, "update_all", {"data"=>site_feed.get_annc(false),"feed_id"=>site_feed.id,"category_id"=>site_feed.merge_with_category})
end
elsif !tmp.nil?
tmp.destroy
end
end
SiteFeedAnnc.create_indexes
sync_fields = SiteFeed::ModuleAppSyncFields
ModuleApp.where(:feeds_model.ne=>nil).each do |module_app|
sync_fields_data = sync_fields.map{|f| [f, module_app[f]] }.to_h
SiteFeedAnnc.where(:channel_key=>module_app.key).update_all(sync_fields_data)
SiteFeed.where(:channel_key=>module_app.key).update_all(sync_fields_data)
end
end
rescue => e
puts ['feed_routes',e]

View File

@ -15,31 +15,31 @@ module FeedModel
if tmp.nil?
tmp = SiteFeedAnnc.new(feed_id: feed.id)
end
tmp[:feed_name] = feed[:feed_name]
tmp.merge_with_category = feed.merge_with_category
tmp.channel_key = feed.channel_key
tmp.category_title = feed.category[:title] rescue {}
tmp.remote_site_url = feed.remote_site_url
tmp.channel_title = feed.channel_title_for_cache
tmp.all_contents_for_feed = tmp.cache_annc(true)
tmp.save
if feed.feeds_model && feed.feeds_finish_callback
feeds_model = feed.feeds_model.constantize
feeds_model.send(feed.feeds_finish_callback, "update_all", {"data"=>feed.get_annc(false),"feed_id"=>feed.id,"category_id"=>feed.merge_with_category})
end
end
def do_before_save
if self.class == Category
Thread.new do
SiteFeedAnnc.where(merge_with_category: self.id.to_s).each do |site_feed_annc|
recreate_annc_cache(site_feed_annc)
end
end
elsif self.class == SiteFeed
if self.disabled != true
unless @skip_callback
if self.class == Category
Thread.new do
recreate_annc_cache(self)
SiteFeedAnnc.where(merge_with_category: self.id.to_s).each do |site_feed_annc|
recreate_annc_cache(site_feed_annc)
end
end
else
tmp = SiteFeedAnnc.where(feed_id: self.id).first
if !tmp.nil?
tmp.destroy
elsif self.class == SiteFeed
if self.disabled != true
Thread.new do
recreate_annc_cache(self)
end
else
tmp = SiteFeedAnnc.where(feed_id: self.id).first
if !tmp.nil?
tmp.destroy
end
end
end
end

View File

@ -14,7 +14,11 @@ module Feeds
base_url File.expand_path File.dirname(__FILE__)
categorizable
authorizable
begin
avoid_page_cache SiteFeed
rescue => e
puts ["avoid_page_cache", e.to_s]
end
side_bar do
head_label_i18n 'feed.feed', icon_class: "icons-rss"
available_for "managers"