Merge branch 'rdavydov:master' into ctrlcbug
This commit is contained in:
4
.github/workflows/deploy-docker.yml
vendored
4
.github/workflows/deploy-docker.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v3.3.0
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3.1.0
|
||||
uses: docker/login-action@v3.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- name: Build and push AMD64, ARM64, ARMv7
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v5.3.0
|
||||
uses: docker/build-push-action@v5.4.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
||||
@@ -66,7 +66,10 @@ If you want to offer me a coffee, I would be grateful! ❤️
|
||||
|
||||
| | |
|
||||
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
|
||||
|<a href="https://bitcoin.org" target="_blank"><img src="https://dynamic-assets.coinbase.com/e785e0181f1a23a30d9476038d9be91e9f6c63959b538eabbc51a1abc8898940383291eede695c3b8dfaa1829a9b57f5a2d0a16b0523580346c6b8fab67af14b/asset_icons/b57ac673f06a4b0338a596817eb0a50ce16e2059f327dc117744449a47915cb2.png" alt="Donate BTC" height="16" width="16"></a>|`bc1qq49mvgda2zw4f9kta0a85xztwuxewqwac5eckd` _(<a href="https://bitcoin.org" target="_blank">BTC</a>)_|
|
||||
|<a href="https://dogechain.info" target="_blank"><img src="https://dynamic-assets.coinbase.com/3803f30367bb3972e192cd3fdd2230cd37e6d468eab12575a859229b20f12ff9c994d2c86ccd7bf9bc258e9bd5e46c5254283182f70caf4bd02cc4f8e3890d82/asset_icons/1597d628dd19b7885433a2ac2d7de6ad196c519aeab4bfe679706aacbf1df78a.png" alt="Donate DOGE" height="16" width="16"></a>|`DAKzncwKkpfPCm1xVU7u2pConpXwX7HS3D` _(<a href="https://dogechain.info" target="_blank">DOGE</a>)_|
|
||||
|<a href="https://www.donationalerts.com/r/rdavydov" target="_blank"><img src="https://www.donationalerts.com/static/donations/dist/favicon.ico" alt="Donate via DonationAlerts" height="16" width="16"></a>|https://www.donationalerts.com/r/rdavydov|
|
||||
|<a href="https://boosty.to/rdavydov/donate" target="_blank"><img src="https://static.boosty.to/static/favicon.png?v=11" alt="Donate via Boosty" height="16" width="16"></a>|https://boosty.to/rdavydov/donate|
|
||||
|
||||
If you have any issues or you want to contribute, you are welcome! But please read the [CONTRIBUTING.md](https://github.com/rdavydov/Twitch-Channel-Points-Miner-v2/blob/master/CONTRIBUTING.md) file.
|
||||
|
||||
|
||||
@@ -190,6 +190,7 @@ class TwitchChannelPointsMiner:
|
||||
if Settings.enable_analytics is True:
|
||||
from TwitchChannelPointsMiner.classes.AnalyticsServer import AnalyticsServer
|
||||
|
||||
days_ago = days_ago if days_ago <= 365*15 else 365*15
|
||||
http_server = AnalyticsServer(
|
||||
host=host, port=port, refresh=refresh, days_ago=days_ago, username=self.username
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
__version__ = "1.9.5"
|
||||
__version__ = "1.9.7"
|
||||
from .TwitchChannelPointsMiner import TwitchChannelPointsMiner
|
||||
|
||||
__all__ = [
|
||||
|
||||
@@ -11,14 +11,14 @@ import random
|
||||
import re
|
||||
import string
|
||||
import time
|
||||
# from datetime import datetime
|
||||
# import json
|
||||
import requests
|
||||
import validators
|
||||
from pathlib import Path
|
||||
from secrets import choice, token_hex
|
||||
|
||||
# import json
|
||||
# from urllib.parse import quote
|
||||
# from base64 import urlsafe_b64decode
|
||||
|
||||
import requests
|
||||
# from datetime import datetime
|
||||
|
||||
from TwitchChannelPointsMiner.classes.entities.Campaign import Campaign
|
||||
from TwitchChannelPointsMiner.classes.entities.Drop import Drop
|
||||
@@ -79,7 +79,7 @@ class Twitch(object):
|
||||
self.client_session = token_hex(16)
|
||||
self.client_version = CLIENT_VERSION
|
||||
self.twilight_build_id_pattern = re.compile(
|
||||
r"window\.__twilightBuildID=\"([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-4[0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12})\";"
|
||||
r'window\.__twilightBuildID\s*=\s*"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})"'
|
||||
)
|
||||
|
||||
def login(self):
|
||||
@@ -433,7 +433,8 @@ class Twitch(object):
|
||||
)
|
||||
> 30
|
||||
)
|
||||
and streamers[index].stream.minute_watched < 7 # fix #425
|
||||
# fix #425
|
||||
and streamers[index].stream.minute_watched < 7
|
||||
):
|
||||
streamers_watching.append(index)
|
||||
if len(streamers_watching) == 2:
|
||||
@@ -467,14 +468,87 @@ class Twitch(object):
|
||||
streamers_watching = streamers_watching[:2]
|
||||
|
||||
for index in streamers_watching:
|
||||
next_iteration = time.time() + 60 / len(streamers_watching)
|
||||
# next_iteration = time.time() + 60 / len(streamers_watching)
|
||||
next_iteration = time.time() + 20 / len(streamers_watching)
|
||||
|
||||
try:
|
||||
####################################
|
||||
# Start of fix for 2024/5 API Change
|
||||
# Create the JSON data for the GraphQL request
|
||||
json_data = copy.deepcopy(
|
||||
GQLOperations.PlaybackAccessToken)
|
||||
json_data["variables"] = {
|
||||
"login": streamers[index].username,
|
||||
"isLive": True,
|
||||
"isVod": False,
|
||||
"vodID": "",
|
||||
# "playerType": "site"
|
||||
"playerType": "picture-by-picture"
|
||||
}
|
||||
|
||||
# Get signature and value using the post_gql_request method
|
||||
responsePlaybackAccessToken = self.post_gql_request(
|
||||
json_data)
|
||||
logger.debug(
|
||||
f"Sent PlaybackAccessToken request for {streamers[index]}"
|
||||
)
|
||||
signature = responsePlaybackAccessToken["data"]['streamPlaybackAccessToken']["signature"]
|
||||
value = responsePlaybackAccessToken["data"]['streamPlaybackAccessToken']["value"]
|
||||
if not signature or not value:
|
||||
continue
|
||||
|
||||
# encoded_value = quote(json.dumps(value))
|
||||
|
||||
# Construct the URL for the broadcast qualities
|
||||
RequestBroadcastQualitiesURL = f"https://usher.ttvnw.net/api/channel/hls/{streamers[index].username}.m3u8?sig={signature}&token={value}"
|
||||
|
||||
# Get list of video qualities
|
||||
responseBroadcastQualities = requests.get(RequestBroadcastQualitiesURL, headers={
|
||||
"User-Agent": self.user_agent}, timeout=20) # timeout=60
|
||||
logger.debug(
|
||||
f"Send RequestBroadcastQualitiesURL request for {streamers[index]} - Status code: {responseBroadcastQualities.status_code}"
|
||||
)
|
||||
if responseBroadcastQualities.status_code != 200:
|
||||
continue
|
||||
BroadcastQualities = responseBroadcastQualities.text
|
||||
|
||||
# Just takes the last line, which should be the URL for the lowest quality
|
||||
BroadcastLowestQualityURL = BroadcastQualities.split(
|
||||
"\n")[-1]
|
||||
if not validators.url(BroadcastLowestQualityURL):
|
||||
continue
|
||||
|
||||
# Get list of video URLs
|
||||
responseStreamURLList = requests.get(BroadcastLowestQualityURL, headers={
|
||||
"User-Agent": self.user_agent}, timeout=20) # timeout=60
|
||||
logger.debug(
|
||||
f"Send BroadcastLowestQualityURL request for {streamers[index]} - Status code: {responseStreamURLList.status_code}"
|
||||
)
|
||||
if responseStreamURLList.status_code != 200:
|
||||
continue
|
||||
StreamURLList = responseStreamURLList.text
|
||||
|
||||
# Just takes the last line, which should be the URL for the lowest quality
|
||||
StreamLowestQualityURL = StreamURLList.split("\n")[-2]
|
||||
if not validators.url(StreamLowestQualityURL):
|
||||
continue
|
||||
|
||||
# Perform a HEAD request to simulate watching the stream
|
||||
responseStreamLowestQualityURL = requests.head(StreamLowestQualityURL, headers={
|
||||
"User-Agent": self.user_agent}, timeout=20) # timeout=60
|
||||
logger.debug(
|
||||
f"Send StreamLowestQualityURL request for {streamers[index]} - Status code: {responseStreamLowestQualityURL.status_code}"
|
||||
)
|
||||
if responseStreamLowestQualityURL.status_code != 200:
|
||||
continue
|
||||
# End of fix for 2024/5 API Change
|
||||
##################################
|
||||
response = requests.post(
|
||||
streamers[index].stream.spade_url,
|
||||
data=streamers[index].stream.encode_payload(),
|
||||
headers={"User-Agent": self.user_agent},
|
||||
timeout=60,
|
||||
# timeout=60,
|
||||
timeout=20,
|
||||
)
|
||||
logger.debug(
|
||||
f"Send minute watched request for {streamers[index]} - Status code: {response.status_code}"
|
||||
@@ -543,7 +617,8 @@ class Twitch(object):
|
||||
)
|
||||
|
||||
if streamers_watching == []:
|
||||
self.__chuncked_sleep(60, chunk_size=chunk_size)
|
||||
# self.__chuncked_sleep(60, chunk_size=chunk_size)
|
||||
self.__chuncked_sleep(20, chunk_size=chunk_size)
|
||||
except Exception:
|
||||
logger.error(
|
||||
"Exception raised in send minute watched", exc_info=True)
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
# Twitch endpoints
|
||||
URL = "https://www.twitch.tv"
|
||||
URL = "https://www.twitch.tv" # Browser, Apps
|
||||
# URL = "https://m.twitch.tv" # Mobile Browser
|
||||
# URL = "https://android.tv.twitch.tv" # TV
|
||||
IRC = "irc.chat.twitch.tv"
|
||||
IRC_PORT = 6667
|
||||
WEBSOCKET = "wss://pubsub-edge.twitch.tv/v1"
|
||||
CLIENT_ID = "ue6666qo983tsx6so1t0vnawi233wa" # TV
|
||||
# CLIENT_ID = "kimne78kx3ncx6brgo4mv6wki5h1ko" # Browser
|
||||
# CLIENT_ID = "r8s4dac0uhzifbpu9sjdiwzctle17ff" # Mobile Browser
|
||||
# CLIENT_ID = "kd1unb4b3q4t58fwlpcbzcbnm76a8fp" # Android App
|
||||
# CLIENT_ID = "851cqzxpb9bqu9z6galo155du" # iOS App
|
||||
DROP_ID = "c2542d6d-cd10-4532-919b-3d19f30a768b"
|
||||
@@ -46,6 +49,15 @@ class GQLOperations:
|
||||
}
|
||||
},
|
||||
}
|
||||
PlaybackAccessToken = {
|
||||
"operationName": "PlaybackAccessToken",
|
||||
"extensions": {
|
||||
"persistedQuery": {
|
||||
"version": 1,
|
||||
"sha256Hash": "3093517e37e4f4cb48906155bcd894150aef92617939236d2508f3375ab732ce",
|
||||
}
|
||||
},
|
||||
}
|
||||
VideoPlayerStreamInfoOverlayChannel = {
|
||||
"operationName": "VideoPlayerStreamInfoOverlayChannel",
|
||||
"extensions": {
|
||||
|
||||
@@ -10,3 +10,4 @@ flask
|
||||
irc
|
||||
pandas
|
||||
pytz
|
||||
validators
|
||||
|
||||
Reference in New Issue
Block a user