snapcat 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +194 -0
  7. data/Rakefile +10 -0
  8. data/lib/snapcat.rb +19 -0
  9. data/lib/snapcat/client.rb +189 -0
  10. data/lib/snapcat/crypt.rb +35 -0
  11. data/lib/snapcat/friend.rb +57 -0
  12. data/lib/snapcat/media.rb +81 -0
  13. data/lib/snapcat/requestor.rb +106 -0
  14. data/lib/snapcat/response.rb +43 -0
  15. data/lib/snapcat/snap.rb +80 -0
  16. data/lib/snapcat/snapcat_error.rb +4 -0
  17. data/lib/snapcat/timestamp.rb +17 -0
  18. data/lib/snapcat/user.rb +46 -0
  19. data/snapcat.gemspec +28 -0
  20. data/spec/snapcat/client_spec.rb +217 -0
  21. data/spec/snapcat/crypt_spec.rb +27 -0
  22. data/spec/snapcat/friend_spec.rb +22 -0
  23. data/spec/snapcat/media_spec.rb +61 -0
  24. data/spec/snapcat/response_spec.rb +71 -0
  25. data/spec/snapcat/snap_spec.rb +72 -0
  26. data/spec/snapcat/timestamp_spec.rb +32 -0
  27. data/spec/snapcat/user_spec.rb +40 -0
  28. data/spec/snapcat_spec.rb +4 -0
  29. data/spec/spec_helper.rb +13 -0
  30. data/spec/support/data_helper.rb +20 -0
  31. data/spec/support/fixture.rb +70 -0
  32. data/spec/support/minitest_spec_context.rb +7 -0
  33. data/spec/support/request_stub.rb +322 -0
  34. data/spec/support/response_helper.rb +15 -0
  35. data/spec/support/responses/block_success.json +5 -0
  36. data/spec/support/responses/delete_success.json +5 -0
  37. data/spec/support/responses/login_success.json +91 -0
  38. data/spec/support/responses/logout_success.json +1 -0
  39. data/spec/support/responses/register_failure.json +4 -0
  40. data/spec/support/responses/register_success.json +6 -0
  41. data/spec/support/responses/registeru_failure.json +4 -0
  42. data/spec/support/responses/registeru_success.json +58 -0
  43. data/spec/support/responses/send_snap_success.json +1 -0
  44. data/spec/support/responses/set_display_name_failure.json +4 -0
  45. data/spec/support/responses/set_display_name_success.json +9 -0
  46. data/spec/support/responses/unblock_success.json +10 -0
  47. data/spec/support/responses/update_email_success.json +5 -0
  48. data/spec/support/responses/update_privacy_success.json +5 -0
  49. data/spec/support/responses/updates_success.json +97 -0
  50. data/spec/support/responses/upload_success.json +1 -0
  51. data/spec/support/snaps/image_decrypted.jpg +0 -0
  52. data/spec/support/snaps/image_encrypted.jpg +0 -0
  53. data/spec/support/snaps/video_decrypted.mp4 +0 -0
  54. data/spec/support/snaps/video_encrypted.mp4 +0 -0
  55. data/spec/support/user_experience.rb +20 -0
  56. metadata +218 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1e888b4d7abb16b802f4805367bb673590c1220a
