1
0
mirror of https://github.com/gryf/vimblogger_ft.git synced 2025-12-17 19:40:24 +01:00
Files
vimblogger_ft/ftplugin/rst/rst2blogger/main.py
2010-12-13 22:09:57 +01:00

205 lines
6.7 KiB
Python

# vim: fileencoding=utf8
"""
File: main.py
Author: Roman 'gryf' Dobosz
Description: main file to provide fuctionality between vim and moudles rest
and blogger
"""
import webbrowser
from xml.dom import minidom
from xml.parsers.expat import ExpatError
import vim
from rst2blogger.rest import blogPreview, blogArticleString
from rst2blogger.blogger import VimBlogger
class Rst2Blogger(object):
"""
Provide convenient way to communicate between vim and blogger through reST
"""
def __init__(self):
vim.command('call setqflist([])')
self.buff = vim.current.buffer
self.docinfo_len = 0
self._set_docinfo_len()
self.login = vim.eval("g:blogger_login")
self.password = vim.eval("g:blogger_pass")
self.blogname = vim.eval("g:blogger_name")
self.buffer_encoding = vim.eval("&fileencoding")
self.vim_encoding = vim.eval("&encoding")
self.draft = int(vim.eval("g:blogger_draft"))
self.maxarticles = int(vim.eval("g:blogger_maxarticles"))
self.confirm_del = int(vim.eval("g:blogger_confirm_del"))
self.stylesheets = vim.eval("g:blogger_stylesheets")
def preview(self):
"""
Generate HTML Blogger article preview and (optionally) display it in
systems' web browser
"""
bufcontent = "\n".join(self.buff)
name = self.buff.name
name = name[:-4] + ".html"
html = blogPreview(bufcontent, self.stylesheets)
self._open_qf(self._check_html(html))
output_file = open(name, "w")
output_file.write(html)
output_file.close()
if vim.eval("g:blogger_browser"):
webbrowser.open(name)
return "Generated HTML has been opened in browser"
else:
return "Generated HTML has been written to %s" % name
def post(self):
"""
Do post article
"""
bufcontent = "\n".join(self.buff)
html, attrs = blogArticleString(bufcontent)
parse_msg = self._check_html(html, True)
if parse_msg:
self._open_qf(parse_msg)
return "There are errors in generated document"
if not self.password:
self.password = \
vim.eval('inputsecret("Enter your gmail password: ")')
blog = VimBlogger(self.blogname, self.login, self.password)
blog.draft = self.draft > 0
if 'id' in attrs and attrs['id']:
post = blog.update_article(html, attrs=attrs)
msg = unicode("Article '%s' has been updated" % post.title.text)
msg = msg.encode(self.vim_encoding)
else:
post = blog.create_article(html, attrs=attrs)
msg = "New article with id %s has been created" % \
post.get_post_id()
for item, value in (('id', post.get_post_id()),
('date', post.published.text),
('title', post.title.text),
('modified', post.updated.text),
('tags',
", ".join([cat.term for cat in post.category]))):
self._update_docinfo(item, value)
return msg
def delete(self):
"""
Get list of articles, display it to the user, make him choose one and
delete
"""
if not self.password:
self.password = \
vim.eval('inputsecret("Enter your gmail password: ")')
blog = VimBlogger(self.blogname, self.login, self.password)
posts = blog.get_articles(self.maxarticles)
msg = u"inputlist(["
for index, entries in enumerate(posts):
line = "%2d %s %s" % (index + 1,
entries[1],
entries[2])
msg += u'"' + line.replace('"', '\\"') + u'",'
msg = msg[:-1]
msg += u"])"
msg = unicode(msg).encode(self.vim_encoding)
choice = int(vim.eval(msg))
if choice:
art = posts[choice - 1]
msg = 'confirm("You are about to delete article \'%s\'. '
msg += 'Are you sure?"'
msg = unicode(msg % art[1]).encode(self.vim_encoding)
msg += ', "&No\n&Yes")'
if self.confirm_del:
choice = int(vim.eval(msg))
else:
choice = 2
if choice == 2:
blog.delete_article(art[0])
return "Article deleted"
return "No articles deleted"
def _update_docinfo(self, attr, val):
"""
Update current buffer with attributes value
"""
val = unicode(":%s: %s" % (attr.capitalize(), val))
val = val.encode(self.buffer_encoding)
if not self.docinfo_len:
self.buff.append(val, 0)
return
for num, line in enumerate(self.buff[:self.docinfo_len]):
if ':%s:' % attr in line.lower() and line.startswith(":"):
self.buff[num] = val
return
self.buff.append(val, 0)
self.docinfo_len += 1
def _set_docinfo_len(self):
"""
Set docinfo_len, which means number of lines from the beginning of the
buffer to the first empty line.
"""
for num, line in enumerate(self.buff):
if line and line.startswith(':'):
continue
elif not line:
self.docinfo_len = num
break
else:
self.docinfo_len = 0
break
def _open_qf(self, msg):
"""
Open VIm QuickFix window with message, if argument msg is non empty
string.
"""
if msg:
msg1 = "There are problems reported by XML parser:"
msg2 = "Check generated html for errors."
vim.command('call setqflist([{"text": "%s"}, {"text": "%s"}, '
'{"text": "%s"}])' % (msg1, msg, msg2))
vim.command('copen')
def _check_html(self, html, add_container=False):
"""
Check HTML generated document, by simply use minidom parser
If add_container is set to True, entire document is wrapped inside
additional div
returns empty string if parses succeed, else exception message.
"""
# minidom doesn't understand html entities like ' ' For checking
# purpose it is perfectly ok, to switch them with '&'
html = html.replace(" ", "&")
if add_container:
html = "<div>" + html + "</div>"
message = ""
try:
minidom.parseString(html)
except ExpatError as ex:
message = str(ex)
return message