~aleteoryx/tclfeed-bsky

ref: b412dbd9bef8091f139642f647b66b4f02974529 tclfeed-bsky/lib/atpagent.tcl -rw-r--r-- 2.0 KiB
b412dbd9Aleteoryx publisher 30 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
proc atpagent {procname service} {
  global atp_state
  upvar 0 atp_state($procname) state

  dict set state service $service
  dict set state session 0
  proc $procname {cmd args} [concat uplevel {[list } ::atpagent_inner [list $procname] {$cmd $args ]} ]
}

proc atpagent_inner {statename cmd argv} {
  global atp_state
  upvar 0 atp_state($statename) state

  switch -- $cmd {
    login {
      lassign $argv username password

      lassign [$statename xrpc com.atproto.server.createSession \
         identifier [::json::write string $username] \
         password [::json::write string $password]] ncode data

      if {$ncode != 200} {
        return -code error "code $ncode from [dict get $state service]!\n$data]"
      }

      dict set state session 1
      dict set state jwt [dict get $data accessJwt]
      dict set state handle [dict get $data handle]
      dict set state did [dict get $data did]
    }
    xrpc {
      set rest [lassign $argv endpoint]

      set headers {}
      if [dict get $state session] {dict set headers Authorization "Bearer [dict get $state jwt]"}

      if {[llength $rest] == 0} {
        # GET path

        set http_state [http::geturl \
          [dict get $state service]/xrpc/$endpoint \
          -headers $headers]

        set ncode [::http::ncode $http_state]
        set data [::json::json2dict [::http::data $http_state]]
        return [list $ncode $data]
      }

      # POST path

      set mime "application/json"
      if {[lindex $rest 0] == "-type"} {
        set rest [lasign $rest _ mime]
      }

      if {[llength $rest] > 1 && $mime == "application/json"} {
        set rest [::json::write object {*}$rest]
      }

      set http_state [http::geturl \
        [dict get $state service]/xrpc/$endpoint \
        -headers $headers \
        -query $rest \
        -type $mime]

      set ncode [::http::ncode $http_state]
      set data [::json::json2dict [::http::data $http_state]]
      return [list $ncode $data]
    }
    state {
      dict get $state {*}$argv
    }
  }
}