Skip to content

Commit 0c514cb

Browse files
authored
Merge pull request #9 from anxdpanic/dev
updates, complete v5 endpoints
2 parents 9a2e2b2 + 3f9cd7a commit 0c514cb

17 files changed

Lines changed: 715 additions & 144 deletions

resources/lib/twitch/api/parameters.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- encoding: utf-8 -*-
2+
from base64 import b64decode
23

34

45
class _Parameter(object):
@@ -40,17 +41,60 @@ class SortBy(_Parameter):
4041
_valid = [CREATED_AT, LAST_BROADCAST, LOGIN]
4142

4243

44+
class VideoSort(_Parameter):
45+
VIEWS = 'views'
46+
TIME = 'time'
47+
48+
_valid = [VIEWS, TIME]
49+
50+
4351
class BroadcastType(_Parameter):
4452
ARCHIVE = 'archive'
4553
HIGHLIGHT = 'highlight'
4654
UPLOAD = 'upload'
4755

4856
_valid = [ARCHIVE, HIGHLIGHT, UPLOAD]
4957

58+
@classmethod
59+
def validate(cls, value):
60+
split_values = value.split(',')
61+
for val in split_values:
62+
if val not in cls._valid:
63+
raise ValueError(value)
64+
return value
65+
5066

5167
class StreamType(_Parameter):
5268
LIVE = 'live'
5369
PLAYLIST = 'playlist'
5470
ALL = 'all'
5571

5672
_valid = [LIVE, PLAYLIST, ALL]
73+
74+
75+
class Cursor(_Parameter):
76+
@classmethod
77+
def validate(cls, value):
78+
try:
79+
decoded = int(b64decode(value))
80+
return value
81+
except ValueError:
82+
raise ValueError(value)
83+
84+
85+
class Language(_Parameter):
86+
ALL = 'all'
87+
# add twitch supported language codes
88+
_valid = [ALL]
89+
90+
@classmethod
91+
def validate(cls, value):
92+
split_values = value.split(',')
93+
for val in split_values:
94+
if val not in cls._valid:
95+
raise ValueError(value)
96+
return value
97+
98+
99+
class Duration(_Parameter):
100+
_valid = [30, 60, 90, 120, 150, 180]

resources/lib/twitch/api/v5/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
# -*- encoding: utf-8 -*-
22
# https://dev.twitch.tv/docs/
33

