timetrello 1.0.0

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: 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: []