mastodonをpythonからさわる API解説

# <font color="red">2017/04/16更新</font>
メディアファイルのトゥートするやり方が分かったので更新

コメント通りsuzuryuさんより
Mastodon.pyを書き換える
それぞれの環境によって異なるが
\Python27\Lib\site-packages\mastodon

```Mastodon.py
    ###
    # Writing data: Media
    ###
    def media_post(self, media_file, mime_type = None):
        """
        Post an image. media_file can either be image data or
        a file name. If image data is passed directly, the mime
        type has to be specified manually, otherwise, it is
        determined from the file name.

        Throws a MastodonIllegalArgumentError if the mime type of the
        passed data or file can not be determined properly.

        Returns a media dict. This contains the id that can be used in
        status_post to attach the media file to a toot.
        """
        if os.path.isfile(media_file) and mime_type == None:
            mime_type = mimetypes.guess_type(media_file)[0]
            media_file = open(media_file, 'rb')

        if mime_type == None:
            raise MastodonIllegalArgumentError('Could not determine mime type or data passed directly without mime type.')

        random_suffix = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10))
        file_name = "mastodonpyupload_" + str(time.time()) + "_" + str(random_suffix) + mimetypes.guess_extension(mime_type)

        media_file_description = (file_name, media_file, mime_type)

        #下を書き換える
        #return self.__api_request('POST', '/api/v1/media', files = {'file': media_file_description}) #旧
        return self.__api_request("POST", "/api/v1/media", files = {"file" : (file_name, open(media_file, "rb"))}) #新

```

と、書き換え以下のコードでメデイアファイルがトゥート出来ます！

```py
# -*- coding: utf-8 -*-
from mastodon import *

import warnings
warnings.simplefilter("ignore", UnicodeWarning)

def login():
    mastodon = Mastodon(
        client_id="my_clientcred_pawoo.txt",
        access_token="my_usercred_pawoo.txt",
        api_base_url="https://pawoo.net"
    )
    return mastodon

def main():
    mastodon = login()
    media_files = [mastodon.media_post(media, "image/jpeg") for media in ["test.jpg"]]
    mastodon.status_post(status="test", media_ids=media_files)

if __name__ == '__main__':
    main()
```

# 環境
- Windows
- Python2.7

