snapcat 0.0.1

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.
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