lionel_richie 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -49,6 +49,55 @@ You should now be ready to run the export:
49
49
 
50
50
  $ lionel
51
51
 
52
+ ## Crafting the Export
53
+
54
+ ```ruby
55
+
56
+ LionelRichie.export do
57
+ # Card Id
58
+ b { id }
59
+
60
+ # Card Link
61
+ c { link }
62
+
63
+ # Ready date
64
+ d do
65
+ ready_action = card.first_action do |a|
66
+ (a.create? && a.board_id == trello_board_id) || a.moved_to?("Ready")
67
+ end
68
+ format_date(ready_action.date) if ready_action
69
+ end
70
+
71
+ # In Progress date
72
+ e { date_moved_to("In Progress") }
73
+
74
+ # Code Review date
75
+ f { date_moved_to("Code Review") }
76
+
77
+ # Review date
78
+ g { date_moved_to("Review") }
79
+
80
+ # Deploy date
81
+ h { date_moved_to("Deploy") }
82
+
83
+ # Completed date
84
+ i { date_moved_to("Completed") }
85
+
86
+ # Type
87
+ j { type }
88
+
89
+ # Project
90
+ k { project }
91
+
92
+ # Estimate
93
+ l { estimate }
94
+
95
+ # Due Date
96
+ m { due_date }
97
+ end
98
+ ```
99
+
100
+
52
101
  ## Contributing
53
102
 
54
103
  1. Fork it
data/bin/lionel CHANGED
@@ -1,109 +1,43 @@
1
1
  #! /usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
3
+ # Trap interrupts to quit cleanly. See
4
+ # https://twitter.com/mitchellh/status/283014103189053442
5
+ Signal.trap("INT") { exit 1 }
4
6
 
5
7
  require 'lionel_richie'
6
8
 
7
- Trello.configure do |c|
8
- c.developer_public_key = ENV['TRELLO_KEY']
9
- c.member_token = ENV['TRELLO_TOKEN']
9
+ # Output message to $stderr, prefixed with the program name
10
+ def pute(*args)
11
+ first = args.shift.dup
12
+ first.insert(0, "#{$0}: ")
13
+ args.unshift(first)
14
+ $stderr.puts(*args)
10
15
  end
11
16
 
12
- board_id = ENV['TRELLO_BOARD_ID']
13
- board = Trello::Board.find(board_id)
14
-
15
- cards = []
16
- board.lists.each do |list|
17
- list.cards.each do |card|
18
- cards << card
19
- end
20
- end
21
-
22
- session = GoogleDrive.login_with_oauth(ENV['GOOGLE_TOKEN'])
23
-
24
- sp = session.spreadsheet_by_key(ENV['GOOGLE_DOC_ID'])
25
- ws = sp.worksheets[0]
26
-
27
- start_row = 2
28
- rows = ws.rows.size
29
-
30
- card_ids = cards.map(&:id)
31
-
32
- def sync_row(ws, row, card)
33
- puts "syncing row[#{row}] with #{card.name}"
34
- ws["B#{row}"] = card.id
35
-
36
- # Card link
37
- ws["C#{row}"] = %Q[=HYPERLINK("#{card.url}", "#{card.name.gsub(/"/, "")}")]
38
-
39
- actions = card.actions
40
- actions = actions.select { |a| a.data["listBefore"].present? }
41
-
42
- # Ready date
43
- ws["D#{row}"] = action_date(actions) do |a|
44
- (a.type == "createCard" && a.data["board"]["id"] == board_id) ||
45
- a.data["listAfter"]["name"] =~ /ready/i
17
+ begin
18
+ Lionel::CLI.start(ARGV)
19
+
20
+ rescue GoogleDrive::Error, GoogleDrive::AuthenticationError => e
21
+ @attempts ||= 0
22
+ @attempts += 1
23
+ Lionel::GoogleAuthentication.new.refresh
24
+ if @attempts < 2
25
+ retry
26
+ else
27
+ puts e.class
28
+ puts "-" * e.class.name.size
29
+ pute e.message
30
+ puts "Unable to access Google Drive"
31
+ puts "run 'lionel authorize'"
46
32
  end
47
33
 
