twitterpunch 0.0.5 → 0.0.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7cb13b290389bd6f3b20b57181852594cf5bfcd0
4
- data.tar.gz: a23c5888916326fd00d7e5bf21d30659b43d9358
3
+ metadata.gz: f713d6cb1c1e707769c09897f11913046bbffbd4
4
+ data.tar.gz: c37e34a59d06f4e0f6edfcfee3d23e0d87af4b77
5
5
  SHA512:
6
- metadata.gz: 1c47fa244a2615e42532731e7a5c56076ca4b885058bf66613e2836d86150684d960fcb9f8ffb1add623aea146e3f458b6b2696519b8206981c7f9327eccb939
7
- data.tar.gz: 5e7893d78b0c84c6d804e5d091996edb3b689a306a2e48ade06a51379e56190be1a7f2a97d082b5282b62af10df0861922cce21808a763b0ecfa47b1cfef6b3d
6
+ metadata.gz: 840fce97e3c6a0b6b55d34aea8080a2bc82873bcb528b6e108036544e6427b48b542eac7509b1cbce852fb0dd108c0dba010df85bb261da23efa3eed4642e7cd
7
+ data.tar.gz: 789cc9841fb3bf2b22f0184ff425fca27b8bf8b33aeaf76312efba604d07bbdecb041063ff1cc4cdf2f5508037c5676e4d1644cde99056ef6850a4c80942cd6e
@@ -4,10 +4,14 @@ require 'rubygems'
4
4
  require 'twitter'
5
5
  require 'optparse'
6
6
  require "net/http"
7
+ require 'fileutils'
7
8
  require 'yaml'
8
9
 
9
10
  require 'twitterpunch'
10
11
 
12
+ FileUtils.mkdir_p File.expand_path('~/.twitterpunch')
13
+ FileUtils.touch(File.expand_path('~/.twitterpunch/queue.yaml'))
14
+
11
15
  configfile = File.expand_path('~/.twitterpunch.yaml')
12
16
  config = YAML.load_file(configfile) rescue {}
13
17
 
