timetrello 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 29ddfa611b55bd19230b313aa9d1e0967ad0ebe4
4
+ data.tar.gz: acd5a81c5aa88d3f767d1f8fc9590bbee00c6295
5
+ SHA512:
6
+ metadata.gz: 729ca5285e2259d674dce181730c3e28547c0cd75f62d111a89da221c5d18e535676646b88a64d1229edc36f4e5877840c49e796e182bc575a8ec53da86fbbd9
7
+ data.tar.gz: cdbf70e22bc99c46d0841dc7769e668a913f80f97e62d5f7a50dbbeeb14eb150c2a966fe1769853c447e498c01864e4592fb93f404a186a9e21e99fc92cbbcd6
@@ -0,0 +1,68 @@
1
+ # -*-ruby-*-
2
+ # Copyright (c) 2016 - Formaweb - All rights reserved
3
+ #
4
+ # Author:: Ronaldo Faria Lima
5
+ # Created:: 2016-03-21
6
+ #
7
+ # Defines the structure that holds the activity record grabbed from a trello
8
+ # board.
9
+
10
+ require 'time_trello/duration';
11
+
12
+ module TimeTrello
13
+
14
+ # Public: An activity record identifies completely an activity done in
15
+ # trello. Its main ideia is to be a standard record that can be compared,
16
+ # sorted and collected, used for reporting purposes.
17
+ class ActivityRecord
18
+ include Comparable
19
+
20
+ # Public: Task duration
21
+ attr_accessor :duration
22
+ # Public: Task owner
23
+ attr_accessor :owner
24
+ # Public: Project name (i.e., Trello board)
25
+ attr_accessor :project
26
+ # Public: Task start date
27
+ attr_accessor :start_date
28
+ # Public: Task comment
29
+ attr_accessor :task_description
30
+
31
+ # Public: Initializes this class with proper information about a given task
32
+ #
33
+ # project - Project name (i.e., the board name)
34
+ # owner - Name of the duration owner
35
+ # start_date - When the task started
36
+ # duration - The task duration
37
+ def initialize(*args)
38
+ if args.size != 0
39
+ @duration = args[0]
40
+ @owner = args[1]
41
+ @project = args[2]
42
+ @start_date = args[3]
43
+ @task_description = args[4]
44
+ end
45
+ end
46
+
47
+ # Public: Implementation of Comparable mixin. The comparison is done
48
+ # following this attributes hierarchy:
49
+ # - project
50
+ # - owner
51
+ # - start_date
52
+ #
53
+ # other - The other instance of ActivityRecord to compare with.
54
+ def <=>(other)
55
+ if other == nil
56
+ return -1
57
+ end
58
+ result = @project <=> other.project
59
+ result = @owner <=> other.owner if result == 0
60
+ result = @start_date <=> other.start_date if result == 0
61
+
62
+ result
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+
@@ -0,0 +1,97 @@
1
+ # -*-ruby-*-
2
+ # Copyright (c) 2016 - Formaweb - All rights reserved
3
+ #
4
+ # Author:: Ronaldo Faria Lima
5
+ # Created:: 2016-03-21
6
+ #
7
+ # Describes a duration in hours and minutes and proper operations using those.
8
+
9
+ module TimeTrello
10
+
11
+ # Public: Describes a duration in terms of hours and minutes, representing
12
+ # data internaly as seconds.
13
+ class Duration
14
+ protected
15
+ attr_accessor :internal_seconds # Internal representation of a duration
16
+
17
+ # Public: Initializes this class with hours, minutes and seconds. You can
18
+ # provide two different sets of arguments in order to initialize this class.
19
+ #
20
+ # hours - Hours as an integer.
21
+ # minutes - Minutes as an integer using sexagesimal representation.
22
+ # seconds - Seconds as an integer, using sexagesimal representation.
23
+ #
24
+ # or:
25
+ #
26
+ # a string containing the duration using the format hh:mm.ss
27
+ public
28
+ def initialize(*args)
29
+ @internal_seconds = 0
30
+ time_components = args
31
+ if args.size == 1 && args[0].class.equal?(String)
32
+ time_components = args[0].split(/[:.]/)
33
+ end
34
+ factor = 3600
35
+ time_components.each do |component|
36
+ @internal_seconds += factor * component.to_i
37
+ factor /= 60
38
+ end
39
+ end
40
+
41
+ # Public: Getter. Returns the number of hours from a given duration
42
+ def hours
43
+ @internal_seconds.abs / 3600
44
+ end
45
+
46
+ # Public: Getter. Returns the number of minutes from the internal representation
47
+ def minutes
48
+ (@internal_seconds.abs / 60) % 60
49
+ end
50
+
51
+ # Public: Getter. Returns the number of seconds of a given duration
52
+ def seconds
53
+ @internal_seconds.abs % 60
54
+ end
55
+
56
+ # Public: Getter. Returns the number of raw minutes of a given duration
57
+ #
58
+ # Important: This is a float value, since it is a raw value
59
+ def raw_minutes
60
+ @internal_seconds.abs.to_f / 60.0
61
+ end
62
+
63
+ # Public: Operator overload. Sums up two different instances of Duration
64
+ #
65
+ # other - The other operand
66
+ def +(other)
67
+ duration = Duration.new(0)
68
+ duration.internal_seconds = @internal_seconds + other.internal_seconds
69
+
70
+ duration
71
+ end
72
+
73
+ # Public: Operator overload. Subtracts two different instances of Duration.
74
+ #
75
+ # other - The other operand
76
+ #
77
+ # Important: The resultant duration will have its components described
78
+ # always as positive numbers, even if other is greater than this
79
+ # instance. It is because the way ruby operates over negative numbers in an
80
+ # integer division.
81
+ def -(other)
82
+ duration = Duration.new(0)
83
+ duration.internal_seconds = @internal_seconds - other.internal_seconds
84
+
85
+ duration
86
+ end
87
+
88
+ # Public: Converts an instance of this class to a string
89
+ # representation. This is a simple facility for fast representation
90
+ # on-screen.
91
+ #
92
+ def to_s
93
+ "#{hours}:#{minutes}.#{seconds}"
94
+ end
95
+ end
96
+
97
+ end
@@ -0,0 +1,125 @@
1
+ # -*-ruby-*-
2
+ # Copyright (c) 2016 - Formaweb - All rights reserved
3
+ #
4
+ # Author:: Ronaldo Faria Lima
5
+ # Created:: 2016-03-26
6
+ #
7
+ # Parser for ActivityRecord conversion from Trello data
8
+
9
+ require 'date'
10
+
11
+ require 'time_trello/activity_record'
12
+
13
+ module TimeTrello
14
+
15
+ # Public: Parser for Trello::Action to ActivityRecord conversion. See
16
+ # ruby-trello for Trello::Action class specification.
17
+ class Parser
18
+ # Private: Instance of Trello::Action to analize
19
+ private
20
+ attr :action_record
21
+
22
+ # Private: Prefix to use in detecting if a given comment is really an
23
+ # expected one
24
+ attr :prefix
25
+
26
+ # Private: Class variable used to hold the workflow pieces that parses the
27
+ # Trello::Action into TimeTrello::ActivityRecord. Each workflow step is a
28
+ # block that takes two parameters:
29
+ #
30
+ # action_record - Hash containing Trello::Action and Trello::Member instances
31
+ # record - TimeTrello::ActivityRecord instance to build
32
+ #
33
+ # Return:: true if parsing was flawless and false otherwise
34
+ #
35
+ protected
36
+ def workflow
37
+ [
38
+ # Detects if a given action_record is the one we are looking for.
39
+ lambda do |action_record, activity|
40
+ return action_record[:action].data['text'].starts_with?(@prefix) unless action_record[:action].data['text'] == nil
41
+
42
+ false
43
+ end,
44
+
45
+ # Parses the duration
46
+ lambda do |action_record, activity|
47
+ txt_duration = action_record[:action].data['text'].scan(/[0-9]+:[0-9]+/)
48
+ activity.duration = Duration.new(txt_duration[0]) unless txt_duration.size == 0
49
+
50
+ activity.duration != nil
51
+ end,
52
+
53
+ # Parses the comment owner
54
+ lambda do |action_record, activity|
55
+ activity.owner = action_record[:member].full_name
56
+
57
+ activity.owner != nil
58
+ end,
59
+
60
+ # Parses the project
61
+ lambda do |action_record, activity|
62
+ activity.project = action_record[:action].data["board"]["name"]
63
+
64
+ activity.project != nil
65
+ end,
66
+
67
+ # Parses the start date
68
+ lambda do |action_record, activity|
69
+ activity.start_date = action_record[:action].date
70
+ txt_date = action_record[:action].data["text"].scan(/\[[A-Z0-9:. -]+\]/)
71
+ activity.start_date = DateTime.parse(txt_date[0].to_s).to_time unless txt_date.size == 0
72
+
73
+ activity.start_date != nil
74
+ end,
75
+
76
+ # Parses the task comment
77
+ lambda do |action_record, activity|
78
+ txt_comment = action_record[:action].data["text"].scan(/"[a-zA-Z0-9]+"/)
79
+ if txt_comment.size != 0
80
+ activity.task_description = txt_comment[0]
81
+ else
82
+ activity.task_description = action_record[:action].card.name
83
+ end
84
+
85
+ activity.task_description != nil
86
+ end
87
+ ]
88
+ end
89
+
90
+ # Private: List of steps that parses the action_record, loading fields of a
91
+ # provided ActivityRecord instance. It is used as a workflow.
92
+
93
+ # Public: Initializes the parser, setting it to the proper state.
94
+ #
95
+ # action_record - Hash containing the following elements:
96
+ # - :action_record - An instance of Trello::Action_Record class
97
+ # - :member - An instance of Trello::Member class, which is the
98
+ # creator of the action_record with details.
99
+ # prefix - Prefix to use for comment detection
100
+ public
101
+ def initialize(action_record, prefix)
102
+ @action_record = action_record
103
+ @prefix = prefix
104
+ end
105
+
106
+ # Public: Parses the action_record, building an instance of ActivityRecord. This
107
+ # parser is based on a workflow defined by a constant array of blocks. Each
108
+ # block is a step that will be executed in sequence.
109
+ def parse
110
+ record = ActivityRecord.new()
111
+
112
+ for step in self.workflow
113
+ if !step.call(@action_record, record)
114
+ # Workflow was interrupted. Not necessarily an error. Possibly the
115
+ # action_record was not the one we are looking for.
116
+ return nil
117
+ end
118
+ end
119
+
120
+ record
121
+ end
122
+
123
+ end
124
+
125
+ end
@@ -0,0 +1,60 @@
1
+ # -*-ruby-*-
2
+ # Copyright (c) 2016 - Formaweb - All rights reserved
3
+ #
4
+ # Author:: Ronaldo Faria Lima
5
+ # Created:: 2016-03-21
6
+ #
7
+ # Reporting engine. Used to select and build a result set to the caller.
8
+
9
+ require 'time_trello/trello_driver'
10
+
11
+ module TimeTrello
12
+
13
+ # Public: This class represents a report manager on the time trello
14
+ # structure. It coordinates efforts with the persistence manager in order to
15
+ # collect data from a given trello board.
16
+ class Report
17
+ # Public: Prefix for proper filtering
18
+ attr_accessor :prefix
19
+ # Public: Report start date
20
+ attr_accessor :start_date
21
+ # Public: Report end date
22
+ attr_accessor :end_date
23
+ # Public: board identification for reporting
24
+ attr_accessor :board_id
25
+
26
+ # Public: Initializes this class providing initial filter information
27
+ #
28
+ # start_date - Used to limit the result set. It is the start of time records
29
+ # end_date - Used to limit the result set. It is the end of time records
30
+ # board_id - Identification of the given board. Used to grab information
31
+ # from an specific board.
32
+ def initialize(start_date, end_date, board_id, prefix)
33
+ @start_date = start_date
34
+ @end_date = end_date
35
+ @board_id = board_id
36
+ @prefix = prefix
37
+ end
38
+
39
+ # Public: Generates the report based on a filter, if provided. The filter is
40
+ # a block that will filter the result set accordingly. The result set is
41
+ # always an array containing instances of ActivityRecord. See::
42
+ # ActivityRecord
43
+ #
44
+ # filter - Block used to filter the result set even further. It must follow
45
+ # the same format for the block passed as parameter to Array.find_all
46
+ # method. Each element on the array is, in fact, an instance of
47
+ # TimeTrello::ActivityRecord
48
+ def find_all &filter
49
+ driver = TrelloDriver.new(@board_id, @prefix)
50
+ result_set = driver.activities.find_all { |activity| activity.start_date >= @start_date && activity.start_date <= @end_date }
51
+
52
+ if filter
53
+ return result_set.find_all &filter
54
+ end
55
+
56
+ result_set
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,55 @@
1
+ # -*-ruby-*-
2
+ # Copyright (c) 2016 - Formaweb - All rights reserved
3
+ #
4
+ # Author:: Ronaldo Faria Lima
5
+ # Created:: 2016-03-22
6
+ #
7
+ # Trello driver, used to access trello and convert records to an internal
8
+ # representation
9
+
10
+ require 'trello'
11
+
12
+ require 'time_trello/activity_record'
13
+ require 'time_trello/parser'
14
+
15
+ module TimeTrello
16
+
17
+ # Public: Driver responsible to convert data gathered from Trello to an
18
+ # internal representation.
19
+ class TrelloDriver
20
+ attr_accessor :board_id
21
+ attr_accessor :prefix
22
+
23
+ def initialize(board_id, prefix)
24
+ @board_id = board_id
25
+ @prefix = prefix
26
+ @activities = []
27
+ @board = nil
28
+ end
29
+
30
+ # Public: Getter. Gets a board, based on a board id.
31
+ def board
32
+ @board = Trello::Board.find(@board_id) if @board == nil
33
+
34
+ @board
35
+ end
36
+
37
+ # Public: Getter. Gets all activities for a given board.
38
+ def activities
39
+ return @activities if @activities != nil && @activities.length > 0
40
+
41
+ @activities = []
42
+ self.board.cards.each do |card|
43
+ card.actions.each do |action|
44
+ member = Trello::Member.find(action.member_creator_id)
45
+ action_record = {action: action, member: member}
46
+ activity = (Parser.new(action_record, @prefix)).parse
47
+ @activities.push(activity) unless activity == nil
48
+ end
49
+ end
50
+
51
+ @activities
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module TimeTrello
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,46 @@
1
+ # -*-ruby-*-
2
+ # Copyright (c) 2016 - Formaweb - All rights reserved
3
+ #
4
+ # Author:: Ronaldo Faria Lima
5
+ # Created:: 2016-03-21
6
+ #
7
+ # Main gem module
8
+
9
+ require 'trello'
10
+
11
+ require 'time_trello/version'
12
+ require 'time_trello/report'
13
+ require 'time_trello/duration'
14
+ require 'time_trello/activity_record'
15
+
16
+ module TimeTrello
17
+ # Private: Prefix for comment detection/parsing
18
+ private
19
+ attr_accessor :prefix
20
+
21
+ # Public: Initializes this module with the proper trello client configuration.
22
+ #
23
+ # public_key - Trello public key used for authentication.
24
+ # member_token - Trello member token, used for authentication.
25
+ public
26
+ def self.initialize(public_key, member_token, prefix = ':clock12:')
27
+ @prefix = prefix
28
+ Trello.configure do |config|
29
+ config.developer_public_key = public_key
30
+ config.member_token = member_token
31
+ end
32
+ end
33
+
34
+ # Public: Generates the report based on the provided parameters.
35
+ #
36
+ # start_date - The start date to limit the results.
37
+ # end_date - The end date to limit the results.
38
+ # board_id - Identification of the board that should be parsed in order to
39
+ # return results.
40
+ # filter - A block containing a filter for the results. The block must receive
41
+ # a parameter which is an instance of ActivityRecord.
42
+ def self.find_all(start_date, end_date, board_id, &filter)
43
+ (Report.new(start_date, end_date, board_id, @prefix)).find_all(&filter)
44
+ end
45
+
46
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timetrello
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Caio Tarifa
8
+ - Ronaldo Faria Lima
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-03-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ruby-trello
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.4'
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.4.1
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '1.4'
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.4.1
34
+ description: Trello time tracking.
35
+ email:
36
+ - caiotarifa@gmail.com
37
+ - ronaldo@nineteen.com.br
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - lib/time_trello.rb
43
+ - lib/time_trello/activity_record.rb
44
+ - lib/time_trello/duration.rb
45
+ - lib/time_trello/parser.rb
46
+ - lib/time_trello/report.rb
47
+ - lib/time_trello/trello_driver.rb
48
+ - lib/time_trello/version.rb
49
+ homepage: http://www.formaweb.com.br
50
+ licenses:
51
+ - MIT
52
+ metadata: {}
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 2.4.8
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Trello time tracking with Ruby.
73
+ test_files: []