redpomo 0.0.1

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.
@@ -0,0 +1,50 @@
1
+ require 'todo-txt/list'
2
+ require 'redpomo/task'
3
+
4
+ module Redpomo
5
+ class TaskList < Array
6
+
7
+ def self.find(task_number)
8
+ list = TaskList.new(Config.todo_path)
9
+ list.find(task_number)
10
+ end
11
+
12
+ def self.pull_from_trackers!
13
+ list = TaskList.new(Config.todo_path)
14
+ list.pull_from_trackers!
15
+ end
16
+
17
+ def initialize(path)
18
+ @path = path
19
+ File.read(path).split("\n").each do |line|
20
+ push Task.new(self, line)
21
+ end
22
+ end
23
+
24
+ def find(task_number)
25
+ slice(task_number.to_i - 1)
26
+ end
27
+
28
+ def remove!(task)
29
+ delete(task)
30
+ write!
31
+ end
32
+
33
+ def pull_from_trackers!
34
+ issue_tasks = Tracker.all.map(&:issues).flatten.map(&:to_task)
35
+ delete_if do |task|
36
+ task.tracker.present?
37
+ end
38
+ self << issue_tasks
39
+ self.flatten!
40
+ write!
41
+ end
42
+
43
+ def write!
44
+ File.open(@path, 'w') do |file|
45
+ file.write map(&:orig).join("\n") + "\n"
46
+ end
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,108 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'redpomo/issue'
3
+ require 'redpomo/config'
4
+
5
+ module Redpomo
6
+ class Tracker
7
+
8
+ def self.find(name)
9
+ if data = Config.trackers_data[name.to_sym]
10
+ Tracker.new(name.to_sym, data)
11
+ end
12
+ end
13
+
14
+ def self.all
15
+ Config.trackers_data.map do |name, data|
16
+ Tracker.new(name.to_sym, data)
17
+ end
18
+ end
19
+
20
+ attr_reader :name, :base_url
21
+
22
+ def initialize(name, options)
23
+ options.symbolize_keys!
24
+ @name = name
25
+ @base_url = options[:url]
26
+ @api_key = options[:token]
27
+ @default_project = options[:default_project]
28
+ @closed_status_id = options[:closed_status].to_i
29
+ end
30
+
31
+ def issues
32
+ data = get("/issues", assigned_to_id: current_user_id, status_id: "open")
33
+ data["issues"].map do |issue|
34
+ issue["project"] = project_identifier_for(issue["project"]["id"])
35
+ Issue.new(self, issue)
36
+ end
37
+ end
38
+
39
+ def push_entry!(entry)
40
+ task = entry.to_task
41
+ time_entry = {}
42
+
43
+ if issue = task.issue
44
+ time_entry[:issue_id] = issue
45
+ elsif project = task.project
46
+ time_entry[:project_id] = project
47
+ else
48
+ time_entry[:project_id] = @default_project
49
+ end
50
+
51
+ time_entry[:spent_on] = entry.datetime
52
+ time_entry[:hours] = entry.duration / 3600.0
53
+ time_entry[:comments] = task.text
54
+
55
+ post("/time_entries", time_entry: time_entry)
56
+ end
57
+
58
+ def close_issue!(id, message = nil)
59
+ issue = { status_id: @closed_status_id }
60
+ issue[:notes] = message if message.present?
61
+ put("/issues/#{id}", issue: issue)
62
+ end
63
+
64
+ private
65
+
66
+ def project_identifier_for(project_id)
67
+ Config.cache.get("#{@name}:#{project_id}:identifier") do
68
+ data = get("/projects/#{project_id}")
69
+ data["project"]["identifier"]
70
+ end
71
+ end
72
+
73
+ def current_user_id
74
+ get("/users/current")["user"]["id"]
75
+ end
76
+
77
+ def get(url, params = {})
78
+ request(:get, url, params)
79
+ end
80
+
81
+ def post(url, data)
82
+ request(:post, url, body: data)
83
+ end
84
+
85
+ def put(url, data)
86
+ request(:put, url, body: data)
87
+ end
88
+
89
+ def request(type, url, params = {})
90
+ require 'rest_client'
91
+ require 'json'
92
+ args = []
93
+ args << @base_url + url + ".json"
94
+ args << params.delete(:body).to_json unless type == :get
95
+ args << {
96
+ accept: :json,
97
+ content_type: :json,
98
+ params: params.merge(key: @api_key)
99
+ }
100
+ parse RestClient.send(type, *args)
101
+ end
102
+
103
+ def parse(json)
104
+ json && json.length >= 2 ? JSON.parse(json) : nil
105
+ end
106
+
107
+ end
108
+ end
@@ -0,0 +1,3 @@
1
+ module Redpomo
2
+ VERSION = "0.0.1"
3
+ end
data/lib/redpomo.rb ADDED
@@ -0,0 +1,15 @@
1
+ # require "active_support/core_ext"
2
+ # require "rest-client"
3
+ # require "todo-txt"
4
+ # require "yaml"
5
+ # require "json"
6
+ # require "csv"
7
+ # require "launchy"
8
+ # require "applescript"
9
+
10
+ require "redpomo/version"
11
+ # require "redpomo/ext"
12
+ # require "redpomo/cli"
13
+
14
+ module Redpomo
15
+ end
data/redpomo.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/redpomo/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Stefano Verna"]
6
+ gem.email = ["stefano.verna@welaika.com"]
7
+ gem.description = %q{A nice little gem that integrates Redmine, Todo.txt and Pomodoro.app}
8
+ gem.summary = %q{A nice little gem that integrates Redmine, Todo.txt and Pomodoro.app}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "redpomo"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Redpomo::VERSION
17
+
18
+ gem.add_dependency "activesupport"
19
+ gem.add_dependency "thor"
20
+ gem.add_dependency "todo-txt"
21
+ gem.add_dependency "rest-client"
22
+ gem.add_dependency "launchy"
23
+ gem.add_dependency "applescript"
24
+ gem.add_dependency "terminal-table"
25
+
26
+ gem.add_development_dependency "rspec"
27
+ gem.add_development_dependency "vcr"
28
+ gem.add_development_dependency "webmock"
29
+ gem.add_development_dependency "mocha"
30
+ gem.add_development_dependency "simplecov"
31
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'redpomo/file_cache'
3
+ require 'tempfile'
4
+
5
+ describe Redpomo::FileCache do
6
+
7
+ describe "#get" do
8
+ it "executes the block on cache miss" do
9
+ Redpomo::FileCache.instance.cache_path = Tempfile.new('cache').path
10
+ counter = Redpomo::FileCache.get("foobar") { 5 }
11
+ counter.should == 5
12
+ counter = Redpomo::FileCache.get("foobar") { 10 }
13
+ counter.should == 5
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,51 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: put
5
+ uri: https://project.cantierecreativo.net/issues/838.json?key=CANTIERE_TOKEN
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"issue":{"status_id":5}}'
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ Content-Type:
15
+ - application/json
16
+ Content-Length:
17
+ - '25'
18
+ User-Agent:
19
+ - Ruby
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Sat, 05 May 2012 12:50:41 GMT
27
+ Server:
28
+ - Apache/2.2.9 (Debian) DAV/2 PHP/5.2.6-1+lenny10 with Suhosin-Patch mod_python/3.3.1
29
+ Python/2.5.2 mod_ssl/2.2.9 OpenSSL/0.9.8g Phusion_Passenger/3.0.0
30
+ X-Powered-By:
31
+ - Phusion Passenger (mod_rails/mod_rack) 3.0.0
32
+ X-Runtime:
33
+ - '2868'
34
+ Cache-Control:
35
+ - no-cache
36
+ Set-Cookie:
37
+ - _redmine_session=BAh7BzoPc2Vzc2lvbl9pZCIlYTRjNzRjYzVmMDllNDJmYTNlMzU0NmEwMWQwYTEwYzUiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhhc2h7BjoLbm90aWNlIhlNb2RpZmljYSBlZmZldHR1YXRhLgY6CkB1c2VkewY7B0Y%3D--1337564c1bf1f5b34c2a505039c279d6f7074532;
38
+ path=/; HttpOnly
39
+ - autologin=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
40
+ Content-Length:
41
+ - '1'
42
+ Status:
43
+ - '200'
44
+ Content-Type:
45
+ - application/json; charset=utf-8
46
+ body:
47
+ encoding: US-ASCII
48
+ string: ! ' '
49
+ http_version:
50
+ recorded_at: Sat, 05 May 2012 12:50:46 GMT
51
+ recorded_with: VCR 2.0.1