@@ -44,10 +48,18 @@ optparse = OptionParser.new { |opts|
44
48
  config[:action] = :configure
45
49
  end
46
50
 
47
- opts.on("-i", "--install", "Install the Folder Action workflow (OS X only).") do
51
+ opts.on("-i", "--remote", "Start the Twitterpunch remote web service") do
52
+ config[:action] = :remote
53
+ end
54
+
55
+ opts.on("-r", "--install", "Install the Folder Action workflow (OS X only).") do
48
56
  config[:action] = :install
49
57
  end
50
58
 
59
+ opts.on("-t", "--test", "Load up Pry debugging console.") do
60
+ config[:action] = :test
61
+ end
62
+
51
63
  opts.on("-v", "--version", "Display version information.") do
52
64
  puts "Twitterpunch v#{Twitterpunch::VERSION}"
53
65
  exit 0
@@ -62,8 +74,11 @@ optparse = OptionParser.new { |opts|
62
74
  }
63
75
  optparse.parse!
64
76
 
65
- config[:action] = :post if ARGV.size > 0 and config[:action].nil?
66
- config[:resources] = File.expand_path("#{File.dirname(__FILE__)}/../resources")
77
+ config[:action] = :post if ARGV.size > 0 and config[:action].nil?
78
+ config[:resources] = File.expand_path("#{File.dirname(__FILE__)}/../resources")
79
+ config[:queue] = {}
80
+ config[:queue][:file] = File.expand_path('~/.twitterpunch/queue.yaml')
81
+ config[:queue][:ttl] = 30
67
82
 
68
83
  case config[:action]
69
84
  when :stream
@@ -103,6 +118,20 @@ when :configure
103
118
  when :install
104
119
  system('open', "#{config[:resources]}/Twitterpunch.workflow")
105
120
 
121
+ when :remote
122
+ require 'twitterpunch/remote'
123
+ options = {
124
+ :port => 8080,
125
+ :bind => '0.0.0.0',
126
+ :queue => Twitterpunch::Queue.new(config),
127
+ }
128
+
129
+ Twitterpunch::Remote.run! options
130
+
131
+ when :test
132
+ require 'pry'
133
+ binding.pry
134
+
106
135
  else
107
136
  puts "Run twitterpunch --help for usage."
108
137
  exit 1
@@ -1,5 +1,5 @@
1
1
  module Twitterpunch
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
 
4
4
  # Twitter application credentials
5
5
  API_KEY = 'STurW17Tj7HuoZ7dSzS0uSoIP'
@@ -1,34 +1,40 @@
1
1
  require 'rubygems'
2
2
  require 'twitter'
3
+ require 'twitterpunch/queue'
3
4
 
4
5
  module Twitterpunch
5
6
  class Poster
6
7
  def initialize(config)
7
8
  @config = config
8
9
  @client = Twitter::REST::Client.new(config[:twitter])
10
+ @sound = @config[:sendsound] || "#{@config[:resources]}/tweet_sent.wav"
11
+ @length = 113 - @config[:hashtag].length
12
+ @queue = Twitterpunch::Queue.new(config)
9
13
  end
10
14
 
11
15
  def post(files)
12
16
  files.each do |img|
17
+ message = @queue.pop || @config[:messages].sample
18
+ message = "#{message[0..@length]} ##{@config[:hashtag]}"
13
19
 
14
- message = "#{@config[:messages].sample} ##{@config[:hashtag]}"
15
20
  @client.update_with_media(message, File.new(File.expand_path(img)))
21
+ chirp()
22
+ end
23
+ end
16
24
 
17
- soundfile = @config[:sendsound] || "#{@config[:resources]}/tweet_sent.wav"
18
-
19
- case RUBY_PLATFORM
20
- when /mingw|cygwin/
21
- begin
22
- require 'win32/sound'
23
- Win32::Sound.play(soundfile)
24
- rescue LoadError
25
- puts 'gem install win32-sound to enable sounds.'
26
- end
27
- when /darwin/
28
- system("afplay #{soundfile}")
25
+ def chirp
26
+ case RUBY_PLATFORM
27
+ when /mingw|cygwin/
28
+ begin
29
+ require 'win32/sound'
30
+ Win32::Sound.play(@sound)
31
+ rescue LoadError
32
+ puts 'gem install win32-sound to enable sounds.'
29
33
  end
30
-
34
+ when /darwin/
35
+ system("afplay #{@sound}")
31
36
  end
32
37
  end
38
+
33
39
  end
34
40
  end
@@ -0,0 +1,53 @@
1
+ class Twitterpunch::Queue
2
+ def initialize(config)
3
+ @config = config
4
+ @file = config[:queue][:file]
5
+ @ttl = config[:queue][:ttl]
6
+ end
7
+
8
+ def pop
9
+ message = nil
10
+ File.open(@file, 'r+') do |file|
11
+ file.flock(File::LOCK_EX)
12
+ queue = load(file)
13
+
14
+ unless queue.empty?
15
+ if RUBY_VERSION < "1.9.3"
16
+ message = queue[queue.keys.sort.first]
17
+ else
18
+ message = queue.shift[1]
19
+ end
20
+ end
21
+
22
+ save(file, queue)
23
+ end
24
+ message
25
+ end
26
+
27
+ def push(message)
28
+ return unless message.is_a? String
29
+ return if message.empty?
30
+ File.open(@file, 'r+') do |file|
31
+ file.flock(File::LOCK_EX)
32
+
33
+ queue = load(file)
34
+ queue[Time.now] = message
35
+ save(file, queue)
36
+ end
37
+ end
38
+
39
+ def load(file)
40
+ queue = YAML.load(file.read) rescue {}
41
+ queue ||= {}
42
+
43
+ # forcibly expire anything that's too old.
44
+ queue.select { |k,v| (Time.now - k) < @ttl }
45
+ end
46
+
47
+ def save(file, queue)
48
+ puts "Saving #{queue.inspect}"
49
+ file.rewind
50
+ file.truncate 0
51
+ file.write(queue.to_yaml)
52
+ end
53
+ end
@@ -0,0 +1,54 @@
1
+ require 'sinatra/base'
2
+ require 'webrick'
3
+ require 'tilt/erb'
4
+ require 'open3'
5
+ require 'twitterpunch/queue'
6
+
7
+ class Twitterpunch::Remote < Sinatra::Base
8
+
9
+ set :views, File.dirname(__FILE__) + '/../../views'
10
+ set :public_folder, File.dirname(__FILE__) + '/../../public'
11
+ set :erb, :trim => '-'
12
+ set :configfile, File.expand_path('~/.twitterpunch/queue.yaml')
13
+
14
+ configure :production, :development do
15
+ enable :logging
16
+ enable :sessions
17
+ system('osascript', '-e' 'tell application "Photo Booth" to activate')
18
+ end
19
+
20
+ get '/' do
21
+ erb :index
22
+ end
23
+
24
+ get '/photo' do
25
+ settings.queue.push(params[:message]) unless params.empty?
26
+ photo()
27
+ end
28
+
29
+ not_found do
30
+ status 404
31
+ end
32
+
33
+ helpers do
34
+ def photo
35
+ begin
36
+ stdout, status = Open3.capture2e('osascript', '-e', 'tell application "Photo Booth" to activate')
37
+ puts stdout
38
+ raise "Could not activate Photo Booth" unless status.success?
39
+
40
+ # This is kind of iffy, because it depends on having full control over the UI.
41
+ # This will only work when Photo Booth actually has the foreground.
42
+ stdout, status = Open3.capture2e('osascript', '-e', 'tell application "System Events" to keystroke return')
43
+ puts stdout
44
+ raise "Snapshot failed" unless status.success?
45
+
46
+ 'ok'
47
+ rescue => e
48
+ status 500
49
+ e.message
50
+ end
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,147 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
5
+ <meta name="apple-mobile-web-app-capable" content="yes">
6
+ <meta name="apple-mobile-web-app-title" content="Twitterpunch" />
7
+ <meta name="apple-mobile-web-app-status-bar-style" content="black">
8
+ <link rel="apple-touch-icon" sizes="120x120" href="touch-icon-iphone-retina.png">
9
+ <link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad-retina.png">
10
+ <title>Twitterpunch Remote</title>
11
+ <style>
12
+ body {
13
+ display: flex;
14
+ flex-direction: column;
15
+ margin: 0;
16
+ padding: 0;
17
+ height: 100%;
18
+ width: 100%;
19
+ background-color: black;
20
+ }
21
+ #message {
22
+ flex: 1;
23
+ font-size: 16px;
24
+ }
25
+ input[type=button] {
26
+ flex: 4;
27
+ margin: 5px;
28
+ padding: 0;
29
+ font-size: 104pt;
30
+ font-weight: bolder;
31
+ background-color: #5e5959;
32
+ border: 6px solid #ccc;
33
+ border-radius: 32px;
34
+ white-space:normal;
35
+ -webkit-appearance: none;
36
+ }
37
+ input.active {
38
+ color: white;
39
+ font-size: 64pt;
40
+ background-color: #5e2524;
41
+ }
42
+ body.focused #message {
43
+ flex: 2;
44
+ }
45
+ body.focused input[type=button] {
46
+ flex: 3;
47
+ margin-bottom: 325px;
48
+ font-size: 64pt;
49
+ }
50
+
51
+ @media screen and (max-width: 370px) and (orientation:portrait) {
52
+ input[type=button] {
53
+ font-size: 64pt;
54
+ }
55
+ input.active {
56
+ font-size: 52pt;
57
+ }
58
+ body.focused #message {
59
+ flex: 6;
60
+ }
61
+ body.focused input[type=button] {
62
+ flex: 4;
63
+ margin-bottom: 250px;
64
+ font-size: 20pt;
65
+ border-radius: 6px;
66
+ padding: 0;
67
+ }
68
+ }
69
+ @media screen and (max-width: 650px) and (orientation:landscape) {
70
+ input[type=button] {
71
+ font-size: 84pt;
72
+ }
73
+ input.active {
74
+ font-size: 56pt;
75
+ }
76
+ }
77
+ </style>
78
+ <script type="text/javascript">
79
+ function get(url, callback) {
80
+ var xmlHttp = new XMLHttpRequest();
81
+ xmlHttp.onreadystatechange = function() {
82
+ if (xmlHttp.readyState == 4) {
83
+ if(xmlHttp.status == 200) {
84
+ if(typeof(callback) == 'function') {
85
+ callback(xmlHttp.responseText);
86
+ }
87
+ }
88
+ else {
89
+ console.log(xmlHttp.responseText);
90
+ }
91
+ }
92
+ }
93
+ xmlHttp.open("GET", url, true);
94
+ xmlHttp.send(null);
95
+ }
96
+ function activate() {
97
+ var msg = document.getElementById("message");
98
+ var btn = document.getElementById("btn");
99
+ var txt = msg.value;
100
+ btn.className = "active";
101
+ btn.value = "Say Cheese!";
102
+
103
+ setTimeout(function(){
104
+ btn.className = "";
105
+ btn.value = "Push Me";
106
+ msg.value = "";
107
+ },3000);
108
+
109
+ if (txt == "") {
110
+ get('/photo');
111
+ }
112
+ else {
113
+ get('/photo?message='+txt);
114
+ }
115
+ }
116
+ function shrink() {
117
+ var body = document.getElementsByTagName("body")[0];
118
+ body.className = "focused";
119
+ }
120
+ function expand() {
121
+ var body = document.getElementsByTagName("body")[0];
122
+ body.className = "";
123
+ }
124
+ </script>
125
+ </head>
126
+ <body>
127
+ <textarea id="message" class="item" placeholder="Enter a message if you like..." onclick="shrink()" onblur="expand()"></textarea>
128
+ <input type="button" id="btn" class="item" value="Push Me" onClick="activate()" />
129
+ </body>
130
+ <script>
131
+ // really truly disable the shit out of pinch-to-zoom
132
+ var lastTouchEnd = 0;
133
+ document.documentElement.addEventListener('touchend', function (event) {
134
+ var now = (new Date()).getTime();
135
+ if (now - lastTouchEnd <= 300) {
136
+ event.preventDefault();
137
+ }
138
+ lastTouchEnd = now;
139
+ }, false);
140
+
141
+ document.documentElement.addEventListener('touchstart', function (event) {
142
+ if (event.touches.length > 1) {
143
+ event.preventDefault();
144
+ }
145
+ }, false);
146
+ </script>
147
+ </html>
metadata CHANGED
@@ -1,69 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitterpunch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
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-05 00:00:00.000000000 Z
11
+ date: 2016-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: twitter
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: oauth
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: colorize
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rubygame
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: "Twitterpunch\n===============\n\nTwitterpunch is designed to work with
@@ -134,6 +134,8 @@ files:
134
134
  - lib/twitterpunch/configuration.rb
