logo

Wp Filter

← Back to Filter List

Wp


Posts to a WordPress blog. WordPress has a very confusing API setup since it implements its own API methods (under the wp namespace) and also supports the Blogger, metaWeblog and MovableType APIs. Unfortunately the wp namespace methods are incomplete, so you have to mix and match. Uses the WP XMLRPC API where possible: http://codex.wordpress.org/XML-RPC_wp Creating and editing blog posts uses the metaWeblog API: http://xmlrpc.scripting.com/metaWeblogApi.html If this filter is applied to a document with file extension in PAGE_CONTENT_EXTENSIONS (defined in ApiFilter class and inherited here) then the document will be uploaded to WordPress as a blog post. If not, then the document is assumed to be an image or other binary asset, and file upload will be used instead, so a new element will be added to the Media Library. If this is the case, then the URL is the resulting image is returned, so you can use that URL directly in your blog posts or other documents that need to link to the asset. IMPORTANT There is currently a frustrating bug in WP: http://core.trac.wordpress.org/ticket/17604 which means that every time you run this filter, a *new* image asset will be created, even though we tell WordPress to overwrite the existing image of the same name. You will end up with dozens of copies of this image cluttering up your media library. For now, we recommend using an external site to host your images and assets, such as Amazon S3.

Aliases for this filter

  • wp
  • wordpress

Converts from file formats:

  • .*

To file formats:

  • .txt

Available settings:

SettingDescriptionDefault
add-new-filesBoolean or list of extensions/patterns to match.False
added-in-versionDexy version when this filter was first available.
additional-doc-filtersFilters to apply to additional documents created as side effects.{}
additional-doc-settingsSettings to apply to additional documents created as side effects.{}
api-key-nameThe name of this APIwordpress
api-passwordThe password to sign into the API with.None
api-urlThe url of the API endpoint.None
api-usernameThe username to sign into the API with.None
blog-idThe wordpress blog id.0
data-typeAlias of custom data class to use to store filter output.generic
document-api-config-fileFilename to store config for a file (can only have 1 per directory, dexy looks for suffix format first.wordpress.json
document-api-config-postfixSuffix to attach to content filename to indicate this is the config for that file.-config.json
examplesTemplates which should be used as examples for this filter.[]
exclude-add-new-filesList of patterns to skip even if they match add-new-files.[]
exclude-new-files-from-dirList of directories to skip when adding new files.[]
extFile extension to output.None
extension-mapDictionary mapping input extensions to default output extensions.None
helpHelpstring for plugin.Posts to a WordPress blog. WordPress has a very confusing API setup since it implements its own API methods (under the wp namespace) and also supports the Blogger, metaWeblog and MovableType APIs. Unfortunately the wp namespace methods are incomplete, so you have to mix and match. Uses the WP XMLRPC API where possible: http://codex.wordpress.org/XML-RPC_wp Creating and editing blog posts uses the metaWeblog API: http://xmlrpc.scripting.com/metaWeblogApi.html If this filter is applied to a document with file extension in PAGE_CONTENT_EXTENSIONS (defined in ApiFilter class and inherited here) then the document will be uploaded to WordPress as a blog post. If not, then the document is assumed to be an image or other binary asset, and file upload will be used instead, so a new element will be added to the Media Library. If this is the case, then the URL is the resulting image is returned, so you can use that URL directly in your blog posts or other documents that need to link to the asset. IMPORTANT There is currently a frustrating bug in WP: http://core.trac.wordpress.org/ticket/17604 which means that every time you run this filter, a *new* image asset will be created, even though we tell WordPress to overwrite the existing image of the same name. You will end up with dozens of copies of this image cluttering up your media library. For now, we recommend using an external site to host your images and assets, such as Amazon S3.
input-extensionsList of extensions which this filter can accept as input.[u'.*']
keep-originalsWhether, if additional-doc-filters are specified, the original unmodified docs should also be added.False
master-api-key-fileMaster API key file for user.~/.dexyapis
mkdirA directory which should be created in working dir.None
mkdirsA list of directories which should be created in working dir.[]
nodocWhether filter should be excluded from documentation.False
outputWhether to output results of this filter by default by reporters such as 'output' or 'website'.False
output-extensionsList of extensions which this filter can produce as output.[u'.txt']
override-workspace-exclude-filtersIf True, document will be populated to other workspaces ignoring workspace-exclude-filters.False
page-content-extensions[u'.md', u'.txt', u'.html']
preserve-prior-data-classWhether output data class should be set to match the input data class.False
project-api-key-fileAPI key file for project..dexyapis
require-outputShould dexy raise an exception if no output is produced by this filter?True
tagsTags which describe the filter.[]
variablesA dictionary of variable names and values to make available to this filter.{}
varsA dictionary of variable names and values to make available to this filter.{}
workspace-exclude-filtersFilters whose output should be excluded from workspace.[u'pyg']
workspace-includesIf set to a list of filenames or extensions, only these will be populated to working dir.None
Filter Source Code
class WordPressFilter(ApiFilter):
    """
    Posts to a WordPress blog.

    WordPress has a very confusing API setup since it implements its own API
    methods (under the wp namespace) and also supports the Blogger, metaWeblog
    and MovableType APIs. Unfortunately the wp namespace methods are
    incomplete, so you have to mix and match.

    Uses the WP XMLRPC API where possible:
    http://codex.wordpress.org/XML-RPC_wp

    Creating and editing blog posts uses the metaWeblog API:
    http://xmlrpc.scripting.com/metaWeblogApi.html

    If this filter is applied to a document with file extension in
    PAGE_CONTENT_EXTENSIONS (defined in ApiFilter class and inherited here)
    then the document will be uploaded to WordPress as a blog post.

    If not, then the document is assumed to be an image or other binary asset,
    and file upload will be used instead, so a new element will be added to the
    Media Library. If this is the case, then the URL is the resulting image is
    returned, so you can use that URL directly in your blog posts or other
    documents that need to link to the asset.

    IMPORTANT There is currently a frustrating bug in WP:
    http://core.trac.wordpress.org/ticket/17604
    which means that every time you run this filter, a *new* image asset will
    be created, even though we tell WordPress to overwrite the existing image
    of the same name. You will end up with dozens of copies of this image
    cluttering up your media library.

    For now, we recommend using an external site to host your images and
    assets, such as Amazon S3.
    """
    aliases = ['wp', 'wordpress']

    _settings = {
            'blog-id' : ("The wordpress blog id.", 0),
            'page-content-extensions' : ('', ['.md', '.txt', '.html']),
            'document-api-config-file' : 'wordpress.json',
            'api-key-name' : 'wordpress',
            'output-extensions' : ['.txt']
            }

    def docmd_create_keyfile(self):
        """
        Creates a key file for WordPress in the local directory.
        """
        self.create_keyfile("project-api-key-file")

    def api_url(self):
        base_url = self.read_param('url')
        if base_url.endswith("xmlrpc.php"):
            return base_url
        else:
            if not base_url.endswith("/"):
                base_url = "%s/" % base_url
            return "%sxmlrpc.php" % base_url

    def api(klass):
        if not hasattr(klass, "_api"):
            klass._api = xmlrpclib.ServerProxy(klass.api_url())
        return klass._api

    def docmd_list_methods(klass):
        """
        List API methods exposed by WordPress API.
        """
        for method in sorted(klass.api().system.listMethods()):
            print method

    def docmd_list_categories(self):
        """
        List available blog post categories.
        """
        username = self.read_param('username')
        password = self.read_param('password')
        headers = ['categoryName']
        print "\t".join(headers)
        for category_info in self.api().wp.getCategories(self.setting('blog-id'), username, password):
            print "\t".join(category_info[h] for h in headers)

    def upload_page_content(self):
        input_text = unicode(self.input_data)
        document_config = self.read_document_config()

        document_config['description'] = input_text
        post_id = document_config.get('postid')
        publish = document_config.get('publish', False)

        for key, value in document_config.iteritems():
            if not key == "description":
                self.log_debug("%s: %s" % (key, value))

        if post_id:
            self.log_debug("Making editPost API call.")
            self.api().metaWeblog.editPost(
                    post_id,
                    self.read_param('username'),
                    self.read_param('password'),
                    document_config,
                    publish
                    )
        else:
            self.log_debug("Making newPost API call.")
            post_id = self.api().metaWeblog.newPost(
                    self.setting('blog-id'),
                    self.read_param('username'),
                    self.read_param('password'),
                    document_config,
                    publish
                    )
            document_config['postid'] = post_id

        self.log_debug("Making getPost API call.")
        post_info = self.api().metaWeblog.getPost(
                post_id,
                self.read_param('username'),
                self.read_param('password')
                )

        for key, value in post_info.iteritems():
            if key in ('date_modified_gmt', 'dateCreated', 'date_modified', 'date_created_gmt',):
                post_info[key] = value.value

            if not key == "description":
                self.log_debug("%s: %s" % (key, value))

        del document_config['description']
        document_config['publish'] = publish
        self.save_document_config(document_config)

        if publish:
            self.output_data.set_data(post_info['permaLink'])
        else:
            self.output_data.set_data(json.dumps(post_info))

    def upload_image_content(self):
        with open(self.input_data.storage.data_file(), 'rb') as f:
            image_base_64 = xmlrpclib.Binary(f.read())

            upload_file = {
                     'name' : self.work_input_filename(),
                     'type' : mimetypes.types_map[self.prev_ext],
                     'bits' : image_base_64,
                     'overwrite' : 'true'
                     }

            upload_result = self.api().wp.uploadFile(
                     self.setting('blog-id'),
                     self.read_param('username'),
                     self.read_param('password'),
                     upload_file
                     )

            self.log_debug("wordpress upload results: %s" % upload_result)
            url = upload_result['url']
            self.log_debug("uploaded %s to %s" % (self.key, url))

        self.output_data.set_data(url)

    def process(self):
        try:
            if self.prev_ext in self.setting('page-content-extensions'):
                self.upload_page_content()
            else:
                self.upload_image_content()

        except xmlrpclib.Fault as e:
            raise dexy.exceptions.UserFeedback(unicode(e))

Content © 2013 Dr. Ana Nelson | Site Design © Copyright 2011 Andre Gagnon | All Rights Reserved.