Merge branch 'hotfix/membership_renderer'

This commit is contained in:
taizan-hokuto
2020-05-05 22:51:16 +09:00
6 changed files with 1996 additions and 61 deletions

View File

@@ -4,10 +4,12 @@ from .renderer.textmessage import LiveChatTextMessageRenderer
from .renderer.paidmessage import LiveChatPaidMessageRenderer
from .renderer.paidsticker import LiveChatPaidStickerRenderer
from .renderer.legacypaid import LiveChatLegacyPaidMessageRenderer
from .renderer.membership import LiveChatMembershipItemRenderer
from .. chat_processor import ChatProcessor
from ... import config
logger = config.logger(__name__)
class CompatibleProcessor(ChatProcessor):
def process(self, chat_components: list):
@@ -24,11 +26,15 @@ class CompatibleProcessor(ChatProcessor):
timeout += chat_component.get('timeout', 0)
chatdata = chat_component.get('chatdata')
if chatdata is None: break
if chatdata is None:
break
for action in chatdata:
if action is None: continue
if action.get('addChatItemAction') is None: continue
if action['addChatItemAction'].get('item') is None: continue
if action is None:
continue
if action.get('addChatItemAction') is None:
continue
if action['addChatItemAction'].get('item') is None:
continue
chat = self.parse(action)
if chat:
@@ -47,7 +53,8 @@ class CompatibleProcessor(ChatProcessor):
action = sitem.get("addChatItemAction")
if action:
item = action.get("item")
if item is None: return None
if item is None:
return None
rd = {}
try:
renderer = self.get_renderer(item)
@@ -75,7 +82,8 @@ class CompatibleProcessor(ChatProcessor):
renderer = LiveChatPaidStickerRenderer(item)
elif item.get("liveChatLegacyPaidMessageRenderer"):
renderer = LiveChatLegacyPaidMessageRenderer(item)
elif item.get("liveChatMembershipItemRenderer"):
renderer = LiveChatMembershipItemRenderer(item)
else:
renderer = None
return renderer

View File

@@ -0,0 +1,40 @@
from .base import BaseRenderer
class LiveChatMembershipItemRenderer(BaseRenderer):
def __init__(self, item):
super().__init__(item, "newSponsorEvent")
def get_snippet(self):
message = self.get_message(self.renderer)
return {
"type": self.chattype,
"liveChatId": "",
"authorChannelId": self.renderer.get("authorExternalChannelId"),
"publishedAt": self.get_publishedat(self.renderer.get("timestampUsec", 0)),
"hasDisplayContent": True,
"displayMessage": message,
}
def get_authordetails(self):
authorExternalChannelId = self.renderer.get("authorExternalChannelId")
# parse subscriber type
isVerified, isChatOwner, _, isChatModerator = (
self.get_badges(self.renderer)
)
return {
"channelId": authorExternalChannelId,
"channelUrl": "http://www.youtube.com/channel/"+authorExternalChannelId,
"displayName": self.renderer["authorName"]["simpleText"],
"profileImageUrl": self.renderer["authorPhoto"]["thumbnails"][1]["url"],
"isVerified": isVerified,
"isChatOwner": isChatOwner,
"isChatSponsor": True,
"isChatModerator": isChatModerator
}
def get_message(self, renderer):
message = (renderer["headerSubtext"]["runs"][0]["text"]
)+' / '+(renderer["authorName"]["simpleText"])
return message

View File

