checkoff 0.161.0 → 0.162.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -1
- data/Makefile +8 -1
- data/checkoff.gemspec +1 -0
- data/lib/checkoff/attachments.rb +203 -0
- data/lib/checkoff/version.rb +1 -1
- metadata +16 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79b74e311c0a9146b3dd2d501940eee17ff14519bdf422ae031808cdd64afef9
|
4
|
+
data.tar.gz: 2b464f0fc470ac543a24683dc6d58f2b7131cf6094ab8a9f84813dbae0726d04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc73effc84d1d49b688a494ff729b07507d94b29bb8647a96f207cde22d72a39006d9e756e6a35bc218eb603d2736de578914c90871fef595f4301fad193a0ed
|
7
|
+
data.tar.gz: 9825765f922b7ceac77884761cef8e937eb39313ff8daf9daed4d478c3a6b63ea497eb0aa9e3f9727483c6657307d85317c03e22d08e36b71d5dd971f6487916
|
data/Gemfile.lock
CHANGED
@@ -12,12 +12,13 @@ GIT
|
|
12
12
|
PATH
|
13
13
|
remote: .
|
14
14
|
specs:
|
15
|
-
checkoff (0.
|
15
|
+
checkoff (0.162.0)
|
16
16
|
activesupport
|
17
17
|
asana (> 0.10.0)
|
18
18
|
cache_method
|
19
19
|
dalli
|
20
20
|
gli
|
21
|
+
mime-types
|
21
22
|
|
22
23
|
GEM
|
23
24
|
remote: https://rubygems.org/
|
@@ -110,6 +111,9 @@ GEM
|
|
110
111
|
mixlib-config (>= 2.2.1, < 4)
|
111
112
|
mixlib-shellout
|
112
113
|
method_source (1.0.0)
|
114
|
+
mime-types (3.5.1)
|
115
|
+
mime-types-data (~> 3.2015)
|
116
|
+
mime-types-data (3.2023.1205)
|
113
117
|
minitest (5.20.0)
|
114
118
|
minitest-profile (0.0.2)
|
115
119
|
minitest-reporters (1.6.1)
|
data/Makefile
CHANGED
@@ -49,7 +49,6 @@ clear_metrics: ## remove or reset result artifacts created by tests and quality
|
|
49
49
|
|
50
50
|
clean: clear_metrics ## remove all built artifacts
|
51
51
|
|
52
|
-
|
53
52
|
citest: test ## Run unit tests from CircleCI
|
54
53
|
|
55
54
|
overcommit: ## run precommit quality checks
|
@@ -69,6 +68,14 @@ repl: ## Load up checkoff in pry
|
|
69
68
|
clean-coverage:
|
70
69
|
@bundle exec rake clear_metrics
|
71
70
|
|
71
|
+
clean-typecheck: ## Refresh information that type checking depends on
|
72
|
+
bundle install
|
73
|
+
bundle exec solargraph clear
|
74
|
+
rm -fr .yardoc/
|
75
|
+
bundle exec yard gems
|
76
|
+
bundle exec solargraph scan
|
77
|
+
echo all clear
|
78
|
+
|
72
79
|
coverage: test report-coverage ## check code coverage
|
73
80
|
@bundle exec rake undercover
|
74
81
|
|
data/checkoff.gemspec
CHANGED
@@ -0,0 +1,203 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
require 'faraday'
|
6
|
+
require 'faraday/multipart'
|
7
|
+
require 'forwardable'
|
8
|
+
require 'cache_method'
|
9
|
+
require 'mime/types'
|
10
|
+
require 'net/http'
|
11
|
+
require 'net/http/response'
|
12
|
+
require 'net/http/responses'
|
13
|
+
require 'tempfile'
|
14
|
+
require_relative 'internal/config_loader'
|
15
|
+
require_relative 'internal/logging'
|
16
|
+
require_relative 'workspaces'
|
17
|
+
require_relative 'tasks'
|
18
|
+
require_relative 'clients'
|
19
|
+
|
20
|
+
# https://developers.asana.com/reference/attachments
|
21
|
+
|
22
|
+
module Checkoff
|
23
|
+
# Manage attachments in Asana
|
24
|
+
class Attachments
|
25
|
+
# @!parse
|
26
|
+
# extend CacheMethod::ClassMethods
|
27
|
+
|
28
|
+
include Logging
|
29
|
+
|
30
|
+
MINUTE = 60
|
31
|
+
private_constant :MINUTE
|
32
|
+
HOUR = MINUTE * 60
|
33
|
+
private_constant :HOUR
|
34
|
+
DAY = 24 * HOUR
|
35
|
+
private_constant :DAY
|
36
|
+
REALLY_LONG_CACHE_TIME = HOUR * 1
|
37
|
+
private_constant :REALLY_LONG_CACHE_TIME
|
38
|
+
LONG_CACHE_TIME = MINUTE * 15
|
39
|
+
private_constant :LONG_CACHE_TIME
|
40
|
+
SHORT_CACHE_TIME = MINUTE
|
41
|
+
private_constant :SHORT_CACHE_TIME
|
42
|
+
|
43
|
+
# @param config [Hash]
|
44
|
+
# @param workspaces [Checkoff::Workspaces]
|
45
|
+
# @param clients [Checkoff::Clients]
|
46
|
+
# @param client [Asana::Client]
|
47
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
48
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
49
|
+
clients: Checkoff::Clients.new(config: config),
|
50
|
+
client: clients.client)
|
51
|
+
@workspaces = workspaces
|
52
|
+
@client = client
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param url [String]
|
56
|
+
# @param resource [Asana::Resources::Resource]
|
57
|
+
# @param attachment_name [String,nil]
|
58
|
+
# @param just_the_url [Boolean]
|
59
|
+
#
|
60
|
+
# @return [Asana::Resources::Attachment]
|
61
|
+
def create_attachment_from_url!(url,
|
62
|
+
resource,
|
63
|
+
attachment_name: nil,
|
64
|
+
just_the_url: false)
|
65
|
+
if just_the_url
|
66
|
+
create_attachment_from_url_alone!(url, resource, attachment_name: attachment_name)
|
67
|
+
else
|
68
|
+
create_attachment_from_downloaded_url!(url, resource, attachment_name: attachment_name)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Writes contents of URL to a temporary file with the same
|
73
|
+
# extension as the URL using Net::HTTP, raising an exception if
|
74
|
+
# not succesful
|
75
|
+
#
|
76
|
+
# @param uri [URI]
|
77
|
+
#
|
78
|
+
# @return [Object]
|
79
|
+
# @sg-ignore
|
80
|
+
def download_uri(uri, &block)
|
81
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
82
|
+
# @sg-ignore
|
83
|
+
request = Net::HTTP::Get.new(uri)
|
84
|
+
http.request(request) do |response|
|
85
|
+
# use a block to ensure the file is closed after we're done with it
|
86
|
+
raise("Unexpected response code: #{response.code}") unless response.code == '200'
|
87
|
+
|
88
|
+
write_tempfile_from_response(response) do |tempfile|
|
89
|
+
block.yield tempfile
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# @sg-ignore
|
96
|
+
# @param response [Net::HTTPResponse]
|
97
|
+
#
|
98
|
+
# @yields [IO]
|
99
|
+
#
|
100
|
+
# @return [Object]
|
101
|
+
def write_tempfile_from_response(response)
|
102
|
+
Tempfile.create('checkoff') do |tempfile|
|
103
|
+
tempfile.binmode
|
104
|
+
# @sg-ignore
|
105
|
+
response.read_body do |chunk|
|
106
|
+
tempfile.write(chunk)
|
107
|
+
end
|
108
|
+
tempfile.rewind
|
109
|
+
|
110
|
+
yield tempfile
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# @param url [String]
|
115
|
+
# @param resource [Asana::Resources::Resource]
|
116
|
+
# @param attachment_name [String,nil]
|
117
|
+
#
|
118
|
+
# @return [Asana::Resources::Attachment]
|
119
|
+
def create_attachment_from_downloaded_url!(url, resource, attachment_name:)
|
120
|
+
uri = URI(url)
|
121
|
+
attachment_name ||= File.basename(uri.path)
|
122
|
+
download_uri(uri) do |tempfile|
|
123
|
+
content_type ||= content_type_from_filename(attachment_name)
|
124
|
+
content_type ||= content_type_from_filename(uri.path)
|
125
|
+
|
126
|
+
resource.attach(filename: attachment_name, mime: content_type,
|
127
|
+
io: tempfile)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
# @param url [String]
|
134
|
+
# @param resource [Asana::Resources::Resource]
|
135
|
+
# @param attachment_name [String,nil]
|
136
|
+
#
|
137
|
+
# @return [Asana::Resources::Attachment,nil]
|
138
|
+
def create_attachment_from_url_alone!(url, resource, attachment_name:)
|
139
|
+
with_params = {
|
140
|
+
'parent' => resource.gid,
|
141
|
+
'url' => url,
|
142
|
+
'resource_subtype' => 'external',
|
143
|
+
'name' => attachment_name,
|
144
|
+
}
|
145
|
+
options = {}
|
146
|
+
Asana::Resource.new(parse(client.post('/attachments', body: with_params, options: options)).first,
|
147
|
+
client: client)
|
148
|
+
end
|
149
|
+
|
150
|
+
# @param filename [String]
|
151
|
+
#
|
152
|
+
# @return [String,nil]
|
153
|
+
# @sg-ignore
|
154
|
+
def content_type_from_filename(filename)
|
155
|
+
# @sg-ignore
|
156
|
+
MIME::Types.type_for(filename)&.first&.content_type
|
157
|
+
end
|
158
|
+
|
159
|
+
# https://github.com/Asana/ruby-asana/blob/master/lib/asana/resource_includes/response_helper.rb#L7
|
160
|
+
# @param response [Faraday::Response]
|
161
|
+
#
|
162
|
+
# @return [Array<Hash, Hash>]
|
163
|
+
def parse(response)
|
164
|
+
data = response.body.fetch('data') do
|
165
|
+
raise("Unexpected response body: #{response.body}")
|
166
|
+
end
|
167
|
+
extra = response.body.except('data')
|
168
|
+
[data, extra]
|
169
|
+
end
|
170
|
+
|
171
|
+
# @return [Checkoff::Workspaces]
|
172
|
+
attr_reader :workspaces
|
173
|
+
|
174
|
+
# @return [Asana::Client]
|
175
|
+
attr_reader :client
|
176
|
+
|
177
|
+
# bundle exec ./attachments.rb
|
178
|
+
# :nocov:
|
179
|
+
class << self
|
180
|
+
# @return [void]
|
181
|
+
def run
|
182
|
+
# @sg-ignore
|
183
|
+
# @type [String]
|
184
|
+
gid = ARGV[0] || raise('Please pass task gid as first argument')
|
185
|
+
# @sg-ignore
|
186
|
+
# @type [String]
|
187
|
+
url = ARGV[1] || raise('Please pass attachment URL as second argument')
|
188
|
+
|
189
|
+
tasks = Checkoff::Tasks.new
|
190
|
+
attachments = Checkoff::Attachments.new
|
191
|
+
task = tasks.task_by_gid(gid)
|
192
|
+
attachment = attachments.create_attachment_from_url!(url, task)
|
193
|
+
puts "Results: #{attachment.inspect}"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
# :nocov:
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# :nocov:
|
201
|
+
abs_program_name = File.expand_path($PROGRAM_NAME)
|
202
|
+
Checkoff::Attachments.run if abs_program_name == File.expand_path(__FILE__)
|
203
|
+
# :nocov:
|
data/lib/checkoff/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: checkoff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.162.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vince Broz
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mime-types
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description:
|
84
98
|
email:
|
85
99
|
- vince@broz.cc
|
@@ -129,6 +143,7 @@ files:
|
|
129
143
|
- exe/checkoff
|
130
144
|
- fix.sh
|
131
145
|
- lib/checkoff.rb
|
146
|
+
- lib/checkoff/attachments.rb
|
132
147
|
- lib/checkoff/cli.rb
|
133
148
|
- lib/checkoff/clients.rb
|
134
149
|
- lib/checkoff/create-entity.sh
|