OSDN Git Service

フォトライフへの投稿に成功。疲れた。WsseAtomConnectionの試行錯誤の結果。
authorazyobuzin <azyobuzin@users.sourceforge.jp>
Tue, 10 May 2011 10:03:33 +0000 (19:03 +0900)
committerazyobuzin <azyobuzin@users.sourceforge.jp>
Tue, 10 May 2011 10:03:33 +0000 (19:03 +0900)
TODO:いろいろ

HatenaDiaryClient/HatenaDiaryClient.csproj
HatenaDiaryClient/Models/Hatena/BlogEntry.cs
HatenaDiaryClient/Models/Hatena/FotolifeEntry.cs [new file with mode: 0644]
HatenaDiaryClient/Models/Hatena/HatenaDiary.cs
HatenaDiaryClient/Models/Hatena/HatenaFotolife.cs [new file with mode: 0644]
HatenaDiaryClient/Models/Hatena/WsseAtomConnection.cs

index 24aae48..ce9df44 100644 (file)
@@ -75,7 +75,9 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Models\Hatena\BlogEntry.cs" />
+    <Compile Include="Models\Hatena\FotolifeEntry.cs" />
     <Compile Include="Models\Hatena\HatenaDiary.cs" />
+    <Compile Include="Models\Hatena\HatenaFotolife.cs" />
     <Compile Include="Models\Hatena\WsseAtomConnection.cs" />
     <Compile Include="Models\Hatena\XmlNamespaces.cs" />
     <Compile Include="Models\Model.cs" />
