PowerShellで作るdeliciousクライアント その4

前回の続きです。

ブックマークの削除

今回はブックマークの削除機能から実装します。

DeliciousクラスにDeleteBookmarkという名前で、引数に削除するブックマークのURLを指定するメソッドを定義します。

Delicious.vb

Sub DeleteBookmark(ByVal url As String)
     Dim address = "https://api.del.icio.us/v1/posts/delete?url=" + Web.HttpUtility.UrlEncode(url)

     Dim wc = New Net.WebClient()
     wc.Credentials = _credential
     wc.Encoding = Text.Encoding.UTF8

     Dim contents = wc.DownloadString(address)
     Dim resultMsg = GetResultMessage(contents)

     If resultMsg <> "done" Then Throw New ArgumentException(resultMsg)
End Sub

Private Shared Function GetResultMessage(ByVal contents As String) As String
     Dim result = Text.RegularExpressions.Regex.Match( _
         contents, "<result code=""(?<msg>.*?)"" />", Text.RegularExpressions.RegexOptions.Multiline _
     )
     Return IIf(result.Success, result.Groups("msg").Value, String.Empty)
End Function

レスポンスのXMLから結果メッセージを取得する処理をGetResultMessageというメソッドに分離しておきました。

Remove-Itemコマンドレットのパラメータクラスをインナークラスで定義しておきます。

DeliciousProvider.vb
Private Class RemoveItemParameters
     Private _bookmark As DeliciousBookmark
     <Parameter(Mandatory:=True, Position:=0, ValueFromPipeline:=True)> _
     Public Property Bookmark() As DeliciousBookmark
         Get
             Return _bookmark
         End Get
         Set(ByVal value As DeliciousBookmark)
             _bookmark = value
         End Set
     End Property
End Class

後は、RemoveItemRemove-Itemコマンドレットに対応)メソッドをオーバーライドして、その中でDeleteBookmarkメソッドを呼び出すだけです。

DeliciousProvider.vb

Protected Overrides Sub RemoveItem(ByVal path As String, ByVal recurse As Boolean)
     Dim dynaParams = CType(Me.DynamicParameters, RemoveItemParameters)

     Me.Delicious.DeleteBookmark(dynaParams.Bookmark.Url)
End Sub

Protected Overrides Function RemoveItemDynamicParameters(ByVal path As String, ByVal recurse As Boolean) As Object
     Return New RemoveItemParameters()
End Function

これで以下のようにして、ブックマークを削除する事ができるようになります。

PS delicious:\> dir -Count 10 | del

次の機能に行く前に少しGet-ChildItemコマンドレットに機能を追加しておきます。

DeliciousクラスのGetBookmarksメソッドを以下のように変更します。

Delicious.vb

Function GetBookmarks(ByVal start As Integer?, ByVal count As Integer?, ByVal tags As String()) As List(Of DeliciousBookmark)
     Dim address = "https://api.del.icio.us/v1/posts/all"
     Dim queries = New Dictionary(Of String, Object)()
     If start.HasValue Then queries.Add("start", start.Value)
     If count.HasValue Then queries.Add("results", count.Value)
     If Not tags Is Nothing AndAlso tags.Length > 0 Then queries.Add("tag", String.Join(" ", tags))

     Dim wc = New Net.WebClient()
     wc.Credentials = _credential
     wc.Encoding = Text.Encoding.UTF8

     Dim contents = wc.DownloadString(JoinQueries(address, queries))
     Dim xml = XDocument.Parse(contents)
     Dim results = From ele In xml.Descendants("post") _
                   Select New DeliciousBookmark With { _
                     .Title = ele.Attribute("description"), _
                     .Url = ele.Attribute("href"), _
                     .Tags = CType(ele.Attribute("tag"), String).Split(" "), _
                     .Comment = ele.Attribute("extended"), _
                     .Date = ele.Attribute("time") _
                   }

     Return New List(Of DeliciousBookmark)(results)
End Function

「tags」という引数を追加して、タグ名でブックマークを検索できるようにしました。

Get-ChildItemコマンドレットのパラメータクラスにもTagプロパティを追加しておきます。

DeliciousProvider.vb
Private Class GetChildItemsParameters
     Private _start As Integer = 0
     <Parameter(Position:=0)> _
     Public Property Start() As Integer
         Get
             Return _start
         End Get
         Set(ByVal value As Integer)
             _start = value
         End Set
     End Property

     Private _count As Integer = 20
     <Parameter(Position:=1)> _
     Public Property Count() As Integer
         Get
             Return _count
         End Get
         Set(ByVal value As Integer)
             _count = value
         End Set
     End Property

     Private _tag As String()
     <Parameter(Position:=2)> _
     Public Property Tag() As String()
         Get
             Return _tag
         End Get
         Set(ByVal value As String())
             _tag = value
         End Set
     End Property
End Class

GetChildItemsメソッドを以下のように変更しておきます。

DeliciousProvider.vb

Protected Overrides Sub GetChildItems(ByVal path As String, ByVal recurse As Boolean)
     Dim dynaParams = CType(DynamicParameters, GetChildItemsParameters)

     For Each bookmark In Me.Delicious.GetBookmarks(dynaParams.Start, dynaParams.Count, dynaParams.Tag)
         WriteItemObject(bookmark, path, False)
     Next
End Sub

こうする事で、例えば以下のように「.net」というタグの付いたブックマークを10件取ってきて、それを一度に削除するという作業が一行でできるようになります。

PS delicious:\> dir -Tag .net -Count 10 | del

たいした事じゃないですけど、なんだか夢が広がりますね!!

次はタグ関係を一気にやります。