#coding: utf-8
## For more information, see:
## http://www.docverter.com/api.html
## http://wcm1.web.rice.edu/pandoc-on-ios.html
import clipboard
import console
import editor
import httplib
import json
import mimetypes
import os
import shutil
import ui
import urllib
import webbrowser
import workflow
########################
# #
# GLOBAL VARIABLES #
# #
########################
view = None
# Variables defined by red actions in workflow
filename = urllib.quote_plus(workflow.get_variable('Filename'), '/')
folder_path = workflow.get_variable('FolderPath')
# Variables governed by Docverter API
md_only = ['atx_headers', 'reference_links']
non_file_only = ['button1', 'button2']
args_with_files = ['template', 'include_in_header', 'include_before_body', 'include_after_body', 'reference_docx', 'epub_stylesheet', 'epub_cover_image', 'epub_metadata', 'epub_embed_font']
def clear_vars():
global formats, fields, files, text
formats = {}
fields = []
files = []
scrollview['textfield1'].text = ''
text = ''
########################
# #
# FORM-DATA HELPERS #
# #
########################
## Updated to reflect changes to httplib in Python 2.0.
## {{{ http://code.activestate.com/recipes/146306/ (r1)
def post_multipart(fields, files):
"""
Post fields and files to Docverter as multipart/form-data.
Return the server's response page or error alert
"""
content_type, body = encode_multipart_formdata(fields, files)
bodystr = body.encode('utf-8', 'replace')
h = httplib.HTTPConnection('c.docverter.com')
h.putrequest('POST', '/convert')
h.putheader('content-type', content_type)
h.putheader('content-length', str(len(bodystr)))
h.endheaders()
h.send(bodystr)
r = h.getresponse()
output = r.read()
if r.status == 200:
return output
else:
try:
error = json.loads(output)['error']
except Exception as e:
error = e
message = '%s %s: %s' % (r.status, r.reason, error)
console.hud_alert(message, 'error', 4)
workflow.stop()
def encode_multipart_formdata(fields, files):
"""
fields = (name, value) elements for regular form fields.
files = (name, filename, value) elements for uploaded file data
Return (content_type, body) ready for httplib.HTTP instance
"""
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key, filename, value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
L.append('Content-Type: %s' % get_content_type(filename))
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
def get_content_type(filename):
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
## end of http://code.activestate.com/recipes/146306/ }}}
########################
# #
# CUSTOM UI HANDLERS #
# #
########################
# switch
def switch_action(sender):
param = (sender.name, 'true')
if sender.value:
fields.append(param)
elif param in fields and not sender.value:
fields.remove(param)
# switch
def to_pdf_epub_docx(sender):
global formats
if sender.value:
scrollview['to'].segments = ('pdf', 'epub', 'docx')
scrollview['button3'].enabled = True
scrollview['table_of_contents'].enabled = True
for opt in md_only + non_file_only:
scrollview[opt].enabled = False
else:
scrollview['to'].segments = ('markdown', 'html', 'latex')
scrollview['button3'].enabled = False
for opt in non_file_only:
scrollview[opt].enabled = True
scrollview['to'].selected_index = 0
set_to(scrollview['to'])
# segmented control
def set_from(sender):
global formats
formats['from'] = sender.segments[sender.selected_index]
# segmented control
def set_to(sender):
global formats
formats['to'] = sender.segments[sender.selected_index]
if formats['to'] == 'markdown':
scrollview['table_of_contents'].enabled = False
for opt in md_only:
scrollview[opt].enabled = True
else:
scrollview['table_of_contents'].enabled = True
for opt in md_only:
scrollview[opt].enabled = False
# button1
def out_to_editor(sender):
input_to_files()
args_to_fields(scrollview['textfield1'])
request = post_multipart(formats.items() + fields, files)
editor.replace_text(0, len(text), request)
view.close()
# button2
def out_to_clipboard(sender):
input_to_files()
args_to_fields(scrollview['textfield1'])
request = post_multipart(formats.items() + fields, files)
clipboard.set(request)
console.hud_alert('Converted text on clipboard!', 'success')
view.close()
# button3
def out_to_file(sender):
global files, fields
input_to_files()
args_to_fields(scrollview['textfield1'])
if workflow.get_variable('Css'):
c = open('custom.css', 'w').write(workflow.get_variable('Css'))
files.append(('other_files[]', 'custom.css', open('custom.css', 'r').read()))
fields.append(('css', 'custom.css'))
request = post_multipart(formats.items() + fields, files)
ext = scrollview['to'].segments[scrollview['to'].selected_index]
o = open('docverter/' + filename + '.' + ext, 'w').write(request)
output_path = os.path.abspath('docverter/' + filename + '.' + ext)
open_file(output_path)
########################
# #
# MAIN EXECUTE BLOCK #
# #
########################
def input_to_files():
global files, text
text = editor.get_text()
fw = open('docverterin.txt', 'w')
fw.write(text)
fw.close()
files.append(('input_files[]', 'docverterin.txt', open('docverterin.txt', 'r').read()))
def args_to_fields(sender):
global fields, files
args = sender.text
args_list = [i.rstrip() for i in args.split('--') if i is not '']
for arg in args_list:
param = tuple(arg.split('='))
if len(param) == 1:
fields.append(param + tuple(['true']))
elif param[0] in args_with_files:
fp = os.path.join(folder_path, param[1])
files.append(('other_files[]', param[1], open(fp, 'r').read()))
fields.append(param)
else:
fields.append(param)
@ui.in_background
def open_file(p):
console.open_in(p)
view.close()
# clear temp docverter directory of old output files
temp_dir = os.path.abspath('docverter/')
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir)
os.mkdir(temp_dir)
else:
os.mkdir(temp_dir)
view = ui.load_view()
scrollview = view['scrollview1']
clear_vars()
# Work around for segmented text bug
scrollview['from'].action = set_from
scrollview['to'].action = set_to
# end workaround
set_from(scrollview['from'])
set_to(scrollview['to'])
to_pdf_epub_docx(scrollview['toswitch'])
view.present('popover')
There are no comments yet.
...dave