17 Commits

Author SHA1 Message Date
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
VC
3fdd81df50 Merge branch 'feat_links' into 'master'
feat: fields_attributes and note inside copyprofile

See merge request veretcle/scootaloo!50
2022-12-12 14:35:42 +00:00
VC
90f47079d9 fix: fields_attribute is busted so 🤷 2022-12-12 15:25:12 +01:00
VC
88b73f4bc5 chore: bump version 2022-12-12 15:25:12 +01:00
VC
87797c7ab0 feat: note inside copyprofile 2022-12-12 15:25:06 +01:00
10 changed files with 269 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.1"
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.1"
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

@@ -83,22 +83,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
Commands:
register Command to register to a Mastodon Instance
init Command to init Scootaloo DB
migrate Command to migrate Scootaloo DB
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.Valid values are: Off, Warn, Error, Info, Debug
SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
init Command to init Scootaloo DB
migrate Command to migrate Scootaloo DB
register Command to register to a Mastodon Instance
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}"),
_ => (),
}
}
@@ -263,6 +260,13 @@ pub async fn profile(config: Config, bot: Option<bool>) {
.user
.ok_or_else(|| ScootalooError::new("No user in Tweet!"))?;
let note = get_note_from_description(
&twitter_user.description,
&twitter_user.entities.description.urls,
);
let fields_attributes = get_attribute_from_url(&twitter_user.entities.url);
let display_name = Some(String::from_utf16_lossy(
&twitter_user
.name
@@ -277,18 +281,16 @@ pub async fn profile(config: Config, bot: Option<bool>) {
};
let update_creds = UpdateCredentialsInputOptions {
discoverable: None,
bot,
display_name,
note: twitter_user.description,
note,
avatar: Some(
base64_media(&twitter_user.profile_image_url_https.replace("_normal", ""))
.await?,
),
header,
locked: None,
source: None,
fields_attributes: None,
fields_attributes,
..Default::default()
};
let mastodon = get_mastodon_token(&mastodon_config);
@@ -302,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

@@ -1,7 +1,14 @@
use crate::config::MastodonConfig;
use egg_mode::entities::{MentionEntity, UrlEntity};
use megalodon::{generator, mastodon::Mastodon, megalodon::AppInputOptions};
use egg_mode::{
entities::{MentionEntity, UrlEntity},
user::UserEntityDetail,
};
use megalodon::{
generator,
mastodon::Mastodon,
megalodon::{AppInputOptions, CredentialsFieldAttribute},
};
use regex::Regex;
use std::{collections::HashMap, io::stdin};
@@ -76,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}/"));
}
}
}
@@ -113,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}");
}
}
}
@@ -123,6 +130,32 @@ pub fn get_mastodon_token(masto: &MastodonConfig) -> Mastodon {
Mastodon::new(masto.base.to_string(), Some(masto.token.to_string()), None)
}
/// Gets note from twitter_user description
pub fn get_note_from_description(t: &Option<String>, urls: &[UrlEntity]) -> Option<String> {
t.as_ref().map(|d| {
let mut n = d.to_owned();
let a_urls = associate_urls(urls, &None);
decode_urls(&mut n, &a_urls);
n
})
}
/// Gets fields_attribute from UserEntityDetail
pub fn get_attribute_from_url(
user_entity_detail: &Option<UserEntityDetail>,
) -> Option<Vec<CredentialsFieldAttribute>> {
user_entity_detail.as_ref().and_then(|u| {
u.urls.first().and_then(|v| {
v.expanded_url.as_ref().map(|e| {
vec![CredentialsFieldAttribute {
name: v.display_url.to_string(),
value: e.to_string(),
}]
})
})
})
}
/// Generic register function
/// As this function is supposed to be run only once, it will panic for every error it encounters
/// Most of this function is a direct copy/paste of the official `elefren` crate
@@ -151,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();
@@ -207,6 +240,63 @@ token = "{}""#,
mod tests {
use super::*;
#[test]
fn test_get_attribute_from_url() {
let expected_credentials_field_attribute = CredentialsFieldAttribute {
name: "Nintendojo.fr".to_string(),
value: "https://www.nintendojo.fr".to_string(),
};
let true_urls = vec![UrlEntity {
display_url: "Nintendojo.fr".to_string(),
expanded_url: Some("https://www.nintendojo.fr".to_string()),
range: (1, 3),
url: "https://t.me/balek".to_string(),
}];
let false_urls = vec![UrlEntity {
display_url: "Nintendojo.fr".to_string(),
expanded_url: None,
range: (1, 3),
url: "https://t.me/balek".to_string(),
}];
assert!(get_attribute_from_url(&None).is_none());
assert!(get_attribute_from_url(&Some(UserEntityDetail { urls: false_urls })).is_none());
let binding = get_attribute_from_url(&Some(UserEntityDetail { urls: true_urls })).unwrap();
let result_credentials_field_attribute = binding.first().unwrap();
assert_eq!(
result_credentials_field_attribute.name,
expected_credentials_field_attribute.name
);
assert_eq!(
result_credentials_field_attribute.value,
expected_credentials_field_attribute.value
);
}
#[test]
fn test_get_note_from_description() {
let urls = vec![UrlEntity {
display_url: "tamerelol".to_string(),
expanded_url: Some("https://www.nintendojo.fr/dojobar".to_string()),
range: (1, 3),
url: "https://t.me/tamerelol".to_string(),
}];
let some_description = Some("Youpi | https://t.me/tamerelol".to_string());
let none_description = None;
assert_eq!(
get_note_from_description(&some_description, &urls),
Some("Youpi | https://www.nintendojo.fr/dojobar".to_string())
);
assert_eq!(get_note_from_description(&none_description, &urls), None);
}
#[test]
fn test_replace_tweet_by_toot() {
let mut associated_urls = HashMap::from([

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?;