piwave 2.0.9__py3-none-any.whl → 2.1.1__py3-none-any.whl
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.
- piwave/__init__.py +3 -1
- piwave/__main__.py +105 -0
- piwave/backends/__init__.py +126 -0
- piwave/backends/base.py +245 -0
- piwave/backends/fm_transmitter.py +44 -0
- piwave/backends/pi_fm_rds.py +49 -0
- piwave/logger.py +99 -0
- piwave/piwave.py +283 -177
- piwave-2.1.1.dist-info/METADATA +750 -0
- piwave-2.1.1.dist-info/RECORD +13 -0
- piwave-2.0.9.dist-info/METADATA +0 -419
- piwave-2.0.9.dist-info/RECORD +0 -7
- {piwave-2.0.9.dist-info → piwave-2.1.1.dist-info}/WHEEL +0 -0
- {piwave-2.0.9.dist-info → piwave-2.1.1.dist-info}/licenses/LICENSE +0 -0
- {piwave-2.0.9.dist-info → piwave-2.1.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
piwave/__init__.py,sha256=jz2r-qclltKTxJjlGnqhAwIlUgjvRTR31f4hjTHP5NA,230
|
|
2
|
+
piwave/__main__.py,sha256=ygl6F8VmOZjsnnUbAbzLoA7_1qv18ruG6TW4EocSaQE,3927
|
|
3
|
+
piwave/logger.py,sha256=lPG3cz3ByqC1p1UKpwlv3R9KgiAb0zzyu6c3bhTpST0,2766
|
|
4
|
+
piwave/piwave.py,sha256=p9rsvwx5BdV7bHIW30vj1ipWOrSJOOMjczvs_DtghYA,31335
|
|
5
|
+
piwave/backends/__init__.py,sha256=DUbdyYf2V2XcDB05vmFWEkuJ292YTNiNJjzh1raJ5Cg,3756
|
|
6
|
+
piwave/backends/base.py,sha256=amjdR3pwx-0XN2ngpwfYNt74j5kWrW1cI0zMOTMU-q8,7668
|
|
7
|
+
piwave/backends/fm_transmitter.py,sha256=6CuYpkCgb40PEpemMlbTkQ6Gq8qFe3C1TSSLLnwXXX4,1338
|
|
8
|
+
piwave/backends/pi_fm_rds.py,sha256=l1y9JUKjw-d9lh9X7HLQNEwbNVO-whYlzaYnqEfRviI,1429
|
|
9
|
+
piwave-2.1.1.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
10
|
+
piwave-2.1.1.dist-info/METADATA,sha256=4nXRHn0KaoiUzo7KegQyG5tEMDx9ZDn4WWBlpzxYa2c,20563
|
|
11
|
+
piwave-2.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
+
piwave-2.1.1.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
|
|
13
|
+
piwave-2.1.1.dist-info/RECORD,,
|
piwave-2.0.9.dist-info/METADATA
DELETED
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: piwave
|
|
3
|
-
Version: 2.0.9
|
|
4
|
-
Summary: A python module to broadcast radio waves with your Raspberry Pi.
|
|
5
|
-
Home-page: https://github.com/douxxtech/piwave
|
|
6
|
-
Author: Douxx
|
|
7
|
-
Author-email: douxx@douxx.tech
|
|
8
|
-
License: GPL-3.0-or-later
|
|
9
|
-
Project-URL: Bug Reports, https://github.com/douxxtech/piwave/issues
|
|
10
|
-
Project-URL: Source, https://github.com/douxxtech/piwave
|
|
11
|
-
Keywords: raspberry pi,radio,fm,rds,streaming,audio,broadcast
|
|
12
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
-
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
-
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
17
|
-
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
-
Requires-Python: >=3.7
|
|
19
|
-
Description-Content-Type: text/markdown
|
|
20
|
-
License-File: LICENSE
|
|
21
|
-
Provides-Extra: dev
|
|
22
|
-
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
23
|
-
Requires-Dist: pytest-cov>=2.0; extra == "dev"
|
|
24
|
-
Requires-Dist: black>=22.0; extra == "dev"
|
|
25
|
-
Requires-Dist: flake8>=4.0; extra == "dev"
|
|
26
|
-
Dynamic: license-file
|
|
27
|
-
|
|
28
|
-
<div align=center>
|
|
29
|
-
<img alt="PiWave image" src="https://piwave.xyz/static/img/logo.png"/>
|
|
30
|
-
<h1>PiWave</h1>
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
**PiWave** is a Python module designed to manage and control your Raspberry Pi radio using the `pi_fm_rds` utility. It allows you to easily convert audio files to WAV format and broadcast them at a specified frequency with RDS (Radio Data System) support.
|
|
34
|
-
|
|
35
|
-
## Features
|
|
36
|
-
|
|
37
|
-
- Supports most audio file formats (MP3, FLAC, M4A, etc.)
|
|
38
|
-
- Configurable broadcast frequency, PS (Program Service), RT (Radio Text), and PI (Program Identifier)
|
|
39
|
-
- Real-time settings updates without restart
|
|
40
|
-
- Detailed logging with debug mode
|
|
41
|
-
- Error handling and event callbacks
|
|
42
|
-
- Non-blocking playback with threading
|
|
43
|
-
- Simple streaming-focused design
|
|
44
|
-
|
|
45
|
-
## Hardware Installation
|
|
46
|
-
|
|
47
|
-
To use PiWave for broadcasting, you need to set up the hardware correctly. This involves connecting an antenna or cable to the Raspberry Pi's GPIO pin.
|
|
48
|
-
|
|
49
|
-
1. **Connect the Cable or Antenna**:
|
|
50
|
-
- Attach a cable or an antenna to GPIO 4 (Pin 7) on the Raspberry Pi.
|
|
51
|
-
- Ensure the connection is secure to avoid any broadcasting issues.
|
|
52
|
-
|
|
53
|
-
2. **GPIO Pinout**:
|
|
54
|
-
- GPIO 4 (Pin 7) is used for the broadcasting signal.
|
|
55
|
-
- Ensure that the cable or antenna is properly connected to this pin for optimal performance.
|
|
56
|
-
|
|
57
|
-
## Installation
|
|
58
|
-
|
|
59
|
-
> [!WARNING]
|
|
60
|
-
> **Warning**: Using PiWave involves broadcasting signals which may be subject to local regulations and laws. It is your responsibility to ensure that your use of PiWave complies with all applicable legal requirements and regulations in your area. Unauthorized use of broadcasting equipment may result in legal consequences, including fines or penalties.
|
|
61
|
-
>
|
|
62
|
-
> **Liability**: The author of PiWave is not responsible for any damage, loss, or legal issues that may arise from the use of this software. By using PiWave, you agree to accept all risks and liabilities associated with its operation and broadcasting capabilities.
|
|
63
|
-
>
|
|
64
|
-
> Please exercise caution and ensure you have the proper permissions and knowledge of the regulations before using PiWave for broadcasting purposes.
|
|
65
|
-
|
|
66
|
-
### Auto Installer
|
|
67
|
-
|
|
68
|
-
For a quick and easy installation, you can use the auto installer script. Open a terminal and run:
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
curl -sL https://setup.piwave.xyz/ | sudo bash
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
This command will download and execute the installation script, setting up PiWave and its dependencies automatically.
|
|
75
|
-
|
|
76
|
-
> [!NOTE]
|
|
77
|
-
> To uninstall, use the following command:
|
|
78
|
-
> ```bash
|
|
79
|
-
> curl -sL https://setup.piwave.xyz/uninstall | sudo bash
|
|
80
|
-
> ```
|
|
81
|
-
|
|
82
|
-
### Manual Installation
|
|
83
|
-
|
|
84
|
-
To install PiWave manually, follow these steps:
|
|
85
|
-
|
|
86
|
-
1. **Clone the repository and install**:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
pip install git+https://github.com/douxxtech/piwave.git
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
2. **Dependencies**:
|
|
93
|
-
|
|
94
|
-
PiWave requires the `ffmpeg` and `ffprobe` utilities for file conversion and duration extraction. Install them using:
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
sudo apt-get install ffmpeg
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
3. **PiFmRds**:
|
|
101
|
-
|
|
102
|
-
PiWave uses [PiFmRds](https://github.com/ChristopheJacquet/PiFmRds) to work. Make sure you have installed it before running PiWave.
|
|
103
|
-
|
|
104
|
-
## Quick Start
|
|
105
|
-
|
|
106
|
-
### Basic Usage
|
|
107
|
-
|
|
108
|
-
```python
|
|
109
|
-
from piwave import PiWave
|
|
110
|
-
|
|
111
|
-
# Create PiWave instance
|
|
112
|
-
pw = PiWave(
|
|
113
|
-
frequency=90.0,
|
|
114
|
-
ps="MyRadio",
|
|
115
|
-
rt="Playing great music",
|
|
116
|
-
pi="ABCD",
|
|
117
|
-
debug=True
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
# Play a single audio file
|
|
121
|
-
pw.play("song.mp3")
|
|
122
|
-
|
|
123
|
-
# Stop playback
|
|
124
|
-
pw.stop()
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Real-time Settings Updates
|
|
128
|
-
|
|
129
|
-
```python
|
|
130
|
-
from piwave import PiWave
|
|
131
|
-
|
|
132
|
-
pw = PiWave()
|
|
133
|
-
|
|
134
|
-
# Update multiple settings at once
|
|
135
|
-
pw.update(
|
|
136
|
-
frequency=101.5,
|
|
137
|
-
ps="NewName",
|
|
138
|
-
rt="Updated radio text",
|
|
139
|
-
debug=True
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
# Update individual settings
|
|
143
|
-
pw.update(frequency=102.1)
|
|
144
|
-
pw.update(ps="Radio2024")
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Control Playback
|
|
148
|
-
|
|
149
|
-
```python
|
|
150
|
-
from piwave import PiWave
|
|
151
|
-
|
|
152
|
-
pw = PiWave(frequency=95.0)
|
|
153
|
-
|
|
154
|
-
# Play, pause, resume
|
|
155
|
-
pw.play("music.mp3")
|
|
156
|
-
pw.pause()
|
|
157
|
-
pw.resume()
|
|
158
|
-
|
|
159
|
-
# Check status
|
|
160
|
-
status = pw.get_status()
|
|
161
|
-
print(f"Playing: {status['is_playing']}")
|
|
162
|
-
print(f"Current file: {status['current_file']}")
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## Examples
|
|
166
|
-
|
|
167
|
-
### Text-to-Speech Radio
|
|
168
|
-
|
|
169
|
-
```python
|
|
170
|
-
from gtts import gTTS
|
|
171
|
-
from piwave import PiWave
|
|
172
|
-
from pydub import AudioSegment
|
|
173
|
-
import os
|
|
174
|
-
import sys
|
|
175
|
-
import time
|
|
176
|
-
|
|
177
|
-
wav_file = sys.argv[1] if len(sys.argv) > 1 else 'tts.wav'
|
|
178
|
-
|
|
179
|
-
def tts(text, wav_file):
|
|
180
|
-
mp3_file = "tts.mp3"
|
|
181
|
-
tts = gTTS(text=text, lang="en", slow=False)
|
|
182
|
-
tts.save(mp3_file)
|
|
183
|
-
sound = AudioSegment.from_mp3(mp3_file)
|
|
184
|
-
sound.export(wav_file, format="wav")
|
|
185
|
-
os.remove(mp3_file)
|
|
186
|
-
|
|
187
|
-
def main():
|
|
188
|
-
pw = None
|
|
189
|
-
|
|
190
|
-
print("=" * 50)
|
|
191
|
-
print("Text Broadcast by https://douxx.tech")
|
|
192
|
-
print("""You need PiWave and a raspberry pi with root
|
|
193
|
-
access to run this tool !""")
|
|
194
|
-
|
|
195
|
-
try:
|
|
196
|
-
while True:
|
|
197
|
-
print("=" * 50)
|
|
198
|
-
text = input("Text to broadcast: ").strip()
|
|
199
|
-
if not text:
|
|
200
|
-
print("No text entered, skipping...\n")
|
|
201
|
-
continue
|
|
202
|
-
|
|
203
|
-
try:
|
|
204
|
-
freq = float(input("Frequency to broadcast (MHz): "))
|
|
205
|
-
except ValueError:
|
|
206
|
-
print("Invalid frequency, please enter a number.\n")
|
|
207
|
-
continue
|
|
208
|
-
|
|
209
|
-
tts(text, wav_file)
|
|
210
|
-
pw = PiWave(silent=True, frequency=freq)
|
|
211
|
-
|
|
212
|
-
print("=" * 50)
|
|
213
|
-
print("Ready to play!")
|
|
214
|
-
print(f"Frequency : {freq} MHz")
|
|
215
|
-
print(f"Text : {text}")
|
|
216
|
-
print(f"WAV file : {os.path.abspath(wav_file)}")
|
|
217
|
-
print("=" * 50)
|
|
218
|
-
|
|
219
|
-
pw.play(wav_file)
|
|
220
|
-
print("Playing! Press Ctrl+C to stop or wait for completion...\n")
|
|
221
|
-
|
|
222
|
-
# Wait for playback to complete
|
|
223
|
-
while pw.get_status()['is_playing']:
|
|
224
|
-
time.sleep(0.5)
|
|
225
|
-
|
|
226
|
-
print("Playback completed!\n")
|
|
227
|
-
|
|
228
|
-
except KeyboardInterrupt:
|
|
229
|
-
print("\nStopped by user.")
|
|
230
|
-
finally:
|
|
231
|
-
# Cleanup PiWave
|
|
232
|
-
if pw:
|
|
233
|
-
pw.stop()
|
|
234
|
-
pw.cleanup()
|
|
235
|
-
|
|
236
|
-
# Remove temp file
|
|
237
|
-
if os.path.exists(wav_file):
|
|
238
|
-
os.remove(wav_file)
|
|
239
|
-
|
|
240
|
-
print("Cleanup done. Exiting...")
|
|
241
|
-
|
|
242
|
-
if __name__ == "__main__":
|
|
243
|
-
main()
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### Music Player with Callbacks
|
|
247
|
-
|
|
248
|
-
```python
|
|
249
|
-
from piwave import PiWave
|
|
250
|
-
import os
|
|
251
|
-
import time
|
|
252
|
-
|
|
253
|
-
def on_track_change(filename):
|
|
254
|
-
print(f"🎵 Now playing: {os.path.basename(filename)}")
|
|
255
|
-
|
|
256
|
-
def on_error(error):
|
|
257
|
-
print(f"❌ Error occurred: {error}")
|
|
258
|
-
|
|
259
|
-
def main():
|
|
260
|
-
# Create player with callbacks
|
|
261
|
-
pw = PiWave(
|
|
262
|
-
frequency=101.5,
|
|
263
|
-
ps="MyMusic",
|
|
264
|
-
rt="Your favorite tunes",
|
|
265
|
-
on_track_change=on_track_change,
|
|
266
|
-
on_error=on_error
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
try:
|
|
270
|
-
# Play different formats
|
|
271
|
-
audio_files = ["song1.mp3", "song2.flac", "song3.m4a"]
|
|
272
|
-
|
|
273
|
-
for audio_file in audio_files:
|
|
274
|
-
if os.path.exists(audio_file):
|
|
275
|
-
print(f"Playing {audio_file}...")
|
|
276
|
-
pw.play(audio_file)
|
|
277
|
-
|
|
278
|
-
# Wait for playback to complete
|
|
279
|
-
while pw.get_status()['is_playing']:
|
|
280
|
-
time.sleep(0.5)
|
|
281
|
-
|
|
282
|
-
print("Track completed. Press Enter for next song or Ctrl+C to quit...")
|
|
283
|
-
input()
|
|
284
|
-
else:
|
|
285
|
-
print(f"File {audio_file} not found, skipping...")
|
|
286
|
-
|
|
287
|
-
print("All tracks completed!")
|
|
288
|
-
|
|
289
|
-
except KeyboardInterrupt:
|
|
290
|
-
print("\nPlayback interrupted by user.")
|
|
291
|
-
finally:
|
|
292
|
-
# Cleanup
|
|
293
|
-
pw.stop()
|
|
294
|
-
pw.cleanup()
|
|
295
|
-
print("Cleanup completed.")
|
|
296
|
-
|
|
297
|
-
if __name__ == "__main__":
|
|
298
|
-
main()
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### Simple FM Transmitter
|
|
302
|
-
|
|
303
|
-
```python
|
|
304
|
-
from piwave import PiWave
|
|
305
|
-
import os
|
|
306
|
-
import time
|
|
307
|
-
|
|
308
|
-
def simple_broadcast():
|
|
309
|
-
pw = None
|
|
310
|
-
|
|
311
|
-
try:
|
|
312
|
-
# Initialize with custom settings
|
|
313
|
-
pw = PiWave(
|
|
314
|
-
frequency=88.5,
|
|
315
|
-
ps="Pi-FM",
|
|
316
|
-
rt="Broadcasting from Raspberry Pi",
|
|
317
|
-
pi="RAPI"
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
audio_file = input("Enter audio file path: ")
|
|
321
|
-
|
|
322
|
-
if not os.path.exists(audio_file):
|
|
323
|
-
print("File not found!")
|
|
324
|
-
return
|
|
325
|
-
|
|
326
|
-
print(f"Broadcasting {audio_file} on 88.5 MHz")
|
|
327
|
-
print("Press Ctrl+C to stop...")
|
|
328
|
-
|
|
329
|
-
pw.play(audio_file)
|
|
330
|
-
|
|
331
|
-
# Keep program running and show status
|
|
332
|
-
while pw.get_status()['is_playing']:
|
|
333
|
-
time.sleep(1)
|
|
334
|
-
|
|
335
|
-
print("\nPlayback completed!")
|
|
336
|
-
|
|
337
|
-
except KeyboardInterrupt:
|
|
338
|
-
print("\nStopping broadcast...")
|
|
339
|
-
except Exception as e:
|
|
340
|
-
print(f"Error: {e}")
|
|
341
|
-
finally:
|
|
342
|
-
if pw:
|
|
343
|
-
pw.stop()
|
|
344
|
-
pw.cleanup()
|
|
345
|
-
print("Broadcast stopped and cleaned up.")
|
|
346
|
-
|
|
347
|
-
if __name__ == "__main__":
|
|
348
|
-
simple_broadcast()
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
## API Reference
|
|
352
|
-
|
|
353
|
-
### PiWave Class
|
|
354
|
-
|
|
355
|
-
#### Initialization
|
|
356
|
-
|
|
357
|
-
```python
|
|
358
|
-
PiWave(
|
|
359
|
-
frequency=90.0, # Broadcast frequency (80.0-108.0 MHz)
|
|
360
|
-
ps="PiWave", # Program Service name (max 8 chars)
|
|
361
|
-
rt="PiWave: ...", # Radio Text (max 64 chars)
|
|
362
|
-
pi="FFFF", # Program Identifier (4 hex digits)
|
|
363
|
-
debug=False, # Enable debug logging
|
|
364
|
-
silent=False, # Disable all logging
|
|
365
|
-
on_track_change=None, # Callback for track changes
|
|
366
|
-
on_error=None # Callback for errors
|
|
367
|
-
)
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
#### Methods
|
|
371
|
-
|
|
372
|
-
- **`play(file_path)`** - Play an audio file
|
|
373
|
-
- **`stop()`** - Stop playback
|
|
374
|
-
- **`pause()`** - Pause current playback
|
|
375
|
-
- **`resume()`** - Resume playback
|
|
376
|
-
- **`update(**kwargs)`** - Update any settings in real-time
|
|
377
|
-
- **`set_frequency(freq)`** - Change broadcast frequency
|
|
378
|
-
- **`get_status()`** - Get current player status
|
|
379
|
-
- **`cleanup()`** - Clean up resources
|
|
380
|
-
|
|
381
|
-
#### Properties
|
|
382
|
-
|
|
383
|
-
Access current settings through `get_status()`:
|
|
384
|
-
- `is_playing` - Whether audio is currently playing
|
|
385
|
-
- `frequency` - Current broadcast frequency
|
|
386
|
-
- `current_file` - Currently loaded file
|
|
387
|
-
- `ps` - Program Service name
|
|
388
|
-
- `rt` - Radio Text
|
|
389
|
-
- `pi` - Program Identifier
|
|
390
|
-
|
|
391
|
-
## Error Handling
|
|
392
|
-
|
|
393
|
-
- **Raspberry Pi Check**: Verifies the program is running on a Raspberry Pi
|
|
394
|
-
- **Root User Check**: Requires root privileges for GPIO access
|
|
395
|
-
- **Executable Check**: Automatically finds `pi_fm_rds` or prompts for path
|
|
396
|
-
- **File Validation**: Checks file existence and conversion capability
|
|
397
|
-
- **Process Management**: Handles cleanup of broadcasting processes
|
|
398
|
-
|
|
399
|
-
## Requirements
|
|
400
|
-
|
|
401
|
-
- Raspberry Pi (any model with GPIO)
|
|
402
|
-
- Root access (`sudo`)
|
|
403
|
-
- Python 3.6+
|
|
404
|
-
- FFmpeg for audio conversion
|
|
405
|
-
- PiFmRds for FM transmission
|
|
406
|
-
|
|
407
|
-
## License
|
|
408
|
-
|
|
409
|
-
PiWave is licensed under the GNU General Public License (GPL) v3.0. See the [LICENSE](LICENSE) file for more details.
|
|
410
|
-
|
|
411
|
-
## Contributing
|
|
412
|
-
|
|
413
|
-
Contributions are welcome! Please submit a pull request or open an issue on [GitHub](https://github.com/douxxtech/piwave/issues) for any bugs or feature requests.
|
|
414
|
-
|
|
415
|
-
---
|
|
416
|
-
|
|
417
|
-
Thank you for using PiWave!
|
|
418
|
-
|
|
419
|
-

|
piwave-2.0.9.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
piwave/__init__.py,sha256=tAmruZvneieh6fgkf7chKzOX9Q6fEB-5Jt9FJ7Fl5xQ,74
|
|
2
|
-
piwave/piwave.py,sha256=OSSQWrsm37eiyq4GBFkddZnY4qxTfqOmhm05ClIB7w4,24207
|
|
3
|
-
piwave-2.0.9.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
4
|
-
piwave-2.0.9.dist-info/METADATA,sha256=BkYwSKDSJ0eWXxSWZvB3v_YU2HAZJXc3WIgabvyU5yM,11697
|
|
5
|
-
piwave-2.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
-
piwave-2.0.9.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
|
|
7
|
-
piwave-2.0.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|