@@ -4,10 +4,13 @@ from .renderer.textmessage import LiveChatTextMessageRenderer
from .renderer.paidmessage import LiveChatPaidMessageRenderer
from .renderer.paidsticker import LiveChatPaidStickerRenderer
from .renderer.legacypaid import LiveChatLegacyPaidMessageRenderer
from .renderer.membership import LiveChatMembershipItemRenderer
from .. chat_processor import ChatProcessor
from ... import config
logger = config.logger(__name__)
class Chatdata:
def __init__(self, chatlist: list, timeout: float):
self.items = chatlist
@@ -25,6 +28,7 @@ class Chatdata:
return
await asyncio.sleep(self.interval/len(self.items))
class DefaultProcessor(ChatProcessor):
def process(self, chat_components: list):
@@ -35,24 +39,27 @@ class DefaultProcessor(ChatProcessor):
for component in chat_components:
timeout += component.get('timeout', 0)
chatdata = component.get('chatdata')
if chatdata is None: continue
if chatdata is None:
continue
for action in chatdata:
if action is None: continue
if action.get('addChatItemAction') is None: continue
if action['addChatItemAction'].get('item') is None: continue
if action is None:
continue
if action.get('addChatItemAction') is None:
continue
if action['addChatItemAction'].get('item') is None:
continue
chat = self._parse(action)
if chat:
chatlist.append(chat)
return Chatdata(chatlist, float(timeout))
def _parse(self, sitem):
action = sitem.get("addChatItemAction")
if action:
item = action.get("item")
if item is None: return None
if item is None:
return None
try:
renderer = self._get_renderer(item)
if renderer == None:
@@ -74,6 +81,8 @@ class DefaultProcessor(ChatProcessor):
renderer = LiveChatPaidStickerRenderer(item)
elif item.get("liveChatLegacyPaidMessageRenderer"):
renderer = LiveChatLegacyPaidMessageRenderer(item)
elif item.get("liveChatMembershipItemRenderer"):
renderer = LiveChatMembershipItemRenderer(item)
else:
renderer = None
return renderer

View File

@@ -0,0 +1,15 @@
from .base import BaseRenderer
class LiveChatMembershipItemRenderer(BaseRenderer):
def __init__(self, item):
super().__init__(item, "newSponsor")
def get_authordetails(self):
super().get_authordetails()
self.author.isChatSponsor = True
def get_message(self, renderer):
message = (renderer["headerSubtext"]["runs"][0]["text"]
)+' / '+(renderer["authorName"]["simpleText"])
return message

View File

@@ -1,6 +1,7 @@
import json
import pytest
import asyncio,aiohttp
import asyncio
import aiohttp
from pytchat.parser.live import Parser
from pytchat.processors.compatible.processor import CompatibleProcessor
from pytchat.exceptions import (
@@ -14,6 +15,7 @@ from pytchat.processors.compatible.renderer.legacypaid import LiveChatLegacyPaid
parser = Parser(is_replay=False)
def test_textmessage(mocker):
'''api互換processorのテスト通常テキストメッセージ'''
processor = CompatibleProcessor()
@@ -51,6 +53,7 @@ def test_textmessage(mocker):
assert "LCC." in ret["items"][0]["id"]
assert ret["items"][0]["snippet"]["type"] == "textMessageEvent"
def test_newsponcer(mocker):
'''api互換processorのテストメンバ新規登録'''
processor = CompatibleProcessor()
@@ -87,6 +90,42 @@ def test_newsponcer(mocker):
assert ret["items"][0]["snippet"]["type"] == "newSponsorEvent"
def test_newsponcer_rev(mocker):
'''api互換processorのテストメンバ新規登録'''
processor = CompatibleProcessor()
_json = _open_file("tests/testdata/compatible/newSponsor_rev.json")
_, chatdata = parser.parse(parser.get_contents(json.loads(_json)))
data = {
"video_id": "",
"timeout": 7,
"chatdata": chatdata
}
ret = processor.process([data])
assert ret["kind"] == "youtube#liveChatMessageListResponse"
assert ret["pollingIntervalMillis"] == data["timeout"]*1000
assert ret.keys() == {
"kind", "etag", "pageInfo", "nextPageToken", "pollingIntervalMillis", "items"
}
assert ret["pageInfo"].keys() == {
"totalResults", "resultsPerPage"
}
assert ret["items"][0].keys() == {
"kind", "etag", "id", "snippet", "authorDetails"
}
assert ret["items"][0]["snippet"].keys() == {
'type', 'liveChatId', 'authorChannelId', 'publishedAt', 'hasDisplayContent', 'displayMessage'
}
assert ret["items"][0]["authorDetails"].keys() == {
'channelId', 'channelUrl', 'displayName', 'profileImageUrl', 'isVerified', 'isChatOwner', 'isChatSponsor', 'isChatModerator'
}
assert "LCC." in ret["items"][0]["id"]
assert ret["items"][0]["snippet"]["type"] == "newSponsorEvent"
def test_superchat(mocker):
'''api互換processorのテストスパチャ'''
processor = CompatibleProcessor()
@@ -124,6 +163,7 @@ def test_superchat(mocker):
assert "LCC." in ret["items"][0]["id"]
assert ret["items"][0]["snippet"]["type"] == "superChatEvent"
def test_unregistered_currency(mocker):
processor = CompatibleProcessor()

File diff suppressed because it is too large Load Diff