18 Commits

Author SHA1 Message Date
VC
3413f49d08 Update README.md 2023-07-13 09:02:57 +00:00
VC
d4fbccc69b Merge branch 'youpi' into 'master'
Update file README.md

See merge request veretcle/scootaloo!57
2023-07-13 08:57:08 +00:00
VC
058a07865d Update file README.md 2023-07-13 08:53:54 +00:00
VC
c6a29d1d7d Merge branch 'doc_correct' into 'master'
doc: update example regexp

See merge request veretcle/scootaloo!55
2023-02-10 08:53:08 +00:00
VC
3692d6e51f doc: update example regexp 2023-02-10 09:40:42 +01:00
VC
5fe57f189a Merge branch 'feat_wait_for_upload' into 'master'
Feat wait for upload

See merge request veretcle/scootaloo!54
2023-02-09 14:51:14 +00:00
VC
83c398cebf feat: wait 1 full sec between loop when uploading big media 2023-02-09 15:19:22 +01:00
VC
8f567ed6b4 chore: bump version 2023-02-09 15:18:12 +01:00
VC
d7431862ba Merge branch 'fix_copy_lang' into 'master'
Fix copy lang

See merge request veretcle/scootaloo!53
2023-02-09 14:12:25 +00:00
VC
f3b13eb62f refactor: conforms to clippy 1.67 recommandations 2023-02-09 11:32:22 +01:00
VC
6b68c8e299 fix: no need for defaults with clap v4 2023-02-09 11:31:58 +01:00
VC
0bb5eabdac fix: copy the original lang from Twitter to Mastodon 2023-02-09 10:58:34 +01:00
VC
3d44bbfb86 refactor: remove isolang, bump version 2023-02-09 10:58:12 +01:00
VC
9a03c7681b Merge branch 'fix_attachment' into 'master'
Fix attachment

See merge request veretcle/scootaloo!52
2023-01-09 11:51:41 +00:00
VC
a8a8f8c13f fix: wait until media is uploaded 2023-01-09 12:45:38 +01:00
VC
90a9df220a chore: bump version to 1.1.4, megalodon to 0.3.6 2023-01-09 12:45:18 +01:00
VC
6218c59ce5 Merge branch 'feat_fields' into 'master'
Feat fields

See merge request veretcle/scootaloo!51
2022-12-27 14:46:21 +00:00
VC
6ffcbfc89a feat: add links in fields attribute 2022-12-27 15:31:12 +01:00
10 changed files with 177 additions and 187 deletions

228
Cargo.lock generated
View File

