Merge branch 'rdavydov:master' into ctrlcbug

This commit is contained in:
Petrarka
2024-06-24 20:02:55 +03:00
committed by GitHub
7 changed files with 106 additions and 14 deletions

View File

@@ -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

View File

@@ -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.

View 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
)

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
__version__ = "1.9.5"
__version__ = "1.9.7"
from .TwitchChannelPointsMiner import TwitchChannelPointsMiner
__all__ = [

View File

@@ -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)

View File

@@ -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": {

View File

@@ -10,3 +10,4 @@ flask
irc
pandas
pytz
validators