module MetaWeblogStructs class Article < ActionWebService::Struct member :description, :string member :title, :string member :postid, :string member :url, :string member :link, :string member :permaLink, :string member :categories, [:string] member :mt_text_more, :string member :mt_excerpt, :string member :mt_keywords, :string member :mt_allow_comments, :int member :mt_allow_pings, :int member :mt_convert_breaks, :string member :mt_tb_ping_urls, [:string] member :dateCreated, :time end class MediaObject < ActionWebService::Struct member :bits, :string member :name, :string member :type, :string end class Url < ActionWebService::Struct member :url, :string end end class MetaWeblogApi < ActionWebService::API::Base inflect_names false api_method :getCategories, :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string} ], :returns => [[:string]] api_method :getPost, :expects => [ {:postid => :string}, {:username => :string}, {:password => :string} ], :returns => [MetaWeblogStructs::Article] api_method :getRecentPosts, :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string}, {:numberOfPosts => :int} ], :returns => [[MetaWeblogStructs::Article]] api_method :deletePost, :expects => [ {:appkey => :string}, {:postid => :string}, {:username => :string}, {:password => :string}, {:publish => :int} ], :returns => [:bool] api_method :editPost, :expects => [ {:postid => :string}, {:username => :string}, {:password => :string}, {:struct => MetaWeblogStructs::Article}, {:publish => :int} ], :returns => [:bool] api_method :newPost, :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string}, {:struct => MetaWeblogStructs::Article}, {:publish => :int} ], :returns => [:string] api_method :newMediaObject, :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string}, {:data => MetaWeblogStructs::MediaObject} ], :returns => [MetaWeblogStructs::Url] end class MetaWeblogService < TypoWebService web_service_api MetaWeblogApi before_invocation :authenticate def getCategories(blogid, username, password) Category.find(:all).collect { |c| c.name } end def getPost(postid, username, password) article = this_blog.articles.find(postid) article_dto_from(article) end def getRecentPosts(blogid, username, password, numberOfPosts) this_blog.articles.find(:all, :order => "created_at DESC", :limit => numberOfPosts).collect{ |c| article_dto_from(c) } end def newPost(blogid, username, password, struct, publish) article = this_blog.articles.build article.body = struct['description'] || '' article.title = struct['title'] || '' article.published = publish article.author = username article.published_at = struct['dateCreated'].to_time.getlocal rescue Time.now article.user = @user # Movable Type API support article.allow_comments = struct['mt_allow_comments'] || this_blog.default_allow_comments article.allow_pings = struct['mt_allow_pings'] || this_blog.default_allow_pings article.extended = struct['mt_text_more'] || '' article.excerpt = struct['mt_excerpt'] || '' article.keywords = struct['mt_keywords'] || '' article.text_filter = TextFilter.find_by_name(struct['mt_convert_breaks'] || this_blog.text_filter) if struct['categories'] article.categories.clear Category.find(:all).each do |c| article.categories << c if struct['categories'].include?(c.name) end end if article.save article.id.to_s else raise article.errors.full_messages * ", " end end def deletePost(appkey, postid, username, password, publish) article = this_blog.articles.find(postid) article.destroy true end def editPost(postid, username, password, struct, publish) article = this_blog.articles.find(postid) article.body = struct['description'] || '' article.title = struct['title'] || '' article.published = publish article.author = username article.published_at = struct['dateCreated'].to_time.getlocal unless struct['dateCreated'].blank? # Movable Type API support article.allow_comments = struct['mt_allow_comments'] || this_blog.default_allow_comments article.allow_pings = struct['mt_allow_pings'] || this_blog.default_allow_pings article.extended = struct['mt_text_more'] || '' article.excerpt = struct['mt_excerpt'] || '' article.keywords = struct['mt_keywords'] || '' article.text_filter = TextFilter.find_by_name(struct['mt_convert_breaks'] || this_blog.text_filter) if struct['categories'] article.categories.clear Category.find(:all).each do |c| article.categories << c if struct['categories'].include?(c.name) end end RAILS_DEFAULT_LOGGER.info(struct['mt_tb_ping_urls']) article.save true end def newMediaObject(blogid, username, password, data) resource = Resource.create(:filename => data['name'], :mime => data['type'], :created_at => Time.now) resource.write_to_disk(data['bits']) MetaWeblogStructs::Url.new("url" => this_blog.file_url(resource.filename)) end def article_dto_from(article) MetaWeblogStructs::Article.new( :description => article.body, :title => article.title, :postid => article.id.to_s, :url => article.permalink_url(only_path=false), :link => article.permalink_url(only_path=false), :permaLink => article.permalink_url(only_path=false), :categories => article.categories.collect { |c| c.name }, :mt_text_more => article.extended.to_s, :mt_excerpt => article.excerpt.to_s, :mt_keywords => article.keywords.to_s, :mt_allow_comments => article.allow_comments? ? 1 : 0, :mt_allow_pings => article.allow_pings? ? 1 : 0, :mt_convert_breaks => (article.text_filter.name.to_s rescue ''), :mt_tb_ping_urls => article.pings.collect { |p| p.url }, :dateCreated => (article.published_at.to_formatted_s(:db) rescue "") ) end protected def pub_date(time) time.strftime "%a, %e %b %Y %H:%M:%S %Z" end end