SagMor-thetwitthit 0.1.0

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/Manifest ADDED
@@ -0,0 +1,12 @@
1
+ bin/thetwitthit
2
+ lib/thetwitthit/cli/helpers.rb
3
+ lib/thetwitthit/cli.rb
4
+ lib/thetwitthit/config.rb
5
+ lib/thetwitthit/properties.rb
6
+ lib/thetwitthit/version.rb
7
+ lib/thetwitthit/worker.rb
8
+ lib/thetwitthit.rb
9
+ Rakefile
10
+ README.rdoc
11
+ thetwitthit.gemspec
12
+ Manifest
data/README.rdoc ADDED
@@ -0,0 +1,56 @@
1
+ = TheTwittHit
2
+
3
+ I'm a GTD fan and the idea is simple, i want my contacts to be able to post things they need me to do in my inbox and also post thing by my self when I'm away from my computer.
4
+
5
+ So i integrated {The Hit List}[http://www.potionfactory.com/thehitlist/], the application i use to manage my todo list and {Twitter}[http://twitter.com/] and created TheTwittHit
6
+
7
+ TheTwittHit is a simple script that collects twitts with the hashtag *#todo* from twitter that either were:
8
+
9
+ * Posted by you
10
+ * Replied to you
11
+ * Direct Messaged to you
12
+
13
+ and add them to the application's inbox were i can review them later.
14
+
15
+ == Install
16
+
17
+ Just open a terminal and write:
18
+
19
+ sudo gem install SagMor-thetwitthit --source http://gems.github.com
20
+ thetwitthit install
21
+
22
+ follow the instructions and you are ready to go
23
+
24
+ == Usage
25
+
26
+ Once you had configured it simply {twitt using the #todo hashtag}[http://twitter.com/home?status=%23todo] and see how TheTwittHit do the rest
27
+
28
+ == Contact
29
+
30
+ If you want to contact me my twitter account is {SagMor}[http://twitter.com/sagmor] and if there is something i should do you can {twitt it}[http://twitter.com/home?status=@sagmor%20%23todo] ;)
31
+
32
+ == License
33
+
34
+ Copyright (c) 2009 Sebastián Gamboa
35
+
36
+ Permission is hereby granted, free of charge, to any
37
+ person obtaining a copy of this software and associated
38
+ documentation files (the "Software"), to deal in the
39
+ Software without restriction, including without limitation
40
+ the rights to use, copy, modify, merge, publish,
41
+ distribute, sublicense, and/or sell copies of the
42
+ Software, and to permit persons to whom the Software is
43
+ furnished to do so, subject to the following conditions:
44
+
45
+ The above copyright notice and this permission notice
46
+ shall be included in all copies or substantial portions of
47
+ the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
50
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
51
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
52
+ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
53
+ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
54
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
55
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
56
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ ProjectName = 'thetwitthit'
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'echoe'
6
+ require "lib/#{ProjectName}/version"
7
+
8
+ Echoe.new(ProjectName, TheTwittHit::Version) do |p|
9
+ p.description = "Fetches tasks from twitter and adds them to The Hit List.app"
10
+ p.url = "http://github.com/SagMor/#{ProjectName}"
11
+ p.author = "Sebastian Gamboa"
12
+ p.email = "me@sagmor.com"
13
+ p.ignore_pattern = ["tmp/*", "script/*"]
14
+ p.development_dependencies = []
15
+ p.runtime_dependencies = ['twitter >=0.5.3', 'main >= 2.8.2', 'highline >= 1.4.0']
16
+
17
+ end
18
+
19
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/bin/thetwitthit ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'thetwitthit'))
4
+ require 'thetwitthit/cli'
@@ -0,0 +1,120 @@
1
+ module TheTwittHit
2
+ module CLI
3
+ module Helpers
4
+ LAUNCH_AGENT_PLIST =<<EOF
5
+ <?xml version="1.0" encoding="UTF-8"?>
6
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
7
+ <plist version="1.0">
8
+ <dict>
9
+ <key>Label</key>
10
+ <string>com.sagmor.TheTwittHit</string>
11
+ <key>OnDemand</key>
12
+ <false/>
13
+ <key>ProgramArguments</key>
14
+ <array>
15
+ <string>#s</string>
16
+ <string>start</string>
17
+ </array>
18
+ </dict>
19
+ </plist>
20
+ EOF
21
+
22
+ PLIST_FILE = File.join(ENV['HOME'],'Library','LaunchAgents','com.sagmor.thetwitthit.plist')
23
+
24
+ def daemon(mode)
25
+ Daemons.run_proc('TheTwittHit', :dir_mode => :normal,
26
+ :log_output => :true,
27
+ :dir => TheTwittHit::Config::APP_SUPPORT,
28
+ :ARGV => [mode]) do
29
+
30
+ Signal.trap("TERM") do
31
+ puts "#{Time.now} - Stoping TheTwittHit"
32
+ exit(0)
33
+ end
34
+
35
+ puts "#{Time.now} - Starting TheTwittHit"
36
+
37
+ while(true) do
38
+ puts "#{Time.now} - Fetching last Tweets"
39
+ w = TheTwittHit::Worker.new
40
+ w.load
41
+
42
+ sleep w.config.sleep_time
43
+ end
44
+
45
+
46
+
47
+ end
48
+ end
49
+
50
+ def configure
51
+ config = TheTwittHit::Config.new
52
+ puts "load \#todo twitts from [yes/no]:"
53
+ config.load_user_timeline_todos = agree(" * your timeline?")
54
+ config.load_replies_todos = agree(" * your replies?")
55
+ config.load_direct_messages_todos = agree(" * your direct messages?")
56
+ puts
57
+ config.sleep_time = 60*ask(
58
+ "how often dou you want to load your twitts? (in minutes)",
59
+ Integer) { |q| q.default = 60 }
60
+
61
+ config.save
62
+ end
63
+
64
+ def start_on_login
65
+ if agree("Do you want to configure TheTwittHit to start on login? [yes/no]")
66
+ File.open(PLIST_FILE,'w') do |f|
67
+ bin = File.join(File.dirname(__FILE__),'..','..','..','bin','thetwitthit')
68
+ f.puts LAUNCH_AGENT_PLIST % bin
69
+ end
70
+ else
71
+ File.delete(PLIST_FILE) if File.exists?(PLIST_FILE)
72
+ end
73
+ end
74
+
75
+ def authorize
76
+ config = TheTwittHit::Config.new
77
+
78
+ if config.access_token
79
+ puts "There is a twitter access configured!"
80
+ clear = agree("do you want to re-authorize TheTwittHit? [yes/no]")
81
+ return unless clear
82
+
83
+ config.access_token = nil
84
+ end
85
+
86
+ while config.access_token.nil? do
87
+ puts "Authenticating with Twitter:"
88
+ begin
89
+ auth = config.auth(false)
90
+ rtoken, rsecret = auth.request_token.token, auth.request_token.secret
91
+
92
+ puts "The script will open your browser,"
93
+ puts "authorize the app at twitter and come back here"
94
+
95
+ sleep 2
96
+ %x(open #{auth.request_token.authorize_url})
97
+
98
+ until agree("are you ready? [yes/no]")
99
+ end
100
+
101
+ auth = config.auth(false,true)
102
+ auth.authorize_from_request(rtoken, rsecret)
103
+ twitter = Twitter::Base.new(auth)
104
+ twitter.friends_timeline
105
+
106
+ config.access_token = auth.access_token.token
107
+ config.access_secret = auth.access_token.secret
108
+
109
+ config.auth(true,true)
110
+
111
+ rescue
112
+ puts "Authorization Failed!"
113
+ end
114
+ end
115
+
116
+ config.save
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,72 @@
1
+ require 'rubygems'
2
+
3
+ gem 'main', '>= 2.8.2'
4
+ gem 'highline', '>= 1.4.0'
5
+
6
+ require 'main'
7
+ require 'highline/import'
8
+ require 'daemons'
9
+
10
+ HighLine.track_eof = false
11
+ CLI_ROOT = File.expand_path(File.join(File.dirname(__FILE__), 'cli'))
12
+
13
+ require CLI_ROOT + '/helpers'
14
+ include TheTwittHit::CLI::Helpers
15
+
16
+ Main {
17
+ def run
18
+ puts "thetwitthit [command] --help for usage instructions."
19
+ puts "The available commands are: \n\t install, uninstall, start, stop, restart."
20
+ end
21
+
22
+ mode 'install' do
23
+ description 'Installs and configure the application'
24
+ def run
25
+ puts "Installing TheTwittHit"
26
+ authorize
27
+ configure
28
+ start_on_login
29
+
30
+ if agree("do you want to start TheTwittHit?")
31
+ daemon('start')
32
+ end
33
+ end
34
+ end
35
+
36
+ mode 'uninstall' do
37
+ description 'Uninstalls the application'
38
+ def run
39
+ if agree("Are you shure that you want to remove TheTwittHit?")
40
+ puts "Nooooo!!!, whyyyy, ok, lets do this!"
41
+ daemon('stop')
42
+
43
+ File.delete(TheTwittHit::CLI::Helpers::PLIST_FILE)
44
+ File.delete(TheTwittHit::Config::CONFIG_FILE)
45
+ File.delete(File.join(TheTwittHit::Config::APP_SUPPORT,'TheTwittHit.output'))
46
+ else
47
+ puts "Uff, that was close..."
48
+ end
49
+ end
50
+ end
51
+
52
+ mode 'start' do
53
+ description 'Starts TheTwittHit daemon'
54
+ def run
55
+ daemon('start')
56
+ end
57
+ end
58
+
59
+ mode 'stop' do
60
+ description 'Stops TheTwittHit daemon'
61
+ def run
62
+ daemon('stop')
63
+ end
64
+ end
65
+
66
+ mode 'restart' do
67
+ description 'Restarts TheTwittHit daemon'
68
+ def run
69
+ daemon('restart')
70
+ end
71
+ end
72
+ }
@@ -0,0 +1,55 @@
1
+ module TheTwittHit
2
+ class Config
3
+ APP_SUPPORT = File.join(ENV['HOME'], "Library", "Application Support", "The Hit List")
4
+ CONFIG_FILE = File.join(APP_SUPPORT, 'thetwitthit.yml')
5
+ CONSUMER_KEY = 'IvgtcoFEQaVcvckEjoQQ9w'
6
+ CONSUMER_SECRET = 'mS7iOi5QvLqC4oMupeO1kbVXyngyDa5Jq80qVS9KI8Q'
7
+
8
+ def initialize
9
+ @config = load()
10
+ end
11
+
12
+ [:access_token, :access_secret, :load_user_timeline_todos,
13
+ :load_replies_todos, :load_direct_messages_todos, :last_user_timeline,
14
+ :last_reply, :last_direct_message, :sleep_time].each do |key|
15
+
16
+ define_method key do
17
+ @config[key]
18
+ end
19
+
20
+ define_method "#{key}=".to_sym do |value|
21
+ @config[key]=value
22
+ end
23
+ end
24
+
25
+ def save
26
+ File.open(CONFIG_FILE, 'w') do |f|
27
+ YAML::dump(@config, f)
28
+ end
29
+
30
+ true
31
+ end
32
+
33
+ def auth(force_auth = true, force_build = false)
34
+ if @auth.nil? || force_build
35
+ @auth = Twitter::OAuth.new(CONSUMER_KEY,CONSUMER_SECRET)
36
+ if @config[:access_token]
37
+ @auth.authorize_from_access(@config[:access_token], @config[:access_secret])
38
+ elsif force_auth
39
+ raise "Not Authorized"
40
+ end
41
+ end
42
+
43
+ @auth
44
+ end
45
+
46
+ private
47
+ def load
48
+ if File.exists?(CONFIG_FILE)
49
+ YAML::load_file(CONFIG_FILE)
50
+ else
51
+ {}
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,27 @@
1
+ module TheTwittHit
2
+ class Properties
3
+ def initialize()
4
+ @hash = {}
5
+ end
6
+
7
+ def title
8
+ @hash[:title]
9
+ end
10
+
11
+ def title=(title)
12
+ @hash[:title] = title
13
+ end
14
+
15
+ def notes
16
+ @hash[:notes]
17
+ end
18
+
19
+ def notes=(notes)
20
+ @hash[:notes] = notes
21
+ end
22
+
23
+ def to_s
24
+ (@hash.map{ |key, val| "#{key}:\"#{val}\"" }).join(', ')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module TheTwittHit #:nodoc:
2
+ Version = '0.1.0'
3
+ end
@@ -0,0 +1,83 @@
1
+ module TheTwittHit
2
+ class Worker
3
+
4
+ SCRIPT =<<EOF
5
+ tell application "The Hit List"
6
+ tell inbox to make new task with properties {%s}
7
+ end tell
8
+ EOF
9
+
10
+ def initialize
11
+ @config = TheTwittHit::Config.new
12
+ end
13
+
14
+ def load
15
+ twitts = user_timeline_todos + replies_todos + direct_messages_todos
16
+ twitts.each { |twitt| save(twitt) }
17
+ @config.save
18
+ end
19
+
20
+ def config
21
+ @config
22
+ end
23
+
24
+ private
25
+ def twitter
26
+ @twitter ||= Twitter::Base.new(@config.auth)
27
+ end
28
+
29
+ def user_timeline_todos
30
+ if @config.load_user_timeline_todos
31
+ twitts = twitter.user_timeline(options(:since_id => @config.last_user_timeline))
32
+ @config.last_user_timeline = twitts[0].id unless twitts.empty?
33
+
34
+ twitts
35
+ else
36
+ []
37
+ end
38
+ end
39
+
40
+ def replies_todos
41
+ if @config.load_replies_todos
42
+ twitts = twitter.replies(options(:since_id => @config.last_reply))
43
+ @config.last_reply = twitts[0].id unless twitts.empty?
44
+
45
+ twitts
46
+ else
47
+ []
48
+ end
49
+ end
50
+
51
+ def direct_messages_todos
52
+ if @config.load_direct_messages_todos
53
+ twitts = twitter.direct_messages(options(:since_id => @config.last_direct_message))
54
+ @config.last_direct_message = twitts[0].id unless twitts.empty?
55
+
56
+ twitts
57
+ else
58
+ []
59
+ end
60
+ end
61
+
62
+ def save(twitt)
63
+ if twitt.text.match(/\#todo/)
64
+ p = Properties.new
65
+ p.title = twitt.text.gsub(/\#todo/, '').gsub(/\#/, '/').gsub(/@/, 'to:')
66
+ p.title << ' /twit'
67
+ p.notes = "Twitt: http://twitter.com/#{twitt.user.screen_name}/status/#{twitt.id}"
68
+
69
+ `osascript -e '#{SCRIPT % p}'`
70
+ true
71
+ else
72
+ false
73
+ end
74
+ end
75
+
76
+ def options(hash = {})
77
+ o = { :per_page => 50 }
78
+ o[:since_id] = hash[:since_id] if hash[:since_id]
79
+
80
+ o
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'twitter'
3
+
4
+ $:.unshift(File.dirname(__FILE__))
5
+ require 'thetwitthit/config'
6
+ require 'thetwitthit/properties'
7
+ require 'thetwitthit/worker'
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{thetwitthit}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Sebastian Gamboa"]
9
+ s.date = %q{2009-04-12}
10
+ s.default_executable = %q{thetwitthit}
11
+ s.description = %q{Fetches tasks from twitter and adds them to The Hit List.app}
12
+ s.email = %q{me@sagmor.com}
13
+ s.executables = ["thetwitthit"]
14
+ s.extra_rdoc_files = ["bin/thetwitthit", "lib/thetwitthit/cli/helpers.rb", "lib/thetwitthit/cli.rb", "lib/thetwitthit/config.rb", "lib/thetwitthit/properties.rb", "lib/thetwitthit/version.rb", "lib/thetwitthit/worker.rb", "lib/thetwitthit.rb", "README.rdoc"]
15
+ s.files = ["bin/thetwitthit", "lib/thetwitthit/cli/helpers.rb", "lib/thetwitthit/cli.rb", "lib/thetwitthit/config.rb", "lib/thetwitthit/properties.rb", "lib/thetwitthit/version.rb", "lib/thetwitthit/worker.rb", "lib/thetwitthit.rb", "Rakefile", "README.rdoc", "thetwitthit.gemspec", "Manifest"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/SagMor/thetwitthit}
18
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Thetwitthit", "--main", "README.rdoc"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{thetwitthit}
21
+ s.rubygems_version = %q{1.3.1}
22
+ s.summary = %q{Fetches tasks from twitter and adds them to The Hit List.app}
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 2
27
+
28
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
+ s.add_runtime_dependency(%q<twitter>, [">= 0.5.3"])
30
+ s.add_runtime_dependency(%q<main>, [">= 0", "= 2.8.2"])
31
+ s.add_runtime_dependency(%q<highline>, [">= 0", "= 1.4.0"])
32
+ else
33
+ s.add_dependency(%q<twitter>, [">= 0.5.3"])
34
+ s.add_dependency(%q<main>, [">= 0", "= 2.8.2"])
35
+ s.add_dependency(%q<highline>, [">= 0", "= 1.4.0"])
36
+ end
37
+ else
38
+ s.add_dependency(%q<twitter>, [">= 0.5.3"])
39
+ s.add_dependency(%q<main>, [">= 0", "= 2.8.2"])
40
+ s.add_dependency(%q<highline>, [">= 0", "= 1.4.0"])
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: SagMor-thetwitthit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sebastian Gamboa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-12 00:00:00 -07:00
13
+ default_executable: thetwitthit
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: twitter
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.5.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: main
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ - - "="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.8.2
37
+ version:
38
+ - !ruby/object:Gem::Dependency
39
+ name: highline
40
+ type: :runtime
41
+ version_requirement:
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ - - "="
48
+ - !ruby/object:Gem::Version
49
+ version: 1.4.0
50
+ version:
51
+ description: Fetches tasks from twitter and adds them to The Hit List.app
52
+ email: me@sagmor.com
53
+ executables:
54
+ - thetwitthit
55
+ extensions: []
56
+
57
+ extra_rdoc_files:
58
+ - bin/thetwitthit
59
+ - lib/thetwitthit/cli/helpers.rb
60
+ - lib/thetwitthit/cli.rb
61
+ - lib/thetwitthit/config.rb
62
+ - lib/thetwitthit/properties.rb
63
+ - lib/thetwitthit/version.rb
64
+ - lib/thetwitthit/worker.rb
65
+ - lib/thetwitthit.rb
66
+ - README.rdoc
67
+ files:
68
+ - bin/thetwitthit
69
+ - lib/thetwitthit/cli/helpers.rb
70
+ - lib/thetwitthit/cli.rb
71
+ - lib/thetwitthit/config.rb
72
+ - lib/thetwitthit/properties.rb
73
+ - lib/thetwitthit/version.rb
74
+ - lib/thetwitthit/worker.rb
75
+ - lib/thetwitthit.rb
76
+ - Rakefile
77
+ - README.rdoc
78
+ - thetwitthit.gemspec
79
+ - Manifest
80
+ has_rdoc: true
81
+ homepage: http://github.com/SagMor/thetwitthit
82
+ post_install_message:
83
+ rdoc_options:
84
+ - --line-numbers
85
+ - --inline-source
86
+ - --title
87
+ - Thetwitthit
88
+ - --main
89
+ - README.rdoc
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: "0"
97
+ version:
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: "1.2"
103
+ version:
104
+ requirements: []
105
+
106
+ rubyforge_project: thetwitthit
107
+ rubygems_version: 1.2.0
108
+ signing_key:
109
+ specification_version: 2
110
+ summary: Fetches tasks from twitter and adds them to The Hit List.app
111
+ test_files: []
112
+