Merge pull request #341 from Tkd-Alex/ChannelFollows
Use GQL API to list follows
This commit is contained in:
22
README.md
22
README.md
@@ -183,7 +183,7 @@ from colorama import Fore
|
||||
from TwitchChannelPointsMiner import TwitchChannelPointsMiner
|
||||
from TwitchChannelPointsMiner.logger import LoggerSettings, ColorPalette
|
||||
from TwitchChannelPointsMiner.classes.Telegram import Telegram
|
||||
from TwitchChannelPointsMiner.classes.Settings import Priority, Events
|
||||
from TwitchChannelPointsMiner.classes.Settings import Priority, Events, FollowersOrder
|
||||
from TwitchChannelPointsMiner.classes.entities.Bet import Strategy, BetSettings, Condition, OutcomeKeys, FilterCondition, DelayMode
|
||||
from TwitchChannelPointsMiner.classes.entities.Streamer import Streamer, StreamerSettings
|
||||
|
||||
@@ -194,11 +194,11 @@ twitch_miner = TwitchChannelPointsMiner(
|
||||
priority=[ # Custom priority in this case for example:
|
||||
Priority.STREAK, # - We want first of all to catch all watch streak from all streamers
|
||||
Priority.DROPS, # - When we don't have anymore watch streak to catch, wait until all drops are collected over the streamers
|
||||
Priority.ORDER # - When we have all of the drops claimed and no watch-streak available, use the order priority (POINTS_ASCENDING, POINTS_DESCEDING)
|
||||
Priority.ORDER # - When we have all of the drops claimed and no watch-streak available, use the order priority (POINTS_ASCENDING, POINTS_DESCEDING)
|
||||
],
|
||||
logger_settings=LoggerSettings(
|
||||
save=True, # If you want to save logs in a file (suggested)
|
||||
console_level=logging.INFO, # Level of logs - use logging.DEBUG for more info)
|
||||
console_level=logging.INFO, # Level of logs - use logging.DEBUG for more info
|
||||
file_level=logging.DEBUG, # Level of logs - If you think the log file it's too big, use logging.INFO
|
||||
emoji=True, # On Windows, we have a problem printing emoji. Set to false if you have a problem
|
||||
less=False, # If you think that the logs are too verbose, set this to True
|
||||
@@ -219,12 +219,12 @@ twitch_miner = TwitchChannelPointsMiner(
|
||||
make_predictions=True, # If you want to Bet / Make prediction
|
||||
follow_raid=True, # Follow raid to obtain more points
|
||||
claim_drops=True, # We can't filter rewards base on stream. Set to False for skip viewing counter increase and you will never obtain a drop reward from this script. Issue #21
|
||||
watch_streak=True, # If a streamer go online change the priotiry of streamers array and catch the watch screak. Issue #11
|
||||
watch_streak=True, # If a streamer go online change the priority of streamers array and catch the watch streak. Issue #11
|
||||
join_chat=True, # Join irc chat to increase watch-time
|
||||
bet=BetSettings(
|
||||
strategy=Strategy.SMART, # Choose you strategy!
|
||||
percentage=5, # Place the x% of your channel points
|
||||
percentage_gap=20, # Gap difference between outcomesA and outcomesB (for SMART stragegy)
|
||||
percentage_gap=20, # Gap difference between outcomesA and outcomesB (for SMART strategy)
|
||||
max_points=50000, # If the x percentage of your channel points is gt bet_max_points set this value
|
||||
stealth_mode=True, # If the calculated amount of channel points is GT the highest bet, place the highest value minus 1-2 points Issue #33
|
||||
delay_mode=DelayMode.FROM_END, # When placing a bet, we will wait until `delay` seconds before the end of the timer
|
||||
@@ -261,16 +261,18 @@ twitch_miner.mine(
|
||||
"streamer-username10",
|
||||
"streamer-username11"
|
||||
], # Array of streamers (order = priority)
|
||||
followers=False # Automatic download the list of your followers (unable to set custom settings for you followers list)
|
||||
followers=False, # Automatic download the list of your followers
|
||||
order=FollowersOrder.ASC # Sort the followers list by follow date. ASC or DESC
|
||||
)
|
||||
```
|
||||
You can also use all the default values except for your username obv. Short version:
|
||||
```python
|
||||
from TwitchChannelPointsMiner import TwitchChannelPointsMiner
|
||||
from TwitchChannelPointsMiner.classes.Settings import FollowersOrder
|
||||
twitch_miner = TwitchChannelPointsMiner("your-twitch-username")
|
||||
twitch_miner.mine(["streamer1", "streamer2"]) # Array of streamers OR
|
||||
twitch_miner.mine(followers=True) # Automatic use the followers list OR
|
||||
twitch_miner.mine(["streamer1", "streamer2"], followers=True) # Mixed
|
||||
twitch_miner.mine(["streamer1", "streamer2"]) # Array of streamers OR
|
||||
twitch_miner.mine(followers=True, order=FollowersOrder.ASC) # Automatic use the followers list OR
|
||||
twitch_miner.mine(["streamer1", "streamer2"], followers=True, order=FollowersOrder.DESC) # Mixed
|
||||
```
|
||||
If you follow so many streamers on Twitch, but you don't want to mine points for all of them, you can blacklist the users with the `blacklist` keyword. [#94](https://github.com/Tkd-Alex/Twitch-Channel-Points-Miner-v2/issues/94)
|
||||
```python
|
||||
@@ -355,7 +357,7 @@ About the *Docker* version; the community has always shown great interest in the
|
||||
### Limits
|
||||
> Twitch has a limit - you can't watch more than two channels at one time. We take the first two streamers from the list as they have the highest priority.
|
||||
|
||||
Make sure to write the streamers array in order of priority from left to right. If you use `followers=True` Twitch return the streamers order by followed_at. So your last follow has the highest priority.
|
||||
Make sure to write the streamers array in order of priority from left to right. If you use `followers=True` you can choose to download the followers sorted by follow date (ASC or DESC).
|
||||
|
||||
## Settings
|
||||
Most of the settings are self-explained and are commented on in the example.
|
||||
|
||||
@@ -19,7 +19,7 @@ from TwitchChannelPointsMiner.classes.entities.Streamer import (
|
||||
StreamerSettings,
|
||||
)
|
||||
from TwitchChannelPointsMiner.classes.Exceptions import StreamerDoesNotExistException
|
||||
from TwitchChannelPointsMiner.classes.Settings import Priority, Settings
|
||||
from TwitchChannelPointsMiner.classes.Settings import FollowersOrder, Priority, Settings
|
||||
from TwitchChannelPointsMiner.classes.Twitch import Twitch
|
||||
from TwitchChannelPointsMiner.classes.WebSocketsPool import WebSocketsPool
|
||||
from TwitchChannelPointsMiner.logger import LoggerSettings, configure_loggers
|
||||
@@ -129,10 +129,22 @@ class TwitchChannelPointsMiner:
|
||||
http_server.name = "Analytics Thread"
|
||||
http_server.start()
|
||||
|
||||
def mine(self, streamers: list = [], blacklist: list = [], followers=False):
|
||||
def mine(
|
||||
self,
|
||||
streamers: list = [],
|
||||
blacklist: list = [],
|
||||
followers: bool = False,
|
||||
followers_order: FollowersOrder = FollowersOrder.ASC,
|
||||
):
|
||||
self.run(streamers=streamers, blacklist=blacklist, followers=followers)
|
||||
|
||||
def run(self, streamers: list = [], blacklist: list = [], followers=False):
|
||||
def run(
|
||||
self,
|
||||
streamers: list = [],
|
||||
blacklist: list = [],
|
||||
followers: bool = False,
|
||||
followers_order: FollowersOrder = FollowersOrder.ASC,
|
||||
):
|
||||
if self.running:
|
||||
logger.error("You can't start multiple sessions of this instance!")
|
||||
else:
|
||||
@@ -161,7 +173,7 @@ class TwitchChannelPointsMiner:
|
||||
streamers_dict[username] = streamer
|
||||
|
||||
if followers is True:
|
||||
followers_array = self.twitch.get_followers()
|
||||
followers_array = self.twitch.get_followers(order=followers_order)
|
||||
logger.info(
|
||||
f"Load {len(followers_array)} followers from your profile!",
|
||||
extra={"emoji": ":clipboard:"},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
__version__ = "2.0.5"
|
||||
__version__ = "2.0.6"
|
||||
from .TwitchChannelPointsMiner import TwitchChannelPointsMiner
|
||||
|
||||
__all__ = [
|
||||
|
||||
@@ -10,6 +10,14 @@ class Priority(Enum):
|
||||
POINTS_DESCEDING = auto()
|
||||
|
||||
|
||||
class FollowersOrder(Enum):
|
||||
ASC = auto()
|
||||
DESC = auto()
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
# Empty object shared between class
|
||||
class Settings(object):
|
||||
__slots__ = ["logger", "streamer_settings"]
|
||||
|
||||
@@ -21,7 +21,12 @@ from TwitchChannelPointsMiner.classes.Exceptions import (
|
||||
StreamerDoesNotExistException,
|
||||
StreamerIsOfflineException,
|
||||
)
|
||||
from TwitchChannelPointsMiner.classes.Settings import Events, Priority, Settings
|
||||
from TwitchChannelPointsMiner.classes.Settings import (
|
||||
Events,
|
||||
FollowersOrder,
|
||||
Priority,
|
||||
Settings,
|
||||
)
|
||||
from TwitchChannelPointsMiner.classes.TwitchLogin import TwitchLogin
|
||||
from TwitchChannelPointsMiner.constants import CLIENT_ID, GQLOperations
|
||||
from TwitchChannelPointsMiner.utils import (
|
||||
@@ -155,22 +160,28 @@ class Twitch(object):
|
||||
else:
|
||||
return json_response["data"]["user"]["id"]
|
||||
|
||||
def get_followers(self):
|
||||
json_data = copy.deepcopy(GQLOperations.PersonalSections)
|
||||
json_response = self.post_gql_request(json_data)
|
||||
try:
|
||||
if (
|
||||
"data" in json_response
|
||||
and "personalSections" in json_response["data"]
|
||||
and json_response["data"]["personalSections"] != []
|
||||
):
|
||||
return [
|
||||
fw["user"]["login"]
|
||||
for fw in json_response["data"]["personalSections"][0]["items"]
|
||||
if fw["user"] is not None
|
||||
]
|
||||
except KeyError:
|
||||
return []
|
||||
def get_followers(
|
||||
self, limit: int = 100, order: FollowersOrder = FollowersOrder.ASC
|
||||
):
|
||||
json_data = copy.deepcopy(GQLOperations.ChannelFollows)
|
||||
json_data["variables"] = {"limit": limit, "order": str(order)}
|
||||
has_next = True
|
||||
last_cursor = ""
|
||||
follows = []
|
||||
while has_next is True and last_cursor != "":
|
||||
json_data["variables"]["cursor"] = last_cursor
|
||||
json_response = self.post_gql_request(json_data)
|
||||
try:
|
||||
follows_response = json_response["data"]["user"]["follows"]
|
||||
last_cursor = None
|
||||
for f in follows_response["edges"]:
|
||||
follows.append(f["node"]["login"].lower())
|
||||
last_cursor = f["cursor"]
|
||||
|
||||
has_next = follows_response["pageInfo"]["hasNextPage"]
|
||||
except KeyError:
|
||||
return []
|
||||
return follows
|
||||
|
||||
def update_raid(self, streamer, raid):
|
||||
if streamer.raid != raid:
|
||||
|
||||
@@ -145,21 +145,33 @@ class GQLOperations:
|
||||
}
|
||||
},
|
||||
}
|
||||
PersonalSections = {
|
||||
"operationName": "PersonalSections",
|
||||
"variables": {
|
||||
"input": {
|
||||
"sectionInputs": ["FOLLOWED_SECTION"],
|
||||
"recommendationContext": {"platform": "web"},
|
||||
PersonalSections = (
|
||||
{
|
||||
"operationName": "PersonalSections",
|
||||
"variables": {
|
||||
"input": {
|
||||
"sectionInputs": ["FOLLOWED_SECTION"],
|
||||
"recommendationContext": {"platform": "web"},
|
||||
},
|
||||
"channelLogin": None,
|
||||
"withChannelUser": False,
|
||||
"creatorAnniversariesExperimentEnabled": False,
|
||||
},
|
||||
"extensions": {
|
||||
"persistedQuery": {
|
||||
"version": 1,
|
||||
"sha256Hash": "9fbdfb00156f754c26bde81eb47436dee146655c92682328457037da1a48ed39",
|
||||
}
|
||||
},
|
||||
"channelLogin": None,
|
||||
"withChannelUser": False,
|
||||
"creatorAnniversariesExperimentEnabled": False,
|
||||
},
|
||||
)
|
||||
ChannelFollows = {
|
||||
"operationName": "ChannelFollows",
|
||||
"variables": {"limit": 100, "order": "ASC"},
|
||||
"extensions": {
|
||||
"persistedQuery": {
|
||||
"version": 1,
|
||||
"sha256Hash": "9fbdfb00156f754c26bde81eb47436dee146655c92682328457037da1a48ed39",
|
||||
"sha256Hash": "4b9cb31b54b9213e5760f2f6e9e935ad09924cac2f78aac51f8a64d85f028ed0",
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ from colorama import Fore
|
||||
from TwitchChannelPointsMiner import TwitchChannelPointsMiner
|
||||
from TwitchChannelPointsMiner.logger import LoggerSettings, ColorPalette
|
||||
from TwitchChannelPointsMiner.classes.Telegram import Telegram
|
||||
from TwitchChannelPointsMiner.classes.Settings import Priority, Events
|
||||
from TwitchChannelPointsMiner.classes.Settings import Priority, Events, FollowersOrder
|
||||
from TwitchChannelPointsMiner.classes.entities.Bet import Strategy, BetSettings, Condition, OutcomeKeys, FilterCondition, DelayMode
|
||||
from TwitchChannelPointsMiner.classes.entities.Streamer import Streamer, StreamerSettings
|
||||
|
||||
@@ -83,5 +83,6 @@ twitch_miner.mine(
|
||||
"streamer-username10",
|
||||
"streamer-username11"
|
||||
], # Array of streamers (order = priority)
|
||||
followers=False # Automatic download the list of your followers (unable to set custom settings for you followers list)
|
||||
followers=False, # Automatic download the list of your followers
|
||||
order=FollowersOrder.ASC # Sort the followers list by follow date. ASC or DESC
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user