neocities 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 91023e44cb2b6df2ed6014513a925da7b00420f7
4
- data.tar.gz: 728a534ab0854def9a92ce9397aca1b5b07ca80b
3
+ metadata.gz: e6247ca86f02faa4f57147bf46dde7f04e6d96f9
4
+ data.tar.gz: 9f4a4b8f63992410de81fb9992edd7f133e7ad4d
5
5
  SHA512:
6
- metadata.gz: 8c9e360c1d69af9f34d5ba7be22dc87944e827e781a2f689212d39e75d5520cf08767510c9f590b28ab1213ed510b427e218c8cccbb9f9ecf86f26de866942c4
7
- data.tar.gz: 40f7d15988184963237693961b240ad5467eb231eb2bee559fa7d5ec527f585526573fef66936bc46ad1a1e098ea002727020929b87707f69c8ea609a5fd34d8
6
+ metadata.gz: 5547e47f7ff6d96504cf4b7883da0503b5a9bda6d6cd795fdae357afb83e67152e1fffe33e012193e5512ec83e502dfd6882c520fc76e79397e339354027dded
7
+ data.tar.gz: efcd58356410fbd8ee8e28389d789c803ba7ff6659f4ce8ff9aafba49637bff0d05ac39ef033e50d50ffb6e4c398e337a24320ce33f354d9a3ceedbab48a3aba
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  Gemfile.lock
2
2
  test.rb
3
+ *.gem
@@ -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.
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- require_relative '../lib/neocities'
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'neocities')
3
3
  cli = Neocities::CLI.new ARGV
4
4
  cli.run
@@ -1,3 +1,3 @@
1
- require_relative 'neocities/version'
2
- require_relative 'neocities/client'
3
- require_relative 'neocities/cli'
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')
@@ -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
- API_KEY_PATH = ENV['HOME']+'/.neocities/api_key'
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 API_KEY_PATH
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(API_KEY_PATH).dirname
63
- File.write API_KEY_PATH, res[:api_key]
64
- puts "The api key for #{@pastel.bold @sitename} has been stored in #{@pastel.bold API_KEY_PATH}."
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 sync
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}")); display_sync_help_and_exit
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
- display_sync_help_and_exit
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
- display_sync_help_and_exit
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
- ignore = Buff::Ignore::IgnoreFile.new '.gitignore'
170
- ignore.apply! paths
171
- puts "Not syncing .gitignore entries (--no-gitignore to disable)"
172
- rescue Buff::Ignore::IgnoreFileNotFound
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("Syncing #{path} ... ")
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 sync command)"
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'} Delete myfile.jpg
285
+ #{@pastel.green '$ neocities delete myfile.jpg'} Delete myfile.jpg
260
286
 
261
- #{@pastel.green '$ neocities delete myfile.jpg myfile2.jpg'} Delete myfile.jpg and 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 display_sync_help_and_exit
311
+ def display_push_help_and_exit
284
312
  display_banner
285
313
 
286
314
  puts <<HERE
287
- #{@pastel.green.bold 'sync'} - Upload a local directory to your Neocities site
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 sync .'} Recursively upload current directory
319
+ #{@pastel.green '$ neocities push .'} Recursively upload current directory.
292
320
 
293
- #{@pastel.green '$ neocities sync -e node_modules -e secret.txt .'} Exclude certain files from sync
321
+ #{@pastel.green '$ neocities push -e node_modules -e secret.txt .'} Exclude certain files from push
294
322
 
295
- #{@pastel.green '$ neocities sync --no-gitignore .'} Don't use .gitignore to exclude files
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
- sync Recursively upload a local directory to your site
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
@@ -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
- if opts[:api_key]
11
- @http = HTTP.auth "Bearer #{opts[:api_key]}"
12
- elsif opts[:sitename] && opts[:password]
13
- @http = HTTP.basic_auth user: opts[:sitename], pass: opts[:password]
14
- else
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
- run :get, 'list', params: {path: path}
24
+ get 'list', :path => path
21
25
  end
22
26
 
23
27
  def key
24
- run :get, 'key', {}
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
- run :post, 'upload', form: {
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
- run :post, 'delete', form: {'filenames[]' => paths}
42
+ post 'delete', 'filenames[]' => paths
41
43
  end
42
44
 
43
45
  def info(sitename)
44
- run :get, 'info', params: {sitename: sitename}
46
+ get 'info', sitename: sitename
45
47
  end
46
48
 
47
49
  private
48
50
 
49
- def run(meth, path, args)
50
- resp = @http.send(meth, API_URI+path, args)
51
- JSON.parse resp.body, symbolize_names: true
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
@@ -1,3 +1,3 @@
1
1
  module Neocities
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -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', '~> 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 'http', '~> 2.2', '>= 2.2.2'
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.2
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-15 00:00:00.000000000 Z
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: http
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.2'
79
+ version: '2.0'
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 2.2.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.2'
89
+ version: '2.0'
90
90
  - - ">="
91
91
  - !ruby/object:Gem::Version
92
- version: 2.2.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