neocities 0.0.2 → 0.0.3
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 +4 -4
- data/.gitignore +1 -0
- data/README.md +15 -0
- data/bin/neocities +1 -1
- data/lib/neocities.rb +3 -3
- data/lib/neocities/cli.rb +94 -24
- data/lib/neocities/client.rb +32 -16
- data/lib/neocities/version.rb +1 -1
- data/neocities.gemspec +4 -14
- metadata +8 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6247ca86f02faa4f57147bf46dde7f04e6d96f9
|
4
|
+
data.tar.gz: 9f4a4b8f63992410de81fb9992edd7f133e7ad4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5547e47f7ff6d96504cf4b7883da0503b5a9bda6d6cd795fdae357afb83e67152e1fffe33e012193e5512ec83e502dfd6882c520fc76e79397e339354027dded
|
7
|
+
data.tar.gz: efcd58356410fbd8ee8e28389d789c803ba7ff6659f4ce8ff9aafba49637bff0d05ac39ef033e50d50ffb6e4c398e337a24320ce33f354d9a3ceedbab48a3aba
|
data/.gitignore
CHANGED
data/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# The Neocities Gem
|
2
|
+
|
3
|
+
A CLI and library for using the Neocities API. Makes it easy to quickly upload, push, delete, and list your Neocities site.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
If you're using OSX (or already have ruby installed), run this command:
|
8
|
+
|
9
|
+
gem install neocities
|
10
|
+
|
11
|
+
After that, you are all set! Run `neocities` to see the options and get started.
|
12
|
+
|
13
|
+
## Neocities::Client
|
14
|
+
|
15
|
+
This gem also ships with Neocities::Client, which you can use to write code that interfaces with the Neocities API.
|
data/bin/neocities
CHANGED
data/lib/neocities.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require File.join(File.dirname(__FILE__), 'neocities', 'version')
|
2
|
+
require File.join(File.dirname(__FILE__), 'neocities', 'client')
|
3
|
+
require File.join(File.dirname(__FILE__), 'neocities', 'cli')
|
data/lib/neocities/cli.rb
CHANGED
@@ -4,11 +4,11 @@ require 'tty/table'
|
|
4
4
|
require 'tty/prompt'
|
5
5
|
require 'fileutils'
|
6
6
|
require 'buff/ignore'
|
7
|
+
require File.join(File.dirname(__FILE__), 'client')
|
7
8
|
|
8
9
|
module Neocities
|
9
10
|
class CLI
|
10
|
-
|
11
|
-
SUBCOMMANDS = %w{upload delete list info sync pizza}
|
11
|
+
SUBCOMMANDS = %w{upload delete list info push logout pizza}
|
12
12
|
HELP_SUBCOMMANDS = ['-h', '--help', 'help']
|
13
13
|
PENELOPE_MOUTHS = %w{^ o ~ - v U}
|
14
14
|
PENELOPE_EYES = %w{o ~ O}
|
@@ -20,6 +20,7 @@ module Neocities
|
|
20
20
|
@subargs = @argv[1..@argv.length]
|
21
21
|
@prompt = TTY::Prompt.new
|
22
22
|
@api_key = ENV['NEOCITIES_API_KEY'] || nil
|
23
|
+
@app_config_path = File.join self.class.app_config_path, 'config'
|
23
24
|
end
|
24
25
|
|
25
26
|
def display_response(resp)
|
@@ -42,7 +43,7 @@ module Neocities
|
|
42
43
|
send "display_#{@subcmd}_help_and_exit" if @subargs.empty?
|
43
44
|
|
44
45
|
begin
|
45
|
-
@api_key = File.read
|
46
|
+
@api_key = File.read @app_config_path
|
46
47
|
rescue Errno::ENOENT
|
47
48
|
@api_key = nil
|
48
49
|
end
|
@@ -59,9 +60,9 @@ module Neocities
|
|
59
60
|
|
60
61
|
res = @client.key
|
61
62
|
if res[:api_key]
|
62
|
-
FileUtils.mkdir_p Pathname(
|
63
|
-
File.write
|
64
|
-
puts "The api key for #{@pastel.bold @sitename} has been stored in #{@pastel.bold
|
63
|
+
FileUtils.mkdir_p Pathname(@app_config_path).dirname
|
64
|
+
File.write @app_config_path, res[:api_key]
|
65
|
+
puts "The api key for #{@pastel.bold @sitename} has been stored in #{@pastel.bold @app_config_path}."
|
65
66
|
else
|
66
67
|
display_response resp
|
67
68
|
exit
|
@@ -82,6 +83,21 @@ module Neocities
|
|
82
83
|
end
|
83
84
|
end
|
84
85
|
|
86
|
+
def logout
|
87
|
+
confirmed = false
|
88
|
+
loop {
|
89
|
+
case @subargs[0]
|
90
|
+
when '-y' then @subargs.shift; confirmed = true
|
91
|
+
when /^-/ then puts(@pastel.red.bold("Unknown option: #{@subargs[0].inspect}")); display_logout_help_and_exit
|
92
|
+
else break
|
93
|
+
end
|
94
|
+
}
|
95
|
+
if confirmed
|
96
|
+
FileUtils.rm @app_config_path
|
97
|
+
puts @pastel.bold("Your api key has been removed.")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
85
101
|
def info
|
86
102
|
resp = @client.info(@subargs[0] || @sitename)
|
87
103
|
|
@@ -137,14 +153,14 @@ module Neocities
|
|
137
153
|
end
|
138
154
|
end
|
139
155
|
|
140
|
-
def
|
156
|
+
def push
|
141
157
|
@no_gitignore = false
|
142
158
|
@excluded_files = []
|
143
159
|
loop {
|
144
160
|
case @subargs[0]
|
145
161
|
when '--no-gitignore' then @subargs.shift; @no_gitignore = true
|
146
162
|
when '-e' then @subargs.shift; @excluded_files.push(@subargs.shift)
|
147
|
-
when /^-/ then puts(@pastel.red.bold("Unknown option: #{@subargs[0].inspect}"));
|
163
|
+
when /^-/ then puts(@pastel.red.bold("Unknown option: #{@subargs[0].inspect}")); display_push_help_and_exit
|
148
164
|
else break
|
149
165
|
end
|
150
166
|
}
|
@@ -153,12 +169,12 @@ module Neocities
|
|
153
169
|
|
154
170
|
if !root_path.exist?
|
155
171
|
display_response result: 'error', message: "path #{root_path} does not exist"
|
156
|
-
|
172
|
+
display_push_help_and_exit
|
157
173
|
end
|
158
174
|
|
159
175
|
if !root_path.directory?
|
160
176
|
display_response result: 'error', message: 'provided path is not a directory'
|
161
|
-
|
177
|
+
display_push_help_and_exit
|
162
178
|
end
|
163
179
|
|
164
180
|
Dir.chdir(root_path) do
|
@@ -166,10 +182,20 @@ module Neocities
|
|
166
182
|
|
167
183
|
if @no_gitignore == false
|
168
184
|
begin
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
185
|
+
ignores = File.readlines('.gitignore').collect! do |ignore|
|
186
|
+
File.directory?(ignore.strip!) ? "#{ignore}**" : ignore
|
187
|
+
end
|
188
|
+
paths.select! do |path|
|
189
|
+
res = true
|
190
|
+
ignores.each do |ignore|
|
191
|
+
if File.fnmatch?(ignore.strip, path)
|
192
|
+
res = false
|
193
|
+
break
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
puts "Not pushing .gitignore entries (--no-gitignore to disable)"
|
198
|
+
rescue Errno::ENOENT
|
173
199
|
end
|
174
200
|
end
|
175
201
|
|
@@ -179,7 +205,7 @@ module Neocities
|
|
179
205
|
|
180
206
|
paths.each do |path|
|
181
207
|
next if path.directory?
|
182
|
-
print @pastel.bold("
|
208
|
+
print @pastel.bold("Uploading #{path} ... ")
|
183
209
|
resp = @client.upload path, path
|
184
210
|
|
185
211
|
if resp[:result] == 'success'
|
@@ -213,7 +239,7 @@ module Neocities
|
|
213
239
|
end
|
214
240
|
|
215
241
|
if path.directory?
|
216
|
-
puts "#{path} is a directory, skipping (see the
|
242
|
+
puts "#{path} is a directory, skipping (see the push command)"
|
217
243
|
next
|
218
244
|
end
|
219
245
|
|
@@ -256,9 +282,11 @@ HERE
|
|
256
282
|
|
257
283
|
#{@pastel.dim 'Examples:'}
|
258
284
|
|
259
|
-
#{@pastel.green '$ neocities delete myfile.jpg'}
|
285
|
+
#{@pastel.green '$ neocities delete myfile.jpg'} Delete myfile.jpg
|
260
286
|
|
261
|
-
#{@pastel.green '$ neocities delete myfile.jpg myfile2.jpg'}
|
287
|
+
#{@pastel.green '$ neocities delete myfile.jpg myfile2.jpg'} Delete myfile.jpg and myfile2.jpg
|
288
|
+
|
289
|
+
#{@pastel.green '$ neocities delete mydir'} Deletes mydir and everything inside it (be careful!)
|
262
290
|
|
263
291
|
HERE
|
264
292
|
exit
|
@@ -280,19 +308,19 @@ HERE
|
|
280
308
|
exit
|
281
309
|
end
|
282
310
|
|
283
|
-
def
|
311
|
+
def display_push_help_and_exit
|
284
312
|
display_banner
|
285
313
|
|
286
314
|
puts <<HERE
|
287
|
-
#{@pastel.green.bold '
|
315
|
+
#{@pastel.green.bold 'push'} - Recursively upload a local directory to your Neocities site
|
288
316
|
|
289
317
|
#{@pastel.dim 'Examples:'}
|
290
318
|
|
291
|
-
#{@pastel.green '$ neocities
|
319
|
+
#{@pastel.green '$ neocities push .'} Recursively upload current directory.
|
292
320
|
|
293
|
-
#{@pastel.green '$ neocities
|
321
|
+
#{@pastel.green '$ neocities push -e node_modules -e secret.txt .'} Exclude certain files from push
|
294
322
|
|
295
|
-
#{@pastel.green '$ neocities
|
323
|
+
#{@pastel.green '$ neocities push --no-gitignore .'} Don't use .gitignore to exclude files
|
296
324
|
|
297
325
|
HERE
|
298
326
|
exit
|
@@ -308,6 +336,20 @@ HERE
|
|
308
336
|
|
309
337
|
#{@pastel.green '$ neocities info fauux'} Gets info for 'fauux' site
|
310
338
|
|
339
|
+
HERE
|
340
|
+
exit
|
341
|
+
end
|
342
|
+
|
343
|
+
def display_logout_help_and_exit
|
344
|
+
display_banner
|
345
|
+
|
346
|
+
puts <<HERE
|
347
|
+
#{@pastel.green.bold 'logout'} - Remove the site api key from the config
|
348
|
+
|
349
|
+
#{@pastel.dim 'Examples:'}
|
350
|
+
|
351
|
+
#{@pastel.green '$ neocities logout -y'}
|
352
|
+
|
311
353
|
HERE
|
312
354
|
exit
|
313
355
|
end
|
@@ -326,16 +368,44 @@ HERE
|
|
326
368
|
display_banner
|
327
369
|
puts <<HERE
|
328
370
|
#{@pastel.dim 'Subcommands:'}
|
329
|
-
|
371
|
+
push Recursively upload a local directory to your site
|
330
372
|
upload Upload individual files to your Neocities site
|
331
373
|
delete Delete files from your Neocities site
|
332
374
|
list List files from your Neocities site
|
333
375
|
info Information and stats for your site
|
376
|
+
logout Remove the site api key from the config
|
334
377
|
version Unceremoniously display version and self destruct
|
335
378
|
pizza Order a free pizza
|
336
379
|
|
337
380
|
HERE
|
338
381
|
exit
|
339
382
|
end
|
383
|
+
|
384
|
+
def self.app_config_path
|
385
|
+
File.join root_config_path, 'neocities'
|
386
|
+
end
|
387
|
+
|
388
|
+
def self.root_config_path
|
389
|
+
platform = if RUBY_PLATFORM =~ /win32/
|
390
|
+
:win32
|
391
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
392
|
+
:darwin
|
393
|
+
elsif RUBY_PLATFORM =~ /linux/
|
394
|
+
:linux
|
395
|
+
else
|
396
|
+
:unknown
|
397
|
+
end
|
398
|
+
|
399
|
+
case platform
|
400
|
+
when :win32
|
401
|
+
return File.join(ENV['LOCALAPPDATA']) if ENV['LOCALAPPDATA']
|
402
|
+
File.join ENV['USERPROFILE'], 'Local Settings', 'Application Data'
|
403
|
+
when :darwin
|
404
|
+
File.join ENV['HOME'], 'Library', 'Application Support'
|
405
|
+
else
|
406
|
+
return File.join(ENV['XDG_CONFIG_HOME']) if ENV['XDG_CONFIG_HOME']
|
407
|
+
File.join ENV['HOME'], '.config'
|
408
|
+
end
|
409
|
+
end
|
340
410
|
end
|
341
411
|
end
|
data/lib/neocities/client.rb
CHANGED
@@ -1,27 +1,31 @@
|
|
1
|
-
require 'http'
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
2
3
|
require 'json'
|
3
4
|
require 'pathname'
|
5
|
+
require 'uri'
|
6
|
+
require 'net/http/post/multipart'
|
4
7
|
|
5
8
|
module Neocities
|
6
9
|
class Client
|
7
10
|
API_URI = 'https://neocities.org/api/'
|
8
11
|
|
9
12
|
def initialize(opts={})
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
@uri = URI.parse API_URI
|
14
|
+
@http = Net::HTTP.new @uri.host, @uri.port
|
15
|
+
@http.use_ssl = true
|
16
|
+
@opts = opts
|
17
|
+
|
18
|
+
unless @opts[:api_key] || (@opts[:sitename] && @opts[:password])
|
15
19
|
raise ArgumentError, 'client requires a login (sitename/password) or an api_key'
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
19
23
|
def list(path=nil)
|
20
|
-
|
24
|
+
get 'list', :path => path
|
21
25
|
end
|
22
26
|
|
23
27
|
def key
|
24
|
-
|
28
|
+
get 'key'
|
25
29
|
end
|
26
30
|
|
27
31
|
def upload(path, remote_path=nil)
|
@@ -31,25 +35,37 @@ module Neocities
|
|
31
35
|
raise ArgumentError, "#{path.to_s} does not exist."
|
32
36
|
end
|
33
37
|
|
34
|
-
|
35
|
-
(remote_path || path.basename) => HTTP::FormData::File.new(path.to_s)
|
36
|
-
}
|
38
|
+
post 'upload', (remote_path || path.basename) => UploadIO.new(path.to_s, 'application/octet-stream')
|
37
39
|
end
|
38
40
|
|
39
41
|
def delete(*paths)
|
40
|
-
|
42
|
+
post 'delete', 'filenames[]' => paths
|
41
43
|
end
|
42
44
|
|
43
45
|
def info(sitename)
|
44
|
-
|
46
|
+
get 'info', sitename: sitename
|
45
47
|
end
|
46
48
|
|
47
49
|
private
|
48
50
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
51
|
+
def get(path, params={})
|
52
|
+
req = Net::HTTP::Get.new "#{@uri.path}#{path}?#{URI.encode_www_form(params)}"
|
53
|
+
request req
|
54
|
+
end
|
55
|
+
|
56
|
+
def post(path, args={})
|
57
|
+
req = Net::HTTP::Post::Multipart.new("#{@uri.path}#{path}", args)
|
58
|
+
res = request req
|
52
59
|
end
|
53
60
|
|
61
|
+
def request(req)
|
62
|
+
if @opts[:api_key]
|
63
|
+
req['Authorization'] = "Bearer #{@opts[:api_key]}"
|
64
|
+
else
|
65
|
+
req.basic_auth @opts[:sitename], @opts[:password]
|
66
|
+
end
|
67
|
+
resp = @http.request req
|
68
|
+
JSON.parse resp.body, symbolize_names: true
|
69
|
+
end
|
54
70
|
end
|
55
71
|
end
|
data/lib/neocities/version.rb
CHANGED
data/neocities.gemspec
CHANGED
@@ -16,18 +16,8 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^(tests)/})
|
17
17
|
spec.require_paths = ["lib"]
|
18
18
|
|
19
|
-
spec.add_dependency 'tty-table',
|
20
|
-
spec.add_dependency 'tty-prompt',
|
21
|
-
spec.add_dependency 'pastel',
|
22
|
-
spec.add_dependency '
|
23
|
-
spec.add_dependency 'buff-ignore', '~> 1.2'
|
24
|
-
|
25
|
-
# spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
-
# spec.add_development_dependency 'faker'
|
27
|
-
# spec.add_development_dependency 'minitest'
|
28
|
-
# spec.add_development_dependency 'minitest-reporters'
|
29
|
-
# spec.add_development_dependency 'rack-test'
|
30
|
-
# spec.add_development_dependency 'mocha'
|
31
|
-
# spec.add_development_dependency 'webmock'
|
32
|
-
# spec.add_development_dependency 'simplecov'
|
19
|
+
spec.add_dependency 'tty-table', '~> 0.8', '>= 0.8.0'
|
20
|
+
spec.add_dependency 'tty-prompt', '~> 0.12', '>= 0.12.0'
|
21
|
+
spec.add_dependency 'pastel', '~> 0.7', '>= 0.7.1'
|
22
|
+
spec.add_dependency 'multipart-post', '~> 2.0', '>= 2.0.0'
|
33
23
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neocities
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Drake
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-table
|
@@ -71,39 +71,25 @@ dependencies:
|
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: 0.7.1
|
73
73
|
- !ruby/object:Gem::Dependency
|
74
|
-
name:
|
74
|
+
name: multipart-post
|
75
75
|
requirement: !ruby/object:Gem::Requirement
|
76
76
|
requirements:
|
77
77
|
- - "~>"
|
78
78
|
- !ruby/object:Gem::Version
|
79
|
-
version: '2.
|
79
|
+
version: '2.0'
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 2.
|
82
|
+
version: 2.0.0
|
83
83
|
type: :runtime
|
84
84
|
prerelease: false
|
85
85
|
version_requirements: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '2.
|
89
|
+
version: '2.0'
|
90
90
|
- - ">="
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version: 2.
|
93
|
-
- !ruby/object:Gem::Dependency
|
94
|
-
name: buff-ignore
|
95
|
-
requirement: !ruby/object:Gem::Requirement
|
96
|
-
requirements:
|
97
|
-
- - "~>"
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
version: '1.2'
|
100
|
-
type: :runtime
|
101
|
-
prerelease: false
|
102
|
-
version_requirements: !ruby/object:Gem::Requirement
|
103
|
-
requirements:
|
104
|
-
- - "~>"
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
version: '1.2'
|
92
|
+
version: 2.0.0
|
107
93
|
description:
|
108
94
|
email:
|
109
95
|
- contact@neocities.org
|
@@ -114,6 +100,7 @@ extra_rdoc_files: []
|
|
114
100
|
files:
|
115
101
|
- ".gitignore"
|
116
102
|
- Gemfile
|
103
|
+
- README.md
|
117
104
|
- bin/neocities
|
118
105
|
- lib/neocities.rb
|
119
106
|
- lib/neocities/cli.rb
|