keybase-unofficial 0.4.0 → 0.5.0.pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1762edac1ac71c3ef4105b96ac9e9fd5852c11f4
4
- data.tar.gz: c6728d7afd5340830e6d494e2208efb75576a6e9
3
+ metadata.gz: e8c5d0eafbde60f44f654e0b8fbc85298f24135b
4
+ data.tar.gz: 4a078ac321524233bec84f4965dd44d789d32d77
5
5
  SHA512:
6
- metadata.gz: bc1a2d07cc9a79f009039451f7260e9735cd208e3fb6a78f55aa5c2e2f5b5b8f761e92cf5831dc8298b289958212177cde890c4f26815b176c38d69d03e4fa23
7
- data.tar.gz: 9cf31fc1d6ba53271f030b0c390f0a256a75480c81b5199ef1bc1fb7fe77ca7dc03ec56d69a72a13f7b090d4a7abf022140049d3108929371fd5fdb936b8ceba
6
+ metadata.gz: d3c1cd280c1c5f52ce45db1098641756530e30d81c86c3b0d582db9ddc3f566712e1ebff9f14a4785fad64fb6897dd4be4c379b63f545bf153ad46f70fdab4b6
7
+ data.tar.gz: 51c48d6fcd9ec1fc7a46b24a2fe1ca8c90543ca2224f85c4808fa2fdc7c5f02a4f58d3079d98236abe5d8e632cb2defec4e4b3517e0a377f0e074d9a98a5704a
data/README.md CHANGED
@@ -15,19 +15,22 @@ $ gem install keybase-unofficial
15
15
 
16
16
  ### Documentation
17
17
 
