ruby-bepasty-client 1.0.0
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 +7 -0
- data/.editorconfig +11 -0
- data/.gitignore +9 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +21 -0
- data/README.md +5 -0
- data/Rakefile +17 -0
- data/bin/bepastyrb +4 -0
- data/lib/bepasty-client/cli.rb +162 -0
- data/lib/bepasty-client/client.rb +131 -0
- data/lib/bepasty-client/version.rb +3 -0
- data/lib/bepasty-client.rb +4 -0
- data/man/man1/bepastyrb.1.md +83 -0
- data/ruby-bepasty-client.gemspec +24 -0
- data/shell.nix +21 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e832e4200ea4decc2a800db7a43ad8deb8c0049000c29c0cb45679e9f62698d8
|
4
|
+
data.tar.gz: 1e0bcf99dc68452e83d4daec6913190dae4ecb715046c10318ffbee4c61600e9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3ea2c4da75e919b9a353b2084b5558f8916fc99b070ba9d904fabd4f39fdec682a783f78831b48dff83d10fdf56d82486818d9aa29ae6c78d6a7f0db3cb1ca1b
|
7
|
+
data.tar.gz: ae41da0e6fb739c7aec2b04fc848f3e64583495acb4051ffa7458719f4c03703a2bb3d4554d139037a231cefacd04d5bc8005e3dfcf9444417d460f80ed720e2
|
data/.editorconfig
ADDED
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2023 Jakub Skokan
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'md2man/rakefile'
|
3
|
+
require 'md2man/roff/engine'
|
4
|
+
require 'md2man/html/engine'
|
5
|
+
|
6
|
+
# Override markdown engine to add extra parameter
|
7
|
+
[Md2Man::Roff, Md2Man::HTML].each do |mod|
|
8
|
+
mod.send(:remove_const, :ENGINE)
|
9
|
+
mod.send(:const_set, :ENGINE, Redcarpet::Markdown.new(mod.const_get(:Engine),
|
10
|
+
tables: true,
|
11
|
+
autolink: true,
|
12
|
+
superscript: true,
|
13
|
+
strikethrough: true,
|
14
|
+
no_intra_emphasis: false,
|
15
|
+
fenced_code_blocks: true,
|
16
|
+
))
|
17
|
+
end
|
data/bin/bepastyrb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module BepastyClient
|
5
|
+
class Cli
|
6
|
+
def self.run
|
7
|
+
cli = new
|
8
|
+
cli.run
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
parse
|
13
|
+
load_config
|
14
|
+
|
15
|
+
if @server.nil?
|
16
|
+
warn 'Specify server URL using option --server or via config file'
|
17
|
+
exit(false)
|
18
|
+
end
|
19
|
+
|
20
|
+
client = Client.new(@server, password: @password, verbose: @verbose)
|
21
|
+
client.setup
|
22
|
+
|
23
|
+
if @files.empty?
|
24
|
+
puts client.upload_io(STDIN, **@upload_opts)
|
25
|
+
else
|
26
|
+
@files.each do |path|
|
27
|
+
file_loc = File.open(path, 'r') do |f|
|
28
|
+
client.upload_io(f, **@upload_opts)
|
29
|
+
end
|
30
|
+
|
31
|
+
if @files.length > 1
|
32
|
+
puts "#{path}: #{file_loc}"
|
33
|
+
else
|
34
|
+
puts file_loc
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
rescue Error => e
|
40
|
+
warn "Error occurred: #{e.message}"
|
41
|
+
exit(false)
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
def parse
|
46
|
+
@upload_opts = {}
|
47
|
+
|
48
|
+
OptionParser.new do |parser|
|
49
|
+
parser.banner = "Usage: #{$0} [options] FILE..."
|
50
|
+
|
51
|
+
parser.on('-h', '--help', 'Show help message and exit') do |v|
|
52
|
+
puts parser
|
53
|
+
exit
|
54
|
+
end
|
55
|
+
|
56
|
+
parser.on('-v', '--verbose', 'Enable verbose output') do |v|
|
57
|
+
@verbose = true
|
58
|
+
end
|
59
|
+
|
60
|
+
parser.on('-s', '--server=SERVER', 'bepasty server URL') do |v|
|
61
|
+
@server = v
|
62
|
+
end
|
63
|
+
|
64
|
+
parser.on('-p', '--password=PASSWORD', 'bepasty server password') do |v|
|
65
|
+
@password = v
|
66
|
+
end
|
67
|
+
|
68
|
+
parser.on('--password-file=FILE', 'Read bepasty server password from a file') do |v|
|
69
|
+
@password = File.read(v).strip
|
70
|
+
end
|
71
|
+
|
72
|
+
parser.on('-f', '--filename=NAME', 'File name including extension') do |v|
|
73
|
+
@upload_opts[:filename] = v
|
74
|
+
end
|
75
|
+
|
76
|
+
parser.on('-t', '--content-type=TYPE', 'Content mime type') do |v|
|
77
|
+
@upload_opts[:content_type] = v
|
78
|
+
end
|
79
|
+
|
80
|
+
parser.on(
|
81
|
+
'--minute=[N]',
|
82
|
+
OptionParser::DecimalInteger,
|
83
|
+
'Keep the file for N minutes, defaults to 30 minutes',
|
84
|
+
) do |v|
|
85
|
+
@upload_opts[:max_life] = {unit: :minutes, value: v || 30}
|
86
|
+
end
|
87
|
+
|
88
|
+
parser.on(
|
89
|
+
'--hour=[N]',
|
90
|
+
OptionParser::DecimalInteger,
|
91
|
+
'Keep the file for N hours, defaults to 1 hour',
|
92
|
+
) do |v|
|
93
|
+
@upload_opts[:max_life] = {unit: :hours, value: v || 1}
|
94
|
+
end
|
95
|
+
|
96
|
+
parser.on(
|
97
|
+
'--day=[N]',
|
98
|
+
OptionParser::DecimalInteger,
|
99
|
+
'Keep the file for N days, defaults to 1 day',
|
100
|
+
) do |v|
|
101
|
+
@upload_opts[:max_life] = {unit: :days, value: v || 1}
|
102
|
+
end
|
103
|
+
|
104
|
+
parser.on(
|
105
|
+
'--week=[N]',
|
106
|
+
OptionParser::DecimalInteger,
|
107
|
+
'Keep the file for N weeks, defaults to 1 week',
|
108
|
+
) do |v|
|
109
|
+
@upload_opts[:max_life] = {unit: :weeks, value: v || 1}
|
110
|
+
end
|
111
|
+
|
112
|
+
parser.on(
|
113
|
+
'--month=[N]',
|
114
|
+
OptionParser::DecimalInteger,
|
115
|
+
'Keep the file for N months, defaults to 1 month',
|
116
|
+
) do |v|
|
117
|
+
@upload_opts[:max_life] = {unit: :months, value: v || 1}
|
118
|
+
end
|
119
|
+
|
120
|
+
parser.on(
|
121
|
+
'--forever',
|
122
|
+
'Keep the file as long as possible',
|
123
|
+
) do |v|
|
124
|
+
@upload_opts[:max_life] = {unit: :forever, value: 1}
|
125
|
+
end
|
126
|
+
end.parse!
|
127
|
+
|
128
|
+
@files = ARGV.empty? ? [] : ARGV
|
129
|
+
end
|
130
|
+
|
131
|
+
def load_config
|
132
|
+
cfg = load_config_file('/etc/bepastyrb.yml')
|
133
|
+
|
134
|
+
conf_dir = ENV.fetch('XDG_CONFIG_HOME', '')
|
135
|
+
conf_dir = File.join(Dir.home, '.config') if conf_dir.empty?
|
136
|
+
|
137
|
+
cfg.update(load_config_file(File.join(conf_dir, 'bepastyrb.yml')))
|
138
|
+
|
139
|
+
@verbose = true if cfg[:verbose]
|
140
|
+
@server ||= cfg[:server]
|
141
|
+
@password ||= cfg[:password]
|
142
|
+
@max_life ||= cfg[:max_life]
|
143
|
+
end
|
144
|
+
|
145
|
+
def load_config_file(path)
|
146
|
+
cfg = YAML.load_file(path)
|
147
|
+
puts "Reading config at #{path}" if @verbose
|
148
|
+
|
149
|
+
{
|
150
|
+
verbose: cfg.fetch('verbose', false),
|
151
|
+
server: cfg['server'],
|
152
|
+
password: cfg['password_file'] ? File.read(cfg['password_file']).strip : cfg['password'],
|
153
|
+
max_life: {
|
154
|
+
unit: cfg.fetch('max_life', {}).fetch('unit', 'days').to_sym,
|
155
|
+
value: cfg.fetch('max_life', {}).fetch('value', 1),
|
156
|
+
},
|
157
|
+
}
|
158
|
+
rescue Errno::ENOENT
|
159
|
+
{}
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
module BepastyClient
|
7
|
+
class Error < StandardError ; end
|
8
|
+
|
9
|
+
class Client
|
10
|
+
BODY_SIZE = 128*1024
|
11
|
+
|
12
|
+
# @param server [String] bepasty server URL
|
13
|
+
# @param password [String, nil]
|
14
|
+
# @param verbose [Boolean]
|
15
|
+
def initialize(server, password: nil, verbose: false)
|
16
|
+
@server = server
|
17
|
+
@password = password
|
18
|
+
@verbose = verbose
|
19
|
+
end
|
20
|
+
|
21
|
+
# Fetch server settings
|
22
|
+
def setup
|
23
|
+
http_start('/apis/rest') do |uri, http|
|
24
|
+
res = http.get(uri)
|
25
|
+
|
26
|
+
case res
|
27
|
+
when Net::HTTPSuccess
|
28
|
+
settings = JSON.parse(res.body)
|
29
|
+
|
30
|
+
@max_file_size = settings['MAX_ALLOWED_FILE_SIZE']
|
31
|
+
@max_body_size = settings.fetch('MAX_BODY_SIZE', BODY_SIZE)
|
32
|
+
|
33
|
+
if @verbose
|
34
|
+
puts "Max file size = #{@max_file_size}"
|
35
|
+
puts "Max body size = #{@max_body_size}"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
raise Error, "Failed to query server settings: HTTP #{res.code}, #{res.message}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Upload file
|
44
|
+
# @param io [IO]
|
45
|
+
# @param filename [String, nil]
|
46
|
+
# @param content_type [String, nil]
|
47
|
+
# @param max_life [Hash, nil]
|
48
|
+
# @raise [Error]
|
49
|
+
# @return [String] file URL
|
50
|
+
def upload_io(io, filename: nil, content_type: nil, max_life: nil)
|
51
|
+
if filename.nil? && io.respond_to?(:path)
|
52
|
+
filename = File.basename(io.path)
|
53
|
+
end
|
54
|
+
|
55
|
+
max_life ||= {unit: :days, value: 1}
|
56
|
+
|
57
|
+
sent_bytes = 0
|
58
|
+
transaction_id = nil
|
59
|
+
file_location = nil
|
60
|
+
|
61
|
+
if io.respond_to?(:size)
|
62
|
+
send_io = io
|
63
|
+
else
|
64
|
+
send_io = StringIO.new(io.read)
|
65
|
+
end
|
66
|
+
|
67
|
+
if @max_file_size && send_io.size > @max_file_size
|
68
|
+
raise Error, "File size #{send_io.size} exceeds server max file size of #{@max_file_size} bytes"
|
69
|
+
end
|
70
|
+
|
71
|
+
http_start('/apis/rest/items') do |uri, http|
|
72
|
+
until send_io.eof?
|
73
|
+
chunk = send_io.read(@max_body_size)
|
74
|
+
|
75
|
+
req = Net::HTTP::Post.new(uri)
|
76
|
+
req.basic_auth('bepasty', @password) if @password
|
77
|
+
req['Content-Range'] = "bytes #{sent_bytes}-#{sent_bytes + chunk.size - 1}/#{send_io.size}"
|
78
|
+
req['Transaction-ID'] = transaction_id if transaction_id
|
79
|
+
req['Content-Type'] = content_type || ''
|
80
|
+
req['Content-Filename'] = filename || ''
|
81
|
+
req['Content-Length'] = send_io.size
|
82
|
+
req['Maxlife-Unit'] = max_life[:unit].to_s.upcase
|
83
|
+
req['Maxlife-Value'] = max_life[:value]
|
84
|
+
|
85
|
+
req.body = Base64.encode64(chunk)
|
86
|
+
|
87
|
+
if @verbose
|
88
|
+
puts "Uploading chunk, Content-Range=#{req['Content-Range']}, Transaction-ID=#{transaction_id}"
|
89
|
+
end
|
90
|
+
|
91
|
+
res = http.request(req)
|
92
|
+
|
93
|
+
case res
|
94
|
+
when Net::HTTPSuccess
|
95
|
+
if transaction_id.nil? && res['Transaction-ID']
|
96
|
+
transaction_id = res['Transaction-ID']
|
97
|
+
end
|
98
|
+
|
99
|
+
file_location = res['Content-Location'] if res['Content-Location']
|
100
|
+
else
|
101
|
+
if res['Content-Type'] == 'application/json'
|
102
|
+
err = JSON.parse(res.body)['error']
|
103
|
+
raise Error, "bepasty error: code=#{err['code']}, message=#{err['message']}"
|
104
|
+
else
|
105
|
+
raise Error, "HTTP #{res.code}: #{res.message}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
sent_bytes += chunk.size
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
if file_location.nil?
|
114
|
+
raise Error, 'Server did not disclose file location'
|
115
|
+
end
|
116
|
+
|
117
|
+
# bepasty returns REST item URL, we want web URL instead
|
118
|
+
File.join(@server, file_location.split('/').last)
|
119
|
+
end
|
120
|
+
|
121
|
+
protected
|
122
|
+
def http_start(path)
|
123
|
+
uri = URI(File.join(@server, path))
|
124
|
+
args = [uri.hostname, uri.port] + Array.new(5, nil) + [{use_ssl: uri.scheme == 'https'}]
|
125
|
+
|
126
|
+
Net::HTTP.start(*args) do |http|
|
127
|
+
yield(uri, http)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# bepastyrb 8 2023-05-14 1.0.0
|
2
|
+
|
3
|
+
## NAME
|
4
|
+
`bepastyrb` - upload files to bepasty servers
|
5
|
+
|
6
|
+
## SYNOPSIS
|
7
|
+
`bepastyrb` [*options*] [*file*...]
|
8
|
+
|
9
|
+
## DESCRIPTION
|
10
|
+
`bepastyrb` uploads one or more files to bepasty servers. If no *file* is given
|
11
|
+
as an argument, `bepastyrb` will read from standard input.
|
12
|
+
|
13
|
+
bepasty server URL needs to be given using option `-s`, `--server` or can be
|
14
|
+
set in a config file, see `CONFIG FILES`.
|
15
|
+
|
16
|
+
If no life time is set, it defaults to one day.
|
17
|
+
|
18
|
+
## OPTIONS
|
19
|
+
`-v`, `--verbose`
|
20
|
+
Enable verbose output.
|
21
|
+
|
22
|
+
`-s`, `--server`=*SERVER*
|
23
|
+
bepasty server URL.
|
24
|
+
|
25
|
+
`-p`, `--password`=*PASSWORD*
|
26
|
+
bepasty server password.
|
27
|
+
|
28
|
+
`--password-file`=*FILE*
|
29
|
+
Read bepasty server password from a file.
|
30
|
+
|
31
|
+
`-f`, `--filename`=*NAME*
|
32
|
+
File name including extension. Can be used to provide name for files read
|
33
|
+
from standard input or to override given file name.
|
34
|
+
|
35
|
+
`-t`, `--content-type`=*TYPE*
|
36
|
+
Content mime type. If not given, the mime type is guessed by the bepasty server
|
37
|
+
based on file name.
|
38
|
+
|
39
|
+
`--minute`=[*N*]
|
40
|
+
Keep the file for *N* minutes, defaults to 30 minutes.
|
41
|
+
|
42
|
+
`--hour`=[*N*]
|
43
|
+
Keep the file for *N* hours, defaults to 1 hour.
|
44
|
+
|
45
|
+
`--day`=[*N*]
|
46
|
+
Keep the file for *N* days, defaults to 1 day.
|
47
|
+
|
48
|
+
`--week`=[*N*]
|
49
|
+
Keep the file for *N* weeks, defaults to 1 week.
|
50
|
+
|
51
|
+
`--month`=[*N*]
|
52
|
+
Keep the file for *N* months, defaults to 1 month.
|
53
|
+
|
54
|
+
`--forever`
|
55
|
+
Keep the file as long as possible.
|
56
|
+
|
57
|
+
## CONFIG FILES
|
58
|
+
Config files can be used to provide default values for certain options.
|
59
|
+
Command-line options override settings found in config files. Config files are
|
60
|
+
read from the following locations:
|
61
|
+
|
62
|
+
- `/etc/bepastyrb.yml`
|
63
|
+
- `$XDG_CONFIG_HOME/bepastyrb.yml` or `~/.config/bepastyrb.yml`
|
64
|
+
|
65
|
+
Settings from user's config will override settings in `/etc`.
|
66
|
+
|
67
|
+
Example configuration:
|
68
|
+
|
69
|
+
```
|
70
|
+
# bepasty config file in YAML
|
71
|
+
server: https://bepasty.yourserver.tld
|
72
|
+
# password: optional password if the server uses it
|
73
|
+
# password_file: read password from a file
|
74
|
+
# max_life:
|
75
|
+
# unit: minutes|hours|days|weeks|months|forever
|
76
|
+
# value: 14
|
77
|
+
```
|
78
|
+
|
79
|
+
## SEE ALSO
|
80
|
+
bepasty server: https://bepasty-server.readthedocs.org/
|
81
|
+
|
82
|
+
## BUGS
|
83
|
+
Report bugs to https://github.com/aither64/ruby-bepasty-client.
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bepasty-client/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'ruby-bepasty-client'
|
8
|
+
spec.version = BepastyClient::VERSION
|
9
|
+
spec.authors = ['Jakub Skokan']
|
10
|
+
spec.email = ['jakub.skokan@vpsfree.cz']
|
11
|
+
spec.summary =
|
12
|
+
spec.description = 'Ruby client and CLI for bepasty'
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler'
|
22
|
+
spec.add_development_dependency 'md2man'
|
23
|
+
spec.add_development_dependency 'rake'
|
24
|
+
end
|
data/shell.nix
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
let
|
2
|
+
pkgs = import <nixpkgs> {};
|
3
|
+
stdenv = pkgs.stdenv;
|
4
|
+
|
5
|
+
in stdenv.mkDerivation rec {
|
6
|
+
name = "ruby-bepasty-client";
|
7
|
+
|
8
|
+
buildInputs = with pkgs;[
|
9
|
+
ruby
|
10
|
+
git
|
11
|
+
openssl
|
12
|
+
];
|
13
|
+
|
14
|
+
shellHook = ''
|
15
|
+
export GEM_HOME=$(pwd)/.gems
|
16
|
+
export PATH="$GEM_HOME/bin:$PATH"
|
17
|
+
export MANPATH="$(pwd)/man:$(man --path)"
|
18
|
+
gem install bundler
|
19
|
+
bundle install
|
20
|
+
'';
|
21
|
+
}
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-bepasty-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jakub Skokan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 1980-01-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: md2man
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Ruby client and CLI for bepasty
|
56
|
+
email:
|
57
|
+
- jakub.skokan@vpsfree.cz
|
58
|
+
executables:
|
59
|
+
- bepastyrb
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".editorconfig"
|
64
|
+
- ".gitignore"
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- bin/bepastyrb
|
70
|
+
- lib/bepasty-client.rb
|
71
|
+
- lib/bepasty-client/cli.rb
|
72
|
+
- lib/bepasty-client/client.rb
|
73
|
+
- lib/bepasty-client/version.rb
|
74
|
+
- man/man1/bepastyrb.1.md
|
75
|
+
- ruby-bepasty-client.gemspec
|
76
|
+
- shell.nix
|
77
|
+
homepage: ''
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubygems_version: 3.3.20
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: Ruby client and CLI for bepasty
|
100
|
+
test_files: []
|