twitterpunch 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -14
- data/bin/twitterpunch +8 -4
- data/lib/twitterpunch.rb +1 -1
- data/lib/twitterpunch/configuration.rb +2 -3
- data/lib/twitterpunch/logger.rb +1 -1
- data/lib/twitterpunch/sprite.rb +69 -18
- data/lib/twitterpunch/streamer.rb +24 -17
- data/lib/twitterpunch/viewer.rb +26 -14
- metadata +36 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c881f24bd1e7cc981175e5f5fb52f80a7725e12f
|
4
|
+
data.tar.gz: 7516403fe3be89a85cf8ac0a11427857a28119a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e2a4303a64a59f3cee1c582b74706fdbff6f7095ea60b3b4adcbc2c3c85c404f384f07d1b94e7c9abaed2c6ee340f2dcd1f8292ccbc67602b7f19e58110ebe1
|
7
|
+
data.tar.gz: 6c147d09131b4393231a97d531fe029fa3101299aff4e0dc154c3223c49b9407f684020559bd1102d1f0ebbb48f7faa8a111661da831ad1045d96197b7c1b420
|
data/README.md
CHANGED
@@ -17,20 +17,20 @@ Configure the program via the `~/.twitterpunch.yaml` YAML file. This file should
|
|
17
17
|
look similar to the example below.
|
18
18
|
|
19
19
|
---
|
20
|
-
:twitter:
|
20
|
+
:twitter: # twitter configuration
|
21
21
|
:consumer_key: <consumer key>
|
22
22
|
:consumer_secret: <consumer secret>
|
23
23
|
:access_token: <access token>
|
24
24
|
:access_token_secret: <access secret>
|
25
|
-
:messages:
|
26
|
-
- Hello there
|
25
|
+
:messages: # list of messages to attach
|
26
|
+
- Hello there # to outgoing tweets
|
27
27
|
- I'm a posting fool
|
28
28
|
- minimally viable product
|
29
|
-
:hashtag:
|
30
|
-
:
|
31
|
-
:
|
32
|
-
:
|
33
|
-
|
29
|
+
:hashtag: Twitterpunch # The hashtag to post and listen to
|
30
|
+
:photodir: ~/Pictures/twitterpunch/ # Where to save downloaded images
|
31
|
+
:logfile: ~/.twitterpunch.log # Where to save logs
|
32
|
+
:viewer: # Use the built-in slideshow viewer
|
33
|
+
:count: 5 # How many images to have onscreen at once
|
34
34
|
|
35
35
|
A skeleton configuration file, with access tokens from Twitter, can be generated
|
36
36
|
by running the program with the `--genconfig` flag.
|
@@ -71,14 +71,18 @@ multiple files at once.
|
|
71
71
|
|
72
72
|
### Viewing the Twitter stream
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
user will be spoken aloud.
|
74
|
+
Twitterpunch will run on OS X or Windows equally well. Simply configure it on the
|
75
|
+
computer that will act as the Twitter display and then run in streaming mode.
|
76
|
+
All images tweeted to the configured hashtag will be displayed in the slideshow
|
77
|
+
and tweets that come from any other user will also be spoken aloud.
|
79
78
|
|
80
79
|
[ben@ganymede] ~ $ twitterpunch --stream
|
81
80
|
|
81
|
+
If you don't want to use the built-in slideshow viewer, you can disable it by
|
82
|
+
removing the `:viewer` key from your `~/.twitterpunch.yaml` config file. Twitterpunch
|
83
|
+
will then simply download the tweeted images and save them into the `:photodir`
|
84
|
+
directory. You can then use anything you like to view them.
|
85
|
+
|
82
86
|
There are currently two decent viewing options I am aware of.
|
83
87
|
|
84
88
|
* Windows background image:
|
@@ -98,7 +102,7 @@ Limitations
|
|
98
102
|
===========
|
99
103
|
|
100
104
|
* It currently requires manual setup for Folder Actions.
|
101
|
-
*
|
105
|
+
* Rubygame is kind of a pain to set up.
|
102
106
|
|
103
107
|
|
104
108
|
Contact
|
data/bin/twitterpunch
CHANGED
@@ -66,11 +66,14 @@ when :stream
|
|
66
66
|
require 'twitterpunch/streamer'
|
67
67
|
require 'twitterpunch/viewer'
|
68
68
|
|
69
|
-
statefile
|
70
|
-
|
69
|
+
statefile = File.expand_path('~/.twitterpunch.state')
|
70
|
+
viewer = Twitterpunch::Viewer.new(config)
|
71
|
+
|
72
|
+
config[:state] = YAML.load_file(statefile) rescue {}
|
73
|
+
config[:display] = viewer
|
71
74
|
|
72
75
|
Twitterpunch::Streamer.new(config).thread
|
73
|
-
|
76
|
+
viewer.run
|
74
77
|
|
75
78
|
File.open(statefile, 'w') {|f| f.write(config[:state].to_yaml) }
|
76
79
|
|
@@ -85,7 +88,8 @@ when :view
|
|
85
88
|
statefile = File.expand_path('~/.twitterpunch.state')
|
86
89
|
config[:state] = YAML.load_file(statefile) rescue {}
|
87
90
|
|
88
|
-
|
91
|
+
viewer = Twitterpunch::Viewer.new(config)
|
92
|
+
viewer.run
|
89
93
|
|
90
94
|
when :configure
|
91
95
|
require 'twitterpunch/configuration'
|
data/lib/twitterpunch.rb
CHANGED
@@ -59,10 +59,9 @@ module Twitterpunch
|
|
59
59
|
:viewer => {
|
60
60
|
:count => 5,
|
61
61
|
},
|
62
|
-
:hashtag => "
|
63
|
-
:handle => "fassford",
|
62
|
+
:hashtag => "Twitterpunch",
|
64
63
|
:photodir => "~/Pictures/twitterpunch/",
|
65
|
-
:logfile => '
|
64
|
+
:logfile => '~/.twitterpunch.log',
|
66
65
|
}
|
67
66
|
end
|
68
67
|
end
|
data/lib/twitterpunch/logger.rb
CHANGED
data/lib/twitterpunch/sprite.rb
CHANGED
@@ -6,34 +6,55 @@ module Twitterpunch
|
|
6
6
|
include Rubygame
|
7
7
|
include Sprites::Sprite
|
8
8
|
|
9
|
-
def initialize(dimensions, image, text)
|
9
|
+
def initialize(dimensions, image, text, pop=false)
|
10
10
|
# Invoking the base class constructor is important and yet easy to forget:
|
11
11
|
super()
|
12
12
|
|
13
13
|
@dimensions = dimensions
|
14
|
+
@popped = pop
|
15
|
+
@text = text
|
16
|
+
@original = Surface.load(image)
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
if pop
|
19
|
+
@image = @original
|
20
|
+
@start = Time.now
|
21
|
+
@stale = 10
|
22
|
+
else
|
23
|
+
@rate = rand(35..150)
|
24
|
+
@zoom = rand(50..100) / 100.0
|
25
|
+
@image = @original.zoom(@zoom)
|
26
|
+
end
|
20
27
|
|
21
28
|
max_width = dimensions[0] * 0.75
|
22
29
|
if @image.width > max_width
|
23
|
-
|
30
|
+
factor = max_width/@image.width
|
31
|
+
@original = @original.zoom(factor)
|
32
|
+
@image = @image.zoom(factor)
|
33
|
+
end
|
34
|
+
|
35
|
+
if pop
|
36
|
+
@left = (dimensions[0] - @image.width) / 2
|
37
|
+
@top = (dimensions[1] - @image.height) / 2
|
38
|
+
else
|
39
|
+
@left = (dimensions[0] - @image.width ) * rand
|
40
|
+
@top = 0 - @image.height
|
24
41
|
end
|
25
42
|
|
26
|
-
@top = 0 - @image.height
|
27
|
-
@left = (dimensions[0] - @image.width ) * rand
|
28
43
|
@rect = @image.make_rect
|
29
44
|
|
30
|
-
|
31
|
-
|
32
|
-
|
45
|
+
render_text
|
46
|
+
end
|
47
|
+
|
48
|
+
def render_text
|
49
|
+
if @text
|
50
|
+
text = $font.render_utf8(@text, true, Color[:black], Color[:gray])
|
51
|
+
|
52
|
+
# for some reason, windows doesn't deal with this properly
|
53
|
+
text.alpha = 150 unless RUBY_PLATFORM =~ /mingw|cygwin/
|
33
54
|
|
34
55
|
# Determine the dimensions in pixels of the area used to render the text. The
|
35
56
|
# "topleft" of the returned rectangle is at [ 0, 0]
|
36
|
-
rt =
|
57
|
+
rt = text.make_rect
|
37
58
|
|
38
59
|
# Re-use the "topleft" of the rectangle to indicate where the text should
|
39
60
|
# appear on screen ( lower left corner )
|
@@ -41,16 +62,34 @@ module Twitterpunch
|
|
41
62
|
rt.topleft = [ 0, @image.height - rt.height]
|
42
63
|
|
43
64
|
# Copy the pixels of the rendered text to the image
|
44
|
-
|
65
|
+
text.blit(@image, rt)
|
45
66
|
end
|
46
67
|
end
|
47
68
|
|
48
|
-
# Animate this object. "seconds_passed" contains the number of
|
69
|
+
# Animate this object. "seconds_passed" contains the number of real-world
|
49
70
|
# seconds that have passed since the last time this object was updated and is
|
50
|
-
# therefore useful for working out how far the object should move (
|
71
|
+
# therefore useful for working out how far the object should move (which
|
51
72
|
# should be independent of the frame rate)
|
52
73
|
def update(seconds_passed)
|
53
|
-
|
74
|
+
if @popped
|
75
|
+
elapsed = (Time.now - @start).to_f
|
76
|
+
|
77
|
+
if elapsed < 1
|
78
|
+
scale = 1 + damped_sin(elapsed, 4, 0.05)
|
79
|
+
|
80
|
+
@image = @original.zoom(scale)
|
81
|
+
@top *= scale
|
82
|
+
@left *= scale
|
83
|
+
|
84
|
+
# We changed image size, so rebuild the rect and draw new text
|
85
|
+
@rect = @image.make_rect
|
86
|
+
render_text
|
87
|
+
elsif elapsed > @stale
|
88
|
+
@image.alpha -= 5
|
89
|
+
end
|
90
|
+
else
|
91
|
+
@top += seconds_passed * @rate
|
92
|
+
end
|
54
93
|
@rect.topleft = [ @left, @top ]
|
55
94
|
end
|
56
95
|
|
@@ -59,7 +98,19 @@ module Twitterpunch
|
|
59
98
|
end
|
60
99
|
|
61
100
|
def visible
|
62
|
-
|
101
|
+
if @popped
|
102
|
+
@image.alpha > 0
|
103
|
+
else
|
104
|
+
@top < @dimensions[1]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def damped_sin(input, cycles = 4, scale = 1)
|
109
|
+
Math.sin(input * cycles * Math::PI) * (1 - input) * scale
|
110
|
+
end
|
111
|
+
|
112
|
+
def popped?
|
113
|
+
return @popped
|
63
114
|
end
|
64
115
|
end
|
65
116
|
end
|
@@ -12,6 +12,8 @@ module Twitterpunch
|
|
12
12
|
@client = Twitter::Streaming::Client.new(config[:twitter])
|
13
13
|
@logger = Twitterpunch::Logger.new(config)
|
14
14
|
@output = File.expand_path(config[:photodir])
|
15
|
+
@handle = Twitter::REST::Client.new(config[:twitter]).current_user.screen_name
|
16
|
+
@viewer = config[:display]
|
15
17
|
|
16
18
|
FileUtils.mkdir_p(@output) unless File.directory?(@output)
|
17
19
|
end
|
@@ -31,18 +33,6 @@ module Twitterpunch
|
|
31
33
|
|
32
34
|
content = tweet.text.gsub(/ http\S*/,'').gsub(/#\S*/,'')
|
33
35
|
|
34
|
-
|
35
|
-
unless tweet.user.screen_name == @config[:handle]
|
36
|
-
message = "#{tweet.user.name} says #{content}"
|
37
|
-
|
38
|
-
case RUBY_PLATFORM
|
39
|
-
when /mingw|cygwin/
|
40
|
-
system('cscript', "#{@config[:resources]}/say.vbs", message)
|
41
|
-
when /darwin/
|
42
|
-
system('say', message)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
36
|
if tweet.media?
|
47
37
|
uri = tweet.media.first.media_uri
|
48
38
|
|
@@ -56,16 +46,33 @@ module Twitterpunch
|
|
56
46
|
file.write(response.body)
|
57
47
|
end
|
58
48
|
|
59
|
-
unless tweet.user.screen_name == @
|
49
|
+
unless tweet.user.screen_name == @handle
|
60
50
|
@config[:state][image] = content
|
61
51
|
end
|
62
52
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
53
|
+
if @viewer
|
54
|
+
@viewer.pop(image, content)
|
55
|
+
else
|
56
|
+
# OS X screensaver doesn't reload images dynamically. This kinda sucks.
|
57
|
+
if RUBY_PLATFORM =~ /darwin/ and system('pgrep ScreenSaverEngine >/dev/null')
|
58
|
+
system('osascript', '-e', 'tell application "System Events" to stop current screen saver')
|
59
|
+
system('osascript', '-e', 'tell application "System Events" to start current screen saver')
|
60
|
+
end
|
67
61
|
end
|
62
|
+
|
68
63
|
end
|
64
|
+
|
65
|
+
unless tweet.user.screen_name == @handle
|
66
|
+
message = "#{tweet.user.name} says #{content}"
|
67
|
+
|
68
|
+
case RUBY_PLATFORM
|
69
|
+
when /mingw|cygwin/
|
70
|
+
system('cscript', "#{@config[:resources]}/say.vbs", message)
|
71
|
+
when /darwin/
|
72
|
+
system('say', message)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
69
76
|
end
|
70
77
|
end
|
71
78
|
rescue Interrupt => e
|
data/lib/twitterpunch/viewer.rb
CHANGED
@@ -9,18 +9,19 @@ module Twitterpunch
|
|
9
9
|
|
10
10
|
def initialize(config)
|
11
11
|
@config = config
|
12
|
-
@state = YAML.load_file(File.expand_path('~/.twitterpunch.state')) rescue {}
|
13
12
|
srand
|
13
|
+
end
|
14
14
|
|
15
|
+
def run
|
15
16
|
if @config.has_key? :viewer
|
16
|
-
|
17
|
+
display
|
17
18
|
else
|
18
19
|
puts 'Press enter to exit'
|
19
20
|
STDIN.gets
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
def
|
24
|
+
def display
|
24
25
|
onscreen = @config[:viewer][:count] || 5
|
25
26
|
|
26
27
|
# Set up the TrueType Font module
|
@@ -30,9 +31,9 @@ module Twitterpunch
|
|
30
31
|
|
31
32
|
#@screen = Screen.open [ 640, 480]
|
32
33
|
default_depth = 0
|
33
|
-
maximum_resolution = Screen.get_resolution
|
34
|
+
@maximum_resolution = Screen.get_resolution
|
34
35
|
|
35
|
-
screen = Screen.open(maximum_resolution, default_depth, [ HWSURFACE, DOUBLEBUF, FULLSCREEN])
|
36
|
+
screen = Screen.open(@maximum_resolution, default_depth, [ HWSURFACE, DOUBLEBUF, FULLSCREEN])
|
36
37
|
|
37
38
|
screen.show_cursor = false
|
38
39
|
|
@@ -45,15 +46,15 @@ module Twitterpunch
|
|
45
46
|
|
46
47
|
# Create a new group of sprites so that all sprites in the group may be updated
|
47
48
|
# or drawn with a single method invocation.
|
48
|
-
sprites = Sprites::Group.new
|
49
|
-
Sprites::UpdateGroup.extend_object(sprites)
|
49
|
+
@sprites = Sprites::Group.new
|
50
|
+
Sprites::UpdateGroup.extend_object(@sprites)
|
50
51
|
onscreen.times do
|
51
|
-
sprites << Twitterpunch::Sprite.new(maximum_resolution, *next_image)
|
52
|
+
@sprites << Twitterpunch::Sprite.new(@maximum_resolution, *next_image)
|
52
53
|
end
|
53
54
|
|
54
55
|
#@background = Surface.load("background.png").zoom_to(maximum_resolution[0], maximum_resolution[1])
|
55
56
|
# Create a background image and copy it to the screen. With no image, it's just black.
|
56
|
-
background = Surface.new(maximum_resolution)
|
57
|
+
background = Surface.new(@maximum_resolution)
|
57
58
|
background.blit(screen, [ 0, 0])
|
58
59
|
|
59
60
|
event_queue = EventQueue.new
|
@@ -71,26 +72,37 @@ module Twitterpunch
|
|
71
72
|
end
|
72
73
|
|
73
74
|
# remove all sprites who've gone out of sight
|
74
|
-
sprites.reject { |sprite| sprite.visible }.each do |sprite|
|
75
|
+
@sprites.reject { |sprite| sprite.visible }.each do |sprite|
|
76
|
+
sprite.undraw(screen, background)
|
75
77
|
sprite.kill
|
76
|
-
|
78
|
+
next if sprite.popped?
|
79
|
+
|
80
|
+
@sprites << Twitterpunch::Sprite.new(@maximum_resolution, *next_image)
|
77
81
|
end
|
78
82
|
|
79
83
|
# "undraw" all of the sprites by drawing the background image at their
|
80
84
|
# current location ( before their location has been changed by the animation)
|
81
|
-
sprites.undraw(screen, background)
|
85
|
+
@sprites.undraw(screen, background)
|
82
86
|
|
83
87
|
# Give all of the sprites an opportunity to move themselves to a new location
|
84
|
-
sprites.update(seconds_passed)
|
88
|
+
@sprites.update(seconds_passed)
|
85
89
|
|
86
90
|
# Draw all of the sprites
|
87
|
-
sprites.draw(screen)
|
91
|
+
@sprites.draw(screen)
|
92
|
+
|
93
|
+
# Then redraw the popped sprite to ensure it's on top
|
94
|
+
@sprites.select { |sprite| sprite.popped? }.each { |popped| popped.draw(screen) }
|
88
95
|
|
89
96
|
screen.flip
|
90
97
|
end
|
91
98
|
|
92
99
|
end
|
93
100
|
|
101
|
+
def pop(image, text)
|
102
|
+
path = File.expand_path("#{@config[:photodir]}/#{image}")
|
103
|
+
@sprites << Twitterpunch::Sprite.new(@maximum_resolution, path, text, true)
|
104
|
+
end
|
105
|
+
|
94
106
|
def next_image
|
95
107
|
image = Dir.glob(File.expand_path("#{@config[:photodir]}/*")).sample
|
96
108
|
text = @config[:state][File.basename(image)]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twitterpunch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Ford
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: twitter
|
@@ -74,15 +74,19 @@ description: "Twitterpunch\n===============\n\nTwitterpunch is designed to work
|
|
74
74
|
them to a specified directory. If\nthe tweet came from another user, Twitterpunch
|
75
75
|
will speak it aloud.\n\nConfiguration\n===========\n\nConfigure the program via
|
76
76
|
the `~/.twitterpunch.yaml` YAML file. This file should\nlook similar to the example
|
77
|
-
below.\n\n ---\n :twitter
|
78
|
-
<consumer
|
79
|
-
<access
|
80
|
-
|
81
|
-
\
|
82
|
-
\
|
83
|
-
|
84
|
-
|
85
|
-
|
77
|
+
below.\n\n ---\n :twitter: # twitter configuration\n
|
78
|
+
\ :consumer_key: <consumer key>\n :consumer_secret: <consumer secret>\n
|
79
|
+
\ :access_token: <access token>\n :access_token_secret: <access secret>\n
|
80
|
+
\ :messages: # list of messages to attach\n -
|
81
|
+
Hello there # to outgoing tweets\n - I'm a posting
|
82
|
+
fool\n - minimally viable product\n :hashtag: Twitterpunch #
|
83
|
+
The hashtag to post and listen to\n :photodir: ~/Pictures/twitterpunch/ #
|
84
|
+
Where to save downloaded images\n :logfile: ~/.twitterpunch.log # Where
|
85
|
+
to save logs\n :viewer: # Use the built-in slideshow
|
86
|
+
viewer\n :count: 5 # How many images to have onscreen
|
87
|
+
at once\n\nA skeleton configuration file, with access tokens from Twitter, can be
|
88
|
+
generated\nby running the program with the `--genconfig` flag.\n\nUsage \n==========\n\n###
|
89
|
+
Using OS X PhotoBooth\n\n1. Start PhotoBooth at least once to generate its library.\n1.
|
86
90
|
Install the Twitterpunch Folder Action\n * `twitterpunch --install`\n * It
|
87
91
|
may claim that it could not be attached, fear not.\n1. Profit!\n * _and by that,
|
88
92
|
I mean take some shots with PhotoBooth!_\n\n#### Troubleshooting.\n\n1. Make sure
|
@@ -97,24 +101,27 @@ description: "Twitterpunch\n===============\n\nTwitterpunch is designed to work
|
|
97
101
|
the program you are using for your photo shoot to call Twitterpunch\neach time it
|
98
102
|
snaps a photo. Pass the name of the new photo as a command line\nargument. Alternatively,
|
99
103
|
you could batch them, as Twitterpunch can accept\nmultiple files at once.\n\n [ben@ganymede]
|
100
|
-
~ $ twitterpunch photo.jpg\n\n### Viewing the Twitter stream\n\
|
101
|
-
|
102
|
-
the
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
104
|
+
~ $ twitterpunch photo.jpg\n\n### Viewing the Twitter stream\n\nTwitterpunch will
|
105
|
+
run on OS X or Windows equally well. Simply configure it on the\ncomputer that will
|
106
|
+
act as the Twitter display and then run in streaming mode.\nAll images tweeted to
|
107
|
+
the configured hashtag will be displayed in the slideshow\nand tweets that come
|
108
|
+
from any other user will also be spoken aloud.\n\n [ben@ganymede] ~ $ twitterpunch
|
109
|
+
--stream\n\nIf you don't want to use the built-in slideshow viewer, you can disable
|
110
|
+
it by\nremoving the `:viewer` key from your `~/.twitterpunch.yaml` config file.
|
111
|
+
Twitterpunch\nwill then simply download the tweeted images and save them into the
|
112
|
+
`:photodir`\ndirectory. You can then use anything you like to view them.\n\nThere
|
113
|
+
are currently two decent viewing options I am aware of.\n\n* Windows background
|
114
|
+
image:\n * Configure the Windows background to randomly cycle through photos
|
115
|
+
in a directory.\n * Hide desktop icons.\n * Hide the taskbar.\n * Disable
|
116
|
+
screensaver and power savings.\n * Drawbacks: You're using Windows and you have
|
117
|
+
to install Ruby & RubyGems manually.\n* OS X screensaver:\n * Choose one of the
|
118
|
+
sexy screensavers and configure it to show photos from the `:photodir`\n * Set
|
119
|
+
screensaver to a super short timeout.\n * Disable power savings.\n * Drawbacks:
|
120
|
+
The screensaver doesn't reload dynamically, so I have to kick it\n and you'll
|
121
|
+
see it reloading each time a new tweet comes in.\n\nLimitations\n===========\n\n*
|
122
|
+
It currently requires manual setup for Folder Actions.\n* Rubygame is kind of a
|
123
|
+
pain to set up.\n\n\nContact\n=======\n\n* Author: Ben Ford\n* Email: binford2k@gmail.com\n*
|
124
|
+
Twitter: @binford2k\n* IRC (Freenode): binford2k\n"
|
118
125
|
email: binford2k@gmail.com
|
119
126
|
executables:
|
120
127
|
- twitterpunch
|