mirror of
https://github.com/discourse/discourse.git
synced 2024-12-13 10:13:45 +08:00
30990006a9
This reduces chances of errors where consumers of strings mutate inputs and reduces memory usage of the app. Test suite passes now, but there may be some stuff left, so we will run a few sites on a branch prior to merging
55 lines
1.8 KiB
Ruby
55 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rexml/document'
|
|
require 'rss'
|
|
|
|
class FeedElementInstaller
|
|
private_class_method :new
|
|
|
|
def self.install(element_name, feed)
|
|
# RSS Specification at http://cyber.harvard.edu/rss/rss.html#extendingRss
|
|
# > A RSS feed may contain [non-standard elements], only if those elements are *defined in a namespace*
|
|
|
|
new(element_name, feed).install if element_name.include?(':')
|
|
end
|
|
|
|
attr_reader :feed, :original_name, :element_namespace, :element_name, :element_accessor
|
|
|
|
def initialize(element_name, feed)
|
|
@feed = feed
|
|
@original_name = element_name
|
|
@element_namespace, @element_name = *element_name.split(':')
|
|
@element_accessor = "#{@element_namespace}_#{@element_name}"
|
|
end
|
|
|
|
def element_uri
|
|
@element_uri ||= REXML::Document.new(feed).root&.attributes&.namespaces&.fetch(@element_namespace, '') || ''
|
|
end
|
|
|
|
def install
|
|
install_in_rss unless installed_in_rss?
|
|
install_in_atom unless installed_in_atom?
|
|
end
|
|
|
|
private
|
|
|
|
def install_in_rss
|
|
RSS::Rss::Channel::Item.install_text_element(element_name, element_uri, '?', element_accessor, nil, original_name)
|
|
RSS::BaseListener.install_get_text_element(element_uri, element_name, element_accessor)
|
|
end
|
|
|
|
def install_in_atom
|
|
RSS::Atom::Entry.install_text_element(element_name, element_uri, '?', element_accessor, nil, original_name)
|
|
RSS::Atom::Feed::Entry.install_text_element(element_name, element_uri, '?', element_accessor, nil, original_name)
|
|
RSS::BaseListener.install_get_text_element(element_uri, element_name, element_accessor)
|
|
end
|
|
|
|
def installed_in_rss?
|
|
RSS::Rss::Channel::Item.method_defined?(element_accessor)
|
|
end
|
|
|
|
def installed_in_atom?
|
|
RSS::Atom::Entry.method_defined?(element_accessor) || RSS::Atom::Feed::Entry.method_defined?(element_accessor)
|
|
end
|
|
end
|