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 field :channel_title, :localize => true field :channel_key field :feed_name, localize: true 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' 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")} == [] `(crontab -l ; echo "*/5 * * * * /bin/bash -l -c 'cd #{site_root} && bundle exec rake feeds_module:make_cache > /dev/null'") | crontab` 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) FileUtils.rm_rf(feed_directory.to_s) if tmp.count!=0 tmp.destroy end end after_save do if @skip_callback unless @skip_fix_data update_url = self.remote_site_url_changed? if self.channel_title_changed? self.update_channel_title(update_url) elsif update_url self.update_remote_site_url end end else self.sync_data_to_annc end @site_feed_annc = nil end scope :enabled, ->{where(:disabled => false)} def site_feed_annc @site_feed_annc ||= SiteFeedAnnc.where(:feed_id=>self.id).first end def update_channel_title(update_url=false) #update_url=true will also fix remote_site_url in data site_feed_annc.update_channel_title(update_url) if site_feed_annc end def update_remote_site_url site_feed_annc.update_remote_site_url if site_feed_annc end 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 tmp.save 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) if !force_refresh && File.exists?(feed_directory) anns = JSON.parse(File.read(File.join(feed_directory.to_s, self.feed_uid + ".json")))[self.channel_key.pluralize] rescue [] else uri = URI(self.feed_url) res = get_response_body(uri) rescue '' FileUtils.mkdir_p(feed_directory) if !File.exists?(feed_directory) File.open(File.join(feed_directory.to_s,self.feed_uid + ".json"),"w") do |file| res.force_encoding("utf-8") file.write(res) end anns = JSON.parse(res)[self.channel_key.pluralize] rescue [] end anns end def get_response_body(uri) res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https', open_timeout: 60,read_timeout: 60, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http| req = Net::HTTP::Get.new(uri) http.request(req) end if res.code == "302" || res.code == "301" location = res['Location'] cookie = res['Set-Cookie'] if location[0] == "/" uri = URI.parse("#{uri.scheme}://#{uri.host}#{location}") else uri = URI.parse(location) end res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https', open_timeout: 60,read_timeout: 60, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http| req = Net::HTTP::Get.new(uri) req['Cookie'] = cookie http.request(req) end return res.body else return res.body end end def category Category.find(self.merge_with_category) rescue nil end def channel_title_for_cache !self[:channel_title].to_s.empty? ? self[:channel_title] : I18n.t("feed.source") end def http_request(http, request) response = http.request(request) if response.code.to_i == 301 || response.code.to_i == 302 location = response["location"] new_uri = URI(location) http = Net::HTTP.new(new_uri.host, new_uri.port) if location.include?('https') http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE end request.instance_variable_set(:@path, new_uri.path) response = http_request(http, request) end response 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 http_req.verify_mode = OpenSSL::SSL::VERIFY_NONE 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_request( http_req , request ) if response.code.to_i == 200 self.update(:enable_notify=>true) end 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 http_req.verify_mode = OpenSSL::SSL::VERIFY_NONE 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_request( http_req , request ) if response.code.to_i == 200 self.update(:enable_notify=>false) end end end end end