Check-in [659724c658]
Logged in as anonymous
Overview
Comment:0.2.4: sources are enabled by default when adding, minimize type conversions
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 659724c6585a14a71f1bec7e77faf91958bc06e0ff802fe1edb743a79b1234c0
User & Date: arcade on 2021-12-08 13:14:28.124
Other Links: manifest | tags
Context
2021-12-30
13:14
0.2.5: update deps, clean strings check-in: 4b64438e28 user: arcade tags: trunk
2021-12-08
13:14
0.2.4: sources are enabled by default when adding, minimize type conversions check-in: 659724c658 user: arcade tags: trunk
2021-11-20
08:52
0.2.3: number of fixes for URL editing, plus now edited url is considered for duplicate removal check-in: f48d583330 user: arcade tags: trunk
Changes
50
51
52
53
54
55
56
57

58
59

60
61
62
63
64
65
66
50
51
52
53
54
55
56

57
58

59
60
61
62
63
64
65
66







-
+

-
+







checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2"
dependencies = [
 "alloc-no-stdlib",
]

[[package]]
name = "anyhow"
version = "1.0.47"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38d9ff5d688f1c13395289f67db01d4826b46dd694e7580accdc3e8430f2d98e"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"

[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"

331
332
333
334
335
336
337
338

339
340

341
342
343
344
345
346
347
331
332
333
334
335
336
337

338
339

340
341
342
343
344
345
346
347







-
+

-
+







name = "crc-catalog"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403"

[[package]]
name = "crc32fast"
version = "1.2.1"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
dependencies = [
 "cfg-if 1.0.0",
]

[[package]]
name = "crossbeam-channel"
version = "0.5.1"
610
611
612
613
614
615
616
617

618
619

620
621
622
623
624
625
626
610
611
612
613
614
615
616

617
618

619
620
621
622
623
624
625
626







-
+

-
+







name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"

[[package]]
name = "encoding_rs"
version = "0.8.29"
version = "0.8.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746"
checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df"
dependencies = [
 "cfg-if 1.0.0",
]

[[package]]
name = "failure"
version = "0.1.8"
712
713
714
715
716
717
718
719

720
721

722
723
724
725
726
727
728
729
730
731
732
733
734

735
736

737
738
739
740
741
742
743
744

745
746

747
748
749
750
751
752
753
754
755
756
757
758
759
760

761
762

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782

783
784

785
786
787
788

789
790

791
792
793
794
795
796
797
798
799
800
801

802
803

804
805
806
807

808
809

810
811
812
813

814
815

816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
712
713
714
715
716
717
718

719
720

721
722
723
724
725
726
727
728
729
730
731
732
733

734
735

736
737
738
739
740
741
742
743

744
745

746
747
748
749
750
751
752
753
754
755
756
757
758
759

760
761

762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781

782
783

784
785
786
787

788
789

790
791


792
793
794
795
796
797
798

799
800

801
802
803
804

805
806

807
808
809
810

811
812

813
814

815
816
817
818
819
820
821
822
823


824
825
826
827
828
829
830







-
+

-
+












-
+

-
+







-
+

-
+













-
+

-
+



















-
+

-
+



-
+

-
+

-
-







-
+

-
+



-
+

-
+



-
+

-
+

-









-
-







name = "futures"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"

[[package]]
name = "futures"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e"
dependencies = [
 "futures-channel",
 "futures-core",
 "futures-executor",
 "futures-io",
 "futures-sink",
 "futures-task",
 "futures-util",
]

[[package]]
name = "futures-channel"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27"
dependencies = [
 "futures-core",
 "futures-sink",
]

[[package]]
name = "futures-core"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"

[[package]]
name = "futures-cpupool"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
dependencies = [
 "futures 0.1.31",
 "num_cpus",
]

[[package]]
name = "futures-executor"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97"
dependencies = [
 "futures-core",
 "futures-task",
 "futures-util",
]

[[package]]
name = "futures-intrusive"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e"
dependencies = [
 "futures-core",
 "lock_api 0.4.5",
 "parking_lot 0.11.2",
]

[[package]]
name = "futures-io"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11"

[[package]]
name = "futures-macro"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd"
dependencies = [
 "autocfg 1.0.1",
 "proc-macro-hack",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "futures-sink"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af"

[[package]]
name = "futures-task"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"

[[package]]
name = "futures-util"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e"
dependencies = [
 "autocfg 1.0.1",
 "futures-channel",
 "futures-core",
 "futures-io",
 "futures-macro",
 "futures-sink",
 "futures-task",
 "memchr",
 "pin-project-lite",
 "pin-utils",
 "proc-macro-hack",
 "proc-macro-nested",
 "slab",
]

[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
1153
1154
1155
1156
1157
1158
1159
1160

1161
1162

1163
1164
1165
1166
1167
1168
1169
1148
1149
1150
1151
1152
1153
1154

1155
1156

1157
1158
1159
1160
1161
1162
1163
1164







-
+

-
+







name = "ipnet"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"

[[package]]
name = "itertools"
version = "0.10.1"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
dependencies = [
 "either",
]

[[package]]
name = "itoa"
version = "0.4.8"
1206
1207
1208
1209
1210
1211
1212
1213

1214
1215

1216
1217
1218
1219
1220
1221
1222
1201
1202
1203
1204
1205
1206
1207

1208
1209

1210
1211
1212
1213
1214
1215
1216
1217







-
+

-
+







 "cfg-if 1.0.0",
 "ryu",
 "static_assertions",
]

[[package]]
name = "libc"
version = "0.2.107"
version = "0.2.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"

[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"

1643
1644
1645
1646
1647
1648
1649
1650

1651
1652

1653
1654
1655
1656
1657
1658
1659
1660
1661
1662


1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1638
1639
1640
1641
1642
1643
1644

1645
1646

1647
1648
1649
1650
1651
1652
1653
1654
1655


1656
1657
1658


1659











1660
1661
1662
1663
1664
1665
1666







-
+

-
+








-
-
+
+

-
-
+
-
-
-
-
-
-
-
-
-
-
-







name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"

[[package]]
name = "pkg-config"
version = "0.3.22"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
checksum = "d1a3ea4f0dd7f1f3e512cf97bf100819aa547f36a6eccac8dbaae839eb92363e"

[[package]]
name = "ppv-lite86"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"

[[package]]
name = "proc-macro-hack"
version = "0.5.19"
name = "proc-macro2"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"

checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a"
[[package]]
name = "proc-macro-nested"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"

[[package]]
name = "proc-macro2"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
 "unicode-xid",
]

[[package]]
name = "publicsuffix"
version = "1.5.6"
1996
1997
1998
1999
2000
2001
2002
2003

2004
2005

2006
2007
2008
2009
2010
2011
2012
1979
1980
1981
1982
1983
1984
1985

1986
1987

1988
1989
1990
1991
1992
1993
1994
1995







-
+

-
+







 "url 1.7.2",
 "uuid",
 "winreg 0.6.2",
]

[[package]]
name = "reqwest"
version = "0.11.6"
version = "0.11.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280"
checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5"
dependencies = [
 "async-compression",
 "base64 0.13.0",
 "bytes 1.1.0",
 "encoding_rs",
 "futures-core",
 "futures-util",
2044
2045
2046
2047
2048
2049
2050
2051

2052
2053
2054
2055
2056
2057

2058
2059
2060
2061

2062
2063
2064
2065
2066
2067
2068
2027
2028
2029
2030
2031
2032
2033

2034
2035
2036
2037
2038
2039

2040
2041
2042
2043

2044
2045
2046
2047
2048
2049
2050
2051







-
+





-
+



-
+







 "derive_builder 0.9.0",
 "quick-xml 0.17.2",
 "reqwest 0.9.24",
]

[[package]]
name = "rsstg"
version = "0.2.3"
version = "0.2.4"
dependencies = [
 "anyhow",
 "atom_syndication",
 "chrono",
 "config",
 "futures 0.3.17",
 "futures 0.3.18",
 "futures-util",
 "lazy_static",
 "regex",
 "reqwest 0.11.6",
 "reqwest 0.11.7",
 "rss",
 "sedregex",
 "sqlx",
 "telegram-bot",
 "tokio 1.14.0",
]

2085
2086
2087
2088
2089
2090
2091
2092

2093
2094

2095
2096
2097
2098
2099
2100
2101
2068
2069
2070
2071
2072
2073
2074

2075
2076

2077
2078
2079
2080
2081
2082
2083
2084







-
+

-
+







checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
 "semver",
]