18
- Documentation for the current release can be found on
19
- [RubyDoc](http://www.rubydoc.info/gems/keybase-unofficial/).
18
+ Documentation for keybase-unofficial is split across its three sublibraries:
20
19
 
21
- ### Example
20
+ * [keybase-unofficial-core docs](http://www.rubydoc.info/gems/keybase-unofficial-core/)
21
+ * [keybase-unofficial-api docs](http://www.rubydoc.info/gems/keybase-unofficial-api/)
22
+ * [keybase-unofficial-local docs](http://www.rubydoc.info/gems/keybase-unofficial-local/)
23
+
24
+ ### Examples
22
25
 
23
26
  ```ruby
24
27
  require "keybase"
25
28
 
26
29
  # reads your local configuration
27
- Keybase.current_user # => "yossarian"
30
+ Keybase::Local.current_user # => "yossarian"
28
31
 
29
32
  # Chatting API
30
- Keybase::Chat.send_message ["yossarian", "you"], "hello"
33
+ Keybase::Local::Chat.send_message ["yossarian", "you"], "hello"
31
34
 
32
35
  # REST API
33
36
  person = Keybase::API.lookup username: "yossarian"
@@ -1,17 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "keybase/exceptions"
4
- require_relative "keybase/config"
5
- require_relative "keybase/u"
6
- require_relative "keybase/local_user"
7
- require_relative "keybase/kbfs"
8
- require_relative "keybase/api"
9
- require_relative "keybase/chat"
3
+ require "keybase/core"
4
+ require "keybase/api"
5
+ require "keybase/local"
10
6
 
11
- # The primary namespace for keybase-unofficial.
7
+ # The primary namespace.
12
8
  module Keybase
13
- # keybase-unofficial's current version
14
- VERSION = "0.4.0"
15
-
16
- extend Config
9
+ # The current version of `keybase-unofficial`.
10
+ VERSION = "0.5.0.pre.1"
17
11
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keybase-unofficial
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0.pre.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Woodruff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-02 00:00:00.000000000 Z
11
+ date: 2017-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: faraday
14
+ name: keybase-unofficial-core
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
@@ -24,7 +24,42 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- description: A unofficial library for Keybase
27
+ - !ruby/object:Gem::Dependency
28
+ name: keybase-unofficial-api
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: keybase-unofficial-local
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |
56
+ An unofficial library for Keybase.
57
+
58
+ This library is a wrapper over three individual libraries.
59
+ keybase-unofficial-core provides core utility methods,
60
+ keybase-unofficial-api provides an interface to Keybase's
61
+ REST API, and keybase-unofficial-local provides an interface
62
+ to a local Keybase installation's functionality.
28
63
  email: william@tuffbizz.com
29
64
  executables: []
30
65
  extensions: []
@@ -34,13 +69,6 @@ files:
34
69
  - LICENSE
35
70
  - README.md
36
71
  - lib/keybase.rb
37
- - lib/keybase/api.rb
38
- - lib/keybase/chat.rb
39
- - lib/keybase/config.rb
40
- - lib/keybase/exceptions.rb
41
- - lib/keybase/kbfs.rb
42
- - lib/keybase/local_user.rb
43
- - lib/keybase/u.rb
44
72
  homepage: https://github.com/woodruffw/keybase-unofficial
45
73
  licenses:
46
74
  - MIT
@@ -56,9 +84,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
84
  version: 2.3.0
57
85
  required_rubygems_version: !ruby/object:Gem::Requirement
58
86
  requirements:
59
- - - ">="
87
+ - - ">"
60
88
  - !ruby/object:Gem::Version
61
- version: '0'
89
+ version: 1.3.1
62
90
  requirements: []
63
91
  rubyforge_project:
64
92
  rubygems_version: 2.6.13
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "faraday"
4
- require "json"
5
- require "ostruct"
6
-
7
- module Keybase
8
- # Represents (parts of) the Keybase REST API.
9
- # @see https://keybase.io/docs/api/1.0
10
- class API
11
- # The base URL for the majority of API calls.
12
- BASE_URL = "https://keybase.io/_/api/1.0"
13
-
14
- class << self
15
- # Look up a user, users, or external identity.
16
- # @param query [Hash] the request parameters
17
- # @option query username [String] the username to look up
18
- # @option query usernames [Array<String>] multiple usernames to look up
19
- # @return [OpenStruct] a struct mapping of the JSON response
20
- # @example
21
- # Keybase::API.lookup username: "yossarian"
22
- # Keybase::API.lookup github: "woodruffw"
23
- # @note Any identity supported by keybase should work (e.g, `domain`,
24
- # `hackernews`, `reddit`, `github`, etc.)
25
- # @see https://keybase.io/docs/api/1.0/call/user/lookup
26
- def lookup(**query)
27
- query[:usernames] = U[query[:usernames]]
28
-
29
- fetch_and_structify "/user/lookup.json", query
30
- end
31
-
32
- # Test whether the given user exists on Keybase.
33
- # @param user [String] the username to test
34
- # @return [Boolean] whether or not the user exists
35
- # @example
36
- # Keybase::API.user? "yossarian" # => true
37
- # Keybase::API.user? "idonotexist" # => false
38
- # @note This call only works on Keybase usernames, not external identities.
39
- def user?(user)
40
- lookup(username: user).status.code.zero?
41
- end
42
-
43
- # Search Keybase for identity components.
44
- # @param query [String] the string to search for
45
- # @return [OpenStruct] a struct mapping of the JSON response
46
- # @example
47
- # Keybase::API.autocomplete "William Woodruff"
48
- # @see https://keybase.io/docs/api/1.0/call/user/autocomplete
49
- def autocomplete(query)
50
- fetch_and_structify "/user/autocomplete.json", q: query
51
- end
52
-
53
- # Discover Keybase users from external identities.
54
- # @param query [Hash] the request parameters
55
- # @option query flatten [Boolean] whether or not to remove duplicates
56
- # @option query usernames_only [Boolean] whether or not to reply with
57
- # only names
58
- # @return [OpenStruct] a struct mapping of the JSON response
59
- # @example
60
- # Keybase::API.discover github: "woodruffw", flatten: true
61
- # @note Any identity supported by keybase should work (e.g, `domain`,
62
- # `hackernews`, `reddit`, `github`, etc.)
63
- # @see https://keybase.io/docs/api/1.0/call/user/discover
64
- def discover(**query)
65
- fetch_and_structify "/user/discover.json", query
66
- end
67
-
68
- # Retrieve the current site-wide Merkle root hash.
69
- # @param query [Hash] the request parameters
70
- # @option query seqno [Integer] a specific Merkle root to return, if found
71
- # @option query ctime [Integer] return the first root on or after the
72
- # given time (UTC)
73
- # @return [OpenStruct] a struct mapping of the JSON response
74
- # @see https://keybase.io/docs/api/1.0/call/merkle/root
75
- def merkle_root(**query)
76
- fetch_and_structify "/merkle/root.json", query
77
- end
78
-
79
- # Retrieve a Merkle node corresponding to a given hash.
80
- # @param query [Hash] the request parameters
81
- # @option query hash [String] the hash of the block to look up
82
- # @return [OpenStruct] a struct mapping of the JSON response
83
- # @see https://keybase.io/docs/api/1.0/call/merkle/block
84
- def merkle_block(**query)
85
- fetch_and_structify "/merkle/block.json", query
86
- end
87
-
88
- # Make a GET request to the given endpoint with the given parameters.
89
- # @param endpoint [String] the keybase API endpoint
90
- # @param query [Hash] the request parameters
91
- # @return [OpenStruct] a struct mapping of the JSON response
92
- # @api private
93
- def fetch_and_structify(endpoint, query)
94
- response = Faraday.get "#{BASE_URL}#{endpoint}", query
95
- JSON.parse(response.body, object_class: OpenStruct)
96
- end
97
- end
98
- end
99
- end
@@ -1,185 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "open3"
4
- require "json"
5
- require "ostruct"
6
-
7
- module Keybase
8
- # Represents Keybase's JSON chat API.
9
- class Chat
10
- # The initial arguments to pass when executing Keybase for chatting.
11
- CHAT_EXEC_ARGS = %w[keybase chat api].freeze
12
-
13
- class << self
14
- # @param meth [Symbol] the chat method
15
- # @param options [Hash] the options hash
16
- # @return [String] the JSON serialized envelope
17
- # @api private
18
- def envelope(meth, options: {})
19
- {
20
- method: meth,
21
- params: {
22
- options: options,
23
- },
24
- }.to_json
25
- end
26
-
27
- # @param payload [String] the JSON payload to send to the chat API
28
- # @return [OpenStruct] a struct mapping of the JSON response
29
- # @api private
30
- def chat_call(payload)
31
- response = Open3.popen3(*CHAT_EXEC_ARGS) do |stdin, stdout, _, _|
32
- stdin.write payload
33
- stdin.close # close after writing to let keybase know we're done
34
- stdout.read
35
- end
36
-
37
- JSON.parse response, object_class: OpenStruct
38
- end
39
-
40
- # List the user's inbox.
41
- # @param topic_type [String] the topic type to list by
42
- # @return [OpenStruct] a struct mapping of the JSON response
43
- def list_inbox(topic_type: nil)
44
- payload = envelope :list, options: {
45
- topic_type: topic_type,
46
- }
47
-
48
- chat_call payload
49
- end
50
-
51
- # Read a conversation.
52
- # @param users [Array<String>] a list of the users in the conversation
53
- # @param peek [Boolean] whether to mark the conversation read
54
- # @param unread_only [Boolean] whether to fetch unread messages only
55
- # @return [OpenStruct] a struct mapping of the JSON response
56
- def conversation(users, peek: false, unread_only: false)
57
- payload = envelope :read, options: {
58
- channel: {
59
- name: U[*users],
60
- },
61
- peek: peek,
62
- unread_only: unread_only,
63
- }
64
-
65
- chat_call payload
66
- end
67
-
68
- # Send a message to a conversation.
69
- # @param users [Array<String>] a list of the users in the conversation
70
- # @param message [String] the message to send
71
- # @param public [Boolean] whether to send the message to a public channel
72
- # @return [OpenStruct] a struct mapping of the JSON response
73
- def send_message(users, message, public: false)
74
- payload = envelope :send, options: {
75
- channel: {
76
- name: U[*users],
77
- public: public,
78
- },
79
- message: {
80
- body: message,
81
- },
82
- }
83
-
84
- chat_call payload
85
- end
86
-
87
- # Delete a message from a conversation.
88
- # @param users [Array<String>] a list of the users in the conversation
89
- # @param id [Integer] the id of the message to delete
90
- # @return [OpenStruct] a struct mapping of the JSON response
91
- def delete_message(users, id)
92
- payload = envelope :delete, options: {
93
- channel: {
94
- name: U[*users],
95
- },
96
- message_id: id,
97
- }
98
-
99
- chat_call payload
100
- end
101
-
102
- # Edit a message in a conversation.
103
- # @param users [Array<String>] a list of the users in the conversation
104
- # @param id [Integer] the id of the message to delete
105
- # @param message [String] the message to send
106
- # @return [OpenStruct] a struct mapping of the JSON response
107
- def edit_message(users, id, message)
108
- payload = envelope :edit, options: {
109
- channel: {
110
- name: U[*users],
111
- },
112
- message_id: id,
113
- message: {
114
- body: message,
115
- },
116
- }
117
-
118
- chat_call payload
119
- end
120
-
121
- # Upload a file to a conversation.
122
- # @param users [Array<String>] a list of the users in the conversation
123
- # @param path [String] the pathname of the file to upload
124
- # @param title [String] the uploaded file's title
125
- # @return [OpenStruct] a struct mapping of the JSON response
126
- def upload_attachment(users, path, title)
127
- payload = envelope :attach, options: {
128
- channel: {
129
- name: U[*users],
130
- },
131
- filename: path,
132
- title: title,
133
- }
134
-
135
- chat_call payload
136
- end
137
-
138
- # Download a file from a conversation.
139
- # @param users [Array<String>] a list of the users in the conversation
140
- # @param id [Integer] the id of the message to download from
141
- # @param path [String] the pathname to download to
142
- # @return [OpenStruct] a struct mapping of the JSON response
143
- def download_attachment(users, id, path)
144
- payload = envelope :download, options: {
145
- channel: {
146
- name: U[*users],
147
- },
148
- message_id: id,
149
- output: path,
150
- }
151
-
152
- chat_call payload
153
- end
154
-
155
- # Make a conversation as read up to a specific ID.
156
- # @param users [Array<String>] a list of the users in the conversation
157
- # @param id [Integer] the id of the message to mark up to
158
- # @return [OpenStruct] a struct mapping of the JSON response
159
- def mark_conversation(users, id)
160
- payload = envelope :mark, options: {
161
- channel: {
162
- name: U[*users],
163
- },
164
- message_id: id,
165
- }
166
-
167
- chat_call payload
168
- end
169
-
170
- # Mute a conversation.
171
- # @param users [Array<String>] a list of the users in the conversation
172
- # @return [OpenStruct] a struct mapping of the JSON response
173
- def mute_conversation(users)
174
- payload = envelope :setstatus, options: {
175
- channel: {
176
- name: U[*users],
177
- },
178
- status: "muted",
179
- }
180
-
181
- chat_call payload
182
- end
183
- end
184
- end
185
- end
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
-
5
- module Keybase
6
- # Methods and constants related to a local Keybase installation.
7
- module Config
8
- # The Keybase configuration directory.
9
- CONFIG_DIR = if Gem.win_platform?
10
- File.expand_path("#{ENV["LOCALAPPDATA"]}/Keybase").freeze
11
- else
12
- File.expand_path("~/.config/keybase").freeze
13
- end
14
-
15
- # The Keybase configuration file.
16
- CONFIG_FILE = File.join(CONFIG_DIR, "config.json").freeze
17
-
18
- # there's not much this library can do without a local config
19
- raise Exceptions::KeybaseNotInstalledError unless File.file?(CONFIG_FILE)
20
-
21
- # The hash from Keybase's configuration file.
22
- CONFIG_HASH = JSON.parse(File.read(CONFIG_FILE)).freeze
23
-
24
- # The mountpoint for KBFS.
25
- KBFS_MOUNT = "/keybase"
26
-
27
- # @return [String] the currently logged-in user
28
- def current_user
29
- CONFIG_HASH["current_user"]
30
- end
31
-
32
- # @return [Array<Keybase::LocalUser>] a list of all local users known
33
- # to Keybase
34
- def local_users
35
- CONFIG_HASH["users"].map { |_, v| Keybase::LocalUser.new(v) }
36
- end
37
-
38
- # @return [String] the user's private KBFS directory
39
- def private_dir
40
- File.join(KBFS_MOUNT, "private", current_user)
41
- end
42
-
43
- # @return [String] the user's public KBFS directory
44
- def public_dir
45
- File.join(KBFS_MOUNT, "public", current_user)
46
- end
47
-
48
- # @return [Boolean] whether or not Keybase is currently running
49
- def running?
50
- if Gem.win_platform?
51
- !`tasklist | find "keybase.exe"`.empty?
52
- else
53
- # is there a more efficient way to do this that doesn't involve an exec?
54
- Dir["/proc/[0-9]*/comm"].any? do |comm|
55
- File.read(comm).chomp == "keybase" rescue false # hooray for TOCTOU
56
- end
57
- end
58
- end
59
-
60
- # @return [String] the running Keybase's version string
61
- # @raise [Exceptions::KeybaseNotRunningError] if Keybase is not running
62
- def running_version
63
- raise Exceptions::KeybaseNotRunningError unless Keybase.running?
64
- `keybase --version`.split[2]
65
- end
66
- end
67
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Keybase
4
- # A namespace for all exceptions defined by {Keybase}.
5
- module Exceptions
6
- # A top-level exception for the library.
7
- class KeybaseError < RuntimeError
8
- end
9
-
10
- # Raised if a Keybase installation can't be found.
11
- class KeybaseNotInstalledError < KeybaseError
12
- def initialize
13
- super "keybase needs to be installed"
14
- end
15
- end
16
-
17
- # Raised whenever Keybase is not running locally.
18
- class KeybaseNotRunningError < KeybaseError
19
- def initialize
20
- super "keybase needs to be running"
21
- end
22
- end
23
-
24
- # Raised whenever KBFS is not running locally.
25
- class KBFSNotRunningError < KeybaseError
26
- def initialize
27
- super "KBFS needs to be enabled and running"
28
- end
29
- end
30
- end
31
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Keybase
4
- # Represents the Keybase filesystem.
5
- # @note This is just a stub for the time being.
6
- class KBFS
7
- # @raise [Exceptions::KeybaseNotRunningError] unless Keybase is running
8
- # @raise [Exceptions::KBFSNotRunningError] unless KBFS is running
9
- def initialize
10
- raise Exceptions::KeybaseNotRunningError unless Keybase.running?
11
- raise Exceptions::KBFSNotRunningError unless Dir.exist?("/keybase")
12
- end
13
- end
14
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Keybase
4
- # Represents a user known to the local Keybase process.
5
- # These are (presumably) users that have been logged into locally.
6
- class LocalUser
7
- # @return [String] the device's unique identifier
8
- attr_reader :device
9
-
10
- # @return [String] the user's unique identifier
11
- attr_reader :id
12
-
13
- # @return [String] the user's Keybase username
14
- attr_reader :name
15
-
16
- # @return [String] some kind of salt
17
- # @note I have no idea what this field does.
18
- attr_reader :salt
19
-
20
- # @param fields [Hash] the user's configuration fields
21
- # @option fields device [String] the device's unique identifier
22
- # @option fields id [String] the user's unique identifier
23
- # @option fields name [String] the user's Keybase username
24
- # @option fields salt [String] some kind of salt
25
- def initialize(fields)
26
- @device = fields["device"]
27
- @id = fields["id"]
28
- @name = fields["name"]
29
- @salt = fields["salt"]
30
- end
31
- end
32
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Keybase
4
- # A class for converting arrays of users into Keybase-style strings.
5
- class U
6
- class << self
7
- # @param args [Array<String>] the list of users to merge
8
- # @return [String] the Keybase-style user string
9
- # @example
10
- # Keybase::U["a", "b"] # => "a,b"
11
- def [](*args)
12
- args.join(",")
13
- end
14
- end
15
- end
16
- end