æ°å¹Žåãç§ã¯å¹žéã«ãWordPressããã°ãæã€ããšãã§ããŸããã æ®å¿µãªãããããã°ã¯æçš¿ããŒã¿ããŒã¹å šäœãšåãããã«çãæ®ããŸããã§ããããããã°èªäœã«ã€ããŠã§ã¯ãªãããã¹ãŠã®æ å ±ãã©ã®ããã«å ¬éããããã«ã€ããŠã話ããããšæããŸãã åœæãMicrosoftã¯æè¿Windows 7ãç«ã¡äžãããããšå ±ã«Windows Liveã¢ããªã±ãŒã·ã§ã³ã¹ã€ãŒãããªãªãŒã¹ããŸããã ã ããç§ã¯èŠãŠã¿ãããšã«ããŸãã-ãã®ããã±ãŒãžã§äœãããããã§ããïŒ äœããããç§ã¯Windows Live Writerã¢ããªã±ãŒã·ã§ã³ãæ°ã«å ¥ããŸãããããã¯ãããã¹ããå ¥åããã³æžåŒèšå®ããããã°ã«å ¬éã§ããããã°ã©ã ã§ãã ãŠãŒã¶ãŒãã¬ã³ããªãŒãªã€ã³ã¿ãŒãã§ãŒã¹ãå€ãã®æžåŒèšå®ããŒã«ãäžæžããããŒã«ã«ã«ä¿åããæ©èœãªã©ãç§ã¯æã«èœã¡ãŸããã ãã°ããããŠãWindows Live Writerãªãã§ã¯ããã°ãæ³åã§ããŸããã§ããã
æ°å¹Žãçµã¡ãŸããã ãã§ã«æžããããã«ããã®ããã°ã¯æ¶ããããšã¯ãªããPythonããããŠDjangoã§ã®ããã°ã©ãã³ã°ã«èå³ãæã€ããã«ãªããŸããã ãã¬ãŒã ã¯ãŒã¯ãç 究ããéçšã§ãæ°ããããã°ãäœæããããšããèŠæããããŸããããä»å-ãœãããŠã§ã¢éšåãèªåã§æžãããã«ãDjangoã®å©ç¹ã¯ç°¡åã§æ¥œãããã®ã§ãã ãããŠä»ããã¥ãŒã¹ã®ããã¡ã€ã³ããŒãžãããã€ãã®ã»ã¯ã·ã§ã³ãã³ã¡ã³ãã®ãµããŒããªã©ãç»å ŽããŸããããäœããæ¬ ããŠããŸãã-䟿å©ãªç·šéãšããã¹ãã®å ¬éã ããã§Windows Live WriterãæãåºããŸããã ããã°ã«æçš¿ããããã«äœ¿çšã§ããŸããïŒ ãããå€æããããã«-ç§ã¯ã§ããããã¹ãŠãéåžžã«ç°¡åã§ãã ããã©ã«ãã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯ããã€ãã®äººæ°ã®ããããã°ãµãŒãã¹ãžã®å ¬éã®ã¿ããµããŒãããŸãããæ°ããããã°ãµãŒãã¹ã®è¿œå ã劚ãããã®ã¯äœããããŸãã-MetaWeblog APIã«åºã¥ãå ¬éããµããŒãããããã°ã§ååã§ãã æšæºèªäœã«ã€ããŠã¯èª¬æããŸãããWikiãç§ãããåªããŠããã§ãããã Djangoã®ãããµã€ãã§MetaWeblogã®ãµãŒããŒåŽãå®è£ ããæ¹æ³ã«çŠç¹ãåœãŠãŸãã ããã»ã¹èªäœã¯éåžžã«ç°¡åã§ãããå€æããããã«ããã·ã¢èªã®ãããã¯ã«é¢ããæ å ±ã¯ããŸããªããã»ãšãã©ãPHPãŸãã¯.NETã³ãŒãã§ãã ãã®ããã¹ãã¯ã決ããŠå®å šãªãµããããŠããããã§ã¯ãããŸãããç§ã®ç®æšã¯ãç§ã®ãããªåãåå¿è ãæ£ããéçã«æ²¿ã£ãŠèªå°ããããšã§ãããã®ããã次ã®ããšãç解ããã®ã¯é£ãããããŸããã
ããã§ãäœãå¿ èŠã§ããïŒ ãŸãã XML-RPCãµãŒããŒïŒMetaWeblog APIã¯XML-RPCã«åºã¥ããŠããŸãïŒã Pythonã®ããã©ã«ãããã±ãŒãžã«ã¯ååãªxmlrpclibãå«ãŸããŠããŸããããµãŒããŒãDjangoãšçŽæ¥å¯Ÿè©±ããæ¹ã䟿å©ãªããã«æããŸããã ãã°ããæ€çŽ¢ããåŸã django-xmlrpc-䟿å©ãªãµãŒããŒ-XML -RPCãªã¯ãšã¹ãããã»ããµãèŠã€ãããŸããã ããã§äœ¿çšããŸãã ã€ã³ã¹ããŒã«ã¯ç°¡åã§ã質åãããã¹ãã§ã¯ãããŸããã ã€ã³ã¹ããŒã«ã®æåŸã®httpïŒ// domain / xmlrpc /ã§ãç»é²æžã¿ã¡ãœããã®ãªã¹ãã確èªã§ããŸãã äž»ãªèšå®ã¯å€æ°ã§ã
XMLRPC_METHODSããã®å®çŸ©ã¯ãsetting.pyã®ã©ããã«é 眮ããå¿ èŠããããŸããããã¯ãé¢æ°ãžã®ãã¹ïŒãã³ãã©ãŒãã¡ãœããã®ååïŒãå«ãã«ãŒããªããžã®éãŸãã§ãã äŸïŒ
XMLRPC_METHODS = (('myproject.myapp.views.get_users_blogs', 'blogger.getUsersBlogs'),)
ãããã£ãŠãé¢æ°ããã³ãã©ãŒã§ããblogger.getUsersBlogsãšããã¡ãœãããç»é²ããŸããã ãªããªã å°æ¥ããŸã£ããåãååã®ã¡ãœãããå¿ èŠã«ãªããŸã-ç»é²ããããšããå§ãããŸãã
ããã§ãæå®ãããã¢ãã¬ã¹ã®é¢æ°ã«çŽæ¥æž¡ããŸãã ããã©ã«ãã§ã¯ãMeta Weblog APIã«ã¯ãå®è£ ããå¿ èŠã®ããããã€ãã®ã¡ãœããããããå ·äœçã«ã¯æ¬¡ã®ãšããã§ãã
- metaWeblog.newPostïŒïŒ
- metaWeblog.getPostïŒïŒ
- metaWeblog.editPostïŒïŒ
- metaWeblog.getCategoriesïŒïŒ
- metaWeblog.getRecentPostsïŒïŒ
- metaWeblog.newMediaObjectïŒïŒ
ã¡ãœããã«ãã£ãŠåä¿¡ããã³è¿ãããããŒã¿ã®è©³çŽ°ã«ã€ããŠã¯ãããšãã°ãã¡ããã芧ãã ãã ã ãã ããã¡ãœãããå¿ èŠã§ãã
- blogger.getUsersBlogsïŒïŒ
- blogger.deletePostïŒïŒ
- blogger.getUserInfoïŒïŒ
ãã ããæåŸã®2ã€ãå¿ èŠã§ããããªãã·ã§ã³ã§ããå Žåãæåã®Windows Live Writerããªããã°ããµã€ãã®ç»é²ãæåŠããŸãã ãã®ãããblogger.getUsersBlogsïŒïŒããå§ããŸãã ãããŠãããã«ãã³ãã©ãŒã®æ©èœã³ãŒãããããŸãïŒ
from django_xmlrpc.decorators import xmlrpc_func @xmlrpc_func(returns='string', args=['string', 'string', 'string',]) def get_users_blogs(appKey, username, password): user = u_authenticate(username, password) return [{'isAdmin': user.is_superuser, 'url': 'http://127.0.0.1:8000/', 'blogid': '1', 'blogName': 'MyWebBlog'}]
ã³ãŒãã¯ã·ã³ãã«ã§ãããã³ã¡ã³ããå¿ èŠã§ãã æåã«ç®ãåŒãã®ã¯ãxmlrpc_funcãã³ã¬ãŒã¿ã§ãã ã芧ã®ãšããã2ã€ã®ãã©ã¡ãŒã¿ãŒãããã1ã€ç®ã¯ã¡ãœããã«ãã£ãŠè¿ãããããŒã¿ã®ã¿ã€ããæ åœãã2ã€ç®ã¯åä¿¡ããã¿ã€ããæ åœããŸãã ãªããã®ãã³ã¬ãŒã¿ãå¿ èŠãªã®ã§ããïŒ ã¡ãœããã«XML-RPC眲åãè¿œå ããŸãã äžè¬çã«å³å¯ã«èšãã°ãèªç±ã«ãããè¡ãããšãã§ããŸãããã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãã®ã·ã°ããã£ãèªã¿åã£ãŠã¡ãœããã«é¢ããå¿ èŠãªæ å ±ãååŸã§ããŸãã ããŠãäœã«å¯ŸããŠããããªãããšä»ãå ããŸããããïŒ
é¢æ°èªäœã¯3ã€ã®ãã©ã¡ãŒã¿ãŒãåããŸãã
- appKey-ã¢ããªã±ãŒã·ã§ã³ã®äžæã®ããŒ-ã¯ã©ã€ã¢ã³ããç§ãã¡ã¯ããã䜿çšããŸããã
- ãŠãŒã¶ãŒå -ãµãŒãã¹ã®ãŠãŒã¶ãŒå
- password-ãŠãŒã¶ãŒãã¹ã¯ãŒãã
u_authenticateé¢æ°ã¯ãããŒã¿ããŒã¹ã«ããŒã¿ããŒã¹ãããã°ãããŒã¿ããŒã¹ãããŠãŒã¶ãŒãè¿ãããã¹ã¯ãŒãã¯æ£ããã§ãã æ€èšŒèŠä»¶ã«å¿ããŠããã®ãããªé¢æ°ãèªåã§äœæã§ããŸãããç§ãæã£ãŠãããã®ã䜿çšã§ããŸãïŒ
from xmlrpclib import Fault def u_authenticate(username, password): try: user = User.objects.get(username__exact=username) except User.DoesNotExist: raise Fault('1', 'Username is incorrect.') if not user.check_password(password): raise Fault('1', 'Password is invalid.') if not user.is_staff or not user.is_active: raise Fault('2', 'User account unavailable.') return user
Faultã¯XML-RPC ErrorãçæããŸãããã®æåã®ãã©ã¡ãŒã¿ãŒã¯ãšã©ãŒã³ãŒãïŒä»»æãä»»æïŒãããã³ãã®ããã¹ãè¡šçŸã§ãã åé¡ãçºçããå Žåã«ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã衚瀺ããã®ã¯ããã®ã³ãŒããšããã¹ãã§ãã
get_users_blogsé¢æ°ã«æ»ããããŒã¿ãè¿ããŸãã ã芧ã®ãšãããããã¯æ¬¡ã®èŠçŽ ãæã€èŸæžãå«ããªã¹ãã§ãã
- isAdmin-ãŠãŒã¶ãŒã管çè ã§ãããã©ããã瀺ããŸãã
- url-ãããã¯ãŒã¯äžã®ããã°ã®ã¢ãã¬ã¹ãçŽæ¥
- blogidã¯ããµãŒãã¹å ã®ããã°ã®äžæã®IDã§ãã ãµã€ãã«ããã€ãã®ããã°ãããå Žåã«å¿ èŠã§ãã 1ã€ãããªãå Žåã¯ãããšãã°ãŒããªã©ãä»»æã®æ°ã§ååã§ãã
- blogName-ããã°ã®ååã¯ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã§ååãšããŠäœ¿çšãããŸãã
ã³ãŒãå ã®URLãšãµã€ãåãå³å¯ã«æå®ãããŠããããšã«æ³šæããŠãã ãããããã¯ãŸã£ããåœãŠã¯ãŸããŸãããã¢ãã¬ã¹ãŸãã¯ãµã€ãåãå€æŽããå Žåãå€ãã®é¢æ°ã®ã³ãŒããå€æŽããå¿ èŠããããŸãã è¯ãããšã«ã¯ããã®ãããªãã®ãèšå®å ã®ã©ããã®å¥ã®å€æ°ã«ä¿åããããšããå§ãããŸãããããã§ã¯ç解ãç°¡åã«ããããã«ãã®ãã©ãŒã ã«ãã¹ãŠãæ®ããŸããã
ãããå®éã«ãã¹ãŠã§ãã 察話çšã®ã¢ãã¬ã¹ãšããŠhttp://127.0.0.1:8000/xmlrpc/ã®ãããªãã®ãæå®ããã€ã³ã¿ãŒãã§ãŒã¹ãšããŠMeta Weblog APIãæå®ããŠãããã°ãWindows Live Writerã«è¿œå ããŠã¿ãŠãã ããã ãã¹ãŠãæ£ããè¡ãããå ŽåãWindows Live Writerã¯èªèº«ã§ããã°ãç»é²ããå ¬éåã«ãã¬ãã¥ãŒæ©èœçšã«ããã°ã®ããžã¥ã¢ã«ããŒãïŒhtmlãcssïŒãããŠã³ããŒãããããšãææ¡ããŸãããä»ã¯æåŠããå¿ èŠããããŸã-ãããã¯ã決å®ãããããWindows Live Writerã¯äžæçãªããã°ãå ¬éã¬ã³ãŒããå ¬éããããã®ã¡ãœããmetaWeblog.newPostïŒïŒã¯ãŸã å®è£ ãããŠããŸããã ããŠãç§ãã¡ã¯äœãåŸ ã£ãŠããŸããïŒ
åæ§ã«ããŸããã¡ãœãããXMLRPC_METHODSã«è¿œå ããŸãã
('myproject.myapp.views.new_post', 'metaWeblog.newPost')
ããã§ã¯ãé¢æ°ãéå§ããŸããã-ãã³ãã©ãŒïŒ
from datetime import datetime @xmlrpc_func(returns='string', args=['string', 'string', 'string', 'struct', 'boolean']) def new_post(blog_id, username, password, post, publish): user = u_authenticate(username, password) item = News() item.title = post['title'] item.text_news = post['description'] if post.get('dateCreated'): item.date = datetime.strptime(str(post['dateCreated']), '%Y%m%dT%H:%M:%S') else: item.date = datetime.now() item.author = user item.public = publish item.save() return item.pk
ã³ãŒããéåžžã«åçŽã§ããã念ã®ããã³ã¡ã³ãããŸãã
æåã®3ã€ã®èš±å®¹å€ã¯æ確ã§ãªããã°ãªããŸãããæ®ãã®2ã€ã«çŠç¹ãåœãŠãŸãã
- æçš¿ -çŽæ¥å ¬éãããã³ã³ãã³ãã ããã¯å€ãã®ãã®ãå«ãããšãã§ããèŸæžã§ã...ããã©ã«ãã§ã¯ãããã¯ãã¡ããã¿ã€ãã«ã§ã-ã¬ã³ãŒãã®ã¿ã€ãã«ã説æ-ã¡ã€ã³ããã¹ããdateCreated-ã¬ã³ãŒããäœæãããæ¥ä»ãããã³ã«ããŽãª-ã¬ã³ãŒãã®ã¿ã°ã ããã§ããããã¯ã¯ã©ã€ã¢ã³ããæäŸããå¯èœæ§ã®ããããŒã¿ã®ããäžéšã«ããããããšãã°ãWindows Live WriterãŠãŒã¶ãŒãæ¥ä»ã®æå®ãå¿ããå ŽåãdateCreatedã¯ãŸã£ãã䜿çšã§ããªãå ŽåããããŸãã ãã¡ãããããããã¹ãŠãèæ ®ã«å ¥ããããªãã®ç®æš/欲æ±ã«å¿ããŠäœ¿çšããå¿ èŠããããŸãããæçš¿ã«è¡šç€ºãããå¯èœæ§ã®ãããã¹ãŠã®ããŒããªã¹ãããããã§ã¯ãããŸãããèªåã§ç¢ºèªããæ¹ãç°¡åã§ãã æçµçã«ãèªå® ã§äœ¿çšããããŒã¿ã決å®ããã®ã¯ããªã次第ã§ãã
- publish-ããŒã«åã®å€æ°ãæçš¿ãããã«å ¬éããå Žåã¯Trueããã©ããã³ããŒã«é 眮ããå Žåã¯Falseã§ãã
æ®ãã®ã³ãŒãã¯éåžžã«åçŽã§ãã ãŸãããŠãŒã¶ãŒãèªèšŒããŸãã 次ã«ããã¥ãŒã¹ã®æãåçŽãªNewsïŒïŒã¢ãã«ã«åºã¥ããŠã¢ã€ãã ãªããžã§ã¯ããäœæãããåä¿¡ããããŒã¿ãå ¥åãããŸãã ãã¶ããitem.dateã§åæ¢ããã ãã®äŸ¡å€ãããã§ãããã å®éã«ã¯ãããŒdateCreatedã«ã¯ã¬ã³ãŒãã®å ¬éæ¥æãå«ãŸããŠãããããã¯æããã«ããã¹ã圢åŒã§ãã ãã®ãããæååãã³ã³ããŒãã³ãã«è§£æããæ¥ä»ãªããžã§ã¯ãã«å€æããå¿ èŠããããŸãã ããŒdateCreatedããŸã£ãããªãã£ãå ŽåãçŸåšã®æ¥æãäœææ¥æãšããŠæå®ãããŸãã ç¹°ãè¿ããŸãããããã¯ãã¥ãŒã¹ã®æãåçŽãªã¢ãã«ã§ãããå®éã«ã¯ãããžã§ã¯ãã«ãã£ãšå€ãã®ããŒã¿ãããå¯èœæ§ããããŸãã ããšãã°ãã«ããŽãªããŒã®åŠçã¯ãããŸããã å ·äœçã«ã¯ããã®ãã¥ãŒã¹ã¢ãã«ã«ã¯ãããããŸã£ããå«ãŸããŠããŸããããå¿ èŠãªå Žåã¯èª°ã䜿çšãçŠæ¢ããŸããã
é ç®ãªããžã§ã¯ãã®å ¥åãå®äºãããšãããŒã¿ããŒã¹ã«ä¿åãããé¢æ°ã¯item.pkãè¿ããŸãã ããã§ã¯ãããã«è©³ãã説æãã䟡å€ããããŸãã newPostïŒïŒã¡ãœããã¯ãå ¬éãããã¬ã³ãŒãã®äžæã®èå¥åãã¯ã©ã€ã¢ã³ãã«è¿ãããã«å¿ èŠã§ããããã«ãããå°æ¥ãç·šé/åé€ã®ããã«ãã®ã¬ã³ãŒããèŠã€ããããšãã§ããããã«ãªããŸãã pkãã¢ã€ãã ã®äžæã®èå¥åãšããŠäœ¿çšã§ããŸãããããã¯äžè¬çã«ããŸãè¯ããããŸããã äºå®ã¯ãpkã¯æ¬è³ªçã«ãå ¬éæã®ããŒã¿ããŒã¹å ã®ã¬ã³ãŒãã®ã·ãªã¢ã«çªå·ã§ãããšããããšã§ãã ããã§ãWindows Live Writerãä»ããŠèšé²ãå ¬éããDjango管çããã«ã§ãããåé€ããããããæ°ããèšé²ãæçš¿ãããã®åŸãWindows Live Writerãä»ããŠåé€ããèšé²ãå ¬éããããšãããšã©ããªããŸããïŒ ããããåçŽãªããšãèµ·ãããŸããWindowsLive Writerã¯ãã¬ã³ãŒããçºè¡ã®ç¬éããæ¢ã«åé€ãããŠããããšãç¥ãããå¥ã®ã¬ã³ãŒãããã®å Žæã«è¡šç€ºãããŸããããåã®pkãšåãã§ãã ãããã£ãŠã管çããã«ãä»ããŠå ¬éãããã¬ã³ãŒãã¯ãWindows Live Writerããå ¬éãããã¬ã³ãŒãã«ãã£ãŠæžãæããããŸãã 人çã§ã¯æ¯æ¥ãã®ãããªç¶æ³ã«å¯ŸåŠããå¿ èŠã¯ãªãããšã¯æããã§ãããããã«ãããããããpkããããŠããŒã¯ãªäœããè¿ã䟡å€ãããããã§ãã ããã«ãé¢ããããpkãå®èšŒããã«ã¯ãç®ã®ããã«ååãªãã®ããããŸãã
ããã ãã§ããWindowsLive Writerã«ã¢ã¯ã»ã¹ããŠãæ°ãããšã³ããªãå ¬éããæ©äŒãã楜ãã¿ãã ãã:)ã
ãŸãã以äžã®metaWeblog.editPostïŒïŒããã³blogger.deletePostïŒïŒã¡ãœããã®å®è£ ãæäŸããŸãã ã³ãŒãã«ã¯å ·äœçãªãã®ã¯äœãå«ãŸããŠããªãã®ã§ã詳ããã¯èª¬æããŸããã
@xmlrpc_func(returns='boolean', args=['string', 'string', 'string', 'struct', 'boolean']) def edit_post(post_id, username, password, post, publish): user = u_authenticate(username, password) item = News.objects.get(id=post_id, author=user) item.title = post['title'] item.text_news = post['description'] if post.get('dateCreated'): item.date = datetime.strptime(str(post['dateCreated']), '%Y%m%dT%H:%M:%S') else: item.date = datetime.now().date() item.author = user item.public = publish item.save() return True @xmlrpc_func(returns='boolean', args=['string', 'string', 'string', 'string', 'string']) def delete_post(apikey, post_id, username, password, publish): print post_id user = u_authenticate(username, password) News.objects.get(id=post_id, author=user).delete() return True
äž¡æ¹ã®é¢æ°ã¯ãæåãããšTrueãè¿ããŸãã ããã§ãåé¡ãªãããã°ã®ããŒããWindows Live Writerã«ããŠã³ããŒãã§ããŸããäžèšã®æ¹æ³ã§ååã§ãã
ä»ã®ãã¹ãŠã®ã¡ãœããã®å®è£ ã«ã€ããŠã¯èšåããŸããã äžèšã®æ å ±ã¯Meta Weblog APIã®ä»çµã¿ãç解ããã®ã«ååã§ãããå¿ èŠãªã¡ãœãããå®è£ ããããšã¯é£ãããããŸããã ããã ãã§ããä»ã§ã¯ãã¹ãŠã§ã:)ã ç°¡åã§ãããPythonã®ãããã¯ã«é¢ãããã·ã¢èªã®æ å ±ãäžè¶³ããŠããããšãããã³ãµãŒããŒã©ã€ãã©ãªãå°ãé©ããã®ã§ããã®èšäºã§ã®ã£ãããå°ãåããããšãæã¿ãŸãã å人çã«ã¯ã䜿ãæ £ãã䟿å©ãªããã°ã©ã ã䜿çšããŠå°æ¥ã®ããã°ã«ãã¥ãŒã¹ãå ¬éã§ããããã«ãªã£ãããšãå¬ããæããŸãããŸããMeta Weblog APIããµããŒãããå¥ã®ã¯ã©ã€ã¢ã³ãããå§ãããŸããWindowsLive Writer ãæž èŽããããšãããããŸããã