📄 xmlrpcserver.pm
字号:
my($entry_id, $user, $pass) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. require MT::Entry; my $entry = MT::Entry->load($entry_id) or die _fault("Invalid entry ID '$entry_id'"); my($author, $perms) = __PACKAGE__->_login($user, $pass, $entry->blog_id); die _fault("Invalid login") unless $author; die _fault("Not privileged to get entry") unless $perms && $perms->can_edit_entry($entry, $author); my $co = sprintf "%04d%02d%02dT%02d:%02d:%02d", unpack 'A4A2A2A2A2A2', $entry->created_on; require MT::Blog; my $blog = MT::Blog->load($entry->blog_id); my $link = $entry->permalink; { dateCreated => SOAP::Data->type(dateTime => $co), userid => SOAP::Data->type(string => $entry->author_id), postid => SOAP::Data->type(string => $entry->id), description => SOAP::Data->type(string => $entry->text), title => SOAP::Data->type(string => $entry->title), link => SOAP::Data->type(string => $link), permaLink => SOAP::Data->type(string => $link), mt_allow_comments => SOAP::Data->type(int => $entry->allow_comments), mt_allow_pings => SOAP::Data->type(int => $entry->allow_pings), mt_convert_breaks => SOAP::Data->type(string => $entry->convert_breaks), mt_text_more => SOAP::Data->type(string => $entry->text_more), mt_excerpt => SOAP::Data->type(string => $entry->excerpt), mt_keywords => SOAP::Data->type(string => $entry->keywords), }}sub supportedMethods { [ 'blogger.newPost', 'blogger.editPost', 'blogger.getRecentPosts', 'blogger.getUsersBlogs', 'blogger.getUserInfo', 'blogger.deletePost', 'metaWeblog.getPost', 'metaWeblog.newPost', 'metaWeblog.editPost', 'metaWeblog.getRecentPosts', 'metaWeblog.newMediaObject', 'mt.getCategoryList', 'mt.setPostCategories', 'mt.getPostCategories', 'mt.getTrackbackPings', 'mt.supportedTextFilters', 'mt.getRecentPostTitles', 'mt.publishPost' ];}sub supportedTextFilters { my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. my $filters = $mt->all_text_filters; my @res; for my $filter (keys %$filters) { push @res, { key => SOAP::Data->type(string => $filter), label => SOAP::Data->type(string => $filters->{$filter}{label}) }; } \@res;}## getCategoryList, getPostCategories, and setPostCategories were## originally written by Daniel Drucker with the assistance of## Six Apart, then later modified by Six Apart.sub getCategoryList { my $class = shift; my($blog_id, $user, $pass) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. my($author, $perms) = $class->_login($user, $pass, $blog_id); die _fault("Invalid login") unless $author; die _fault("Author does not have privileges") unless $perms && $perms->can_post; require MT::Category; my $iter = MT::Category->load_iter({ blog_id => $blog_id }); my @data; while (my $cat = $iter->()) { push @data, { categoryName => SOAP::Data->type(string => $cat->label), categoryId => SOAP::Data->type(string => $cat->id) }; } \@data;}sub getPostCategories { my $class = shift; my($entry_id, $user, $pass) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. require MT::Entry; my $entry = MT::Entry->load($entry_id) or die _fault("Invalid entry ID '$entry_id'"); my($author, $perms) = $class->_login($user, $pass, $entry->blog_id); die _fault("Invalid login") unless $author; die _fault("No posting privileges") unless $perms && $perms->can_post; my @data; my $prim = $entry->category; my $cats = $entry->categories; for my $cat (@$cats) { my $is_primary = $prim && $cat->id == $prim->id ? 1 : 0; push @data, { categoryName => SOAP::Data->type(string => $cat->label), categoryId => SOAP::Data->type(string => $cat->id), isPrimary => SOAP::Data->type(boolean => $is_primary), }; } \@data;}sub setPostCategories { my $class = shift; my($entry_id, $user, $pass, $cats) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. require MT::Entry; require MT::Placement; my $entry = MT::Entry->load($entry_id) or die _fault("Invalid entry ID '$entry_id'"); my($author, $perms) = $class->_login($user, $pass, $entry->blog_id); die _fault("Invalid login") unless $author; die _fault("Not privileged to set entry categories") unless $perms && $perms->can_edit_entry($entry, $author); my @place = MT::Placement->load({ entry_id => $entry_id }); for my $place (@place) { $place->remove; } ## Keep track of which category is named the primary category. ## If the first structure in the array does not have an isPrimary ## key, we just make it the primary category; if it does, we use ## that flag to determine the primary category. my $is_primary = 1; for my $cat (@$cats) { my $place = MT::Placement->new; $place->entry_id($entry_id); $place->blog_id($entry->blog_id); if (defined $cat->{isPrimary} && $is_primary) { $place->is_primary($cat->{isPrimary}); } else { $place->is_primary($is_primary); } ## If we just set the is_primary flag to 1, we don't want to ## make any other categories primary. $is_primary = 0 if $place->is_primary; $place->category_id($cat->{categoryId}); $place->save or die _fault("Saving placement failed: " . $place->errstr); } SOAP::Data->type(boolean => 1);}sub getTrackbackPings { my $class = shift; my($entry_id) = @_; require MT::Trackback; require MT::TBPing; my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. my $tb = MT::Trackback->load({ entry_id => $entry_id }) or return []; my $iter = MT::TBPing->load_iter({ tb_id => $tb->id }); my @data; while (my $ping = $iter->()) { push @data, { pingTitle => SOAP::Data->type(string => $ping->title), pingURL => SOAP::Data->type(string => $ping->source_url), pingIP => SOAP::Data->type(string => $ping->ip), }; } \@data;}sub publishPost { my $class = shift; my($entry_id, $user, $pass) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. require MT::Entry; my $entry = MT::Entry->load($entry_id) or die _fault("Invalid entry ID '$entry_id'"); my($author, $perms) = __PACKAGE__->_login($user, $pass, $entry->blog_id); die _fault("Invalid login") unless $author; die _fault("Not privileged to edit entry") unless $perms && $perms->can_edit_entry($entry, $author); $mt->rebuild_entry( Entry => $entry, BuildDependencies => 1 ) or die _fault("Publish failed: " . $mt->errstr); SOAP::Data->type(boolean => 1);}sub runPeriodicTasks { my $class = shift; my ($user, $pass) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); my $author = $class->_login($user, $pass); use POSIX qw(strftime); use MT::Entry qw{HOLD RELEASE FUTURE}; # Iterate over just those blogs for which the auth'd user has # edit_config access. require MT::Permission; my $iter = MT::Blog->load_iter({}, {join => ['MT::Permission', 'blog_id', { author_id => $author->id() }]}); my @nows = (); my $total_changed = 0; my $pub_cnt = 0; my $blogs_modified = 0;# my $next_scheduled = undef; while (my $blog = $iter->()) { # Have to check the permissions here because MT::Object won't # let us filter by a single bit of a field. my $perm = MT::Permission->load({author_id => $author->id(), blog_id => $blog->id()}); next unless $perm->can_edit_config(); my $result = $class->publishScheduledFuturePosts($blog->id(), $user, $pass); $pub_cnt += $result->{publishedCount}; $blogs_modified++ if $result->{publishedCount};# if (defined($result->{nextScheduledTime})) {# if (!defined($next_scheduled)# || ($next_scheduled > $result->{nextScheduledTime}))# {# $next_scheduled = $result->{nextScheduledTime};# }# } } MT->run_callbacks('PeriodicTask'); { publishedCount => $pub_cnt,# nextScheduledTime => $next_scheduled, numBlogs => $blogs_modified };}sub publishScheduledFuturePosts { my $class = shift; my ($blog_id, $user, $pass) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); my $author = $class->_login($user, $pass); my $blog = MT::Blog->load($blog_id); my $now = time; # Convert $now to user's timezone, which is how future post dates # are stored. $now = MT::Util::offset_time($now); $now = strftime("%Y%m%d%H%M%S", gmtime($now)); my $iter = MT::Entry->load_iter({blog_id => $blog->id, status => FUTURE}, {'sort' => 'created_on', direction => 'descend'}); my @queue; while (my $i = $iter->()) { push @queue, $i->id(); } my $changed = 0; my $total_changed = 0; my @results;# my $next_scheduled = undef; foreach my $entry_id (@queue) { my $entry = MT::Entry->load($entry_id); if ($entry->created_on <= $now) { $entry->status(RELEASE); $entry->save or die $entry->errstr; start_background_task(sub { $mt->rebuild_entry( Entry => $entry, Blog => $blog ) or die $mt->errstr; }); $changed++; $total_changed++; } else {# my $entry_utc = MT::XMLRPCServer::Util::ts2iso($blog, # $entry->created_on);# if (!defined($next_scheduled) || $entry_utc < $next_scheduled)# {# $next_scheduled = $entry_utc;# } } } if ($changed) { $mt->rebuild_indexes( Blog => $blog ) or die $mt->errstr; } { responseCode => 'success', publishedCount => $total_changed,# nextScheduledTime => $next_scheduled };}sub getNextScheduled { my $class = shift; my ($user, $pass) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); my $author = $class->_login($user, $pass); my $next_scheduled = MT::get_next_sched_post_for_user($author->id()); { nextScheduledTime => $next_scheduled };}sub setRemoteAuthToken { my $class = shift; my ($user, $pass, $remote_auth_username, $remote_auth_token) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. my($author) = __PACKAGE__->_login($user, $pass); die _fault("Invalid login") unless $author; $author->remote_auth_username($remote_auth_username); $author->remote_auth_token($remote_auth_token); $author->save(); 1;}sub newMediaObject { my $class = shift; my($blog_id, $user, $pass, $file) = @_; my $mt = MT::XMLRPCServer::Util::mt_new(); ## Will die if MT->new fails. my($author, $perms) = __PACKAGE__->_login($user, $pass, $blog_id); die _fault("Invalid login") unless $author; die _fault("Not privileged to upload files") unless $perms && $perms->can_upload; require MT::Blog; require File::Spec; my $blog = MT::Blog->load($blog_id); my $fname = $file->{name} or die _fault("No filename provided"); if ($fname =~ m!\.\.|\0|\|!) { die _fault("Invalid filename '$fname'"); } my $local_file = File::Spec->catfile($blog->site_path, $file->{name}); my $fmgr = $blog->file_mgr; my($vol, $path, $name) = File::Spec->splitpath($local_file); $path =~ s!/$!!; ## OS X doesn't like / at the end in mkdir(). unless ($fmgr->exists($path)) { $fmgr->mkpath($path) or die _fault("Error making path '$path': " . $fmgr->errstr); } defined(my $bytes = $fmgr->put_data($file->{bits}, $local_file, 'upload')) or die _fault("Error writing uploaded file: " . $fmgr->errstr); my $url = $blog->site_url . $fname; { url => SOAP::Data->type(string => $url) };}## getTemplate and setTemplate are not applicable in MT's template## structure, so they are unimplemented (they return a fault).## We assign it twice to get rid of "setTemplate used only once" warnings.sub getTemplate { die _fault( "Template methods are not implemented, due to differences between " . "the Blogger API and the Movable Type API.");}*setTemplate = *setTemplate = \&getTemplate;## The above methods will be called as blogger.newPost, blogger.editPost,## etc., because we are implementing Blogger's API. Thus, the empty## subclass.package blogger;BEGIN { @blogger::ISA = qw( MT::XMLRPCServer ); }package metaWeblog;BEGIN { @metaWeblog::ISA = qw( MT::XMLRPCServer ); }package mt;BEGIN { @mt::ISA = qw( MT::XMLRPCServer ); }1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -