+297
-52
Cargo.lock
+297
-52
Cargo.lock
···
57
]
58
59
[[package]]
60
name = "alsa"
61
version = "0.6.0"
62
source = "registry+https://github.com/rust-lang/crates.io-index"
63
checksum = "5915f52fe2cf65e83924d037b6c5290b7cee097c6b5c8700746e6168a343fd6b"
64
dependencies = [
65
"alsa-sys",
66
-
"bitflags",
67
"libc",
68
"nix",
69
]
···
237
dependencies = [
238
"proc-macro2",
239
"quote",
240
-
"syn",
241
]
242
243
[[package]]
···
267
dependencies = [
268
"proc-macro2",
269
"quote",
270
-
"syn",
271
]
272
273
[[package]]
···
301
dependencies = [
302
"async-trait",
303
"axum-core",
304
-
"bitflags",
305
"bytes",
306
"futures-util",
307
"http",
···
369
source = "registry+https://github.com/rust-lang/crates.io-index"
370
checksum = "8a022e58a142a46fea340d68012b9201c094e93ec3d033a944a24f8fd4a4f09a"
371
dependencies = [
372
-
"bitflags",
373
"cexpr",
374
"clang-sys",
375
"lazy_static",
···
380
"regex",
381
"rustc-hash",
382
"shlex",
383
-
"syn",
384
]
385
386
[[package]]
···
390
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
391
392
[[package]]
393
name = "block-buffer"
394
version = "0.9.0"
395
source = "registry+https://github.com/rust-lang/crates.io-index"
···
437
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
438
439
[[package]]
440
name = "cc"
441
version = "1.0.79"
442
source = "registry+https://github.com/rust-lang/crates.io-index"
···
493
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
494
dependencies = [
495
"atty",
496
-
"bitflags",
497
"clap_lex",
498
"indexmap",
499
"strsim",
···
524
dependencies = [
525
"bytes",
526
"memchr",
527
]
528
529
[[package]]
···
591
source = "registry+https://github.com/rust-lang/crates.io-index"
592
checksum = "11894b20ebfe1ff903cbdc52259693389eea03b94918a2def2c30c3bf227ad88"
593
dependencies = [
594
-
"bitflags",
595
"coreaudio-sys",
596
]
597
···
663
]
664
665
[[package]]
666
name = "crypto-mac"
667
version = "0.10.1"
668
source = "registry+https://github.com/rust-lang/crates.io-index"
···
679
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
680
dependencies = [
681
"quote",
682
-
"syn",
683
]
684
685
[[package]]
···
704
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
705
dependencies = [
706
"cfg-if",
707
-
"hashbrown",
708
"lock_api",
709
"once_cell",
710
"parking_lot_core",
···
876
dependencies = [
877
"proc-macro2",
878
"quote",
879
-
"syn",
880
]
881
882
[[package]]
···
995
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
996
997
[[package]]
998
name = "heck"
999
version = "0.4.1"
1000
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1202
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
1203
dependencies = [
1204
"autocfg",
1205
-
"hashbrown",
1206
]
1207
1208
[[package]]
1209
name = "infer"
···
1236
]
1237
1238
[[package]]
1239
name = "itoa"
1240
version = "1.0.5"
1241
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1318
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
1319
dependencies = [
1320
"arrayvec 0.5.2",
1321
-
"bitflags",
1322
"cfg-if",
1323
"ryu",
1324
"static_assertions",
···
1361
]
1362
1363
[[package]]
1364
name = "m3u"
1365
version = "1.0.0"
1366
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1489
source = "registry+https://github.com/rust-lang/crates.io-index"
1490
checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4"
1491
dependencies = [
1492
-
"bitflags",
1493
"jni-sys",
1494
"ndk-sys 0.3.0",
1495
"num_enum",
···
1502
source = "registry+https://github.com/rust-lang/crates.io-index"
1503
checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0"
1504
dependencies = [
1505
-
"bitflags",
1506
"jni-sys",
1507
"ndk-sys 0.4.1+23.1.7779620",
1508
"num_enum",
···
1540
source = "registry+https://github.com/rust-lang/crates.io-index"
1541
checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
1542
dependencies = [
1543
-
"bitflags",
1544
"cc",
1545
"cfg-if",
1546
"libc",
···
1585
dependencies = [
1586
"proc-macro2",
1587
"quote",
1588
-
"syn",
1589
]
1590
1591
[[package]]
···
1625
"proc-macro-crate",
1626
"proc-macro2",
1627
"quote",
1628
-
"syn",
1629
]
1630
1631
[[package]]
···
1668
1669
[[package]]
1670
name = "once_cell"
1671
-
version = "1.17.1"
1672
source = "registry+https://github.com/rust-lang/crates.io-index"
1673
-
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
1674
1675
[[package]]
1676
name = "opaque-debug"
···
1684
source = "registry+https://github.com/rust-lang/crates.io-index"
1685
checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1"
1686
dependencies = [
1687
-
"bitflags",
1688
"cfg-if",
1689
"foreign-types",
1690
"libc",
···
1701
dependencies = [
1702
"proc-macro2",
1703
"quote",
1704
-
"syn",
1705
]
1706
1707
[[package]]
···
1765
]
1766
1767
[[package]]
1768
name = "peeking_take_while"
1769
version = "0.1.2"
1770
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1809
dependencies = [
1810
"proc-macro2",
1811
"quote",
1812
-
"syn",
1813
]
1814
1815
[[package]]
···
1877
checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78"
1878
dependencies = [
1879
"proc-macro2",
1880
-
"syn",
1881
]
1882
1883
[[package]]
···
1898
1899
[[package]]
1900
name = "proc-macro2"
1901
-
version = "1.0.51"
1902
source = "registry+https://github.com/rust-lang/crates.io-index"
1903
-
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
1904
dependencies = [
1905
"unicode-ident",
1906
]
···
1923
dependencies = [
1924
"bytes",
1925
"heck",
1926
-
"itertools",
1927
"lazy_static",
1928
"log",
1929
"multimap",
···
1932
"prost",
1933
"prost-types",
1934
"regex",
1935
-
"syn",
1936
"tempfile",
1937
"which",
1938
]
···
1944
checksum = "4ea9b0f8cbe5e15a8a042d030bd96668db28ecb567ec37d691971ff5731d2b1b"
1945
dependencies = [
1946
"anyhow",
1947
-
"itertools",
1948
"proc-macro2",
1949
"quote",
1950
-
"syn",
1951
]
1952
1953
[[package]]
···
1961
1962
[[package]]
1963
name = "quote"
1964
-
version = "1.0.23"
1965
source = "registry+https://github.com/rust-lang/crates.io-index"
1966
-
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
1967
dependencies = [
1968
"proc-macro2",
1969
]
···
2040
]
2041
2042
[[package]]
2043
name = "raw-window-handle"
2044
version = "0.5.0"
2045
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2054
source = "registry+https://github.com/rust-lang/crates.io-index"
2055
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
2056
dependencies = [
2057
-
"bitflags",
2058
]
2059
2060
[[package]]
···
2241
source = "registry+https://github.com/rust-lang/crates.io-index"
2242
checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
2243
dependencies = [
2244
-
"bitflags",
2245
"core-foundation",
2246
"core-foundation-sys",
2247
"libc",
···
2275
2276
[[package]]
2277
name = "serde"
2278
-
version = "1.0.152"
2279
source = "registry+https://github.com/rust-lang/crates.io-index"
2280
-
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
2281
dependencies = [
2282
"serde_derive",
2283
]
2284
2285
[[package]]
2286
name = "serde_derive"
2287
-
version = "1.0.152"
2288
source = "registry+https://github.com/rust-lang/crates.io-index"
2289
-
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
2290
dependencies = [
2291
"proc-macro2",
2292
"quote",
2293
-
"syn",
2294
]
2295
2296
[[package]]
···
2362
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
2363
2364
[[package]]
2365
name = "simple-mutex"
2366
version = "1.1.5"
2367
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2413
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
2414
2415
[[package]]
2416
name = "standback"
2417
version = "0.2.17"
2418
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2451
"quote",
2452
"serde",
2453
"serde_derive",
2454
-
"syn",
2455
]
2456
2457
[[package]]
···
2467
"serde_derive",
2468
"serde_json",
2469
"sha1",
2470
-
"syn",
2471
]
2472
2473
[[package]]
···
2483
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
2484
2485
[[package]]
2486
name = "subtle"
2487
version = "2.4.1"
2488
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2550
source = "registry+https://github.com/rust-lang/crates.io-index"
2551
checksum = "55a0846e7a2c9a8081ff799fc83a975170417ad2a143f644a77ec2e3e82a2b73"
2552
dependencies = [
2553
-
"bitflags",
2554
"lazy_static",
2555
"log",
2556
"symphonia-core",
···
2616
checksum = "6b9567e2d8a5f866b2f94f5d366d811e0c6826babcff6d37de9e1a6690d38869"
2617
dependencies = [
2618
"arrayvec 0.7.2",
2619
-
"bitflags",
2620
"bytemuck",
2621
"lazy_static",
2622
"log",
···
2705
]
2706
2707
[[package]]
2708
name = "sync_wrapper"
2709
version = "0.1.2"
2710
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2768
dependencies = [
2769
"proc-macro2",
2770
"quote",
2771
-
"syn",
2772
]
2773
2774
[[package]]
···
2806
"proc-macro2",
2807
"quote",
2808
"standback",
2809
-
"syn",
2810
]
2811
2812
[[package]]
···
2860
dependencies = [
2861
"proc-macro2",
2862
"quote",
2863
-
"syn",
2864
]
2865
2866
[[package]]
···
2957
"proc-macro2",
2958
"prost-build",
2959
"quote",
2960
-
"syn",
2961
]
2962
2963
[[package]]
···
3004
source = "registry+https://github.com/rust-lang/crates.io-index"
3005
checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858"
3006
dependencies = [
3007
-
"bitflags",
3008
"bytes",
3009
"futures-core",
3010
"futures-util",
···
3050
dependencies = [
3051
"proc-macro2",
3052
"quote",
3053
-
"syn",
3054
]
3055
3056
[[package]]
···
3095
3096
[[package]]
3097
name = "tunein-cli"
3098
-
version = "0.1.3"
3099
dependencies = [
3100
"anyhow",
3101
"clap",
3102
"cpal",
3103
"futures",
3104
"futures-util",
3105
"hyper",
···
3108
"owo-colors",
3109
"pls",
3110
"prost",
3111
"reqwest",
3112
"rodio",
3113
"surf",
3114
"symphonia",
3115
"termion",
···
3158
]
3159
3160
[[package]]
3161
name = "universal-hash"
3162
version = "0.4.1"
3163
source = "registry+https://github.com/rust-lang/crates.io-index"
···
3278
"once_cell",
3279
"proc-macro2",
3280
"quote",
3281
-
"syn",
3282
"wasm-bindgen-shared",
3283
]
3284
···
3312
dependencies = [
3313
"proc-macro2",
3314
"quote",
3315
-
"syn",
3316
"wasm-bindgen-backend",
3317
"wasm-bindgen-shared",
3318
]
···
3535
dependencies = [
3536
"winapi",
3537
]
···
57
]
58
59
[[package]]
60
+
name = "ahash"
61
+
version = "0.8.10"
62
+
source = "registry+https://github.com/rust-lang/crates.io-index"
63
+
checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b"
64
+
dependencies = [
65
+
"cfg-if",
66
+
"once_cell",
67
+
"version_check",
68
+
"zerocopy",
69
+
]
70
+
71
+
[[package]]
72
+
name = "allocator-api2"
73
+
version = "0.2.16"
74
+
source = "registry+https://github.com/rust-lang/crates.io-index"
75
+
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
76
+
77
+
[[package]]
78
name = "alsa"
79
version = "0.6.0"
80
source = "registry+https://github.com/rust-lang/crates.io-index"
81
checksum = "5915f52fe2cf65e83924d037b6c5290b7cee097c6b5c8700746e6168a343fd6b"
82
dependencies = [
83
"alsa-sys",
84
+
"bitflags 1.3.2",
85
"libc",
86
"nix",
87
]
···
255
dependencies = [
256
"proc-macro2",
257
"quote",
258
+
"syn 1.0.107",
259
]
260
261
[[package]]
···
285
dependencies = [
286
"proc-macro2",
287
"quote",
288
+
"syn 1.0.107",
289
]
290
291
[[package]]
···
319
dependencies = [
320
"async-trait",
321
"axum-core",
322
+
"bitflags 1.3.2",
323
"bytes",
324
"futures-util",
325
"http",
···
387
source = "registry+https://github.com/rust-lang/crates.io-index"
388
checksum = "8a022e58a142a46fea340d68012b9201c094e93ec3d033a944a24f8fd4a4f09a"
389
dependencies = [
390
+
"bitflags 1.3.2",
391
"cexpr",
392
"clang-sys",
393
"lazy_static",
···
398
"regex",
399
"rustc-hash",
400
"shlex",
401
+
"syn 1.0.107",
402
]
403
404
[[package]]
···
408
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
409
410
[[package]]
411
+
name = "bitflags"
412
+
version = "2.4.2"
413
+
source = "registry+https://github.com/rust-lang/crates.io-index"
414
+
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
415
+
416
+
[[package]]
417
name = "block-buffer"
418
version = "0.9.0"
419
source = "registry+https://github.com/rust-lang/crates.io-index"
···
461
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
462
463
[[package]]
464
+
name = "cassowary"
465
+
version = "0.3.0"
466
+
source = "registry+https://github.com/rust-lang/crates.io-index"
467
+
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
468
+
469
+
[[package]]
470
+
name = "castaway"
471
+
version = "0.2.2"
472
+
source = "registry+https://github.com/rust-lang/crates.io-index"
473
+
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
474
+
dependencies = [
475
+
"rustversion",
476
+
]
477
+
478
+
[[package]]
479
name = "cc"
480
version = "1.0.79"
481
source = "registry+https://github.com/rust-lang/crates.io-index"
···
532
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
533
dependencies = [
534
"atty",
535
+
"bitflags 1.3.2",
536
"clap_lex",
537
"indexmap",
538
"strsim",
···
563
dependencies = [
564
"bytes",
565
"memchr",
566
+
]
567
+
568
+
[[package]]
569
+
name = "compact_str"
570
+
version = "0.7.1"
571
+
source = "registry+https://github.com/rust-lang/crates.io-index"
572
+
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
573
+
dependencies = [
574
+
"castaway",
575
+
"cfg-if",
576
+
"itoa",
577
+
"ryu",
578
+
"static_assertions",
579
]
580
581
[[package]]
···
643
source = "registry+https://github.com/rust-lang/crates.io-index"
644
checksum = "11894b20ebfe1ff903cbdc52259693389eea03b94918a2def2c30c3bf227ad88"
645
dependencies = [
646
+
"bitflags 1.3.2",
647
"coreaudio-sys",
648
]
649
···
715
]
716
717
[[package]]
718
+
name = "crossterm"
719
+
version = "0.27.0"
720
+
source = "registry+https://github.com/rust-lang/crates.io-index"
721
+
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
722
+
dependencies = [
723
+
"bitflags 2.4.2",
724
+
"crossterm_winapi",
725
+
"libc",
726
+
"mio",
727
+
"parking_lot",
728
+
"signal-hook",
729
+
"signal-hook-mio",
730
+
"winapi",
731
+
]
732
+
733
+
[[package]]
734
+
name = "crossterm_winapi"
735
+
version = "0.9.1"
736
+
source = "registry+https://github.com/rust-lang/crates.io-index"
737
+
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
738
+
dependencies = [
739
+
"winapi",
740
+
]
741
+
742
+
[[package]]
743
name = "crypto-mac"
744
version = "0.10.1"
745
source = "registry+https://github.com/rust-lang/crates.io-index"
···
756
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
757
dependencies = [
758
"quote",
759
+
"syn 1.0.107",
760
]
761
762
[[package]]
···
781
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
782
dependencies = [
783
"cfg-if",
784
+
"hashbrown 0.12.3",
785
"lock_api",
786
"once_cell",
787
"parking_lot_core",
···
953
dependencies = [
954
"proc-macro2",
955
"quote",
956
+
"syn 1.0.107",
957
]
958
959
[[package]]
···
1072
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
1073
1074
[[package]]
1075
+
name = "hashbrown"
1076
+
version = "0.14.3"
1077
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1078
+
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
1079
+
dependencies = [
1080
+
"ahash",
1081
+
"allocator-api2",
1082
+
]
1083
+
1084
+
[[package]]
1085
name = "heck"
1086
version = "0.4.1"
1087
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1289
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
1290
dependencies = [
1291
"autocfg",
1292
+
"hashbrown 0.12.3",
1293
]
1294
+
1295
+
[[package]]
1296
+
name = "indoc"
1297
+
version = "2.0.4"
1298
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1299
+
checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
1300
1301
[[package]]
1302
name = "infer"
···
1329
]
1330
1331
[[package]]
1332
+
name = "itertools"
1333
+
version = "0.12.1"
1334
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1335
+
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
1336
+
dependencies = [
1337
+
"either",
1338
+
]
1339
+
1340
+
[[package]]
1341
name = "itoa"
1342
version = "1.0.5"
1343
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1420
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
1421
dependencies = [
1422
"arrayvec 0.5.2",
1423
+
"bitflags 1.3.2",
1424
"cfg-if",
1425
"ryu",
1426
"static_assertions",
···
1463
]
1464
1465
[[package]]
1466
+
name = "lru"
1467
+
version = "0.12.3"
1468
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1469
+
checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
1470
+
dependencies = [
1471
+
"hashbrown 0.14.3",
1472
+
]
1473
+
1474
+
[[package]]
1475
name = "m3u"
1476
version = "1.0.0"
1477
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1600
source = "registry+https://github.com/rust-lang/crates.io-index"
1601
checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4"
1602
dependencies = [
1603
+
"bitflags 1.3.2",
1604
"jni-sys",
1605
"ndk-sys 0.3.0",
1606
"num_enum",
···
1613
source = "registry+https://github.com/rust-lang/crates.io-index"
1614
checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0"
1615
dependencies = [
1616
+
"bitflags 1.3.2",
1617
"jni-sys",
1618
"ndk-sys 0.4.1+23.1.7779620",
1619
"num_enum",
···
1651
source = "registry+https://github.com/rust-lang/crates.io-index"
1652
checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
1653
dependencies = [
1654
+
"bitflags 1.3.2",
1655
"cc",
1656
"cfg-if",
1657
"libc",
···
1696
dependencies = [
1697
"proc-macro2",
1698
"quote",
1699
+
"syn 1.0.107",
1700
]
1701
1702
[[package]]
···
1736
"proc-macro-crate",
1737
"proc-macro2",
1738
"quote",
1739
+
"syn 1.0.107",
1740
]
1741
1742
[[package]]
···
1779
1780
[[package]]
1781
name = "once_cell"
1782
+
version = "1.19.0"
1783
source = "registry+https://github.com/rust-lang/crates.io-index"
1784
+
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
1785
1786
[[package]]
1787
name = "opaque-debug"
···
1795
source = "registry+https://github.com/rust-lang/crates.io-index"
1796
checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1"
1797
dependencies = [
1798
+
"bitflags 1.3.2",
1799
"cfg-if",
1800
"foreign-types",
1801
"libc",
···
1812
dependencies = [
1813
"proc-macro2",
1814
"quote",
1815
+
"syn 1.0.107",
1816
]
1817
1818
[[package]]
···
1876
]
1877
1878
[[package]]
1879
+
name = "paste"
1880
+
version = "1.0.14"
1881
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1882
+
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
1883
+
1884
+
[[package]]
1885
name = "peeking_take_while"
1886
version = "0.1.2"
1887
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1926
dependencies = [
1927
"proc-macro2",
1928
"quote",
1929
+
"syn 1.0.107",
1930
]
1931
1932
[[package]]
···
1994
checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78"
1995
dependencies = [
1996
"proc-macro2",
1997
+
"syn 1.0.107",
1998
]
1999
2000
[[package]]
···
2015
2016
[[package]]
2017
name = "proc-macro2"
2018
+
version = "1.0.78"
2019
source = "registry+https://github.com/rust-lang/crates.io-index"
2020
+
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
2021
dependencies = [
2022
"unicode-ident",
2023
]
···
2040
dependencies = [
2041
"bytes",
2042
"heck",
2043
+
"itertools 0.10.5",
2044
"lazy_static",
2045
"log",
2046
"multimap",
···
2049
"prost",
2050
"prost-types",
2051
"regex",
2052
+
"syn 1.0.107",
2053
"tempfile",
2054
"which",
2055
]
···
2061
checksum = "4ea9b0f8cbe5e15a8a042d030bd96668db28ecb567ec37d691971ff5731d2b1b"
2062
dependencies = [
2063
"anyhow",
2064
+
"itertools 0.10.5",
2065
"proc-macro2",
2066
"quote",
2067
+
"syn 1.0.107",
2068
]
2069
2070
[[package]]
···
2078
2079
[[package]]
2080
name = "quote"
2081
+
version = "1.0.35"
2082
source = "registry+https://github.com/rust-lang/crates.io-index"
2083
+
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
2084
dependencies = [
2085
"proc-macro2",
2086
]
···
2157
]
2158
2159
[[package]]
2160
+
name = "ratatui"
2161
+
version = "0.26.1"
2162
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2163
+
checksum = "bcb12f8fbf6c62614b0d56eb352af54f6a22410c3b079eb53ee93c7b97dd31d8"
2164
+
dependencies = [
2165
+
"bitflags 2.4.2",
2166
+
"cassowary",
2167
+
"compact_str",
2168
+
"crossterm",
2169
+
"indoc",
2170
+
"itertools 0.12.1",
2171
+
"lru",
2172
+
"paste",
2173
+
"stability",
2174
+
"strum",
2175
+
"unicode-segmentation",
2176
+
"unicode-width",
2177
+
]
2178
+
2179
+
[[package]]
2180
name = "raw-window-handle"
2181
version = "0.5.0"
2182
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2191
source = "registry+https://github.com/rust-lang/crates.io-index"
2192
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
2193
dependencies = [
2194
+
"bitflags 1.3.2",
2195
]
2196
2197
[[package]]
···
2378
source = "registry+https://github.com/rust-lang/crates.io-index"
2379
checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
2380
dependencies = [
2381
+
"bitflags 1.3.2",
2382
"core-foundation",
2383
"core-foundation-sys",
2384
"libc",
···
2412
2413
[[package]]
2414
name = "serde"
2415
+
version = "1.0.197"
2416
source = "registry+https://github.com/rust-lang/crates.io-index"
2417
+
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
2418
dependencies = [
2419
"serde_derive",
2420
]
2421
2422
[[package]]
2423
name = "serde_derive"
2424
+
version = "1.0.197"
2425
source = "registry+https://github.com/rust-lang/crates.io-index"
2426
+
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
2427
dependencies = [
2428
"proc-macro2",
2429
"quote",
2430
+
"syn 2.0.51",
2431
]
2432
2433
[[package]]
···
2499
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
2500
2501
[[package]]
2502
+
name = "signal-hook"
2503
+
version = "0.3.17"
2504
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2505
+
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
2506
+
dependencies = [
2507
+
"libc",
2508
+
"signal-hook-registry",
2509
+
]
2510
+
2511
+
[[package]]
2512
+
name = "signal-hook-mio"
2513
+
version = "0.2.3"
2514
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2515
+
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
2516
+
dependencies = [
2517
+
"libc",
2518
+
"mio",
2519
+
"signal-hook",
2520
+
]
2521
+
2522
+
[[package]]
2523
+
name = "signal-hook-registry"
2524
+
version = "1.4.1"
2525
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2526
+
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
2527
+
dependencies = [
2528
+
"libc",
2529
+
]
2530
+
2531
+
[[package]]
2532
name = "simple-mutex"
2533
version = "1.1.5"
2534
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2580
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
2581
2582
[[package]]
2583
+
name = "stability"
2584
+
version = "0.1.1"
2585
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2586
+
checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce"
2587
+
dependencies = [
2588
+
"quote",
2589
+
"syn 1.0.107",
2590
+
]
2591
+
2592
+
[[package]]
2593
name = "standback"
2594
version = "0.2.17"
2595
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2628
"quote",
2629
"serde",
2630
"serde_derive",
2631
+
"syn 1.0.107",
2632
]
2633
2634
[[package]]
···
2644
"serde_derive",
2645
"serde_json",
2646
"sha1",
2647
+
"syn 1.0.107",
2648
]
2649
2650
[[package]]
···
2660
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
2661
2662
[[package]]
2663
+
name = "strum"
2664
+
version = "0.26.1"
2665
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2666
+
checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f"
2667
+
dependencies = [
2668
+
"strum_macros",
2669
+
]
2670
+
2671
+
[[package]]
2672
+
name = "strum_macros"
2673
+
version = "0.26.1"
2674
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2675
+
checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18"
2676
+
dependencies = [
2677
+
"heck",
2678
+
"proc-macro2",
2679
+
"quote",
2680
+
"rustversion",
2681
+
"syn 2.0.51",
2682
+
]
2683
+
2684
+
[[package]]
2685
name = "subtle"
2686
version = "2.4.1"
2687
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2749
source = "registry+https://github.com/rust-lang/crates.io-index"
2750
checksum = "55a0846e7a2c9a8081ff799fc83a975170417ad2a143f644a77ec2e3e82a2b73"
2751
dependencies = [
2752
+
"bitflags 1.3.2",
2753
"lazy_static",
2754
"log",
2755
"symphonia-core",
···
2815
checksum = "6b9567e2d8a5f866b2f94f5d366d811e0c6826babcff6d37de9e1a6690d38869"
2816
dependencies = [
2817
"arrayvec 0.7.2",
2818
+
"bitflags 1.3.2",
2819
"bytemuck",
2820
"lazy_static",
2821
"log",
···
2904
]
2905
2906
[[package]]
2907
+
name = "syn"
2908
+
version = "2.0.51"
2909
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2910
+
checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c"
2911
+
dependencies = [
2912
+
"proc-macro2",
2913
+
"quote",
2914
+
"unicode-ident",
2915
+
]
2916
+
2917
+
[[package]]
2918
name = "sync_wrapper"
2919
version = "0.1.2"
2920
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2978
dependencies = [
2979
"proc-macro2",
2980
"quote",
2981
+
"syn 1.0.107",
2982
]
2983
2984
[[package]]
···
3016
"proc-macro2",
3017
"quote",
3018
"standback",
3019
+
"syn 1.0.107",
3020
]
3021
3022
[[package]]
···
3070
dependencies = [
3071
"proc-macro2",
3072
"quote",
3073
+
"syn 1.0.107",
3074
]
3075
3076
[[package]]
···
3167
"proc-macro2",
3168
"prost-build",
3169
"quote",
3170
+
"syn 1.0.107",
3171
]
3172
3173
[[package]]
···
3214
source = "registry+https://github.com/rust-lang/crates.io-index"
3215
checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858"
3216
dependencies = [
3217
+
"bitflags 1.3.2",
3218
"bytes",
3219
"futures-core",
3220
"futures-util",
···
3260
dependencies = [
3261
"proc-macro2",
3262
"quote",
3263
+
"syn 1.0.107",
3264
]
3265
3266
[[package]]
···
3305
3306
[[package]]
3307
name = "tunein-cli"
3308
+
version = "0.2.0"
3309
dependencies = [
3310
"anyhow",
3311
"clap",
3312
"cpal",
3313
+
"crossterm",
3314
"futures",
3315
"futures-util",
3316
"hyper",
···
3319
"owo-colors",
3320
"pls",
3321
"prost",
3322
+
"ratatui",
3323
"reqwest",
3324
"rodio",
3325
+
"serde",
3326
"surf",
3327
"symphonia",
3328
"termion",
···
3371
]
3372
3373
[[package]]
3374
+
name = "unicode-segmentation"
3375
+
version = "1.11.0"
3376
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3377
+
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
3378
+
3379
+
[[package]]
3380
+
name = "unicode-width"
3381
+
version = "0.1.11"
3382
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3383
+
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
3384
+
3385
+
[[package]]
3386
name = "universal-hash"
3387
version = "0.4.1"
3388
source = "registry+https://github.com/rust-lang/crates.io-index"
···
3503
"once_cell",
3504
"proc-macro2",
3505
"quote",
3506
+
"syn 1.0.107",
3507
"wasm-bindgen-shared",
3508
]
3509
···
3537
dependencies = [
3538
"proc-macro2",
3539
"quote",
3540
+
"syn 1.0.107",
3541
"wasm-bindgen-backend",
3542
"wasm-bindgen-shared",
3543
]
···
3760
dependencies = [
3761
"winapi",
3762
]
3763
+
3764
+
[[package]]
3765
+
name = "zerocopy"
3766
+
version = "0.7.32"
3767
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3768
+
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
3769
+
dependencies = [
3770
+
"zerocopy-derive",
3771
+
]
3772
+
3773
+
[[package]]
3774
+
name = "zerocopy-derive"
3775
+
version = "0.7.32"
3776
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3777
+
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
3778
+
dependencies = [
3779
+
"proc-macro2",
3780
+
"quote",
3781
+
"syn 2.0.51",
3782
+
]
+24
-22
Cargo.toml
+24
-22
Cargo.toml
···
1
[package]
2
-
name = "tunein-cli"
3
-
version = "0.1.3"
4
edition = "2021"
5
-
repository = "https://github.com/tsirysndr/tunein-cli"
6
license = "MIT"
7
readme = "README.md"
8
-
authors = ["Tsiry Sandratraina <tsiry.sndr@aol.com>"]
9
-
categories = ["command-line-utilities"]
10
-
keywords = ["radio", "api", "tokio", "web", "tunein"]
11
-
description = "Browse and listen to thousands of radio stations across the globe right from your terminal ๐ ๐ป ๐ตโจ"
12
13
[[bin]]
14
name = "tunein"
···
20
anyhow = "1.0.69"
21
clap = "3.2.20"
22
cpal = "0.14.0"
23
-
owo-colors = "3.5.0"
24
-
tunein = "0.1.2"
25
-
tokio = { version = "1.24.2", features = ["tokio-macros", "macros", "rt", "rt-multi-thread"] }
26
-
pls = "0.2.2"
27
-
m3u = "1.0.0"
28
-
symphonia = { version = "0.5.1", features = ["aac", "alac", "mp3", "isomp4", "flac"] }
29
-
hyper = { version = "0.14.23", features = ["client", "stream", "tcp", "http1", "http2"] }
30
-
surf = { version = "2.3.2", features = ["h1-client-rustls"], default-features = false}
31
futures-util = "0.3.26"
32
-
url = "2.3.1"
33
-
rodio = { version = "0.16" }
34
-
reqwest = { version = "0.11.14", features = ["blocking"] }
35
minimp3 = "0.5.1"
36
tonic = "0.8.3"
37
-
prost = "0.11.8"
38
tonic-web = "0.4.0"
39
-
futures = "0.3.26"
40
-
termion = "2.0.1"
41
-
42
43
[build-dependencies]
44
tonic-build = "0.8"
···
1
[package]
2
+
authors = ["Tsiry Sandratraina <tsiry.sndr@aol.com>"]
3
+
categories = ["command-line-utilities"]
4
+
description = "Browse and listen to thousands of radio stations across the globe right from your terminal ๐ ๐ป ๐ตโจ"
5
edition = "2021"
6
+
keywords = ["radio", "api", "tokio", "web", "tunein"]
7
license = "MIT"
8
+
name = "tunein-cli"
9
readme = "README.md"
10
+
repository = "https://github.com/tsirysndr/tunein-cli"
11
+
version = "0.2.0"
12
13
[[bin]]
14
name = "tunein"
···
20
anyhow = "1.0.69"
21
clap = "3.2.20"
22
cpal = "0.14.0"
23
+
crossterm = "0.27.0"
24
+
futures = "0.3.26"
25
futures-util = "0.3.26"
26
+
hyper = {version = "0.14.23", features = ["client", "stream", "tcp", "http1", "http2"]}
27
+
m3u = "1.0.0"
28
minimp3 = "0.5.1"
29
+
owo-colors = "3.5.0"
30
+
pls = "0.2.2"
31
+
prost = "0.11.8"
32
+
ratatui = "0.26.1"
33
+
reqwest = {version = "0.11.14", features = ["blocking"]}
34
+
rodio = {version = "0.16"}
35
+
serde = "1.0.197"
36
+
surf = {version = "2.3.2", features = ["h1-client-rustls"], default-features = false}
37
+
symphonia = {version = "0.5.1", features = ["aac", "alac", "mp3", "isomp4", "flac"]}
38
+
termion = "2.0.1"
39
+
tokio = {version = "1.24.2", features = ["tokio-macros", "macros", "rt", "rt-multi-thread"]}
40
tonic = "0.8.3"
41
tonic-web = "0.4.0"
42
+
tunein = "0.1.2"
43
+
url = "2.3.1"
44
45
[build-dependencies]
46
tonic-build = "0.8"
+1
-1
LICENSE
+1
-1
LICENSE
+3
README.md
+3
README.md
···
7
<a href="https://crates.io/crates/tunein-cli" target="_blank">
8
<img src="https://img.shields.io/crates/v/tunein-cli.svg" />
9
</a>
10
+
<a href="https://flakestry.dev/flake/github/tsirysndr/tunein-cli" target="_blank">
11
+
<img src="https://flakestry.dev/api/badge/flake/github/tsirysdnr/tunein-cli" />
12
+
</a>
13
<a href="https://crates.io/crates/tunein-cli" target="_blank">
14
<img src="https://img.shields.io/crates/dr/tunein-cli" />
15
</a>
+123
src/app.rs
+123
src/app.rs
···
···
1
+
use std::{
2
+
io,
3
+
sync::{Arc, Mutex},
4
+
};
5
+
6
+
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
7
+
use ratatui::{
8
+
prelude::*,
9
+
widgets::{block::*, *},
10
+
};
11
+
use tokio::sync::mpsc::UnboundedReceiver;
12
+
13
+
use crate::tui;
14
+
15
+
#[derive(Debug, Default, Clone)]
16
+
pub struct State {
17
+
pub name: String,
18
+
pub now_playing: String,
19
+
pub genre: String,
20
+
pub description: String,
21
+
pub br: String,
22
+
}
23
+
24
+
impl State {
25
+
pub fn update(&mut self, state: State) {
26
+
*self = state;
27
+
}
28
+
}
29
+
30
+
#[derive(Debug, Default)]
31
+
pub struct App {
32
+
pub state: Arc<Mutex<State>>,
33
+
exit: bool,
34
+
}
35
+
36
+
impl App {
37
+
pub fn new() -> Self {
38
+
let state = Arc::new(Mutex::new(State::default()));
39
+
Self { state, exit: false }
40
+
}
41
+
}
42
+
43
+
impl App {
44
+
/// runs the application's main loop until the user quits
45
+
pub async fn run(
46
+
&mut self,
47
+
terminal: &mut tui::Tui,
48
+
mut cmd_rx: UnboundedReceiver<State>,
49
+
) -> anyhow::Result<()> {
50
+
let new_state = cmd_rx.recv().await.unwrap();
51
+
self.state.lock().unwrap().update(new_state);
52
+
while !self.exit {
53
+
terminal.draw(|frame| self.render_frame(frame))?;
54
+
self.handle_events()?;
55
+
}
56
+
Ok(())
57
+
}
58
+
59
+
fn render_frame(&self, frame: &mut Frame) {
60
+
let areas = Layout::new(
61
+
Direction::Vertical,
62
+
[
63
+
Constraint::Length(1),
64
+
Constraint::Length(1),
65
+
Constraint::Length(1),
66
+
Constraint::Length(1),
67
+
Constraint::Length(1),
68
+
Constraint::Min(0),
69
+
],
70
+
)
71
+
.split(frame.size());
72
+
73
+
frame.render_widget(
74
+
Block::new()
75
+
.borders(Borders::TOP)
76
+
.title(" TuneIn CLI ")
77
+
.title_alignment(Alignment::Center),
78
+
areas[0],
79
+
);
80
+
81
+
let state = self.state.lock().unwrap();
82
+
83
+
self.render_line("Station ", &state.name, areas[1], frame);
84
+
self.render_line("Now Playing ", &state.now_playing, areas[2], frame);
85
+
self.render_line("Genre ", &state.genre, areas[3], frame);
86
+
self.render_line("Description ", &state.description, areas[4], frame);
87
+
self.render_line("Bitrate ", &format!("{} kbps", &state.br), areas[5], frame);
88
+
}
89
+
90
+
fn render_line(&self, label: &str, value: &str, area: Rect, frame: &mut Frame) {
91
+
let span1 = Span::styled(label, Style::new().fg(Color::LightBlue));
92
+
let span2 = Span::raw(value);
93
+
94
+
let line = Line::from(vec![span1, span2]);
95
+
let text: Text = Text::from(vec![line]);
96
+
97
+
frame.render_widget(Paragraph::new(text), area);
98
+
}
99
+
100
+
/// updates the application's state based on user input
101
+
fn handle_events(&mut self) -> io::Result<()> {
102
+
match event::read()? {
103
+
// it's important to check that the event is a key press event as
104
+
// crossterm also emits key release and repeat events on Windows.
105
+
Event::Key(key_event) if key_event.kind == KeyEventKind::Press => {
106
+
self.handle_key_event(key_event)
107
+
}
108
+
_ => {}
109
+
};
110
+
Ok(())
111
+
}
112
+
113
+
fn handle_key_event(&mut self, key_event: KeyEvent) {
114
+
match key_event.code {
115
+
KeyCode::Char('q') => self.exit(),
116
+
_ => {}
117
+
}
118
+
}
119
+
120
+
fn exit(&mut self) {
121
+
self.exit = true;
122
+
}
123
+
}
+27
src/extract.rs
+27
src/extract.rs
···
1
use std::time::Duration;
2
3
use anyhow::Error;
4
+
use serde::Deserialize;
5
use surf::{Client, Config, Url};
6
+
7
+
#[derive(Deserialize)]
8
+
pub struct Header {
9
+
#[serde(rename = "Title")]
10
+
pub title: String,
11
+
#[serde(rename = "Subtitle")]
12
+
pub subtitle: String,
13
+
}
14
+
15
+
#[derive(Deserialize)]
16
+
pub struct NowPlaying {
17
+
#[serde(rename = "Header")]
18
+
pub header: Header,
19
+
}
20
21
pub async fn extract_stream_url(url: &str, playlist_type: Option<String>) -> Result<String, Error> {
22
match playlist_type {
···
52
None => Ok(url.to_string()),
53
}
54
}
55
+
56
+
pub async fn get_currently_playing(station: &str) -> Result<String, Error> {
57
+
let client = Client::new();
58
+
let url = format!("https://feed.tunein.com/profiles/{}/nowPlaying", station);
59
+
let response: NowPlaying = client
60
+
.get(Url::parse(&url)?)
61
+
.recv_json()
62
+
.await
63
+
.map_err(|e| Error::msg(e.to_string()))?;
64
+
65
+
Ok(response.header.subtitle)
66
+
}
+3
-1
src/main.rs
+3
-1
src/main.rs
···
1
use anyhow::Error;
2
use clap::{arg, Command};
3
4
mod browse;
5
mod decoder;
6
mod extract;
···
8
mod player;
9
mod search;
10
mod server;
11
12
fn cli() -> Command<'static> {
13
const VESRION: &str = env!("CARGO_PKG_VERSION");
14
Command::new("tunein")
15
.version(VESRION)
16
-
.author("Tsiry Sandratraina <tsiry.sndr@aol.com>")
17
.about(
18
r#"
19
______ ____ _______ ____
···
1
use anyhow::Error;
2
use clap::{arg, Command};
3
4
+
mod app;
5
mod browse;
6
mod decoder;
7
mod extract;
···
9
mod player;
10
mod search;
11
mod server;
12
+
mod tui;
13
14
fn cli() -> Command<'static> {
15
const VESRION: &str = env!("CARGO_PKG_VERSION");
16
Command::new("tunein")
17
.version(VESRION)
18
+
.author("Tsiry Sandratraina <tsiry.sndr@fluentci.io>")
19
.about(
20
r#"
21
______ ____ _______ ____
+47
-26
src/play.rs
+47
-26
src/play.rs
···
1
-
use std::time::Duration;
2
3
use anyhow::Error;
4
-
use owo_colors::OwoColorize;
5
-
use termion::{clear, cursor};
6
use tunein::TuneInClient;
7
8
-
use crate::{decoder::Mp3Decoder, extract::extract_stream_url};
9
-
10
-
const METER_CHAR: char = 'โ';
11
12
pub async fn exec(name_or_id: &str) -> Result<(), Error> {
13
let client = TuneInClient::new();
···
15
.get_station(name_or_id)
16
.await
17
.map_err(|e| Error::msg(e.to_string()))?;
18
-
let (url, playlist_type, _) = match results.is_empty() {
19
true => {
20
let results = client
21
.search(name_or_id)
···
36
station.url.clone(),
37
station.playlist_type.clone(),
38
station.media_type.clone(),
39
)
40
}
41
-
None => ("".to_string(), None, "".to_string()),
42
}
43
}
44
false => {
···
47
result.url.clone(),
48
result.playlist_type.clone(),
49
result.media_type.clone(),
50
)
51
}
52
};
53
let stream_url = extract_stream_url(&url, playlist_type).await?;
54
println!("{}", stream_url);
55
56
-
tokio::task::spawn_blocking(move || {
57
let client = reqwest::blocking::Client::new();
58
59
let response = client.get(stream_url).send().unwrap();
60
61
-
println!("headers: {:#?}", response.headers());
62
let location = response.headers().get("location");
63
64
let response = match location {
···
79
sink.append(decoder);
80
81
loop {
82
-
let level = sink.volume();
83
-
display_vu_meter(level);
84
std::thread::sleep(Duration::from_millis(10));
85
}
86
-
})
87
-
.await?;
88
-
89
-
Ok(())
90
-
}
91
92
-
fn display_vu_meter(level: f32) {
93
-
print!("{}{}", clear::All, cursor::Goto(1, 1));
94
-
for i in 0..20 {
95
-
if (i as f32) / 20.0 <= level {
96
-
print!("{}", METER_CHAR.bright_yellow());
97
-
} else {
98
-
print!("{}", METER_CHAR.bright_yellow());
99
-
}
100
-
}
101
}
···
1
+
use std::{thread, time::Duration};
2
3
use anyhow::Error;
4
use tunein::TuneInClient;
5
6
+
use crate::{
7
+
app::{App, State},
8
+
decoder::Mp3Decoder,
9
+
extract::{extract_stream_url, get_currently_playing},
10
+
tui,
11
+
};
12
13
pub async fn exec(name_or_id: &str) -> Result<(), Error> {
14
let client = TuneInClient::new();
···
16
.get_station(name_or_id)
17
.await
18
.map_err(|e| Error::msg(e.to_string()))?;
19
+
let (url, playlist_type, _, id) = match results.is_empty() {
20
true => {
21
let results = client
22
.search(name_or_id)
···
37
station.url.clone(),
38
station.playlist_type.clone(),
39
station.media_type.clone(),
40
+
id.clone(),
41
)
42
}
43
+
None => ("".to_string(), None, "".to_string(), "".to_string()),
44
}
45
}
46
false => {
···
49
result.url.clone(),
50
result.playlist_type.clone(),
51
result.media_type.clone(),
52
+
name_or_id.to_string(),
53
)
54
}
55
};
56
+
let now_playing = get_currently_playing(&id).await?;
57
let stream_url = extract_stream_url(&url, playlist_type).await?;
58
println!("{}", stream_url);
59
60
+
let (cmd_tx, cmd_rx) = tokio::sync::mpsc::unbounded_channel::<State>();
61
+
62
+
let mut app = App::new();
63
+
64
+
thread::spawn(move || {
65
let client = reqwest::blocking::Client::new();
66
67
let response = client.get(stream_url).send().unwrap();
68
69
+
let headers = response.headers();
70
+
cmd_tx
71
+
.send(State {
72
+
name: headers
73
+
.get("icy-name")
74
+
.unwrap()
75
+
.to_str()
76
+
.unwrap()
77
+
.to_string(),
78
+
now_playing,
79
+
genre: headers
80
+
.get("icy-genre")
81
+
.unwrap()
82
+
.to_str()
83
+
.unwrap()
84
+
.to_string(),
85
+
description: headers
86
+
.get("icy-description")
87
+
.unwrap()
88
+
.to_str()
89
+
.unwrap()
90
+
.to_string(),
91
+
br: headers.get("icy-br").unwrap().to_str().unwrap().to_string(),
92
+
})
93
+
.unwrap();
94
let location = response.headers().get("location");
95
96
let response = match location {
···
111
sink.append(decoder);
112
113
loop {
114
std::thread::sleep(Duration::from_millis(10));
115
}
116
+
});
117
118
+
let mut terminal = tui::init()?;
119
+
let app_result = app.run(&mut terminal, cmd_rx).await;
120
+
tui::restore()?;
121
+
app_result
122
}
+23
src/tui.rs
+23
src/tui.rs
···
···
1
+
use std::io::{self, stderr, stdout, Stdout};
2
+
3
+
use crossterm::{execute, terminal::*};
4
+
use ratatui::prelude::*;
5
+
6
+
/// A type alias for the terminal type used in this application
7
+
pub type Tui = Terminal<CrosstermBackend<Stdout>>;
8
+
9
+
/// Initialize the terminal
10
+
pub fn init() -> io::Result<Tui> {
11
+
execute!(stdout(), EnterAlternateScreen)?;
12
+
execute!(stderr(), EnterAlternateScreen)?;
13
+
enable_raw_mode()?;
14
+
Terminal::new(CrosstermBackend::new(stdout()))
15
+
}
16
+
17
+
/// Restore the terminal to its original state
18
+
pub fn restore() -> io::Result<()> {
19
+
execute!(stdout(), LeaveAlternateScreen)?;
20
+
execute!(stderr(), LeaveAlternateScreen)?;
21
+
disable_raw_mode()?;
22
+
Ok(())
23
+
}