ardekantur-taskomaly 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ taskomaly: access tasko and taskpaper files in ruby
2
+ Copyright (C) 2008 Ardekantur
3
+
4
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5
+
6
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
7
+
8
+ Please see <http://www.gnu.org/licenses/> for the full version of this license.
@@ -0,0 +1,54 @@
1
+ = taskomaly
2
+
3
+ access your Tasko or TaskPaper papers. in ruby.
4
+
5
+ == you need to clean your room
6
+
7
+ === make it a project
8
+
9
+ proj = Taskomaly::Project.new 'Room Cleaning'
10
+
11
+ === add some tasks to it
12
+
13
+ proj.add 'put away clean laundry'
14
+ proj.add 'wash dirty dishes'
15
+
16
+ === tag those suckas up
17
+
18
+ proj.add 'file taxes @april @15'
19
+ proj.tasks.last.tags # [:april, :"15"]
20
+
21
+ proj.add 'organize shelf'
22
+ proj.tasks.last.tag :knickknacks, 1000, 'september'
23
+ proj.tasks.last.tags # [:knickknacks, :"1000", :september]
24
+
25
+ == working with tasko
26
+
27
+ t = Taskomaly::With :user => 9999, :key => 'd9cca721a735dac4efe709e0f3518373'
28
+
29
+ or, create this file:
30
+
31
+ # ~/.tasks.yml
32
+ user: 9999
33
+ key: d9cca721a735dac4efe709e0f3518373
34
+
35
+ and do this:
36
+
37
+ t = Taskomaly::From '~/.tasks.yml'
38
+
39
+ === getting your papers
40
+
41
+ t.get :papers # ['Paper One', 'Paper Two']
42
+ p = t.papers.first
43
+
44
+ puts p.name # 'Paper One'
45
+ puts p.body # duh
46
+
47
+ === change + upload
48
+
49
+ p.body["@today"] = "@tomorrow"
50
+ p.save # true if groovy, false if failed
51
+
52
+ === made a mistake? refresh from the server
53
+
54
+ p.refresh # true if groovy, false if failed
@@ -0,0 +1,73 @@
1
+ require 'rake'
2
+ require 'hanna/rdoctask'
3
+ require 'spec/rake/spectask'
4
+ require 'rake/gempackagetask'
5
+ require 'rubygems/specification'
6
+ require 'date'
7
+
8
+ GEM = "taskomaly"
9
+ GEM_VERSION = "0.0.8"
10
+ AUTHOR = "Ardekantur"
11
+ EMAIL = "greystone@ardekantur.com"
12
+ HOMEPAGE = "http://github.com/ardekantur/taskomaly"
13
+ SUMMARY = "use taskpaper papers and tasko in ruby"
14
+
15
+ spec = Gem::Specification.new do |s|
16
+ s.name = GEM
17
+ s.version = GEM_VERSION
18
+ s.platform = Gem::Platform::RUBY
19
+ s.has_rdoc = true
20
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
21
+ s.summary = SUMMARY
22
+ s.description = s.summary
23
+ s.author = AUTHOR
24
+ s.email = EMAIL
25
+ s.homepage = HOMEPAGE
26
+
27
+ # Uncomment this to add a dependency
28
+ # s.add_dependency "foo"
29
+
30
+ s.require_path = 'lib'
31
+ s.files = %w(LICENSE README.rdoc Rakefile) + Dir.glob("{lib,specs}/**/*")
32
+ end
33
+
34
+ Rake::GemPackageTask.new(spec) do |pkg|
35
+ pkg.gem_spec = spec
36
+ end
37
+
38
+ desc "install the gem locally"
39
+ task :install => [:package] do
40
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
41
+ end
42
+
43
+ desc "create a gemspec file"
44
+ task :make_spec do
45
+ File.open("#{GEM}.gemspec", "w") do |file|
46
+ file.puts spec.to_ruby
47
+ end
48
+ end
49
+
50
+ desc "Run all specs"
51
+ Spec::Rake::SpecTask.new(:spec) do |t|
52
+ t.spec_files = FileList['spec/*.rb']
53
+ t.spec_opts = ['--color']
54
+ end
55
+
56
+ desc "generate rdoc documentation"
57
+ Rake::RDocTask.new(:rdoc) do |rdoc|
58
+ rdoc.rdoc_files.include('README.rdoc', 'LICENSE' ).
59
+ include('lib/**/*.rb')
60
+
61
+ rdoc.main = "README.rdoc"
62
+ rdoc.rdoc_dir = 'doc' # rdoc output folder
63
+ end
64
+
65
+ desc "run rspec + rcov"
66
+ Spec::Rake::SpecTask.new("spec:rcov") do |t|
67
+ t.spec_files = FileList['spec/**/*_spec.rb']
68
+ t.rcov_opts = ['--exclude', "spec/,rcov.rb,rspec.rb,spec*,gems*"]
69
+ t.rcov = true
70
+ t.rcov_dir = 'doc/coverage'
71
+ end
72
+
73
+ task :default => :spec
@@ -0,0 +1,125 @@
1
+ require 'yaml'
2
+ require 'rest_client'
3
+ require 'rexml/document'
4
+
5
+ module Taskomaly
6
+
7
+ def self.From file
8
+ return API.new(:config => file)
9
+ end
10
+
11
+ def self.With hash
12
+ return API.new(hash)
13
+ end
14
+
15
+ class API
16
+
17
+ SERVICE = 'http://taskodone.com/api'
18
+ SUPPORTED_ACTIONS = [ :papers, :paper, :rename, :edit, :new, :delete ]
19
+
20
+ attr_reader :response
21
+ attr_reader :papers
22
+
23
+ # Creates an instance of the API processor with +hash+ passed a set of configuration
24
+ # options in a hash. +hash+ should either be a Tasko user ID and API key (in this case
25
+ # +:user+ and +:key+), or a file where those keys are located in YAML format (in this case
26
+ # +:config+).
27
+ def initialize hash
28
+ @config = {}
29
+
30
+ raise ArgumentError,
31
+ 'please specify either :user and :key or :config' unless (hash.has_key? :user and hash.has_key? :key) or (hash.has_key? :config)
32
+
33
+ @config['user'] = hash[:user] if hash.has_key? :user
34
+ @config['key'] = hash[:key] if hash.has_key? :key
35
+
36
+ if hash.has_key? :config
37
+ begin
38
+ @config = parse_config(File.expand_path(hash[:config]))
39
+ rescue
40
+ raise ArgumentError, "unable to load from file #{hash[:config]}"
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ # The user ID specified in the API configuration.
47
+ def user; @config['user']; end
48
+
49
+ # The API key specified in the API configuration.
50
+ def key; @config['key']; end
51
+
52
+ # Request something from the server. See SUPPORTED_ACTIONS for what is possible to retrieve
53
+ # and send. A brief summary follows:
54
+ #
55
+ # <tt>api.request :papers</tt>:: retrieve a list of all papers the user has saved to Tasko.
56
+ # <tt>api.request :paper, 'Paper Name'</tt>:: return the single paper with the name passed to +request+.
57
+ # <tt>api.request :rename, 'Old Paper Name', 'New Paper Name'</tt>:: rename one of the papers in the account.
58
+ # <tt>api.request :edit, 'Paper Name', 'Paper Body'</tt>:: save a new version of the document to Tasko.
59
+ def request type, *args
60
+ raise ArgumentError, "invalid send request type #{type}" unless SUPPORTED_ACTIONS.include? type
61
+
62
+ begin
63
+ @req = request_generator
64
+ @response = @req.send :post, (base_payload type, *args)
65
+ rescue SocketError
66
+ raise 'the site appears to be unavailable'
67
+ rescue
68
+ raise 'there was an error processing your request'
69
+ end
70
+
71
+ return handle_response(type, *args)
72
+ end
73
+
74
+ alias :get :request
75
+
76
+ private
77
+
78
+ def handle_response type, *args
79
+ doc = REXML::Document.new @response
80
+ case type
81
+ when :papers
82
+ @papers = doc.elements.to_a('//string').map { |m| m.text }
83
+ return @papers
84
+ when :paper
85
+ @data = doc.elements.to_a('//string').map { |m| m.text }
86
+ return Taskomaly::Paper.new( args.first, @data.last, self )
87
+ when :edit
88
+ @data = doc.elements.to_a('//string').map { |m| m.text }
89
+ return true if @data.size > 0
90
+ end
91
+
92
+ return false
93
+
94
+ end
95
+
96
+ def request_generator
97
+ RestClient::Resource.new SERVICE
98
+ end
99
+
100
+ def parse_config config_filepath
101
+ YAML::load_file config_filepath
102
+ end
103
+
104
+ def base_payload method_name, *args
105
+ params = ''
106
+ extra_data = ([] << args).flatten.compact
107
+ if extra_data
108
+ extra_data.each do |data|
109
+ type = (data.class == Fixnum) ? 'integer' : 'string'
110
+ params += "<param><value><#{type}>#{data}</#{type}></value></param>\n"
111
+ end
112
+ end
113
+ <<-XML
114
+ <methodCall><methodName>#{method_name}</methodName>
115
+ <params>
116
+ <param><value><int>#{user}</int></value></param>
117
+ <param><value><string>#{key}</string></value></param>
118
+ #{params}
119
+ </params></methodCall>
120
+ XML
121
+ end
122
+
123
+ end
124
+
125
+ end
@@ -0,0 +1,52 @@
1
+ module Taskomaly
2
+
3
+ class Paper
4
+
5
+ attr_accessor :name, :body
6
+
7
+ def self.From file
8
+ raise ArgumentError, "file #{file} does not exist" unless File.exist? file
9
+ return Paper.new(
10
+ file.gsub(/\.\w+$/, '').gsub(/^.*\//, '').gsub(/[-_]/, ' ').split(' ').each{|word| word.capitalize! }.join(' '),
11
+ File.open(file, "r").readlines.join
12
+ )
13
+ end
14
+
15
+ def initialize name, body = "", api = nil
16
+ @name = name
17
+ @body = body
18
+ @api = api
19
+ parse_body
20
+ end
21
+
22
+ def api
23
+ return @api
24
+ end
25
+
26
+ def save
27
+ return false unless @api
28
+ return @api.request(:edit, @name, @body)
29
+ end
30
+
31
+ def refresh
32
+ return false unless @api
33
+ @body = (@api.request :paper, @name).body
34
+ return true
35
+ end
36
+
37
+ def projects
38
+ @projects
39
+ end
40
+
41
+ private
42
+
43
+ def parse_body
44
+ @projects = []
45
+ @body.split("\n").each do |line|
46
+ @projects << line.gsub(/:\s*$/, '').gsub(/ /, '_').downcase.to_sym if line =~ /^.*:\s*$/
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,19 @@
1
+ module Taskomaly
2
+
3
+ class Project
4
+
5
+ attr_accessor :name, :tasks
6
+
7
+ def initialize name
8
+ @name = name
9
+ @tasks = []
10
+ end
11
+
12
+ def add task
13
+ @tasks << Task.new(task) if task.class == String
14
+ @tasks << task if task.class == Taskomaly::Task
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,80 @@
1
+ module Taskomaly
2
+
3
+ TAG_REGEX = /\@\w+/
4
+
5
+ def self.Do task
6
+ return Task.new(task)
7
+ end
8
+
9
+ class Task
10
+
11
+ attr_accessor :desc, :tags
12
+
13
+ def initialize description
14
+ @desc, @tags = parse(description)
15
+ @delimiter = nil
16
+ end
17
+
18
+ # Tag a task. Duplicate tags are ignored.
19
+ #
20
+ # t = Taskomaly::Do 'wash the dishes'
21
+ # t.tag :kitchen
22
+ # puts t.tags # [:kitchen]
23
+ # t.tag :sink, :july, 4
24
+ # puts t.tags # [:kitchen, :sink, :july, :"4"]
25
+ #
26
+ def tag *args
27
+ @tags = [] unless @tags
28
+ @tags = (@tags + args.map { |tag| tag.to_s.to_sym } ).uniq
29
+ end
30
+
31
+ # Remove tags from a task.
32
+ #
33
+ # t = Taskomaly::Do 'wash the dishes @kitchen'
34
+ # t.untag :kitchen
35
+ # puts t.display # "wash the dishes"
36
+ def untag *args
37
+ return unless @tags
38
+ @tags = (@tags - args)
39
+ end
40
+
41
+ # Display the task, with tags appended to the end.
42
+ #
43
+ # t = Taskomaly::Do 'wash the dishes'
44
+ # t.tag :kitchen
45
+ # puts t.display # "wash the dishes @kitchen"
46
+ def display
47
+ "#{@desc} #{@tags.collect { |tag| '@' + tag.to_s }.join(@delimiter || ' ')}"
48
+ end
49
+
50
+ # Change how listing tags are delimited. +delimiter+ is a string, like <tt>','</tt>,
51
+ # that will be used to join tags. +symmetric_spacing+ is a boolean value
52
+ # that determines whether or not the delimiter should be separated by tags
53
+ # on both sides, or just the right side.
54
+ # Some examples:
55
+ #
56
+ # t = Taskomaly::Do 'wash the dishes @dishes @sink @other'
57
+ # t.display # 'wash the dishes @dishes @sink @other'
58
+ #
59
+ # t.delimit_with ','
60
+ # t.display # 'wash the dishes @dishes, @sink, @other'
61
+ #
62
+ # t.delimit_with '/'
63
+ # t.display # 'wash the dishes @dishes/ @sink/ @other'
64
+ # t.delimit_with '/', true
65
+ # t.display # 'wash the dishes @dishes / @sink / @other'
66
+ #
67
+ def delimit_with delimiter, symmetric_spacing = false
68
+ @delimiter = (symmetric_spacing ? ' ' : '') + delimiter + ' '
69
+ return true
70
+ end
71
+
72
+ private
73
+
74
+ def parse description
75
+ return description.gsub(TAG_REGEX, '').strip.squeeze(' '), description.scan(TAG_REGEX).map { |tag| tag.to_s.gsub(/^\@/, '').to_sym }.uniq
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1 @@
1
+ %w/ api paper project task /.each { |x| require x }
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ardekantur-taskomaly
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ platform: ruby
6
+ authors:
7
+ - Ardekantur
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-16 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: use taskpaper papers and tasko in ruby
17
+ email: greystone@ardekantur.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - LICENSE
25
+ files:
26
+ - LICENSE
27
+ - README.rdoc
28
+ - Rakefile
29
+ - lib/api.rb
30
+ - lib/paper.rb
31
+ - lib/project.rb
32
+ - lib/task.rb
33
+ - lib/taskomaly.rb
34
+ has_rdoc: true
35
+ homepage: http://github.com/ardekantur/taskomaly
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.2.0
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: use taskpaper papers and tasko in ruby
60
+ test_files: []
61
+