twitch-auto-clipper 0.1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. twitch_auto_clipper-0.1.7/.coveragerc +2 -0
  2. twitch_auto_clipper-0.1.7/.github/workflows/test_runner.yml +18 -0
  3. twitch_auto_clipper-0.1.7/.gitignore +9 -0
  4. twitch_auto_clipper-0.1.7/LICENSE +19 -0
  5. twitch_auto_clipper-0.1.7/PKG-INFO +170 -0
  6. twitch_auto_clipper-0.1.7/README.md +152 -0
  7. twitch_auto_clipper-0.1.7/examples/logger.py +61 -0
  8. twitch_auto_clipper-0.1.7/examples/simple.py +19 -0
  9. twitch_auto_clipper-0.1.7/pyproject.toml +33 -0
  10. twitch_auto_clipper-0.1.7/pyrightconfig.json +14 -0
  11. twitch_auto_clipper-0.1.7/scripts/coverage.sh +3 -0
  12. twitch_auto_clipper-0.1.7/scripts/install.sh +1 -0
  13. twitch_auto_clipper-0.1.7/scripts/night_run.sh +3 -0
  14. twitch_auto_clipper-0.1.7/scripts/rebuild.sh +4 -0
  15. twitch_auto_clipper-0.1.7/scripts/run_test.sh +1 -0
  16. twitch_auto_clipper-0.1.7/scripts/run_tests.sh +1 -0
  17. twitch_auto_clipper-0.1.7/tests/__init__.py +0 -0
  18. twitch_auto_clipper-0.1.7/tests/auth/__init__.py +0 -0
  19. twitch_auto_clipper-0.1.7/tests/auth/test_TwitchAuthTokens.py +160 -0
  20. twitch_auto_clipper-0.1.7/tests/chat/__init__.py +0 -0
  21. twitch_auto_clipper-0.1.7/tests/chat/test_Streamer.py +176 -0
  22. twitch_auto_clipper-0.1.7/tests/chat/test_TwitchChatIRC.py +161 -0
  23. twitch_auto_clipper-0.1.7/tests/clip/__init__.py +0 -0
  24. twitch_auto_clipper-0.1.7/tests/clip/test_Clip.py +29 -0
  25. twitch_auto_clipper-0.1.7/tests/helpers.py +45 -0
  26. twitch_auto_clipper-0.1.7/tests/test_TwitchAutoClipper.py +102 -0
  27. twitch_auto_clipper-0.1.7/tests/utils/LockedCounter.py +28 -0
  28. twitch_auto_clipper-0.1.7/tests/utils/__init__.py +0 -0
  29. twitch_auto_clipper-0.1.7/tests/utils/test_ProtectedVar.py +103 -0
  30. twitch_auto_clipper-0.1.7/tests/utils/test_utils.py +16 -0
  31. twitch_auto_clipper-0.1.7/twitch_auto_clipper/TwitchAutoClipper.py +88 -0
  32. twitch_auto_clipper-0.1.7/twitch_auto_clipper/TwitchAutoClipperContext.py +16 -0
  33. twitch_auto_clipper-0.1.7/twitch_auto_clipper/Urls.py +5 -0
  34. twitch_auto_clipper-0.1.7/twitch_auto_clipper/__init__.py +0 -0
  35. twitch_auto_clipper-0.1.7/twitch_auto_clipper/auth/TwitchAuthTokens.py +185 -0
  36. twitch_auto_clipper-0.1.7/twitch_auto_clipper/auth/__init__.py +0 -0
  37. twitch_auto_clipper-0.1.7/twitch_auto_clipper/chat/Message.py +5 -0
  38. twitch_auto_clipper-0.1.7/twitch_auto_clipper/chat/Streamer.py +186 -0
  39. twitch_auto_clipper-0.1.7/twitch_auto_clipper/chat/TwitchChatIRC.py +108 -0
  40. twitch_auto_clipper-0.1.7/twitch_auto_clipper/chat/__init__.py +0 -0
  41. twitch_auto_clipper-0.1.7/twitch_auto_clipper/clip/Clip.py +25 -0
  42. twitch_auto_clipper-0.1.7/twitch_auto_clipper/clip/__init__.py +0 -0
  43. twitch_auto_clipper-0.1.7/twitch_auto_clipper/type_aliases/__init__.py +0 -0
  44. twitch_auto_clipper-0.1.7/twitch_auto_clipper/type_aliases/types.py +6 -0
  45. twitch_auto_clipper-0.1.7/twitch_auto_clipper/utils/ProtectedVar.py +55 -0
  46. twitch_auto_clipper-0.1.7/twitch_auto_clipper/utils/__init__.py +0 -0
  47. twitch_auto_clipper-0.1.7/twitch_auto_clipper/utils/utils.py +14 -0
