redpomo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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