http://sourceforge.jp/projects/futonwriter/の旧リポジトリ
| Revision | 3410d03f2a4be601525efcb9eb04e935ace2989b (tree) |
|---|---|
| Time | 2011-05-09 18:15:23 |
| Author | azyobuzin <azyobuzin@user...> |
| Commiter | azyobuzin |
下書きの実装完了
| @@ -1,7 +1,5 @@ | ||
| 1 | 1 | using System; |
| 2 | -using System.Collections.Generic; | |
| 3 | 2 | using System.Linq; |
| 4 | -using System.Text; | |
| 5 | 3 | using System.Text.RegularExpressions; |
| 6 | 4 | using System.Xml.Linq; |
| 7 | 5 |
| @@ -29,7 +27,13 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena | ||
| 29 | 27 | this.HatenaSyntax = xml.Elements(XmlNamespaces.HatenaNs + "syntax") |
| 30 | 28 | .Select(_ => _.Value) |
| 31 | 29 | .SingleOrDefault(); |
| 32 | - this.DateId = Regex.Match(this.BlogPage, @"\d+/\d+$").ToString(); | |
| 30 | + this.DateId = Regex.Match( | |
| 31 | + xml.Elements(XmlNamespaces.Atom + "link") | |
| 32 | + .Where(_ => _.Attribute("rel").Value == "edit") | |
| 33 | + .Select(_ => _.Attribute("href").Value) | |
| 34 | + .First(), | |
| 35 | + @"(\d+/\d+|\d+)$" | |
| 36 | + ).ToString(); | |
| 33 | 37 | } |
| 34 | 38 | } |
| 35 | 39 | } |
| @@ -1,7 +1,8 @@ | ||
| 1 | 1 | using System; |
| 2 | 2 | using System.Collections.Generic; |
| 3 | 3 | using System.Linq; |
| 4 | -using System.Text; | |
| 4 | +using System.Net; | |
| 5 | +using System.Text.RegularExpressions; | |
| 5 | 6 | using System.Xml.Linq; |
| 6 | 7 | |
| 7 | 8 | namespace Azyobuzi.HatenaDiaryClient.Models.Hatena |
| @@ -31,8 +32,8 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena | ||
| 31 | 32 | private static XDocument CreatePostEntryXml(string title, string content, DateTime? updated) |
| 32 | 33 | { |
| 33 | 34 | var elm = new XElement(XmlNamespaces.Atom02Spec + "entry", |
| 34 | - new XElement(XmlNamespaces.Atom02Spec + "title", title), | |
| 35 | - new XElement(XmlNamespaces.Atom02Spec + "content", new XAttribute("type", "text/plain"), content)); | |
| 35 | + new XElement(XmlNamespaces.Atom02Spec + "title", title), | |
| 36 | + new XElement(XmlNamespaces.Atom02Spec + "content", new XAttribute("type", "text/plain"), content)); | |
| 36 | 37 | if (updated.HasValue) |
| 37 | 38 | elm.Add(new XElement(XmlNamespaces.Atom02Spec + "updated", updated.Value.ToString("o"))); |
| 38 | 39 | return new XDocument(elm); |
| @@ -63,10 +64,10 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena | ||
| 63 | 64 | public BlogEntry EditEntry(string dateId, string title, string content, DateTime? updated = null) |
| 64 | 65 | { |
| 65 | 66 | var reXml = WsseAtomConnection.Put( |
| 66 | - string.Format("http://d.hatena.ne.jp/{0}/atom/blog/{1}", this.userName, dateId), | |
| 67 | - CreatePostEntryXml(title, content, updated), | |
| 68 | - this.userName, | |
| 69 | - this.password); | |
| 67 | + string.Format("http://d.hatena.ne.jp/{0}/atom/blog/{1}", this.userName, dateId), | |
| 68 | + CreatePostEntryXml(title, content, updated), | |
| 69 | + this.userName, | |
| 70 | + this.password); | |
| 70 | 71 | return new BlogEntry(reXml.Root) |
| 71 | 72 | { |
| 72 | 73 | HatenaSyntax = content |
| @@ -80,5 +81,77 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena | ||
| 80 | 81 | this.userName, |
| 81 | 82 | this.password); |
| 82 | 83 | } |
| 84 | + | |
| 85 | + public Tuple<string, IEnumerable<BlogEntry>> GetDrafts(int page = 1) | |
| 86 | + { | |
| 87 | + var xdoc = WsseAtomConnection.Get( | |
| 88 | + string.Format("http://d.hatena.ne.jp/{0}/atom/draft?page={1}", this.userName, page), | |
| 89 | + this.userName, | |
| 90 | + this.password); | |
| 91 | + var title = xdoc.Root.Element(XmlNamespaces.Atom + "title").Value; | |
| 92 | + var entrys = xdoc.Root.Elements(XmlNamespaces.Atom + "entry").Select(_ => new BlogEntry(_)); | |
| 93 | + return Tuple.Create(title, entrys); | |
| 94 | + } | |
| 95 | + | |
| 96 | + public BlogEntry PostDraft(string title, string content, DateTime? updated = null) | |
| 97 | + { | |
| 98 | + var reXml = WsseAtomConnection.Post( | |
| 99 | + string.Format("http://d.hatena.ne.jp/{0}/atom/draft", this.userName), | |
| 100 | + CreatePostEntryXml(title, content, updated), | |
| 101 | + this.userName, | |
| 102 | + this.password); | |
| 103 | + return new BlogEntry(reXml.Root) | |
| 104 | + { | |
| 105 | + HatenaSyntax = content | |
| 106 | + }; | |
| 107 | + } | |
| 108 | + | |
| 109 | + public BlogEntry GetDraft(string id) | |
| 110 | + { | |
| 111 | + var xdoc = WsseAtomConnection.Get( | |
| 112 | + string.Format("http://d.hatena.ne.jp/{0}/atom/draft/{1}", this.userName, id), | |
| 113 | + this.userName, | |
| 114 | + this.password); | |
| 115 | + return new BlogEntry(xdoc.Root); | |
| 116 | + } | |
| 117 | + | |
| 118 | + public BlogEntry EditDraft(string id, string title, string content, DateTime? updated = null) | |
| 119 | + { | |
| 120 | + var reXml = WsseAtomConnection.Put( | |
| 121 | + string.Format("http://d.hatena.ne.jp/{0}/atom/draft/{1}", this.userName, id), | |
| 122 | + CreatePostEntryXml(title, content, updated), | |
| 123 | + this.userName, | |
| 124 | + this.password); | |
| 125 | + return new BlogEntry(reXml.Root) | |
| 126 | + { | |
| 127 | + HatenaSyntax = content | |
| 128 | + }; | |
| 129 | + } | |
| 130 | + | |
| 131 | + public void DeleteDraft(string id) | |
| 132 | + { | |
| 133 | + WsseAtomConnection.Delete( | |
| 134 | + string.Format("http://d.hatena.ne.jp/{0}/atom/draft/{1}", this.userName, id), | |
| 135 | + this.userName, | |
| 136 | + this.password); | |
| 137 | + } | |
| 138 | + | |
| 139 | + public string PublishDraft(string id) | |
| 140 | + { | |
| 141 | + var req = (HttpWebRequest)WebRequest.Create(string.Format( | |
| 142 | + "http://d.hatena.ne.jp/{0}/atom/draft/{1}", | |
| 143 | + this.userName, | |
| 144 | + id)); | |
| 145 | + req.Method = "PUT"; | |
| 146 | + req.AllowAutoRedirect = false; | |
| 147 | + req.Headers.Add(WsseAtomConnection.CreateHeader(this.userName, this.password)); | |
| 148 | + req.Headers.Add("X-HATENA-PUBLISH: 1"); | |
| 149 | + using (var res = req.GetResponse()) | |
| 150 | + return Regex.Match( | |
| 151 | + res.Headers[HttpResponseHeader.Location], | |
| 152 | + @"\d+/\d+" | |
| 153 | + ) | |
| 154 | + .ToString(); | |
| 155 | + } | |
| 83 | 156 | } |
| 84 | 157 | } |
| @@ -10,7 +10,7 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena | ||
| 10 | 10 | { |
| 11 | 11 | private static Random random = new Random(); |
| 12 | 12 | |
| 13 | - private static string CreateHeader(string userName, string password) | |
| 13 | + public static string CreateHeader(string userName, string password) | |
| 14 | 14 | { |
| 15 | 15 | var tmp = new byte[25]; |
| 16 | 16 | random.NextBytes(tmp); |