PerfectlyNormal-Twitorious 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/TODO ADDED
@@ -0,0 +1,12 @@
1
+ * Support updating one site, a few sites, all but one site, all but a few sites, and all sites
2
+ * Support in_reply_to to send replies
3
+ * UI for displaying past updates
4
+ * Receive/send private messages
5
+ * SSL for Identi.ca authentication
6
+ * Not OS X only
7
+ * Support growling to remote machines
8
+ * Support other forms of notification (libnotify?)
9
+ * Configuration generation tool
10
+ * Error handling
11
+ * Daemon that runs in the background
12
+ * Make sure the directory for images is created
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ require 'twitorious'
3
+ require 'readline'
4
+
5
+ module Twitorious
6
+ class Twit
7
+ def initialize
8
+ File.open(File.expand_path(File.join(%w{~ twit}))) do |f|
9
+ f.each_line do |line|
10
+ Readline::HISTORY.push(line.split("\t")[1])
11
+ end
12
+ end
13
+
14
+ begin
15
+ status = Readline.readline("> ", true)
16
+ raise Twitorious::TooLongUpdate.new(status) if status.length > 140
17
+ Twitorious::Update.new(status)
18
+ rescue Twitorious::TooLongUpdate => e
19
+ puts "Ooops, you entered more than 140 characters. #{e.message.length} to be exact."
20
+ Readline::HISTORY.push(e.message)
21
+ retry
22
+ rescue Interrupt
23
+ exit
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ Twitorious::Twit.new
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ require 'twitorious'
3
+
4
+ module Twitorious
5
+ class TwitNotifier
6
+ def initialize
7
+ config = Twitorious::Config.new
8
+ timeline = Twitorious::Timeline.new(config)
9
+
10
+ timeline.fetch_timeline
11
+ end
12
+ end
13
+ end
14
+
15
+ Twitorious::TwitNotifier.new
@@ -0,0 +1,12 @@
1
+ module Twitorious
2
+ VERSION = '0.2.5'
3
+
4
+ class TooLongUpdate < StandardError; end
5
+ end
6
+
7
+ require 'twitorious/config'
8
+ require 'twitorious/timeline'
9
+ require 'twitorious/update'
10
+ require 'twitorious/image'
11
+ require 'twitorious/notifier'
12
+ require 'twitorious/api/twitter'
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module Twitorious
7
+ module API
8
+ class Twitter
9
+ def initialize(config, site)
10
+ @config = config
11
+ @site = site
12
+ @notifier = Twitorious::Notifier.new
13
+ end
14
+
15
+ def update(status)
16
+ puts "Updating #{@site[:name]}"
17
+ req = Net::HTTP::Post.new(@site[:url].path + "/statuses/update.json")
18
+ req.basic_auth @site[:user], @site[:pass]
19
+ req.set_form_data({'status' => status}, ';')
20
+ res = Net::HTTP.new(@site[:url].host, @site[:url].port).start { |http| http.request(req) }
21
+ end
22
+
23
+ def fetch_timeline
24
+ res = nil
25
+ Net::HTTP.start(@site[:url].host, @site[:url].port) do |http|
26
+ path = @site[:url].path + "/statuses/friends_timeline.json"
27
+ path += "?count=200&since_id=#{@site[:since_id]}" if @site[:since_id]
28
+ req = Net::HTTP::Get.new(path)
29
+ req.basic_auth @site[:user], @site[:pass]
30
+ res = http.request(req)
31
+ end
32
+
33
+ updates = JSON.parse(res.body)
34
+ return if updates.empty?
35
+
36
+ updates.reverse.each do |update|
37
+ image = Twitorious::Image.from_url(update["user"]["profile_image_url"], @config.image_store)
38
+ @notifier.notify(update["user"]["screen_name"], update["text"], image.filename)
39
+ sleep @config.sleep_between_notifications.to_i
40
+ end
41
+
42
+ @site[:since_id] = updates[0]["id"]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ module Twitorious
2
+ class Config
3
+ def initialize
4
+ @file = File.expand_path(File.join(['~', '.twitorious']))
5
+ @config = YAML.load_file(@file)
6
+ end
7
+
8
+ def [](key)
9
+ return @config[key] if @config.has_key?(key)
10
+ return nil
11
+ end
12
+
13
+ def []=(key, value)
14
+ @config[key] = value
15
+ return @config[key]
16
+ end
17
+
18
+ def save
19
+ File.open(@file, "w") do |f|
20
+ f.puts @config.to_yaml
21
+ end
22
+ end
23
+
24
+ def method_missing(sym, *args)
25
+ return @config[sym] if @config.has_key?(sym)
26
+ super(sym, args)
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,33 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'digest/md5'
4
+
5
+ module Twitorious
6
+ class Image
7
+ attr_reader :filename
8
+
9
+ def initialize(filename)
10
+ @filename = filename
11
+ end
12
+
13
+ def self.from_url(url, store)
14
+ file = Digest::MD5.hexdigest(url).to_s
15
+ path = File.expand_path(File.join([store, file]))
16
+
17
+ if(File.exists?(path))
18
+ return Image.new(path)
19
+ end
20
+
21
+ site = URI.parse(url)
22
+ res = Net::HTTP.start(site.host, site.port) do |http|
23
+ http.get(site.path)
24
+ end
25
+
26
+ File.open(path, "wb+") do |f|
27
+ f.puts res.body
28
+ end
29
+
30
+ return Image.new(path)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'meow'
3
+ require 'uri'
4
+
5
+ module Twitorious
6
+ class Notifier
7
+ def initialize
8
+ @meow = Meow.new("Twitorious")
9
+ end
10
+
11
+ def notify(sender, message, icon = nil)
12
+ opts = {}
13
+ opts[:icon] = icon if icon
14
+
15
+ @meow.notify("Update from #{sender}", message, opts) do
16
+ urls = URI.extract(message, ['http', 'https'])
17
+ urls.each do |url|
18
+ %x{open #{url}}
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ module Twitorious
2
+ class Timeline
3
+ def initialize(config)
4
+ @config = config
5
+ end
6
+
7
+ def fetch_timeline
8
+ @config.sites.each do |site|
9
+ case site[:api]
10
+ when "Twitter": Twitorious::API::Twitter.new(@config, site).fetch_timeline
11
+ else puts "Unknown API #{site[:api]} for site #{site[:name]}"
12
+ end
13
+ end
14
+ @config.save # Since we've gotten newer since_id's
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module Twitorious
2
+ class Update
3
+ def initialize(status, config = nil)
4
+ @status = status.to_s
5
+ @config = config
6
+ @config = Twitorious::Config.new unless @config
7
+
8
+ @config.sites.each do |site|
9
+ case site[:api]
10
+ when "Twitter": Twitorious::API::Twitter.new(@config, site).update(status)
11
+ else puts "Unknown API #{site[:api]} for site #{site[:name]}"
12
+ end
13
+ end
14
+ save_update
15
+ end
16
+
17
+ def save_update
18
+ File.open(File.expand_path(@config.update_store), "a+") do |f|
19
+ f.puts "#{Time.now.to_i}\t#{@status}"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "Twitorious"
3
+ s.version = "0.2.5"
4
+ s.date = "2009-03-23"
5
+ s.author = "Per Christian B. Viken"
6
+ s.email = "perchr@northblue.org"
7
+ s.homepage = "http://eastblue.org/projects/twitorious/"
8
+ s.platform = Gem::Platform::RUBY
9
+ s.summary = "A simple microblogging client that can post updates, and display received updates"
10
+ s.files = ["twitorious.gemspec",
11
+ "lib/twitorious.rb",
12
+ "lib/twitorious/config.rb",
13
+ "lib/twitorious/image.rb",
14
+ "lib/twitorious/timeline.rb",
15
+ "lib/twitorious/update.rb",
16
+ "lib/twitorious/notifier.rb",
17
+ "lib/twitorious/api/twitter.rb",
18
+ "TODO"]
19
+ s.executables << 'twit'
20
+ s.executables << 'twit-notifier'
21
+ s.add_dependency("meow", ">= 2.1.0")
22
+ s.add_dependency("json", ">= 1.1.0")
23
+ s.has_rdoc = true
24
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: PerfectlyNormal-Twitorious
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.5
5
+ platform: ruby
6
+ authors:
7
+ - Per Christian B. Viken
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-23 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: meow
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.1.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.0
34
+ version:
35
+ description:
36
+ email: perchr@northblue.org
37
+ executables:
38
+ - twit
39
+ - twit-notifier
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - twitorious.gemspec
46
+ - lib/twitorious.rb
47
+ - lib/twitorious/config.rb
48
+ - lib/twitorious/image.rb
49
+ - lib/twitorious/timeline.rb
50
+ - lib/twitorious/update.rb
51
+ - lib/twitorious/notifier.rb
52
+ - lib/twitorious/api/twitter.rb
53
+ - TODO
54
+ has_rdoc: true
55
+ homepage: http://eastblue.org/projects/twitorious/
56
+ post_install_message:
57
+ rdoc_options: []
58
+
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ requirements: []
74
+
75
+ rubyforge_project:
76
+ rubygems_version: 1.2.0
77
+ signing_key:
78
+ specification_version: 2
79
+ summary: A simple microblogging client that can post updates, and display received updates
80
+ test_files: []
81
+