SagMor-thetwitthit 0.1.0

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