Exemple #1
0
        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);
            }
        }
Exemple #2
0
        protected HatenaBlogAtomPubClient CreateClient(HatenaBlogAtomPubCredential credential)
        {
            HatenaBlogAtomPubClient.InitializeHttpsServicePoint();

            var client = HatenaBlogAtomPubClient.Create(credential);

            client.UserAgent = UserAgent;

            return(client);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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
                );
        }
Exemple #5
0
        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);
                        }
                    }
                }
            }
        }