4+
from twitch.api.v5 import bits # NOQA
5+
from twitch.api.v5 import channel_feed # NOQA
46
from twitch.api.v5 import channels # NOQA
7+
from twitch.api.v5 import chat # NOQA
8+
from twitch.api.v5 import collections # NOQA
9+
from twitch.api.v5 import communities # NOQA
510
from twitch.api.v5 import games # NOQA
611
from twitch.api.v5 import ingests # NOQA
12+
from twitch.api.v5.root import root # NOQA
713
from twitch.api.v5 import search # NOQA
814
from twitch.api.v5 import streams # NOQA
915
from twitch.api.v5 import teams # NOQA
1016
from twitch.api.v5 import users # NOQA
1117
from twitch.api.v5 import videos # NOQA
12-
from twitch.api.v5 import communities # NOQA
13-
from twitch.api.v5.root import root # NOQA
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# -*- encoding: utf-8 -*-
2+
# https://dev.twitch.tv/docs/v5/reference/bits/
3+
4+
from twitch import keys
5+
from twitch.queries import V5Query as Qry
6+
from twitch.queries import query
7+
8+
9+
# required scope: None
10+
@query
11+
def get_cheermotes(channel_id=None):
12+
q = Qry('bits/actions')
13+
q.add_param(keys.CHANNEL_ID, channel_id, None)
14+
return q
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# -*- encoding: utf-8 -*-
2+
# https://dev.twitch.tv/docs/v5/reference/channel-feed/
3+
4+
from twitch import keys, methods
5+
from twitch.api.parameters import Boolean, Cursor
6+
from twitch.queries import V5Query as Qry
7+
from twitch.queries import query
8+
9+
10+
# required scope: any/none
11+
@query
12+
def get_posts(channel_id, limit=10, cursor='MA==', comments=5):
13+
q = Qry('feed/{channel_id}/posts')
14+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
15+
q.add_param(keys.LIMIT, limit, 10)
16+
q.add_param(keys.CURSOR, Cursor.validate(cursor), 'MA==')
17+
q.add_param(keys.COMMENTS, comments, 5)
18+
return q
19+
20+
21+
# required scope: any/none
22+
@query
23+
def get_post(channel_id, post_id, comments=5):
24+
q = Qry('feed/{channel_id}/posts/{post_id}')
25+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
26+
q.add_urlkw(keys.POST_ID, post_id)
27+
q.add_param(keys.COMMENTS, comments, 5)
28+
return q
29+
30+
31+
# required scope: channel_feed_edit
32+
@query
33+
def create_post(channel_id, content, share=Boolean.FALSE):
34+
q = Qry('feed/{channel_id}/posts/', method=methods.POST)
35+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
36+
q.add_param(keys.SHARE, Boolean.validate(share))
37+
q.add_data(keys.CONTENT, content)
38+
return q
39+
40+
41+
# required scope: channel_feed_edit
42+
@query
43+
def delete_post(channel_id, post_id):
44+
q = Qry('feed/{channel_id}/posts/{post_id}', method=methods.DELETE)
45+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
46+
q.add_urlkw(keys.POST_ID, post_id)
47+
return q
48+
49+
50+
# required scope: channel_feed_edit
51+
@query
52+
def create_post_reaction(channel_id, post_id, emote_id):
53+
q = Qry('feed/{channel_id}/posts/{post_id}/reactions', method=methods.POST)
54+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
55+
q.add_urlkw(keys.POST_ID, post_id)
56+
q.add_param(keys.EMOTE_ID, emote_id)
57+
return q
58+
59+
60+
# required scope: channel_feed_edit
61+
@query
62+
def delete_post_reaction(channel_id, post_id, emote_id):
63+
q = Qry('feed/{channel_id}/posts/{post_id}/reactions', method=methods.DELETE)
64+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
65+
q.add_urlkw(keys.POST_ID, post_id)
66+
q.add_param(keys.EMOTE_ID, emote_id)
67+
return q
68+
69+
70+
# required scope: any/none
71+
@query
72+
def get_comments(channel_id, post_id, limit=10, cursor='MA=='):
73+
q = Qry('feed/{channel_id}/posts/{post_id}/comments')
74+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
75+
q.add_urlkw(keys.POST_ID, post_id)
76+
q.add_param(keys.LIMIT, limit, 10)
77+
q.add_param(keys.CURSOR, Cursor.validate(cursor), 'MA==')
78+
return q
79+
80+
81+
# required scope: channel_feed_edit
82+
@query
83+
def comment(channel_id, post_id, content):
84+
q = Qry('feed/{channel_id}/posts/{post_id}/comments', method=methods.POST)
85+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
86+
q.add_urlkw(keys.POST_ID, post_id)
87+
q.add_data(keys.CONTENT, content)
88+
return q
89+
90+
91+
# required scope: channel_feed_edit
92+
@query
93+
def delete_comment(channel_id, post_id, comment_id):
94+
q = Qry('feed/{channel_id}/posts/{post_id}/comments/{comment_id}', method=methods.DELETE)
95+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
96+
q.add_urlkw(keys.POST_ID, post_id)
97+
q.add_urlkw(keys.COMMENT_ID, comment_id)
98+
return q
99+
100+
101+
# required scope: channel_feed_edit
102+
@query
103+
def create_comment_reaction(channel_id, post_id, comment_id, emote_id):
104+
q = Qry('feed/{channel_id}/posts/{post_id}/comments/{comment_id}/reactions', method=methods.POST)
105+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
106+
q.add_urlkw(keys.POST_ID, post_id)
107+
q.add_urlkw(keys.COMMENT_ID, comment_id)
108+
q.add_param(keys.EMOTE_ID, emote_id)
109+
return q
110+
111+
112+
# required scope: channel_feed_edit
113+
@query
114+
def delete_comment_reaction(channel_id, post_id, comment_id, emote_id):
115+
q = Qry('feed/{channel_id}/posts/{post_id}/comments/{comment_id}/reactions', method=methods.DELETE)
116+
q.add_urlkw(keys.CHANNEL_ID, channel_id)
117+
q.add_urlkw(keys.POST_ID, post_id)
118+
q.add_urlkw(keys.COMMENT_ID, comment_id)
119+
q.add_param(keys.EMOTE_ID, emote_id)
120+
return q

0 commit comments

Comments
 (0)