11from __future__ import annotations
22
3- from enum import Enum
4- from typing import TYPE_CHECKING , Literal
3+ from dataclasses import dataclass
4+ from enum import Enum , StrEnum
5+ from typing import TYPE_CHECKING , Literal , TypedDict
56
67from ..utils .types import (
78 CheckAnyPayload ,
89 TranslatePayload ,
9- TranslateSupportedPayload
10+ TranslateSupportedPayload ,
11+ TotalSiteStatusPayload ,
12+ MonthlySiteTrafficPayload ,
13+ MonthlyActivityGraphPayload ,
14+ MonthlyActivityPayload
1015)
1116from ..utils .common import (
1217 UNKNOWN ,
1318 MAYBE_UNKNOWN ,
19+ dt_from_timestamp
1420)
1521
1622if TYPE_CHECKING :
@@ -144,4 +150,171 @@ async def tts(client:"HTTPClient",language:str,type:Literal["male","female"],tex
144150 "text" :text
145151 }
146152 )
147- return response .data
153+ return response .data
154+
155+ @dataclass
156+ class TotalSiteStats :
157+ project_count :int
158+ user_count :int
159+ studio_comment_count :int
160+ profile_comment_count :int
161+ studio_count :int
162+ comment_count :int
163+ project_comment_count :int
164+ _timestamp :float
165+
166+ async def get_total_site_stats (client :HTTPClient ) -> TotalSiteStats :
167+ """
168+ 全体の統計情報を取得する
169+
170+ Args:
171+ client (HTTPClient): 通信に使用するHTTPClient
172+
173+ Returns:
174+ TotalSiteStats:
175+ """
176+ response = await client .get ("https://scratch.mit.edu/statistics/data/daily/" )
177+ data :TotalSiteStatusPayload = response .json ()
178+ return TotalSiteStats (
179+ project_count = data .get ("PROJECT_COUNT" ),
180+ user_count = data .get ("USER_COUNT" ),
181+ studio_comment_count = data .get ("STUDIO_COMMENT_COUNT" ),
182+ profile_comment_count = data .get ("PROFILE_COMMENT_COUNT" ),
183+ studio_count = data .get ("STUDIO_COUNT" ),
184+ comment_count = data .get ("COMMENT_COUNT" ),
185+ project_comment_count = data .get ("PROJECT_COMMENT_COUNT" ),
186+ _timestamp = data .get ("_TS" )
187+ )
188+
189+ @dataclass
190+ class MonthlySiteTraffic :
191+ pageviews :int
192+ users :int
193+ sessions :int
194+ _timestamp :float
195+
196+ async def get_monthly_site_traffic (client :HTTPClient ) -> MonthlySiteTraffic :
197+ """
198+ 月のアクティビティ数を取得する。
199+
200+ Args:
201+ client (HTTPClient): 通信に使用するHTTPClient
202+
203+ Returns:
204+ MonthlySiteTraffic:
205+ """
206+ response = await client .get ("https://scratch.mit.edu/statistics/data/monthly-ga/" )
207+ data :MonthlySiteTrafficPayload = response .json ()
208+ return MonthlySiteTraffic (
209+ pageviews = data .get ("pageviews" ),
210+ users = data .get ("users" ),
211+ sessions = data .get ("sessions" ),
212+ _timestamp = data .get ("_TS" )
213+ )
214+
215+
216+
217+ GraphData = list [tuple [int , int ]]
218+
219+ @dataclass
220+ class CommentData :
221+ """コメント統計データ"""
222+ project : GraphData
223+ studio : GraphData
224+ profile : GraphData
225+
226+ @dataclass
227+ class ActivityData :
228+ """アクティビティ統計データ"""
229+ new_projects : GraphData
230+ new_users : GraphData
231+ new_comments : GraphData
232+
233+ @dataclass
234+ class ActiveUserData :
235+ """アクティブユーザー統計データ"""
236+ project_creators : GraphData
237+ comment_creators : GraphData
238+
239+ @dataclass
240+ class ProjectData :
241+ """プロジェクト統計データ"""
242+ new_projects : GraphData
243+ remix_projects : GraphData
244+
245+ @dataclass
246+ class AgeDistributionData :
247+ """年齢分布データ"""
248+ registration_age : GraphData
249+
250+ @dataclass
251+ class MonthlyActivity :
252+ """
253+ 月間アクティビティ統計情報を表す
254+ """
255+ _timestamp : float
256+ comment_data : CommentData
257+ activity_data : ActivityData
258+ active_user_data : ActiveUserData
259+ project_data : ProjectData
260+ age_distribution_data : AgeDistributionData
261+ country_distribution : dict [str ,int ]
262+
263+ def _parse_graph_data (raw_data : list [MonthlyActivityGraphPayload ], index : int ) -> GraphData :
264+ if index < len (raw_data ) and "values" in raw_data [index ]:
265+ return [(d ["x" ], d ["y" ]) for d in raw_data [index ]["values" ]]
266+ return []
267+
268+ async def get_monthly_activity (client : HTTPClient ) -> MonthlyActivity :
269+ """
270+ 月間アクティビティ統計情報を取得する。
271+
272+ Args:
273+ client (HTTPClient): 通信に使用するHTTPClient
274+
275+ Returns:
276+ MonthlyActivity:
277+ """
278+ response = await client .get ("https://scratch.mit.edu/statistics/data/monthly/" )
279+ data :MonthlyActivityPayload = response .json ()
280+
281+ raw_comment_data = data .get ("comment_data" , [])
282+ comment_data = CommentData (
283+ project = _parse_graph_data (raw_comment_data , 0 ),
284+ studio = _parse_graph_data (raw_comment_data , 1 ),
285+ profile = _parse_graph_data (raw_comment_data , 2 ),
286+ )
287+
288+ raw_activity_data = data .get ("activity_data" , [])
289+ activity_data = ActivityData (
290+ new_projects = _parse_graph_data (raw_activity_data , 0 ),
291+ new_users = _parse_graph_data (raw_activity_data , 1 ),
292+ new_comments = _parse_graph_data (raw_activity_data , 2 ),
293+ )
294+
295+ raw_active_user_data = data .get ("active_user_data" , [])
296+ active_user_data = ActiveUserData (
297+ project_creators = _parse_graph_data (raw_active_user_data , 0 ),
298+ comment_creators = _parse_graph_data (raw_active_user_data , 1 ),
299+ )
300+
301+ raw_project_data = data .get ("project_data" , [])
302+ project_data = ProjectData (
303+ new_projects = _parse_graph_data (raw_project_data , 0 ),
304+ remix_projects = _parse_graph_data (raw_project_data , 1 ),
305+ )
306+
307+ raw_age_distribution_data = data .get ("age_distribution_data" , [])
308+ age_distribution_data = AgeDistributionData (
309+ registration_age = _parse_graph_data (raw_age_distribution_data , 0 )
310+ )
311+
312+ return MonthlyActivity (
313+ _timestamp = data .get ("_TS" , 0.0 ),
314+ comment_data = comment_data ,
315+ activity_data = activity_data ,
316+ active_user_data = active_user_data ,
317+ project_data = project_data ,
318+ country_distribution = data .get ("country_distribution" , {}),
319+ age_distribution_data = age_distribution_data ,
320+ )
0 commit comments