[[package]]
name = "ryu"
version = "1.0.5"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568"

[[package]]
name = "schannel"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
dependencies = [
2202
2203
2204
2205
2206
2207
2208
2209

2210
2211

2212
2213
2214
2215
2216
2217
2218
2185
2186
2187
2188
2189
2190
2191

2192
2193

2194
2195
2196
2197
2198
2199
2200
2201







-
+

-
+







 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "serde_json"
version = "1.0.71"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19"
checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
dependencies = [
 "itoa",
 "ryu",
 "serde 1.0.130",
]

[[package]]
2439
2440
2441
2442
2443
2444
2445
2446

2447
2448

2449
2450
2451
2452
2453
2454
2455
2422
2423
2424
2425
2426
2427
2428

2429
2430

2431
2432
2433
2434
2435
2436
2437
2438







-
+

-
+







name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"

[[package]]
name = "syn"
version = "1.0.81"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-xid",
]

[[package]]
2466
2467
2468
2469
2470
2471
2472
2473

2474
2475
2476
2477
2478
2479
2480
2449
2450
2451
2452
2453
2454
2455

2456
2457
2458
2459
2460
2461
2462
2463







-
+








[[package]]
name = "telegram-bot"
version = "0.9.0"
source = "git+https://github.com/telegram-rs/telegram-bot#65ad5cfd578e9a1260ce6daac714eb2153c0bec7"
dependencies = [
 "bytes 1.1.0",
 "futures 0.3.17",
 "futures 0.3.18",
 "hyper 0.14.15",
 "hyper-tls 0.5.0",
 "multipart",
 "telegram-bot-raw",
 "tokio 1.14.0",
 "tracing",
 "tracing-futures",
3018
3019
3020
3021
3022
3023
3024
3025

3026
3027

3028
3029
3030
3031
3032
3033
3034
3001
3002
3003
3004
3005
3006
3007

3008
3009

3010
3011
3012
3013
3014
3015
3016
3017







-
+

-
+







dependencies = [
 "js-sys",
 "wasm-bindgen",
]

[[package]]
name = "whoami"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c33ac5ee236a4efbf2c98967e12c6cc0c51d93a744159a52957ba206ae6ef5f7"
checksum = "524b58fa5a20a2fb3014dd6358b70e6579692a56ef6fce928834e488f42f65e8"
dependencies = [
 "wasm-bindgen",
 "web-sys",
]

[[package]]
name = "winapi"
1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







[package]
name = "rsstg"
version = "0.2.3"
version = "0.2.4"
authors = ["arcade"]
edition = "2018"

[dependencies]
anyhow = "*"
atom_syndication = { version = "*", features = [ "with-serde" ] }
chrono = "*"
Modified rsstg.sql from [3e04f7b829] to [b4b5fc5ff8].
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18










-
+







create table rsstg_updates (owner integer, update jsonb);

create unique index rsstg_updates__id on rsstg_updates(update->>'update_id');

create table rsstg_source (
	source_id serial,
	channel text not null,
	channel_id integer not null,
	url text not null,
	last_scrape not null timestamptz default now(),
	enabled boolean not null default false,
	enabled boolean not null default true,
	iv_hash text,
	owner bigint not null);
create unique index rsstg_source__source_id on rsstg_source(source_id);
create unique index rsstg_source__channel_id__owner on rsstg_source(channel_id, owner);
create index rsstg_source__owner on rsstg_source(owner);

create table rsstg_post (
18
19
20
21
22
23
24
25

26
27
28
29
30

31
32
33

34
35
36
37
38
39
40
41
18
19
20
21
22
23
24

25
26
27
28
29

30

31

32

33
34
35
36
37
38
39







-
+




-
+
-

-
+
-







pub async fn list(core: &Core, sender: telegram_bot::UserId) -> Result<()> {
	core.send(core.list(sender).await?, Some(sender), Some(telegram_bot::types::ParseMode::MarkdownV2))?;
	Ok(())
}

pub async fn command(core: &Core, sender: telegram_bot::UserId, command: Vec<&str>) -> Result<()> {
	core.send( match &command[1].parse::<i32>() {
		Err(err) => format!("I need a number\\.\n{}", &err),
		Err(err) => format!("I need a number\\.\n{}", &err).into(),
		Ok(number) => match command[0] {
			"/check" => core.check(&number, sender, false).await
				.context("Channel check failed.")?,
			"/clean" => core.clean(&number, sender).await?,
			"/enable" => core.enable(&number, sender).await?
			"/enable" => core.enable(&number, sender).await?.into(),
				.to_string(),
			"/delete" => core.delete(&number, sender).await?,
			"/disable" => core.disable(&number, sender).await?
			"/disable" => core.disable(&number, sender).await?.into(),
				.to_string(),
			_ => bail!("Command {} not handled.", &command[0]),
		},
	}, Some(sender), None)?;
	Ok(())
}

pub async fn update(core: &Core, sender: telegram_bot::UserId, command: Vec<&str>) -> Result<()> {
85
86
87
88
89
90
91

92
93


94
95
96
97
98
99
100
83
84
85
86
87
88
89
90


91
92
93
94
95
96
97
98
99







+
-
-
+
+







					let _url_rex = ReplaceCommand::new(thing).context("Regexp parsing error:")?;
					Some(thing)
				}
			}
		},
		None => None,
	};
	let s_channel = &channel.to_string();
	let channel_id = i64::from(core.tg.send(telegram_bot::GetChat::new(telegram_bot::types::ChatRef::ChannelUsername(channel.to_string()))).await?.id());
	let chan_adm = core.tg.send(telegram_bot::GetChatAdministrators::new(telegram_bot::types::ChatRef::ChannelUsername(channel.to_string()))).await
	let channel_id = i64::from(core.tg.send(telegram_bot::GetChat::new(telegram_bot::types::ChatRef::ChannelUsername(s_channel.into()))).await?.id());
	let chan_adm = core.tg.send(telegram_bot::GetChatAdministrators::new(telegram_bot::types::ChatRef::ChannelUsername(s_channel.into()))).await
		.context("Sorry, I have no access to that chat.")?;
	let (mut me, mut user) = (false, false);
	for admin in chan_adm {
		if admin.user.id == core.my.id {
			me = true;
		};
		if admin.user.id == sender {
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
+







		self.tg.spawn(telegram_bot::SendMessage::new(match target {
			Some(user) => user,
			None => self.owner_chat,
		}, msg).parse_mode(parse_mode));
		Ok(())
	}

	pub async fn check<S>(&self, id: &i32, owner: S, real: bool) -> Result<String>
	pub async fn check<S>(&self, id: &i32, owner: S, real: bool) -> Result<Cow<'_, str>>
	where S: Into<i64> {
		let owner = owner.into();

		let mut posted: i32 = 0;
		let id = {
			let mut set = self.sources.lock().unwrap();
			match set.get(id) {
148
149
150
151
152
153
154
155
156
157



158
159
160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209


210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226


227
228
229
230
231
232
233
148
149
150
151
152
153
154



155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195

196
197
198
199
200
201
202
203
204
205
206
207


208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224


225
226
227
228
229
230
231
232
233







-
-
-
+
+
+


-
+
















-
+















-
+


-
+











-
-
+
+



-
+











-
-
+
+







					rss::Error::Eof => (),
					_ => bail!("Unsupported or mangled content:\n{:?}\n{:#?}\n{:#?}\n", &url, err, status)
				}
			};
			for (date, url) in posts.iter() {
				let mut conn = self.pool.acquire().await
					.with_context(|| format!("Check post fetch conn:\n{:?}", &self.pool))?;
				let post_url = match url_re {
					Some(ref x) => x.execute(url).to_string(),
					None => url.to_string(),
				let post_url: Cow<str> = match url_re {
					Some(ref x) => x.execute(url).into(),
					None => url.into(),
				};
				let row = sqlx::query("select exists(select true from rsstg_post where url = $1 and source_id = $2) as exists;")
					.bind(&post_url)
					.bind(&*post_url)
					.bind(*id)
					.fetch_one(&mut conn).await
					.with_context(|| format!("Check post:\n{:?}", &conn))?;
				let exists: bool = row.try_get("exists")?;
				if ! exists {
					if this_fetch == None || *date > this_fetch.unwrap() {
						this_fetch = Some(*date);
					};
					self.tg.send( match iv_hash {
							Some(hash) => telegram_bot::SendMessage::new(destination, format!("<a href=\"https://t.me/iv?url={}&rhash={}\"> </a>{0}", &post_url, hash)),
							None => telegram_bot::SendMessage::new(destination, format!("{}", post_url)),
						}.parse_mode(telegram_bot::types::ParseMode::Html)).await
						.context("Can't post message:")?;
					sqlx::query("insert into rsstg_post (source_id, posted, url) values ($1, $2, $3);")
						.bind(*id)
						.bind(date)
						.bind(post_url)
						.bind(&*post_url)
						.execute(&mut conn).await
						.with_context(|| format!("Record post:\n{:?}", &conn))?;
					drop(conn);
					tokio::time::sleep(std::time::Duration::new(4, 0)).await;
				};
				posted += 1;
			};
			posts.clear();
		};
		let mut conn = self.pool.acquire().await
			.with_context(|| format!("Update scrape fetch conn:\n{:?}", &self.pool))?;
		sqlx::query("update rsstg_source set last_scrape = now() where source_id = $1;")
			.bind(*id)
			.execute(&mut conn).await
			.with_context(|| format!("Update scrape:\n{:?}", &conn))?;
		Ok(format!("Posted: {}", &posted))
		Ok(format!("Posted: {}", &posted).into())
	}

	pub async fn delete<S>(&self, source_id: &i32, owner: S) -> Result<String>
	pub async fn delete<S>(&self, source_id: &i32, owner: S) -> Result<Cow<'_, str>>
	where S: Into<i64> {
		let owner = owner.into();

		let mut conn = self.pool.acquire().await
			.with_context(|| format!("Delete fetch conn:\n{:?}", &self.pool))?;
		match sqlx::query("delete from rsstg_source where source_id = $1 and owner = $2;")
			.bind(source_id)
			.bind(owner)
			.execute(&mut conn).await
			.with_context(|| format!("Delete source rule:\n{:?}", &self.pool))?
			.rows_affected() {
			0 => { Ok("No data found found.".to_string()) },
			x => { Ok(format!("{} sources removed.", x)) },
			0 => { Ok("No data found found.".into()) },
			x => { Ok(format!("{} sources removed.", x).into()) },
		}
	}

	pub async fn clean<S>(&self, source_id: &i32, owner: S) -> Result<String>
	pub async fn clean<S>(&self, source_id: &i32, owner: S) -> Result<Cow<'_, str>>
	where S: Into<i64> {
		let owner = owner.into();

		let mut conn = self.pool.acquire().await
			.with_context(|| format!("Clean fetch conn:\n{:?}", &self.pool))?;
		match sqlx::query("delete from rsstg_post p using rsstg_source s where p.source_id = $1 and owner = $2 and p.source_id = s.source_id;")
			.bind(source_id)
			.bind(owner)
			.execute(&mut conn).await
			.with_context(|| format!("Clean seen posts:\n{:?}", &self.pool))?
			.rows_affected() {
			0 => { Ok("No data found found.".to_string()) },
			x => { Ok(format!("{} posts purged.", x)) },
			0 => { Ok("No data found found.".into()) },
			x => { Ok(format!("{} posts purged.", x).into()) },
		}
	}

	pub async fn enable<S>(&self, source_id: &i32, owner: S) -> Result<&str>
	where S: Into<i64> {
		let owner = owner.into();

259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273







-
+







			.rows_affected() {
			1 => { Ok("Source disabled.") },
			0 => { Ok("Source not found.") },
			_ => { Err(anyhow!("Database error.")) },
		}
	}

	pub async fn update<S>(&self, update: Option<i32>, channel: &str, channel_id: i64, url: &str, iv_hash: Option<&str>, url_re: Option<&str>, owner: S) -> Result<String>
	pub async fn update<S>(&self, update: Option<i32>, channel: &str, channel_id: i64, url: &str, iv_hash: Option<&str>, url_re: Option<&str>, owner: S) -> Result<&str>
	where S: Into<i64> {
		let owner = owner.into();

		let mut conn = self.pool.acquire().await
			.with_context(|| format!("Update fetch conn:\n{:?}", &self.pool))?;

		match match update {
281
282
283
284
285
286
287
288

289
290
291

292
293
294
295

296
297
298

299
300
301

302
303
304
305
306
307
308
281
282
283
284
285
286
287

288
289
290

291
292
293
294

295
296
297

298
299
300

301
302
303
304
305
306
307
308







-
+


-
+



-
+


-
+


-
+







			.bind(channel_id)
			.bind(url)
			.bind(iv_hash)
			.bind(owner)
			.bind(channel)
			.bind(url_re)
			.execute(&mut conn).await {
			Ok(_) => return Ok(String::from(match update {
			Ok(_) => return Ok(match update {
				Some(_) => "Channel updated.",
				None => "Channel added.",
			})),
			}),
			Err(sqlx::Error::Database(err)) => {
				match err.downcast::<sqlx::postgres::PgDatabaseError>().routine() {
					Some("_bt_check_unique", ) => {
						return Ok("Duplicate key.".to_string())
						return Ok("Duplicate key.")
					},
					Some(_) => {
						return Ok("Database error.".to_string())
						return Ok("Database error.")
					},
					None => {
						return Ok("No database error extracted.".to_string())
						return Ok("No database error extracted.")
					},
				};
			},
			Err(err) => {
				bail!("Sorry, unknown error:\n{:#?}\n", err);
			},
		};
345
346
347
348
349
350
351
352

353
354
355

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

371
372

373
374
375

376
377
378
379
380
345
346
347
348
349
350
351

352
353
354

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

370
371

372
373
374

375
376
377
378
379
380







-
+


-
+














-
+

-
+


-
+





		}
	}

	pub async fn list<S>(&self, owner: S) -> Result<String>
	where S: Into<i64> {
		let owner = owner.into();

		let mut reply = vec![];
		let mut reply: Vec<Cow<str>> = vec![];
		let mut conn = self.pool.acquire().await
			.with_context(|| format!("List fetch conn:\n{:?}", &self.pool))?;
		reply.push("Channels:".to_string());
		reply.push("Channels:".into());
		let rows = sqlx::query("select source_id, channel, enabled, url, iv_hash, url_re from rsstg_source where owner = $1 order by source_id")
			.bind(owner)
			.fetch_all(&mut conn).await?;
		for row in rows.iter() {
			let source_id: i32 = row.try_get("source_id")?;
			let username: &str = row.try_get("channel")?;
			let enabled: bool = row.try_get("enabled")?;
			let url: &str = row.try_get("url")?;
			let iv_hash: Option<&str> = row.try_get("iv_hash")?;
			let url_re: Option<&str> = row.try_get("url_re")?;
			reply.push(format!("\n\\#ļøāƒ£ {} \\*ļøāƒ£ `{}` {}\nšŸ”— `{}`", source_id, username,  
				match enabled {
					true  => "šŸ”„ enabled",
					false => "ā›” disabled",
				}, url));
				}, url).into());
			if let Some(hash) = iv_hash {
				reply.push(format!("IV: `{}`", hash));
				reply.push(format!("IV: `{}`", hash).into());
			}
			if let Some(re) = url_re {
				reply.push(format!("RE: `{}`", re));
				reply.push(format!("RE: `{}`", re).into());
			}
		};
		Ok(reply.join("\n"))
	}
}