48
- # In Progress date
49
- ws["E#{row}"] = action_date(actions) { |a| a.data["listAfter"]["name"] =~ /^in progress/i }
50
-
51
- # Code Review date
52
- ws["F#{row}"] = action_date(actions) { |a| a.data["listAfter"]["name"] =~ /^code review/i }
53
-
54
- # Review date
55
- ws["G#{row}"] = action_date(actions) { |a| a.data["listAfter"]["name"] =~ /^review/i }
56
-
57
- # Deploy date
58
- ws["H#{row}"] = action_date(actions) { |a| a.data["listAfter"]["name"] =~ /^deploy/i }
34
+ rescue Trello::Error, Trello::InvalidAccessToken => e
35
+ puts "Unable to access Trello"
36
+ puts "run 'lionel authorize'"
59
37
 
60
- # Completed date
61
- ws["I#{row}"] = action_date(actions) { |a| a.data["listAfter"]["name"] =~ /^completed/i }
62
-
63
- # Type
64
- labels = card.labels.map(&:name)
65
- type = labels.detect { |l| l.downcase =~ %r{bug|chore|task}i } || 'story'
66
- ws["J#{row}"] = type
67
-
68
- # Estimate
69
- match = card.name.match(/\[(?<estimate>\w)\]/)
70
- ws["L#{row}"] = match[:estimate] if match
71
-
72
- rescue Trello::Error => e
73
- puts e.inspect
74
- puts card.inspect
75
- end
76
-
77
- def action_date(actions, &block)
78
- actions = actions.select(&block)
79
- return "" if actions.empty?
80
- action = actions.sort { |a, b| a.date <=> b.date }.first
81
- action.date.strftime("%m/%d/%Y")
82
- end
83
-
84
- card_rows = {}
85
-
86
- # Find existing rows for current cards
87
- (start_row..rows).each do |row|
88
- cell_id = ws["B#{row}"]
89
- next unless cell_id.present?
90
- card = cards.find { |c| c.id == cell_id }
91
- next unless card.present?
92
- card_rows[row] = card
93
- end
94
-
95
- # Set available rows for new cards
96
- new_cards = cards - card_rows.values
97
- new_cards.each_with_index do |card, i|
98
- row = rows + i + 1
99
- card_rows[row] = card
38
+ rescue StandardError => e
39
+ puts e.class
40
+ puts "-" * e.class.name.size
41
+ pute e.message
42
+ raise e
100
43
  end
