gdsh 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ea4c9787d401d716741f4db5606ddc739b16a8f9
4
+ data.tar.gz: 3f7a0aada9445817f3c3efdaaba3e3ddc6425ed8
5
+ SHA512:
6
+ metadata.gz: 482ad86b93d60e9a832485aad59ccfd86043e60e366e594a086cab8350bcdfcbfe96b8ca714995ee570441a37753771890ef4c8b5e2650db9bfea90692cb325d
7
+ data.tar.gz: e0acf4d5cc78838575181a6b38164db73c165f150748f41fb30eb8b632dbeec54f1b2aa05dc430ebd1c54bce1f59f1c81d48ae3b93a129e2db1822e28d824239
@@ -0,0 +1,21 @@
1
+ auth.json
2
+ .session.yaml
3
+
4
+ # Bundle generated
5
+ *.gem
6
+ *.rbc
7
+ .bundle
8
+ .config
9
+ .yardoc
10
+ Gemfile.lock
11
+ installedfiles
12
+ _yardoc
13
+ coverage
14
+ doc/
15
+ lib/bundler/man
16
+ pkg
17
+ rdoc
18
+ spec/reports
19
+ test/tmp
20
+ test/version_tmp
21
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gdsh.gemspec
4
+ gemspec
5
+
6
+ # forked from JakobR's branch + patch
7
+ gem 'differ', git: 'git://github.com/emintham/differ'
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Emin Tham
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # gdsh [![Code Climate](https://codeclimate.com/github/emintham/gdsh.png)](https://codeclimate.com/github/emintham/gdsh)
2
+
3
+ A Google Drive shell in Ruby.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'gdsh'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install gdsh
18
+
19
+ ## Usage
20
+
21
+ (adapted from https://developers.google.com/drive/web/quickstart/quickstart-ruby)
22
+
23
+ 1. Set up a project in [Google](https://console.developers.google.com//start/api?id=drive&credential=client_key).
24
+ 2. Select the created project and select APIs & auth and make sure the status
25
+ is **ON** for the Drive API.
26
+ 3. In the sidebar on the left, select Credentials and set up new credentials
27
+ for this project.
28
+ 4. Download (as JSON) or save the client id and client secret.
29
+ 5. `bundle exec ruby gdsh.rb <credentials_json>` or `bundle exec ruby gdsh.rb`. In the former, credentials
30
+ will be automatically retrieved from JSON; in the latter, you will need to
31
+ copy and paste the `client_id` and `client_secret` from the credentials above.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,10 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require_relative '../lib/gdsh'
4
+
5
+ # if run as standalone script, launch shell
6
+ if __FILE__ == $PROGRAM_NAME
7
+ filename = ARGV.first if ARGV.length > 0
8
+ s = Gdsh::Gdsh.new(filename)
9
+ s.shell
10
+ end
@@ -0,0 +1,2 @@
1
+ hello
2
+ world
@@ -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 'gdsh/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'gdsh'
8
+ spec.version = Gdsh::VERSION
9
+ spec.authors = ['Emin Tham']
10
+ spec.email = ['emintham@gmail.com']
11
+ spec.summary = 'A Google Drive shell in Ruby.'
12
+ spec.description = ''
13
+ spec.homepage = 'https://github.com/emintham/gdsh'
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', '~> 1.5'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rspec'
24
+ spec.add_runtime_dependency 'google-api-client'
25
+ spec.add_runtime_dependency 'launchy'
26
+ spec.add_runtime_dependency 'differ'
27
+ spec.add_runtime_dependency 'colorize'
28
+ end
@@ -0,0 +1,61 @@
1
+ require 'google/api_client'
2
+ require 'launchy'
3
+ require 'json'
4
+
5
+ require_relative 'gdsh/version'
6
+ require_relative 'gdsh/drive'
7
+ require_relative 'gdsh/command_factory'
8
+
9
+ ##
10
+ # Implements a command interpreter to wrap Google Drive API.
11
+ #
12
+ module Gdsh
13
+ ##
14
+ # Gdsh Class
15
+ #
16
+ class Gdsh < DriveService
17
+ include CommandFactory
18
+
19
+ def puts_banner
20
+ puts ''
21
+ puts 'CLI tool to interface with Google Drive'.colorize(:green)
22
+ puts '======================================='.colorize(:green)
23
+ end
24
+
25
+ def puts_hint
26
+ puts 'Hint: type \'help\'.'.colorize(:green)
27
+ end
28
+
29
+ def clear_screen
30
+ system('clear') || system('cls')
31
+ end
32
+
33
+ def init_shell
34
+ puts_banner
35
+ authorize
36
+ clear_screen
37
+ puts_hint
38
+ end
39
+
40
+ def prints_prompt
41
+ print 'gdsh> '.colorize(:light_blue)
42
+ end
43
+
44
+ ##
45
+ # Command interpreter
46
+ #
47
+ def shell
48
+ init_shell
49
+
50
+ loop do
51
+ prints_prompt
52
+ params = parsed_inputs
53
+ command = next_command(params)
54
+ command.new(@client, params).execute
55
+ break if command.terminal?
56
+ end
57
+
58
+ write_session_info_to_file
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'commands'
2
+
3
+ module Commands
4
+ ##
5
+ # Clear screen.
6
+ #
7
+ class Clear < Command
8
+ def self.command_name
9
+ 'clear'
10
+ end
11
+
12
+ def self.function
13
+ 'Clears the screen.'
14
+ end
15
+
16
+ def execute
17
+ system('clear') || system('cls')
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'commands'
2
+ require_relative 'clear'
3
+ require_relative 'help'
4
+ require_relative 'list_files'
5
+ require_relative 'query_revision'
6
+ require_relative 'quit'
7
+ require_relative 'unrecognized'
8
+ require_relative 'upload_template'
9
+ require_relative 'get_file'
10
+ require_relative 'revision_diff'
11
+ require_relative 'remove'
12
+ require_relative 'share_read_only'
13
+ require_relative 'share_read_write'
14
+
15
+ ##
16
+ # Factory pattern to create the appropriate command.
17
+ #
18
+ module CommandFactory
19
+ include Commands
20
+
21
+ def parsed_inputs
22
+ # gets user input, defaulting to empty and removing newline
23
+ user_input = $stdin.gets || ''
24
+
25
+ # if command has parameters, split it up
26
+ user_input.chomp.split(/[\(,\),\,,\ ]/)
27
+ end
28
+
29
+ def next_command(params)
30
+ Commands.interpret(params[0])
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ require 'colorize'
2
+
3
+ ##
4
+ # Commands
5
+ #
6
+ module Commands
7
+ ##
8
+ # Command mixin
9
+ #
10
+ module CommandMixin
11
+ def execute
12
+ fail 'Method not implemented.'
13
+ end
14
+
15
+ def self.included(base)
16
+ base.extend(ClassMethods)
17
+ end
18
+
19
+ ##
20
+ # Every 'useful' Command class should override the following
21
+ # (except terminal?)
22
+ #
23
+ module ClassMethods
24
+ def command_name
25
+ ''
26
+ end
27
+
28
+ def function
29
+ ''
30
+ end
31
+
32
+ def parameters
33
+ ''
34
+ end
35
+
36
+ def description
37
+ (command_name + parameters + ":\n ").colorize(:green) +
38
+ function.colorize(:yellow)
39
+ end
40
+
41
+ def terminal?
42
+ false
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,53 @@
1
+ require 'google/api_client'
2
+ require 'json'
3
+ require 'colorize'
4
+
5
+ require_relative 'command_mixin'
6
+ require_relative 'error'
7
+
8
+ ##
9
+ # Commands
10
+ #
11
+ module Commands
12
+ ##
13
+ # Command with an initialized client object.
14
+ #
15
+ class Command
16
+ include CommandMixin
17
+ include DriveError
18
+
19
+ def initialize(client, params)
20
+ @client, @params = client, params
21
+ end
22
+ end
23
+
24
+ module_function
25
+
26
+ def commands
27
+ constants.select { |c| const_get(c).is_a? Class }
28
+ end
29
+
30
+ def puts_usage_header
31
+ puts 'Commands'.colorize(:green)
32
+ puts '--------'.colorize(:green)
33
+ end
34
+
35
+ def usage
36
+ puts_usage_header
37
+ commands.each do |c|
38
+ klass = const_get(c)
39
+ puts klass.description unless klass.command_name.empty?
40
+ end
41
+ end
42
+
43
+ def interpret(input)
44
+ return Quit if input.nil?
45
+
46
+ commands.each do |c|
47
+ klass = const_get(c)
48
+ return klass if input == klass.command_name
49
+ end
50
+
51
+ Unrecognized
52
+ end
53
+ end
@@ -0,0 +1,113 @@
1
+ require 'google/api_client'
2
+ require 'launchy'
3
+ require 'json'
4
+ require 'colorize'
5
+ require 'yaml'
6
+
7
+ ##
8
+ # DriveService module implements a service that interfaces with
9
+ # Google Drive using Google Drive API.
10
+ #
11
+ class DriveService
12
+ ##
13
+ # Creates a new Google Drive Shell object.
14
+ #
15
+ # @param [String] filename
16
+ # filename of json containing credentials downloaded from Google.
17
+ #
18
+ def initialize(filename = nil)
19
+ # default to per-file permissions
20
+ @oauth_scope = 'https://www.googleapis.com/auth/drive.file'
21
+ @redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
22
+ @filename = filename
23
+
24
+ if filename && File.exist?(filename)
25
+ credentials_from_file
26
+ else
27
+ credentials_from_stdin
28
+ end
29
+ end
30
+
31
+ def credentials_from_file
32
+ File.open(@filename, 'r') do |f|
33
+ buffer = f.read
34
+ credentials = JSON.parse(buffer)
35
+ @client_id = credentials['installed']['client_id']
36
+ @client_secret = credentials['installed']['client_secret']
37
+ end
38
+ end
39
+
40
+ def init_client
41
+ # Create a new API client & load the Google Drive API
42
+ @client = Google::APIClient.new
43
+
44
+ # Request authorization
45
+ @client.authorization.client_id = @client_id
46
+ @client.authorization.client_secret = @client_secret
47
+ @client.authorization.scope = @oauth_scope
48
+ @client.authorization.redirect_uri = @redirect_uri
49
+ end
50
+
51
+ def puts_refresh_error
52
+ puts 'Could not refresh token from saved session.'.colorize(:red)
53
+ end
54
+
55
+ def authorize
56
+ init_client
57
+
58
+ begin
59
+ authorize_from_refresh_token
60
+ rescue
61
+ puts_refresh_error
62
+ authorize_from_authorization_code
63
+ ensure
64
+ @client.authorization.fetch_access_token!
65
+ end
66
+ end
67
+
68
+ def authorize_from_refresh_token
69
+ fail StandardError unless File.exist?('.session.yaml')
70
+
71
+ f = File.open('.session.yaml', 'r')
72
+ session = YAML.load(f.read)
73
+ @client.authorization.grant_type = 'refresh_token'
74
+ @client.authorization.refresh_token = session.authorization.refresh_token
75
+ f.close
76
+ end
77
+
78
+ def authorize_from_authorization_code
79
+ uri = @client.authorization.authorization_uri
80
+ Launchy.open(uri)
81
+
82
+ # Exchange authorization code for access token
83
+ print 'Enter authorization code: '.colorize(:light_blue)
84
+ @client.authorization.code = $stdin.gets.chomp
85
+ end
86
+
87
+ ##
88
+ # Get credentials from shell if no credentials file was specified.
89
+ #
90
+ def credentials_from_stdin
91
+ # get preset if exists
92
+ @client_id ||= ''
93
+ @client_secret ||= ''
94
+
95
+ # Ask from user otherwise
96
+ if @client_id == ''
97
+ print 'Please enter your client id: '
98
+ @client_id = $stdin.gets.chomp
99
+ end
100
+
101
+ if @client_secret == ''
102
+ print 'Please enter your client secret: '
103
+ @client_secret = $stdin.gets.chomp
104
+ end
105
+ end
106
+
107
+ def write_session_info_to_file
108
+ return if @client.nil?
109
+ f = File.new('.session.yaml', 'w')
110
+ f.write(@client.to_yaml)
111
+ f.close
112
+ end
113
+ end