@@ -33,9 +33,9 @@ dependencies = [
[[package]]
name = "async-trait"
version = "0.1.59"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364"
checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3"
dependencies = [
"proc-macro2",
"quote",
@@ -109,9 +109,9 @@ checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
[[package]]
name = "cc"
version = "1.0.77"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
[[package]]
name = "cfg-if"
@@ -137,9 +137,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.0.29"
version = "4.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d"
checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
dependencies = [
"bitflags",
"clap_lex",
@@ -231,9 +231,9 @@ dependencies = [
[[package]]
name = "cxx"
version = "1.0.82"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453"
checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd"
dependencies = [
"cc",
"cxxbridge-flags",
@@ -243,9 +243,9 @@ dependencies = [
[[package]]
name = "cxx-build"
version = "1.0.82"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0"
checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0"
dependencies = [
"cc",
"codespan-reporting",
@@ -258,15 +258,15 @@ dependencies = [
[[package]]
name = "cxxbridge-flags"
version = "1.0.82"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71"
checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59"
[[package]]
name = "cxxbridge-macro"
version = "1.0.82"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470"
checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6"
dependencies = [
"proc-macro2",
"quote",
@@ -326,7 +326,7 @@ dependencies = [
"regex",
"serde",
"serde_json",
"sha-1 0.9.8",
"sha-1",
"thiserror",
"tokio",
"url",
@@ -604,9 +604,9 @@ dependencies = [
[[package]]
name = "html-escape"
version = "0.2.12"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15315cfa9503e9aa85a477138eff76a1b203a430703548052c330b69d8d8c205"
checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476"
dependencies = [
"utf8-width",
]
@@ -671,9 +671,9 @@ dependencies = [
[[package]]
name = "hyper-rustls"
version = "0.23.1"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59df7c4e19c950e6e0e868dcc0a300b09a9b88e9ec55bd879ca819087a77355d"
checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
dependencies = [
"http",
"hyper",
@@ -760,15 +760,15 @@ dependencies = [
[[package]]
name = "ipnet"
version = "2.5.1"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745"
checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e"
[[package]]
name = "is-terminal"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
dependencies = [
"hermit-abi 0.2.6",
"io-lifetimes",
@@ -776,20 +776,11 @@ dependencies = [
"windows-sys 0.42.0",
]
[[package]]
name = "isolang"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b64fd6448ee8a45ce6e4365c58e4fa7d8740cba2ed70db3e9ab4879ebd93eaaa"
dependencies = [
"phf",
]
[[package]]
name = "itoa"
version = "1.0.4"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "js-sys"
@@ -808,9 +799,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.137"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "libsqlite3-sys"
@@ -824,18 +815,18 @@ dependencies = [
[[package]]
name = "link-cplusplus"
version = "1.0.7"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
dependencies = [
"cc",
]
[[package]]
name = "linux-raw-sys"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "lock_api"
@@ -858,12 +849,13 @@ dependencies = [
[[package]]
name = "megalodon"
version = "0.2.5"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c871fd0f7cfb5ea5f41322e31d86d2cb7f964e01e57e6399bb31fd602bf050a"
checksum = "3b39bd378603a46216457c1c95c54f8dec37959a02c06a59cc33d00fc71a0ba0"
dependencies = [
"async-trait",
"chrono",
"futures-util",
"hex",
"log",
"oauth2",
@@ -873,8 +865,8 @@ dependencies = [
"sha1",
"thiserror",
"tokio",
"tokio-tungstenite",
"tokio-util",
"tungstenite",
"url",
"urlencoding",
]
@@ -952,11 +944,11 @@ dependencies = [
[[package]]
name = "num_cpus"
version = "1.14.0"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi 0.1.19",
"hermit-abi 0.2.6",
"libc",
]
@@ -1003,9 +995,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl"
version = "0.10.43"
version = "0.10.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "020433887e44c27ff16365eaa2d380547a94544ad509aff6eb5b6e3e0b27b376"
checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1"
dependencies = [
"bitflags",
"cfg-if",
@@ -1035,9 +1027,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.78"
version = "0.9.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07d5c8cb6e57b3a3612064d7b18b117912b4ce70955c2504d4b741c9e244b132"
checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7"
dependencies = [
"autocfg",
"cc",
@@ -1081,24 +1073,6 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]]
name = "phf"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_shared"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
@@ -1125,18 +1099,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.47"
version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
@@ -1291,9 +1265,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.36.4"
version = "0.36.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb93e85278e08bb5788653183213d3a60fc242b10cb9be96586f5a73dcb67c23"
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
dependencies = [
"bitflags",
"errno",
@@ -1326,9 +1300,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.11"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "schannel"
@@ -1342,14 +1316,13 @@ dependencies = [
[[package]]
name = "scootaloo"
version = "1.1.2"
version = "1.1.6"
dependencies = [
"base64",
"clap",
"egg-mode",
"futures",
"html-escape",
"isolang",
"log",
"megalodon",
"mime",
@@ -1370,9 +1343,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "scratch"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
[[package]]
name = "sct"
@@ -1409,24 +1382,24 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.14"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
[[package]]
name = "serde"
version = "1.0.148"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.148"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [
"proc-macro2",
"quote",
@@ -1435,9 +1408,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.89"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
dependencies = [
"itoa",
"ryu",
@@ -1446,9 +1419,9 @@ dependencies = [
[[package]]
name = "serde_path_to_error"
version = "0.1.8"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "184c643044780f7ceb59104cef98a5a6f12cb2288a7bc701ab93a362b49fd47d"
checksum = "26b04f22b563c91331a10074bda3dd5492e3cc39d56bd557e91c0af42b6c7341"
dependencies = [
"serde",
]
@@ -1478,17 +1451,6 @@ dependencies = [
"opaque-debug",
]
[[package]]
name = "sha-1"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c"
dependencies = [
"cfg-if",
"cpufeatures",
"digest 0.10.6",
]
[[package]]
name = "sha1"
version = "0.10.5"
@@ -1533,12 +1495,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]]
name = "slab"
version = "0.4.7"
@@ -1584,9 +1540,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.104"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
@@ -1618,18 +1574,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
@@ -1693,9 +1649,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.22.0"
version = "1.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3"
checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
dependencies = [
"autocfg",
"bytes",
@@ -1708,14 +1664,14 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
"winapi",
"windows-sys 0.42.0",
]
[[package]]
name = "tokio-macros"
version = "1.8.1"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ec8ecbbb74d42a8dd0ce8ea9bfc38ad13e2ed5203c4f272dbe144f4e17d70ac"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
@@ -1743,6 +1699,20 @@ dependencies = [
"webpki",
]
[[package]]
name = "tokio-tungstenite"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd"
dependencies = [
"futures-util",
"log",
"native-tls",
"tokio",
"tokio-native-tls",
"tungstenite",
]
[[package]]
name = "tokio-util"
version = "0.7.4"
@@ -1759,9 +1729,9 @@ dependencies = [
[[package]]
name = "toml"
version = "0.5.9"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f"
dependencies = [
"serde",
]
@@ -1800,9 +1770,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "tungstenite"
version = "0.17.3"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788"
dependencies = [
"base64",
"byteorder",
@@ -1812,7 +1782,7 @@ dependencies = [
"log",
"native-tls",
"rand",
"sha-1 0.10.1",
"sha1",
"thiserror",
"url",
"utf-8",
@@ -1820,9 +1790,9 @@ dependencies = [
[[package]]
name = "typenum"
version = "1.15.0"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "unicase"
@@ -1841,9 +1811,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
version = "1.0.5"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "unicode-normalization"
@@ -2018,9 +1988,9 @@ dependencies = [
[[package]]
name = "webpki-roots"
version = "0.22.5"
version = "0.22.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be"
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
dependencies = [
"webpki",
]

View File

@@ -1,6 +1,6 @@
[package]
name = "scootaloo"
version = "1.1.2"
version = "1.1.6"
authors = ["VC <veretcle+framagit@mateu.be>"]
edition = "2021"
@@ -14,10 +14,9 @@ toml = "^0.5"
clap = "^4"
egg-mode = "^0.16"
rusqlite = "^0.27"
isolang = "^2"
tokio = { version = "^1", features = ["rt"]}
futures = "^0.3"
megalodon = "^0.2"
megalodon = "^0.3.6"
html-escape = "^0.2"
reqwest = "^0.11"
log = "^0.4"

View File

@@ -1,3 +1,9 @@
**Due to the new Twitter policy about API v1.1 and API v2, this project will no longer be updated as it no longer can work for free any way, shape or form.**
First of all, Im deeply sorry about that. It worked pretty great for what it did with a level of quality Im very proud to have achieved.
Secondly, fuck you Musk, fuck you.
A Twitter to Mastodon copy bot written in Rust
It:
@@ -25,7 +31,7 @@ rate_limiting = 4 ## optional, default 4, number of accounts handled simultaneou
## this parameter allows you to catch such URLs and apply the `display_url` (i.e. `tout.es`) instead of the `expanded_url` (i.e. `http://tout.es`)
## in those particular cases
## (!) use with caution, it might have some undesired effects
show_url_as_display_url_for = "^http(s)://(.+)\\.es$"
show_url_as_display_url_for = "^https?://(.+)\\.es$"
## optional, this allows you to replace the host for popular services such as YouTube of Twitter, or any other
## with their more freely accessible equivalent
[scootaloo.alternative_services_for]
@@ -83,22 +89,20 @@ You can then run the application via `cron` for example. Here is the generic usa
```sh
A Twitter to Mastodon bot
USAGE:
scootaloo [OPTIONS] [SUBCOMMAND]
Usage: scootaloo [OPTIONS] [COMMAND]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-c, --config <CONFIG_FILE> TOML config file for scootaloo (default /usr/local/etc/scootaloo.toml)
-l, --loglevel <LOGLEVEL> Log level.Valid values are: Off, Warn, Error, Info, Debug
SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
Commands:
register Command to register to a Mastodon Instance
init Command to init Scootaloo DB
migrate Command to migrate Scootaloo DB
register Command to register to a Mastodon Instance
copyprofile Command to copy a Twitter profile into Mastodon
help Print this message or the help of the given subcommand(s)
Options:
-c, --config <CONFIG_FILE> TOML config file for scootaloo [default: /usr/local/etc/scootaloo.toml]
-l, --loglevel <LOGLEVEL> Log level [possible values: Off, Warn, Error, Info, Debug]
-h, --help Print help information
-V, --version Print version information
```
# Quirks

View File

@@ -43,10 +43,10 @@ pub struct ScootalooConfig {
/// Parses the TOML file into a Config Struct
pub fn parse_toml(toml_file: &str) -> Config {
let toml_config = read_to_string(toml_file)
.unwrap_or_else(|e| panic!("Cannot open config file {}: {}", toml_file, e));
.unwrap_or_else(|e| panic!("Cannot open config file {toml_file}: {e}"));
let config: Config = toml::from_str(&toml_config)
.unwrap_or_else(|e| panic!("Cannot parse TOML file {}: {}", toml_file, e));
.unwrap_or_else(|e| panic!("Cannot parse TOML file {toml_file}: {e}"));
config
}

View File

@@ -30,12 +30,12 @@ impl Display for ScootalooError {
impl From<Box<dyn Error>> for ScootalooError {
fn from(error: Box<dyn Error>) -> Self {
ScootalooError::new(&format!("Error in a subset crate: {}", error))
ScootalooError::new(&format!("Error in a subset crate: {error}"))
}
}
impl From<megalodonError> for ScootalooError {
fn from(error: megalodonError) -> Self {
ScootalooError::new(&format!("Error in megalodon crate: {}", error))
ScootalooError::new(&format!("Error in megalodon crate: {error}"))
}
}

View File

@@ -21,7 +21,6 @@ use state::{read_state, write_state, TweetToToot};
use futures::StreamExt;
use html_escape::decode_html_entities;
use isolang::Language;
use log::info;
use megalodon::{
megalodon::PostStatusInputOptions, megalodon::UpdateCredentialsInputOptions, Megalodon,
@@ -204,9 +203,7 @@ pub async fn run(config: Config) {
// language if any
if let Some(l) = &tweet.lang {
if let Some(r) = Language::from_639_1(l) {
post_status.language = Some(r.to_string());
}
post_status.language = Some(l.to_string());
}
// can be activated for test purposes
@@ -238,8 +235,8 @@ pub async fn run(config: Config) {
// launch and wait for every handle
while let Some(result) = stream.next().await {
match result {
Ok(Err(e)) => eprintln!("Error within thread: {}", e),
Err(e) => eprintln!("Error with thread: {}", e),
Ok(Err(e)) => eprintln!("Error within thread: {e}"),
Err(e) => eprintln!("Error with thread: {e}"),
_ => (),
}
}
@@ -268,7 +265,7 @@ pub async fn profile(config: Config, bot: Option<bool>) {
&twitter_user.entities.description.urls,
);
// let fields_attributes = get_attribute_from_url(&twitter_user.entities.url);
let fields_attributes = get_attribute_from_url(&twitter_user.entities.url);
let display_name = Some(String::from_utf16_lossy(
&twitter_user
@@ -284,7 +281,6 @@ pub async fn profile(config: Config, bot: Option<bool>) {
};
let update_creds = UpdateCredentialsInputOptions {
discoverable: None,
bot,
display_name,
note,
@@ -293,9 +289,8 @@ pub async fn profile(config: Config, bot: Option<bool>) {
.await?,
),
header,
locked: None,
source: None,
fields_attributes: None,
fields_attributes,
..Default::default()
};
let mastodon = get_mastodon_token(&mastodon_config);
@@ -309,8 +304,8 @@ pub async fn profile(config: Config, bot: Option<bool>) {
while let Some(result) = stream.next().await {
match result {
Ok(Err(e)) => eprintln!("Error within thread: {}", e),
Err(e) => eprintln!("Error with thread: {}", e),
Ok(Err(e)) => eprintln!("Error within thread: {e}"),
Err(e) => eprintln!("Error with thread: {e}"),
_ => (),
}
}

View File

@@ -63,10 +63,7 @@ fn main() {
.short('c')
.long("config")
.value_name("CONFIG_FILE")
.help(&format!(
"TOML config file for scootaloo (default {})",
DEFAULT_CONFIG_PATH
))
.help("TOML config file for scootaloo")
.default_value(DEFAULT_CONFIG_PATH)
.num_args(1)
.display_order(1),
@@ -81,7 +78,7 @@ fn main() {
.short('c')
.long("config")
.value_name("CONFIG_FILE")
.help(&format!("TOML config file for scootaloo (default {})", DEFAULT_CONFIG_PATH))
.help("TOML config file for scootaloo")
.default_value(DEFAULT_CONFIG_PATH)
.num_args(1)
.display_order(1),
@@ -104,7 +101,7 @@ fn main() {
.short('c')
.long("config")
.value_name("CONFIG_FILE")
.help(&format!("TOML config file for scootaloo (default {})", DEFAULT_CONFIG_PATH))
.help("TOML config file for scootaloo")
.default_value(DEFAULT_CONFIG_PATH)
.num_args(1)
.display_order(1),

View File

@@ -83,7 +83,7 @@ pub fn associate_urls(urls: &[UrlEntity], re: &Option<Regex>) -> HashMap<String,
pub fn replace_alt_services(urls: &mut HashMap<String, String>, alts: &HashMap<String, String>) {
for val in urls.values_mut() {
for (k, v) in alts {
*val = val.replace(&format!("/{}/", k), &format!("/{}/", v));
*val = val.replace(&format!("/{k}/"), &format!("/{v}/"));
}
}
}
@@ -120,7 +120,7 @@ pub fn replace_tweet_by_toot(
twitter_screen_name.to_lowercase(),
tweet_id
)) {
*val = format!("{}/@{}/{}", base_url, mastodon_screen_name, toot_id);
*val = format!("{base_url}/@{mastodon_screen_name}/{toot_id}");
}
}
}
@@ -141,7 +141,6 @@ pub fn get_note_from_description(t: &Option<String>, urls: &[UrlEntity]) -> Opti
}
/// Gets fields_attribute from UserEntityDetail
#[allow(dead_code)]
pub fn get_attribute_from_url(
user_entity_detail: &Option<UserEntityDetail>,
) -> Option<Vec<CredentialsFieldAttribute>> {
@@ -185,7 +184,7 @@ pub async fn register(host: &str, screen_name: &str) {
let url = app_data.url.expect("Cannot generate registration URI!");
println!("Click this link to authorize on Mastodon: {}", url);
println!("Click this link to authorize on Mastodon: {url}");
println!("Paste the returned authorization code: ");
let mut input = String::new();

View File

@@ -21,8 +21,8 @@ pub fn read_state(
) -> Result<Option<TweetToToot>, Box<dyn Error>> {
debug!("Reading tweet_id {:?}", s);
let query: String = match s {
Some(i) => format!("SELECT * FROM tweet_to_toot WHERE tweet_id = {} and twitter_screen_name = \"{}\"", i, n),
None => format!("SELECT * FROM tweet_to_toot WHERE twitter_screen_name = \"{}\" ORDER BY tweet_id DESC LIMIT 1", n),
Some(i) => format!("SELECT * FROM tweet_to_toot WHERE tweet_id = {i} and twitter_screen_name = \"{n}\""),
None => format!("SELECT * FROM tweet_to_toot WHERE twitter_screen_name = \"{n}\" ORDER BY tweet_id DESC LIMIT 1"),
};
let mut stmt = conn.prepare(&query)?;
@@ -78,8 +78,7 @@ pub fn migrate_db(d: &str, s: &str) -> Result<(), Box<dyn Error>> {
&format!(
"ALTER TABLE tweet_to_toot
ADD COLUMN twitter_screen_name TEXT NOT NULL
DEFAULT \"{}\"",
s
DEFAULT \"{s}\""
),
[],
);

View File

@@ -4,12 +4,18 @@ use base64::encode;
use egg_mode::tweet::Tweet;
use futures::{stream, stream::StreamExt};
use log::{error, info, warn};
use megalodon::{mastodon::Mastodon, megalodon::Megalodon};
use megalodon::{
entities::UploadMedia::{AsyncAttachment, Attachment},
error,
mastodon::Mastodon,
megalodon::Megalodon,
};
use reqwest::Url;
use std::error::Error;
use tokio::{
fs::{create_dir_all, remove_file, File},
io::copy,
time::{sleep, Duration},
};
/// Generate associative table between media ids and tweet extended entities
@@ -49,7 +55,12 @@ pub async fn generate_media_ids(
// it doesnt matter if we cant remove, cache_media fn is idempotent
remove_file(&local_tweet_media_path).await.ok();
Ok::<String, ScootalooError>(mastodon_media.id)
let id = match mastodon_media {
Attachment(m) => m.id,
AsyncAttachment(m) => wait_until_uploaded(&mastodon, &m.id).await?,
};
Ok::<String, ScootalooError>(id)
})
})
.buffered(4); // there are max four medias per tweet and they need to be treated in
@@ -72,6 +83,24 @@ pub async fn generate_media_ids(
(media_url, media_ids)
}
/// Wait on uploaded medias when necessary
async fn wait_until_uploaded(client: &Mastodon, id: &str) -> Result<String, error::Error> {
loop {
sleep(Duration::from_secs(1)).await;
let res = client.get_media(id.to_string()).await;
return match res {
Ok(res) => Ok(res.json.id),
Err(err) => match err {
error::Error::OwnError(ref own_err) => match own_err.kind {
error::Kind::HTTPPartialContentError => continue,
_ => Err(err),
},
_ => Err(err),
},
};
}
}
/// Transforms the media into a base64 equivalent
pub async fn base64_media(u: &str) -> Result<String, Box<dyn Error>> {
let mut response = reqwest::get(u).await?;
@@ -85,12 +114,12 @@ pub async fn base64_media(u: &str) -> Result<String, Box<dyn Error>> {
let content_type = response
.headers()
.get("content-type")
.ok_or_else(|| ScootalooError::new(&format!("Cannot get media content type for {}", u)))?
.ok_or_else(|| ScootalooError::new(&format!("Cannot get media content type for {u}")))?
.to_str()?;
let encoded_f = encode(buffer);
Ok(format!("data:{};base64,{}", content_type, encoded_f))
Ok(format!("data:{content_type};base64,{encoded_f}"))
}
/// Gets and caches Twitter Media inside the determined temp dir
@@ -107,19 +136,17 @@ pub async fn cache_media(u: &str, t: &str) -> Result<String, Box<dyn Error>> {
.path_segments()
.ok_or_else(|| {
ScootalooError::new(&format!(
"Cannot determine the destination filename for {}",
u
"Cannot determine the destination filename for {u}"
))
})?
.last()
.ok_or_else(|| {
ScootalooError::new(&format!(
"Cannot determine the destination filename for {}",
u
"Cannot determine the destination filename for {u}"
))
})?;
let dest_filepath = format!("{}/{}", t, dest_filename);
let dest_filepath = format!("{t}/{dest_filename}");
let mut dest_file = File::create(&dest_filepath).await?;