101
-
102
- card_rows.each do |row, card|
103
- sleep 1
104
- Timeout.timeout(5) { sync_row(ws, row, card) }
105
- end
106
-
107
- ws.save
108
-
109
- puts "exiting"
data/lib/lionel.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'yajl'
2
+ require 'trello'
3
+ require 'google_drive'
4
+ require 'launchy'
5
+ require 'thor'
6
+ require 'lionel/version'
7
+ require 'lionel/cli'
8
+ require 'lionel/configuration'
9
+ require 'lionel/configurable'
10
+ require 'lionel/export'
11
+ require 'lionel/proxy_action'
12
+ require 'lionel/proxy_card'
13
+ require 'lionel/proxy_worksheet'
14
+ require 'lionel/trello_authentication'
15
+ require 'lionel/google_authentication'
16
+
17
+ module Lionel
18
+ end
data/lib/lionel/cli.rb ADDED
@@ -0,0 +1,65 @@
1
+ module Lionel
2
+ class CLI < Thor
3
+
4
+ def initialize(*)
5
+ @configuration = Lionel::Configuration.instance
6
+ super
7
+ end
8
+
9
+ desc "authorize PROVIDER", "Allows application to request user authorization for provider (google|trello)"
10
+ def authorize(provider)
11
+ case provider
12
+ when 'trello'
13
+ auth = Lionel::TrelloAuthentication.new
14
+
15
+ Launchy.open(auth.trello_key_url)
16
+ auth.trello_key = ask "Enter trello key:"
17
+
18
+ Launchy.open(auth.trello_token_url)
19
+ auth.trello_token = ask "Enter trello token:"
20
+
21
+ auth.save
22
+ when 'google'
23
+ auth = Lionel::GoogleAuthentication.new
24
+
25
+ Launchy.open(auth.api_console_url)
26
+ auth.google_client_id = ask("Enter your google client id:")
27
+ auth.google_client_secret = ask("Enter your google client secret:")
28
+
29
+ Launchy.open(auth.authorize_url)
30
+ auth.retrieve_access_token ask("Enter your google key:")
31
+
32
+ auth.save
33
+ else
34
+ "Provider not recognized: #{provider}"
35
+ end
36
+ end
37
+
38
+ desc "export", "Saves Trello export to Google Docs"
39
+ method_option "print", :aliases => "-p", :type => :boolean, :default => false, :desc => "Print results instead of saving them to Google Docs."
40
+ def export
41
+ export = Lionel::Export.new
42
+
43
+ unless export.has_sources?
44
+ export.trello_board_id = ask("Enter a trello board id to export from:")
45
+ export.google_doc_id = ask("Enter a google doc id to export to:")
46
+ export.save
47
+ end
48
+
49
+ export.authenticate
50
+
51
+ welcome = "Trello? Is it me you're looking for?"
52
+ say welcome
53
+ say '=' * welcome.size
54
+
55
+ export.download
56
+
57
+ if options['print']
58
+ export.rows.each { |row| say row }
59
+ else
60
+ export.upload
61
+ end
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,33 @@
1
+ module Lionel
2
+ module Configurable
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ def configuration
8
+ Configuration.instance
9
+ end
10
+
11
+ def save
12
+ configuration.save(data)
13
+ end
14
+
15
+ def data
16
+ {}
17
+ end
18
+
19
+ end
20
+
21
+ module ClassMethods
22
+
23
+ def config_accessor(*args)
24
+ attr_writer(*args)
25
+
26
+ args.each do |reader|
27
+ define_method(reader) do
28
+ instance_variable_get("@#{reader}") || configuration.send(reader)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,79 @@
1
+ require 'singleton'
2
+
3
+ module Lionel
4
+ class Configuration
5
+ include Singleton
6
+ attr_reader :path, :data
7
+
8
+ FILE_NAME = '.lionelrc'
9
+ CONFIG_ACCESSORS = [
10
+ :trello_key, :trello_token, :trello_board_id,
11
+ :google_token, :google_refresh_token,
12
+ :google_client_id, :google_client_secret,
13
+ :google_doc_id
14
+ ]
15
+
16
+ def self.config_accessor(*args)
17
+ delegate(*args, to: :data)
18
+
19
+ args.each do |accessor|
20
+ define_method("#{accessor}=") do |value|
21
+ data.send("#{accessor}=", value)
22
+ write
23
+ end
24
+ end
25
+ end
26
+
27
+ config_accessor(*CONFIG_ACCESSORS)
28
+
29
+ def initialize
30
+ @path = File.join(File.expand_path("~"), FILE_NAME)
31
+ @data = OpenStruct.new(load_data)
32
+ end
33
+
34
+ def save(attrs = {})
35
+ attrs.each do |accessor, value|
36
+ data.send("#{accessor}=", value)
37
+ end
38
+ write
39
+ end
40
+
41
+ def load_data
42
+ load_file
43
+ rescue Errno::ENOENT
44
+ puts "Couldn't load file, falling back to ENV"
45
+ default_data
46
+ end
47
+
48
+ def default_data
49
+ # {
50
+ # 'trello_key' => ENV['TRELLO_KEY'],
51
+ # 'trello_token' => ENV['TRELLO_TOKEN'],
52
+ # 'trello_board_id' => ENV['TRELLO_BOARD_ID'],
53
+ # 'google_token' => ENV['GOOGLE_TOKEN'],
54
+ # 'google_refresh_token' => ENV['GOOGLE_REFRESH_TOKEN'],
55
+ # 'google_doc_id' => ENV['GOOGLE_DOC_ID']
56
+ # 'google_client_id' => ENV['GOOGLE_CLIENT_ID']
57
+ # 'google_client_secret' => ENV['GOOGLE_CLIENT_SECRET']
58
+ # }
59
+ {}.tap do |data|
60
+ CONFIG_ACCESSORS.each do |name|
61
+ data[name] = ENV[name.to_s.upcase]
62
+ end
63
+ end
64
+ end
65
+
66
+ def load_file
67
+ require 'yaml'
68
+ YAML.load_file(@path)
69
+ end
70
+
71
+ def write
72
+ require 'yaml'
73
+ File.open(@path, File::RDWR|File::TRUNC|File::CREAT, 0600) do |rcfile|
74
+ rcfile.write @data.marshal_dump.to_yaml
75
+ end
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,162 @@
1
+ module Lionel
2
+ class Export
3
+ include Configurable
4
+
5
+ config_accessor :google_doc_id, :trello_board_id
6
+
7
+ def has_sources?
8
+ trello_board_id && google_doc_id
9
+ end
10
+
11
+ def data
12
+ {
13
+ trello_board_id: trello_board_id,
14
+ google_doc_id: google_doc_id
15
+ }
16
+ end
17
+
18
+ def board
19
+ @board ||= Trello::Board.find(trello_board_id)
20
+ end
21
+
22
+ def cards
23
+ cards ||= [].tap do |c|
24
+ # iterate over active lists rather
25
+ # than retrieving all historical cards;
26
+ # trello api returns association proxy
27
+ # that does not respond to "flatten"
28
+ board.lists.each do |list|
29
+ list.cards.each do |card|
30
+ c << card
31
+ end
32
+ end
33
+ end.map { |c| Lionel::ProxyCard.new(c) }
34
+ end
35
+
36
+ def spreadsheet
37
+ @spreadsheet ||= google_session.spreadsheet_by_key(google_doc_id)
38
+ end
39
+
40
+ def worksheet
41
+ @worksheet ||= Lionel::ProxyWorksheet.new(spreadsheet.worksheets[0])
42
+ end
43
+
44
+ def download
45
+ puts "Exporting trello board '#{board.name}' (#{trello_board_id}) to " + "google doc '#{spreadsheet.title}' (#{google_doc_id})"
46
+
47
+ start_row = 2
48
+ rows = worksheet.size
49
+
50
+ card_rows = {}
51
+
52
+ # Find existing rows for current cards
53
+ (start_row..rows).each do |row|
54
+ cell_id = worksheet["B",row]
55
+ next unless cell_id.present?
56
+ card = cards.find { |c| c.id == cell_id }
57
+ next unless card.present?
58
+ card_rows[row] = card
59
+ end
60
+
61
+ # Set available rows for new cards
62
+ new_cards = cards - card_rows.values
63
+ new_cards.each_with_index do |card, i|
64
+ row = rows + i + 1
65
+ card_rows[row] = card
66
+ end
67
+
68
+ card_rows.each do |row, card|
69
+ Timeout.timeout(5) { sync_row(row, card) }
70
+ end
71
+ end
72
+
73
+ class CardMap
74
+ include Enumerable
75
+
76
+ attr_reader :cards, :worksheet
77
+
78
+ def initialize(cards, worksheet)
79
+ @cards, @worksheet = cards, worksheet
80
+ end
81
+
82
+ def each(&block)
83
+ card_rows.each(&block)
84
+ end
85
+
86
+ def card_rows
87
+ @card_rows ||= {}.tap do |map|
88
+ end
89
+ end
90
+ end
91
+
92
+ def upload
93
+ worksheet.save
94
+ end
95
+
96
+ def rows
97
+ worksheet.rows
98
+ end
99
+
100
+ def sync_row(row, card)
101
+ puts "row[#{row}] : #{card.name}"
102
+
103
+ worksheet["B",row] = card.id
104
+
105
+ # Card link
106
+ worksheet["C",row] = card.link
107
+
108
+ # Ready date
109
+ ready_action = card.first_action do |a|
110
+ (a.create? && a.board_id == trello_board_id) || a.moved_to?("Ready")
111
+ end
112
+ worksheet["D",row] = card.format_date(ready_action.date) if ready_action
113
+
114
+ # In Progress date
115
+ worksheet["E",row] = card.date_moved_to("In Progress")
116
+
117
+ # Code Review date
118
+ worksheet["F",row] = card.date_moved_to("Code Review")
119
+
120
+ # Review date
121
+ worksheet["G",row] = card.date_moved_to("Review")
122
+
123
+ # Deploy date
124
+ worksheet["H",row] = card.date_moved_to("Deploy")
125
+
126
+ # Completed date
127
+ worksheet["I",row] = card.date_moved_to("Completed")
128
+
129
+ # Type
130
+ worksheet["J",row] = card.type
131
+
132
+ # Project
133
+ worksheet["K",row] = card.project
134
+
135
+ # Estimate
136
+ worksheet["L",row] = card.estimate
137
+
138
+ # Due Date
139
+ worksheet["M",row] = card.due_date
140
+
141
+ rescue Trello::Error => e
142
+ puts e.inspect
143
+ puts card.inspect
144
+ end
145
+
146
+ def authenticate
147
+ return if @authenticated
148
+ trello_session.configure
149
+ google_session
150
+ @authenticated
151
+ end
152
+
153
+ def google_session
154
+ @google_session ||= GoogleDrive.login_with_oauth(configuration.google_token)
155
+ end
156
+
157
+ def trello_session
158
+ @trello_session ||= TrelloAuthentication.new
159
+ end
160
+
161
+ end
162
+ end
@@ -0,0 +1,58 @@
1
+ module Lionel
2
+ class GoogleAuthentication
3
+ include Configurable
4
+
5
+ attr_reader :access_token
6
+ config_accessor :google_client_id, :google_client_secret
7
+
8
+ def data
9
+ raise "No access token" unless access_token
10
+ {
11
+ google_token: access_token.token,
12
+ google_refresh_token: access_token.refresh_token,
13
+ google_client_id: google_client_id,
14
+ google_client_secret: google_client_secret
15
+ }
16
+ end
17
+
18
+ def retrieve_access_token(authorization_code)
19
+ @access_token = client.auth_code.get_token(authorization_code,
20
+ :redirect_uri => "urn:ietf:wg:oauth:2.0:oob")
21
+ end
22
+
23
+ def refresh
24
+ return false unless refresh_token
25
+
26
+ current_token = OAuth2::AccessToken.from_hash(client,
27
+ {:refresh_token => refresh_token, :expires_at => 36000})
28
+ @access_token = current_token.refresh! # returns new access_token
29
+ end
30
+
31
+ def authorize_url
32
+ client.auth_code.authorize_url(
33
+ :redirect_uri => "urn:ietf:wg:oauth:2.0:oob",
34
+ :scope =>
35
+ "https://docs.google.com/feeds/ " +
36
+ "https://docs.googleusercontent.com/ " +
37
+ "https://spreadsheets.google.com/feeds/")
38
+ end
39
+
40
+ def api_console_url
41
+ "https://code.google.com/apis/console"
42
+ end
43
+
44
+ private
45
+
46
+ def client
47
+ @client ||= OAuth2::Client.new(google_client_id, google_client_secret,
48
+ :site => "https://accounts.google.com",
49
+ :token_url => "/o/oauth2/token",
50
+ :authorize_url => "/o/oauth2/auth")
51
+ end
52
+
53
+ def refresh_token
54
+ @refresh_token || configuration.google_refresh_token
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,48 @@
1
+ module Lionel
2
+ class ProxyAction
3
+ attr_reader :action
4
+ delegate :data, :type, :date, to: :action
5
+
6
+ def initialize(action)
7
+ @action = action
8
+ end
9
+
10
+ def data_attributes(key)
11
+ data[key] || {}
12
+ end
13
+
14
+ def create?
15
+ type == "createCard"
16
+ end
17
+
18
+ def update?
19
+ type == "updateCard"
20
+ end
21
+
22
+ def board_id
23
+ data_attributes("board")["id"]
24
+ end
25
+
26
+ def list_after
27
+ data_attributes("listAfter")
28
+ end
29
+
30
+ def list_before
31
+ data_attributes("listBefore")
32
+ end
33
+
34
+ def list_after?
35
+ list_after.any?
36
+ end
37
+
38
+ def list_before?
39
+ list_before.any?
40
+ end
41
+
42
+ def moved_to?(list_name)
43
+ return false unless list_after?
44
+ !!(list_after["name"] =~ %r{^#{Regexp.escape(list_name.downcase)}}i)
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,62 @@
1
+ module Lionel
2
+ class ProxyCard
3
+ attr_reader :card
4
+ delegate :id, :url, :name, :due, to: :card
5
+
6
+ def initialize(card)
7
+ @card = card
8
+ end
9
+
10
+ def link
11
+ %Q[=HYPERLINK("#{card.url}", "#{card.name.gsub(/"/, "")}")]
12
+ end
13
+
14
+ def actions
15
+ @actions ||= card.actions.map { |a| Lionel::ProxyAction.new(a) }
16
+ end
17
+
18
+ def action_date(&block)
19
+ filtered = actions.select(&block)
20
+ return "" if filtered.empty?
21
+ action = filtered.sort { |a, b| a.date <=> b.date }.first
22
+ format_date action.date
23
+ end
24
+
25
+ def date_moved_to(list_name)
26
+ action = first_action { |a| a.moved_to?(list_name) }
27
+ return "" unless action
28
+ format_date(action.date)
29
+ end
30
+
31
+ def format_date(date, format = "%m/%d/%Y")
32
+ date.strftime(format)
33
+ end
34
+
35
+ def first_action(&block)
36
+ actions.select(&block).sort { |a, b| a.date <=> b.date }.first
37
+ end
38
+
39
+ def type
40
+ labels.detect { |l| l =~ %r{bug|chore|task}i } || 'story'
41
+ end
42
+
43
+ def project
44
+ labels.detect { |l| l !~ %r{bug|chore|task}i }
45
+ end
46
+
47
+ def labels
48
+ @labels ||= card.labels.map(&:name).map(&:downcase)
49
+ end
50
+
51
+ def estimate
52
+ match = card.name.match(/\[(?<estimate>\w)\]/)
53
+ return "" unless match
54
+ match[:estimate]
55
+ end
56
+
57
+ def due_date
58
+ format_date(due) if due
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,25 @@
1
+ module Lionel
2
+ class ProxyWorksheet
3
+ delegate :rows, to: :worksheet
4
+ delegate :size, to: :rows
5
+
6
+ attr_reader :worksheet
7
+ def initialize(worksheet)
8
+ @worksheet = worksheet
9
+ end
10
+
11
+ def []=(col, row, value)
12
+ worksheet["#{col}#{row}"] = value
13
+ end
14
+
15
+ def [](col, row)
16
+ worksheet["#{col}#{row}"]
17
+ end
18
+
19
+ HEADER_ROW = 1
20
+ def content_rows
21
+ rows(HEADER_ROW)
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ module Lionel
2
+ class TrelloAuthentication
3
+ include Configurable
4
+
5
+ config_accessor :trello_key, :trello_token
6
+
7
+ def data
8
+ {
9
+ trello_key: trello_key,
10
+ trello_token: trello_token
11
+ }
12
+ end
13
+
14
+ def configure
15
+ Trello.configure do |c|
16
+ c.developer_public_key = trello_key
17
+ c.member_token = trello_token
18
+ end
19
+ end
20
+
21
+ def trello_key_url
22
+ "https://trello.com/1/appKey/generate"
23
+ end
24
+
25
+ def trello_token_url(key = trello_key)
26
+ "https://trello.com/1/authorize?key=#{key}&name=#{app_name}&response_type=token&scope=read,write,account&expiration=never"
27
+ end
28
+
29
+ def app_name
30
+ "LionelRichie"
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module Lionel
2
+ VERSION = "0.1.0"
3
+ end
data/lib/lionel_richie.rb CHANGED
@@ -1,8 +1 @@
1
- require 'yajl'
2
- require 'trello'
3
- require 'google_drive'
4
- require "lionel_richie/version"
5
-
6
- module LionelRichie
7
- # Your code goes here...
8
- end
1
+ require 'lionel'
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'lionel_richie/version'
4
+ require 'lionel/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "lionel_richie"
8
- spec.version = LionelRichie::VERSION
8
+ spec.version = Lionel::VERSION
9
9
  spec.authors = ["Ross Kaffenberger"]
10
10
  spec.email = ["rosskaff@gmail.com"]
11
11
  spec.description = %q{Export Trello to Google Docs}
@@ -18,11 +18,14 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.bindir = 'bin'
22
+ spec.executables = %w(lionel)
23
+
21
24
  spec.add_dependency "ruby-trello"
22
25
  spec.add_dependency "google_drive"
23
26
  spec.add_dependency "yajl-ruby"
27
+ spec.add_dependency "thor"
24
28
 
25
- spec.add_development_dependency "bundler", "~> 1.3"
26
29
  spec.add_development_dependency "bundler", "~> 1.3"
27
30
  spec.add_development_dependency "launchy"
28
31
  end
data/script/console ADDED
@@ -0,0 +1,13 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ # Trap interrupts to quit cleanly. See
6
+ # https://twitter.com/mitchellh/status/283014103189053442
7
+ Signal.trap("INT") { exit 1 }
8
+
9
+ require 'irb'
10
+ require 'lionel_richie'
11
+
12
+ ARGV.clear # otherwise all script parameters get passed to IRB
13
+ IRB.start
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lionel_richie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-09 00:00:00.000000000 Z
12
+ date: 2013-07-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby-trello
@@ -60,21 +60,21 @@ dependencies:
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: bundler
63
+ name: thor
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
67
- - - ~>
67
+ - - ! '>='
68
68
  - !ruby/object:Gem::Version
69
- version: '1.3'
70
- type: :development
69
+ version: '0'
70
+ type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
- - - ~>
75
+ - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
- version: '1.3'
77
+ version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: bundler
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -111,7 +111,6 @@ description: Export Trello to Google Docs
111
111
  email:
112
112
  - rosskaff@gmail.com
113
113
  executables:
114
- - authorize_lionel
115
114
  - lionel
116
115
  extensions: []
117
116
  extra_rdoc_files: []
@@ -121,11 +120,21 @@ files:
121
120
  - LICENSE.txt
122
121
  - README.md
123
122
  - Rakefile
124
- - bin/authorize_lionel
125
123
  - bin/lionel
124
+ - lib/lionel.rb
125
+ - lib/lionel/cli.rb
126
+ - lib/lionel/configurable.rb
127
+ - lib/lionel/configuration.rb
128
+ - lib/lionel/export.rb
129
+ - lib/lionel/google_authentication.rb
130
+ - lib/lionel/proxy_action.rb
131
+ - lib/lionel/proxy_card.rb
132
+ - lib/lionel/proxy_worksheet.rb
133
+ - lib/lionel/trello_authentication.rb
134
+ - lib/lionel/version.rb
126
135
  - lib/lionel_richie.rb
127
- - lib/lionel_richie/version.rb
128
136
  - lionel_richie.gemspec
137
+ - script/console
129
138
  homepage: ''
130
139
  licenses:
131
140
  - MIT
data/bin/authorize_lionel DELETED
@@ -1,61 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
-
5
- require 'bundler'
6
- require 'lionel_richie'
7
- Bundler.require(:development)
8
-
9
- commands = []
10
-
11
- puts "Authorize for Trello?"
12
- if gets.strip =~ /\Ay/i
13
- Launchy.open "https://trello.com/1/appKey/generate"
14
- puts "Enter your trello key:"
15
- trello_key = gets.strip
16
- commands << "export TRELLO_KEY=#{trello_key}"
17
-
18
- Launchy.open "https://trello.com/1/authorize?key=#{trello_key.strip}&name=LionelRichie&response_type=token&scope=read,write,account&expiration=never"
19
- puts "Enter your trello token"
20
- trello_token = gets.strip
21
- commands << "export TRELLO_TOKEN=#{trello_token}"
22
- end
23
-
24
- # Google Auth
25
- puts "Authorize for Google?"
26
- if gets.strip =~ /\Ay/i
27
- client = OAuth2::Client.new(
28
- ENV['GOOGLE_CLIENT_ID'],
29
- ENV['GOOGLE_CLIENT_SECRET'],
30
- :site => "https://accounts.google.com",
31
- :token_url => "/o/oauth2/token",
32
- :authorize_url => "/o/oauth2/auth")
33
-
34
- if !(refresh_token = ENV['GOOGLE_REFRESH_TOKEN'])
35
- google_auth_token = OAuth2::AccessToken.from_hash(client,
36
- {:refresh_token => refresh_token, :expires_at => 7200})
37
- google_auth_token = google_auth_token.refresh!
38
- else
39
- auth_url = client.auth_code.authorize_url(
40
- :redirect_uri => "urn:ietf:wg:oauth:2.0:oob",
41
- :scope =>
42
- "https://docs.google.com/feeds/ " +
43
- "https://docs.googleusercontent.com/ " +
44
- "https://spreadsheets.google.com/feeds/")
45
-
46
- # Redirect the user to auth_url and get authorization code from redirect URL.
47
- Launchy.open auth_url
48
-
49
- puts "Enter your google key:"
50
- authorization_code = gets.strip
51
- google_auth_token = client.auth_code.get_token(
52
- authorization_code,
53
- :redirect_uri => "urn:ietf:wg:oauth:2.0:oob")
54
- end
55
-
56
- commands << "export GOOGLE_TOKEN=#{google_auth_token.token}"
57
- commands << "export GOOGLE_REFRESH_TOKEN=#{google_auth_token.refresh_token}"
58
- end
59
-
60
- puts "Run the following:\n"
61
- puts commands
@@ -1,3 +0,0 @@
1
- module LionelRichie
2
- VERSION = "0.0.1"
3
- end