twitterpunch 0.0.5 → 0.0.6

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