pello 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/pello +5 -0
- data/lib/pello/board.rb +43 -0
- data/lib/pello/card.rb +55 -0
- data/lib/pello/config.rb +39 -0
- data/lib/pello/inputs.rb +39 -0
- data/lib/pello/list.rb +13 -0
- data/lib/pello/runner.rb +101 -0
- data/lib/pello/version.rb +3 -0
- data/lib/pello.rb +11 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bb48f8c0c18e6c06d29397396cbfa5792475d6da699d0215d1a7f9224364004d
|
4
|
+
data.tar.gz: c3a18b8d8af0664246e902d1ee4de3c28ac8357fd3e6e5e37086e78a34e2a321
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dcf908b718977550d8d681aec12effc122ea0fee149397e3a3d686758957c47081088bbb41b1027e953d2a02e9dcb8b4bcc549ae1895e7e227624ee79bad2d91
|
7
|
+
data.tar.gz: 5ace79e7fb062fafdcf654b337be2ae62d5b658d0ad01ae2d102f4e2c150aea289866c23daa147236ebdac5d8febf2d6b4586dd8f15adc009b7fe4915a8950d9
|
data/bin/pello
ADDED
data/lib/pello/board.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'tty/table'
|
3
|
+
|
4
|
+
module Pello
|
5
|
+
class Board
|
6
|
+
extend Forwardable
|
7
|
+
attr_accessor :trello_board
|
8
|
+
def_delegators :@trello_board, :cards, :lists
|
9
|
+
|
10
|
+
def initialize(trello_board)
|
11
|
+
@trello_board = trello_board
|
12
|
+
end
|
13
|
+
|
14
|
+
def as_table
|
15
|
+
headers = trello_board.lists.map(&:name)
|
16
|
+
cards = trello_board.lists.map { |list| list.cards.map { |card| truncate(card.name, 45) } }
|
17
|
+
|
18
|
+
max_cards = cards.map(&:length).max
|
19
|
+
cards = cards.map { |list_cards| list_cards + [nil] * (max_cards - list_cards.length) }
|
20
|
+
|
21
|
+
tableized_cards = cards.transpose
|
22
|
+
|
23
|
+
table = TTY::Table.new headers, tableized_cards
|
24
|
+
table.render :unicode, multiline: true, resize: true, padding: [0, 0, 1, 0]
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def truncate(string, truncate_at, options = {})
|
30
|
+
return string.dup unless string.length > truncate_at
|
31
|
+
|
32
|
+
omission = options[:omission] || '...'
|
33
|
+
length_with_room_for_omission = truncate_at - omission.length
|
34
|
+
stop = if options[:separator]
|
35
|
+
rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
|
36
|
+
else
|
37
|
+
length_with_room_for_omission
|
38
|
+
end
|
39
|
+
|
40
|
+
"#{string[0, stop]}#{omission}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/pello/card.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'byebug'
|
3
|
+
|
4
|
+
module Pello
|
5
|
+
class Card
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
TITLE_REGEX = /(\(([0-9.]*)\))*\s*([0-9.]*)\s*🍅*\s*(.*)/.freeze
|
9
|
+
attr_accessor :trello_card
|
10
|
+
def_delegators :@trello_card, :name, :name=, :comments, :add_comment, :save, :id
|
11
|
+
|
12
|
+
def initialize(trello_card)
|
13
|
+
@trello_card = trello_card
|
14
|
+
end
|
15
|
+
|
16
|
+
def extract_pomodori
|
17
|
+
pomos = name.match(TITLE_REGEX)[3]
|
18
|
+
pomos ||= 0
|
19
|
+
pomos.to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
def extract_title
|
23
|
+
name.match(TITLE_REGEX)[-1]
|
24
|
+
end
|
25
|
+
|
26
|
+
def extract_points
|
27
|
+
points = name.match(TITLE_REGEX)[2]
|
28
|
+
points ||= 0
|
29
|
+
points.to_f
|
30
|
+
end
|
31
|
+
|
32
|
+
def title_with_added_pomodori(how_many = 1)
|
33
|
+
current_pomodori = extract_pomodori
|
34
|
+
current_points = extract_points
|
35
|
+
current_title = extract_title
|
36
|
+
result = []
|
37
|
+
result << "(#{current_points})" unless current_points.zero?
|
38
|
+
result << "#{current_pomodori + how_many} 🍅"
|
39
|
+
result << current_title
|
40
|
+
result.join(' ')
|
41
|
+
end
|
42
|
+
|
43
|
+
def log(event)
|
44
|
+
comment = comments.select { |c| c.data['text'] =~ /PELLO LOG/ }.first
|
45
|
+
if comment
|
46
|
+
new_text = [comment.data['text'], event].join("\n")
|
47
|
+
comment.delete
|
48
|
+
add_comment new_text
|
49
|
+
else
|
50
|
+
text = ['~~~PELLO LOG', event].join("\n")
|
51
|
+
add_comment text
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/pello/config.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Pello
|
2
|
+
class Config
|
3
|
+
CONFIG_FILE_PATH = "#{ENV['HOME']}/.config/pello/pello.yaml".freeze
|
4
|
+
attr_accessor :board_url, :developer_public_key, :list_name, :log_file, :member_token, :username
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
return nil unless File.exist?(CONFIG_FILE_PATH)
|
8
|
+
|
9
|
+
config = YAML.safe_load File.open(CONFIG_FILE_PATH).read
|
10
|
+
|
11
|
+
auth_config = config['auth']
|
12
|
+
@developer_public_key = auth_config['developer_public_key']
|
13
|
+
@member_token = auth_config['member_token']
|
14
|
+
|
15
|
+
pello_config = config['config']
|
16
|
+
@username = pello_config['username']
|
17
|
+
@board_url = pello_config['board_url']
|
18
|
+
@list_name = pello_config['list_name']
|
19
|
+
@log_file = pello_config['log_file']
|
20
|
+
rescue => e
|
21
|
+
puts "Error loading config: #{e.message}"
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.write_empty_config
|
26
|
+
system "mkdir -p #{File.dirname(CONFIG_FILE_PATH)}"
|
27
|
+
File.open(CONFIG_FILE_PATH, 'w') do |file|
|
28
|
+
file.puts 'auth:'
|
29
|
+
file.puts ' developer_public_key: ""'
|
30
|
+
file.puts ' member_token: ""'
|
31
|
+
file.puts 'config:'
|
32
|
+
file.puts ' board_url: ""'
|
33
|
+
file.puts ' username: ""'
|
34
|
+
file.puts ' list_name: "In progress"'
|
35
|
+
file.puts ' log_file: "/Users/your_name/.pello_log"'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/pello/inputs.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "tty-prompt"
|
2
|
+
|
3
|
+
module Pello
|
4
|
+
class Inputs
|
5
|
+
BACK_OPTION = '------ BACK ------'.freeze
|
6
|
+
|
7
|
+
def self.choose_board(user, board_url)
|
8
|
+
prompt = TTY::Prompt.new
|
9
|
+
board_names = user.boards.map(&:name)
|
10
|
+
default_board = user.boards.select { |b| b.url == board_url }.first.try(:name)
|
11
|
+
board_names << BACK_OPTION
|
12
|
+
input = prompt.select('Choose board', board_names, per_page: 15, default: default_board)
|
13
|
+
return nil if input == BACK_OPTION
|
14
|
+
|
15
|
+
Pello::Board.new(user.boards.detect { |b| b.name == input })
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.choose_list(board, list_name)
|
19
|
+
prompt = TTY::Prompt.new
|
20
|
+
list_names = board.lists.map(&:name)
|
21
|
+
list_names << BACK_OPTION
|
22
|
+
default_list = board.lists.select { |l| l.name == list_name }.first.try(:name)
|
23
|
+
input = prompt.select('Choose list', list_names, per_page: 15, default: default_list)
|
24
|
+
return nil if input == BACK_OPTION
|
25
|
+
|
26
|
+
Pello::List.new(board.lists.detect { |l| l.name == input })
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.choose_card(list)
|
30
|
+
prompt = TTY::Prompt.new
|
31
|
+
card_names = list.cards.map(&:name)
|
32
|
+
card_names << BACK_OPTION
|
33
|
+
input = prompt.select('Choose card', card_names, per_page: 15)
|
34
|
+
return nil if input == BACK_OPTION
|
35
|
+
|
36
|
+
Pello::Card.new(list.cards.detect { |c| c.name == input })
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/pello/list.rb
ADDED
data/lib/pello/runner.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'trello'
|
3
|
+
require 'tty-prompt'
|
4
|
+
|
5
|
+
Trello::Comment.send(:define_method, :action_id) do
|
6
|
+
id
|
7
|
+
end
|
8
|
+
|
9
|
+
module Pello
|
10
|
+
class Runner
|
11
|
+
attr_accessor :board_url, :list_name, :log_file_path, :prompt, :username
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@prompt = TTY::Prompt.new
|
15
|
+
configure_pello
|
16
|
+
end
|
17
|
+
|
18
|
+
def run!
|
19
|
+
continue = true
|
20
|
+
|
21
|
+
while continue
|
22
|
+
case prompt.select('Choose task') do |menu|
|
23
|
+
menu.choice name: 'Add pomodori', value: :add_pomodori
|
24
|
+
menu.choice name: 'Edit config', value: :edit_config
|
25
|
+
menu.choice name: 'quit', value: :quit
|
26
|
+
end
|
27
|
+
when :add_pomodori
|
28
|
+
add_pomodori_to_card
|
29
|
+
when :edit_config
|
30
|
+
system 'mkdir -p ~/.config/pello'
|
31
|
+
system "#{ENV['EDITOR']} ~/.config/pello/pello.yaml"
|
32
|
+
when :quit
|
33
|
+
puts 'Ok, bye!'
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def file_log(text)
|
42
|
+
File.open(@log_file_path, 'a+') do |file|
|
43
|
+
file.puts(text)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_pomodori_to_card
|
48
|
+
board = Pello::Inputs.choose_board @user, @board_url
|
49
|
+
return unless board
|
50
|
+
|
51
|
+
puts board.as_table
|
52
|
+
continue = true
|
53
|
+
while continue
|
54
|
+
list = Pello::Inputs.choose_list board, @list_name
|
55
|
+
return unless list
|
56
|
+
|
57
|
+
card = Pello::Inputs.choose_card list
|
58
|
+
next unless card
|
59
|
+
|
60
|
+
pomodori_before = card.extract_pomodori
|
61
|
+
pomodori_to_add = prompt.ask('Pomodori', default: 1)
|
62
|
+
|
63
|
+
puts "Updating card #{card.name}"
|
64
|
+
puts "New title: #{card.title_with_added_pomodori(pomodori_to_add.to_i)}"
|
65
|
+
|
66
|
+
if prompt.yes?('Confirm?')
|
67
|
+
card.name = card.title_with_added_pomodori(pomodori_to_add.to_i)
|
68
|
+
card.save
|
69
|
+
file_log "[#{Time.now} - #{@user.full_name}] #{card.extract_title} (#{pomodori_before} -> #{card.extract_pomodori})"
|
70
|
+
card.log "[#{Time.now} - #{@user.full_name}] #{card.extract_title} (#{pomodori_before} -> #{card.extract_pomodori})"
|
71
|
+
puts('Done!')
|
72
|
+
else
|
73
|
+
puts 'Ok, bye!'
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
|
77
|
+
continue = prompt.yes?('Another one?')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def configure_pello
|
82
|
+
config = Pello::Config.new
|
83
|
+
if config
|
84
|
+
Trello.configure do |trello_config|
|
85
|
+
trello_config.developer_public_key = config.developer_public_key
|
86
|
+
trello_config.member_token = config.member_token
|
87
|
+
end
|
88
|
+
|
89
|
+
@user = Trello::Member.find config.username
|
90
|
+
@board_url = config.board_url
|
91
|
+
@list_name = config.list_name
|
92
|
+
@log_file_path = config.log_file
|
93
|
+
else
|
94
|
+
puts 'No config found, opening config file...'
|
95
|
+
Pello::Config.write_empty_config
|
96
|
+
system "#{ENV['EDITOR']} #{Pello::Config::CONFIG_FILE_PATH}"
|
97
|
+
exit
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/pello.rb
ADDED
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pello
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrea Schiavini
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-12-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ruby-trello
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: tty-prompt
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
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: tty-table
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Perform Trello operations like adding pomodori to a card title
|
56
|
+
email:
|
57
|
+
- metalelf0@gmail.com
|
58
|
+
executables:
|
59
|
+
- pello
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- bin/pello
|
64
|
+
- lib/pello.rb
|
65
|
+
- lib/pello/board.rb
|
66
|
+
- lib/pello/card.rb
|
67
|
+
- lib/pello/config.rb
|
68
|
+
- lib/pello/inputs.rb
|
69
|
+
- lib/pello/list.rb
|
70
|
+
- lib/pello/runner.rb
|
71
|
+
- lib/pello/version.rb
|
72
|
+
homepage: https://github.com/metalelf0/pello
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata:
|
76
|
+
allowed_push_host: https://rubygems.org
|
77
|
+
homepage_uri: https://github.com/metalelf0/pello
|
78
|
+
source_code_uri: https://github.com/metalelf0/pello
|
79
|
+
changelog_uri: https://github.com/metalelf0/pello
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 2.4.0
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.7.6.2
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: A console tool to do Trello operations
|
100
|
+
test_files: []
|