# 下準備
## インストール
[ここからダウンロード](https://github.com/halcy/Mastodon.py)

```
> pip install Mastodon.py
Collecting Mastodon.py
  Downloading Mastodon.py-1.0.6-py2.py3-none-any.whl
Collecting dateutils (from Mastodon.py)
  Downloading dateutils-0.6.6.tar.gz
Requirement already satisfied: requests in c:\python27\lib\site-packages (from Mastodon.py)
Collecting argparse (from dateutils->Mastodon.py)
  Downloading argparse-1.4.0-py2.py3-none-any.whl
Requirement already satisfied: python-dateutil in c:\python27\lib\site-packages (from dateutils->Mastodon.py)
Requirement already satisfied: pytz in c:\python27\lib\site-packages (from dateutils->Mastodon.py)
Requirement already satisfied: six>=1.5 in c:\python27\lib\site-packages (from python-dateutil->dateutils->Mastodon.py)
Building wheels for collected packages: dateutils
  Running setup.py bdist_wheel for dateutils ... done
  Stored in directory: C:\Users\Shirokuma\AppData\Local\pip\Cache\wheels\61\60\af\2081d0cb3cfaebaab704b6012d5b1a3bdba9e0c4be33ff7e65
Successfully built dateutils
Installing collected packages: argparse, dateutils, Mastodon.py
Successfully installed Mastodon.py-1.0.6 argparse-1.4.0 dateutils-0.6.6

```

## 登録
一度だけ行うのでコンソールからやる
今回は[pawoo.net](https://pawoo.net)のインスタンスに登録する

```
> python
>> from mastodon import Mastodon
>> Mastodon.create_app("client name", api_base_url = "https://pawoo.net", to_file = "my_clientcred_pawoo.txt")
>> mastodon = Mastodon(client_id="my_clientcred_pawoo.txt",api_base_url = "https://pawoo.net")
>> mastodon.log_in("mail address", "passwd",to_file = "my_usercred_pawoo.txt")
```
# API解説
## トゥート関係
ツイッターで言えばツイート

```py
from mastodon import *

def login():
    mastodon = Mastodon(
        client_id="my_clientcred_pawoo.txt",
        access_token="my_usercred_pawoo.txt",
        api_base_url = "https://pawoo.net"
    )
    return mastodon

def main():
    mastodon = login()
    #トゥート
    mastodon.toot("Hello World Toot by Python!")

    #メディアファイルをトゥートする場合
    #なぜかうまくトゥート出来なかった(´；ω；｀)
    mastodon.media_post("test.jpg", mime_type="image/jpeg")

    #詳細な設定のトゥートが出来る（リプ等用）
    mastodon.status_post(u"クソリプ", in_reply_to_id=None, media_ids=None, sensitive=False, visibility='', spoiler_text=None)

if __name__ == '__main__':
    main()
    
```

他にも...

```py
#特定のトゥートのユーザーを情報を返す
status(id)

#特定のトゥートの発言や返信先を返す
status_context(id)

#特定のトゥート（ブースト？）を削除？要確認
status_delete(id)

#特定のトゥートをお気に入り
status_favourite(id)

#特定のトゥートをお気に入りしたユーザーの一覧をListで返す
status_favourited_by(id)

#特定のトゥートをブーストする？要確認
status_reblog(id)

#特定のトゥートをブーストしたユーザーをListで返す
status_reblogged_by(id)

#特定のトゥートのファボを解除する
status_unfavourite(id)

#特定のトゥートのブーストを解除する
status_unreblog(id)

```

## タイムライン関係
タイムラインは5つある

- home
- local
- public
- hashtag
- mentions

```py
timeline(timeline="", max_id=None, since_id=None, limit=None)
#timeline=""はhomeがデフォルトで他にlocal、public、tag/hashtag、mentionsが指定できる

#指定するのが面倒くさいなら
#home
timeline_home(max_id=None, since_id=None, limit=None)
#local
timeline_local(max_id=None, since_id=None, limit=None)
#public
timeline_publicl(max_id=None, since_id=None, limit=None)
#hashtag
timeline_hashtag(hashtag, max_id=None, since_id=None, limit=None)
#mentaions
timeline_mentaions(max_id=None, since_id=None, limit=None)
```

### タイムラインの中身
timelineはList型なので中を見てみる

```
tl = mastodon.timeline_local(limit=1)
for row in tl:
    print row
```

中身（例）
Key見ればだいたい何だか分かるよね

```

timeline_dict = {
    'account' : {
        'username': 'test',
        'display_name': 'hello',
        'statuses_count': 114,
        'following_count': 514,
        'url': 'https://pawoo.net/@test',
        'locked': False,
        'created_at': '2017-04-15T17:41:30.053Z',
        'avatar_static': 'https://img.pawoo.net/accounts/avatars/***.jpg?****',
        'note': 'test',
        'header': '/headers/original/missing.png', 
        'followers_count': 3, 
        'avatar': 'https://img.pawoo.net/accounts/avatars/***.jpg?****', 
        'header_static': '/headers/original/missing.png', 
        'acct': 'test',
        'id': 114514
    }
    'reblogged' : None,
    'favourites_count' : 0,
    'media_attachments' : [],
    'in_reply_to_id', None,
    'application' : {u'website': None, u'name': u'Web'},
    'reblog' : None,
    'in_reply_to_account_id' : None,
    'tags', None,
    'uri', "tag:pawoo.net,2017-04-15:objectId=114514:objectType=Status",
    'visibility' : 'public',
    'id' : 114514,
    'content' : 'hogehoge',
    'sensitive' : False,
    'favourited' : None,
    'mentions' : [],
    'reblogs_count' : 0,
    'spoiler_text': ,
    'created_at' : '2017-04-15T18:21:15.197Z'
}
```

## アカウント関係

```
account(id)
```

とすると、timeline_dictのキーがaccountの中身が返ってくる
他にも...

```py

#特定のユーザーをブロックする場合
account_block(id)

#特定のユーザーをフォローする場合
account_follow(id)

#特定のユーザーのフォロワーをListで返す
account_followers(id)

#特定のユーザーがフォロワーしてるユーザーをListで返す
account_following(id)

#特定のユーザーをミュートする
account_mute(id)

#特定のユーザーがフォローしてるか等を返す
account_relationships(id)
#例
[{u'requested': False, u'muting': False, u'followed_by': False, u'blocking': False, u'following': False, u'id': id}]

#@nameのユーザーを検索し当てはまる結果をListで返す
account_search(q, limit=None)

#特定のユーザーの発言内容Listでを返す
account_statuses(id, max_id=None, since_id=None, limit=None)

#特定のユーザーのブロックを解除
account_unblock(id)

#特定のユーザーのフォローを解除
account_unfollow(id)

#特定のユーザーのミュートを解除
account_unmute(id)

#認証されたユーザー情報を返す
account_verify_credentials()

#ブロックしたユーザー一覧をListで返す
blocks()

#お気に入り一覧をListで返す
favourites()

#フォローリクエストの一覧をListで返す
follow_requests(id, max_id=None, since_id=None, limit=None)

#特定のユーザーのフォローリクエストを拒否する
follow_request_reject(id)

#特定のユーザーのフォローリクエストを承認する
follow_request_authorize(id)

#ミュートしたユーザー一覧をListで返す
mutes()

#通知の一覧をListで返す（フォローしてるユーザーのトゥート等）
notifications()

```

以上が全ての関数です

# sensitiveがTrueな画像をダウンロードする
おまけです
せっかくpawoo鯖でアカウント作ったんだから、無法地帯でチョメチョメな画像をダウンロードしようっていうコード

```py

# -*- coding: utf-8 -*-
from mastodon import *
import urllib2

#UnicodeWarningを黙らすため
import warnings
warnings.simplefilter("ignore", UnicodeWarning)

#ログインする
def login():
    mastodon = Mastodon(
        client_id="my_clientcred_pawoo.txt",
        access_token="my_usercred_pawoo.txt",
        api_base_url="https://pawoo.net"
    )
    return mastodon

#ダウンロードする
def download(url, save_path):
    def get_file_name(url):
        return url.split("/")[-1]

    req = urllib2.Request(url)
    req.add_header("User-agent", "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)")
    source = urllib2.urlopen(url).read()
    with open(save_path + "/" + get_file_name(url), 'wb') as file:
        file.write(source)

def main():
    #ログイン
    mastodon = login()
    
    #ローカルタイムライン取得
    tl = mastodon.timeline_local()
    for row in tl:
        #メディアファイルがあるかつsensitiveがTrueのみダウンロードする
        if len(row["media_attachments"]) != 0 and row["sensitive"] == True:
            url = row["media_attachments"][0]["url"].split("?")[0]
            print row["account"]["username"], "is uploaded picture"
            download(url, "dl")
if __name__ == '__main__':
    main()
    
```