ardekantur-taskomaly 0.0.8

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.
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
+