def appendMetadataToPost(self, mdict, post): """ Append metadata to post. """ try: id = post.id except AttributeError: id = mdict.get('id', None) if not id: printDebug("ERROR" , "This looks like a new post, use --post option" ) sys.exit(0) post.id = id title = mdict['title'] post.title = title.strip() self.attachType(mdict, post) self.attachStatus(mdict, post) termsAndCats = dict() termsAndCats = self.attachTags(mdict, post, termsAndCats) termsAndCats = self.attachCategories(mdict, post, termsAndCats) post.terms_names = termsAndCats return post
def markdownToHtml(content, convertor='pandoc'): global panDoc global pandocFmt if len(content) < 1: printDebug("WARN", "No content to convert using pandoc") return None if panDoc: printDebug("DEBUG", "Using pandoc for markdown -> html") cmd = ["pandoc", "--mathjax", "--highlight-style=pygments" , "-f", 'markdown'+pandocFmt, "-t", "html"] p = subprocess.Popen(cmd , stdin = subprocess.PIPE , stdout = subprocess.PIPE ) p.stdin.write(content) c = p.communicate()[0] if len(c) < 2: printDebug("WARN", "Seems like pandoc failed to work") return None printDebug("LOG", "\n\n Converted text \n {}".format(c)) return decodeText(c) # else use inbuild html2text.py else: printDebug("DEBUG", "Using python-markdown for markdown -> html") return markdown.markdown(decodeText(content))
def formatContent(txt, fmt): """ Format the content as per fmt. """ content = getContent(txt) if fmt == "html": content = htmlToHtml(content) elif fmt == "markdown": content = markdownToHtml(content) else: printDebug("WARN", "Unsupported format %s " % fmt) printDebug("WARN", " - Assuming markdown") content = markdownToHtml(content) return content
def getMetadata(txt): """ Get metadata out of a txt """ if not "---" in txt: printDebug("ERROR", "The text does not contain any metadata header") print txt sys.exit(1) pat = re.compile(r'\-\-\-+(?P<metadata>.+?)\-\-\-+', re.DOTALL) m = pat.search(txt) if m: return m.group('metadata') else: printDebug("ERROR", "No metadata found in text") sys.exit(0)
def htmlToMarkdown(content, convertor='pandoc'): global panDoc global pandocFmt if panDoc and convertor == 'pandoc': printDebug("INFO", "Using pandoc for html -> markdown") cmd = ["pandoc", "-t", 'markdown'+pandocFmt, "-f", "html"] p = subprocess.Popen(cmd , stdin = subprocess.PIPE , stdout = subprocess.PIPE ) p.stdin.write(content) content = p.communicate()[0] return decodeText(content) # Use markdown package to convert markdown to html else: printDebug("INFO", "html2text for html -> markdown") h = html2text.HTML2Text() content = h.handle(decodeText(content)) return content
def newPostToWordpress(self, postName): printDebug("STEP", "You are going to create a new post!") post = WordPressPost() post.id = self.wp.call(NewPost(post)) ## get the text of new post fileName = postName fmt, txt = formatter.readInputFile(fileName) self.format = fmt try: self.updatePost(post, txt) except Exception as e: printDebug("WARN", "Failed to send post to wordpress") printDebug("DEBUG", "Error was {0}".format(e)) return printDebug("INFO", "Post sent successfully") # Now download the sent post and save it. postNew = self.wp.call(GetPost(post.id)) self.writePosts([postNew]) printDebug("ADVICE", "You should now delete : {0}.".format(postName)) return 0
def main(): parser = argparse.ArgumentParser(description="Wordpress client") parser.add_argument('--config', metavar="config" , default = os.environ['HOME'] + "/.config/twordpress/config" , help = "Config file containing settings: ~/.config/twordpress/config" ) parser.add_argument('--blog', metavar="blog index in config file eg. 0, 1" , default = "0" , help = "Index of blog. If not given 0 is assumed" ) parser.add_argument('--proxy', metavar="proxy" , help = "Setup proxy information.") parser.add_argument('--fetch', metavar="[all|post_name]" , help="Fetch a post with similar looking name. \ If 'all' is given then it fetches all\ posts " ) parser.add_argument('--update', metavar='blog_file' , help="Update a post." ) parser.add_argument('--new', metavar='blog_file' , help="New post or page" ) parser.add_argument('--zemanta', metavar='zemanta' , help="Zemanta suggestion to embed in post" ) args = parser.parse_args() args = parseConfigFile(args) if args.server == "wordpress": printDebug("INFO", "Wordpress `{}`".format(args.blogName)) wpObj = Wordpress(args) else: printDebug("WARN" , "It does not look like a wordpress: {}".format(args.server) )
def run(self, args): p = args.proxy if p is None: p = os.environ.get('http_proxy') if p is not None: printDebug("DEBUG", "Using http_proxy evvironment variable") if 'http://' in p: p = p.replace('http://', '') elif 'https://' in p: p = p.replace('https://', '') else: printDebug("DEBUG", "Not using proxy") self.wp = Client(self.blog, args.user, args.password) else: p = p.replace('https://', '') try: self.wp = Client(self.blog, args.user, args.password, proxy=p) except Exception as e: printDebug("ERROR", "Failed to connect to %s" % self.blog) raise e # Send a file to wordpress. if args.update : fileName = args.update if not os.path.exists(fileName): raise IOError, "File %s does not exists" % fileName fmt, txt = formatter.readInputFile(fileName) self.format = fmt post = WordPressPost() assert post is not None self.updatePost(post, txt) elif args.new : self.newPostToWordpress(args.new) # Fetch blogs from wordpress. elif args.fetch : # Get all posts self.fetchWpPosts(args.fetch) else : # get recent posts printDebug("STEP", "Getting recent posts") posts = self.wp.call(GetPosts( {'post_status': 'publish'})) self.writePosts(posts)
def writePost(self, post, format): """ Fetch a single post and write it to file. """ assert int(post.id.strip()) > 0, "Post must have an id" title = post.title.encode('utf-8') printDebug("POST", "Downloading: `{}`".format(title)) terms = post.terms content = post.content.encode('utf-8') postDir = formatter.titleToFilePath(title, self.blogDir) # Create directory for this filename in blogDir. if not os.path.isdir(postDir): os.makedirs(postDir) # Good now for this post, we have directory. Download its content in # content.md file. fileMarkDown = os.path.join(postDir, 'content.md') fileHtml2 = os.path.join(postDir, 'content.html') with open(fileHtml2, "w") as ff: with open(fileMarkDown, "w") as f: f.write("{}\n".format(deliminator)) f.write("title: ") f.write(title) f.write("\ncomments: true") f.write("\ntype: " + post.post_type) f.write("\nlayout: " + post.post_type) f.write("\nstatus: " + post.post_status) f.write("\nid: " + post.id) ff.write("{}\n".format(deliminator)) ff.write("title: ") ff.write(title) ff.write("\ntype: " + post.post_type) ff.write("\nlayout: " + post.post_type) ff.write("\nstatus: " + post.post_status) ff.write("\nid: " + post.id) cats = [] tags = [] for t in terms : tname = t.name.encode('utf-8') if t.taxonomy == 'post_tag': tags.append(tname) elif t.taxonomy == 'category': cats.append(tname) else: cats.append(tname) if tags: tags = filter(None, [t for t in tags]) tagLine = 'tags: [{}]'.format(', '.join(tags)) f.write('\n{}'.format(tagLine)) ff.write('\n{0}'.format(tagLine)) if cats: cats = filter(None, [c.encode('utf-8') for c in cats]) f.write('\ncategories: [{0}]'.format(', '.join(cats))) ff.write('\ncategories: [{0}]'.format(', '.join(cats))) f.write('\n') ff.write('\n') f.write("{}\n\n".format(deliminator)) ff.write("{}\n\n".format(deliminator)) # TODO: Get links from the post # Write content to file. self.writeContent(f, content, format) self.writeContent(ff, content, "html")
def updatePost(self, post, txt) : # Check if there is no id. mdict = formatter.metadataDict(txt) content = formatter.getContent(txt) post = self.appendMetadataToPost(mdict, post) printDebug("STEP", "Updating post .. ", post.title) assert post.post_type # content if content : if len(content.strip()) == 0 : print("[E] : No content in file.") return else : printDebug("WARN", "Post with empty content.") content = "" if self.format == "html": content = formatter.htmlToHtml(content) elif self.format == "markdown": content = formatter.markdownToHtml(content) # Fix the math class pat = re.compile(r'\<span\s+class\=\"math\"\>\\\((.+?)\\\)\<\/span\>' , re.DOTALL) for m in pat.findall(content): printDebug("INFO", "Latex expression: ", m) content = pat.sub(r'$latex \1$', content) post.content = content.encode('utf-8') else: post.content = content.encode('utf-8') #logFile = os.path.join(self.blogDir, "sent_html") #printDebug("DEBUG", "Logging content into %s" % logFile) #with open(logFile, "w") as f: #f.write(post.content.encode('utf-8')) printDebug("STEP" , "Sending post : {0} : {1}.".format(post.id, post.title) ) try: self.wp.call(EditPost(post.id, post)) except Exception as e: printDebug("DEBUG", "I was trying to update but failed") printDebug("INFO", "Error was : {0}".format(e)) printDebug("DEBUG", "Content of post was written to log.txt file") with open("log.txt", "w") as f: f.write(post.content) sys.exit(0)