fxtwitter 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,13 @@
1
+ === 1.0.0 / 2008-03-15
2
+
3
+ * 4 major enhancement
4
+
5
+ * Birthday!
6
+ * Read your friends' Tweets
7
+ * Post your own Tweets
8
+ * Character counter lets you know that your Tweet is short enough.
9
+
10
+ * 1 major limitation
11
+
12
+ * No tests!
13
+
data/Manifest.txt ADDED
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/fxtwitter
6
+ lib/fxtwitter.rb
7
+ test/test_fxtwitter.rb
data/README.txt ADDED
@@ -0,0 +1,56 @@
1
+ = fxtwitter
2
+
3
+ * http://projects.rubyforge.org/fxtwitte
4
+
5
+ == DESCRIPTION:
6
+
7
+ fxtwitter is a GUI client for the Twitter <http://twitter.com> system.
8
+ It provides a simple interface comparable to many popular instant
9
+ messaging chat clients.
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ * View the recent tweets of all your friends in a scrolled window
14
+ * Post your own tweets
15
+
16
+ == SYNOPSIS:
17
+
18
+ The fxtwitter executable should be installed in a file on your path. Running
19
+ the application after installation should be easy:
20
+
21
+ $ fxtwitter -u USERNAME -p PASSWORD
22
+
23
+ == REQUIREMENTS:
24
+
25
+ * Ruby (developed on 1.8.6)
26
+ * Twitter4R (developed with 0.3.0)
27
+ * FXRuby (developed with 1.6.13)
28
+
29
+ == INSTALL:
30
+
31
+ $ sudo gem install fxtwitter
32
+
33
+ == LICENSE:
34
+
35
+ (The MIT License)
36
+
37
+ Copyright (c) 2008 Brian Wisti
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining
40
+ a copy of this software and associated documentation files (the
41
+ 'Software'), to deal in the Software without restriction, including
42
+ without limitation the rights to use, copy, modify, merge, publish,
43
+ distribute, sublicense, and/or sell copies of the Software, and to
44
+ permit persons to whom the Software is furnished to do so, subject to
45
+ the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be
48
+ included in all copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
51
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
52
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
53
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
54
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
55
+ TORT OR 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,13 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/fxtwitter.rb'
6
+
7
+ Hoe.new('fxtwitter', FxTwitter::VERSION) do |p|
8
+ p.developer('Brian Wisti', 'brianwisti@rubyforge.org')
9
+ p.extra_deps << [ 'fxruby' ]
10
+ p.extra_deps << [ 'twitter4r' ]
11
+ end
12
+
13
+ # vim: syntax=Ruby
data/bin/fxtwitter ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'fxtwitter'
5
+
6
+ FxTwitter.main()
7
+
8
+ #vim:set filetype=ruby
data/lib/fxtwitter.rb ADDED
@@ -0,0 +1,187 @@
1
+ require 'rubygems'
2
+ require 'cgi'
3
+ require 'fox16'
4
+ require 'fox16/colors'
5
+ require 'time'
6
+ require 'twitter'
7
+
8
+ include Fox
9
+
10
+ class FxTwitter
11
+ VERSION = '0.1.0'
12
+ TWEET_LENGTH = 140 # Twitter allows this many characters at most.
13
+
14
+ # The primary user interface for fxtwitter
15
+ class TwitterWindow < Fox::FXMainWindow
16
+ include Fox
17
+ def initialize(app, username, password)
18
+ super(app, "fxtwitter", nil, nil,
19
+ :opts => DECOR_TITLE | DECOR_CLOSE | DECOR_RESIZE,
20
+ :width => 480)
21
+ @username = username
22
+ @password = password
23
+
24
+ # Put together UI elements
25
+ @tweet_display = FXText.new(self,
26
+ :opts => LAYOUT_FIX_WIDTH | LAYOUT_FIX_HEIGHT |
27
+ LAYOUT_FILL_X | LAYOUT_FILL_Y |
28
+ TEXT_READONLY | TEXT_WORDWRAP,
29
+ :width => 480, :height => 200)
30
+
31
+ @control_frame = FXHorizontalFrame.new(self)
32
+ @quit_btn = FXButton.new(@control_frame, "Quit")
33
+ @refresh_btn = FXButton.new(@control_frame, "Refresh")
34
+ @post_btn = FXButton.new(@control_frame, "Post")
35
+ FXHorizontalSeparator.new(@control_frame)
36
+ @length_lbl = FXLabel.new(@control_frame, TWEET_LENGTH.to_s)
37
+ @twitter_input = FXTextField.new(self, 80,
38
+ :opts => LAYOUT_FILL_X | TEXTFIELD_ENTER_ONLY,
39
+ :width => 450)
40
+ @status_line = FXStatusLine.new(self)
41
+ @status_line.normalText = "fxtwitter"
42
+
43
+ @post_btn.connect(SEL_COMMAND) do |sender, selector, data|
44
+ post_tweet()
45
+ end
46
+
47
+ @quit_btn.connect(SEL_COMMAND) do |sender, selecter, data|
48
+ quit_application()
49
+ end
50
+
51
+ @refresh_btn.connect(SEL_COMMAND) do |sender, selector, data|
52
+ update_tweets()
53
+ end
54
+
55
+ @twitter_input.connect(SEL_CHANGED) do |sender, selector, data|
56
+ @length_lbl.text = (TWEET_LENGTH - data.length).to_s
57
+ end
58
+
59
+ @twitter_input.connect(SEL_COMMAND) do |sender, selector, data|
60
+ post_tweet()
61
+ end
62
+
63
+ # Set up text styles for the twitter display
64
+ name_style = FXHiliteStyle.from_text(@tweet_display)
65
+ name_style.style = FXText::STYLE_BOLD
66
+ time_style = FXHiliteStyle.from_text(@tweet_display)
67
+ time_style.normalForeColor = FXColor::MidnightBlue
68
+ @tweet_display.styled = true
69
+ @tweet_display.hiliteStyles = [ name_style, time_style ]
70
+
71
+ # TODO: Replace global constant with config and/or user input.
72
+ @tweets_updated_at = nil
73
+ @tweets = []
74
+ end
75
+
76
+ # Opens a validated connection to the Twitter service.
77
+ def connect_to_twitter(login, password)
78
+ @status_line.text = "Connecting #{login} to Twitter"
79
+ return Twitter::Client.new(:login => login, :password => password)
80
+ end
81
+
82
+ # Part of the GUI construction code
83
+ def create()
84
+ super
85
+ show(PLACEMENT_SCREEN)
86
+ setup_twitter()
87
+ end
88
+
89
+ # Submit user text from twitter_input
90
+ def post_tweet()
91
+ tweet_text = @twitter_input.text
92
+ if tweet_text.length > 0 then
93
+ if tweet_text.length <= TWEET_LENGTH then
94
+ @status_line.text = "Posting Tweet..."
95
+ status = Twitter::Status.create(:text => tweet_text,
96
+ :client => @twitter)
97
+ @twitter_input.text = ""
98
+ @length_lbl.text = TWEET_LENGTH.to_s
99
+ else
100
+ message = "Your Tweet must have #{TWEET_LENGTH} or less characters"
101
+ FXMessageBox.warning(self, MBOX_OK, "Tweet too long!", message)
102
+ end
103
+ end
104
+ end
105
+
106
+ # Perform any needed cleanup and exit
107
+ def quit_application()
108
+ exit
109
+ end
110
+
111
+ def setup_twitter()
112
+ if @username and @password then
113
+ @twitter = connect_to_twitter(@username, @password)
114
+ update_tweets()
115
+
116
+ # Check for new Tweets every minute
117
+ timeout_duration = 60 * 1000
118
+ @refresh_timeout = app.addTimeout(timeout_duration, :repeat => true) do |sender, selector, data|
119
+ update_tweets()
120
+ end
121
+ else
122
+ # TODO: Login view
123
+ raise "Username and password required. fxtwitter --help for usage"
124
+ end
125
+ end
126
+
127
+ def update_tweets()
128
+ this_load = Time.now
129
+ @status_line.text = "#{this_load}: Updating Tweets..."
130
+ begin
131
+ if @tweets and @tweets_updated_at then
132
+ tweets = @twitter.timeline_for(:friends, :since => @tweets_updated_at)
133
+ @tweets_updated_at = Time.now
134
+ else
135
+ tweets = @twitter.timeline_for(:friends)
136
+ @tweets_updated_at = this_load
137
+ end
138
+ rescue Twitter::RESTError => e
139
+ if e.message == "Not Modified" then
140
+ @status_line.normalText = "#{this_load}: No new Tweets"
141
+ return
142
+ else
143
+ raise e
144
+ end
145
+ end
146
+ @tweets = tweets
147
+ @tweets_updated_at = this_load
148
+ @status_line.normalText = "#{@tweets_updated_at}: #{@tweets.length} new Tweets"
149
+
150
+ # Now that we have new Tweets, display them.
151
+ @tweets.reverse.each do |tweet|
152
+ created_at = tweet.created_at.strftime("%I:%M %p")
153
+ screen_name = CGI::unescapeHTML(tweet.user.screen_name)
154
+ text = ": #{CGI::unescapeHTML(tweet.text)} -- "
155
+ @tweet_display.appendStyledText(screen_name, 1)
156
+ @tweet_display.appendText(text)
157
+ @tweet_display.appendStyledText(created_at, 2)
158
+ @tweet_display.appendStyledText("\n")
159
+ @tweet_display.makePositionVisible(@tweet_display.cursorPos)
160
+ end
161
+ end
162
+
163
+ end
164
+
165
+ # Runs the fxtwitter application.
166
+ def FxTwitter.main()
167
+ require 'optparse'
168
+ login = nil
169
+ password = nil
170
+ opts = OptionParser.new
171
+ opts.on("-u", "--user USERNAME", "Twitter account name", String) { |val| login = val }
172
+ opts.on("-p", "--password PASSWORD", "Twitter account password", String) { |val| password = val }
173
+ opts.on("-h", "--help", "Show usage") { |val| puts opts.to_s; exit }
174
+ opts.parse(ARGV)
175
+
176
+ unless login and password
177
+ puts "Username and password required in this version of fxtwitter"
178
+ print opts.to_s
179
+ exit
180
+ end
181
+
182
+ application = FXApp.new
183
+ main_window = TwitterWindow.new(application, login, password)
184
+ application.create()
185
+ application.run()
186
+ end
187
+ end
@@ -0,0 +1,3 @@
1
+ # No tests yet!
2
+ # (How *do* I test a GUI?)
3
+
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fxtwitter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Brian Wisti
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-03-16 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fxruby
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: twitter4r
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: hoe
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.5.1
41
+ version:
42
+ description: fxtwitter is a GUI client for the Twitter <http://twitter.com> system. It provides a simple interface comparable to many popular instant messaging chat clients.
43
+ email:
44
+ - brianwisti@rubyforge.org
45
+ executables:
46
+ - fxtwitter
47
+ extensions: []
48
+
49
+ extra_rdoc_files:
50
+ - History.txt
51
+ - Manifest.txt
52
+ - README.txt
53
+ files:
54
+ - History.txt
55
+ - Manifest.txt
56
+ - README.txt
57
+ - Rakefile
58
+ - bin/fxtwitter
59
+ - lib/fxtwitter.rb
60
+ - test/test_fxtwitter.rb
61
+ has_rdoc: true
62
+ homepage: http://projects.rubyforge.org/fxtwitte
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --main
66
+ - README.txt
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ requirements: []
82
+
83
+ rubyforge_project: fxtwitter
84
+ rubygems_version: 1.0.1
85
+ signing_key:
86
+ specification_version: 2
87
+ summary: fxtwitter is a GUI client for the Twitter <http://twitter.com> system
88
+ test_files:
89
+ - test/test_fxtwitter.rb