harvest_slack_report 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: dfb66b329c6e2765209cdf8b26f784d11a60c648
4
+ data.tar.gz: 49b6298cd91ce335ee9dd3ed323b638ced60b7e3
5
+ SHA512:
6
+ metadata.gz: 7e62a0cf6d9b594333164bc6660e44d0c2e1da08dea90fe0669a9ca6b2ef6fe815bc74ba457a487c59ad43459de9d58da4d51f3936ba6a3ab68fe64c6cf7b0fe
7
+ data.tar.gz: 51703594bf954548b0f6113a220decfdbaa7e904f533011501d8e9ab611445d28e6da3c7da619929f20b57ab7735a9e9d75c324e04c5bfff83a7fcb50b264ff0
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .env
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.11.2
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at matt@bitzesty.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in harvest_slack_report.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Matthew Ford
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # HarvestSlackReport
2
+
3
+ Reporting on daily harvest activity.
4
+
5
+ [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
6
+
7
+ ## Installation
8
+
9
+ $ gem install harvest_slack_report
10
+
11
+ ## Usage
12
+
13
+ The following environment variables must be set:
14
+
15
+ HARVEST_DOMAIN=your subdomain
16
+ HARVEST_USERNAME=your email
17
+ HARVEST_PASSWORD=password
18
+ SLACK_API_TOKEN=slack bot token
19
+
20
+ ## Contributing
21
+
22
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bitzesty/harvest_slack_report. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
23
+
24
+ ## License
25
+
26
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/app.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "HarvestSlackReport: A Slack Timesheet Bot",
3
+ "description": "A bot that notifies Slack about timespent on projects.",
4
+ "keywords": [
5
+ "slack",
6
+ "harvest"
7
+ ],
8
+ "repository": "https://github.com/bitzesty/harvest_slack_report",
9
+ "env": {
10
+ "HARVEST_DOMAIN": {
11
+ "description": "Your Harvest subdomain"
12
+ },
13
+ "HARVEST_USERNAME": {
14
+ "description": "An admin Harvest account username/email"
15
+ },
16
+ "HARVEST_PASSWORD": {
17
+ "description": "The password for that account"
18
+ },
19
+ "IGNORE_USERS": {
20
+ "description": "List of user ids to ignore, e.g. 1234,5678"
21
+ },
22
+ "SLACK_API_TOKEN": {
23
+ "description": "Your Slack Bot API Token (https://my.slack.com/services/new/bot)"
24
+ },
25
+ },
26
+ "addons": [
27
+ "scheduler"
28
+ ]
29
+ }
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "harvest_slack_report"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'harvest_slack_report'
5
+
6
+ require 'dotenv'
7
+ Dotenv.load
8
+
9
+ HarvestSlackReport.run
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'harvest_slack_report/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "harvest_slack_report"
8
+ spec.version = HarvestSlackReport::VERSION
9
+ spec.authors = ["Matthew Ford"]
10
+ spec.email = ["matt@bitzesty.com"]
11
+
12
+ spec.summary = %q{Reporting Harvest data to Slack}
13
+ spec.description = %q{Reporting Harvest data to Slack}
14
+ spec.homepage = "https://github.com/bitzesty/harvest_slack_report"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "slack-ruby-client", "~> 0.7.0"
23
+ spec.add_dependency "harvested", "~> 3.1.1"
24
+ spec.add_dependency "activesupport", "~> 4.2.6"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.11"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ spec.add_development_dependency "dotenv", "~> 2.1.0"
30
+ end
@@ -0,0 +1,3 @@
1
+ module HarvestSlackReport
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,99 @@
1
+ require 'harvest_slack_report/version'
2
+ require 'harvested'
3
+ require 'slack-ruby-client'
4
+ require 'active_support/all'
5
+
6
+ # Posts summary harvest data to a slack channel
7
+ module HarvestSlackReport
8
+ def self.fetch_harvest_data(from_date)
9
+ domain = ENV.fetch 'HARVEST_DOMAIN'
10
+ username = ENV.fetch 'HARVEST_USERNAME'
11
+ password = ENV.fetch 'HARVEST_PASSWORD'
12
+ puts "Collecting Harvest data for #{domain}..."
13
+ harvest = Harvest.hardy_client(subdomain: domain,
14
+ username: username,
15
+ password: password
16
+ )
17
+
18
+ ignore_users = if ENV['IGNORE_USERS'].present?
19
+ ENV['IGNORE_USERS'].split(',').map{ |user_id| user_id.to_i }
20
+ else
21
+ []
22
+ end
23
+
24
+ people = harvest.users.all.select { |u| u.is_active? && !ignore_users.include?(u.id) }
25
+
26
+ # puts people.map{ |u| u.email }
27
+
28
+ projects = harvest.projects.all
29
+
30
+ # puts projects
31
+
32
+ puts 'Aggregating data...'
33
+
34
+ report = []
35
+ n_people = people.count
36
+ people.each_with_index do |person, i|
37
+ # TODO Make this customisable
38
+ # Timesheet entries for yesterday
39
+ entries = harvest.reports.time_by_user(person.id, from_date, Time.now)
40
+
41
+ name = "#{person.first_name} #{person.last_name}"
42
+
43
+ if entries && entries.any?
44
+ total_hours = entries.map { |x| x.hours }.sum.round(2)
45
+
46
+ hours_by_project = entries.group_by { |x| x.project_id }.map do |project_id, es|
47
+ proj = projects.find { |pr| pr.id == project_id }
48
+ title = "#{proj.code.present? ? "[#{proj.code}] " : ''}#{proj.name}"
49
+ { title: title, value: es.map { |h| h.hours }.sum.round(2), short: true }
50
+ end
51
+
52
+ color_code = case total_hours
53
+ when 0..2
54
+ "#D0021B"
55
+ when 2..4
56
+ "#F59423"
57
+ when 4..5
58
+ "#F8C61C"
59
+ else
60
+ "#72D321"
61
+ end
62
+
63
+ report << { fallback: "#{name} logged #{total_hours} hours",
64
+ text: "#{name} logged #{total_hours} hours",
65
+ fields: hours_by_project,
66
+ color: color_code
67
+ }
68
+
69
+ else
70
+ report << { fallback: "#{name} logged no time", text: "#{name} logged no time", color: "#4A4A4A" }
71
+ end
72
+ puts "#{i+1}/#{n_people}"
73
+ end
74
+
75
+ report
76
+ end
77
+
78
+ def self.run
79
+ from_date = Time.now - 24.hours
80
+ report = fetch_harvest_data(from_date)
81
+
82
+ if ENV['SLACK_API_TOKEN'].present?
83
+ puts 'Posting to Slack'
84
+ Slack.configure do |config|
85
+ config.token = ENV['SLACK_API_TOKEN']
86
+ end
87
+ client = Slack::Web::Client.new
88
+ client.auth_test
89
+ client.chat_postMessage(channel: '#2-standup',
90
+ text: "Time Report from #{from_date.to_formatted_s(:rfc822)} to now:",
91
+ attachments: report,
92
+ as_user: true
93
+ )
94
+ else
95
+ puts 'SLACK_API_TOKEN needs to be set'
96
+ puts report.inspect
97
+ end
98
+ end
99
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: harvest_slack_report
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Ford
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: slack-ruby-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.7.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.7.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: harvested
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.1.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.1.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 4.2.6
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.2.6
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: dotenv
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 2.1.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.1.0
111
+ description: Reporting Harvest data to Slack
112
+ email:
113
+ - matt@bitzesty.com
114
+ executables:
115
+ - harvest_slack_report
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".travis.yml"
122
+ - CODE_OF_CONDUCT.md
123
+ - Gemfile
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - app.json
128
+ - bin/console
129
+ - bin/setup
130
+ - exe/harvest_slack_report
131
+ - harvest_slack_report.gemspec
132
+ - lib/harvest_slack_report.rb
133
+ - lib/harvest_slack_report/version.rb
134
+ homepage: https://github.com/bitzesty/harvest_slack_report
135
+ licenses:
136
+ - MIT
137
+ metadata: {}
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project:
154
+ rubygems_version: 2.4.5
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: Reporting Harvest data to Slack
158
+ test_files: []