Skip to content

Instantly share code, notes, and snippets.

@brokaw
Last active August 6, 2018 14:10
Show Gist options
  • Save brokaw/ceaade25fb7e073e0c63c53ebc4f4681 to your computer and use it in GitHub Desktop.
Save brokaw/ceaade25fb7e073e0c63c53ebc4f4681 to your computer and use it in GitHub Desktop.
Publish from BBEdit to Wordpress via XMLRPC
#!/usr/bin/env python
import sys
import ssl
import subprocess
from xmlrpclib import ServerProxy
from markdown import markdown
SERVER_URL = 'https://www.example.com/xmlrpc.php'
SERVER_USERNAME = ''
SERVER_PASSWORD = ''
applescript_prompt_for_title = """
tell application "BBEdit"
set theDocument to the active document of the front text window
end tell
set theDialogTitle to "Post " & "\\"" & the name of theDocument & "\\""
return the text of (display dialog "Enter the post title" with title theDialogTitle buttons {"Cancel", "Post"} default button "Post" default answer "")
"""
applescript_get_text = """
tell application "BBEdit" to set theDocument to the active document of the front text window
return the text of theDocument
"""
applescript_display_dialog = 'display dialog "%s" with title "%s" buttons "Ok default button "Ok""'
class Server():
def __init__(self, url, username, password):
self.blog_id = 1 # arbitrary, unused
self.url = url
self.username = username
self.password = password
self.proxy = ServerProxy(self.url , context=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2))
self.filter = {'orderby': 'post_id'}
self.fields = ['post_title', 'post_id', 'guid', 'link']
self.content_template = {'post_type'}
def getPosts(self, filter=None, fields=None):
wp_filter = filter or self.filter
wp_fields = fields or self.fields
return self.proxy.wp.getPosts(self.blog_id, self.username, self.password, wp_filter, wp_fields)
def newPost(self, post):
return self.proxy.wp.newPost(self.blog_id, self.username, self.password, post.content())
def updatePost(self, post):
return self.proxy.wp.editPost(self.blog_id, self.username, self.password, kwargs)
class Post():
def __init__(self, title, body):
self.title = title
self.body = body
self.id = None
def content(self):
return {'post_title': self.title,
'post_content': self.body}
def render(text):
extensions = ['markdown.extensions.extra',
'markdown.extensions.codehilite',
'markdown.extensions.smarty']
extension_config = {'markdown.extensions.codehilite':
{'linenums': False, 'guess_lang': False}}
return markdown(text, extensions=extensions, extension_configs=extension_config,
outputformat='html5')
def run_applescript(script):
process = subprocess.Popen(['osascript', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try:
outdata, errdata = process.communicate(script)
except:
pass
if outdata == "":
return None
return outdata
def prompt_for_title():
result = run_applescript(applescript_prompt_for_title)
if not result:
return None
# applescript result is comma separated. Deal with titles with commas in them
title = ','.join(result.split(',')[1:]).strip()
return title
def get_document_text():
return run_applescript(applescript_get_text)
def display_dialog(message, title="Post To Blog"):
script = applescript_display_dialog % (message, title)
_ = run_applescript('display dialog "%s" with title "%s" buttons "Ok" default button "Ok"' % (message, title))
def get_password(account, server):
try:
return subprocess.check_output(["security", "find-internet-password", "-w", "-a", account, "-s", server])
except subprocess.CalledProcessError as e:
return "The command %s exited with error %i: %s" % (e.cmd[0], e.returncode, e.output)
def main(args=None):
try:
title = prompt_for_title()
print(title)
if not title:
#cancelled
return 0
text = get_document_text().decode('utf8')
html = render(text)
post = Post(title, html)
server = Server(SERVER_URL, SERVER_USERNAME, SERVER_PASSWORD)
#server.newPost(post)
display_dialog("Success")
except ImportError:
display_dialog("Configuration file not found")
return 1
except Exception as e:
display_dialog("Failed with error %s" % e)
return 1
return 0
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment