trello_dxy 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ccd015e1ef9737e5006e220319cf34ec94a3c799
4
+ data.tar.gz: 60819ee9f7eea17abe069b973333b37570274a1a
5
+ SHA512:
6
+ metadata.gz: f7dfd2ee6fdb1946766350885e58e76813355727d897241bedbadf4614ee79d7a961b01136c8dbd2f6824ad6600b33cc7cb72d66c46ba4d6b04df9a1f35c1e35
7
+ data.tar.gz: 063d07145d90c752358c25c2c12b7d31b82774c077f26822fb673ba1bf5eafbea88457b14ae593e8a575dec3ff28915ac9e5f88d87883e4e410338462d0ba286
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/bin/trello_dxy ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'trello_dxy'
3
+
4
+ TrelloDXY::CLI::Run.new.run
data/lib/trello_dxy.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'trello_dxy/cli'
2
+ require 'trello_dxy/errors'
3
+ require 'trello_dxy/formatters'
4
+ require 'trello_dxy/meta'
5
+ require 'trello_dxy/requests'
6
+ require 'trello_dxy/utils'
7
+
8
+ module TrelloDXY
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'optparse'
2
+ require 'trello_dxy/cli/commands'
3
+ require 'trello_dxy/cli/run'
4
+ require 'trello_dxy/cli/board'
@@ -0,0 +1 @@
1
+ require 'trello_dxy/cli/board/time'
@@ -0,0 +1,57 @@
1
+ module TrelloDXY
2
+ module CLI
3
+ module Board
4
+ class Time
5
+ def initialize
6
+ @options = {}
7
+ end
8
+
9
+ def run
10
+ option_parser.parse!
11
+ required_options
12
+ board = TrelloDXY::Requests::BoardForUrl.new.board(@options[:url])
13
+ cards = board_cards(board, @options[:closed])
14
+ puts TrelloDXY::Formatters::BoardForUrl.new(cards).output @options[:output]
15
+ end
16
+
17
+ private
18
+
19
+ def board_cards(board, include_closed)
20
+ board.cards.select do |c|
21
+ closed = c.closed
22
+ !closed || (closed && include_closed)
23
+ end
24
+ end
25
+
26
+ def option_parser(options=@options)
27
+ OptionParser.new do |opts|
28
+ opts.banner = "Usage: trello_dxy board [time]"
29
+ opts.on("-u", "--url [URL]", "URL of Trello Board." ) do |o|
30
+ @options[:url] = o
31
+ end
32
+ opts.on("-c", "--closed", "Include closed cards." ) do |o|
33
+ @options[:closed] = o
34
+ end
35
+ opts.on("-o", "--output [OUTPUT]", "Output format [json|csv].") do |o|
36
+ @options[:output] = o
37
+ end
38
+ end
39
+ end
40
+
41
+ def required_options
42
+ mandatory = [:url]
43
+ missing = mandatory.select { |param| @options[param].nil? }
44
+ unless missing.empty?
45
+ puts "Missing options: #{missing.join(', ')}"
46
+ puts option_parser
47
+ exit 1
48
+ end
49
+ end
50
+
51
+ def help
52
+ puts option_parser.help
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,2 @@
1
+ require 'trello_dxy/cli/commands/shared'
2
+ require 'trello_dxy/cli/commands/board'
@@ -0,0 +1,13 @@
1
+ module TrelloDXY
2
+ module CLI
3
+ module Commands
4
+ class Board
5
+ include Shared
6
+
7
+ def time
8
+ TrelloDXY::CLI::Board::Time.new.run
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ module TrelloDXY
2
+ module CLI
3
+ module Commands
4
+ module Shared
5
+ def actions(obj = self)
6
+ (obj.methods - obj.class.superclass.instance_methods).sort - shared_methods
7
+ end
8
+
9
+ def shared_methods
10
+ TrelloDXY::CLI::Commands::Shared.instance_methods
11
+ end
12
+
13
+ def target_name
14
+ self.class.name.downcase.split('::').last
15
+ end
16
+
17
+ def help
18
+ puts "Valid commands for #{target_name}: #{actions.join(', ')}"
19
+ puts "For further help, append -h to sub command."
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,50 @@
1
+ module TrelloDXY
2
+ module CLI
3
+ class Run
4
+ def run
5
+ target = ARGV.shift
6
+ cmd = ARGV.shift || 'help'
7
+ case target
8
+ when *targets
9
+ target_object = CLI::Commands.const_get(target.capitalize).new
10
+ cmd = 'help' unless target_object.actions.include?(cmd.to_sym)
11
+ begin
12
+ target_object.send cmd
13
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
14
+ puts $!.to_s
15
+ puts optparse
16
+ exit 1
17
+ rescue Trello::Error => e
18
+ puts e.message
19
+ exit 1
20
+ rescue TrelloDXY::Errors => e
21
+ puts "error: #{e}"
22
+ exit 1
23
+ rescue NoMethodError => e
24
+ if e.message.match /SocketError/
25
+ puts 'Please connect to the internet to access Trello'
26
+ exit 1
27
+ else
28
+ raise e
29
+ end
30
+ end
31
+ when '-v'
32
+ puts TrelloDXY::Meta::VERSION
33
+ else
34
+ puts "Unkown target: '#{target}'." unless target == '-h'
35
+ puts "trello_dxy [#{targets.join('|')}] [command] OPTIONS"
36
+ puts "Append -h for help on specific target."
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def targets
43
+ klasses = TrelloDXY::CLI.constants.reject do |c|
44
+ ( c == :Run ) || ( c == :Commands )
45
+ end
46
+ klasses.map { |k| k.to_s.downcase }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+
2
+ module TrelloDXY
3
+ class Errors < StandardError
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ require 'trello_dxy/formatters/base'
2
+ require 'trello_dxy/formatters/board_for_url'
@@ -0,0 +1,22 @@
1
+ module TrelloDXY
2
+ module Formatters
3
+ class Base
4
+ def initialize(data)
5
+ @data = data
6
+ end
7
+
8
+ def output(format)
9
+ case format
10
+ when 'json'
11
+ self.to_json
12
+ else 'csv'
13
+ self.to_csv
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :data
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,77 @@
1
+ require 'csv'
2
+ require 'json'
3
+
4
+ module TrelloDXY
5
+ module Formatters
6
+ class BoardForUrl < Base
7
+ def to_csv
8
+ generate_csv(data)
9
+ end
10
+
11
+ def to_json
12
+ generate_json(data)
13
+ end
14
+
15
+ private
16
+
17
+ def generate_csv(cards)
18
+ CSV.generate do |csv|
19
+ csv << ['Card Name', 'Estimated Time', 'Actual Time', 'Members']
20
+ cards.each do |card|
21
+ title, estimated_hours, actual_hours, members = get_relevant_data(card)
22
+ csv << [title, estimated_hours, actual_hours, members]
23
+ end
24
+ end
25
+ end
26
+
27
+ def generate_json(cards)
28
+ relevant_data = cards.map do |card|
29
+ title, estimated_hours, actual_hours, members = get_relevant_data(card)
30
+ {
31
+ 'card_name': title,
32
+ 'estimated_time': estimated_hours,
33
+ 'actual_hours': actual_hours,
34
+ 'members': members
35
+ }
36
+ end
37
+ JSON.pretty_generate(relevant_data)
38
+ end
39
+
40
+ def get_relevant_data(card)
41
+ title = card.name.strip
42
+ estimated_hours, title = get_estimated_hours(title)
43
+ actual_hours, title = get_actual_hours(title)
44
+ members = get_members(card)
45
+ return title, estimated_hours, actual_hours, members
46
+ end
47
+
48
+ def get_estimated_hours(title)
49
+ estimated_hours = ''
50
+ if title[0] == '('
51
+ close_paren_index = title.index(')')
52
+ estimated_hours = title[1..close_paren_index - 1]
53
+ estimated_hours_parens = title[0..close_paren_index]
54
+ title = title.sub(estimated_hours_parens, '')
55
+ title = title.strip
56
+ end
57
+ return estimated_hours, title
58
+ end
59
+
60
+ def get_actual_hours(title)
61
+ actual_hours = ''
62
+ if title[-1] == ']'
63
+ open_bracket_index = title.rindex('[')
64
+ actual_hours = title[open_bracket_index + 1..-2]
65
+ actual_hours_brackets = title[open_bracket_index..-1]
66
+ title = title.sub(actual_hours_brackets, '')
67
+ title = title.strip
68
+ end
69
+ return actual_hours, title
70
+ end
71
+
72
+ def get_members(card)
73
+ card.members.map { |member| member.full_name }.join(', ')
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,6 @@
1
+ module TrelloDXY
2
+ module Meta
3
+ NAME = 'trello_dxy'
4
+ VERSION = '1.0.2'
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ require 'trello'
2
+ require 'trello_dxy/requests/shared'
3
+ require 'trello_dxy/requests/board_for_url'
@@ -0,0 +1,20 @@
1
+ module TrelloDXY
2
+ module Requests
3
+ class BoardForUrl
4
+ include Shared
5
+
6
+ def initialize
7
+ connect_to_trello
8
+ end
9
+
10
+ def board(url)
11
+ board = Trello::Board.all.find { |board| board.url == url }
12
+ if board.nil?
13
+ puts 'The given board URL was not found'
14
+ exit 1
15
+ end
16
+ board
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,51 @@
1
+ require 'highline/import'
2
+
3
+ module TrelloDXY
4
+ module Requests
5
+ module Shared
6
+ def connect_to_trello
7
+ Trello.configure do |config|
8
+ config.developer_public_key = key
9
+ config.member_token = token
10
+ end
11
+ end
12
+
13
+ def key
14
+ get_key 'TRELLO_DEVELOPER_PUBLIC_KEY'
15
+ end
16
+
17
+ def token
18
+ get_key 'TRELLO_MEMBER_TOKEN'
19
+ end
20
+
21
+ def get_key(key_name)
22
+ make_dotfile
23
+ key = ''
24
+ File.open(ENV['HOME'] + '/.trello_dxy').read.each_line do |line|
25
+ if line.start_with? key_name
26
+ key = line.split('=').last.strip
27
+ end
28
+ end
29
+ key
30
+ end
31
+
32
+ def make_dotfile
33
+ current = {}
34
+ dotfile_path = ENV['HOME'] + '/.trello_dxy'
35
+ template_path = TrelloDXY::Utils.gem_libdir + '/templates/trello_dxy.erb'
36
+ if File.exist? dotfile_path
37
+ template = File.readlines(template_path)
38
+ env = File.readlines(dotfile_path).each do |line|
39
+ kv = line.chomp.split('=', 2)
40
+ current[kv[0]] = kv[1] unless kv[1].nil? || kv[1].empty?
41
+ end
42
+ end
43
+ trello_developer_public_key = current['TRELLO_DEVELOPER_PUBLIC_KEY'] || ask('Trello developer public key (visit https://trello.com/app-key): ')
44
+ trello_member_token = current['TRELLO_MEMBER_TOKEN'] || ask("Trello member token (visit https://trello.com/1/connect?key=#{trello_developer_public_key}&name=trello_dxy&response_type=token): ")
45
+ template_file = File.open(template_path, 'r').read
46
+ erb = ERB.new(template_file)
47
+ File.open(dotfile_path, 'w+') { |file| file.write(erb.result(binding)) }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,2 @@
1
+ TRELLO_DEVELOPER_PUBLIC_KEY=<%= trello_developer_public_key %>
2
+ TRELLO_MEMBER_TOKEN=<%= trello_member_token %>
@@ -0,0 +1,10 @@
1
+ module TrelloDXY
2
+ module Utils
3
+ def self.gem_libdir
4
+ t = ["#{File.dirname(File.expand_path($0))}/../lib/#{Meta::NAME}",
5
+ "#{Gem.dir}/gems/#{Meta::NAME}-#{Meta::VERSION}/lib/#{Meta::NAME}"]
6
+ t.each {|i| return i if File.readable?(i) }
7
+ raise "both paths are invalid: #{t}"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'trello_dxy/meta'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'trello_dxy'
8
+ gem.version = TrelloDXY::Meta::VERSION
9
+ gem.authors = ['Adam Gall']
10
+ gem.email = ['adam.gall@dxydoes.com']
11
+ gem.description = 'Trello for DXY Interface'
12
+ gem.summary = 'Output various data from Trello into a DXY friendly interface'
13
+ gem.homepage = 'https://git.dxydoes.com/dxy/trello_dxy'
14
+ gem.license = 'MIT'
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.files -= gem.files.grep(%r{^\.})
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.require_paths = ['lib']
21
+ gem.required_ruby_version = '>= 2.3.0'
22
+
23
+ gem.add_development_dependency 'rspec', '~> 3.4', '>=3.4.0'
24
+ gem.add_development_dependency 'rake', '~> 11.1', '>=11.1.2'
25
+
26
+ gem.add_runtime_dependency 'highline', '1.7.8'
27
+ gem.add_runtime_dependency 'ruby-trello', '1.4.1'
28
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trello_dxy
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Adam Gall
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.4'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.4.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '3.4'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.4.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '11.1'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 11.1.2
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '11.1'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 11.1.2
53
+ - !ruby/object:Gem::Dependency
54
+ name: highline
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '='
58
+ - !ruby/object:Gem::Version
59
+ version: 1.7.8
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - '='
65
+ - !ruby/object:Gem::Version
66
+ version: 1.7.8
67
+ - !ruby/object:Gem::Dependency
68
+ name: ruby-trello
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '='
72
+ - !ruby/object:Gem::Version
73
+ version: 1.4.1
74
+ type: :runtime
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '='
79
+ - !ruby/object:Gem::Version
80
+ version: 1.4.1
81
+ description: Trello for DXY Interface
82
+ email:
83
+ - adam.gall@dxydoes.com
84
+ executables:
85
+ - trello_dxy
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - Gemfile
90
+ - bin/trello_dxy
91
+ - lib/trello_dxy.rb
92
+ - lib/trello_dxy/cli.rb
93
+ - lib/trello_dxy/cli/board.rb
94
+ - lib/trello_dxy/cli/board/time.rb
95
+ - lib/trello_dxy/cli/commands.rb
96
+ - lib/trello_dxy/cli/commands/board.rb
97
+ - lib/trello_dxy/cli/commands/shared.rb
98
+ - lib/trello_dxy/cli/run.rb
99
+ - lib/trello_dxy/errors.rb
100
+ - lib/trello_dxy/formatters.rb
101
+ - lib/trello_dxy/formatters/base.rb
102
+ - lib/trello_dxy/formatters/board_for_url.rb
103
+ - lib/trello_dxy/meta.rb
104
+ - lib/trello_dxy/requests.rb
105
+ - lib/trello_dxy/requests/board_for_url.rb
106
+ - lib/trello_dxy/requests/shared.rb
107
+ - lib/trello_dxy/templates/trello_dxy.erb
108
+ - lib/trello_dxy/utils.rb
109
+ - trello_dxy.gemspec
110
+ homepage: https://git.dxydoes.com/dxy/trello_dxy
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 2.3.0
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 2.6.3
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: Output various data from Trello into a DXY friendly interface
134
+ test_files: []