From 1b906da57a357573268eeb10472dd848c8db11fa Mon Sep 17 00:00:00 2001 From: icyleaf Date: Fri, 4 Jan 2013 20:01:35 +0800 Subject: [PATCH 1/5] import chyrp feed file --- pelican/tools/pelican_import.py | 27 ++++++++++++++++++++++++++- tests/content/chyrpexport.atom | 1 + tests/test_importer.py | 16 +++++++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100755 tests/content/chyrpexport.atom diff --git a/pelican/tools/pelican_import.py b/pelican/tools/pelican_import.py index fdd1ac51..28b8c507 100755 --- a/pelican/tools/pelican_import.py +++ b/pelican/tools/pelican_import.py @@ -6,6 +6,7 @@ import os import subprocess import sys import time +import re from codecs import open @@ -167,6 +168,24 @@ def dc2fields(file): yield (post_title, content, slugify(post_title), post_creadt, author, categories, tags, post_format) +def chyrp2fields(atom): + """Opens a Chyrp Atom file, and yield pelican fields""" + import feedparser + d = feedparser.parse(atom) + for entry in d.entries: + + if entry.chyrp_status == 'public' and entry.chyrp_feather == 'text': + + date = (time.strftime("%Y-%m-%d %H:%M", entry.updated_parsed) + if hasattr(entry, "updated_parsed") else None) + author = entry.author if hasattr(entry, "author") else None + tags = entry.tags if hasattr(entry, "tags") else None + slug = entry.chyrp_url if hasattr(entry, "chyrp_url") else None + tags = [tag[0] for tag in re.findall(r"(.*)\:\s*\"(.*)\"", entry.tags)] if hasattr(entry, "tags") else None + + yield (entry.title, entry.summary, slug, date, author, [], tags, "html") + + def feed2fields(file): """Read a feed and yield pelican fields""" import feedparser @@ -292,6 +311,8 @@ def main(): help='Wordpress XML export') parser.add_argument('--dotclear', action='store_true', dest='dotclear', help='Dotclear export') + parser.add_argument('--chyrp', action='store_true', dest='chyrp', + help='Chyrp Atom export') parser.add_argument('--feed', action='store_true', dest='feed', help='Feed to parse') parser.add_argument('-o', '--output', dest='output', default='output', @@ -316,10 +337,12 @@ def main(): input_type = 'wordpress' elif args.dotclear: input_type = 'dotclear' + elif args.chyrp: + input_type = 'chyrp' elif args.feed: input_type = 'feed' else: - error = "You must provide either --wpfile, --dotclear or --feed options" + error = "You must provide either --wpfile, --dotclear, --chyrp or --feed options" exit(error) if not os.path.exists(args.output): @@ -333,6 +356,8 @@ def main(): fields = wp2fields(args.input) elif input_type == 'dotclear': fields = dc2fields(args.input) + elif input_type == 'chyrp': + fields = chyrp2fields(args.input) elif input_type == 'feed': fields = feed2fields(args.input) diff --git a/tests/content/chyrpexport.atom b/tests/content/chyrpexport.atom new file mode 100755 index 00000000..637769ac --- /dev/null +++ b/tests/content/chyrpexport.atom @@ -0,0 +1 @@ + icyleaf's blog Posts tag:localhost,2013:Chyrp 2013-01-01T00:34:37+00:00 Chyrp 让你的WindowsXP摇身一变为Ubuntu tag:localhost,2007-09-16:/chyrp/admin/id/2 2007-09-16T21:55:00+00:00 2007-09-16T21:55:00+00:00 icyleaf http://icyleaf.com root 翻译+修改自:<a href="http://www.theindietribune.com/2007/06/how-to-make-windows-look-like-ubuntu.html" rel="nofollow external" class="tpc">The Indie Tribune</a> 1.现从visual style(视觉风格)开始,如果你没有安装<a href="http://www.softpedia.com/get/System/OS-Enhancements/UXTheme-MultiPatcher.shtml" rel="nofollow external" class="tpc">Uxtheme Multipatcher</a>, 请下载并安装好否则无法实现。然后需要下载<a href="http://www.deviantart.com/deviation/37743373/" rel="nofollow external" class="tpc">Human Visual Style</a>。 2.打开C:\Windows\Resources\Themes\把Human Visual Style按格式解压缩这这里(Windows的系统盘) 现在在桌面右击,选择“外观”.在主题选项卡选择Human Visual Style。 接着是改图标,首先需要安装<a href="http://joost.endoria.net/home" rel="nofollow external" class="tpc">Icontweaker</a> ,然后在安装<a href="http://www.deviantart.com/deviation/44658210/" rel="nofollow external" class="tpc">Ubuntu Icontweaker theme</a>。 3.如果你想改变壁纸的话,点<a href="http://www.deviantart.com/deviation/18673292/" rel="nofollow external" class="tpc">这里</a> 或者 <a href="http://www.deviantart.com/deviation/57286980/" rel="nofollow external" class="tpc">这里</a>。 4.更换Windows Explorer图标,首先安装<a href="http://www.crystalxp.net/galerie/en.id.551.htm" rel="nofollow external" class="tpc">Styler toolbar</a>(免费) ,在下载<a href="http://www.deviantart.com/deviation/41848476/" rel="nofollow external" class="tpc">Ubuntu Human Theme</a>即可。 5.设置鼠标样式,点<a href="http://www.deviantart.com/deviation/35930998/" rel="nofollow external" class="tpc">这里</a>下载。 6.实现3D效果,使用<a href="http://www.stardock.com/products/bootskin/" rel="nofollow external" class="tpc">这个</a>实现,选择 "3D CUBE"。 7.实现开机启动画面,使用BootSkin(免费),点这里获得,最后下载<a href="http://www.wincustomize.com/skins.aspx?skinid=8476&libid=32&c=1" rel="nofollow external" class="tpc">Ubuntu Bootskin</a>。 8.实现登陆画面点<a href="http://www.deviantart.com/deviation/52590940/" rel="nofollow external" class="tpc">这里</a>。 9.对于使用Firefox浏览器的用户,你也可以安装其<a href="https://addons.mozilla.org/en-US/firefox/addon/3008" rel="nofollow external" class="tpc">Ubuntu Theme(皮肤)</a>。 10.WinRAR样式:<a href="http://www.rarlab.com/rar/WinRAR_Tango_48x48.theme.rar" rel="nofollow external" class="tpc">Here</a>. wordpress 让你的WindowsXP摇身一变为Ubuntu text windowsxp-became-to-ubuntu windowsxp-became-to-ubuntu 0 public 升级 xcode 4.3.1 tag:localhost,2012-03-09:/chyrp/admin/id/271 2012-03-09T14:14:31+00:00 2012-03-08T15:19:25+00:00 icyleaf http://icyleaf.com root 下载 XCode 目前有两种途径: 1. [Mac App Store](http://itunes.apple.com/us/app/xcode/id497799835?mt=12) 2. [Apple Developer Download Page](https://developer.apple.com/downloads/index.action) (需要有开发者账号并登陆) 对于前者好处在于免费下载但下载时间或许非常漫长;但后者如果条件都满足的话(apple developer id + [script](http://t.cn/zOcn4KN) + vps + axel)那就可以非常快速的下载到页面上面的所有资源。 XCode 4.3 之后的版本采用核心和模块分离,现在主程序只有 1.8G 左右,其余的包括 Command line tools + dashcode + graphics tools (同样可以使用上面的脚本)需要单独按需下载。但这还不是变化最大的,最大的地方在于之前版本都是存放在 `/Developer` 路径下面,4.3 之后的版本统一改放在了 `/Applications` 下面,下载 dmg 打开后直接把 Xcode 拖入 `/Applications` 即可。 安装完毕后首次启动,会有一个提示,这点需要非常注意,新版的会要求你把 `/Developer` 以及 `/Applications/Install Xcode` 一并移动至回收站,注意是整个目录完全移动。假如你的机器安装了其他的开发工具放置在了 `/Developer` 了,这里就需要谨慎处理。 初次之外,我参考 [Use Your Loaf](http://useyourloaf.com/blog/2012/2/17/updating-to-xcode-43.html) 的博文,假如你的环境还需要依赖 Command line tools for xcode,除了下载和安装的过程,还需要在终端作下处理。比如上面提到博文所说的 `agvtools` 管理 App 版本自动化的工具。在升级 4.3+ 版本可能就会出现下面的错误 $ agvtools Error: No developer directory found at /Developer. Run /usr/bin/xcode-select to update the developer directory path. Use Your Loaf 博文提到需要使用 `xcode-select` 重新选择 Xcode 的安装路径,来保证终端工具可以正常运行,但是在 4.3.1 中我尝试还是失败。提示如下: $ sudo /usr/bin/xcode-select -switch /Applications/Xcode.app $ agvtool Error: Can't run /Applications/Xcode.app/usr/bin/agvtool (no such file). 经常检查发现,实际上 Command line tools 安装后存放在 `/Applications/Xcode.app/Contents/Developer/usr` 路径下面,尝试更正操作: $ sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer/ 搞定! ---------华丽丽的分割线--------- **Instruments 哪里去了?** 哼哼,尝试在 Xcode 图标右键 "Open Developer Tool",看到了吧,还有一些其他的工具 :) 0 open --- xcode: "xcode" 升级 xcode 4.3.1 text upgrade-xcode-431 upgrade-xcode-431 0 public Diablo 3 Web API tag:localhost,2012-06-20:/chyrp/admin/id/285 2012-06-20T15:17:30+00:00 2012-06-11T10:21:59+00:00 icyleaf http://icyleaf.com root 0 open icyleaf#1667 蛮子技能参考: - [组队](http://db.d.163.com/calculator/barbarian.html#bXYgVk!eVb!cYZYcc) - [SOLO Act1&2](http://db.d.163.com/calculator/barbarian.html#WSPTVk!egb!acZbcc) - [SOLO Act3+](http://db.d.163.com/calculator/barbarian.html#WSPgVk!egb!acZacc) - [Goblin Hunter](http://db.d.163.com/calculator/barbarian.html#WXPUVk!eVh!caZbcZ) Diablo 3 Web API http://blizzard.github.com/d3-api-docs/ --- Diablo3: "diablo3" link diablo-3-web-api diablo-3-web-api 0 public \ No newline at end of file diff --git a/tests/test_importer.py b/tests/test_importer.py index 449a7643..339122fd 100644 --- a/tests/test_importer.py +++ b/tests/test_importer.py @@ -2,11 +2,12 @@ import os -from pelican.tools.pelican_import import wp2fields, fields2pelican +from pelican.tools.pelican_import import wp2fields, chyrp2fields, fields2pelican from .support import unittest, temporary_folder, mute, skipIfNoExecutable CUR_DIR = os.path.dirname(__file__) WORDPRESS_XML_SAMPLE = os.path.join(CUR_DIR, 'content', 'wordpressexport.xml') +CHYRP_ATOM_SAMPLE = os.path.join(CUR_DIR, 'content', 'chyrpexport.atom') try: import BeautifulSoup @@ -16,6 +17,19 @@ except ImportError: @skipIfNoExecutable(['pandoc', '--version']) @unittest.skipUnless(BeautifulSoup, 'Needs BeautifulSoup module') + +class TestChyrpAtomImporter(unittest.TestCase): + + def setUp(self): + self.posts = chyrp2fields(CHYRP_ATOM_SAMPLE) + + def test_ignore_empty_posts(self): + + posts = list(self.posts) + self.assertTrue(posts) + for title, content, slug, date, author, tags, format in posts: + self.assertTrue(title.strip()) + class TestWordpressXmlImporter(unittest.TestCase): def setUp(self): From 3987921875cb5a1b0a622a2c3d4841171732aa33 Mon Sep 17 00:00:00 2001 From: icyleaf Date: Sat, 5 Jan 2013 21:03:45 +0800 Subject: [PATCH 2/5] unescape chyrp html content --- pelican/tools/pelican_import.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pelican/tools/pelican_import.py b/pelican/tools/pelican_import.py index 28b8c507..74d0ab8f 100755 --- a/pelican/tools/pelican_import.py +++ b/pelican/tools/pelican_import.py @@ -171,19 +171,24 @@ def dc2fields(file): def chyrp2fields(atom): """Opens a Chyrp Atom file, and yield pelican fields""" import feedparser + import markdown + d = feedparser.parse(atom) for entry in d.entries: if entry.chyrp_status == 'public' and entry.chyrp_feather == 'text': + # Chyrp support both html and markdown, must convert by finding type + # content = markdown.markdown(entry.summary) + content = HTMLParser().unescape(entry.summary) date = (time.strftime("%Y-%m-%d %H:%M", entry.updated_parsed) if hasattr(entry, "updated_parsed") else None) author = entry.author if hasattr(entry, "author") else None tags = entry.tags if hasattr(entry, "tags") else None slug = entry.chyrp_url if hasattr(entry, "chyrp_url") else None - tags = [tag[0] for tag in re.findall(r"(.*)\:\s*\"(.*)\"", entry.tags)] if hasattr(entry, "tags") else None + tags = [tag[1] for tag in re.findall(r"(.*)\:\s*\"(.*)\"", entry.tags)] if hasattr(entry, "tags") else None - yield (entry.title, entry.summary, slug, date, author, [], tags, "html") + yield (entry.title, content, slug, date, author, [], tags, "html") def feed2fields(file): From 2863135968c66ee6912ef883d02efa348acef1a2 Mon Sep 17 00:00:00 2001 From: icyleaf Date: Tue, 8 Jan 2013 21:33:48 +0800 Subject: [PATCH 3/5] Now you can create article via cli! --- pelican/tools/pelican_article.py | 63 ++++++++++++++++++++++++++++++++ setup.py | 3 +- 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 pelican/tools/pelican_article.py diff --git a/pelican/tools/pelican_article.py b/pelican/tools/pelican_article.py new file mode 100644 index 00000000..7dcdf5dc --- /dev/null +++ b/pelican/tools/pelican_article.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import argparse +import os +import shutil +import sys +import datetime + +from pelican.utils import slugify +from pelican.tools.pelican_import import build_markdown_header, build_header + + +def create_template(args): + + if not os.path.exists(args.path): + try: + os.mkdir(args.path) + except OSError: + error = 'Unable to create the output folder: ' + args.path + exit(error) + + title = args.title.decode('utf-8') + slug = slugify(title) + date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") + categories = args.categories.split('\W+') if args.categories else None + tags = args.tags.split('\W+') if args.tags else None + + if (args.markup == 'markdown') or (args.markup == 'md') : + ext = '.md' + header = build_markdown_header(title, date, args.author, categories, tags, slug) + else: + ext = '.rst' + header = build_header(title, date, args.author, categories, tags, slug) + + filename = os.path.join(args.path, slug+ext) + header = header.encode('utf-8') + + with open(filename, 'w') as fs: + fs.write(header) + + print 'Article template create in "%s"' % filename + + +def main(): + + argv = sys.argv[1:] + argv.append('-h') if len(argv) == 0 else None + + parser = argparse.ArgumentParser(description='Create article with templation') + + parser.add_argument('title', help='article title') + parser.add_argument('-a', '--author', dest='author', default='[name]', help='Article author') + parser.add_argument('-t', '--tags', dest='tags', default=None, help='Article tags(separated by comma)') + parser.add_argument('-c', '--categories', dest='categories', default=None, help='Article categories') + parser.add_argument('-s', '--slug', dest='slug', default=None, help='Article slug') + parser.add_argument('-p', '--path', dest='path', default='content/posts', help='Article save directory') + parser.add_argument('-m', '--markup', dest='markup', default='md', help='Article markup format (supports rst & markdown)') + args = parser.parse_args(argv) + + create_template(args); + + diff --git a/setup.py b/setup.py index b6a54414..af53f8fe 100755 --- a/setup.py +++ b/setup.py @@ -14,7 +14,8 @@ entry_points = { 'pelican = pelican:main', 'pelican-import = pelican.tools.pelican_import:main', 'pelican-quickstart = pelican.tools.pelican_quickstart:main', - 'pelican-themes = pelican.tools.pelican_themes:main' + 'pelican-themes = pelican.tools.pelican_themes:main', + 'pelican-article = pelican.tools.pelican_article:main' ] } From 4167087e380b7873d9a67425327cc35bb8b7d4a4 Mon Sep 17 00:00:00 2001 From: icyleaf Date: Wed, 24 Apr 2013 11:47:05 +0800 Subject: [PATCH 4/5] fixed slug would not work --- pelican/tools/pelican_article.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pelican/tools/pelican_article.py b/pelican/tools/pelican_article.py index 7dcdf5dc..5df1681e 100644 --- a/pelican/tools/pelican_article.py +++ b/pelican/tools/pelican_article.py @@ -21,10 +21,10 @@ def create_template(args): exit(error) title = args.title.decode('utf-8') - slug = slugify(title) + slug = args.slug if args.slug else slugify(title) date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") - categories = args.categories.split('\W+') if args.categories else None - tags = args.tags.split('\W+') if args.tags else None + categories = args.categories.split('\W+') if args.categories else '' + tags = args.tags.split('\W+') if args.tags else '' if (args.markup == 'markdown') or (args.markup == 'md') : ext = '.md' From 230fa6bd8e5faa581bf1fc96f249f266cbbae1c6 Mon Sep 17 00:00:00 2001 From: icyleaf Date: Tue, 17 Sep 2013 22:54:42 +0800 Subject: [PATCH 5/5] typo --- pelican/tools/pelican_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pelican/tools/pelican_import.py b/pelican/tools/pelican_import.py index 001e35af..b9c26553 100755 --- a/pelican/tools/pelican_import.py +++ b/pelican/tools/pelican_import.py @@ -632,7 +632,7 @@ def main(): elif args.feed: input_type = 'feed' else: - error = "You must provide either --wpfile, --dotclear, --posterous, --tumblr, --chrpy or --feed options" + error = "You must provide either --wpfile, --dotclear, --posterous, --tumblr, --chyrp or --feed options" exit(error) if not os.path.exists(args.output):