gistrb 0.1.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/.gitignore +8 -0
- data/.travis.yml +14 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +48 -0
- data/Rakefile +5 -0
- data/bin/console +14 -0
- data/bin/gistrb +70 -0
- data/bin/setup +8 -0
- data/gistrb.gemspec +27 -0
- data/lib/gist/clipboard.rb +10 -0
- data/lib/gist/helpers.rb +9 -0
- data/lib/gist/post.rb +55 -0
- data/lib/gist/user.rb +73 -0
- data/lib/gist/version.rb +3 -0
- data/lib/gist.rb +18 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a2aefb784623a1659b2bafd3eeeec8e050766df6
|
4
|
+
data.tar.gz: fb813f490cf60efb217ea2b3f46d439ac52b4daf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 98aca49aa436b184c517c61e5b7fdb8acffab6b900cbf279d7656e85696bf7ec7a6d2450547befeb8c63b1c04338a72fb585768a63df1975e202c1009414bdcf
|
7
|
+
data.tar.gz: 1fb6927724c4cdef4f360fed6139fa9909b3980bee60503123034eaae08d8d43d018c0b04bbab615292b107c003651615e610e904f9ed446be8b1920e7d04d6a
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.2
|
4
|
+
- jruby-19mode
|
5
|
+
- rbx-2
|
6
|
+
before_install: gem install bundler -v 1.15
|
7
|
+
deploy:
|
8
|
+
provider: rubygems
|
9
|
+
api_key:
|
10
|
+
secure: RmgCZqvJKcpDPrxNsJrivxChVcaPNaJfIpdWCPnhIR/uM8kkD3dXF+dOvtUOXsOn8uO2EbFOPYv8dEcQd3bQaNhgdOrPdg+Z47nf6LphKpDKemmUS2DskepJUG1q0lCHhG5V3v8XIDUdT78ZpyNGh9KQ5ineFVgOJ+oQuxUzkUc=
|
11
|
+
gem: gistrb
|
12
|
+
on:
|
13
|
+
tags: true
|
14
|
+
repo: cameronbroe/gistrb
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Cameron Roe
|
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
@@ -0,0 +1,48 @@
|
|
1
|
+
# gistrb - A command-line utility to post files directly as Gists on GitHub.com
|
2
|
+
### Description:
|
3
|
+
This is a utility to easily post local source files you have on GitHub Gists. It
|
4
|
+
supports uploading multi-file Gists, authenticated Gists, anonymous Gists, and
|
5
|
+
declaring the Gists as private or public. You can also attach descriptions to the Gist you post.
|
6
|
+
|
7
|
+
## Usage:
|
8
|
+
|
9
|
+
```shell
|
10
|
+
gistrb [opts] source_file source_file2 ...
|
11
|
+
```
|
12
|
+
|
13
|
+
`gistrb` also supports input from STDIN. If `gistrb` is invoked with no files and nothing piped in, then it will wait
|
14
|
+
on the terminal for input from STDIN until it reads an EOF character. An EOF character can be inserted on the terminal using Ctrl+D.
|
15
|
+
|
16
|
+
Any files in the Gist from STDIN will be labelled as "STDIN".
|
17
|
+
|
18
|
+
```shell
|
19
|
+
$ cat foo.txt | gistrb [opts] source_file # Reads foo.txt from piped STDIN and source_file as a file.
|
20
|
+
$ gistrb [opts] # Waits until it reads Ctrl+D and processes that data as STDIN
|
21
|
+
```
|
22
|
+
|
23
|
+
## Options:
|
24
|
+
Option | Description
|
25
|
+
-------------------------------------- | -----------
|
26
|
+
-u | --user | Post the Gist as currently signed in user
|
27
|
+
-s | --sign-in | Sign into the utility using your GitHub account
|
28
|
+
--sign-out | Sign out of the utility
|
29
|
+
-p | --public | Post the Gist as public (it posts as private by default)
|
30
|
+
-d [DESC] | --description [DESC] | Use [DESC] as the description for the Gist
|
31
|
+
-c | --clipboard | Automatically put the created Gist URL into your clipboard (beta)
|
32
|
+
|
33
|
+
## Installation:
|
34
|
+
Using RubyGems, simply run this command:
|
35
|
+
`gem install gistrb`
|
36
|
+
|
37
|
+
## Requirements:
|
38
|
+
If on Linux, you need to have xclip installed for clipboard support
|
39
|
+
|
40
|
+
To install this on Ubuntu-based distributions, run the following command.
|
41
|
+
```shell
|
42
|
+
sudo apt-get install xclip
|
43
|
+
```
|
44
|
+
|
45
|
+
## License
|
46
|
+
MIT License
|
47
|
+
|
48
|
+
Copyright © 2017 Cameron Roe
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'gist'
|
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(__FILE__)
|
data/bin/gistrb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.expand_path('../../lib/gist', __FILE__) # Require the Gist library files
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
options = {}
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.banner = 'Usage: gist [options] files'
|
8
|
+
opts.on('-u', '--user', 'Post as user') do |u|
|
9
|
+
options[:user] = u
|
10
|
+
end
|
11
|
+
|
12
|
+
opts.on('-s', '--sign-in', 'Sign in as user') do |s|
|
13
|
+
options[:sign_in] = s
|
14
|
+
end
|
15
|
+
|
16
|
+
opts.on('--sign-out', 'Clear out saved user') do |s|
|
17
|
+
options[:sign_out] = s
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-p', '--public', 'Make the gist public') do |p|
|
21
|
+
options[:public] = p
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-d [DESC]', '--description [DESC]', String, 'Description of the gist') do |d|
|
25
|
+
options[:description] = d
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on('-c', '--clipboard', 'Save the gist URL to clipboard') do |c|
|
29
|
+
options[:clipboard] = c
|
30
|
+
end
|
31
|
+
end.parse!
|
32
|
+
|
33
|
+
# Copy ARGV into another array then clear it, to make gets behave properly
|
34
|
+
files = ARGV.clone
|
35
|
+
ARGV.clear
|
36
|
+
|
37
|
+
# Get anything sent by STDIN to support cat and pasting.
|
38
|
+
if !STDIN.tty? || files.empty? then
|
39
|
+
stdin = STDIN.read
|
40
|
+
end
|
41
|
+
|
42
|
+
if options[:sign_out]
|
43
|
+
File.delete(Gist::ACCESS_TOKEN_PATH) if File.exist?(Gist::ACCESS_TOKEN_PATH)
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
|
47
|
+
if options[:sign_in]
|
48
|
+
print 'Username: '
|
49
|
+
username = gets.chomp
|
50
|
+
password = Gist::Helpers.get_password
|
51
|
+
@user = Gist::User.new(username, password)
|
52
|
+
@user.authenticate
|
53
|
+
end
|
54
|
+
|
55
|
+
if options[:user]
|
56
|
+
@user = Gist::User.new
|
57
|
+
@user.authenticate
|
58
|
+
unless @user.access_token
|
59
|
+
STDERR.puts 'ERROR: There is no user saved. You need to sign in.'
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
post = Gist::Post.new(files, options[:public], options[:description], @user)
|
63
|
+
else
|
64
|
+
post = Gist::Post.new(files, options[:public], options[:description])
|
65
|
+
end
|
66
|
+
gist_url = post.submit(stdin)
|
67
|
+
|
68
|
+
Clipboard.copy(gist_url) if options[:clipboard]
|
69
|
+
|
70
|
+
puts gist_url
|
data/bin/setup
ADDED
data/gistrb.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'gist/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'gistrb'
|
7
|
+
spec.version = Gist::VERSION
|
8
|
+
spec.authors = ['Cameron Roe']
|
9
|
+
spec.email = ['cameron@cameronbroe.com']
|
10
|
+
spec.licenses = ['MIT']
|
11
|
+
|
12
|
+
spec.summary = 'A command-line utility to manage GitHub Gists'
|
13
|
+
spec.homepage = 'https://github.com/cameronbroe/gistrb'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = 'bin'
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
23
|
+
spec.add_development_dependency 'rubocop', '~> 0.51'
|
24
|
+
spec.add_dependency 'clipboard', '~> 1.1'
|
25
|
+
spec.add_dependency 'ffi', '~> 1.9.18' if RUBY_PLATFORM =~ /win32/i
|
26
|
+
spec.add_dependency 'highline', '~> 1.7'
|
27
|
+
end
|
data/lib/gist/helpers.rb
ADDED
data/lib/gist/post.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Gist
|
2
|
+
# Class that controls a posted Gist
|
3
|
+
class Post
|
4
|
+
attr_accessor :source_files
|
5
|
+
attr_accessor :user
|
6
|
+
|
7
|
+
def initialize(filenames, pub = false, description = nil, user = nil)
|
8
|
+
@user ||= user
|
9
|
+
@public ||= pub
|
10
|
+
@description ||= description ? description : ''
|
11
|
+
@source_files ||= {}
|
12
|
+
populate_source_files(filenames)
|
13
|
+
@http = Net::HTTP.new(Gist::API_URL, Gist::API_PORT)
|
14
|
+
@http.use_ssl = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def submit(stdin)
|
18
|
+
unless stdin.nil? then
|
19
|
+
@source_files['STDIN'] = {
|
20
|
+
'content' => stdin
|
21
|
+
}
|
22
|
+
end
|
23
|
+
body = {
|
24
|
+
'files' => @source_files,
|
25
|
+
'public' => @public,
|
26
|
+
'description' => @description
|
27
|
+
}.to_json
|
28
|
+
headers ||= {}
|
29
|
+
unless @user.nil?
|
30
|
+
headers['Authorization'] = "token #{@user.access_token}"
|
31
|
+
end
|
32
|
+
response = @http.post('/gists', body, headers)
|
33
|
+
JSON.parse(response.body)['html_url']
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def load_code(filename)
|
39
|
+
file = File.open(filename)
|
40
|
+
file_str = ''
|
41
|
+
file.each do |line|
|
42
|
+
file_str << line
|
43
|
+
end
|
44
|
+
file_str
|
45
|
+
end
|
46
|
+
|
47
|
+
private def populate_source_files(filenames)
|
48
|
+
filenames.each do |filename|
|
49
|
+
@source_files[File.basename(filename)] = {
|
50
|
+
'content' => load_code(filename)
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/gist/user.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
module Gist
|
2
|
+
# Class to hold user information
|
3
|
+
class User
|
4
|
+
attr_accessor :username
|
5
|
+
attr_accessor :password
|
6
|
+
attr_accessor :access_token # Personal access token
|
7
|
+
|
8
|
+
# Create the GistUser instance
|
9
|
+
def initialize(username = nil, password = nil)
|
10
|
+
@username = username
|
11
|
+
@password = password
|
12
|
+
@http = Net::HTTP.new(Gist::API_URL, Gist::API_PORT)
|
13
|
+
@http.use_ssl = true
|
14
|
+
@access_token = load_token if saved?
|
15
|
+
end
|
16
|
+
|
17
|
+
# Authentication method, will set the authentication token for the user
|
18
|
+
def authenticate
|
19
|
+
# If we already have authenticated, don't let it happen again
|
20
|
+
return unless @access_token.nil?
|
21
|
+
# If not, let's authenticate
|
22
|
+
@http.start do |http|
|
23
|
+
response = http.request(auth_obj)
|
24
|
+
json_response = JSON.parse(response.body)
|
25
|
+
@access_token = json_response['token']
|
26
|
+
end
|
27
|
+
# Then save
|
28
|
+
save
|
29
|
+
populate_methods(user_info)
|
30
|
+
end
|
31
|
+
|
32
|
+
private def user_info
|
33
|
+
headers = { 'Authorization' => "token #{access_token}" }
|
34
|
+
response = @http.get('/user', headers)
|
35
|
+
JSON.parse(response.body)
|
36
|
+
end
|
37
|
+
|
38
|
+
private def populate_methods(response)
|
39
|
+
response.each do |k, v|
|
40
|
+
define_singleton_method(k) { v }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private def saved?
|
45
|
+
File.exist?(Gist::ACCESS_TOKEN_PATH)
|
46
|
+
end
|
47
|
+
|
48
|
+
private def save
|
49
|
+
unless Dir.exist?(File.dirname(Gist::ACCESS_TOKEN_PATH))
|
50
|
+
Dir.mkdir(File.dirname(Gist::ACCESS_TOKEN_PATH))
|
51
|
+
end
|
52
|
+
token_file = File.new(Gist::ACCESS_TOKEN_PATH, 'w+')
|
53
|
+
token_file << @access_token
|
54
|
+
token_file.close
|
55
|
+
end
|
56
|
+
|
57
|
+
private def load_token
|
58
|
+
File.readlines(Gist::ACCESS_TOKEN_PATH).first
|
59
|
+
end
|
60
|
+
|
61
|
+
private def auth_obj
|
62
|
+
req = Net::HTTP::Post.new('/authorizations')
|
63
|
+
req.basic_auth(@username, @password)
|
64
|
+
req['Content-Type'] = 'application/json'
|
65
|
+
req.body = {
|
66
|
+
scopes: ['gist'], # Only need Gist scope
|
67
|
+
note: 'Gist access for GistRB client',
|
68
|
+
note_url: 'https://github.com/cameronbroe/gistrb'
|
69
|
+
}.to_json
|
70
|
+
req
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/gist/version.rb
ADDED
data/lib/gist.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'highline/import'
|
3
|
+
require 'json'
|
4
|
+
require 'clipboard'
|
5
|
+
|
6
|
+
# Library requires
|
7
|
+
require 'gist/user'
|
8
|
+
require 'gist/post'
|
9
|
+
require 'gist/helpers'
|
10
|
+
require 'gist/clipboard'
|
11
|
+
|
12
|
+
module Gist
|
13
|
+
# Module level constants
|
14
|
+
API_URL = 'api.github.com'.freeze
|
15
|
+
API_PORT = 443
|
16
|
+
|
17
|
+
ACCESS_TOKEN_PATH = "#{Dir.home}/.gistrb/access_token".freeze
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gistrb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cameron Roe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-16 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: '1.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.51'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.51'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: clipboard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: highline
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.7'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.7'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- cameron@cameronbroe.com
|
72
|
+
executables:
|
73
|
+
- console
|
74
|
+
- gistrb
|
75
|
+
- setup
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- ".gitignore"
|
80
|
+
- ".travis.yml"
|
81
|
+
- Gemfile
|
82
|
+
- LICENSE
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- bin/console
|
86
|
+
- bin/gistrb
|
87
|
+
- bin/setup
|
88
|
+
- gistrb.gemspec
|
89
|
+
- lib/gist.rb
|
90
|
+
- lib/gist/clipboard.rb
|
91
|
+
- lib/gist/helpers.rb
|
92
|
+
- lib/gist/post.rb
|
93
|
+
- lib/gist/user.rb
|
94
|
+
- lib/gist/version.rb
|
95
|
+
homepage: https://github.com/cameronbroe/gistrb
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.6.10
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: A command-line utility to manage GitHub Gists
|
119
|
+
test_files: []
|