index 19ce6a4..fb246ad 100644 (file)
@@ -8,7 +8,7 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
     public class BlogEntry
     {
         public DateTime Edited { set; get; }
-        public string BlogPage { set; get; }
+        public string BlogPageUri { set; get; }
         public string Title { set; get; }
         public string Html { set; get; }
         public string HatenaSyntax { set; get; }
@@ -18,7 +18,7 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
         public BlogEntry(XElement xml)
         {
             this.Edited = DateTime.Parse(xml.Element(XmlNamespaces.AtomPub + "edited").Value);
-            this.BlogPage = xml.Elements(XmlNamespaces.Atom + "link")
+            this.BlogPageUri = xml.Elements(XmlNamespaces.Atom + "link")
                 .Where(_ => _.Attribute("rel").Value == "alternate")
                 .Select(_ => _.Attribute("href").Value)
                 .FirstOrDefault();
diff --git a/HatenaDiaryClient/Models/Hatena/FotolifeEntry.cs b/HatenaDiaryClient/Models/Hatena/FotolifeEntry.cs
new file mode 100644 (file)
index 0000000..0fc4a30
--- /dev/null
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+using System.Text.RegularExpressions;
+
+namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
+{
+    public class FotolifeEntry
+    {
+        public string Title { set; get; }
+        public string PageUri { set; get; }
+        public string Id { set; get; }
+        public DateTime Issued { set; get; }
+        public string Folder { set; get; }
+        public string ImageUri { set; get; }
+        public string ThumbnailUri { set; get; }
+        public string HatenaSyntax { set; get; }
+
+        public FotolifeEntry() { }
+        public FotolifeEntry(XElement xml, bool isRdf)
+        {
+            if (isRdf)
+            {
+                //TODO
+            }
+            else
+            {
+                this.Title = xml.Element(XmlNamespaces.Atom02Spec + "title").Value;
+                this.PageUri = xml.Elements(XmlNamespaces.Atom02Spec + "link")
+                    .Where(_ => _.Attribute("rel").Value == "alternate")
+                    .Select(_ => _.Attribute("href").Value)
+                    .FirstOrDefault();
+                this.Id = Regex.Match(this.PageUri, @"\d+$").ToString();
+                this.Issued = DateTime.Parse(xml.Element(XmlNamespaces.Atom02Spec + "issued").Value);
+                this.Folder = xml.Element(XmlNamespaces.DublinCore + "subject").Value;
+                this.ImageUri = xml.Element(XmlNamespaces.HatenaNs + "imageurl").Value;
+                this.ThumbnailUri = xml.Element(XmlNamespaces.HatenaNs + "imageurlsmall").Value;
+                this.HatenaSyntax = xml.Element(XmlNamespaces.HatenaNs + "syntax").Value;
+            }
+        }
+    }
+}
index 00539ef..09c1044 100644 (file)
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Net;
+using System.Text;
 using System.Text.RegularExpressions;
 using System.Xml.Linq;
 
@@ -44,6 +45,7 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
             var reXml = WsseAtomConnection.Post(
                 string.Format("http://d.hatena.ne.jp/{0}/atom/blog", this.userName),
                 CreatePostEntryXml(title, content, updated),
+                Encoding.UTF8,
                 this.userName,
                 this.password);
             return new BlogEntry(reXml.Root)
@@ -66,6 +68,7 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
             var reXml = WsseAtomConnection.Put(
                 string.Format("http://d.hatena.ne.jp/{0}/atom/blog/{1}", this.userName, dateId),
                 CreatePostEntryXml(title, content, updated),
+                Encoding.UTF8,
                 this.userName,
                 this.password);
             return new BlogEntry(reXml.Root)
@@ -98,6 +101,7 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
             var reXml = WsseAtomConnection.Post(
                 string.Format("http://d.hatena.ne.jp/{0}/atom/draft", this.userName),
                 CreatePostEntryXml(title, content, updated),
+                Encoding.UTF8,
                 this.userName,
                 this.password);
             return new BlogEntry(reXml.Root)
@@ -120,6 +124,7 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
             var reXml = WsseAtomConnection.Put(
                 string.Format("http://d.hatena.ne.jp/{0}/atom/draft/{1}", this.userName, id),
                 CreatePostEntryXml(title, content, updated),
+                Encoding.UTF8,
                 this.userName,
                 this.password);
             return new BlogEntry(reXml.Root)
diff --git a/HatenaDiaryClient/Models/Hatena/HatenaFotolife.cs b/HatenaDiaryClient/Models/Hatena/HatenaFotolife.cs
new file mode 100644 (file)
index 0000000..cefc45f
--- /dev/null
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Xml.Linq;
+using System.Net;
+
+namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
+{
+    public class HatenaFotolife
+    {
+        private string userName;
+        private string password;
+
+        public HatenaFotolife(string userName, string password)
+        {
+            this.userName = userName;
+            this.password = password;
+        }
+
+        public FotolifeEntry Upload(string title, string fileName, string folder = null)
+        {
+            string mimeType;
+            #region MIME Type判断
+            switch (Path.GetExtension(fileName).TrimStart('.').ToLower())
+            {
+                case "jpg":
+                case "jpeg":
+                    mimeType = "image/jpeg";
+                    break;
+                case "gif":
+                    mimeType = "image/gif";
+                    break;
+                case "png":
+                    mimeType = "image/png";
+                    break;
+                case "bmp":
+                    mimeType = "image/x-bmp";
+                    break;
+                case "mov":
+                    mimeType = "video/quicktime";
+                    break;
+                case "mpg":
+                case "mpeg":
+                case "m1v":
+                    mimeType = "video/mpeg";
+                    break;
+                case "wmv":
+                    mimeType = "video/x-ms-wmv";
+                    break;
+                case "avi":
+                    mimeType = "video/avi";
+                    break;
+                case "flv":
+                    mimeType = "video/x-flv";
+                    break;
+                case "3gp":
+                case "3gpp":
+                    mimeType = "video/3gpp";
+                    break;
+                case "3g2":
+                    mimeType = "video/3gpp2";
+                    break;
+                default:
+                    throw new ArgumentException("対応してないファイルです。");
+            } 
+            #endregion
+
+            var entry = new XElement(XmlNamespaces.Atom02Spec + "entry",
+                new XElement(XmlNamespaces.Atom02Spec + "title", title),
+                new XElement(XmlNamespaces.Atom02Spec + "content",
+                    new XAttribute("mode", "base64"),
+                    new XAttribute("type", mimeType),
+                    Convert.ToBase64String(File.ReadAllBytes(fileName)))
+            );
+
+            if (!string.IsNullOrEmpty(folder))
+                entry.Add(new XElement(XmlNamespaces.DublinCore + "subject", folder));
+                        
+            var reXml = WsseAtomConnection.Post(
+                "http://f.hatena.ne.jp/atom/post",
+                new XDocument(entry),
+                Encoding.GetEncoding("shift_jis"),
+                this.userName,
+                this.password);
+            return new FotolifeEntry(reXml.Root, false);
+        }
+    }
+}
index 93990f4..d01cc00 100644 (file)
@@ -1,4 +1,5 @@
 using System;
+using System.Linq;
 using System.Net;
 using System.Security.Cryptography;
 using System.Text;
@@ -12,18 +13,16 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
 
         public static string CreateHeader(string userName, string password)
         {
-            var tmp = new byte[25];
-            random.NextBytes(tmp);
-            var nonce = Convert.ToBase64String(tmp);
-            tmp = null;
+            var nonce = new byte[8];
+            random.NextBytes(nonce);
             var created = DateTime.Now.ToUniversalTime().ToString("o");
             var digest = Convert.ToBase64String(
                 new SHA1Managed().ComputeHash(
-                    Encoding.ASCII.GetBytes(nonce + created + password)
+                    nonce.Concat(Encoding.ASCII.GetBytes(created)).Concat(Encoding.ASCII.GetBytes(password)).ToArray()
                 ));
             return string.Format(
                 @"X-WSSE:UsernameToken Username=""{0}"", PasswordDigest=""{1}"", Nonce=""{2}"", Created=""{3}""",
-                userName, digest, nonce, created);
+                userName, digest, Convert.ToBase64String(nonce), created);
         }
 
         public static XDocument Get(string reqUri, string userName, string password)
@@ -44,13 +43,13 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
             req.GetResponse().Close();
         }
 