4
+ data.tar.gz: fbb23356c09c30d5544735805a18671afea27ef5
5
+ SHA512:
6
+ metadata.gz: aa65c119939ce0e0cc1c2fd4ad27f0a8a2d7f021bde43d38f319da5564cb7b37d330ba89309f314032cbf48f3bf364c1c000367d4d9d807536ae7bc5ac18dc2b
7
+ data.tar.gz: 16f5299266b6dc2087998db38f3a342f3c9b331ef3606579c31523c5360fd3c4147cbdfebf30b3c1315e2ceba7bdb7d6166992f7dadd6fa48bf92e2ba9ea1960
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ *.rbc
3
+ .DS_Store
4
+ .bundle
5
+ .config
6
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Dependencies in gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Neal Kemp
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,194 @@
1
+ Snapcat
2
+ =======
3
+ [![Build Status](https://travis-ci.org/NealKemp/snapcat.png)](https://travis-ci.org/NealKemp/snapcat)
4
+
5
+
6
+ A cat-tastic Ruby wrapper for the [Snapchat](http://snapchat.com) private API.
7
+ Meow. This gem is designed to give you a friendly Ruby-like interface for
8
+ interacting with the Snapchat API.
9
+
10
+
11
+ Installation
12
+ ------------
13
+
14
+ Add this line to your application's `Gemfile`:
15
+
16
+ gem 'snapcat', '0.0.1'
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Alternatively, install it via command line:
23
+
24
+ $ gem install snapcat
25
+
26
+
27
+ Usage
28
+ -----
29
+
30
+ **User Auth**
31
+
32
+ ```ruby
33
+ # Initialize a client and login
34
+ snapcat = Snapcat::Client.new('your-username')
35
+ snapcat.login('topsecretpassword')
36
+
37
+ # Initialize a new client, register, and login
38
+ snapcat = Snapcat::Client.new('your-new-username')
39
+ snapcat.register('topsecretpassword', '1990-01-20', 'test@example.com')
40
+
41
+ # Logout
42
+ snapcat.logout
43
+ ```
44
+
45
+
46
+ **User Actions**
47
+
48
+ ```ruby
49
+ # Block a user
50
+ snapcat.block('username-to-block')
51
+
52
+ # Clear feed
53
+ snapcat.clear_feed
54
+
55
+ # Fetch a user's updates
56
+ snapcat.fetch_updates
57
+
58
+ # Unblock a user
59
+ snapcat.unblock('username-to-unlock')
60
+
61
+ # Update user's email
62
+ snapcat.update_email('newemail@example.com')
63
+
64
+ # Update user's privacy setting
65
+ # Two choices:
66
+ # Snapcat::User::Privacy::EVERYONE
67
+ # Snapcat::User::Privacy::FRIENDS
68
+ snapcat.update_privacy(Snapcat::User::Privacy::EVERYONE)
69
+
70
+ # Pro tip:
71
+ # Every call to the API responds with Snapcat::Response object with which
72
+ # you can check a few important things
73
+ response = snapcat.block('username-to-block')
74
+ response.code # => 200
75
+ response.http_success # => true
76
+ response.data # => { logged: true, ... }
77
+ ```
78
+
79
+ **User Data**
80
+
81
+ ```ruby
82
+ # Get the user
83
+ user = snapcat.user
84
+
85
+ # Examine all raw user data
86
+ user.data
87
+
88
+ # Examine snaps received
89
+ user.snaps_received
90
+
91
+ # Examine snaps sent
92
+ user.snaps_sent
93
+
94
+ # Examine friends
95
+ user.friends
96
+ ```
97
+
98
+ **Friends**
99
+
100
+ ```ruby
101
+ # Grab a friend
102
+ friend = user.friends.first
103
+
104
+ # Set a friend's display name
105
+ snapcat.set_display_name(friend.username, 'Nik Ro')
106
+
107
+ # Delete a friend :(
108
+ snapcat.delete_friend(friend.username)
109
+
110
+ # Learn more about your friend
111
+ friend.can_see_custom_stories
112
+ friend.display_name
113
+ friend.username
114
+
115
+ # What kind of friend are they anyway??
116
+ friend.type
117
+ friend.type.confirmed?
118
+ friend.type.unconfirmed?
119
+ friend.type.blocked?
120
+ friend.type.deleted?
121
+ ```
122
+
123
+ **Sending Snaps**
124
+
125
+ ```ruby
126
+ # Send it to catsaregreat with 3 seconds duration
127
+ # `data` is a string which can be read directly from an mp4 or jpg
128
+ snapcat.send_media(data, 'catsaregreat')
129
+
130
+ # Or send it to multiple recipients and override default view_duration
131
+ snapcat.send_media(data, %w(catsaregreat ronnie99), view_duration: 4)
132
+ ```
133
+
134
+ **Received Snaps**
135
+
136
+ ```ruby
137
+ # Grab a snap
138
+ snap = user.snaps_received.first
139
+
140
+ # Get the snap image or video data
141
+ media_response = snapcat.media_for(snap.id)
142
+ media = media_response.data[:media]
143
+
144
+ # Learn more about the media
145
+ media.image?
146
+ media.video?
147
+ media.file_extension
148
+ media.type_code
149
+
150
+ # Get the data from the media object
151
+ media.to_s
152
+ ```
153
+
154
+ **Snaps General**
155
+
156
+ ```ruby
157
+ # Learn more about the snap
158
+ snap.broadcast
159
+ snap.broadcast_action_text
160
+ snap.broadcast_hide_timer
161
+ snap.broadcast_url
162
+ snap.screenshot_count
163
+ snap.media_id
164
+ snap.id
165
+ snap.media_type
166
+ snap.recipient
167
+ snap.sender
168
+ snap.status
169
+ snap.sent
170
+ snap.opened
171
+ ```
172
+
173
+
174
+ Contributing
175
+ ------------
176
+
177
+ 1. Fork it
178
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
179
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
180
+ 4. Push to the branch (`git push origin my-new-feature`)
181
+ 5. Add tests and make sure they pass
182
+ 6. Create new Pull Request
183
+
184
+
185
+ Credits
186
+ -------
187
+
188
+ * [Neal Kemp](http://nealke.mp)
189
+ * Based on work by martinp on [pysnap](https://github.com/martinp/pysnap) and by
190
+ djstelles on [php-snapchat](https://github.com/dstelljes/php-snapchat)
191
+
192
+ Copyright © 2013 Neal Kemp
193
+
194
+ Released under the MIT License, which can be found in the repository in `LICENSE.txt`.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs.push 'lib', 'spec'
6
+ t.test_files = FileList['spec/**/*_spec.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task default: :test
data/lib/snapcat.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'digest'
2
+ require 'httmultiparty'
3
+ require 'json'
4
+ require 'openssl'
5
+ require 'tempfile'
6
+
7
+ require 'snapcat/client'
8
+ require 'snapcat/crypt'
9
+ require 'snapcat/friend'
10
+ require 'snapcat/media'
11
+ require 'snapcat/requestor'
12
+ require 'snapcat/response'
13
+ require 'snapcat/snap'
14
+ require 'snapcat/snapcat_error'
15
+ require 'snapcat/timestamp'
16
+ require 'snapcat/user'
17
+
18
+ module Snapcat
19
+ end
@@ -0,0 +1,189 @@
1
+ module Snapcat
2
+ class Client
3
+ attr_reader :user
4
+
5
+ def initialize(username)
6
+ @user = User.new
7
+ @requestor = Requestor.new(username)
8
+ end
9
+
10
+ def block(username)
11
+ @requestor.request_with_username(
12
+ 'friend',
13
+ action: 'block',
14
+ friend: username
15
+ )
16
+ end
17
+
18
+ def clear_feed
19
+ @requestor.request_with_username('clear')
20
+ end
21
+
22
+ def fetch_updates(update_timestamp = 0)
23
+ set_user_data_with(@requestor.request_with_username(
24
+ 'updates',
25
+ update_timestamp: update_timestamp
26
+ ))
27
+ end
28
+
29
+ def media_for(snap_id)
30
+ @requestor.request_media(snap_id)
31
+ end
32
+
33
+ def delete_friend(username)
34
+ @requestor.request_with_username(
35
+ 'friend',
36
+ action: 'delete',
37
+ friend: username
38
+ )
39
+ end
40
+
41
+ def set_display_name(username, display_name)
42
+ @requestor.request_with_username(
43
+ 'friend',
44
+ action: 'display',
45
+ display: display_name,
46
+ friend: username
47
+ )
48
+ end
49
+
50
+ def login(password)
51
+ set_user_data_with(
52
+ @requestor.request_with_username('login', password: password)
53
+ )
54
+ end
55
+
56
+ def logout
57
+ @requestor.request_with_username('logout')
58
+ end
59
+
60
+ def register(password, birthday, email)
61
+ result = @requestor.request(
62
+ 'register',
63
+ birthday: birthday,
64
+ email: email,
65
+ password: password
66
+ )
67
+ unless result.success?
68
+ return result
69
+ end
70
+
71
+ result_two = @requestor.request_with_username(
72
+ 'registeru',
73
+ email: email
74
+ )
75
+
76
+ set_user_data_with(result_two)
77
+ end
78
+
79
+ def screenshot(snap_id, view_duration = 1)
80
+ raise NotImplementedError
81
+
82
+ snap_data = {
83
+ snap_id => {
84
+ c: Status::SCREENSHOT,
85
+ sv: view_duration,
86
+ t: Timestamp.float
87
+ }
88
+ }
89
+ events = [
90
+ {
91
+ eventName: 'SNAP_SCREENSHOT',
92
+ params: { id: snap_id },
93
+ ts: Timestamp.macro - view_duration
94
+ }
95
+ ]
96
+
97
+ request_events(events, snap_data)
98
+ end
99
+
100
+ def send_media(data, recipients, options = {})
101
+ result = @requestor.request_upload(data, options[:type])
102
+
103
+ unless result.success?
104
+ return result
105
+ end
106
+
107
+ media_id = result.data[:media_id]
108
+
109
+ @requestor.request_with_username(
110
+ 'send',
111
+ media_id: media_id,
112
+ recipient: prepare_recipients(recipients),
113
+ time: options[:view_duration] || 3
114
+ )
115
+ end
116
+
117
+ def unblock(username)
118
+ @requestor.request_with_username(
119
+ 'friend',
120
+ action: 'unblock',
121
+ friend: username
122
+ )
123
+ end
124
+
125
+ def view(snap_id, view_duration = 1)
126
+ raise NotImplementedError
127
+
128
+ snap_data = {
129
+ snap_id => { t: Timestamp.float, sv: view_duration }
130
+ }
131
+ events = [
132
+ {
133
+ eventName: 'SNAP_VIEW',
134
+ params: { id: snap_id },
135
+ ts: Timestamp.macro - view_duration
136
+ },
137
+ {
138
+ eventName: 'SNAP_EXPIRED',
139
+ params: { id: snap_id },
140
+ ts: Timestamp.macro
141
+ }
142
+ ]
143
+
144
+ request_events(events, snap_data)
145
+ end
146
+
147
+ def update_email(email)
148
+ @requestor.request_with_username(
149
+ 'settings',
150
+ action: 'updateEmail',
151
+ email: email
152
+ )
153
+ end
154
+
155
+ def update_privacy(code)
156
+ @requestor.request_with_username(
157
+ 'settings',
158
+ action: 'updatePrivacy',
159
+ privacySetting: code
160
+ )
161
+ end
162
+
163
+ private
164
+
165
+ def prepare_recipients(recipients)
166
+ if recipients.is_a? Array
167
+ recipients.join(',')
168
+ else
169
+ recipients
170
+ end
171
+ end
172
+
173
+ def request_events(events, snap_data)
174
+ @requestor.request_with_username(
175
+ 'update_snaps',
176
+ events: events,
177
+ json: snap_data
178
+ )
179
+ end
180
+
181
+ def set_user_data_with(result)
182
+ if result.success?
183
+ @user.data = result.data
184
+ end
185
+
186
+ result
187
+ end
188
+ end
189
+ end