From 99b3d7287bd0ac36ee82129ad38bd88c5b5af625 Mon Sep 17 00:00:00 2001 From: Jonathan B Date: Wed, 14 Aug 2019 21:25:02 +0200 Subject: Initial release --- .editorconfig | 9 +++++++ .gitignore | 9 +++++++ .travis.yml | 6 +++++ LICENSE | 21 ++++++++++++++++ README.md | 41 ++++++++++++++++++++++++++++++++ shard.yml | 9 +++++++ spec/spec_helper.cr | 2 ++ spec/twitcr_spec.cr | 9 +++++++ src/twitch/client.cr | 27 +++++++++++++++++++++ src/twitch/mappings/converters.cr | 3 +++ src/twitch/mappings/user.cr | 21 ++++++++++++++++ src/twitch/rest.cr | 50 +++++++++++++++++++++++++++++++++++++++ src/twitcr.cr | 6 +++++ 13 files changed, 213 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 shard.yml create mode 100644 spec/spec_helper.cr create mode 100644 spec/twitcr_spec.cr create mode 100644 src/twitch/client.cr create mode 100644 src/twitch/mappings/converters.cr create mode 100644 src/twitch/mappings/user.cr create mode 100644 src/twitch/rest.cr create mode 100644 src/twitcr.cr diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..163eb75 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*.cr] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0bbd4a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +/docs/ +/lib/ +/bin/ +/.shards/ +*.dwarf + +# Libraries don't need dependency lock +# Dependencies will be locked in applications that use them +/shard.lock diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..765f0e9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: crystal + +# Uncomment the following if you'd like Travis to run specs and check code formatting +# script: +# - crystal spec +# - crystal tool format --check diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..79081f3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019 Jonathan B. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..04ea7f1 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# twitcr + +Very limited API Rest wrapper for interacting with twitch. Not planning on finishing. + +## Installation + +1. Add the dependency to your `shard.yml`: + + ```yaml + dependencies: + twitcr: + github: your-github-user/twitcr + ``` + +2. Run `shards install` + +## Usage + +```crystal +require "twitcr" + +Twitcr::Client.new(oauth_token, oauth_id).user?(channel) +``` + +TODO: Write usage instructions here + +## Development + +TODO: Write development instructions here + +## Contributing + +1. Fork it () +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create a new Pull Request + +## Contributors + +- [Jonathan B.](https://github.com/your-github-user) - creator and maintainer diff --git a/shard.yml b/shard.yml new file mode 100644 index 0000000..906542c --- /dev/null +++ b/shard.yml @@ -0,0 +1,9 @@ +name: twitcr +version: 0.1.0 + +authors: + - Jonathan B. + +crystal: 0.30.1 + +license: MIT diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr new file mode 100644 index 0000000..a690804 --- /dev/null +++ b/spec/spec_helper.cr @@ -0,0 +1,2 @@ +require "spec" +require "../src/twitcr" diff --git a/spec/twitcr_spec.cr b/spec/twitcr_spec.cr new file mode 100644 index 0000000..c177cd8 --- /dev/null +++ b/spec/twitcr_spec.cr @@ -0,0 +1,9 @@ +require "./spec_helper" + +describe Twitcr do + # TODO: Write tests + + it "works" do + false.should eq(true) + end +end diff --git a/src/twitch/client.cr b/src/twitch/client.cr new file mode 100644 index 0000000..8502b90 --- /dev/null +++ b/src/twitch/client.cr @@ -0,0 +1,27 @@ +require "./rest" +require "./mappings/*" + +module Twitcr::Client + include REST + + getter token : String + getter client_id : String + + def initialize(@token, @client_id) + @token = "Bearer" + @token + end + + def user?(name : String) + true if get_user_by_login(name) + rescue EMPTY_RESULT + false + end + + def user(name : String) + get_user_by_login(name) + end + + def user(id : Int64) + get_user_by_id(id) + end +end diff --git a/src/twitch/mappings/converters.cr b/src/twitch/mappings/converters.cr new file mode 100644 index 0000000..d9b57e9 --- /dev/null +++ b/src/twitch/mappings/converters.cr @@ -0,0 +1,3 @@ +module Twitcr + TIME_FORMAT = Time::Format.new("%FT%TZ") +end diff --git a/src/twitch/mappings/user.cr b/src/twitch/mappings/user.cr new file mode 100644 index 0000000..6ddd08b --- /dev/null +++ b/src/twitch/mappings/user.cr @@ -0,0 +1,21 @@ +require "./converters" + +module Twitcr + struct UserList + JSON.mapping({data: Array(User)}) + end + + struct User + JSON.mapping({ + id: {type: UInt64, converter: ID::Converter}, + login: String, + display_name: String, + }) + end +end + +module ID::Converter + def self.from_json(value : JSON::PullParser) : UInt64 + UInt64.new(value.read_string) + end +end diff --git a/src/twitch/rest.cr b/src/twitch/rest.cr new file mode 100644 index 0000000..1de8d6f --- /dev/null +++ b/src/twitch/rest.cr @@ -0,0 +1,50 @@ +require "http" +require "json" +require "./mappings/*" + +module Twitcr::REST + # Mixin for interacting with Twitch's REST API + SSL_CONTEXT = OpenSSL::SSL::Context::Client.new + API_BASE = "https://api.twitch.tv/helix" + + EMPTY_RESULT = Exception.new("Empty Result") + + # Executes an HTTP request against the API_BASE url + def request(method : String, route : String, version = "5", headers = HTTP::Headers.new, body : String? = nil) + headers["Authorization"] = @token + headers["Client-ID"] = @client_id + + response = HTTP::Client.exec( + method, + API_BASE + route, + headers, + tls: SSL_CONTEXT + ) + + response.body + end + + def get_user_by_login(login : String) + response = request( + "GET", + "/users?login=" + login + ) + + list = UserList.from_json(response) + raise EMPTY_RESULT if list.data.empty? + + list.data.first + end + + def get_user_by_id(id : Int64) + response = request( + "GET", + "/users?id=" + id.to_s + ) + + list = UserList.from_json(response) + raise EMPTY_RESULT if list.data.empty? + + list.data.first + end +end diff --git a/src/twitcr.cr b/src/twitcr.cr new file mode 100644 index 0000000..701653d --- /dev/null +++ b/src/twitcr.cr @@ -0,0 +1,6 @@ +# TODO: Write documentation for `Twitcr` +module Twitcr + VERSION = "0.1.0" + + # TODO: Put your code here +end -- cgit v1.2.3