-        private static XDocument PostOrPut(string reqUri, string method, XDocument reqData, string userName, string password)
+        private static XDocument PostOrPut(string reqUri, string method, XDocument reqData, Encoding enc, string userName, string password)
         {
             var req = WebRequest.Create(reqUri);
             req.Method = method;
             req.Headers.Add(CreateHeader(userName, password));
-            req.ContentType = "application/x.atom+xml; charset=utf-8";
-            var bs = Encoding.UTF8.GetBytes(reqData.ToString());
+            req.ContentType = "application/x.atom+xml";
+            var bs = Encoding.GetEncoding("shift_jis").GetBytes(reqData.ToString());
             req.ContentLength = bs.Length;
             using (var stream = req.GetRequestStream())
                 stream.Write(bs, 0, bs.Length);
@@ -58,14 +57,14 @@ namespace Azyobuzi.HatenaDiaryClient.Models.Hatena
                 return XDocument.Load(res.GetResponseStream());
         }
 
-        public static XDocument Post(string reqUri, XDocument reqData, string userName, string password)
+        public static XDocument Post(string reqUri, XDocument reqData, Encoding enc, string userName, string password)
         {
-            return PostOrPut(reqUri, "POST", reqData, userName, password);
+            return PostOrPut(reqUri, "POST", reqData, enc, userName, password);
         }
 
-        public static XDocument Put(string reqUri, XDocument reqData, string userName, string password)
+        public static XDocument Put(string reqUri, XDocument reqData, Encoding enc, string userName, string password)
         {
-            return PostOrPut(reqUri, "PUT", reqData, userName, password);
+            return PostOrPut(reqUri, "PUT", reqData, enc, userName, password);
         }
     }
 }
\ No newline at end of file