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.
wp
wordpress
.*
.txt
Setting | Description | Default |
---|---|---|
add-new-files | Boolean or list of extensions/patterns to match. | False |
added-in-version | Dexy version when this filter was first available. | |
additional-doc-filters | Filters to apply to additional documents created as side effects. | {} |
additional-doc-settings | Settings to apply to additional documents created as side effects. | {} |
api-key-name | The name of this API | wordpress |
api-password | The password to sign into the API with. | None |
api-url | The url of the API endpoint. | None |
api-username | The username to sign into the API with. | None |
blog-id | The wordpress blog id. | 0 |
data-type | Alias of custom data class to use to store filter output. | generic |
document-api-config-file | Filename to store config for a file (can only have 1 per directory, dexy looks for suffix format first. | wordpress.json |
document-api-config-postfix | Suffix to attach to content filename to indicate this is the config for that file. | -config.json |
examples | Templates which should be used as examples for this filter. | [] |
exclude-add-new-files | List of patterns to skip even if they match add-new-files. | [] |
exclude-new-files-from-dir | List of directories to skip when adding new files. | [] |
ext | File extension to output. | None |
extension-map | Dictionary mapping input extensions to default output extensions. | None |
help | Helpstring 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-extensions | List of extensions which this filter can accept as input. | ['.*'] |
keep-originals | Whether, if additional-doc-filters are specified, the original unmodified docs should also be added. | False |
master-api-key-file | Master API key file for user. | ~/.dexyapis |
mkdir | A directory which should be created in working dir. | None |
mkdirs | A list of directories which should be created in working dir. | [] |
nodoc | Whether filter should be excluded from documentation. | False |
output | Whether to output results of this filter by default by reporters such as 'output' or 'website'. | False |
output-extensions | List of extensions which this filter can produce as output. | ['.txt'] |
override-workspace-exclude-filters | If True, document will be populated to other workspaces ignoring workspace-exclude-filters. | False |
page-content-extensions | ['.md', '.txt', '.html'] | |
preserve-prior-data-class | Whether output data class should be set to match the input data class. | False |
project-api-key-file | API key file for project. | .dexyapis |
require-output | Should dexy raise an exception if no output is produced by this filter? | True |
tags | Tags which describe the filter. | [] |
variables | A dictionary of variable names and values to make available to this filter. | {} |
vars | A dictionary of variable names and values to make available to this filter. | {} |
workspace-exclude-filters | Filters whose output should be excluded from workspace. | ['pyg'] |
workspace-includes | If set to a list of filenames or extensions, only these will be populated to working dir. | None |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | 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_aliases
_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 = xmlrpc.client.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 = str(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.items():
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.items():
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 = xmlrpc.client.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 xmlrpc.client.Fault as e:
raise dexy.exceptions.UserFeedback(str(e))
|
Content © 2020 Dr. Ana Nelson | Site Design © Copyright 2011 Andre Gagnon | All Rights Reserved.