protected bool Login(HatenaBlogAtomPubCredential credential, out HatenaBlogAtomPubClient hatenaBlog) { hatenaBlog = CreateClient(credential); Console.Write("ログインしています ... "); var statusCode = hatenaBlog.Login(out _); if (statusCode == HttpStatusCode.OK) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("ログインに成功しました。"); Console.ResetColor(); return(true); } else { hatenaBlog = null; Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine("ログインに失敗しました。 ({0:D} {0})", statusCode); Console.ResetColor(); return(false); } }
protected HatenaBlogAtomPubClient CreateClient(HatenaBlogAtomPubCredential credential) { HatenaBlogAtomPubClient.InitializeHttpsServicePoint(); var client = HatenaBlogAtomPubClient.Create(credential); client.UserAgent = UserAgent; return(client); }
private static XDocument DumpEntries( HatenaBlogAtomPubClient hatenaBlog, Predicate <PostedEntry> entryPredicate, out IReadOnlyList <PostedEntry> entries ) { var filteredEntries = new List <PostedEntry>(); XDocument outputDocument = null; Console.Error.WriteLine("エントリをダンプ中 ..."); hatenaBlog.EnumerateEntries((postedEntry, entryElement) => { if (outputDocument == null) { // オリジナルのレスポンス文書からlink[@rel=first/next], entry以外の要素をコピーしてヘッダ部を構築する outputDocument = new XDocument(entryElement.Document); outputDocument .Root .Elements(AtomPub.Namespaces.Atom + "entry") .Remove(); outputDocument .Root .Elements(AtomPub.Namespaces.Atom + "link") .Where(e => e.HasAttributeWithValue("rel", "first") || e.HasAttributeWithValue("rel", "next")) .Remove(); } if (!entryPredicate(postedEntry)) { return; // continue } outputDocument.Root.Add(new XElement(entryElement)); filteredEntries.Add(postedEntry); }); entries = filteredEntries; return(outputDocument); }
private static void EditAllEntry( IReadOnlyList <PostedEntry> entries, IHatenaBlogEntryEditor editor, out IReadOnlyList <PostedEntry> updatedEntries, out IReadOnlyList <PostedEntry> modifiedEntries ) { var hatenaBlog = HatenaBlogAtomPubClient.Create(entries); HatenaBlogFunctions.EditAllEntry( hatenaBlog, HatenaBlogFunctions.PostMode.PostIfModified, editor, DiffGenerator.Create(silent: true, null, null, null, null), null, null, out updatedEntries, out modifiedEntries ); }
public void Run(string[] args) { if (!ParseCommonCommandLineArgs(ref args, out var credential)) { return; } var entry = new Entry(); string contentFile = null; string atomEntriesFile = null; for (var i = 0; i < args.Length; i++) { switch (args[i]) { case "--title": case "-title": entry.Title = args[++i]; break; case "--category": case "-category": entry.Categories.Add(args[++i]); break; case "--draft": case "-draft": entry.IsDraft = true; break; case "--from-file": case "-fromfile": contentFile = args[++i]; break; case "--from-atom-file": atomEntriesFile = args[++i]; break; default: entry.Content = args[i]; break; } } var postingEntries = new List <Entry>(); if (string.IsNullOrEmpty(atomEntriesFile)) { if (!string.IsNullOrEmpty(contentFile)) { if (contentFile == "-") { using (var reader = new StreamReader(Console.OpenStandardInput())) { entry.Content = reader.ReadToEnd(); } } else if (File.Exists(contentFile)) { entry.Content = File.ReadAllText(contentFile); } else { Usage("ファイル '{0}' が見つかりません", contentFile); } } postingEntries.Add(entry); } else { using (var reader = File.OpenText(atomEntriesFile)) { foreach (var e in HatenaBlogAtomPubClient.ReadEntriesFrom(XDocument.Load(reader))) { if (e.MemberUri == null) { postingEntries.Add(new Entry(e)); // post as new entry instead of update existing entry } else { postingEntries.Add(e); } } } postingEntries.Sort((e1, e2) => DateTimeOffset.Compare(e1.DateUpdated ?? DateTimeOffset.MinValue, e2.DateUpdated ?? DateTimeOffset.MinValue)); } if (!Login(credential, out var hatenaBlog)) { return; } var failedEntries = new List <Entry>(); try { foreach (var postingEntry in postingEntries) { try { HttpStatusCode statusCode; HttpStatusCode expectedStatusCode; XDocument responseDocument; if (postingEntry is PostedEntry updatingEntry) { Console.Write($"更新しています ({updatingEntry.MemberUri} '{updatingEntry.Title}') ... "); expectedStatusCode = HttpStatusCode.OK; statusCode = hatenaBlog.UpdateEntry(updatingEntry, out responseDocument); } else { Console.Write($"投稿しています ('{postingEntry.Title}') ... "); expectedStatusCode = HttpStatusCode.Created; statusCode = hatenaBlog.PostEntry(postingEntry, out responseDocument); } if (statusCode == expectedStatusCode) { var createdUri = responseDocument.Element(AtomPub.Namespaces.Atom + "entry") ?.Elements(AtomPub.Namespaces.Atom + "link") ?.FirstOrDefault(e => e.HasAttributeWithValue("rel", "alternate")) ?.GetAttributeValue("href"); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("完了しました: {0}", createdUri); Console.ResetColor(); } else { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine("失敗しました: {0}", statusCode); Console.ResetColor(); failedEntries.Add(postingEntry); } } catch (PostEntryFailedException ex) { Console.WriteLine(); Console.Error.WriteLine(ex); Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine("失敗しました"); Console.ResetColor(); failedEntries.Add(postingEntry); } } } finally { if (1 < postingEntries.Count && 0 < failedEntries.Count) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("下記エントリの投稿または更新に失敗しました"); Console.ResetColor(); foreach (var failedEntry in failedEntries) { if (failedEntry is PostedEntry e) { Console.WriteLine($"{e.MemberUri} '{e.Title}'"); } else { Console.WriteLine(failedEntry.Title); } } } } }