Skip to content

Commit

Permalink
Merge remote branch 'core/wordpress-import' into pimp
Browse files Browse the repository at this point in the history
  • Loading branch information
cykod committed Sep 27, 2010
2 parents bac9b52 + 30b28bd commit 6459c20
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 20 deletions.
29 changes: 26 additions & 3 deletions app/models/domain_file.rb
Expand Up @@ -596,9 +596,14 @@ def self.temporary_folder

# Returns the themes folder of the file system
def self.themes_folder
DomainFile.find(:first,:conditions => "name = 'Themes' and parent_id = #{self.root_folder.id}") || DomainFile.create(:name => 'Themes', :parent_id => self.root_folder.id, :file_type => 'fld')
self.push_folder 'Themes'
end


def self.push_folder(name, opts={})
parent_id = opts[:parent_id] || self.root_folder.id
DomainFile.find(:first,:conditions => ["name = ? and parent_id = ?", name, parent_id]) || DomainFile.create(:name => name, :parent_id => parent_id, :file_type => 'fld')
end

# Is this an image
def image?; self.file_type == 'img'; end

Expand Down Expand Up @@ -1329,7 +1334,25 @@ def generate_csv
nil
end
end


def add(filename, opts={})
return nil unless self.folder?

filename = filename.filename if filename.is_a?(DomainFile)

# if it is a url, create a URI
if filename =~ /^https?:\/\//
begin
filename = URI.parse(filename)
rescue URI::Error => e
return nil
end
end

process_immediately = opts.has_key?(:process_immediately) ? opts[:process_immediately] : true
DomainFile.create :parent_id => self.id, :filename => filename, :process_immediately => process_immediately
end

def self.download(uri, limit=10)
raise ArgumentError, 'HTTP redirect too deep' if limit == 0

Expand Down
1 change: 1 addition & 0 deletions config/environment.rb
Expand Up @@ -98,6 +98,7 @@ def webiva_remove_load_paths(file)
config.gem 'libxml-ruby', :lib => 'xml'
config.gem 'soap4r', :lib => 'soap/soap'
config.gem "json"
config.gem "httparty"

if RAILS_ENV == 'test'
config.gem 'factory_girl',:source => 'http://gemcutter.org'
Expand Down
12 changes: 11 additions & 1 deletion lib/active_web_service.rb
Expand Up @@ -212,7 +212,17 @@ def #{name}(#{function_args.join(',')})
end
method_src << "end\n"

self.class_eval method_src, __FILE__, __LINE__
if options[:instance]
options[:instance].instance_eval method_src, __FILE__, __LINE__
elsif options[:class]
options[:class].class_eval method_src, __FILE__, __LINE__
else
self.class_eval method_src, __FILE__, __LINE__
end
end

def route(name, path, options={})
self.class.route name, path, options.merge(:instance => self)
end

# Creates routes for a RESTful API
Expand Down
67 changes: 61 additions & 6 deletions vendor/modules/blog/app/controllers/blog/manage_controller.rb
Expand Up @@ -235,18 +235,73 @@ def import
@blog = Blog::BlogBlog.find(params[:path][0])
blog_path(@blog,"Import Blog")

if request.post? && params[:import] && @file = DomainFile.find_by_id(params[:import][:import_file_id])
@import = ImportOptions.new params[:import]
@import.wordpress_import_settings = ['comments', 'pages'] unless params[:import]

if request.post? && @import.valid?
if params[:commit]
@blog.import_file(@file,myself)
if @import.import @blog, myself
redirect_to :action => 'index', :path => [ @blog.id ]
end
else
redirect_to :action => 'index', :path => [ @blog.id ]
end
redirect_to :action => 'index', :path => [ @blog.id ]
end


end

protected

class ImportOptions < HashModel
attributes :import_file_id => nil, :wordpress_export_file_id => nil, :wordpress_url => nil, :wordpress_username => nil, :wordpress_password => nil, :wordpress_import_settings => []

domain_file_options :import_file_id, :wordpress_export_file_id

def validate
if self.import_file_id.blank? && self.wordpress_export_file_id.blank? && self.wordpress_url.blank?
self.errors.add_to_base 'Import settings not specified'
elsif self.import_file_id.blank? && self.wordpress_export_file_id.blank? && ! self.wordpress_url.blank?
self.errors.add(:wordpress_url, 'is invalid') unless URI::regexp(%w(http https)).match(self.wordpress_url)
self.errors.add(:wordpress_username, 'is missing') if self.wordpress_username.blank?
self.errors.add(:wordpress_password, 'is missing') if self.wordpress_password.blank?
end
end

def wordpress_importer
return @wordpress_importer if @wordpress_importer
@wordpress_importer = Blog::WordpressImporter.new
@wordpress_importer.import_comments = self.wordpress_import_settings.include?('comment')
@wordpress_importer.import_pages = self.wordpress_import_settings.include?('pages')
@wordpress_importer
end

def import(blog, user)
if self.import_file
blog.import_file(self.import_file, user)
elsif self.wordpress_export_file
self.wordpress_importer.blog = blog
self.wordpress_importer.import_file(self.wordpress_export_file)
self.errors.add(:wordpress_export_file_id, self.wordpress_importer.error) unless self.wordpress_importer.import
elsif self.wordpress_url
self.wordpress_importer.blog = blog
unless self.wordpress_importer.import_site(self.wordpress_url, self.wordpress_username, self.wordpress_password)
if self.wordpress_importer.error == 'Login failed'
self.errors.add(:wordpress_username, 'is invalid')
self.errors.add(:wordpress_password, 'is invalid')
else
self.errors.add(:wordpress_url, 'is invalid')
self.errors.add_to_base(self.wordpress_importer.error)
end
end

