master
commit
bbcb88cdcc
|
@ -0,0 +1,10 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.{ex,exs,yml}]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
|
@ -0,0 +1,20 @@
|
||||||
|
# The directory Mix will write compiled artifacts to.
|
||||||
|
/_build
|
||||||
|
|
||||||
|
# If you run "mix test --cover", coverage assets end up here.
|
||||||
|
/cover
|
||||||
|
|
||||||
|
# The directory Mix downloads your dependencies sources to.
|
||||||
|
/deps
|
||||||
|
|
||||||
|
# Where 3rd-party dependencies like ExDoc output generated docs.
|
||||||
|
/doc
|
||||||
|
|
||||||
|
# Ignore .fetch files in case you like to edit your project deps locally.
|
||||||
|
/.fetch
|
||||||
|
|
||||||
|
# If the VM crashes, it generates a dump, let's ignore it too.
|
||||||
|
erl_crash.dump
|
||||||
|
|
||||||
|
# Also ignore archive artifacts (built via "mix archive.build").
|
||||||
|
*.ez
|
|
@ -0,0 +1,17 @@
|
||||||
|
language: elixir
|
||||||
|
elixir:
|
||||||
|
- 1.3.0
|
||||||
|
otp_release:
|
||||||
|
- 19.0
|
||||||
|
- 18.0
|
||||||
|
sudo: false
|
||||||
|
notifications:
|
||||||
|
recipients:
|
||||||
|
- milmazz@gmail.com
|
||||||
|
env:
|
||||||
|
- MIX_ENV=test
|
||||||
|
script:
|
||||||
|
- "mix do local.hex --force, deps.get, test"
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- deps
|
|
@ -0,0 +1,13 @@
|
||||||
|
Copyright 2017 Milton Mazzarri
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,166 @@
|
||||||
|
# Hunter (alpha)
|
||||||
|
|
||||||
|
A Elixir client for [Mastodon](https://github.com/Gargron/mastodon/), a GNU social-compatible micro-blogging service
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
def deps do
|
||||||
|
[{:hunter, "~> 0.1.0"}]
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Assumming that you already know your *instance* and your *bearer token* you can do
|
||||||
|
the following:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(1)> conn = Hunter.new([base_url: "https://example.com", bearer_token: "123456"])
|
||||||
|
%Hunter.Client{base_url: "https://example.com",
|
||||||
|
bearer_token: "123456"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Getting the current user
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(2)> Hunter.verify_credentials(conn)
|
||||||
|
%Hunter.Account{acct: "milmazz",
|
||||||
|
avatar: "https://social.lou.lt/avatars/original/missing.png",
|
||||||
|
created_at: "2017-04-06T17:43:55.325Z", display_name: "Milton Mazzarri",
|
||||||
|
followers_count: 2, following_count: 3,
|
||||||
|
header: "https://social.lou.lt/headers/original/missing.png", id: 8039,
|
||||||
|
locked: false, note: "", statuses_count: 1,
|
||||||
|
url: "https://social.lou.lt/@milmazz", username: "milmazz"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fetching an account
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(3)> Hunter.account(conn, 8039)
|
||||||
|
%Hunter.Account{acct: "milmazz",
|
||||||
|
avatar: "https://social.lou.lt/avatars/original/missing.png",
|
||||||
|
created_at: "2017-04-06T17:43:55.325Z", display_name: "Milton Mazzarri",
|
||||||
|
followers_count: 2, following_count: 3,
|
||||||
|
header: "https://social.lou.lt/headers/original/missing.png", id: 8039,
|
||||||
|
locked: false, note: "", statuses_count: 1,
|
||||||
|
url: "https://social.lou.lt/@milmazz", username: "milmazz"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Getting an account's followers
|
||||||
|
|
||||||
|
Returns a list of `Accounts`
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(4)> Hunter.followers(conn, 8039)
|
||||||
|
[%Hunter.Account{acct: "atmantree@mastodon.club",
|
||||||
|
avatar: "https://social.lou.lt/system/accounts/avatars/000/008/518/original/7715529d4ceb4554.jpg?1491509276",
|
||||||
|
created_at: "2017-04-06T20:07:57.119Z", display_name: "Carlos Gustavo Ruiz",
|
||||||
|
followers_count: 2, following_count: 2,
|
||||||
|
header: "https://social.lou.lt/system/accounts/headers/000/008/518/original/394f31473de7c64a.png?1491509277",
|
||||||
|
id: 8518, locked: false,
|
||||||
|
note: "Programmer, Pythonista, Web Creature, Blogger, C++ and Haskell Fan. Never stop learning, because life never stops teaching.",
|
||||||
|
statuses_count: 1, url: "https://mastodon.club/@atmantree",
|
||||||
|
username: "atmantree"},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Getting who account is following
|
||||||
|
|
||||||
|
Returns a list of `Accounts`
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(5)> Hunter.following(conn, 8039)
|
||||||
|
[%Hunter.Account{acct: "sebasmagri@mastodon.cloud",
|
||||||
|
avatar: "https://social.lou.lt/system/accounts/avatars/000/007/899/original/19b4d8c1e9d4e68a.jpg?1491498458",
|
||||||
|
created_at: "2017-04-06T17:07:38.912Z",
|
||||||
|
display_name: "Sebastián Ramírez Magrí", followers_count: 2,
|
||||||
|
following_count: 1,
|
||||||
|
header: "https://social.lou.lt/system/accounts/headers/000/007/899/original/missing.png?1491498458",
|
||||||
|
id: 7899, locked: false, note: "", statuses_count: 2,
|
||||||
|
url: "https://mastodon.cloud/@sebasmagri", username: "sebasmagri"},
|
||||||
|
...]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Following a remote user
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(6)> Hunter.follow_by_uri(conn, "paperswelove@mstdn.io")
|
||||||
|
%Hunter.Account{acct: "paperswelove@mstdn.io",
|
||||||
|
avatar: "https://social.lou.lt/system/accounts/avatars/000/007/126/original/60ecc8225809c008.png?1491486258",
|
||||||
|
created_at: "2017-04-06T13:44:18.281Z", display_name: "Papers We Love",
|
||||||
|
followers_count: 1, following_count: 0,
|
||||||
|
header: "https://social.lou.lt/system/accounts/headers/000/007/126/original/missing.png?1491486258",
|
||||||
|
id: 7126, locked: false,
|
||||||
|
note: "Building Bridges Between Academia and Industry\r\n\r\n<a href=\"http://paperswelove.org\" rel=\"nofollow noopener\"><span class=\"invisible\">http://</span><span class=\"\">paperswelove.org</span><span class=\"invisible\"></span></a>\r\n<a href=\"http://pwlconf.org\" rel=\"nofollow noopener noopener\"><span class=\"invisible\">http://</span><span class=\"\">pwlconf.org</span><span class=\"invisible\"></span></a>",
|
||||||
|
statuses_count: 1, url: "https://mstdn.io/@paperswelove",
|
||||||
|
username: "paperswelove"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Muting/unmuting an account
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(7)> Hunter.mute(conn, 7899)
|
||||||
|
%Hunter.Relationship{blocking: false, followed_by: false, following: true,
|
||||||
|
muting: true, requested: false}
|
||||||
|
iex(8)> Hunter.unmute(conn, 7899)
|
||||||
|
%Hunter.Relationship{blocking: false, followed_by: false, following: true,
|
||||||
|
muting: false, requested: false}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Getting an account's statuses
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(9)> Hunter.statuses(conn, 8039, [limit: 1])
|
||||||
|
[%Hunter.Status{account: %{"acct" => "milmazz",
|
||||||
|
"avatar" => "https://social.lou.lt/avatars/original/missing.png",
|
||||||
|
"created_at" => "2017-04-06T17:43:55.325Z",
|
||||||
|
"display_name" => "Milton Mazzarri", "followers_count" => 2,
|
||||||
|
"following_count" => 4,
|
||||||
|
"header" => "https://social.lou.lt/headers/original/missing.png",
|
||||||
|
"id" => 8039, "locked" => false, "note" => "", "statuses_count" => 1,
|
||||||
|
"url" => "https://social.lou.lt/@milmazz", "username" => "milmazz"},
|
||||||
|
application: %{"name" => "Web", "website" => nil},
|
||||||
|
content: "<p><a href=\"http://tootplanet.space/@Shutsumon\" class=\"h-card u-url p-nickname mention\">@<span>Shutsumon</span></a> You should read "How to design programs" book <a href=\"http://htdp.org\" rel=\"nofollow noopener\" target=\"_blank\"><span class=\"invisible\">http://</span><span class=\"\">htdp.org</span><span class=\"invisible\"></span></a></p>",
|
||||||
|
created_at: "2017-04-06T18:28:59.392Z", favourited: nil, favourites_count: 0,
|
||||||
|
id: 59144, in_reply_to_account_id: 7742, in_reply_to_id: 59042,
|
||||||
|
media_attachments: [],
|
||||||
|
mentions: [%{"acct" => "Shutsumon@tootplanet.space", "id" => 7742,
|
||||||
|
"url" => "http://tootplanet.space/@Shutsumon", "username" => "Shutsumon"}],
|
||||||
|
reblog: nil, reblogged: nil, reblogs_count: 0, sensitive: false,
|
||||||
|
spoiler_text: "", tags: [],
|
||||||
|
uri: "tag:social.lou.lt,2017-04-06:objectId=59144:objectType=Status",
|
||||||
|
url: "https://social.lou.lt/@milmazz/59144", visibility: "public"}]
|
||||||
|
```
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
* OAuth2 authentication
|
||||||
|
- Register client for token-access
|
||||||
|
- Token authentication for API usage
|
||||||
|
* Search for accounts or content
|
||||||
|
* Getting an account's relationship
|
||||||
|
* Register an application
|
||||||
|
* Fetching a user's blocks
|
||||||
|
* Fetching a user's favourites
|
||||||
|
* Fetching a list of follow requests
|
||||||
|
* Authorizing or rejecting follow requests
|
||||||
|
* Support arrays as parameter types
|
||||||
|
* Getting instance information
|
||||||
|
* Uploading media attachment
|
||||||
|
* Fetching a user's mutes
|
||||||
|
* Fetching a user's notifications
|
||||||
|
* Getting a single notification
|
||||||
|
* Clearing notifications
|
||||||
|
* Fetching user's reports
|
||||||
|
* Reporting a user
|
||||||
|
* Getting status context
|
||||||
|
* Getting a card associated with a status
|
||||||
|
* Getting who reblogged/favourited a status
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Hunter source code is released under Apache 2 License.
|
||||||
|
|
||||||
|
Check the [LICENSE](LICENSE) for more information.
|
|
@ -0,0 +1,30 @@
|
||||||
|
# This file is responsible for configuring your application
|
||||||
|
# and its dependencies with the aid of the Mix.Config module.
|
||||||
|
use Mix.Config
|
||||||
|
|
||||||
|
# This configuration is loaded before any dependency and is restricted
|
||||||
|
# to this project. If another project depends on this project, this
|
||||||
|
# file won't be loaded nor affect the parent project. For this reason,
|
||||||
|
# if you want to provide default values for your application for
|
||||||
|
# 3rd-party users, it should be done in your "mix.exs" file.
|
||||||
|
|
||||||
|
# You can configure for your application as:
|
||||||
|
#
|
||||||
|
# config :hunter, key: :value
|
||||||
|
#
|
||||||
|
# And access this configuration in your application as:
|
||||||
|
#
|
||||||
|
# Application.get_env(:hunter, :key)
|
||||||
|
#
|
||||||
|
# Or configure a 3rd-party app:
|
||||||
|
#
|
||||||
|
# config :logger, level: :info
|
||||||
|
#
|
||||||
|
|
||||||
|
# It is also possible to import configuration files, relative to this
|
||||||
|
# directory. For example, you can emulate configuration per environment
|
||||||
|
# by uncommenting the line below and defining dev.exs, test.exs and such.
|
||||||
|
# Configuration from the imported file will override the ones defined
|
||||||
|
# here (which is why it is important to import them last).
|
||||||
|
#
|
||||||
|
import_config "#{Mix.env}.exs"
|
|
@ -0,0 +1,3 @@
|
||||||
|
use Mix.Config
|
||||||
|
|
||||||
|
config :hunter, hunter_api: Hunter.Api.HTTPClient
|
|
@ -0,0 +1,3 @@
|
||||||
|
use Mix.Config
|
||||||
|
|
||||||
|
config :hunter, hunter_api: Hunter.Api.InMemory
|
|
@ -0,0 +1,384 @@
|
||||||
|
defmodule Hunter do
|
||||||
|
@moduledoc """
|
||||||
|
A Elixir client for Mastodon, a GNU Social compatible micro-blogging service
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@hunter_version Mix.Project.config[:version]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve account of authenticated user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec verify_credentials(Hunter.Client.t) :: Hunter.Account.t
|
||||||
|
def verify_credentials(conn), do: Hunter.Account.verify_credentials(conn)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve account
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - account identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec account(Hunter.Client.t, non_neg_integer) :: Hunter.Account.t
|
||||||
|
def account(conn, id), do: Hunter.Account.account(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of followers
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - account identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec followers(Hunter.Client.t, non_neg_integer) :: [Hunter.Account.t]
|
||||||
|
def followers(conn, id), do: Hunter.Account.followers(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of followed accounts
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - account identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec following(Hunter.Client.t, non_neg_integer) :: [Hunter.Account.t]
|
||||||
|
def following(conn, id), do: Hunter.Account.following(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Follow a remote user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `uri` - URI of the remote user, in the format of `username@domain`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec follow_by_uri(Hunter.Client.t, URI.t) :: Hunter.Account.t
|
||||||
|
def follow_by_uri(conn, uri), do: Hunter.Account.follow_by_uri(conn, uri)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Register a new OAuth client app on the target instance
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `name`
|
||||||
|
* `redirect_uri`
|
||||||
|
* `scopes`
|
||||||
|
* `website`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec create_app(String.t, URI.t, String.t, String.t) :: Hunter.Application.t
|
||||||
|
def create_app(name, redirect_uri, scopes \\ "read", website \\ nil) do
|
||||||
|
Hunter.Application.create_app(name, redirect_uri, scopes, website)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Initializes a client
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `base_url` - URL of the instance you want to connect to
|
||||||
|
* `bearer_token` - [String] OAuth access token for your authenticated user
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec new(Keyword.t) :: Hunter.Client.t
|
||||||
|
def new(options \\ []), do: Hunter.Client.new(options)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
User agent of the client
|
||||||
|
"""
|
||||||
|
@spec user_agent() :: String.t
|
||||||
|
def user_agent, do: Hunter.Client.user_agent()
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Upload a media file
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `file`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec upload_media(Hunter.Client.t, Path.t) :: Hunter.Media.t
|
||||||
|
def upload_media(conn, file), do: Hunter.Media.upload_media(conn, file)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the relationships of authenticated user towards given other users
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `id` - list of relationship IDs
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec relationships([non_neg_integer]) :: [Hunter.Relationship.t]
|
||||||
|
def relationships(ids), do: Hunter.Relationship.relationships(ids)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Follow a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec follow(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def follow(conn, id), do: Hunter.Relationship.follow(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unfollow a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unfollow(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def unfollow(conn, id), do: Hunter.Relationship.unfollow(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Block a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec block(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def block(conn, id), do: Hunter.Relationship.block(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unblock a user
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unblock(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def unblock(conn, id), do: Hunter.Relationship.unblock(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Mute a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec mute(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def mute(conn, id), do: Hunter.Relationship.mute(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unmute a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unmute(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def unmute(conn, id), do: Hunter.Relationship.unmute(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Search for content
|
||||||
|
|
||||||
|
# Parameters
|
||||||
|
|
||||||
|
* `q` - search query
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `resolve` - whether to resolve non-local accounts
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec search(String.t, Keyword.t) :: Hunter.Result.t
|
||||||
|
def search(query, options \\ []), do: Hunter.Result.search(query, options)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create new status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `text` - [String]
|
||||||
|
* `in_reply_to_id` - [Integer]
|
||||||
|
* `media_ids` - [Array<Integer>]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec create_status(Hunter.Client.t, String.t, non_neg_integer, [non_neg_integer]) :: Hunter.Status.t
|
||||||
|
def create_status(conn, text, in_reply_to_id \\ nil, media_ids \\ []) do
|
||||||
|
Hunter.Status.create_status(conn, text, in_reply_to_id, media_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec status(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def status(conn, id), do: Hunter.Status.status(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Destroy status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec destroy_status(Hunter.Client.t, non_neg_integer) :: boolean
|
||||||
|
def destroy_status(conn, id), do: Hunter.Status.destroy_status(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Reblog a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec reblog(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def reblog(conn, id), do: Hunter.Status.reblog(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Undo a reblog of a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unreblog(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def unreblog(conn, id), do: Hunter.Status.unreblog(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Favorite a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec favourite(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def favourite(conn, id), do: Hunter.Status.favourite(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Undo a favorite of a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unfavourite(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def unfavourite(conn, id), do: Hunter.Status.unfavourite(conn, id)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of statuses by a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials -
|
||||||
|
* `account_id` - account identifier
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec statuses(Hunter.Client.t, non_neg_integer, Keyword.t) :: [Hunter.Status.t]
|
||||||
|
def statuses(conn, account_id, options \\ []) do
|
||||||
|
Hunter.Status.statuses(conn, account_id, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from the home timeline
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec home_timeline(Hunter.Client.t, Keyword.t) :: [Hunter.Status.t]
|
||||||
|
def home_timeline(conn, options \\ []) do
|
||||||
|
Hunter.Status.home_timeline(conn, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from the public timeline
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec public_timeline(Hunter.Client.t, Keyword.t) :: [Hunter.Status.t]
|
||||||
|
def public_timeline(conn, options \\ []) do
|
||||||
|
Hunter.Status.public_timeline(conn, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from a hashtag
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `hashtag` - string list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec hashtag_timeline(Hunter.Client.t, Keyword.t) :: [Hunter.Status.t]
|
||||||
|
def hashtag_timeline(conn, hashtag, options \\ []) do
|
||||||
|
Hunter.Status.hashtag_timeline(conn, hashtag, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns Hunter version
|
||||||
|
"""
|
||||||
|
@spec version() :: String.t
|
||||||
|
def version, do: @hunter_version
|
||||||
|
end
|
|
@ -0,0 +1,127 @@
|
||||||
|
defmodule Hunter.Account do
|
||||||
|
@moduledoc """
|
||||||
|
Account entity
|
||||||
|
|
||||||
|
This module defines a `Hunter.Account` struct and the main functions
|
||||||
|
for working with Accounts.
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `id` - the ID of the account
|
||||||
|
* `username` - the username of the account
|
||||||
|
* `acct` - equals `username` for local users, includes `@domain` for remote ones
|
||||||
|
* `display_name` - the account's display name
|
||||||
|
* `note` - Biography of user
|
||||||
|
* `url` - URL of the user's profile page (can be remote)
|
||||||
|
* `avatar` - URL to the avatar image
|
||||||
|
* `header` - URL to the header image
|
||||||
|
* `locked` - boolean for when the account cannot be followed without waiting for approval first
|
||||||
|
* `created_at` - the time the account was created
|
||||||
|
* `followers_count` - the number of followers for the account
|
||||||
|
* `following_count` - the number of accounts the given account is following
|
||||||
|
* `statuses_count` - the number of statuses the account has made
|
||||||
|
|
||||||
|
"""
|
||||||
|
@hunter_api Application.get_env(:hunter, :hunter_api)
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
id: non_neg_integer,
|
||||||
|
username: String.t,
|
||||||
|
acct: String.t,
|
||||||
|
display_name: String.t,
|
||||||
|
note: String.t,
|
||||||
|
url: URI.t,
|
||||||
|
avatar: URI.t,
|
||||||
|
header: URI.t,
|
||||||
|
locked: String.t,
|
||||||
|
created_at: String.t,
|
||||||
|
followers_count: non_neg_integer,
|
||||||
|
following_count: non_neg_integer,
|
||||||
|
statuses_count: non_neg_integer
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:id,
|
||||||
|
:username,
|
||||||
|
:acct,
|
||||||
|
:display_name,
|
||||||
|
:note,
|
||||||
|
:url,
|
||||||
|
:avatar,
|
||||||
|
:header,
|
||||||
|
:locked,
|
||||||
|
:created_at,
|
||||||
|
:followers_count,
|
||||||
|
:following_count,
|
||||||
|
:statuses_count]
|
||||||
|
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve account of authenticated user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec verify_credentials(Hunter.Client.t) :: Hunter.Account.t
|
||||||
|
def verify_credentials(conn) do
|
||||||
|
@hunter_api.verify_credentials(conn)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve account
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec account(Hunter.Client.t, non_neg_integer) :: Hunter.Account.t
|
||||||
|
def account(conn, id) do
|
||||||
|
@hunter_api.account(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of followers
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec followers(Hunter.Client.t, non_neg_integer) :: [Hunter.Account.t]
|
||||||
|
def followers(conn, id) do
|
||||||
|
@hunter_api.followers(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of followed accounts
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec following(Hunter.Client.t, non_neg_integer) :: [Hunter.Account.t]
|
||||||
|
def following(conn, id) do
|
||||||
|
@hunter_api.following(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Follow a remote user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `uri` - URI of the remote user, in the format of username@domain
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec follow_by_uri(Hunter.Client.t, URI.t) :: Hunter.Account.t
|
||||||
|
def follow_by_uri(conn, uri) do
|
||||||
|
@hunter_api.follow_by_uri(conn, uri)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,329 @@
|
||||||
|
defmodule Hunter.Api do
|
||||||
|
## Account
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve account of authenticated user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback verify_credentials(conn :: Hunter.Client.t) :: Hunter.Account.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve account
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - account identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback account(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Account.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of followers
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - account identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback followers(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Account.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of followed accounts
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - account identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback following(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Account.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Follow a remote user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `uri` - URI of the remote user, in the format of `username@domain`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback follow_by_uri(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Account.t
|
||||||
|
|
||||||
|
## Application
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Register a new OAuth client app on the target instance
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `name`
|
||||||
|
* `redirect_uri`
|
||||||
|
* `scopes`
|
||||||
|
* `website`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback create_app(conn :: Hunter.Client.t, name :: String.t, redirect_uri :: URI.t, scopes :: String.t, website :: String.t) :: Hunter.Application.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Upload a media file
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `file` -
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback upload_media(conn :: Hunter.Client.t, file :: Path.t) :: Hunter.Media.t
|
||||||
|
|
||||||
|
|
||||||
|
## Relationship
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the relationships of authenticated user towards given other users
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `id` - list of relationship IDs
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback relationships(ids :: [non_neg_integer]) :: [Hunter.Relationship.t]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Follow a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user id
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback follow(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unfollow a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback unfollow(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Block a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback block(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unblock a user
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback unblock(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Mute a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback mute(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unmute a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - user identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback unmute(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
|
||||||
|
## Result
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Search for content
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `q` - the search query
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `resolve` - whether to resolve non-local accounts
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback search(Hunter.Client.t, query :: String.t, options :: Keyword.t) :: Hunter.Result.t
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create new status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `text` - [String]
|
||||||
|
* `in_reply_to_id` - [Integer]
|
||||||
|
* `media_ids` - [Array<Integer>]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback create_status(conn :: Hunter.Client.t, text :: String.t, in_reply_to_id :: non_neg_integer, media_ids :: [non_neg_integer]) :: Hunter.Status.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback status(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Status
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Destroy status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback destroy_status(conn :: Hunter.Client.t, id :: non_neg_integer) :: boolean
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Reblog a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback reblog(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Status.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Undo a reblog of a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback unreblog(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Status.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Favorite a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback favourite(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Status.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Undo a favorite of a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `id` - status identifier
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback unfavourite(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Status.t
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of statuses by a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `account_id` - account identifier
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback statuses(conn :: Hunter.Client.t, account_id :: non_neg_integer, options :: Keyword.t) :: [Hunter.Status.t]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from the home timeline
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback home_timeline(conn :: Hunter.Client.t, options :: Keyword.t) :: [Hunter.Status.t]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from the public timeline
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback public_timeline(conn :: Hunter.Client.t, options :: Keyword.t) :: [Hunter.Status.t]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from a hashtag
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `hashtag` - list of strings
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@callback hashtag_timeline(conn :: Hunter.Client.t, hashtag :: [String.t], options :: Keyword.t) :: [Hunter.Status]
|
||||||
|
end
|
|
@ -0,0 +1,183 @@
|
||||||
|
defmodule Hunter.Api.HTTPClient do
|
||||||
|
@behaviour Hunter.Api
|
||||||
|
|
||||||
|
def verify_credentials(%Hunter.Client{base_url: base_url} = conn) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/accounts/verify_credentials", get_headers(conn))
|
||||||
|
Poison.decode!(body, as: %Hunter.Account{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def account(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/accounts/#{id}", get_headers(conn))
|
||||||
|
Poison.decode!(body, as: %Hunter.Account{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def followers(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/accounts/#{id}/followers", get_headers(conn))
|
||||||
|
Poison.decode!(body, as: [%Hunter.Account{}])
|
||||||
|
end
|
||||||
|
|
||||||
|
def following(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/accounts/#{id}/following", get_headers(conn))
|
||||||
|
Poison.decode!(body, as: [%Hunter.Account{}])
|
||||||
|
end
|
||||||
|
|
||||||
|
def follow_by_uri(%Hunter.Client{base_url: base_url} = conn, uri) do
|
||||||
|
payload = Poison.encode!(%{uri: uri})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/follows", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Account{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_app(%Hunter.Client{base_url: base_url} = conn, name, redirect_uri, scopes, website) do
|
||||||
|
payload = Poison.encode!(%{client_name: name, redirect_uris: redirect_uri, scopes: scopes, website: website})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/apps", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Application{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_media(%Hunter.Client{base_url: base_url} = conn, file) do
|
||||||
|
payload = Poison.encode!(%{file: file})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/media", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Media{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def relationships(_ids) do
|
||||||
|
# :: [Hunter.Relationship.t]
|
||||||
|
# @return [Hunter::Collection<Hunter::Relationship>]
|
||||||
|
# perform_request_with_collection(:get, '', array_param(:id, ids), Hunter::Relationship)
|
||||||
|
HTTPoison.get("/api/v1/accounts/relationships")
|
||||||
|
|
||||||
|
# Poison.decode!(body, as: [%Hunter.Relationship{}])
|
||||||
|
end
|
||||||
|
|
||||||
|
def follow(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/accounts/#{id}/follow", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Relationship{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfollow(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/accounts/#{id}/unfollow", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Relationship{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def block(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/accounts/#{id}/block", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Relationship{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def unblock(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/accounts/#{id}/unblock", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Relationship{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def mute(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/accounts/#{id}/mute", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Relationship{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def unmute(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/accounts/#{id}/unmute", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Relationship{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def search(_conn, _query, _options) do
|
||||||
|
# :: Hunter.Result.t
|
||||||
|
|
||||||
|
# @return [Hunter::Results] If q is a URL, Hunter will
|
||||||
|
# attempt to fetch the provided account or status. Otherwise, it
|
||||||
|
# will do a local account and hashtag search.
|
||||||
|
|
||||||
|
# opts = {
|
||||||
|
# q: query,
|
||||||
|
# }.merge(options)
|
||||||
|
|
||||||
|
# perform_request_with_object(:get, '/api/v1/search', opts, Hunter::Results)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_status(%Hunter.Client{base_url: base_url} = conn, text, in_reply_to_id, _media_ids) do
|
||||||
|
payload = Poison.encode!(%{status: text, in_reply_to_id: in_reply_to_id})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/statuses", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Status{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def status(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/statuses/#{id}", get_headers(conn))
|
||||||
|
Poison.decode(body, as: %Hunter.Status{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_status(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
case HTTPoison.delete(base_url <> "/api/v1/statuses/#{id}", get_headers(conn)) do
|
||||||
|
{:ok, %HTTPoison.Response{status_code: 200}} ->
|
||||||
|
true
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def reblog(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/statuses/#{id}/reblog", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Status{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def unreblog(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/statuses/#{id}/unreblog", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Status{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def favourite(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/statuses/#{id}/favourite", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Status{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfavourite(%Hunter.Client{base_url: base_url} = conn, id) do
|
||||||
|
payload = Poison.encode!(%{})
|
||||||
|
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.post(base_url <> "/api/v1/statuses/#{id}/unfavourite", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
|
||||||
|
Poison.decode!(body, as: %Hunter.Status{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def statuses(%Hunter.Client{base_url: base_url} = conn, account_id, options) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/accounts/#{account_id}/statuses", get_headers(conn), options)
|
||||||
|
Poison.decode!(body, as: [%Hunter.Status{}])
|
||||||
|
end
|
||||||
|
|
||||||
|
def home_timeline(%Hunter.Client{base_url: base_url} = conn, options) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/timelines/home", get_headers(conn), options)
|
||||||
|
Poison.decode!(body, as: [%Hunter.Status{}])
|
||||||
|
end
|
||||||
|
|
||||||
|
def public_timeline(%Hunter.Client{base_url: base_url} = conn, options) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/timelines/public", get_headers(conn), options)
|
||||||
|
Poison.decode!(body, as: [%Hunter.Status{}])
|
||||||
|
end
|
||||||
|
|
||||||
|
def hashtag_timeline(%Hunter.Client{base_url: base_url} = conn, hashtag, options) do
|
||||||
|
{:ok, %HTTPoison.Response{body: body, status_code: 200}} = HTTPoison.get(base_url <> "/api/v1/timelines/tag/#{hashtag}", get_headers(conn), options)
|
||||||
|
Poison.decode!(body, as: [%Hunter.Status{}])
|
||||||
|
end
|
||||||
|
|
||||||
|
## Helpers
|
||||||
|
defp get_headers(%Hunter.Client{bearer_token: token}) do
|
||||||
|
[{"Authorization", "Bearer #{token}"}]
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,52 @@
|
||||||
|
defmodule Hunter.Application do
|
||||||
|
@moduledoc """
|
||||||
|
Application entity
|
||||||
|
|
||||||
|
This module defines a `Hunter.Application` struct and the main functions
|
||||||
|
for working with Applications.
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `name` - name of the application
|
||||||
|
* `website` - homepage URL of the application
|
||||||
|
* `scope` - access scopes
|
||||||
|
* `redirect_uri` -
|
||||||
|
|
||||||
|
## Scopes
|
||||||
|
|
||||||
|
* `read` - read data
|
||||||
|
* `write` - post statuses and upload media for statuses
|
||||||
|
* `follow` - follow, unfollow, block, unblock
|
||||||
|
|
||||||
|
Multiple scopes can be requested during the authorization phase with the `scope` query param
|
||||||
|
|
||||||
|
"""
|
||||||
|
@hunter_api Application.get_env(:hunter, :hunter_api)
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
name: String.t,
|
||||||
|
redirect_uri: URI.t,
|
||||||
|
scopes: String.t,
|
||||||
|
website: URI.t
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:name, :redirect_uri, :scopes, :website]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Register a new OAuth client app on the target instance
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `name` -
|
||||||
|
* `redirect_uri` -
|
||||||
|
* `scopes` -
|
||||||
|
* `website` -
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec create_app(Hunter.Client.t, String.t, URI.t, String.t, String.t) :: Hunter.Application.t
|
||||||
|
def create_app(conn, name, redirect_uri, scopes \\ "read", website \\ nil) do
|
||||||
|
@hunter_api.create_app(conn, name, redirect_uri, scopes, website)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,29 @@
|
||||||
|
defmodule Hunter.Attribute do
|
||||||
|
@moduledoc """
|
||||||
|
Attribute entity
|
||||||
|
|
||||||
|
This module defines a `Hunter.Attribute` struct and the main functions
|
||||||
|
for working with Attributes.
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `id` - ID of the attachment
|
||||||
|
* `type` - One of: "image", "video", "gifv"
|
||||||
|
* `url` - URL of the locally hosted version of the image
|
||||||
|
* `remote_url` - For remote images, the remote URL of the original image
|
||||||
|
* `preview_url` - URL of the preview image
|
||||||
|
* `text_url` - Shorter URL for the image, for insertion into text (only present on local images)
|
||||||
|
|
||||||
|
"""
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
id: non_neg_integer,
|
||||||
|
type: String.t,
|
||||||
|
url: URI.t,
|
||||||
|
remote_url: URI.t,
|
||||||
|
preview_url: URI.t,
|
||||||
|
text_url: URI.t
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:id, :type, :url, :remote_url, :preview_url, :text_url]
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
defmodule Hunter.Card do
|
||||||
|
@moduledoc """
|
||||||
|
Card entity
|
||||||
|
|
||||||
|
This module defines a `Hunter.Card` struct and the main functions
|
||||||
|
for working with Cards
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `url`- The url associated with the card
|
||||||
|
* `title` - The title of the card
|
||||||
|
* `description` - The card description
|
||||||
|
* `image` - The image associated with the card, if any
|
||||||
|
|
||||||
|
"""
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
url: URI.t,
|
||||||
|
title: String.t,
|
||||||
|
description: String.t,
|
||||||
|
image: String.t
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:url, :title, :description, :image]
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
defmodule Hunter.Client do
|
||||||
|
@moduledoc """
|
||||||
|
Defines a `Hunter` client
|
||||||
|
"""
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
base_url: URI.t,
|
||||||
|
bearer_token: String.t
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:base_url, :bearer_token]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Initializes a client
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `base_url` - URL of the instance you want to connect to
|
||||||
|
* `bearer_token` - [String] OAuth access token for your authenticated user
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec new(Keyword.t) :: Hunter.Client.t
|
||||||
|
def new(options \\ []) do
|
||||||
|
struct(Hunter.Client, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
User agent of the client
|
||||||
|
"""
|
||||||
|
@spec user_agent() :: String.t
|
||||||
|
def user_agent do
|
||||||
|
"Hunter.Elixir/#{Hunter.version}"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,13 @@
|
||||||
|
defmodule Hunter.Context do
|
||||||
|
@moduledoc """
|
||||||
|
Context entity
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `ancestors` - The ancestors of the status in the conversation, as a list of Statuses
|
||||||
|
* `descendants` - The descendants of the status in the conversation, as a list of Statuses
|
||||||
|
|
||||||
|
"""
|
||||||
|
defstruct [:ancestors, :descendants]
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
defmodule Hunter.Instance do
|
||||||
|
@moduledoc """
|
||||||
|
Instance entity
|
||||||
|
|
||||||
|
This module defines a `Hunter.Instance` struct and the main functions
|
||||||
|
for working with Instances.
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `uri` - URI of the current instance
|
||||||
|
* `title` - The instance's title
|
||||||
|
* `description` - A description for the instance
|
||||||
|
* `email` - An email address which can be used to contact the instance administrator
|
||||||
|
|
||||||
|
"""
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
uri: URI.t,
|
||||||
|
title: String.t,
|
||||||
|
description: String.t,
|
||||||
|
email: String.t
|
||||||
|
}
|
||||||
|
|
||||||
|
defstruct [:uri, :title, :description, :email]
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
defmodule Hunter.Media do
|
||||||
|
|
||||||
|
@hunter_api Application.get_env(:hunter, :hunter_api)
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
id: non_neg_integer,
|
||||||
|
url: URI.t,
|
||||||
|
preview_url: URI.t,
|
||||||
|
type: String.t
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:id, :url, :preview_url, :type]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Upload a media file
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `file` - [HTTP::FormData::File]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec upload_media(Hunter.Client.t, Path.t) :: Hunter.Media.t
|
||||||
|
def upload_media(conn, file) do
|
||||||
|
@hunter_api.upload_media(conn, file)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,23 @@
|
||||||
|
defmodule Hunter.Mention do
|
||||||
|
@moduledoc """
|
||||||
|
Mention entity
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `url` - URL of user's profile (can be remote)
|
||||||
|
* `username` - The username of the account
|
||||||
|
* `acct` - Equals `username` for local users, includes `@domain` for remote ones
|
||||||
|
* `id` - Account ID
|
||||||
|
|
||||||
|
"""
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
url: URI.t,
|
||||||
|
username: String.t,
|
||||||
|
acct: String.t,
|
||||||
|
id: non_neg_integer
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:url, :username, :acct, :id]
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,27 @@
|
||||||
|
defmodule Hunter.Notification do
|
||||||
|
@moduledoc """
|
||||||
|
Notification entity
|
||||||
|
|
||||||
|
This module defines a `Hunter.Notification` struct and the main functions
|
||||||
|
for working with Notifications.
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `id` - The notification ID
|
||||||
|
* `type` - One of: "mention", "reblog", "favourite", "follow"
|
||||||
|
* `created_at` - The time the notification was created
|
||||||
|
* `account` - The `Hunter.Account` sending the notification to the user
|
||||||
|
* `status` - The `Hunter.Status` associated with the notification, if applicable
|
||||||
|
|
||||||
|
"""
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
id: String.t,
|
||||||
|
type: String.t,
|
||||||
|
created_at: String.t,
|
||||||
|
account: Hunter.Account.t,
|
||||||
|
status: Hunter.Status.t
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:id, :type, :created_at, :account, :status]
|
||||||
|
end
|
|
@ -0,0 +1,124 @@
|
||||||
|
defmodule Hunter.Relationship do
|
||||||
|
@moduledoc """
|
||||||
|
Relationship entity
|
||||||
|
|
||||||
|
This module defines a `Hunter.Relationship` struct and the main functions
|
||||||
|
for working with Relationship.
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `following` - Whether the user is currently following the account
|
||||||
|
* `followed_by` - Whether the user is currently being followed by the account
|
||||||
|
* `blocking` - Whether the user is currently blocking the account
|
||||||
|
* `muting` - Whether the user is currently muting the account
|
||||||
|
* `requested` - Whether the user has requested to follow the account
|
||||||
|
|
||||||
|
"""
|
||||||
|
@hunter_api Application.get_env(:hunter, :hunter_api)
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
following: boolean,
|
||||||
|
followed_by: boolean,
|
||||||
|
blocking: boolean,
|
||||||
|
muting: boolean,
|
||||||
|
requested: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:following, :followed_by, :blocking, :muting, :requested]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the relationships of authenticated user towards given other users
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `id` - list of relationship IDs
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec relationships([non_neg_integer]) :: [Hunter.Relationship.t]
|
||||||
|
def relationships(ids) do
|
||||||
|
@hunter_api.relationships(ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Follow a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id` - user id
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec follow(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def follow(conn, id) do
|
||||||
|
@hunter_api.follow(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unfollow a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unfollow(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def unfollow(conn, id) do
|
||||||
|
@hunter_api.unfollow(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Block a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec block(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def block(conn, id) do
|
||||||
|
@hunter_api.block(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unblock a user
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unblock(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def unblock(conn, id) do
|
||||||
|
@hunter_api.unblock(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Mute a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec mute(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def mute(conn, id) do
|
||||||
|
@hunter_api.mute(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Unmute a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id`
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unmute(Hunter.Client.t, non_neg_integer) :: Hunter.Relationship.t
|
||||||
|
def unmute(conn, id) do
|
||||||
|
@hunter_api.unmute(conn, id)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
defmodule Hunter.Report do
|
||||||
|
@moduledoc """
|
||||||
|
Report entity
|
||||||
|
|
||||||
|
This module defines a `Hunter.Report` struct and the main functions
|
||||||
|
for working with Reports.
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `id` - The ID of the report
|
||||||
|
* `action_taken` - The action taken in response to the report
|
||||||
|
|
||||||
|
"""
|
||||||
|
defstruct [:id, :action_taken]
|
||||||
|
end
|
|
@ -0,0 +1,42 @@
|
||||||
|
defmodule Hunter.Result do
|
||||||
|
@moduledoc """
|
||||||
|
Result entity
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `accounts` - list of matched `Hunter.Account`
|
||||||
|
* `statuses` - list of matched `Hunter.Status`
|
||||||
|
* `hashtags` - list of matched hashtags, as strings
|
||||||
|
|
||||||
|
"""
|
||||||
|
@hunter_api Application.get_env(:hunter, :hunter_api)
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
accounts: [Hunter.Account.t],
|
||||||
|
statuses: [Hunter.Status.t],
|
||||||
|
hashtags: [String.t]
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct accounts: [],
|
||||||
|
statuses: [],
|
||||||
|
hashtags: []
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Search for content
|
||||||
|
|
||||||
|
# Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `q` - [String] The search query
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `resolve` - [Boolean] Whether to resolve non-local accounts
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec search(Hunter.Client.t, String.t, Keyword.t) :: Hunter.Result.t
|
||||||
|
def search(conn, query, options \\ []) do
|
||||||
|
@hunter_api.search(conn, query, options)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,255 @@
|
||||||
|
defmodule Hunter.Status do
|
||||||
|
@moduledoc """
|
||||||
|
Status entity
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `id` - The ID of the status
|
||||||
|
* `uri` - A Fediverse-unique resource ID
|
||||||
|
* `url` - URL to the status page (can be remote)
|
||||||
|
* `account` - The `Hunter.Account` which posted the status
|
||||||
|
* `in_reply_to_id` - `nil` or the ID of the status it replies to
|
||||||
|
* `in_reply_to_account_id` - `nil` or the ID of the account it replies to
|
||||||
|
* `reblog` - `nil` or the reblogged `Hunter.Status`
|
||||||
|
* `content` - Body of the status; this will contain HTML (remote HTML already sanitized)
|
||||||
|
* `created_at` - The time the status was created
|
||||||
|
* `reblogs_count` - The number of reblogs for the status
|
||||||
|
* `favourites_count` - The number of favourites for the status
|
||||||
|
* `reblogged` - Whether the authenticated user has reblogged the status
|
||||||
|
* `favourited` - Whether the authenticated user has favourited the status
|
||||||
|
* `sensitive` - Whether media attachments should be hidden by default
|
||||||
|
* `spoiler_text` - If not empty, warning text that should be displayed before the actual content
|
||||||
|
* `visibility` - One of: `public`, `unlisted`, `private`, `direct`
|
||||||
|
* `media_attachments` - A list of `Hunter.Attachment`
|
||||||
|
* `mentions` - A list of `Hunter.Mention`
|
||||||
|
* `tags` - A list of `Hunter.Tag`
|
||||||
|
* `application` - `Hunter.Application` from which the status was posted
|
||||||
|
|
||||||
|
"""
|
||||||
|
@hunter_api Application.get_env(:hunter, :hunter_api)
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
id: non_neg_integer,
|
||||||
|
uri: URI.t,
|
||||||
|
url: URI.t,
|
||||||
|
account: Hunter.Account.t,
|
||||||
|
in_reply_to_id: non_neg_integer,
|
||||||
|
reblog: Hunter.Status.t | nil,
|
||||||
|
content: String.t,
|
||||||
|
created_at: String.t,
|
||||||
|
reblogs_count: non_neg_integer,
|
||||||
|
favourites_count: non_neg_integer,
|
||||||
|
reblogged: boolean,
|
||||||
|
favourited: boolean,
|
||||||
|
sensitive: boolean,
|
||||||
|
spoiler_text: String.t,
|
||||||
|
media_attachments: [Hunter.Attachment.t],
|
||||||
|
mentions: [Hunter.Mention.t],
|
||||||
|
tags: [Hunter.Tag.t],
|
||||||
|
application: Hunter.Application.t
|
||||||
|
}
|
||||||
|
|
||||||
|
@derive [Poison.Encoder]
|
||||||
|
defstruct [:id,
|
||||||
|
:uri,
|
||||||
|
:url,
|
||||||
|
:account,
|
||||||
|
:in_reply_to_id,
|
||||||
|
:in_reply_to_account_id,
|
||||||
|
:reblog,
|
||||||
|
:content,
|
||||||
|
:created_at,
|
||||||
|
:reblogs_count,
|
||||||
|
:favourites_count,
|
||||||
|
:reblogged,
|
||||||
|
:favourited,
|
||||||
|
:sensitive,
|
||||||
|
:spoiler_text,
|
||||||
|
:visibility,
|
||||||
|
:media_attachments,
|
||||||
|
:mentions,
|
||||||
|
:tags,
|
||||||
|
:application]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create new status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `text` - [String]
|
||||||
|
* `in_reply_to_id` - [Integer]
|
||||||
|
* `media_ids` - [Array<Integer>]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec create_status(Hunter.Client.t, String.t, non_neg_integer, [non_neg_integer]) :: Hunter.Status.t
|
||||||
|
def create_status(conn, text, in_reply_to_id \\ nil, media_ids \\ []) do
|
||||||
|
@hunter_api.create_status(conn, text, in_reply_to_id, media_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id` [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec status(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def status(conn, id) do
|
||||||
|
@hunter_api.status(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Destroy status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id` [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec destroy_status(Hunter.Client.t, non_neg_integer) :: boolean
|
||||||
|
def destroy_status(conn, id) do
|
||||||
|
@hunter_api.destroy_status(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Reblog a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec reblog(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def reblog(conn, id) do
|
||||||
|
@hunter_api.reblog(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Undo a reblog of a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unreblog(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def unreblog(conn, id) do
|
||||||
|
@hunter_api.unreblog(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Favorite a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec favourite(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def favourite(conn, id) do
|
||||||
|
@hunter_api.favourite(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Undo a favorite of a status
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `id` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec unfavourite(Hunter.Client.t, non_neg_integer) :: Hunter.Status.t
|
||||||
|
def unfavourite(conn, id) do
|
||||||
|
@hunter_api.unfavourite(conn, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a list of statuses by a user
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `account_id` [Integer]
|
||||||
|
* `options` - options
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec statuses(Hunter.Client.t, non_neg_integer, Keyword.t) :: [Hunter.Status.t]
|
||||||
|
def statuses(conn, account_id, options \\ []) do
|
||||||
|
@hunter_api.statuses(conn, account_id, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from the home timeline
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec home_timeline(Hunter.Client.t, Keyword.t) :: [Hunter.Status.t]
|
||||||
|
def home_timeline(conn, options \\ []) do
|
||||||
|
@hunter_api.home_timeline(conn, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from the public timeline
|
||||||
|
|
||||||
|
## Parametes
|
||||||
|
|
||||||
|
* `conn` - Connection credentials
|
||||||
|
* `options` - option list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec public_timeline(Hunter.Client.t, Keyword.t) :: [Hunter.Status.t]
|
||||||
|
def public_timeline(conn, options \\ []) do
|
||||||
|
@hunter_api.public_timeline(conn, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieve statuses from a hashtag
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* `conn` - connection credentials
|
||||||
|
* `hashtag` - string list
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `max_id` - [Integer]
|
||||||
|
* `since_id` - [Integer]
|
||||||
|
* `limit` - [Integer]
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec hashtag_timeline(Hunter.Client.t, Keyword.t) :: [Hunter.Status.t]
|
||||||
|
def hashtag_timeline(conn, hashtag, options \\ []) do
|
||||||
|
@hunter_api.hashtag_timeline(conn, hashtag, options)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,18 @@
|
||||||
|
defmodule Hunter.Tag do
|
||||||
|
@moduledoc """
|
||||||
|
Tag entity
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
* `name` - The hashtag, not including the preceding `#`
|
||||||
|
* `url` - The URL of the hashtag
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
name: String.t,
|
||||||
|
url: URI.t
|
||||||
|
}
|
||||||
|
|
||||||
|
defstruct [:name, :url]
|
||||||
|
end
|
|
@ -0,0 +1,45 @@
|
||||||
|
defmodule Hunter.Mixfile do
|
||||||
|
use Mix.Project
|
||||||
|
|
||||||
|
def project do
|
||||||
|
[app: :hunter,
|
||||||
|
version: "0.1.0",
|
||||||
|
elixir: "~> 1.3",
|
||||||
|
docs: docs(),
|
||||||
|
package: package(),
|
||||||
|
source_url: "https://github.com/milmazz/hunter",
|
||||||
|
description: "Elixir wrapper for Mastodon API",
|
||||||
|
build_embedded: Mix.env == :prod,
|
||||||
|
start_permanent: Mix.env == :prod,
|
||||||
|
elixirc_paths: elixirc_paths(Mix.env),
|
||||||
|
deps: deps()]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Configuration for the OTP application
|
||||||
|
#
|
||||||
|
# Type "mix help compile.app" for more information
|
||||||
|
def application do
|
||||||
|
# Specify extra applications you'll use from Erlang/Elixir
|
||||||
|
[extra_applications: [:logger, :httpoison]]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp deps do
|
||||||
|
[{:httpoison, "~> 0.10.0"},
|
||||||
|
{:poison, "~> 3.0"},
|
||||||
|
{:ex_doc, "~> 0.14", only: :dev, runtime: false}]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp package do
|
||||||
|
[licenses: ["Apache 2.0"],
|
||||||
|
maintainers: ["Milton Mazzarri"],
|
||||||
|
links: %{"GitHub" => "https://github.com/milmazz/hunter"}]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp docs do
|
||||||
|
[extras: ["README.md"], main: "readme"]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Specifies which paths to compile per environment
|
||||||
|
defp elixirc_paths(:test), do: ["lib", "test/support"]
|
||||||
|
defp elixirc_paths(_), do: ["lib"]
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []},
|
||||||
|
"earmark": {:hex, :earmark, "1.2.0", "bf1ce17aea43ab62f6943b97bd6e3dc032ce45d4f787504e3adf738e54b42f3a", [:mix], []},
|
||||||
|
"ex_doc": {:hex, :ex_doc, "0.15.0", "e73333785eef3488cf9144a6e847d3d647e67d02bd6fdac500687854dd5c599f", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]},
|
||||||
|
"hackney": {:hex, :hackney, "1.6.6", "5564b4695d48fd87859e9df77a7fa4b4d284d24519f0cd7cc898f09e8fbdc8a3", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
|
||||||
|
"httpoison": {:hex, :httpoison, "0.10.0", "4727b3a5e57e9a4ff168a3c2883e20f1208103a41bccc4754f15a9366f49b676", [:mix], [{:hackney, "~> 1.6.3", [hex: :hackney, optional: false]}]},
|
||||||
|
"idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []},
|
||||||
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
|
||||||
|
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
|
||||||
|
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
|
||||||
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}}
|
|
@ -0,0 +1,104 @@
|
||||||
|
defmodule Hunter.Api.InMemory do
|
||||||
|
@behaviour Hunter.Api
|
||||||
|
|
||||||
|
def verify_credentials(_) do
|
||||||
|
%Hunter.Account{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def account(_, _) do
|
||||||
|
%Hunter.Account{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def followers(_, _) do
|
||||||
|
[%Hunter.Account{}]
|
||||||
|
end
|
||||||
|
|
||||||
|
def following(_, _) do
|
||||||
|
[%Hunter.Account{}]
|
||||||
|
end
|
||||||
|
|
||||||
|
def follow_by_uri(_, _) do
|
||||||
|
%Hunter.Account{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_app(_, _, _, _, _) do
|
||||||
|
%Hunter.Application{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_media(_, _) do
|
||||||
|
%Hunter.Media{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def relationships(_) do
|
||||||
|
end
|
||||||
|
|
||||||
|
def follow(_, _) do
|
||||||
|
%Hunter.Relationship{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfollow(_, _) do
|
||||||
|
%Hunter.Relationship{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def block(_, _) do
|
||||||
|
%Hunter.Relationship{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def unblock(_, _) do
|
||||||
|
%Hunter.Relationship{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def mute(_, _) do
|
||||||
|
%Hunter.Relationship{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def unmute(_, _) do
|
||||||
|
%Hunter.Relationship{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def search(_, _, _) do
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_status(_, _, _, _) do
|
||||||
|
end
|
||||||
|
|
||||||
|
def status(_, _) do
|
||||||
|
%Hunter.Status{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_status(_, _) do
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def reblog(_, _) do
|
||||||
|
%Hunter.Status{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def unreblog(_, _) do
|
||||||
|
%Hunter.Status{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def favourite(_, _) do
|
||||||
|
%Hunter.Status{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfavourite(_, _) do
|
||||||
|
%Hunter.Status{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def statuses(_, _, _) do
|
||||||
|
[%Hunter.Status{}]
|
||||||
|
end
|
||||||
|
|
||||||
|
def home_timeline(_, _) do
|
||||||
|
[%Hunter.Status{}]
|
||||||
|
end
|
||||||
|
|
||||||
|
def public_timeline(_, _) do
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def hashtag_timeline(_, _, _) do
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
ExUnit.start()
|
Loading…
Reference in New Issue