mirror of
https://github.com/gryf/.vim.git
synced 2025-12-17 11:30:29 +01:00
Removed ACP plugin. Found it annoying after a while. Reorganized rst2blogger plugin. Added documentation for it.
This commit is contained in:
@@ -1,98 +0,0 @@
|
||||
" Blogger vim interface.
|
||||
" Provide some convinient functions for creating preview from the reST file
|
||||
" and to send articles to blog.
|
||||
|
||||
if exists("b:did_rst_plugin")
|
||||
finish " load only once
|
||||
else
|
||||
let b:did_rst_plugin = 1
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_browser")
|
||||
let g:blogger_browser = 0
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_name")
|
||||
let g:blogger_name = ""
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_login")
|
||||
let g:blogger_login= ""
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_pass")
|
||||
let g:blogger_pass = ""
|
||||
endif
|
||||
|
||||
map <F6> :call <SID>Restify()<cr>
|
||||
map <F7> :call <SID>Rst2Blogger()<cr>
|
||||
|
||||
if !exists('*s:Restify')
|
||||
python << EOF
|
||||
#{{{
|
||||
import os
|
||||
import sys
|
||||
import webbrowser
|
||||
|
||||
import vim
|
||||
|
||||
scriptdir = os.path.dirname(vim.eval('expand("<sfile>")'))
|
||||
sys.path.insert(0, scriptdir)
|
||||
try:
|
||||
from vimblogger.rest import blogPreview, blogArticleString
|
||||
from vimblogger.blogger import VimBlogger
|
||||
except ImportError:
|
||||
print "Plugin blogger cannot be loaded, due to lack of required modules"
|
||||
#}}}
|
||||
EOF
|
||||
|
||||
" Translate reSt text into html fragment suitable for preview in browser.
|
||||
fun <SID>Restify()
|
||||
python << EOF
|
||||
# {{{
|
||||
bufcontent = "\n".join(vim.current.buffer)
|
||||
name = vim.current.buffer.name
|
||||
|
||||
name = name[:-4] + ".html"
|
||||
html = blogPreview(bufcontent)
|
||||
output_file = open(name, "w")
|
||||
output_file.write(html)
|
||||
output_file.close()
|
||||
if vim.eval("g:blogger_browser"):
|
||||
webbrowser.open(name)
|
||||
print "Generated HTML has been opened in browser"
|
||||
else:
|
||||
print "Generated HTML has been written to %s" % name
|
||||
#}}}
|
||||
EOF
|
||||
endfun
|
||||
|
||||
" Generate headless html, gather title, dates and tags from filed list and
|
||||
" then send it to blog.
|
||||
fun <SID>Rst2Blogger()
|
||||
python << EOF
|
||||
#{{{
|
||||
bufcontent = "\n".join(vim.current.buffer)
|
||||
name = vim.current.buffer.name
|
||||
html, attrs = blogArticleString(bufcontent)
|
||||
|
||||
login = vim.eval("g:blogger_login")
|
||||
password = vim.eval("g:blogger_pass")
|
||||
blogname = vim.eval("g:blogger_name")
|
||||
|
||||
if not password:
|
||||
password = vim.eval('inputsecret("Enter your gmail password: ")')
|
||||
|
||||
title = 'title' in attrs and attrs['title'] or None
|
||||
date = 'date' in attrs and attrs['date'] or None
|
||||
tags = 'tags' in attrs and attrs['tags'] or ""
|
||||
tags = [tag.strip() for tag in tags.split(',')]
|
||||
modified = 'modified' in attrs and attrs['modified'] or None
|
||||
|
||||
blog = VimBlogger(blogname, login, password)
|
||||
print blog.create_article(title, html, tags=tags)
|
||||
|
||||
#}}}
|
||||
EOF
|
||||
endfun
|
||||
endif
|
||||
@@ -9,3 +9,7 @@ setlocal formatoptions=tcq "set VIms default
|
||||
let g:blogger_login="gryf73"
|
||||
let g:blogger_name="rdobosz"
|
||||
let g:blogger_browser=1
|
||||
let g:blogger_stylesheets=["css/widget_css_2_bundle.css", "css/style_custom.css", "css/style_blogger.css"]
|
||||
|
||||
map <F6> :PreviewBlogArticle<cr>
|
||||
map <F7> :SendBlogArticle<cr>
|
||||
|
||||
1
ftplugin/rst/rst2blogger/__init__.py
Normal file
1
ftplugin/rst/rst2blogger/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# module vimblogger
|
||||
258
ftplugin/rst/rst2blogger/blogger.py
Normal file
258
ftplugin/rst/rst2blogger/blogger.py
Normal file
@@ -0,0 +1,258 @@
|
||||
# vim: fileencoding=utf8
|
||||
#
|
||||
# Blogger interface to make easy way to create/update articles for specified
|
||||
# blog.
|
||||
#
|
||||
# It is assumed one way communication only, so you may create or update an
|
||||
# article from reST source files. There is no way to recreate article from
|
||||
# html to reST format.
|
||||
#
|
||||
# requirements:
|
||||
#
|
||||
# - Vim compiled with +python
|
||||
# - python 2.x (tested with 2.6)
|
||||
# - modules
|
||||
# - gdata (http://code.google.com/p/gdata-python-client)
|
||||
# - docutils (http://docutils.sourceforge.net)
|
||||
#
|
||||
# USE CASES:
|
||||
# 1. Create new post
|
||||
#
|
||||
# use reST template:
|
||||
# ===8<---
|
||||
# :Title: Blog post title
|
||||
# :Date: optional publish date (for example: 2010-11-28 18:47:05),
|
||||
# default: now()
|
||||
# :Modified: optional, default: None
|
||||
# :Tags: comma separated blog tags
|
||||
#
|
||||
# .. more
|
||||
#
|
||||
# --->8===
|
||||
#
|
||||
# All four docinfo are optional, however it is nice to give at least a title
|
||||
# to the article :)
|
||||
#
|
||||
#
|
||||
#
|
||||
# which is provided under templates directory or as a
|
||||
# snipMate shoortcut (see .vim/snippets/rst.snippets)
|
||||
#
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
import datetime
|
||||
import re
|
||||
|
||||
import atom
|
||||
from gdata.blogger.client import BloggerClient, BLOG_POST_URL
|
||||
from gdata.blogger.data import BlogPost
|
||||
|
||||
|
||||
class VimBlogger(object):
|
||||
"""
|
||||
"""
|
||||
DATE_PATTERN = re.compile(r"^(\d{4}-\d{2}-\d{2})"
|
||||
"T(\d{2}:\d{2}:\d{2})(\.\d{3})?[+-]"
|
||||
"(\d{2}:\d{2})$")
|
||||
DATE_FORMAT = "%Y-%m-%d"
|
||||
TIME_FORMAT = "%H:%M:%S"
|
||||
TZ_FORMAT = "%H:%M"
|
||||
|
||||
# TODO: dodać usuwanie artykułów (prosta lista, wybieramy art,
|
||||
# potwierdzamy)
|
||||
# TODO: Dokumentacja jako vimdoc!
|
||||
|
||||
def __init__(self, blogname, login, password):
|
||||
"""
|
||||
"""
|
||||
self.draft = True
|
||||
self.blog_id = None
|
||||
self.blog = None
|
||||
self.client = BloggerClient()
|
||||
self._authorize(login, password)
|
||||
|
||||
self.feed = self.client.get_blogs()
|
||||
self._set_blog(blogname)
|
||||
|
||||
def get_articles(self, maxarticles=0):
|
||||
"""
|
||||
Return list of articles
|
||||
"""
|
||||
|
||||
feed = self.client.get_posts(self.blog_id)
|
||||
posts = []
|
||||
|
||||
for index, entry in enumerate(feed.entry):
|
||||
if maxarticles and index >= maxarticles:
|
||||
break
|
||||
posts.append((entry.get_post_id(),
|
||||
entry.title.text,
|
||||
self._extract_date(entry.published.text)))
|
||||
return posts
|
||||
|
||||
|
||||
def create_article(self, html_doc, attrs=None):
|
||||
"""
|
||||
Create new article
|
||||
html_doc is content of the article in HTML format, without headers,
|
||||
preamble, doctype and body tags.
|
||||
attrs is a dictionary that should hold title, date and tags.
|
||||
return BlogPost object
|
||||
"""
|
||||
if not attrs:
|
||||
attrs = {}
|
||||
|
||||
title = 'title' in attrs and attrs['title'] or ""
|
||||
title = atom.data.Title(text=title, type="text")
|
||||
html_doc = atom.data.Content(text=html_doc, type="html")
|
||||
|
||||
new_post = BlogPost(title=title, content=html_doc)
|
||||
|
||||
if 'tags' in attrs and attrs['tags']:
|
||||
for tag in attrs['tags'].split(','):
|
||||
new_post.add_label(tag.strip())
|
||||
|
||||
if 'date' in attrs and attrs['date'] and \
|
||||
self._check_date(attrs['date']):
|
||||
new_post.published = atom.data.Published(text=attrs['date'])
|
||||
|
||||
if self.draft:
|
||||
new_post.control = atom.data.Control(\
|
||||
draft=atom.data.Draft(text='yes'))
|
||||
|
||||
return self.client.post(new_post, BLOG_POST_URL % self.blog_id)
|
||||
|
||||
def update_article(self, html_doc, attrs):
|
||||
"""
|
||||
Update article.
|
||||
html_doc is content of the article in HTML format, without headers,
|
||||
preamble, doctype and body tags.
|
||||
attrs is a dictionary that should hold title, date and tags.
|
||||
return BlogPost object
|
||||
"""
|
||||
if "id" not in attrs:
|
||||
raise Exception("Post Id not found in attributes!")
|
||||
|
||||
post = self._get_post(attrs['id'])
|
||||
post.content = atom.data.Content(text=html_doc, type="html")
|
||||
|
||||
# update publish date
|
||||
if 'date' in attrs and attrs['date'] and \
|
||||
self._check_date(attrs['date']):
|
||||
post.published = atom.data.Published(text=attrs['date'])
|
||||
|
||||
if 'title' in attrs and attrs['title']:
|
||||
post.title = atom.data.Title(text=attrs['title'], type="text")
|
||||
#
|
||||
# update tag list
|
||||
if 'tags' in attrs:
|
||||
tags = [tag.strip() for tag in attrs['tags'].split(',')]
|
||||
for index, label in enumerate(post.category):
|
||||
if label.term not in tags:
|
||||
del(post.category[index])
|
||||
|
||||
for tag in tags:
|
||||
self._add_tag(post, tag.strip())
|
||||
|
||||
return self.client.update(post)
|
||||
|
||||
def delete_article(self, post_id):
|
||||
"""
|
||||
Delete selected article
|
||||
"""
|
||||
if not post_id:
|
||||
return "No article id provided"
|
||||
|
||||
post = self._get_post(post_id)
|
||||
self.client.delete(post)
|
||||
return None
|
||||
|
||||
|
||||
def _get_post(self, post_id):
|
||||
"""
|
||||
"""
|
||||
post_href = self.blog.get_post_link().href
|
||||
return self.client.get_feed(post_href + "/%s" % post_id,
|
||||
desired_class=BlogPost)
|
||||
|
||||
def _add_tag(self, post, tag):
|
||||
"""
|
||||
post - BlogPost object
|
||||
tag - string with tag/label to add
|
||||
"""
|
||||
for label in post.category:
|
||||
if label.term == tag:
|
||||
return
|
||||
|
||||
post.add_label(tag)
|
||||
|
||||
def _extract_date(self, date_string, time=False):
|
||||
"""
|
||||
Extract date from the string and optionally time
|
||||
"""
|
||||
|
||||
if not self.DATE_PATTERN.match(date_string):
|
||||
return False
|
||||
|
||||
if not time:
|
||||
return self.DATE_PATTERN.match(date_string).groups()[0]
|
||||
|
||||
groups = self.DATE_PATTERN.match(date_string).groups()
|
||||
return groups[0] + " " + groups[1]
|
||||
|
||||
def _check_date(self, date):
|
||||
"""
|
||||
Parse date as RFC 3339 format, for example:
|
||||
2010-11-30T21:06:48.678+01:00
|
||||
or
|
||||
2010-11-30T21:06:48+01:00
|
||||
|
||||
Returns true, if date is acceptable, false otherwise
|
||||
"""
|
||||
if not self.DATE_PATTERN.match(date):
|
||||
return False
|
||||
|
||||
groups = self.DATE_PATTERN.match(date).groups()
|
||||
_date = groups[0]
|
||||
_time = groups[1]
|
||||
_tz = len(groups) == 3 and groups[2] or groups[3]
|
||||
|
||||
try:
|
||||
datetime.datetime.strptime(_date, self.DATE_FORMAT)
|
||||
datetime.datetime.strptime(_time, self.TIME_FORMAT)
|
||||
datetime.datetime.strptime(_tz, self.TZ_FORMAT)
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _update_date(self, post, attrs):
|
||||
"""
|
||||
Update articles published date
|
||||
"""
|
||||
|
||||
def _authorize(self, login, password):
|
||||
"""
|
||||
Try to authorize in Google service.
|
||||
Authorization is kept in client object. In case of wrong credentials,
|
||||
exception is thrown.
|
||||
"""
|
||||
source = 'Blogger_Python_Sample-2.0'
|
||||
service = 'blogger'
|
||||
|
||||
self.client.client_login(login,
|
||||
password,
|
||||
source=source,
|
||||
service=service)
|
||||
|
||||
def _set_blog(self, blogname):
|
||||
"""
|
||||
Set correct blog, as defined in blogname
|
||||
"""
|
||||
for blog in self.feed.entry:
|
||||
if blog.get_blog_name() == blogname:
|
||||
self.blog_id = blog.get_blog_id()
|
||||
self.blog = blog
|
||||
break
|
||||
|
||||
197
ftplugin/rst/rst2blogger/main.py
Normal file
197
ftplugin/rst/rst2blogger/main.py
Normal file
@@ -0,0 +1,197 @@
|
||||
# vim: fileencoding=utf8
|
||||
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 = vim.current.buffer.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):
|
||||
bufcontent = "\n".join(vim.current.buffer)
|
||||
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()
|
||||
|
||||
if not post:
|
||||
return "There is something fishy with creating new article."
|
||||
|
||||
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\'. 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:
|
||||
result = blog.delete_article(art[0])
|
||||
if result is None:
|
||||
return "Article deleted"
|
||||
else:
|
||||
return result
|
||||
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.
|
||||
"""
|
||||
|
||||
if add_container:
|
||||
html = "<div>" + html + "</div>"
|
||||
|
||||
message = ""
|
||||
try:
|
||||
minidom.parseString(html)
|
||||
except ExpatError as ex:
|
||||
message = str(ex)
|
||||
|
||||
return message
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class Attrs(object):
|
||||
|
||||
class Pygments(Directive):
|
||||
"""
|
||||
Source code syntax hightlighting.
|
||||
Source code syntax highlighting.
|
||||
"""
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
@@ -72,7 +72,7 @@ class CustomHTMLTranslator(HTMLTranslator):
|
||||
|
||||
def depart_docinfo(self, node):
|
||||
"""
|
||||
Reset body, remove unnecesairy content.
|
||||
Reset body, remove unnecessary content.
|
||||
"""
|
||||
self.body = []
|
||||
|
||||
@@ -165,8 +165,7 @@ class NoHeaderHTMLTranslator(CustomHTMLTranslator):
|
||||
Harvest docinfo fields and store it in global dictionary.
|
||||
"""
|
||||
key, val = [n.astext() for n in node]
|
||||
key = key.lower()
|
||||
Attrs.ATTRS[key] = val
|
||||
Attrs.ATTRS[key.lower()] = val.strip()
|
||||
|
||||
def visit_date(self, node):
|
||||
"""
|
||||
@@ -176,8 +175,9 @@ class NoHeaderHTMLTranslator(CustomHTMLTranslator):
|
||||
|
||||
class PreviewHTMLTranslator(CustomHTMLTranslator):
|
||||
"""
|
||||
Class for dislpay article in the browser as a preview.
|
||||
Class for display article in the browser as a preview.
|
||||
"""
|
||||
CSS = []
|
||||
def __init__(self, document):
|
||||
"""
|
||||
Alter levels for the heading tags, define custom, blog specific
|
||||
@@ -188,9 +188,7 @@ class PreviewHTMLTranslator(CustomHTMLTranslator):
|
||||
self.initial_header_level = 1
|
||||
self.section_level = 1
|
||||
# order of css files is important
|
||||
self.default_stylesheets = ["css/widget_css_2_bundle.css",
|
||||
"css/style_custom.css",
|
||||
"css/style_blogger.css"]
|
||||
self.default_stylesheets = PreviewHTMLTranslator.CSS
|
||||
self.stylesheet = [self.stylesheet_link % self.encode(css) \
|
||||
for css in self.default_stylesheets]
|
||||
self.body_ = []
|
||||
@@ -230,21 +228,27 @@ class BlogPreviewWriter(Writer):
|
||||
"""
|
||||
Custom Writer class for generating full HTML of the article
|
||||
"""
|
||||
def __init__(self):
|
||||
def __init__(self, stylesheets=None):
|
||||
Writer.__init__(self)
|
||||
if not stylesheets:
|
||||
stylesheets = []
|
||||
self.translator_class = PreviewHTMLTranslator
|
||||
self.translator_class.CSS = stylesheets
|
||||
|
||||
def translate(self):
|
||||
self.document.settings.output_encoding = "utf-8"
|
||||
Writer.translate(self)
|
||||
|
||||
|
||||
def blogPreview(string):
|
||||
def blogPreview(string, stylesheets=None):
|
||||
"""
|
||||
Returns partial HTML of the article, and attribute dictionary
|
||||
Returns full HTML of the article.
|
||||
string argument is an article in reST
|
||||
"""
|
||||
html_output = core.publish_string(string, writer=BlogPreviewWriter())
|
||||
if not stylesheets:
|
||||
stylesheets = []
|
||||
html_output = core.publish_string(string,
|
||||
writer=BlogPreviewWriter(stylesheets))
|
||||
html_output = html_output.strip()
|
||||
html_output = html_output.replace("<!-- more -->", "\n<!-- more -->\n")
|
||||
return html_output
|
||||
@@ -259,5 +263,10 @@ def blogArticleString(string):
|
||||
html_output = core.publish_string(string, writer=BlogBodyWriter())
|
||||
html_output = html_output.strip()
|
||||
html_output = html_output.replace("<!-- more -->", "\n<!-- more -->\n")
|
||||
return html_output, Attrs.ATTRS
|
||||
attrs = {}
|
||||
for key in Attrs.ATTRS:
|
||||
if Attrs.ATTRS[key]:
|
||||
attrs[key] = Attrs.ATTRS[key]
|
||||
|
||||
return html_output, attrs
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
# vim: fileencoding=utf8
|
||||
#
|
||||
# Blogger interface to make easy way to create/update articles for specified
|
||||
# blog.
|
||||
#
|
||||
# It is assumed one way communication only, so you may create or update an
|
||||
# article from reST source files. There is no way to recreate article from
|
||||
# html to reST format.
|
||||
#
|
||||
# requirements:
|
||||
#
|
||||
# - Vim compiled with +python
|
||||
# - python 2.x (tested with 2.6)
|
||||
# - modules
|
||||
# - gdata (http://code.google.com/p/gdata-python-client)
|
||||
# - docutils (http://docutils.sourceforge.net)
|
||||
# - pytz (http://pytz.sourceforge.net)
|
||||
#
|
||||
# USE CASES:
|
||||
# 1. Create new post
|
||||
#
|
||||
# use reST template:
|
||||
# ===8<---
|
||||
# :Title: Blog post title
|
||||
# :Date: optional publish date (for example: 2010-11-28 18:47:05),
|
||||
# default: now()
|
||||
# :Modified: optional, default: None
|
||||
# :Tags: comma separated blog tags
|
||||
#
|
||||
# .. more
|
||||
#
|
||||
# --->8===
|
||||
#
|
||||
# All four docinfo are optional, however it is nice to give at least a title
|
||||
# to the article :)
|
||||
#
|
||||
#
|
||||
#
|
||||
# which is provided under templates directory or as a
|
||||
# snipMate shoortcut (see .vim/snippets/rst.snippets)
|
||||
#
|
||||
|
||||
# vim.eval('inputsecret("Password: ")')
|
||||
# echomsg expand("%:p")
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
import getpass # TODO: remove
|
||||
import time
|
||||
import datetime
|
||||
|
||||
import pytz
|
||||
import atom
|
||||
from gdata.blogger.client import BloggerClient
|
||||
|
||||
|
||||
class VimBlogger(object):
|
||||
"""
|
||||
"""
|
||||
|
||||
def __init__(self, blogname, login, password):
|
||||
"""
|
||||
"""
|
||||
self.blog = None
|
||||
self.client = BloggerClient()
|
||||
self._authorize(login, password)
|
||||
|
||||
self.feed = self.client.get_blogs()
|
||||
self._set_blog(blogname)
|
||||
#self._get_arts(blogname)
|
||||
|
||||
def _set_blog(self, blogname):
|
||||
"""
|
||||
"""
|
||||
for blog in self.feed.entry:
|
||||
if blog.get_blog_name() == blogname:
|
||||
self.blog = blog
|
||||
break
|
||||
|
||||
|
||||
def _get_arts(self, blogname):
|
||||
"""
|
||||
"""
|
||||
feed = self.client.get_posts(self.blog.get_blog_id())
|
||||
for entry in feed.entry:
|
||||
print entry.title.text
|
||||
#
|
||||
import ipdb; ipdb.set_trace()
|
||||
#
|
||||
# entry.content obiekt zawiera ciało artykułu (entry.content.text
|
||||
# posiada czystą formę która mnie interesuje najbardziej, do której
|
||||
# można pisać
|
||||
#
|
||||
# entry.category - lista wszystkich kategorii (blogowych tagów), które
|
||||
# post posiada. Są to elementy klasy atom.data.Category, które
|
||||
# łatwiutko stworzyć i dodać do posta:
|
||||
# import atom
|
||||
# cat1 = atom.data.Category()
|
||||
# cat1.term = "nowy tag dla bloggera"
|
||||
# entry.category.append(cat1)
|
||||
#
|
||||
# entry.title przechowuje tytuł posta
|
||||
|
||||
def _authorize(self, login, password):
|
||||
"""
|
||||
"""
|
||||
source = 'Blogger_Python_Sample-2.0'
|
||||
service = 'blogger'
|
||||
|
||||
self.client.client_login(login,
|
||||
password,
|
||||
source=source,
|
||||
service=service)
|
||||
def create_article(self, title, html_doc, tags=None):
|
||||
"""
|
||||
"""
|
||||
|
||||
blog_id = self.blog.get_blog_id()
|
||||
if tags is None:
|
||||
tags = []
|
||||
return self.client.add_post(blog_id, title, html_doc, labels=tags,
|
||||
draft=True)
|
||||
|
||||
def update_article(self, title, html_doc, tags=None):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
p = getpass.getpass("Password: ")
|
||||
b = VimBlogger("rdobosz", "gryf73@gmail.com", p)
|
||||
72
ftplugin/rst/vimblogger_ft.vim
Normal file
72
ftplugin/rst/vimblogger_ft.vim
Normal file
@@ -0,0 +1,72 @@
|
||||
" reST to blogger vim interface.
|
||||
" Provide some convinient commands for creating preview from the reST file
|
||||
" and to send articles to blog.
|
||||
|
||||
if exists("b:did_rst_plugin")
|
||||
finish " load only once
|
||||
else
|
||||
let b:did_blogger_plugin = 1
|
||||
endif
|
||||
|
||||
if exists(':PreviewBlogArticle')
|
||||
finish
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_browser")
|
||||
let g:blogger_browser = 0
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_name")
|
||||
let g:blogger_name = ""
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_login")
|
||||
let g:blogger_login= ""
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_pass")
|
||||
let g:blogger_pass = "Kurcz4czek"
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_draft")
|
||||
let g:blogger_draft = 1
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_maxarticles")
|
||||
let g:blogger_maxarticles = 0
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_confirm_del")
|
||||
let g:blogger_confirm_del = 1
|
||||
endif
|
||||
|
||||
if !exists("g:blogger_stylesheets")
|
||||
let g:blogger_stylesheets = []
|
||||
endif
|
||||
|
||||
python << EOF
|
||||
import os
|
||||
import sys
|
||||
|
||||
import vim
|
||||
|
||||
scriptdir = os.path.dirname(vim.eval('expand("<sfile>")'))
|
||||
sys.path.insert(0, scriptdir)
|
||||
|
||||
try:
|
||||
from rst2blogger.main import Rst2Blogger
|
||||
except ImportError:
|
||||
print "Plugin vimblogger cannot be loaded, due to lack of required modules"
|
||||
EOF
|
||||
|
||||
if !exists(":PreviewBlogArticle")
|
||||
command PreviewBlogArticle py print Rst2Blogger().preview()
|
||||
endif
|
||||
|
||||
if !exists(":SendBlogArticle")
|
||||
command SendBlogArticle py print Rst2Blogger().post()
|
||||
endif
|
||||
|
||||
if !exists(":DeleteBlogArticle")
|
||||
command DeleteBlogArticle py print Rst2Blogger().delete()
|
||||
endif
|
||||
Reference in New Issue
Block a user