135
135
  - lib/twitterpunch/logger.rb
136
136
  - lib/twitterpunch/poster.rb
137
+ - lib/twitterpunch/queue.rb
138
+ - lib/twitterpunch/remote.rb
137
139
  - lib/twitterpunch/sprite.rb
138
140
  - lib/twitterpunch/streamer.rb
139
141
  - lib/twitterpunch/viewer.rb
@@ -144,6 +146,9 @@ files:
144
146
  - resources/Twitterpunch.workflow/Contents/document.wflow
145
147
  - resources/say.vbs
146
148
  - resources/tweet_sent.wav
149
+ - views/index.erb
150
+ - public/touch-icon-ipad-retina.png
151
+ - public/touch-icon-iphone-retina.png
147
152
  homepage: http://binford2k.com
148
153
  licenses: []
149
154
  metadata: {}
@@ -162,17 +167,17 @@ require_paths:
162
167
  - lib
163
168
  required_ruby_version: !ruby/object:Gem::Requirement
164
169
  requirements:
165
- - - '>='
170
+ - - ">="
166
171
  - !ruby/object:Gem::Version
167
172
  version: '0'
168
173
  required_rubygems_version: !ruby/object:Gem::Requirement
169
174
  requirements:
170
- - - '>='
175
+ - - ">="
171
176
  - !ruby/object:Gem::Version
172
177
  version: '0'
173
178
  requirements: []
174
179
  rubyforge_project:
175
- rubygems_version: 2.0.14
180
+ rubygems_version: 2.0.14.1
176
181
  signing_key:
177
182
  specification_version: 4
178
183
  summary: A simple tool to automate the posting and streaming of PhotoBooth shots over