unless self.wordpress_importer.error
self.errors.add_to_base(self.wordpress_importer.error) unless self.wordpress_importer.import
end
end

self.errors.length > 0 ? false : true
end
end

def blog_path(blog,path=nil)
base = ['Content']
base << 'Site Blogs' if blog.is_user_blog?
Expand Down
188 changes: 188 additions & 0 deletions vendor/modules/blog/app/models/blog/wordpress_importer.rb
@@ -0,0 +1,188 @@

class Blog::WordpressImporter
attr_accessor :xml, :blog, :images, :folder, :error, :import_comments, :import_pages

include ActionView::Helpers::TagHelper
include ActionView::Helpers::TextHelper

def initialize
self.images = {}
self.import_pages = true
self.import_comments = true
end

def folder
@folder ||= DomainFile.push_folder self.blog.name
end

def import_file(file)
file = file.filename if file.is_a?(DomainFile)
File.open(file, 'r') { |f| self.xml = f.read }
true
end

def import_site(url, username, password)
service = Blog::WordpressWebService.new url, username, password
unless service.login
self.error = service.error
return false
end

self.xml = service.export
unless self.xml
self.error = service.error
return false
end

true
end

def parse
begin
Hash.from_xml self.xml.gsub('excerpt:encoded>', 'excerpt>').gsub(/<category domain="tag"(.*?)<\/category>/, '<tag\1</tag>')
rescue
end
end

def import
xml_data = self.parse
unless xml_data
self.error = 'WordPress file is invalid'
return false
end

unless xml_data['rss'] && xml_data['rss']['channel']
self.error = 'WordPress file is invalid'
return false
end

categories = {}
blog_categories = xml_data['rss']['channel']['category']
if blog_categories
blog_categories = [blog_categories] unless blog_categories.is_a?(Array)
blog_categories.each do |category|
cat = self.push_category(category)
next unless cat
categories[category['cat_name']] = cat
end
end

items = xml_data['rss']['channel']['item']
if items
items = [items] unless items.is_a?(Array)
items.each do |item|
if item['post_type'] == 'post'
self.create_post categories, item
elsif item['post_type'] == 'page'
self.create_page item
end
end
else
self.error = 'WordPress file has no posts to import'
return false
end

true
end

def push_category(opts={})
name = opts['cat_name']
return nil if name == 'Uncategorized'
return nil if name.blank?
self.blog.blog_categories.find_by_name(name) || self.blog.blog_categories.create(:name => name)
end

def parse_body(body)
body.gsub!(/src=("|')([^\1]+?)\1/) do |match|
quote = $1
src = $2
file = nil
file = self.folder.add(src) if src =~ /^http/
if file
self.images[src] = file
"src=#{quote}#{file.editor_url}#{quote}"
else
match
end
end

self.images.each do |src, file|
body.gsub! src, file.editor_url
end

simple_format body
end

def create_post(categories, item={})
body = item['encoded']
return if body.blank?
return if self.blog.blog_posts.find_by_permalink item['post_name']

status = item['status'] == 'publish' ? 'published' : 'draft'
disallow_comments = item['comment_status'] == 'open' ? false : true
post = self.blog.blog_posts.create :body => self.parse_body(body), :author => item['creator'], :title => item['title'], :status => 'published', :published_at => Time.parse(item['pubDate']), :status => status, :disallow_comments => disallow_comments, :permalink => item['post_name'], :created_at => Time.parse(item['post_date_gmt']), :preview => self.parse_body(item['excerpt'])

return unless post.id

post_categories = item['category']
post_categories = [post_categories] unless post_categories.is_a?(Array)
post_categories.uniq.each do |cat|
next unless categories[cat]
Blog::BlogPostsCategory.create :blog_post_id => post.id, :blog_category_id => categories[cat].id
end

comments = item['comment']
if comments
comments = [comments] unless comments.is_a?(Array)
comments.each do |comment|
self.create_comment post, comment
end
end

if item['tag']
tags = item['tag']
tags = [tags] unless tags.is_a?(Array)
post.add_tags tags.join(',')
end

post
end

def create_comment(post, comment)
return unless self.import_comments
return if comment['comment_content'].blank?
user = comment['comment_author_email'].blank? ? nil : EndUser.push_target(comment['comment_author_email'], :name => comment['comment_author'])
rating = comment['comment_approved'] == "1" ? 1 : 0
Comment.create :target => post, :end_user_id => user ? user.id : nil, :posted_at => Time.parse(comment['comment_date_gmt']), :posted_ip => comment['comment_author_IP'], :name => comment['comment_author'], :email => comment['comment_author_email'], :comment => comment['comment_content'], :rating => rating
end

def create_page(item)
return unless self.import_pages
body = item['encoded']
return if body.blank?

path = nil
begin
uri = URI.parse(item['link'])
path = uri.path.sub(/^\//, '').sub(/\/$/, '')
rescue
end

return unless path

node_path = nil
parent = SiteVersion.current.root_node
path.split('/').each do |node_path|
node_path = '' if node_path == 'home'
parent = parent.push_subpage(node_path)
end

parent.push_subpage(node_path) do |nd, rv|
rv.title = item['title']
# Basic Paragraph
rv.push_paragraph(nil, 'html') do |para|
para.display_body = self.parse_body(body)
end
end
end
end

0 comments on commit 6459c20

Please sign in to comment.