firering 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +83 -0
- data/Rakefile +143 -0
- data/bin/campf-notify +56 -0
- data/examples/authenticate.rb +22 -0
- data/examples/events.rb +39 -0
- data/examples/recent_messages.rb +43 -0
- data/examples/rooms.rb +24 -0
- data/examples/update_room.rb +33 -0
- data/firering.gemspec +99 -0
- data/lib/firering/data/message.rb +29 -0
- data/lib/firering/data/room.rb +13 -0
- data/lib/firering/data/upload.rb +5 -0
- data/lib/firering/data/user.rb +16 -0
- data/lib/firering/data.rb +35 -0
- data/lib/firering/http.rb +43 -0
- data/lib/firering/requests.rb +185 -0
- data/lib/firering/streaming.rb +51 -0
- data/lib/firering.rb +21 -0
- data/spec/firering/data_spec.rb +21 -0
- data/spec/firering/requests_spec.rb +203 -0
- data/spec/fixtures/headers/delete_messages_ID_star.json +30 -0
- data/spec/fixtures/headers/get_room_ID.json +30 -0
- data/spec/fixtures/headers/get_room_ID_live.json +7 -0
- data/spec/fixtures/headers/get_room_ID_recent.json +30 -0
- data/spec/fixtures/headers/get_room_ID_transcript.json +30 -0
- data/spec/fixtures/headers/get_room_ID_transcript_ID_ID_ID.json +30 -0
- data/spec/fixtures/headers/get_room_ID_uploads.json +30 -0
- data/spec/fixtures/headers/get_rooms.json +30 -0
- data/spec/fixtures/headers/get_search_harmless.json +30 -0
- data/spec/fixtures/headers/get_users_ID.json +30 -0
- data/spec/fixtures/headers/get_users_me.json +30 -0
- data/spec/fixtures/headers/post_messages_ID_star.json +30 -0
- data/spec/fixtures/headers/post_room_ID_join.json +28 -0
- data/spec/fixtures/headers/post_room_ID_leave.json +28 -0
- data/spec/fixtures/headers/post_room_ID_speak.json +30 -0
- data/spec/fixtures/headers/post_room_ID_unlock.json +28 -0
- data/spec/fixtures/headers/put_room_ID.json +28 -0
- data/spec/fixtures/json/delete_messages_ID_star.json +1 -0
- data/spec/fixtures/json/get_room_ID.json +1 -0
- data/spec/fixtures/json/get_room_ID_live.json +1 -0
- data/spec/fixtures/json/get_room_ID_recent.json +33 -0
- data/spec/fixtures/json/get_room_ID_transcript.json +33 -0
- data/spec/fixtures/json/get_room_ID_transcript_ID_ID_ID.json +33 -0
- data/spec/fixtures/json/get_room_ID_uploads.json +1 -0
- data/spec/fixtures/json/get_rooms.json +2 -0
- data/spec/fixtures/json/get_search_harmless.json +3 -0
- data/spec/fixtures/json/get_users_ID.json +1 -0
- data/spec/fixtures/json/get_users_me.json +1 -0
- data/spec/fixtures/json/post_messages_ID_star.json +1 -0
- data/spec/fixtures/json/post_room_ID_join.json +1 -0
- data/spec/fixtures/json/post_room_ID_leave.json +1 -0
- data/spec/fixtures/json/post_room_ID_lock.json +1 -0
- data/spec/fixtures/json/post_room_ID_speak.json +1 -0
- data/spec/fixtures/json/post_room_ID_unlock.json +1 -0
- data/spec/fixtures/json/put_room_ID.json +1 -0
- data/spec/fixtures/load_server.rb +31 -0
- data/spec/fixtures/retrieve.rb +55 -0
- data/spec/fixtures/server.rb +40 -0
- data/spec/spec_helper.rb +10 -0
- metadata +231 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Emmanuel Oga
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
= firering
|
2
|
+
|
3
|
+
Campfire API interface powered by EventMachine and Yajl.
|
4
|
+
|
5
|
+
require 'firering'
|
6
|
+
|
7
|
+
Firering.subdomain = "subdomain"
|
8
|
+
Firering.token = "token"
|
9
|
+
|
10
|
+
EM.run do
|
11
|
+
Firering.rooms do |rooms|
|
12
|
+
rooms.each do |room|
|
13
|
+
if room.name == "RoomName"
|
14
|
+
|
15
|
+
puts "Joining #{room.name}"
|
16
|
+
|
17
|
+
Firering.room_join(room.id) do
|
18
|
+
Firering.stream(room.id) do |message|
|
19
|
+
|
20
|
+
if message.from_user?
|
21
|
+
Firering.user(message.user_id) do |user|
|
22
|
+
puts "( #{user.name} ) #{message.body}"
|
23
|
+
end
|
24
|
+
else
|
25
|
+
puts message.body if message.body.to_s !~ /^\s*$/
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
trap("INT") { EM.stop }
|
36
|
+
end
|
37
|
+
|
38
|
+
= campf-notify
|
39
|
+
|
40
|
+
The gem bundles an executable script for spawning libnotify powered notifications.
|
41
|
+
To be able to use it, check your distro package repositories for the apropriate
|
42
|
+
package containing the "notify-send" command line utility. In the case of archlinux,
|
43
|
+
the package name is "libnotify".
|
44
|
+
|
45
|
+
The script needs the following environment variables in place:
|
46
|
+
|
47
|
+
CAMPFIRE_SUBDOMAIN
|
48
|
+
CAMPFIRE_TOKEN
|
49
|
+
|
50
|
+
Once the variables are set, run the script as follows:
|
51
|
+
|
52
|
+
campf-notify room-name /path/to/an/icon.png
|
53
|
+
|
54
|
+
And watch the lovely notifications each time something is posted to a room.
|
55
|
+
|
56
|
+
== Running the specs
|
57
|
+
|
58
|
+
For running the specs, I opted for running a sinatra application for serving
|
59
|
+
the fixture data. The server runs automatically when "rake spec" is executed,
|
60
|
+
it runs on the standard sinatra port (4567), so you should make sure that
|
61
|
+
port is free when running the specs.
|
62
|
+
|
63
|
+
For more details take a look at spec/fixtures/load_server.rb file.
|
64
|
+
|
65
|
+
== TODO
|
66
|
+
|
67
|
+
* Better API documentation
|
68
|
+
* Post files to a room
|
69
|
+
* Retrieve recently uploaded files
|
70
|
+
|
71
|
+
== Note on Patches/Pull Requests
|
72
|
+
|
73
|
+
* Fork the project.
|
74
|
+
* Make your feature addition or bug fix.
|
75
|
+
* Add tests for it. This is important so I don't break it in a
|
76
|
+
future version unintentionally.
|
77
|
+
* Commit, do not mess with rakefile, version, or history.
|
78
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
79
|
+
* Send me a pull request. Bonus points for topic branches.
|
80
|
+
|
81
|
+
== Copyright
|
82
|
+
|
83
|
+
Copyright (c) 2010 Emmanuel Oga. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
#############################################################################
|
6
|
+
#
|
7
|
+
# Helper functions
|
8
|
+
#
|
9
|
+
#############################################################################
|
10
|
+
|
11
|
+
def name
|
12
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
13
|
+
end
|
14
|
+
|
15
|
+
def version
|
16
|
+
line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
|
17
|
+
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
18
|
+
end
|
19
|
+
|
20
|
+
def date
|
21
|
+
Date.today.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
def rubyforge_project
|
25
|
+
name
|
26
|
+
end
|
27
|
+
|
28
|
+
def gemspec_file
|
29
|
+
"#{name}.gemspec"
|
30
|
+
end
|
31
|
+
|
32
|
+
def gem_file
|
33
|
+
"#{name}-#{version}.gem"
|
34
|
+
end
|
35
|
+
|
36
|
+
def replace_header(head, header_name)
|
37
|
+
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
38
|
+
end
|
39
|
+
|
40
|
+
#############################################################################
|
41
|
+
#
|
42
|
+
# Standard tasks
|
43
|
+
#
|
44
|
+
#############################################################################
|
45
|
+
|
46
|
+
require 'spec/rake/spectask'
|
47
|
+
|
48
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
49
|
+
spec.libs << 'lib' << 'spec'
|
50
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
51
|
+
end
|
52
|
+
|
53
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
54
|
+
spec.libs << 'lib' << 'spec'
|
55
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
56
|
+
spec.rcov = true
|
57
|
+
end
|
58
|
+
|
59
|
+
task :default => :spec
|
60
|
+
|
61
|
+
desc "Open an irb session preloaded with this library"
|
62
|
+
task :console do
|
63
|
+
sh "irb -I ./lib/ -rubygems -r ./lib/#{name}.rb"
|
64
|
+
end
|
65
|
+
|
66
|
+
#############################################################################
|
67
|
+
#
|
68
|
+
# Custom tasks (add your own tasks here)
|
69
|
+
#
|
70
|
+
#############################################################################
|
71
|
+
|
72
|
+
begin
|
73
|
+
require 'yard'
|
74
|
+
YARD::Rake::YardocTask.new
|
75
|
+
rescue LoadError
|
76
|
+
task :yardoc do
|
77
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#############################################################################
|
82
|
+
#
|
83
|
+
# Packaging tasks
|
84
|
+
#
|
85
|
+
#############################################################################
|
86
|
+
|
87
|
+
task :release => :build do
|
88
|
+
unless `git branch` =~ /^\* master$/
|
89
|
+
puts "You must be on the master branch to release!"
|
90
|
+
exit!
|
91
|
+
end
|
92
|
+
sh "git commit --allow-empty -a -m 'Release #{version}'"
|
93
|
+
sh "git tag v#{version}"
|
94
|
+
sh "git push origin master"
|
95
|
+
sh "git push v#{version}"
|
96
|
+
sh "gem push pkg/#{name}-#{version}.gem"
|
97
|
+
end
|
98
|
+
|
99
|
+
task :build => :gemspec do
|
100
|
+
sh "mkdir -p pkg"
|
101
|
+
sh "gem build #{gemspec_file}"
|
102
|
+
sh "mv #{gem_file} pkg"
|
103
|
+
end
|
104
|
+
|
105
|
+
task :gemspec => :validate do
|
106
|
+
# read spec file and split out manifest section
|
107
|
+
spec = File.read(gemspec_file)
|
108
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
109
|
+
|
110
|
+
# replace name version and date
|
111
|
+
replace_header(head, :name)
|
112
|
+
replace_header(head, :version)
|
113
|
+
replace_header(head, :date)
|
114
|
+
#comment this out if your rubyforge_project has a different name
|
115
|
+
replace_header(head, :rubyforge_project)
|
116
|
+
|
117
|
+
# determine file list from git ls-files
|
118
|
+
files = `git ls-files`.
|
119
|
+
split("\n").
|
120
|
+
sort.
|
121
|
+
reject { |file| file =~ /^\./ }.
|
122
|
+
reject { |file| file =~ /^(rdoc|pkg)/ }.
|
123
|
+
map { |file| " #{file}" }.
|
124
|
+
join("\n")
|
125
|
+
|
126
|
+
# piece file back together and write
|
127
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
128
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
129
|
+
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
130
|
+
puts "Updated #{gemspec_file}"
|
131
|
+
end
|
132
|
+
|
133
|
+
task :validate do
|
134
|
+
libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
|
135
|
+
unless libfiles.empty?
|
136
|
+
puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
|
137
|
+
exit!
|
138
|
+
end
|
139
|
+
unless Dir['VERSION*'].empty?
|
140
|
+
puts "A `VERSION` file at root level violates Gem best practices."
|
141
|
+
exit!
|
142
|
+
end
|
143
|
+
end
|
data/bin/campf-notify
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'firering'
|
4
|
+
require 'shellwords'
|
5
|
+
|
6
|
+
Firering.subdomain = ENV["CAMPFIRE_SUBDOMAIN"].to_s
|
7
|
+
Firering.token = ENV["CAMPFIRE_TOKEN"].to_s
|
8
|
+
|
9
|
+
room_name = ARGV[0].to_s
|
10
|
+
icon_path = ARGV[1].to_s
|
11
|
+
|
12
|
+
if Firering.subdomain =~ /^\s*$/ || Firering.token =~ /^\s*$/ || room_name =~ /^\s*$/ || !File.exists?(icon_path)
|
13
|
+
puts "USAGE: campf-notify room-name notify-send-icon-path"
|
14
|
+
puts
|
15
|
+
puts "Icon path #{icon_path} is incorrect\n" unless File.exists?(icon_path)
|
16
|
+
puts "Room name #{room_name} is missing" unless room_name !~ /^\s*$/
|
17
|
+
|
18
|
+
puts "The following environment variables are needed: "
|
19
|
+
puts
|
20
|
+
puts "CAMPFIRE_SUBDOMAIN: #{Firering.subdomain}"
|
21
|
+
puts "CAMPFIRE_TOKEN: #{Firering.token}"
|
22
|
+
puts
|
23
|
+
exit
|
24
|
+
else
|
25
|
+
puts "connecting to #{Firering.subdomain}.#{Firering::HTTP.host}"
|
26
|
+
end
|
27
|
+
|
28
|
+
EM.run do
|
29
|
+
Firering.rooms do |rooms|
|
30
|
+
rooms.each do |room|
|
31
|
+
if room.name == room_name
|
32
|
+
|
33
|
+
puts "Joining #{room.name}"
|
34
|
+
|
35
|
+
Firering.room_join(room.id) do
|
36
|
+
Firering.stream(room.id) do |message|
|
37
|
+
|
38
|
+
if message.from_user?
|
39
|
+
Firering.user(message.user_id) do |user|
|
40
|
+
m = "( #{user.name} ) #{message.body}"
|
41
|
+
system("notify-send -i #{icon_path.shellescape} -t 10000 Campfire #{m.shellescape}")
|
42
|
+
end
|
43
|
+
else
|
44
|
+
m = message.body.to_s
|
45
|
+
system("notify-send -i #{icon_path.shellescape} -t 10000 Campfire #{m.shellescape}") if m !~ /^\s*$/
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
trap("INT") { EM.stop }
|
56
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'firering'
|
2
|
+
|
3
|
+
puts "If you prefer it, you can authenticate your user with u/p instead of the campfire token."
|
4
|
+
|
5
|
+
print "Enter subdomain: "
|
6
|
+
subdomain = gets.chomp
|
7
|
+
|
8
|
+
print "Enter user: "
|
9
|
+
user = gets.chomp
|
10
|
+
|
11
|
+
print "Enter password: "
|
12
|
+
password = gets.chomp
|
13
|
+
|
14
|
+
EM.run do
|
15
|
+
Firering.authenticate(subdomain, user, password) do |user|
|
16
|
+
|
17
|
+
puts "Token for user #{user.name} is #{user.token}"
|
18
|
+
|
19
|
+
EM.stop
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
data/examples/events.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'firering'
|
2
|
+
|
3
|
+
Firering.subdomain = ENV["CAMPFIRE_SUBDOMAIN"]
|
4
|
+
Firering.token = ENV["CAMPFIRE_TOKEN"]
|
5
|
+
|
6
|
+
EM.run do
|
7
|
+
Firering.rooms do |rooms|
|
8
|
+
rooms.each do |room|
|
9
|
+
if room.name == "test2"
|
10
|
+
Firering.room_join(room.id) do
|
11
|
+
Firering.stream(room.id) do |message|
|
12
|
+
|
13
|
+
case
|
14
|
+
when message.advertisement? then puts "Handle Ad"
|
15
|
+
when message.allow_guests? then puts "Handle Allow Guests"
|
16
|
+
when message.disallow_guests? then puts "Handle Disallow Guests"
|
17
|
+
when message.idle? then puts "Handle Idle"
|
18
|
+
when message.kick? then puts "Handle Kick"
|
19
|
+
when message.leave? then puts "Handle Leave"
|
20
|
+
when message.paste? then puts "Handle Paste"
|
21
|
+
when message.sound? then puts "Handle Sound"
|
22
|
+
when message.system? then puts "Handle System"
|
23
|
+
when message.text? then puts "Handle Text"
|
24
|
+
when message.timestamp? then puts "Handle Timestamp"
|
25
|
+
when message.topic_change? then puts "Handle Topic Change"
|
26
|
+
when message.unidle? then puts "Handle Un Idle"
|
27
|
+
when message.unlock? then puts "Handle Unlock"
|
28
|
+
when message.upload? then puts "Handle Upload"
|
29
|
+
end
|
30
|
+
|
31
|
+
puts message.to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
trap("INT") { EM.stop }
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'firering'
|
2
|
+
|
3
|
+
Firering.subdomain = ENV["CAMPFIRE_SUBDOMAIN"]
|
4
|
+
Firering.token = ENV["CAMPFIRE_TOKEN"]
|
5
|
+
|
6
|
+
EM.run do
|
7
|
+
Firering.rooms do |rooms|
|
8
|
+
|
9
|
+
rooms.each do |room|
|
10
|
+
puts "Users in room #{room.name} (#{room.topic})"
|
11
|
+
|
12
|
+
if room.users.empty?
|
13
|
+
puts " empty (locked: #{room.locked?})"
|
14
|
+
else
|
15
|
+
room.users.each do |u|
|
16
|
+
puts " #{ u.name }. Admin: #{ u.admin? }"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if room.locked?
|
21
|
+
puts " can't get recent messages in a locked room'"
|
22
|
+
else
|
23
|
+
Firering.room_recent_messages(room.id) do |messages|
|
24
|
+
|
25
|
+
puts "-" * 80
|
26
|
+
puts "recent message on #{room.name}"
|
27
|
+
puts "-" * 80
|
28
|
+
|
29
|
+
messages.slice(0, 4).each do |m|
|
30
|
+
puts "\n (#{m.user_id})"
|
31
|
+
|
32
|
+
m.body.to_s.split("\n").each do |chunk|
|
33
|
+
puts " > #{chunk}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
trap("INT") { EM.stop }
|
43
|
+
end
|
data/examples/rooms.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'firering'
|
2
|
+
|
3
|
+
Firering.subdomain = ENV["CAMPFIRE_SUBDOMAIN"]
|
4
|
+
Firering.token = ENV["CAMPFIRE_TOKEN"]
|
5
|
+
|
6
|
+
EM.run do
|
7
|
+
Firering.rooms do |rooms|
|
8
|
+
|
9
|
+
rooms.each do |room|
|
10
|
+
puts "Users in room #{room.name}"
|
11
|
+
|
12
|
+
if room.users.empty?
|
13
|
+
puts " empty (locked: #{room.locked?})"
|
14
|
+
else
|
15
|
+
room.users.each do |u|
|
16
|
+
puts " #{ u.name }"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
trap("INT") { EM.stop }
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'firering'
|
2
|
+
|
3
|
+
Firering.subdomain = ENV["CAMPFIRE_SUBDOMAIN"]
|
4
|
+
Firering.token = ENV["CAMPFIRE_TOKEN"]
|
5
|
+
|
6
|
+
ROOM = "test2"
|
7
|
+
|
8
|
+
EM.run do
|
9
|
+
Firering.rooms do |rooms|
|
10
|
+
rooms.each do |room|
|
11
|
+
if room.name == ROOM
|
12
|
+
Firering.room_join(room.id) do
|
13
|
+
|
14
|
+
Firering.update_room(room.id, "topic" => "test test test") do |response|
|
15
|
+
puts " * Updating topic: "
|
16
|
+
puts response.response_header.status
|
17
|
+
end
|
18
|
+
|
19
|
+
Firering.text(room.id, "hola") do
|
20
|
+
puts "texted"
|
21
|
+
end
|
22
|
+
|
23
|
+
Firering.paste(room.id, "hola\nmundo") do
|
24
|
+
puts "pasted"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
trap("INT") { EM.stop }
|
33
|
+
end
|
data/firering.gemspec
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
3
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
|
+
s.rubygems_version = '1.3.5'
|
5
|
+
|
6
|
+
s.name = 'firering'
|
7
|
+
s.version = '0.1.0'
|
8
|
+
s.date = '2010-05-30'
|
9
|
+
s.rubyforge_project = 'firering'
|
10
|
+
|
11
|
+
s.summary = "Campfire API interface powered by EventMachine and Yajl."
|
12
|
+
s.description = "Campfire API interface powered by EventMachine and Yajl."
|
13
|
+
|
14
|
+
s.authors = ["Emmanuel Oga"]
|
15
|
+
s.email = 'EmmanuelOga@gmail.com'
|
16
|
+
s.homepage = 'http://github.com/EmmanuelOga/firering'
|
17
|
+
|
18
|
+
s.require_paths = %w[lib]
|
19
|
+
|
20
|
+
s.executables = ["campf-notify"]
|
21
|
+
s.default_executable = 'campf-notify'
|
22
|
+
|
23
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
24
|
+
s.extra_rdoc_files = %w[README.rdoc LICENSE]
|
25
|
+
|
26
|
+
s.add_dependency('eventmachine', [">= 0.12.10"])
|
27
|
+
s.add_dependency('em-http-request', [">= 0.2.7"])
|
28
|
+
s.add_dependency('yajl-ruby', [">= 0.7.6"])
|
29
|
+
|
30
|
+
s.add_development_dependency('rspec', [">= 1.3.0"])
|
31
|
+
s.add_development_dependency('sinatra', [">= 1.0.0"])
|
32
|
+
|
33
|
+
# = MANIFEST =
|
34
|
+
s.files = %w[
|
35
|
+
LICENSE
|
36
|
+
README.rdoc
|
37
|
+
Rakefile
|
38
|
+
bin/campf-notify
|
39
|
+
examples/authenticate.rb
|
40
|
+
examples/events.rb
|
41
|
+
examples/recent_messages.rb
|
42
|
+
examples/rooms.rb
|
43
|
+
examples/update_room.rb
|
44
|
+
firering.gemspec
|
45
|
+
lib/firering.rb
|
46
|
+
lib/firering/data.rb
|
47
|
+
lib/firering/data/message.rb
|
48
|
+
lib/firering/data/room.rb
|
49
|
+
lib/firering/data/upload.rb
|
50
|
+
lib/firering/data/user.rb
|
51
|
+
lib/firering/http.rb
|
52
|
+
lib/firering/requests.rb
|
53
|
+
lib/firering/streaming.rb
|
54
|
+
spec/firering/data_spec.rb
|
55
|
+
spec/firering/requests_spec.rb
|
56
|
+
spec/fixtures/headers/delete_messages_ID_star.json
|
57
|
+
spec/fixtures/headers/get_room_ID.json
|
58
|
+
spec/fixtures/headers/get_room_ID_live.json
|
59
|
+
spec/fixtures/headers/get_room_ID_recent.json
|
60
|
+
spec/fixtures/headers/get_room_ID_transcript.json
|
61
|
+
spec/fixtures/headers/get_room_ID_transcript_ID_ID_ID.json
|
62
|
+
spec/fixtures/headers/get_room_ID_uploads.json
|
63
|
+
spec/fixtures/headers/get_rooms.json
|
64
|
+
spec/fixtures/headers/get_search_harmless.json
|
65
|
+
spec/fixtures/headers/get_users_ID.json
|
66
|
+
spec/fixtures/headers/get_users_me.json
|
67
|
+
spec/fixtures/headers/post_messages_ID_star.json
|
68
|
+
spec/fixtures/headers/post_room_ID_join.json
|
69
|
+
spec/fixtures/headers/post_room_ID_leave.json
|
70
|
+
spec/fixtures/headers/post_room_ID_speak.json
|
71
|
+
spec/fixtures/headers/post_room_ID_unlock.json
|
72
|
+
spec/fixtures/headers/put_room_ID.json
|
73
|
+
spec/fixtures/json/delete_messages_ID_star.json
|
74
|
+
spec/fixtures/json/get_room_ID.json
|
75
|
+
spec/fixtures/json/get_room_ID_live.json
|
76
|
+
spec/fixtures/json/get_room_ID_recent.json
|
77
|
+
spec/fixtures/json/get_room_ID_transcript.json
|
78
|
+
spec/fixtures/json/get_room_ID_transcript_ID_ID_ID.json
|
79
|
+
spec/fixtures/json/get_room_ID_uploads.json
|
80
|
+
spec/fixtures/json/get_rooms.json
|
81
|
+
spec/fixtures/json/get_search_harmless.json
|
82
|
+
spec/fixtures/json/get_users_ID.json
|
83
|
+
spec/fixtures/json/get_users_me.json
|
84
|
+
spec/fixtures/json/post_messages_ID_star.json
|
85
|
+
spec/fixtures/json/post_room_ID_join.json
|
86
|
+
spec/fixtures/json/post_room_ID_leave.json
|
87
|
+
spec/fixtures/json/post_room_ID_lock.json
|
88
|
+
spec/fixtures/json/post_room_ID_speak.json
|
89
|
+
spec/fixtures/json/post_room_ID_unlock.json
|
90
|
+
spec/fixtures/json/put_room_ID.json
|
91
|
+
spec/fixtures/load_server.rb
|
92
|
+
spec/fixtures/retrieve.rb
|
93
|
+
spec/fixtures/server.rb
|
94
|
+
spec/spec_helper.rb
|
95
|
+
]
|
96
|
+
# = MANIFEST =
|
97
|
+
|
98
|
+
s.test_files = s.files.select { |path| path =~ /^spec/ }
|
99
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Firering
|
2
|
+
class Message < Firering::Data
|
3
|
+
key :id, :room_id, :user_id, :body, :created_at, :type
|
4
|
+
|
5
|
+
MESSAGE_TYPES = %w[
|
6
|
+
TextMessage PasteMessage SoundMessage AdvertisementMessage
|
7
|
+
AllowGuestsMessage DisallowGuestsMessage IdleMessage KickMessage
|
8
|
+
LeaveMessage SystemMessage TimestampMessage TopicChangeMessage
|
9
|
+
UnidleMessage UnlockMessage UploadMessage
|
10
|
+
]
|
11
|
+
|
12
|
+
# txs activesupport
|
13
|
+
underscore = proc do |word|
|
14
|
+
word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
|
15
|
+
end
|
16
|
+
|
17
|
+
MESSAGE_TYPES.each do |message_type|
|
18
|
+
current_type = (message_type =~ /(.+)Message/) && $1
|
19
|
+
define_method("#{underscore[current_type]}?") do
|
20
|
+
type == message_type
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def from_user?
|
25
|
+
!user_id.nil? && (!user_id.instance_of?(String) || user_id !~ /~\s*$/)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Firering
|
2
|
+
class Room < Firering::Data
|
3
|
+
key :id, :name, :topic, :membership_limit, :full, :open_to_guests, :active_token_value, :updated_at, :created_at, :users, :locked
|
4
|
+
|
5
|
+
alias_method :locked?, :locked
|
6
|
+
alias_method :full?, :full
|
7
|
+
alias_method :open_to_guests?, :open_to_guests
|
8
|
+
|
9
|
+
def users
|
10
|
+
@users ||= (super || []).map { |u| Firering::User.new(u, false) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Firering
|
2
|
+
class User < Firering::Data
|
3
|
+
key :id, :name, :email_address, :admin, :created_at, :type, :api_auth_token
|
4
|
+
|
5
|
+
alias_method :token, :api_auth_token
|
6
|
+
alias_method :admin?, :admin
|
7
|
+
|
8
|
+
def member?
|
9
|
+
type == "Member"
|
10
|
+
end
|
11
|
+
|
12
|
+
def gest?
|
13
|
+
type == "Guest"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Firering
|
2
|
+
class Data
|
3
|
+
|
4
|
+
# generates methods to access the data stored in the @data Hash
|
5
|
+
def self.key(*keys)
|
6
|
+
methods = keys.map do |key|
|
7
|
+
<<-CODE
|
8
|
+
def #{key}
|
9
|
+
@data[#{key.to_sym.inspect}]
|
10
|
+
end
|
11
|
+
CODE
|
12
|
+
end
|
13
|
+
|
14
|
+
include(Module.new do
|
15
|
+
module_eval methods.join("\n"), __FILE__, __LINE__
|
16
|
+
end)
|
17
|
+
end
|
18
|
+
|
19
|
+
# data is a hash or a json encoded hash (String)
|
20
|
+
# base_key if present is the main data key on the hash.
|
21
|
+
def initialize(data, base_key = nil)
|
22
|
+
@data = data.is_a?(Hash) ? data : Yajl::Parser.parse(data, :symbolize_keys => true)
|
23
|
+
@data = @data[base_key] if base_key
|
24
|
+
|
25
|
+
@data.each do |key, val|
|
26
|
+
@data[key] = Date.parse(val) rescue val if key.to_s =~ /(_at|_on)$/
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def inspect
|
31
|
+
"<#{self.class.name} #{@data.inspect}>"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|