mtcli 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 215fbd90e2baea2492d8f7a562eaf49769a43ceb
4
+ data.tar.gz: 6e5f11a045660ffb362874369d0c7538d640ca54
5
+ SHA512:
6
+ metadata.gz: 2db5faf932c306b5984889c0410f8fe575d42013656f0eb680573f9e5eb4c8e3750b147e398535976d9642fb7c81aa27b37a9ff40ea6b4d9a60f5ff82667b0c7
7
+ data.tar.gz: 749a5caac93fe93adbc2656328fa93138b2dc9f9992abf41e01852209bf3d4ed8d5e2f115838421efb71b66bdafd1eabc3692453351267c1fc6a2b2bd5928b9b
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /vendor/
11
+ /mtcli-*.gem
12
+ *.swp
13
+ /.idea/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mtcli.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # MTCLI
2
+
3
+ A command line client for Movale Type Data API.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ $ mtcli add localhost http://localhost/mt/mt-data-api.cgi
9
+ $ mtcli current localhost
10
+ $ mtcli list_entries --site_id=1 --limit=3 | jq .
11
+ ```
12
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'mtcli'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/mtcli ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mtcli'
4
+
5
+ MTCLI::CLI.start
data/lib/mtcli.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'mtcli/cli'
2
+ require 'mtcli/version'
3
+
4
+ # A command line client for MT Data API.
5
+ module MTCLI
6
+ end
data/lib/mtcli/cli.rb ADDED
@@ -0,0 +1,192 @@
1
+ require 'json'
2
+ require 'mt/data_api/client'
3
+ require 'thor'
4
+ require 'yaml'
5
+
6
+ require 'mtcli/config'
7
+
8
+ module MTCLI
9
+ # CLI class.
10
+ class CLI < Thor
11
+ desc 'list', 'Show all MT settings'
12
+ def list
13
+ configs = Config.all
14
+ if configs.empty?
15
+ puts 'No MT settings are registered.'
16
+ return
17
+ end
18
+
19
+ configs.each do |config|
20
+ puts config
21
+ end
22
+ end
23
+
24
+ desc 'show <NAME>', 'Show MT setting'
25
+ def show(name)
26
+ config = Config.get(name)
27
+ unless config
28
+ puts "#{name} is not registered."
29
+ return
30
+ end
31
+
32
+ puts config
33
+ end
34
+
35
+ desc 'current [NAME]', 'Show/Set current MT setting'
36
+ def current(name = nil)
37
+ if name.nil?
38
+ unless Config.current
39
+ puts 'Current setting does not exist.'
40
+ return
41
+ end
42
+
43
+ puts Config.current
44
+ else
45
+ Config.current = name
46
+
47
+ puts "Current setting is #{name}."
48
+ end
49
+ end
50
+
51
+ desc 'add <NAME> <BASE_URL>', 'Add MT setting'
52
+ def add(name, base_url)
53
+ puts "Cannot add #{name}." unless Config.create(name, base_url: base_url)
54
+
55
+ puts "Added #{name}."
56
+ end
57
+
58
+ desc 'update <NAME> [arguments]', 'Update MT setting'
59
+ def update(_name)
60
+ puts 'update'
61
+ end
62
+
63
+ desc 'delete <NAME>', 'Delete MT setting'
64
+ def delete(name)
65
+ unless Config.delete(name)
66
+ puts "Cannot delete #{name}"
67
+ return
68
+ end
69
+
70
+ puts "Deleted #{name}"
71
+ end
72
+
73
+ desc 'rename <NAME> <NEW_NAME>', 'Rename MT setting'
74
+ def rename(name, new_name)
75
+ unless Config.get(name)
76
+ puts "#{name} is not registered."
77
+ return
78
+ end
79
+ if Config.get(new_name)
80
+ puts "#{new_name} exists."
81
+ return
82
+ end
83
+ unless Config.rename(name, new_name)
84
+ puts 'Renaming failed.'
85
+ return
86
+ end
87
+
88
+ puts "Renamed #{name} to #{new_name}."
89
+ end
90
+
91
+ desc 'login <USERNAME> <PASSWORD>', 'Login to current MT'
92
+ def login(username, password)
93
+ config = Config.current
94
+ unless config
95
+ puts 'No current setting.'
96
+ return
97
+ end
98
+
99
+ client = MT::DataAPI::Client.new(base_url: config.base_url,
100
+ client_id: 'mtcli')
101
+ client.call('authenticate', username: username,
102
+ password: password)
103
+
104
+ unless client.access_token
105
+ puts 'Login failed.'
106
+ return
107
+ end
108
+
109
+ config.access_token = client.access_token
110
+ config.save
111
+ puts 'Login succeeded.'
112
+ end
113
+
114
+ desc 'logout', 'Logout from current MT'
115
+ def logout
116
+ config = Config.current
117
+ unless config
118
+ puts 'No current setting.'
119
+ return
120
+ end
121
+ unless config.logged_in?
122
+ puts 'Not logged in.'
123
+ return
124
+ end
125
+
126
+ client = MT::DataAPI::Client.new(base_url: config.base_url,
127
+ client_id: 'mtcli',
128
+ access_token: config.access_token)
129
+ res = client.call('revoke_authentication')
130
+ return unless res['status'] == 'success'
131
+
132
+ config.access_token = nil
133
+ config.save
134
+ puts 'Logged out.'
135
+ end
136
+
137
+ def respond_to_missing?(method)
138
+ super
139
+ end
140
+
141
+ def method_missing(method, *_args)
142
+ config = Config.current
143
+ unless config
144
+ puts 'No current setting.'
145
+ return
146
+ end
147
+
148
+ opts = {
149
+ base_url: config.base_url,
150
+ client_id: 'mtcli'
151
+ }
152
+ opts[:access_token] = config.access_token if config.access_token
153
+ client = MT::DataAPI::Client.new(opts)
154
+
155
+ begin
156
+ res = client.call(method, options)
157
+ puts res.to_json
158
+ if opts['access_token'] && res['error'] && res['error']['code'] == 401
159
+ config.access_token = nil
160
+ config.save
161
+ puts 'Removed invalid access token.'
162
+ end
163
+ rescue
164
+ puts $ERROR_INFO
165
+ end
166
+ end
167
+
168
+ private
169
+
170
+ def options
171
+ key = nil
172
+ ARGV[1..-1].each_with_object({}) do |arg, opts|
173
+ if arg =~ /^--/
174
+ if arg =~ /=/
175
+ # key and value
176
+ key, value = arg.sub(/^--/, '').split(/=/)
177
+ opts[key] = value
178
+ key = nil
179
+ else
180
+ # key
181
+ key = arg.sub(/^--/, '')
182
+ end
183
+ elsif key
184
+ # value
185
+ opts[key] = arg
186
+ key = nil
187
+ end
188
+ opts
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,179 @@
1
+ require 'mt/data_api/client/endpoint_manager'
2
+ require 'yaml'
3
+
4
+ require 'mtcli/util'
5
+
6
+ module MTCLI
7
+ # configuration file class.
8
+ class Config
9
+ include Util
10
+
11
+ CONFIG_DIRECTORY = '.mtcli'.freeze
12
+ CURRENT_BASENAME = '.CURRENT'.freeze
13
+ YAML_EXTENSION = '.yml'.freeze
14
+
15
+ attr_accessor :access_token, :base_url, :endpoints, :version
16
+
17
+ def initialize(file_path, hash = {})
18
+ @file_path = file_path
19
+ @version = MT::DataAPI::Client::EndpointManager::DEFAULT_API_VERSION
20
+ set(hash)
21
+ end
22
+
23
+ def self.all
24
+ pattern = File.join(config_dir, '*' + YAML_EXTENSION)
25
+ Dir.glob(pattern).map do |file_path|
26
+ get(file_path)
27
+ end
28
+ end
29
+
30
+ def self.get(basename)
31
+ f = file_path(basename)
32
+ return nil unless File.exist?(f)
33
+ hash = YAML.load_file(f)
34
+ new(f, hash)
35
+ end
36
+
37
+ def self.create(basename, hash)
38
+ get(basename) && (return nil)
39
+ f = file_path(basename)
40
+ config = new(f, hash)
41
+ config.save
42
+ config
43
+ end
44
+
45
+ def self.update(basename, hash)
46
+ (config = get(basename)) || (return nil)
47
+ config.set(hash)
48
+ config.save
49
+ config
50
+ end
51
+
52
+ def self.delete(basename)
53
+ (config = get(basename)) || (return nil)
54
+ config.delete
55
+ config
56
+ end
57
+
58
+ def self.rename(basename, new_basename)
59
+ (config = get(basename)) || (return nil)
60
+ config.rename(new_basename) || (return nil)
61
+ config
62
+ end
63
+
64
+ def self.current
65
+ get(real_current_file_path)
66
+ end
67
+
68
+ def self.current=(basename)
69
+ (config = get(basename)) || (return nil)
70
+ return config if config.current?
71
+ config.set_current
72
+ config
73
+ end
74
+
75
+ def self.delete_current
76
+ return false unless File.exist?(current_file_path)
77
+ File.delete(current_file_path) == 1 || raise
78
+ end
79
+
80
+ def self.config_dir
81
+ File.join(ENV['HOME'], CONFIG_DIRECTORY)
82
+ end
83
+
84
+ def self.file_path(basename)
85
+ return basename if !basename || basename[0] == '/'
86
+ File.join(config_dir, basename + YAML_EXTENSION)
87
+ end
88
+
89
+ def self.current_file_path
90
+ file_path(CURRENT_BASENAME)
91
+ end
92
+
93
+ def self.real_current_file_path
94
+ f = current_file_path
95
+ return nil unless File.exist?(f) && File.ftype(f) == 'link'
96
+ File.readlink(f)
97
+ end
98
+
99
+ def save
100
+ raise unless @base_url || @base_url.empty?
101
+ File.open(@file_path, 'w') do |file|
102
+ YAML.dump(to_hash, file)
103
+ end
104
+ true
105
+ end
106
+
107
+ def set_current
108
+ self.class.delete_current
109
+ File.symlink(@file_path, self.class.current_file_path).zero? || raise
110
+ end
111
+
112
+ def to_s
113
+ hash = stringify_keys(basename => {
114
+ base_url: @base_url,
115
+ current: current?,
116
+ login: logged_in?,
117
+ version: @version
118
+ })
119
+ YAML.dump(hash)
120
+ end
121
+
122
+ def logged_in?
123
+ @access_token && !@access_token.empty? ? true : false
124
+ end
125
+
126
+ def current?
127
+ @file_path == self.class.real_current_file_path ? true : false
128
+ end
129
+
130
+ private
131
+
132
+ def basename
133
+ File.basename(@file_path, '.*')
134
+ end
135
+
136
+ def delete
137
+ self.class.delete_current if current?
138
+ File.delete(@file_path) == 1 || raise
139
+ end
140
+
141
+ def rename(new_basename)
142
+ return nil if self.class.get(new_basename)
143
+ current = current?
144
+ new_f = self.class.file_path(new_basename)
145
+ File.rename(@file_path, new_f).zero? || raise
146
+ set_current if current
147
+ end
148
+
149
+ def set(hash)
150
+ hash = symbolize_keys(hash)
151
+ @access_token = hash[:access_token] if hash.key?(:access_token)
152
+ @base_url = hash[:base_url] if hash.key?(:base_url)
153
+ @endpoints = hash[:endpoints] if hash.key?(:endpoints)
154
+ @version = hash[:version] if hash.key?(:version)
155
+ @current = hash[:current] if hash.key?(:current)
156
+ end
157
+
158
+ def to_hash
159
+ {
160
+ access_token: @access_token,
161
+ base_url: @base_url,
162
+ endpoints: @endpoints,
163
+ version: @version
164
+ }
165
+ end
166
+
167
+ def stringify_keys(data)
168
+ if data.is_a?(Hash)
169
+ data.reduce({}) do |h, (k, v)|
170
+ h.merge(k.to_s => stringify_keys(v))
171
+ end
172
+ elsif data.is_a?(Array)
173
+ data.map { |d| stringify_keys(d) }
174
+ else
175
+ data
176
+ end
177
+ end
178
+ end
179
+ end
data/lib/mtcli/util.rb ADDED
@@ -0,0 +1,18 @@
1
+ module MTCLI
2
+ # common methods.
3
+ module Util
4
+ def symbolize_keys(data)
5
+ if data.is_a?(Hash)
6
+ data.reduce({}) do |h, (k, v)|
7
+ h.merge(k.to_sym => symbolize_keys(v))
8
+ end
9
+ elsif data.is_a?(Array)
10
+ data.map { |d| symbolize_keys(d) }
11
+ else
12
+ data
13
+ end
14
+ end
15
+
16
+ module_function :symbolize_keys
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ # Version of MTCLI.
2
+ module MTCLI
3
+ VERSION = '0.0.1'.freeze
4
+ end
data/mtcli.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mtcli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'mtcli'
8
+ spec.version = MTCLI::VERSION
9
+ spec.authors = ['Masahiro Iuchi']
10
+ spec.email = ['masahiro.iuchi@gmail.com']
11
+
12
+ spec.summary = 'A command line client for MT Data API.'
13
+ spec.description = 'A command line client for Movable Type Data API.'
14
+ spec.homepage = 'https://github.com/masiuchi/mtcli'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_dependency 'thor', '~> 0.19'
24
+ spec.add_dependency 'mt-data_api-client', '~> 0'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.12'
27
+ spec.add_development_dependency 'rake', '~> 11.3'
28
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mtcli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Masahiro Iuchi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-04-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.19'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mt-data_api-client
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: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '11.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '11.3'
69
+ description: A command line client for Movable Type Data API.
70
+ email:
71
+ - masahiro.iuchi@gmail.com
72
+ executables:
73
+ - mtcli
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - README.md
80
+ - Rakefile
81
+ - bin/console
82
+ - bin/setup
83
+ - exe/mtcli
84
+ - lib/mtcli.rb
85
+ - lib/mtcli/cli.rb
86
+ - lib/mtcli/config.rb
87
+ - lib/mtcli/util.rb
88
+ - lib/mtcli/version.rb
89
+ - mtcli.gemspec
90
+ homepage: https://github.com/masiuchi/mtcli
91
+ licenses: []
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.6.8
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: A command line client for MT Data API.
113
+ test_files: []