@@ -0,0 +1,2 @@
1
+ [run]
2
+ omit = tests/*
@@ -0,0 +1,18 @@
1
+ name: Unit Tests
2
+ on: [push]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v7
8
+
9
+ - name: Set up Python
10
+ uses: actions/setup-python@v7
11
+ with:
12
+ python-version: '3.10'
13
+
14
+ - name: Install dependencies
15
+ run: pip install .
16
+
17
+ - name: Run tests
18
+ run: ./scripts/run_tests.sh
@@ -0,0 +1,9 @@
1
+ .env
2
+ .coverage
3
+ htmlcov
4
+ links.txt
5
+ myvenv
6
+ log
7
+ dist
8
+ tests/main.py
9
+ **/__pycache__
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2018 The Python Packaging Authority
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.5
2
+ Name: twitch_auto_clipper
3
+ Version: 0.1.7
4
+ Summary: Automatically create Twitch clips when chat activity spikes
5
+ Project-URL: source, https://github.com/sqrtminustwo/twitch_auto_clipper
6
+ Author-email: Maksym Ziborov <twitch_auto_clipper@blkflag.org>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Requires-Python: >=3.10
12
+ Requires-Dist: dacite>=1.9.2
13
+ Requires-Dist: requests>=2.34.2
14
+ Requires-Dist: sortedcollections>=2.1.0
15
+ Provides-Extra: test
16
+ Requires-Dist: coverage>=7.16.0; extra == 'test'
17
+ Description-Content-Type: text/markdown
18
+
19
+ [![Unit Tests](https://github.com/sqrtminustwo/twitch_auto_clipper/actions/workflows/test_runner.yml/badge.svg?branch=main)](https://github.com/sqrtminustwo/twitch_auto_clipper/actions/workflows/test_runner.yml)
20
+
21
+ # twitch_auto_clipper
22
+
23
+ Automatically create Twitch clips when chat activity spikes.
24
+
25
+ Twitch Auto Clipper monitors Twitch chat and detects moments where a large number of viewers send the same emote/message within a short period of time. When activity exceeds a configurable threshold, it automatically creates a Twitch clip.
26
+
27
+ [demo]
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install twitch_auto_clipper
33
+ ```
34
+
35
+ ## Requirements
36
+
37
+ Minimum Python version supported by `twitch_auto_clipper` is 3.10.
38
+
39
+ ## Quick start
40
+
41
+ ```python
42
+ from twitch_auto_clipper_sqrtminusone.TwitchAutoClipper import TwitchAutoClipper
43
+
44
+ clipper = TwitchAutoClipper(
45
+ ["Marlon", "Lacy"],
46
+ "YOUR_CLIENT_ID",
47
+ "YOUR_CLIENT_SECRET",
48
+ on_clip=lambda clip: print(clip),
49
+ common_value=1,
50
+ emote_value=2,
51
+ clipable_message_ratio=0.5,
52
+ )
53
+
54
+ clipper.start()
55
+ clipper.join()
56
+ ```
57
+
58
+ > [!IMPORTANT]
59
+ > `client_id` and `client_secret` are saved in [TwitchAuthTokens](twitch_auto_clipper_sqrtminusone/auth/TwitchAuthTokens.py) and only sent to the Twitch API.
60
+
61
+ > [!IMPORTANT]
62
+ > Upon initialization of [TwitchAutoClipper](twitch_auto_clipper_sqrtminusone/TwitchAutoClipper.py), your web browser should open to gain clipping permission for your Twitch account (as shown in the demo).
63
+
64
+ ## Features
65
+
66
+ - Automatically handles Twitch OAuth token refresh
67
+ - Automatically monitors multiple Twitch streams
68
+ - Supports custom emotes/messages as clipping triggers
69
+ - Optional 7TV emote support
70
+ - Runs each streamer in separate thread
71
+
72
+ ## How it works
73
+
74
+ ```text
75
+ Twitch chat
76
+ │
77
+ ▼
78
+ Collect messages
79
+ │
80
+ ▼
81
+ Count messages / emotes
82
+ │
83
+ ▼
84
+ Detect activity spike
85
+ │
86
+ ▼
87
+ Threshold exceeded?
88
+ │
89
+ YES
90
+ ▼
91
+ Create Twitch clip
92
+ │
93
+ ▼
94
+ Call on_clip callback
95
+ ```
96
+
97
+ ## Usage
98
+
99
+ There are two classes that you will typically need:
100
+
101
+ - `TwitchAutoClipper` — monitors Twitch chat and automatically creates clips when a message reaches the configured threshold.
102
+ - `Clip` — contains information about a clip that was created.
103
+
104
+ ### `TwitchAutoClipper`
105
+
106
+ ```python
107
+ TwitchAutoClipper(
108
+ streamers_names,
109
+ client_id,
110
+ client_secret,
111
+ on_clip,
112
+ counter_interval_seconds=...,
113
+ clipable_message_ratio=...,
114
+ clipable_wait=...,
115
+ common_value=...,
116
+ emote_value=...,
117
+ excluded_words=...,
118
+ logging_handlers=...,
119
+ logging_level=...
120
+ )
121
+ ```
122
+
123
+ | Argument | Description |
124
+ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
125
+ | `streamers_names` | List of Twitch usernames to monitor. Usernames are case-insensitive and are converted to lowercase. |
126
+ | `client_id` | Your Twitch application client ID. Available from the [Twitch Developer Console](https://dev.twitch.tv/docs/authentication/register-app). |
127
+ | `client_secret` | Your Twitch application client secret. Available from the [Twitch Developer Console](https://dev.twitch.tv/docs/authentication/register-app). |
128
+ | `on_clip` | Callback function invoked with a `Clip` instance when a clip is created. |
129
+ | `counter_interval_seconds` | Time interval over which chat message frequencies are counted. Once the interval ends, the counters are reset. |
130
+ | `clipable_message_ratio` | The weighted frequency of the most frequent message divided by the total number of messages received during the current interval. Because messages can have different values (`common_value` and `emote_value`), the ratio can exceed 1. |
131
+ | `clipable_wait` | Time to wait before creating a clip after a message reaches the clipping threshold. The waiting and clipping are performed in a separate thread, so this does not block the streamer thread. |
132
+ | `common_value` | Value assigned to a regular chat message. A regular message is any message that is not a 7TV emote when the streamer has a 7TV profile. |
133
+ | `emote_value` | Value assigned to a 7TV emote. |
134
+ | `excluded_words` | Words that should be excluded from message frequency counting. |
135
+ | `logging_handlers` | Logging handlers used by the package. See [`examples/logger.py`](examples/logger.py) for an example using multiple handlers. |
136
+ | `logging_level` | Logging level used by the package. See the [Python logging documentation](https://docs.python.org/3/library/logging.html#logging-levels). |
137
+
138
+ > [!NOTE]
139
+ > If multiple streamers are configured, `on_clip` may be called concurrently from multiple threads. Make sure your callback is thread-safe and use the appropriate [Python threading APIs](https://docs.python.org/3/library/threading.html) when necessary.
140
+
141
+ ### `Clip`
142
+
143
+ A `Clip` instance contains information about the clip that was created.
144
+
145
+ | Attribute | Description |
146
+ | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
147
+ | `message` | The chat message that triggered the clip. |
148
+ | `message_count` | Number of occurrences of the triggering message. |
149
+ | `ratio` | Ratio of the triggering message to the total number of messages received during the counting interval. |
150
+ | `broadcaster_id` | Twitch broadcaster ID of the streamer for whom the clip was created. See the [Twitch API documentation](https://dev.twitch.tv/docs/api/reference). |
151
+ | `url` | URL of the created clip. |
152
+ | `timestamp` | Expected timestamp of the event highlighted by the clip. |
153
+ | `duration` | Clip duration in seconds. |
154
+
155
+ ## Motivation
156
+
157
+ Manually watching an entire stream to find moments worth clipping is time-consuming.
158
+
159
+ `twitch_auto_clipper` uses the audience's reaction as a signal: when chat suddenly becomes active around a particular message or emote, the bot can automatically capture the moment.
160
+
161
+ ## Roadmap
162
+
163
+ - [x] Analyze Twitch chat through IRC
164
+ - [x] Twitch OAuth authentication
165
+ - [x] Automatically create clips
166
+ - [x] Monitor multiple live streamers
167
+ - [x] Save clips to a log
168
+ - [x] Add automated tests
169
+ - [ ] Pip package
170
+ - [ ] Web page for constants editing
@@ -0,0 +1,152 @@
1
+ [![Unit Tests](https://github.com/sqrtminustwo/twitch_auto_clipper/actions/workflows/test_runner.yml/badge.svg?branch=main)](https://github.com/sqrtminustwo/twitch_auto_clipper/actions/workflows/test_runner.yml)
2
+
3
+ # twitch_auto_clipper
4
+
5
+ Automatically create Twitch clips when chat activity spikes.
6
+
7
+ Twitch Auto Clipper monitors Twitch chat and detects moments where a large number of viewers send the same emote/message within a short period of time. When activity exceeds a configurable threshold, it automatically creates a Twitch clip.
8
+
9
+ [demo]
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pip install twitch_auto_clipper
15
+ ```
16
+
17
+ ## Requirements
18
+
19
+ Minimum Python version supported by `twitch_auto_clipper` is 3.10.
20
+
21
+ ## Quick start
22
+
23
+ ```python
24
+ from twitch_auto_clipper_sqrtminusone.TwitchAutoClipper import TwitchAutoClipper
25
+
26
+ clipper = TwitchAutoClipper(
27
+ ["Marlon", "Lacy"],
28
+ "YOUR_CLIENT_ID",
29
+ "YOUR_CLIENT_SECRET",
30
+ on_clip=lambda clip: print(clip),
31
+ common_value=1,
32
+ emote_value=2,
33
+ clipable_message_ratio=0.5,
34
+ )
35
+
36
+ clipper.start()
37
+ clipper.join()
38
+ ```
39
+
40
+ > [!IMPORTANT]
41
+ > `client_id` and `client_secret` are saved in [TwitchAuthTokens](twitch_auto_clipper_sqrtminusone/auth/TwitchAuthTokens.py) and only sent to the Twitch API.
42
+
43
+ > [!IMPORTANT]
44
+ > Upon initialization of [TwitchAutoClipper](twitch_auto_clipper_sqrtminusone/TwitchAutoClipper.py), your web browser should open to gain clipping permission for your Twitch account (as shown in the demo).
45
+
46
+ ## Features
47
+
48
+ - Automatically handles Twitch OAuth token refresh
49
+ - Automatically monitors multiple Twitch streams
50
+ - Supports custom emotes/messages as clipping triggers
51
+ - Optional 7TV emote support
52
+ - Runs each streamer in separate thread
53
+
54
+ ## How it works
55
+
56
+ ```text
57
+ Twitch chat
58
+ │
59
+ ▼
60
+ Collect messages
61
+ │
62
+ ▼
63
+ Count messages / emotes
64
+ │
65
+ ▼
66
+ Detect activity spike
67
+ │
68
+ ▼
69
+ Threshold exceeded?
70
+ │
71
+ YES
72
+ ▼
73
+ Create Twitch clip
74
+ │
75
+ ▼
76
+ Call on_clip callback
77
+ ```
78
+
79
+ ## Usage
80
+
81
+ There are two classes that you will typically need:
82
+
83
+ - `TwitchAutoClipper` — monitors Twitch chat and automatically creates clips when a message reaches the configured threshold.
84
+ - `Clip` — contains information about a clip that was created.
85
+
86
+ ### `TwitchAutoClipper`
87
+
88
+ ```python
89
+ TwitchAutoClipper(
90
+ streamers_names,
91
+ client_id,
92
+ client_secret,
93
+ on_clip,
94
+ counter_interval_seconds=...,
95
+ clipable_message_ratio=...,
96
+ clipable_wait=...,
97
+ common_value=...,
98
+ emote_value=...,
99
+ excluded_words=...,
100
+ logging_handlers=...,
101
+ logging_level=...
102
+ )
103
+ ```
104
+
105
+ | Argument | Description |
106
+ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
107
+ | `streamers_names` | List of Twitch usernames to monitor. Usernames are case-insensitive and are converted to lowercase. |
108
+ | `client_id` | Your Twitch application client ID. Available from the [Twitch Developer Console](https://dev.twitch.tv/docs/authentication/register-app). |
109
+ | `client_secret` | Your Twitch application client secret. Available from the [Twitch Developer Console](https://dev.twitch.tv/docs/authentication/register-app). |
110
+ | `on_clip` | Callback function invoked with a `Clip` instance when a clip is created. |
111
+ | `counter_interval_seconds` | Time interval over which chat message frequencies are counted. Once the interval ends, the counters are reset. |
112
+ | `clipable_message_ratio` | The weighted frequency of the most frequent message divided by the total number of messages received during the current interval. Because messages can have different values (`common_value` and `emote_value`), the ratio can exceed 1. |
113
+ | `clipable_wait` | Time to wait before creating a clip after a message reaches the clipping threshold. The waiting and clipping are performed in a separate thread, so this does not block the streamer thread. |
114
+ | `common_value` | Value assigned to a regular chat message. A regular message is any message that is not a 7TV emote when the streamer has a 7TV profile. |
115
+ | `emote_value` | Value assigned to a 7TV emote. |
116
+ | `excluded_words` | Words that should be excluded from message frequency counting. |
117
+ | `logging_handlers` | Logging handlers used by the package. See [`examples/logger.py`](examples/logger.py) for an example using multiple handlers. |
118
+ | `logging_level` | Logging level used by the package. See the [Python logging documentation](https://docs.python.org/3/library/logging.html#logging-levels). |
119
+
120
+ > [!NOTE]
121
+ > If multiple streamers are configured, `on_clip` may be called concurrently from multiple threads. Make sure your callback is thread-safe and use the appropriate [Python threading APIs](https://docs.python.org/3/library/threading.html) when necessary.
122
+
123
+ ### `Clip`
124
+
125
+ A `Clip` instance contains information about the clip that was created.
126
+
127
+ | Attribute | Description |
128
+ | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
129
+ | `message` | The chat message that triggered the clip. |
130
+ | `message_count` | Number of occurrences of the triggering message. |
131
+ | `ratio` | Ratio of the triggering message to the total number of messages received during the counting interval. |
132
+ | `broadcaster_id` | Twitch broadcaster ID of the streamer for whom the clip was created. See the [Twitch API documentation](https://dev.twitch.tv/docs/api/reference). |
133
+ | `url` | URL of the created clip. |
134
+ | `timestamp` | Expected timestamp of the event highlighted by the clip. |
135
+ | `duration` | Clip duration in seconds. |
136
+
137
+ ## Motivation
138
+
139
+ Manually watching an entire stream to find moments worth clipping is time-consuming.
140
+
141
+ `twitch_auto_clipper` uses the audience's reaction as a signal: when chat suddenly becomes active around a particular message or emote, the bot can automatically capture the moment.
142
+
143
+ ## Roadmap
144
+
145
+ - [x] Analyze Twitch chat through IRC
146
+ - [x] Twitch OAuth authentication
147
+ - [x] Automatically create clips
148
+ - [x] Monitor multiple live streamers
149
+ - [x] Save clips to a log
150
+ - [x] Add automated tests
151
+ - [ ] Pip package
152
+ - [ ] Web page for constants editing
@@ -0,0 +1,61 @@
1
+ from twitch_auto_clipper_sqrtminusone.TwitchAutoClipper import TwitchAutoClipper
2
+ from twitch_auto_clipper_sqrtminusone.utils.utils import now_formated
3
+ from twitch_auto_clipper_sqrtminusone.clip.Clip import Clip
4
+
5
+ import csv
6
+ from dataclasses import asdict, fields, is_dataclass
7
+ from pathlib import Path
8
+ from threading import Lock
9
+ from dotenv import load_dotenv
10
+ import os
11
+
12
+
13
+ class Logger:
14
+ def __open_writer(self, csvfile):
15
+ return csv.DictWriter(
16
+ csvfile, fieldnames=self.fieldnames, quoting=csv.QUOTE_NONNUMERIC
17
+ )
18
+
19
+ def __init__(self, type_to_log, dir=Path("log"), filename=f"{now_formated()}.csv"):
20
+ assert is_dataclass(type_to_log)
21
+
22
+ os.makedirs(dir, exist_ok=True)
23
+
24
+ self.type = type_to_log
25
+ self.path = Path(dir, filename)
26
+ self.fieldnames = [field.name for field in fields(type_to_log)]
27
+ self.file_lock = Lock()
28
+
29
+ with open(self.path, "w+") as csvfile:
30
+ writer = self.__open_writer(csvfile)
31
+ writer.writeheader()
32
+
33
+ def write(self, data):
34
+ assert type(data) is self.type
35
+ with self.file_lock:
36
+ with open(self.path, "a") as csvfile:
37
+ writer = self.__open_writer(csvfile)
38
+ writer.writerow(asdict(data))
39
+
40
+
41
+ load_dotenv()
42
+
43
+ CLIP_LOGGER = Logger(Clip)
44
+
45
+
46
+ def on_clip(clip):
47
+ CLIP_LOGGER.write(clip)
48
+
49
+
50
+ clipper = TwitchAutoClipper(
51
+ ["Marlon", "Lacy"],
52
+ os.getenv("client_id"),
53
+ os.getenv("client_secret"),
54
+ on_clip=on_clip,
55
+ common_value=1,
56
+ emote_value=2,
57
+ clipable_message_ratio=0.2,
58
+ )
59
+
60
+ clipper.start()
61
+ clipper.join()
@@ -0,0 +1,19 @@
1
+ from twitch_auto_clipper_sqrtminusone.TwitchAutoClipper import TwitchAutoClipper
2
+
3
+ from dotenv import load_dotenv
4
+ from os import getenv
5
+
6
+ load_dotenv()
7
+
8
+ clipper = TwitchAutoClipper(
9
+ ["Marlon", "Lacy"],
10
+ getenv("client_id"),
11
+ getenv("client_secret"),
12
+ on_clip=lambda clip: print(clip),
13
+ common_value=1,
14
+ emote_value=2,
15
+ clipable_message_ratio=0.2,
16
+ )
17
+
18
+ clipper.start()
19
+ clipper.join()
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.32"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "twitch_auto_clipper"
7
+ version = "0.1.7"
8
+ authors = [
9
+ { name="Maksym Ziborov", email="twitch_auto_clipper@blkflag.org" },
10
+ ]
11
+ description = "Automatically create Twitch clips when chat activity spikes"
12
+ readme = "README.md"
13
+ requires-python = ">=3.10"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3.10",
16
+ "Operating System :: OS Independent",
17
+ ]
18
+ dependencies = [
19
+ "requests>=2.34.2",
20
+ "sortedcollections>=2.1.0",
21
+ "dacite>=1.9.2"
22
+ ]
23
+ license = "MIT"
24
+ license-files = ["LICEN[CS]E*"]
25
+
26
+ [project.urls]
27
+ source = "https://github.com/sqrtminustwo/twitch_auto_clipper"
28
+
29
+
30
+ [project.optional-dependencies]
31
+ test = [
32
+ "coverage>=7.16.0",
33
+ ]
@@ -0,0 +1,14 @@
1
+ // https://www.datacamp.com/tutorial/pyright
2
+ {
3
+ "include": [
4
+ "twitch_auto_clippter",
5
+ ],
6
+ "exclude": [
7
+ "**/__pycache__",
8
+ "**/myvenv"
9
+ ],
10
+ "pythonVersion": "3.12",
11
+ "typeCheckingMode": "off",
12
+ "venvPath": ".",
13
+ "venv": "myvenv"
14
+ }
@@ -0,0 +1,3 @@
1
+ coverage run -m unittest discover tests/
2
+ coverage html
3
+ open htmlcov/index.html
@@ -0,0 +1 @@
1
+ pip install -i https://test.pypi.org/simple/ twitch-auto-clipper-sqrtminusone==0.1.4
@@ -0,0 +1,3 @@
1
+ sudo echo "obtained sudo"
2
+ python3 src/main.py
3
+ sudo shutdown -h now
@@ -0,0 +1,4 @@
1
+ # update version in pyproject.toml first
2
+ rm -rf dist
3
+ python3 -m build
4
+ python3 -m twine upload --repository testpypi dist/*
@@ -0,0 +1 @@
1
+ python -m unittest "$1"
@@ -0,0 +1 @@
1
+ python -m unittest discover tests/
File without changes
File without changes