From 918bdea33f13db19f482b568afcad742c6fbc3fa Mon Sep 17 00:00:00 2001 From: Hiroshi Yoshida Date: Sat, 17 May 2014 13:13:16 +0900 Subject: [PATCH 1/6] Create base for to support new API --- .rspec | 2 + lib/pushbullet/api.rb | 42 +++----------- lib/pushbullet/api/contacts.rb | 13 +++++ lib/pushbullet/api/devices.rb | 13 +++++ lib/pushbullet/api/pushes.rb | 63 +++++++++++++++++++++ lib/pushbullet/api/upload_request.rb | 35 ++++++++++++ lib/pushbullet/api/users.rb | 9 +++ lib/pushbullet/client.rb | 3 +- lib/pushbullet/http_exception.rb | 2 - lib/pushbullet/request.rb | 13 +++-- lib/pushbullet/secret_api.rb | 30 ---------- pushbullet.gemspec | 3 +- spec/fixtures/contacts.json | 16 ++++++ spec/fixtures/devices.json | 19 +++++++ spec/fixtures/push.json | 18 ++++++ spec/fixtures/pushes.json | 24 ++++++++ spec/fixtures/upload_request.json | 14 +++++ spec/fixtures/users.json | 31 +++++++++++ spec/pushbullet/client_spec.rb | 9 +++ spec/spec_helper.rb | 82 ++++++++++++++++++++++++++++ 20 files changed, 369 insertions(+), 72 deletions(-) create mode 100644 .rspec create mode 100644 lib/pushbullet/api/contacts.rb create mode 100644 lib/pushbullet/api/devices.rb create mode 100644 lib/pushbullet/api/pushes.rb create mode 100644 lib/pushbullet/api/upload_request.rb create mode 100644 lib/pushbullet/api/users.rb delete mode 100644 lib/pushbullet/secret_api.rb create mode 100644 spec/fixtures/contacts.json create mode 100644 spec/fixtures/devices.json create mode 100644 spec/fixtures/push.json create mode 100644 spec/fixtures/pushes.json create mode 100644 spec/fixtures/upload_request.json create mode 100644 spec/fixtures/users.json create mode 100644 spec/pushbullet/client_spec.rb create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..5f16476 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format progress diff --git a/lib/pushbullet/api.rb b/lib/pushbullet/api.rb index 5c114a8..efc2e1b 100644 --- a/lib/pushbullet/api.rb +++ b/lib/pushbullet/api.rb @@ -1,37 +1,13 @@ +require 'pushbullet/api/contacts' +require 'pushbullet/api/devices' +require 'pushbullet/api/pushes' +require 'pushbullet/api/users' + module Pushbullet module API - def devices - get('/api/devices') - end - - def push_note(device_id, title, body) - push :note, device_id, title: title, body: body - end - - def push_link(device_id, title, url) - push :link, device_id, title: title, url: url - end - - def push_address(device_id, title, address) - push :address, device_id, title: title, address: address - end - - # FIXME Now, can send *only* one item - def push_list(device_id, title, items) - push :list, device_id, title: title, items: items - end - - def push_file(device_id, file_path) - mime_type = MIME::Types.type_for(file_path).first.to_s - io = Faraday::UploadIO.new(file_path, mime_type) - - push :file, device_id, file: io - end - - private - - def push(type, device_id, payload) - post '/api/pushes', payload.merge(device_id: device_id, type: type) - end + include Contacts + include Devices + include Pushes + include Users end end diff --git a/lib/pushbullet/api/contacts.rb b/lib/pushbullet/api/contacts.rb new file mode 100644 index 0000000..f8cb3ce --- /dev/null +++ b/lib/pushbullet/api/contacts.rb @@ -0,0 +1,13 @@ +module Pushbullet + module API + module Contacts + def contacts + get '/v2/contacts' + end + + def delete_contact(contact_iden) + delete "/v2/contacts/#{contact_iden}" + end + end + end +end diff --git a/lib/pushbullet/api/devices.rb b/lib/pushbullet/api/devices.rb new file mode 100644 index 0000000..a617698 --- /dev/null +++ b/lib/pushbullet/api/devices.rb @@ -0,0 +1,13 @@ +module Pushbullet + module API + module Devices + def devices + get '/v2/devices' + end + + def delete_device(device_iden) + delete "/v2/devices/#{device_iden}" + end + end + end +end diff --git a/lib/pushbullet/api/pushes.rb b/lib/pushbullet/api/pushes.rb new file mode 100644 index 0000000..7d86120 --- /dev/null +++ b/lib/pushbullet/api/pushes.rb @@ -0,0 +1,63 @@ +require 'pushbullet/api/upload_request' + +module Pushbullet + module API + module Pushes + include UploadRequest + + # title - The note's title. + # body - The note's message. + def push_note(device_iden, title, body) + push :note, device_iden, title: title, body: body + end + + # title - The link's title. + # url - The url to open. + # body - An optional message. + def push_link(device_iden, title, url, body) + push :link, device_iden, title: title, url: url, body: body + end + + # name - The place's name. + # address - The place's address or a map search query. + def push_address(device_iden, name, address) + push :address, device_iden, name: name, address: address + end + + # title - The list's title. + # items - The list items. [{text: 'lorem', checked: false}, {text: 'ipsum', checked: true}] + def push_list(device_iden, title, items) + lorem ipsum + push :list, device_iden, title: title, items: items + end + + # file_name - The name of the file. + # file_type - The file's MIME type. + # file_url - The url where the file can be downloaded. + # body - An optional message. + def push_file(device_iden, file_name, file_path, body) + something(file_name, file_path) do |data| + payload = { + file_name: data['file_name'], + file_type: data['file_type'], + file_url: data['file_url'], + body: body + } + + push :file, device_iden, payload + end + end + + # push_iden - The iden of the push to delete. + def delete_push(push_iden) + delete "/v2/pushes/#{push_iden}" + end + + private + + def push(type, device_iden, payload) + post '/v2/pushes', payload.merge(device_iden: device_iden, type: type) + end + end + end +end diff --git a/lib/pushbullet/api/upload_request.rb b/lib/pushbullet/api/upload_request.rb new file mode 100644 index 0000000..1089296 --- /dev/null +++ b/lib/pushbullet/api/upload_request.rb @@ -0,0 +1,35 @@ +# TODO: we should make Faraday middleware of upload request +module Pushbullet + module API + module Pushes + module UploadRequest + private + + def something(file_name, file_path, &block) + mime_type = MIME::Types.type_for(file_path).first.to_s + data = get('/v2/upload-request', file_name: file_name, file_type: mime_type) + io = Faraday::UploadIO.new(file_path, mime_type) + + upload_url = data.body['upload_url'] + payload = data.body['data'] + + res = upload_request(upload_url, payload.merge(file: io)) + + raise 'somthing whent wrong' unless res.status == 204 + + yield data.body + end + + def upload_request(upload_url, payload) + Faraday.new(url: upload_url) {|f| + f.request :multipart + f.request :url_encoded + f.adapter :net_http + }.post {|r| + r.body = payload + } + end + end + end + end +end diff --git a/lib/pushbullet/api/users.rb b/lib/pushbullet/api/users.rb new file mode 100644 index 0000000..216bb9b --- /dev/null +++ b/lib/pushbullet/api/users.rb @@ -0,0 +1,9 @@ +module Pushbullet + module API + module Users + def users + get '/v2/users/me' + end + end + end +end diff --git a/lib/pushbullet/client.rb b/lib/pushbullet/client.rb index 9dbe483..2561f50 100644 --- a/lib/pushbullet/client.rb +++ b/lib/pushbullet/client.rb @@ -1,14 +1,13 @@ require 'faraday' require 'mime/types' + require 'pushbullet/request' require 'pushbullet/api' -require 'pushbullet/secret_api' module Pushbullet class Client include Request include API - include SecretAPI attr_reader :api_key diff --git a/lib/pushbullet/http_exception.rb b/lib/pushbullet/http_exception.rb index 28e7152..2b613cd 100644 --- a/lib/pushbullet/http_exception.rb +++ b/lib/pushbullet/http_exception.rb @@ -1,5 +1,3 @@ -require 'faraday' - module Pushbullet class BadRequest < StandardError; end class Unauthorized < StandardError; end diff --git a/lib/pushbullet/request.rb b/lib/pushbullet/request.rb index e4b9f1e..be046cd 100644 --- a/lib/pushbullet/request.rb +++ b/lib/pushbullet/request.rb @@ -4,20 +4,25 @@ module Pushbullet module Request include Connection - def get(path) - request(:get, path) + def get(path, params = {}) + request(:get, path, params) end def post(path, payload) request(:post, path, payload) end + def delete(path) + request(:delete, path) + end + private - def request(method, path, payload = {}) + def request(method, path, params = {}) response = connection.send(method) {|request| request.url path - request.body = payload if method == :post + request.params = params if method == :get + request.body = params if method == :post } end end diff --git a/lib/pushbullet/secret_api.rb b/lib/pushbullet/secret_api.rb deleted file mode 100644 index 66e90c6..0000000 --- a/lib/pushbullet/secret_api.rb +++ /dev/null @@ -1,30 +0,0 @@ -module Pushbullet - module SecretAPI - def contacts - get('/v2/contacts') - end - - def push_note_to(target_email, title, body) - push_to :note, target_email, title: title, body: body - end - - def push_link_to(target_email, title, url) - push_to :link, target_email, title: title, url: url - end - - def push_address_to(target_email, title, address) - push_to :address, target_email, title: title, address: address - end - - # FIXME Now, can send *only* one item - def push_list_to(target_email, title, items) - push_to :list, target_email, title: title, items: items - end - - private - - def push_to(type, target_email, payload) - post '/api/pushes', payload.merge(target_email: target_email, type: type) - end - end -end diff --git a/pushbullet.gemspec b/pushbullet.gemspec index 2deb2ec..65122b7 100644 --- a/pushbullet.gemspec +++ b/pushbullet.gemspec @@ -18,8 +18,9 @@ Gem::Specification.new do |gem| gem.require_paths = ['lib'] gem.add_development_dependency 'bundler' - gem.add_development_dependency 'rake' gem.add_development_dependency 'pry' + gem.add_development_dependency 'rake' + gem.add_development_dependency 'rspec', '~> 3.0.0.beta2' gem.add_dependency 'faraday' gem.add_dependency 'mime-types' diff --git a/spec/fixtures/contacts.json b/spec/fixtures/contacts.json new file mode 100644 index 0000000..a9dc027 --- /dev/null +++ b/spec/fixtures/contacts.json @@ -0,0 +1,16 @@ +{ + "contacts":[ + { + "iden": "ubdcjAfszs0Smi", + "status": "user", + "name": "Ryan Oldenburg", + "created": 1399011660.4298899, + "modified": 1399011660.42976, + "id": 5695496404336640, + "source": "user", + "email": "ryanjoldenburg@gmail.com" + "email_normalized": "ryanjoldenburg@gmail.com", + "active": true + } + ] +} diff --git a/spec/fixtures/devices.json b/spec/fixtures/devices.json new file mode 100644 index 0000000..d408bd0 --- /dev/null +++ b/spec/fixtures/devices.json @@ -0,0 +1,19 @@ +{ + "devices":[ + { + "iden":"u1qSJddxeKwOGuGW", + "push_token":"u1qSJddxeKwOGuGWu1qSJddxeKwOGuGWu1qSJddxeKwOGuGWu1qSJddxeK", + "app_version":74, + "android_sdk_version":"19", + "fingerprint":"", + "active":true, + "nickname":"Galaxy S4", + "manufacturer":"samsung", + "kind":"android", + "created":1394748080.0139201, + "modified":1399008037.8487799, + "android_version":"4.4.2", + "model":"SCH-I545" + } + ] +} diff --git a/spec/fixtures/push.json b/spec/fixtures/push.json new file mode 100644 index 0000000..f58e998 --- /dev/null +++ b/spec/fixtures/push.json @@ -0,0 +1,18 @@ +{ + "iden":"ubdpjxxxOK0sKG", + "type":"note", + "title":"Note title", + "body":"Note body", + "created":1399253701.9746201, + "modified":1399253701.9744401, + "active":true, + "dismissed":false, + "owner_iden":"ubd", + "target_device_iden":"ubddjAy95rgBxc", + "sender_iden":"ubd", + "sender_email":"ryan@pushbullet.com" + "sender_email_normalized":"ryan@pushbullet.com", + "receiver_iden":"ubd", + "receiver_email":"ryan@pushbullet.com", + "receiver_email_normalized":"ryan@pushbullet.com" +} diff --git a/spec/fixtures/pushes.json b/spec/fixtures/pushes.json new file mode 100644 index 0000000..cbc372b --- /dev/null +++ b/spec/fixtures/pushes.json @@ -0,0 +1,24 @@ +{ + "pushes": [ + { + "iden": "ubdpjAkaGXvUl2", + "type": "link", + "active": true, + "dismissed": false, + "created": 1.39934925E9, + "modified": 1.39934925E9, + "title": "Pushbullet", + "body": "Documenting our API", + "url": "http://docs.pushbullet.com", + "owner_iden": "ubd", + "target_device_iden": "ubddjAy95rgBxc", + "sender_iden": "ubd", + "sender_email": "ryan@pushbullet.com" + "sender_email_normalized": "ryan@pushbullet.com", + "receiver_iden": "ubd", + "receiver_email": "ryan@pushbullet.com", + "receiver_email_normalized": "ryan@pushbullet.com", + } + ], + "cursor": null +} diff --git a/spec/fixtures/upload_request.json b/spec/fixtures/upload_request.json new file mode 100644 index 0000000..45ce2af --- /dev/null +++ b/spec/fixtures/upload_request.json @@ -0,0 +1,14 @@ +{ + "file_type":"image/png", + "file_name":"image.png", + "file_url":"https://s3.amazonaws.com/pushbullet-uploads/ubd-VWb1dP5XrZzvHReWHCycIwPyuAMp2R9I/image.png", + "upload_url":"https://s3.amazonaws.com/pushbullet-uploads", + "data":{ + "awsaccesskeyid":"AKIAJJIUQPUDGPM4GD3W", + "acl":"public-read", + "key":"ubd-CWb1dP5XrZzvHReWHCycIwPyuAMp2R9I/image.png", + "signature":"UX5s1uIy1ov6+xlj58JY7rGFKcs=", + "policy":"eyKjb25kaXRpb25zIjogW3siYnVja2V0IjogInB1c2hidWxsZXQtdXBsb2FkcyJ9LCB7ImtleSI6ICJ1YmQtVldiMWRQNVhyWnp2SFJlV0hDeWNJd1B5dUFNcDJSOUkvaW1hZ2UucG5nIn0sIHsiYWNsIjogInB1YmxpYy1yZWFkIn0sIFsiY29udGVudC1sZW5ndGgtcmFuZ2UiLCAxLCAyNjIxNDQwMF0sIFsiZXEiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS9wbmciXV0sICJleHBpcmF0aW9uIjogIjIwMTQtMDUtMDVUMjI6NTE6MzcuMjM0MTMwWiJ9", + "content-type":"image/png" + } +} diff --git a/spec/fixtures/users.json b/spec/fixtures/users.json new file mode 100644 index 0000000..01450d0 --- /dev/null +++ b/spec/fixtures/users.json @@ -0,0 +1,31 @@ +{ + "iden": "ubd", + "api_key": "", + "email": "", + "email_normalized": "", + "admin": true, + "created": 1357941753.8287899, + "modified": 1399325992.1842301, + "google_id": "110038027176632715601", + "google_userinfo": { + "family_name": "Oldenburg", + "name": "Ryan Oldenburg", + "picture": "", + "locale": "en", + "gender": "male", + "email": "", + "link": "", + "given_name": "Ryan", + "id": "110038027176632715601", + "hd": "", + "verified_email": true + }, + "preferences": { + "onboarding": { + "app": false, + "friends": false, + "extension": false + }, + "social": false + } +} diff --git a/spec/pushbullet/client_spec.rb b/spec/pushbullet/client_spec.rb new file mode 100644 index 0000000..edc1c1b --- /dev/null +++ b/spec/pushbullet/client_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe Pushbullet::Client do + describe '#new' do + let(:client) { described_class.new('ABCDEFGHIJKLMN') } + + it { } + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..d4cb138 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,82 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause this +# file to always be loaded, without a need to explicitly require it in any files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# (such as loading up an entire rails app) will add to the boot time of your +# test suite on EVERY test run, even for an individual file that may not need +# all of that loaded. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # RSpec filters the backtrace by default so as not to be so noisy. + # This causes the full backtrace to be printed when running a single + # spec file (e.g. to troubleshoot a particular spec failure). + config.full_backtrace = true + + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.formatter = 'doc' if config.formatters.none? + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed + + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # Enable only the newer, non-monkey-patching expect syntax. + # For more details, see: + # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + expectations.syntax = :expect + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Enable only the newer, non-monkey-patching expect syntax. + # For more details, see: + # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + mocks.syntax = :expect + + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended. + mocks.verify_partial_doubles = true + end +=end +end From 54506b3d807aa6aa1f67ae8fa4e601a49e4ba6d4 Mon Sep 17 00:00:00 2001 From: Hiroshi Yoshida Date: Sun, 18 May 2014 16:06:26 +0900 Subject: [PATCH 2/6] Refactor --- lib/pushbullet/api/pushes.rb | 29 ++++++++++++++++----- lib/pushbullet/api/upload_request.rb | 35 ------------------------- lib/pushbullet/basic_authentication.rb | 11 ++++++++ lib/pushbullet/client.rb | 36 +++++++++++++++++++++++++- lib/pushbullet/connection.rb | 22 ---------------- lib/pushbullet/parse_json.rb | 6 ++++- lib/pushbullet/request.rb | 4 --- 7 files changed, 73 insertions(+), 70 deletions(-) delete mode 100644 lib/pushbullet/api/upload_request.rb create mode 100644 lib/pushbullet/basic_authentication.rb delete mode 100644 lib/pushbullet/connection.rb diff --git a/lib/pushbullet/api/pushes.rb b/lib/pushbullet/api/pushes.rb index 7d86120..e11db84 100644 --- a/lib/pushbullet/api/pushes.rb +++ b/lib/pushbullet/api/pushes.rb @@ -1,10 +1,6 @@ -require 'pushbullet/api/upload_request' - module Pushbullet module API module Pushes - include UploadRequest - # title - The note's title. # body - The note's message. def push_note(device_iden, title, body) @@ -25,9 +21,9 @@ def push_address(device_iden, name, address) end # title - The list's title. - # items - The list items. [{text: 'lorem', checked: false}, {text: 'ipsum', checked: true}] + # items - The list items. + # [{text: 'lorem', checked: false}, {text: 'ipsum', checked: true}] def push_list(device_iden, title, items) - lorem ipsum push :list, device_iden, title: title, items: items end @@ -36,7 +32,7 @@ def push_list(device_iden, title, items) # file_url - The url where the file can be downloaded. # body - An optional message. def push_file(device_iden, file_name, file_path, body) - something(file_name, file_path) do |data| + upload_file(file_name, file_path) do |data| payload = { file_name: data['file_name'], file_type: data['file_type'], @@ -55,6 +51,25 @@ def delete_push(push_iden) private + def upload_file(file_name, file_path, &block) + mime_type = MIME::Types.type_for(file_path).first.to_s + + data = upload_request(file_name, mime_type) + + upload_url = data.body['upload_url'] + payload = data.body['data'] + + io = Faraday::UploadIO.new(file_path, mime_type) + + post upload_url, payload.merge(file: io) + + yield data.body + end + + def upload_request(file_name, mime_type) + get '/v2/upload-request', file_name: file_name, file_type: mime_type + end + def push(type, device_iden, payload) post '/v2/pushes', payload.merge(device_iden: device_iden, type: type) end diff --git a/lib/pushbullet/api/upload_request.rb b/lib/pushbullet/api/upload_request.rb deleted file mode 100644 index 1089296..0000000 --- a/lib/pushbullet/api/upload_request.rb +++ /dev/null @@ -1,35 +0,0 @@ -# TODO: we should make Faraday middleware of upload request -module Pushbullet - module API - module Pushes - module UploadRequest - private - - def something(file_name, file_path, &block) - mime_type = MIME::Types.type_for(file_path).first.to_s - data = get('/v2/upload-request', file_name: file_name, file_type: mime_type) - io = Faraday::UploadIO.new(file_path, mime_type) - - upload_url = data.body['upload_url'] - payload = data.body['data'] - - res = upload_request(upload_url, payload.merge(file: io)) - - raise 'somthing whent wrong' unless res.status == 204 - - yield data.body - end - - def upload_request(upload_url, payload) - Faraday.new(url: upload_url) {|f| - f.request :multipart - f.request :url_encoded - f.adapter :net_http - }.post {|r| - r.body = payload - } - end - end - end - end -end diff --git a/lib/pushbullet/basic_authentication.rb b/lib/pushbullet/basic_authentication.rb new file mode 100644 index 0000000..7866aca --- /dev/null +++ b/lib/pushbullet/basic_authentication.rb @@ -0,0 +1,11 @@ +module Pushbullet + class BasicAuthentication < Faraday::Request::BasicAuthentication + def call(env) + if env.url.to_s.match(Pushbullet::Client::ENDPOINT) + env.request_headers[KEY] = @header_value + end + + @app.call(env) + end + end +end diff --git a/lib/pushbullet/client.rb b/lib/pushbullet/client.rb index 2561f50..ff6c92f 100644 --- a/lib/pushbullet/client.rb +++ b/lib/pushbullet/client.rb @@ -1,18 +1,52 @@ require 'faraday' require 'mime/types' -require 'pushbullet/request' require 'pushbullet/api' +require 'pushbullet/basic_authentication' +require 'pushbullet/http_exception' +require 'pushbullet/parse_json' +require 'pushbullet/request' module Pushbullet class Client include Request include API + ENDPOINT = 'https://api.pushbullet.com' + attr_reader :api_key def initialize(api_key) @api_key = api_key end + + def middleware + @middleware ||= Faraday::RackBuilder.new do |f| + f.request :multipart + f.request :url_encoded + + f.use Pushbullet::BasicAuthentication, @api_key, '' + f.use Pushbullet::ParseJSON + f.use Pushbullet::HttpException + + f.adapter :net_http + end + end + + def connection_options + @connection_options ||= { + :builder => middleware, + :headers => { + :accept => 'application/json', + :user_agent => "Pushbullet Ruby Gem #{Pushbullet::VERSION}", + } + } + end + + private + + def connection + @connection ||= Faraday.new(ENDPOINT, connection_options) + end end end diff --git a/lib/pushbullet/connection.rb b/lib/pushbullet/connection.rb deleted file mode 100644 index 5a5b497..0000000 --- a/lib/pushbullet/connection.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'pushbullet/http_exception' -require 'pushbullet/parse_json' - -module Pushbullet - module Connection - private - def connection - @connection ||= Faraday.new(url: 'https://api.pushbullet.com/') do |f| - f.request :basic_auth, api_key, '' - f.request :multipart - f.request :url_encoded - - f.response :logger - - f.use Pushbullet::ParseJSON - f.use Pushbullet::HttpException - - f.adapter :net_http - end - end - end -end diff --git a/lib/pushbullet/parse_json.rb b/lib/pushbullet/parse_json.rb index 0e0480f..614b28a 100644 --- a/lib/pushbullet/parse_json.rb +++ b/lib/pushbullet/parse_json.rb @@ -3,7 +3,11 @@ module Pushbullet class ParseJSON < Faraday::Response::Middleware def on_complete(env) - env[:body] = JSON.parse(env[:body]) + env[:body] = JSON.parse(env[:body]) unless unparsable_status_codes.include?(env.status) + end + + def unparsable_status_codes + [204] end end end diff --git a/lib/pushbullet/request.rb b/lib/pushbullet/request.rb index be046cd..53c0a82 100644 --- a/lib/pushbullet/request.rb +++ b/lib/pushbullet/request.rb @@ -1,9 +1,5 @@ -require 'pushbullet/connection' - module Pushbullet module Request - include Connection - def get(path, params = {}) request(:get, path, params) end From 03678308050509b5d4f4b2e3cd7927c1f6e2b497 Mon Sep 17 00:00:00 2001 From: Hiroshi Yoshida Date: Sun, 18 May 2014 16:38:23 +0900 Subject: [PATCH 3/6] Implement delete push --- lib/pushbullet/api/pushes.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/pushbullet/api/pushes.rb b/lib/pushbullet/api/pushes.rb index e11db84..b65e001 100644 --- a/lib/pushbullet/api/pushes.rb +++ b/lib/pushbullet/api/pushes.rb @@ -44,6 +44,16 @@ def push_file(device_iden, file_name, file_path, body) end end + # modified_after - Request pushes modified after this timestamp. + # cursor - Request another page of pushes (if necessary). + def pushes(modified_after = nil, cursor = nil) + params = {modified_after: modified_after, cursor: cursor} + + params = params.values.all?(&:nil?) ? {} : params + + get 'v2/pushes', params + end + # push_iden - The iden of the push to delete. def delete_push(push_iden) delete "/v2/pushes/#{push_iden}" From dbe14a290617a499709b5e5c8d0f532b5614b0c7 Mon Sep 17 00:00:00 2001 From: Hiroshi Yoshida Date: Sun, 18 May 2014 17:07:52 +0900 Subject: [PATCH 4/6] Remove comments --- lib/pushbullet/api/pushes.rb | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/pushbullet/api/pushes.rb b/lib/pushbullet/api/pushes.rb index b65e001..22ea3f6 100644 --- a/lib/pushbullet/api/pushes.rb +++ b/lib/pushbullet/api/pushes.rb @@ -1,36 +1,22 @@ module Pushbullet module API module Pushes - # title - The note's title. - # body - The note's message. def push_note(device_iden, title, body) push :note, device_iden, title: title, body: body end - # title - The link's title. - # url - The url to open. - # body - An optional message. def push_link(device_iden, title, url, body) push :link, device_iden, title: title, url: url, body: body end - # name - The place's name. - # address - The place's address or a map search query. def push_address(device_iden, name, address) push :address, device_iden, name: name, address: address end - # title - The list's title. - # items - The list items. - # [{text: 'lorem', checked: false}, {text: 'ipsum', checked: true}] def push_list(device_iden, title, items) push :list, device_iden, title: title, items: items end - # file_name - The name of the file. - # file_type - The file's MIME type. - # file_url - The url where the file can be downloaded. - # body - An optional message. def push_file(device_iden, file_name, file_path, body) upload_file(file_name, file_path) do |data| payload = { @@ -44,8 +30,6 @@ def push_file(device_iden, file_name, file_path, body) end end - # modified_after - Request pushes modified after this timestamp. - # cursor - Request another page of pushes (if necessary). def pushes(modified_after = nil, cursor = nil) params = {modified_after: modified_after, cursor: cursor} @@ -54,7 +38,6 @@ def pushes(modified_after = nil, cursor = nil) get 'v2/pushes', params end - # push_iden - The iden of the push to delete. def delete_push(push_iden) delete "/v2/pushes/#{push_iden}" end From cacfd230bb4d2d71c5ab633c31b26dfdffe6120c Mon Sep 17 00:00:00 2001 From: Hiroshi Yoshida Date: Sun, 18 May 2014 18:15:16 +0900 Subject: [PATCH 5/6] Rename method --- lib/pushbullet/api.rb | 4 ++-- lib/pushbullet/api/{users.rb => me.rb} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename lib/pushbullet/api/{users.rb => me.rb} (72%) diff --git a/lib/pushbullet/api.rb b/lib/pushbullet/api.rb index efc2e1b..8590706 100644 --- a/lib/pushbullet/api.rb +++ b/lib/pushbullet/api.rb @@ -1,13 +1,13 @@ require 'pushbullet/api/contacts' require 'pushbullet/api/devices' require 'pushbullet/api/pushes' -require 'pushbullet/api/users' +require 'pushbullet/api/me' module Pushbullet module API include Contacts include Devices include Pushes - include Users + include Me end end diff --git a/lib/pushbullet/api/users.rb b/lib/pushbullet/api/me.rb similarity index 72% rename from lib/pushbullet/api/users.rb rename to lib/pushbullet/api/me.rb index 216bb9b..56846df 100644 --- a/lib/pushbullet/api/users.rb +++ b/lib/pushbullet/api/me.rb @@ -1,7 +1,7 @@ module Pushbullet module API - module Users - def users + module Me + def me get '/v2/users/me' end end From c136b4bbb4772e564b06989f63b8d3384d5f38bc Mon Sep 17 00:00:00 2001 From: Hiroshi Yoshida Date: Sun, 18 May 2014 18:39:23 +0900 Subject: [PATCH 6/6] Update README --- README.md | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index e6a9186..471652e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Pushbullet -Ruby client of [Pushbullet](https://www.pushbullet.com/) API. +Ruby client of [Pushbullet](https://www.pushbullet.com/). ## Installation @@ -30,31 +30,35 @@ You can send following list: - file ```ruby -# get json about own device list +# Get own device list client.devices -client.push_note(DEVICE_ID, 'This is Title', 'This is Body!!!!') -client.push_file(DEVICE_ID, 'File Name', 'path/to/file') -``` +# note +client.push_note(device_iden, 'Title of note', 'A note's content') -#### :secret: Push to Friend's device :secret: +# link +client.push_link(device_iden, 'Title of link', 'https://www.pushbullet.com', 'This website is awesome.') -You can send following list: -- note -- link -- address -- list +# address +client.push_address(device_iden, 'Name of address', 'Addrss of place') -```ruby -# get json about friend list of Pushbullet +# list +client.push_list(device_iden, 'Title of lists', [{text: 'Buy milk', checked: true}, {text: 'Buy Soy milk', checked: false}]) + +# file +client.push_file(device_iden, 'File name', 'path/to/file', 'An optional message') + +# Get friend list of Pushbullet client.contacts -client.push_note_to('friend@email.com', 'Hi!!!', 'This is Body!!!!') +# Get self info +client.me ``` ## TODO -- test test test... +- push friend's device +- test... ## Contributing