kopia lustrzana https://github.com/bellingcat/auto-archiver
Added tests, updated instagram_tbot_extractor.py raise failure.
rodzic
f4c623b11b
commit
ce5a200d1f
|
@ -172,18 +172,18 @@ lxml = ["lxml"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "boto3"
|
name = "boto3"
|
||||||
version = "1.36.19"
|
version = "1.36.22"
|
||||||
description = "The AWS SDK for Python"
|
description = "The AWS SDK for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "boto3-1.36.19-py3-none-any.whl", hash = "sha256:7784590369a9d545bb07b2de56b6ce4d5a5e232883a957f704c3f842caeba155"},
|
{file = "boto3-1.36.22-py3-none-any.whl", hash = "sha256:39957eabdce009353d72d131046489fbbfa15891865d5f069f1e8bfa414e6b81"},
|
||||||
{file = "boto3-1.36.19.tar.gz", hash = "sha256:8c2c2a4ccdfe35dd2611ee1b7473dd2383948415c777e42dc4e7f1ebe371fe8c"},
|
{file = "boto3-1.36.22.tar.gz", hash = "sha256:768c8a4d4a6227fe2258105efa086f1424cba5ca915a5eb2305b2cd979306ad1"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
botocore = ">=1.36.19,<1.37.0"
|
botocore = ">=1.36.22,<1.37.0"
|
||||||
jmespath = ">=0.7.1,<2.0.0"
|
jmespath = ">=0.7.1,<2.0.0"
|
||||||
s3transfer = ">=0.11.0,<0.12.0"
|
s3transfer = ">=0.11.0,<0.12.0"
|
||||||
|
|
||||||
|
@ -192,14 +192,14 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "botocore"
|
name = "botocore"
|
||||||
version = "1.36.19"
|
version = "1.36.22"
|
||||||
description = "Low-level, data-driven core of boto 3."
|
description = "Low-level, data-driven core of boto 3."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "botocore-1.36.19-py3-none-any.whl", hash = "sha256:98882c106fec4c08678ea028199f7f5119550fab95d682b30846f7aae04b7bec"},
|
{file = "botocore-1.36.22-py3-none-any.whl", hash = "sha256:75d6b34acb0686ee4d54ff6eb285e78ccfe318407428769d1e3e13351714d890"},
|
||||||
{file = "botocore-1.36.19.tar.gz", hash = "sha256:cdf6729f601f82b1acdb9004b1f88b57cfb470f576394cdb3bbf5150f7fafb5b"},
|
{file = "botocore-1.36.22.tar.gz", hash = "sha256:59520247d5a479731724f97c995d5a1c2aae3b303b324f39d99efcfad1d3019e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -781,14 +781,14 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "google-api-python-client"
|
name = "google-api-python-client"
|
||||||
version = "2.160.0"
|
version = "2.161.0"
|
||||||
description = "Google API Client Library for Python"
|
description = "Google API Client Library for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "google_api_python_client-2.160.0-py2.py3-none-any.whl", hash = "sha256:63d61fb3e4cf3fb31a70a87f45567c22f6dfe87bbfa27252317e3e2c42900db4"},
|
{file = "google_api_python_client-2.161.0-py2.py3-none-any.whl", hash = "sha256:9476a5a4f200bae368140453df40f9cda36be53fa7d0e9a9aac4cdb859a26448"},
|
||||||
{file = "google_api_python_client-2.160.0.tar.gz", hash = "sha256:a8ccafaecfa42d15d5b5c3134ced8de08380019717fc9fb1ed510ca58eca3b7e"},
|
{file = "google_api_python_client-2.161.0.tar.gz", hash = "sha256:324c0cce73e9ea0a0d2afd5937e01b7c2d6a4d7e2579cdb6c384f9699d6c9f37"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2363,14 +2363,14 @@ test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sphinx-autoapi"
|
name = "sphinx-autoapi"
|
||||||
version = "3.5.0"
|
version = "3.6.0"
|
||||||
description = "Sphinx API documentation generator"
|
description = "Sphinx API documentation generator"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.9"
|
||||||
groups = ["docs"]
|
groups = ["docs"]
|
||||||
files = [
|
files = [
|
||||||
{file = "sphinx_autoapi-3.5.0-py3-none-any.whl", hash = "sha256:8676db32dded669dc6be9100696652640dc1e883e45b74710d74eb547a310114"},
|
{file = "sphinx_autoapi-3.6.0-py3-none-any.whl", hash = "sha256:f3b66714493cab140b0e896d33ce7137654a16ac1edb6563edcbd47bf975f711"},
|
||||||
{file = "sphinx_autoapi-3.5.0.tar.gz", hash = "sha256:10dcdf86e078ae1fb144f653341794459e86f5b23cf3e786a735def71f564089"},
|
{file = "sphinx_autoapi-3.6.0.tar.gz", hash = "sha256:c685f274e41d0842ae7e199460c322c4bd7fec816ccc2da8d806094b4f64af06"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2380,7 +2380,7 @@ astroid = [
|
||||||
]
|
]
|
||||||
Jinja2 = "*"
|
Jinja2 = "*"
|
||||||
PyYAML = "*"
|
PyYAML = "*"
|
||||||
sphinx = ">=6.1.0"
|
sphinx = ">=7.4.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sphinx-autobuild"
|
name = "sphinx-autobuild"
|
||||||
|
@ -2680,14 +2680,14 @@ telegram = ["requests"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trio"
|
name = "trio"
|
||||||
version = "0.28.0"
|
version = "0.29.0"
|
||||||
description = "A friendly Python library for async concurrency and I/O"
|
description = "A friendly Python library for async concurrency and I/O"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "trio-0.28.0-py3-none-any.whl", hash = "sha256:56d58977acc1635735a96581ec70513cc781b8b6decd299c487d3be2a721cd94"},
|
{file = "trio-0.29.0-py3-none-any.whl", hash = "sha256:d8c463f1a9cc776ff63e331aba44c125f423a5a13c684307e828d930e625ba66"},
|
||||||
{file = "trio-0.28.0.tar.gz", hash = "sha256:4e547896fe9e8a5658e54e4c7c5fa1db748cbbbaa7c965e7d40505b928c73c05"},
|
{file = "trio-0.29.0.tar.gz", hash = "sha256:ea0d3967159fc130acb6939a0be0e558e364fee26b5deeecc893a6b08c361bdf"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2701,18 +2701,19 @@ sortedcontainers = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trio-websocket"
|
name = "trio-websocket"
|
||||||
version = "0.11.1"
|
version = "0.12.1"
|
||||||
description = "WebSocket library for Trio"
|
description = "WebSocket library for Trio"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "trio-websocket-0.11.1.tar.gz", hash = "sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f"},
|
{file = "trio_websocket-0.12.1-py3-none-any.whl", hash = "sha256:608ec746bb287e5d5a66baf483e41194193c5cf05ffaad6240e7d1fcd80d1e6f"},
|
||||||
{file = "trio_websocket-0.11.1-py3-none-any.whl", hash = "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638"},
|
{file = "trio_websocket-0.12.1.tar.gz", hash = "sha256:d55ccd4d3eae27c494f3fdae14823317839bdcb8214d1173eacc4d42c69fc91b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
exceptiongroup = {version = "*", markers = "python_version < \"3.11\""}
|
exceptiongroup = {version = "*", markers = "python_version < \"3.11\""}
|
||||||
|
outcome = ">=1.2.0"
|
||||||
trio = ">=0.11"
|
trio = ">=0.11"
|
||||||
wsproto = ">=0.14"
|
wsproto = ">=0.14"
|
||||||
|
|
||||||
|
@ -2779,14 +2780,14 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tzlocal"
|
name = "tzlocal"
|
||||||
version = "5.2"
|
version = "5.3"
|
||||||
description = "tzinfo object for the local timezone"
|
description = "tzinfo object for the local timezone"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.9"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"},
|
{file = "tzlocal-5.3-py3-none-any.whl", hash = "sha256:3814135a1bb29763c6e4f08fd6e41dbb435c7a60bfbb03270211bcc537187d8c"},
|
||||||
{file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
|
{file = "tzlocal-5.3.tar.gz", hash = "sha256:2fafbfc07e9d8b49ade18f898d6bcd37ae88ce3ad6486842a2e4f03af68323d2"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -3032,81 +3033,81 @@ test = ["websockets"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "websockets"
|
name = "websockets"
|
||||||
version = "14.2"
|
version = "15.0"
|
||||||
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["main", "docs"]
|
groups = ["main", "docs"]
|
||||||
files = [
|
files = [
|
||||||
{file = "websockets-14.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e8179f95323b9ab1c11723e5d91a89403903f7b001828161b480a7810b334885"},
|
{file = "websockets-15.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5e6ee18a53dd5743e6155b8ff7e8e477c25b29b440f87f65be8165275c87fef0"},
|
||||||
{file = "websockets-14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d8c3e2cdb38f31d8bd7d9d28908005f6fa9def3324edb9bf336d7e4266fd397"},
|
{file = "websockets-15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ee06405ea2e67366a661ed313e14cf2a86e84142a3462852eb96348f7219cee3"},
|
||||||
{file = "websockets-14.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:714a9b682deb4339d39ffa674f7b674230227d981a37d5d174a4a83e3978a610"},
|
{file = "websockets-15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8711682a629bbcaf492f5e0af72d378e976ea1d127a2d47584fa1c2c080b436b"},
|
||||||
{file = "websockets-14.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2e53c72052f2596fb792a7acd9704cbc549bf70fcde8a99e899311455974ca3"},
|
{file = "websockets-15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94c4a9b01eede952442c088d415861b0cf2053cbd696b863f6d5022d4e4e2453"},
|
||||||
{file = "websockets-14.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3fbd68850c837e57373d95c8fe352203a512b6e49eaae4c2f4088ef8cf21980"},
|
{file = "websockets-15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:45535fead66e873f411c1d3cf0d3e175e66f4dd83c4f59d707d5b3e4c56541c4"},
|
||||||
{file = "websockets-14.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b27ece32f63150c268593d5fdb82819584831a83a3f5809b7521df0685cd5d8"},
|
{file = "websockets-15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e389efe46ccb25a1f93d08c7a74e8123a2517f7b7458f043bd7529d1a63ffeb"},
|
||||||
{file = "websockets-14.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4daa0faea5424d8713142b33825fff03c736f781690d90652d2c8b053345b0e7"},
|
{file = "websockets-15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:67a04754d121ea5ca39ddedc3f77071651fb5b0bc6b973c71c515415b44ed9c5"},
|
||||||
{file = "websockets-14.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:bc63cee8596a6ec84d9753fd0fcfa0452ee12f317afe4beae6b157f0070c6c7f"},
|
{file = "websockets-15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:bd66b4865c8b853b8cca7379afb692fc7f52cf898786537dfb5e5e2d64f0a47f"},
|
||||||
{file = "websockets-14.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a570862c325af2111343cc9b0257b7119b904823c675b22d4ac547163088d0d"},
|
{file = "websockets-15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a4cc73a6ae0a6751b76e69cece9d0311f054da9b22df6a12f2c53111735657c8"},
|
||||||
{file = "websockets-14.2-cp310-cp310-win32.whl", hash = "sha256:75862126b3d2d505e895893e3deac0a9339ce750bd27b4ba515f008b5acf832d"},
|
{file = "websockets-15.0-cp310-cp310-win32.whl", hash = "sha256:89da58e4005e153b03fe8b8794330e3f6a9774ee9e1c3bd5bc52eb098c3b0c4f"},
|
||||||
{file = "websockets-14.2-cp310-cp310-win_amd64.whl", hash = "sha256:cc45afb9c9b2dc0852d5c8b5321759cf825f82a31bfaf506b65bf4668c96f8b2"},
|
{file = "websockets-15.0-cp310-cp310-win_amd64.whl", hash = "sha256:4ff380aabd7a74a42a760ee76c68826a8f417ceb6ea415bd574a035a111fd133"},
|
||||||
{file = "websockets-14.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3bdc8c692c866ce5fefcaf07d2b55c91d6922ac397e031ef9b774e5b9ea42166"},
|
{file = "websockets-15.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:dd24c4d256558429aeeb8d6c24ebad4e982ac52c50bc3670ae8646c181263965"},
|
||||||
{file = "websockets-14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c93215fac5dadc63e51bcc6dceca72e72267c11def401d6668622b47675b097f"},
|
{file = "websockets-15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f83eca8cbfd168e424dfa3b3b5c955d6c281e8fc09feb9d870886ff8d03683c7"},
|
||||||
{file = "websockets-14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c9b6535c0e2cf8a6bf938064fb754aaceb1e6a4a51a80d884cd5db569886910"},
|
{file = "websockets-15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4095a1f2093002c2208becf6f9a178b336b7572512ee0a1179731acb7788e8ad"},
|
||||||
{file = "websockets-14.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a52a6d7cf6938e04e9dceb949d35fbdf58ac14deea26e685ab6368e73744e4c"},
|
{file = "websockets-15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb915101dfbf318486364ce85662bb7b020840f68138014972c08331458d41f3"},
|
||||||
{file = "websockets-14.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f05702e93203a6ff5226e21d9b40c037761b2cfb637187c9802c10f58e40473"},
|
{file = "websockets-15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:45d464622314973d78f364689d5dbb9144e559f93dca11b11af3f2480b5034e1"},
|
||||||
{file = "websockets-14.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22441c81a6748a53bfcb98951d58d1af0661ab47a536af08920d129b4d1c3473"},
|
{file = "websockets-15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace960769d60037ca9625b4c578a6f28a14301bd2a1ff13bb00e824ac9f73e55"},
|
||||||
{file = "websockets-14.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd9b868d78b194790e6236d9cbc46d68aba4b75b22497eb4ab64fa640c3af56"},
|
{file = "websockets-15.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c7cd4b1015d2f60dfe539ee6c95bc968d5d5fad92ab01bb5501a77393da4f596"},
|
||||||
{file = "websockets-14.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1a5a20d5843886d34ff8c57424cc65a1deda4375729cbca4cb6b3353f3ce4142"},
|
{file = "websockets-15.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4f7290295794b5dec470867c7baa4a14182b9732603fd0caf2a5bf1dc3ccabf3"},
|
||||||
{file = "websockets-14.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:34277a29f5303d54ec6468fb525d99c99938607bc96b8d72d675dee2b9f5bf1d"},
|
{file = "websockets-15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3abd670ca7ce230d5a624fd3d55e055215d8d9b723adee0a348352f5d8d12ff4"},
|
||||||
{file = "websockets-14.2-cp311-cp311-win32.whl", hash = "sha256:02687db35dbc7d25fd541a602b5f8e451a238ffa033030b172ff86a93cb5dc2a"},
|
{file = "websockets-15.0-cp311-cp311-win32.whl", hash = "sha256:110a847085246ab8d4d119632145224d6b49e406c64f1bbeed45c6f05097b680"},
|
||||||
{file = "websockets-14.2-cp311-cp311-win_amd64.whl", hash = "sha256:862e9967b46c07d4dcd2532e9e8e3c2825e004ffbf91a5ef9dde519ee2effb0b"},
|
{file = "websockets-15.0-cp311-cp311-win_amd64.whl", hash = "sha256:8d7bbbe2cd6ed80aceef2a14e9f1c1b61683194c216472ed5ff33b700e784e37"},
|
||||||
{file = "websockets-14.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1f20522e624d7ffbdbe259c6b6a65d73c895045f76a93719aa10cd93b3de100c"},
|
{file = "websockets-15.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:cccc18077acd34c8072578394ec79563664b1c205f7a86a62e94fafc7b59001f"},
|
||||||
{file = "websockets-14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:647b573f7d3ada919fd60e64d533409a79dcf1ea21daeb4542d1d996519ca967"},
|
{file = "websockets-15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4c22992e24f12de340ca5f824121a5b3e1a37ad4360b4e1aaf15e9d1c42582d"},
|
||||||
{file = "websockets-14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af99a38e49f66be5a64b1e890208ad026cda49355661549c507152113049990"},
|
{file = "websockets-15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1206432cc6c644f6fc03374b264c5ff805d980311563202ed7fef91a38906276"},
|
||||||
{file = "websockets-14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:091ab63dfc8cea748cc22c1db2814eadb77ccbf82829bac6b2fbe3401d548eda"},
|
{file = "websockets-15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d3cc75ef3e17490042c47e0523aee1bcc4eacd2482796107fd59dd1100a44bc"},
|
||||||
{file = "websockets-14.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b374e8953ad477d17e4851cdc66d83fdc2db88d9e73abf755c94510ebddceb95"},
|
{file = "websockets-15.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b89504227a5311610e4be16071465885a0a3d6b0e82e305ef46d9b064ce5fb72"},
|
||||||
{file = "websockets-14.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a39d7eceeea35db85b85e1169011bb4321c32e673920ae9c1b6e0978590012a3"},
|
{file = "websockets-15.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56e3efe356416bc67a8e093607315951d76910f03d2b3ad49c4ade9207bf710d"},
|
||||||
{file = "websockets-14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0a6f3efd47ffd0d12080594f434faf1cd2549b31e54870b8470b28cc1d3817d9"},
|
{file = "websockets-15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f2205cdb444a42a7919690238fb5979a05439b9dbb73dd47c863d39640d85ab"},
|
||||||
{file = "websockets-14.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:065ce275e7c4ffb42cb738dd6b20726ac26ac9ad0a2a48e33ca632351a737267"},
|
{file = "websockets-15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aea01f40995fa0945c020228ab919b8dfc93fc8a9f2d3d705ab5b793f32d9e99"},
|
||||||
{file = "websockets-14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e9d0e53530ba7b8b5e389c02282f9d2aa47581514bd6049d3a7cffe1385cf5fe"},
|
{file = "websockets-15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9f8e33747b1332db11cf7fcf4a9512bef9748cb5eb4d3f7fbc8c30d75dc6ffc"},
|
||||||
{file = "websockets-14.2-cp312-cp312-win32.whl", hash = "sha256:20e6dd0984d7ca3037afcb4494e48c74ffb51e8013cac71cf607fffe11df7205"},
|
{file = "websockets-15.0-cp312-cp312-win32.whl", hash = "sha256:32e02a2d83f4954aa8c17e03fe8ec6962432c39aca4be7e8ee346b05a3476904"},
|
||||||
{file = "websockets-14.2-cp312-cp312-win_amd64.whl", hash = "sha256:44bba1a956c2c9d268bdcdf234d5e5ff4c9b6dc3e300545cbe99af59dda9dcce"},
|
{file = "websockets-15.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffc02b159b65c05f2ed9ec176b715b66918a674bd4daed48a9a7a590dd4be1aa"},
|
||||||
{file = "websockets-14.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f1372e511c7409a542291bce92d6c83320e02c9cf392223272287ce55bc224e"},
|
{file = "websockets-15.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d2244d8ab24374bed366f9ff206e2619345f9cd7fe79aad5225f53faac28b6b1"},
|
||||||
{file = "websockets-14.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4da98b72009836179bb596a92297b1a61bb5a830c0e483a7d0766d45070a08ad"},
|
{file = "websockets-15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3a302241fbe825a3e4fe07666a2ab513edfdc6d43ce24b79691b45115273b5e7"},
|
||||||
{file = "websockets-14.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8a86a269759026d2bde227652b87be79f8a734e582debf64c9d302faa1e9f03"},
|
{file = "websockets-15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:10552fed076757a70ba2c18edcbc601c7637b30cdfe8c24b65171e824c7d6081"},
|
||||||
{file = "websockets-14.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86cf1aaeca909bf6815ea714d5c5736c8d6dd3a13770e885aafe062ecbd04f1f"},
|
{file = "websockets-15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c53f97032b87a406044a1c33d1e9290cc38b117a8062e8a8b285175d7e2f99c9"},
|
||||||
{file = "websockets-14.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b0f6c3ba3b1240f602ebb3971d45b02cc12bd1845466dd783496b3b05783a5"},
|
{file = "websockets-15.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1caf951110ca757b8ad9c4974f5cac7b8413004d2f29707e4d03a65d54cedf2b"},
|
||||||
{file = "websockets-14.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:669c3e101c246aa85bc8534e495952e2ca208bd87994650b90a23d745902db9a"},
|
{file = "websockets-15.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bf1ab71f9f23b0a1d52ec1682a3907e0c208c12fef9c3e99d2b80166b17905f"},
|
||||||
{file = "websockets-14.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eabdb28b972f3729348e632ab08f2a7b616c7e53d5414c12108c29972e655b20"},
|
{file = "websockets-15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bfcd3acc1a81f106abac6afd42327d2cf1e77ec905ae11dc1d9142a006a496b6"},
|
||||||
{file = "websockets-14.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2066dc4cbcc19f32c12a5a0e8cc1b7ac734e5b64ac0a325ff8353451c4b15ef2"},
|
{file = "websockets-15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c8c5c8e1bac05ef3c23722e591ef4f688f528235e2480f157a9cfe0a19081375"},
|
||||||
{file = "websockets-14.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab95d357cd471df61873dadf66dd05dd4709cae001dd6342edafc8dc6382f307"},
|
{file = "websockets-15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:86bfb52a9cfbcc09aba2b71388b0a20ea5c52b6517c0b2e316222435a8cdab72"},
|
||||||
{file = "websockets-14.2-cp313-cp313-win32.whl", hash = "sha256:a9e72fb63e5f3feacdcf5b4ff53199ec8c18d66e325c34ee4c551ca748623bbc"},
|
{file = "websockets-15.0-cp313-cp313-win32.whl", hash = "sha256:26ba70fed190708551c19a360f9d7eca8e8c0f615d19a574292b7229e0ae324c"},
|
||||||
{file = "websockets-14.2-cp313-cp313-win_amd64.whl", hash = "sha256:b439ea828c4ba99bb3176dc8d9b933392a2413c0f6b149fdcba48393f573377f"},
|
{file = "websockets-15.0-cp313-cp313-win_amd64.whl", hash = "sha256:ae721bcc8e69846af00b7a77a220614d9b2ec57d25017a6bbde3a99473e41ce8"},
|
||||||
{file = "websockets-14.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7cd5706caec1686c5d233bc76243ff64b1c0dc445339bd538f30547e787c11fe"},
|
{file = "websockets-15.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c348abc5924caa02a62896300e32ea80a81521f91d6db2e853e6b1994017c9f6"},
|
||||||
{file = "websockets-14.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ec607328ce95a2f12b595f7ae4c5d71bf502212bddcea528290b35c286932b12"},
|
{file = "websockets-15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5294fcb410ed0a45d5d1cdedc4e51a60aab5b2b3193999028ea94afc2f554b05"},
|
||||||
{file = "websockets-14.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da85651270c6bfb630136423037dd4975199e5d4114cae6d3066641adcc9d1c7"},
|
{file = "websockets-15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c24ba103ecf45861e2e1f933d40b2d93f5d52d8228870c3e7bf1299cd1cb8ff1"},
|
||||||
{file = "websockets-14.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ecadc7ce90accf39903815697917643f5b7cfb73c96702318a096c00aa71f5"},
|
{file = "websockets-15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc8821a03bcfb36e4e4705316f6b66af28450357af8a575dc8f4b09bf02a3dee"},
|
||||||
{file = "websockets-14.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1979bee04af6a78608024bad6dfcc0cc930ce819f9e10342a29a05b5320355d0"},
|
{file = "websockets-15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc5ae23ada6515f31604f700009e2df90b091b67d463a8401c1d8a37f76c1d7"},
|
||||||
{file = "websockets-14.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dddacad58e2614a24938a50b85969d56f88e620e3f897b7d80ac0d8a5800258"},
|
{file = "websockets-15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ac67b542505186b3bbdaffbc303292e1ee9c8729e5d5df243c1f20f4bb9057e"},
|
||||||
{file = "websockets-14.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:89a71173caaf75fa71a09a5f614f450ba3ec84ad9fca47cb2422a860676716f0"},
|
{file = "websockets-15.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c86dc2068f1c5ca2065aca34f257bbf4f78caf566eb230f692ad347da191f0a1"},
|
||||||
{file = "websockets-14.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6af6a4b26eea4fc06c6818a6b962a952441e0e39548b44773502761ded8cc1d4"},
|
{file = "websockets-15.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:30cff3ef329682b6182c01c568f551481774c476722020b8f7d0daacbed07a17"},
|
||||||
{file = "websockets-14.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:80c8efa38957f20bba0117b48737993643204645e9ec45512579132508477cfc"},
|
{file = "websockets-15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:98dcf978d4c6048965d1762abd534c9d53bae981a035bfe486690ba11f49bbbb"},
|
||||||
{file = "websockets-14.2-cp39-cp39-win32.whl", hash = "sha256:2e20c5f517e2163d76e2729104abc42639c41cf91f7b1839295be43302713661"},
|
{file = "websockets-15.0-cp39-cp39-win32.whl", hash = "sha256:37d66646f929ae7c22c79bc73ec4074d6db45e6384500ee3e0d476daf55482a9"},
|
||||||
{file = "websockets-14.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4c8cef610e8d7c70dea92e62b6814a8cd24fbd01d7103cc89308d2bfe1659ef"},
|
{file = "websockets-15.0-cp39-cp39-win_amd64.whl", hash = "sha256:24d5333a9b2343330f0f4eb88546e2c32a7f5c280f8dd7d3cc079beb0901781b"},
|
||||||
{file = "websockets-14.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d7d9cafbccba46e768be8a8ad4635fa3eae1ffac4c6e7cb4eb276ba41297ed29"},
|
{file = "websockets-15.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b499caef4bca9cbd0bd23cd3386f5113ee7378094a3cb613a2fa543260fe9506"},
|
||||||
{file = "websockets-14.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c76193c1c044bd1e9b3316dcc34b174bbf9664598791e6fb606d8d29000e070c"},
|
{file = "websockets-15.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:17f2854c6bd9ee008c4b270f7010fe2da6c16eac5724a175e75010aacd905b31"},
|
||||||
{file = "websockets-14.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd475a974d5352390baf865309fe37dec6831aafc3014ffac1eea99e84e83fc2"},
|
{file = "websockets-15.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89f72524033abbfde880ad338fd3c2c16e31ae232323ebdfbc745cbb1b3dcc03"},
|
||||||
{file = "websockets-14.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c6c0097a41968b2e2b54ed3424739aab0b762ca92af2379f152c1aef0187e1c"},
|
{file = "websockets-15.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1657a9eecb29d7838e3b415458cc494e6d1b194f7ac73a34aa55c6fb6c72d1f3"},
|
||||||
{file = "websockets-14.2-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d7ff794c8b36bc402f2e07c0b2ceb4a2424147ed4785ff03e2a7af03711d60a"},
|
{file = "websockets-15.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e413352a921f5ad5d66f9e2869b977e88d5103fc528b6deb8423028a2befd842"},
|
||||||
{file = "websockets-14.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dec254fcabc7bd488dab64846f588fc5b6fe0d78f641180030f8ea27b76d72c3"},
|
{file = "websockets-15.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8561c48b0090993e3b2a54db480cab1d23eb2c5735067213bb90f402806339f5"},
|
||||||
{file = "websockets-14.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bbe03eb853e17fd5b15448328b4ec7fb2407d45fb0245036d06a3af251f8e48f"},
|
{file = "websockets-15.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:190bc6ef8690cd88232a038d1b15714c258f79653abad62f7048249b09438af3"},
|
||||||
{file = "websockets-14.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3c4aa3428b904d5404a0ed85f3644d37e2cb25996b7f096d77caeb0e96a3b42"},
|
{file = "websockets-15.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:327adab7671f3726b0ba69be9e865bba23b37a605b585e65895c428f6e47e766"},
|
||||||
{file = "websockets-14.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:577a4cebf1ceaf0b65ffc42c54856214165fb8ceeba3935852fc33f6b0c55e7f"},
|
{file = "websockets-15.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd8ef197c87afe0a9009f7a28b5dc613bfc585d329f80b7af404e766aa9e8c7"},
|
||||||
{file = "websockets-14.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad1c1d02357b7665e700eca43a31d52814ad9ad9b89b58118bdabc365454b574"},
|
{file = "websockets-15.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:789c43bf4a10cd067c24c321238e800b8b2716c863ddb2294d2fed886fa5a689"},
|
||||||
{file = "websockets-14.2-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f390024a47d904613577df83ba700bd189eedc09c57af0a904e5c39624621270"},
|
{file = "websockets-15.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7394c0b7d460569c9285fa089a429f58465db930012566c03046f9e3ab0ed181"},
|
||||||
{file = "websockets-14.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3c1426c021c38cf92b453cdf371228d3430acd775edee6bac5a4d577efc72365"},
|
{file = "websockets-15.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ea4f210422b912ebe58ef0ad33088bc8e5c5ff9655a8822500690abc3b1232d"},
|
||||||
{file = "websockets-14.2-py3-none-any.whl", hash = "sha256:7a6ceec4ea84469f15cf15807a747e9efe57e369c384fa86e022b3bea679b79b"},
|
{file = "websockets-15.0-py3-none-any.whl", hash = "sha256:51ffd53c53c4442415b613497a34ba0aa7b99ac07f1e4a62db5dcd640ae6c3c3"},
|
||||||
{file = "websockets-14.2.tar.gz", hash = "sha256:5059ed9c54945efb321f097084b4c7e52c246f2c869815876a69d1efc4ad6eb5"},
|
{file = "websockets-15.0.tar.gz", hash = "sha256:ca36151289a15b39d8d683fd8b7abbe26fc50be311066c5f8dcf3cb8cee107ab"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -77,13 +77,14 @@ class InstagramTbotExtractor(Extractor):
|
||||||
chat, since_id = self._send_url_to_bot(url)
|
chat, since_id = self._send_url_to_bot(url)
|
||||||
message = self._process_messages(chat, since_id, tmp_dir, result)
|
message = self._process_messages(chat, since_id, tmp_dir, result)
|
||||||
|
|
||||||
|
# This may be outdated and replaced by the below message, but keeping until confirmed
|
||||||
if "You must enter a URL to a post" in message:
|
if "You must enter a URL to a post" in message:
|
||||||
logger.debug(f"invalid link {url=} for {self.name}: {message}")
|
logger.debug(f"invalid link {url=} for {self.name}: {message}")
|
||||||
return False
|
return False
|
||||||
# # TODO: It currently returns this as a success - is that intentional?
|
|
||||||
# if "Media not found or unavailable" in message:
|
if "Media not found or unavailable" in message:
|
||||||
# logger.debug(f"invalid link {url=} for {self.name}: {message}")
|
logger.debug(f"No media found for link {url=} for {self.name}: {message}")
|
||||||
# return False
|
return False
|
||||||
|
|
||||||
if message:
|
if message:
|
||||||
result.set_content(message).set_title(message[:128])
|
result.set_content(message).set_title(message[:128])
|
||||||
|
|
|
@ -46,7 +46,7 @@ def dump_payload(p):
|
||||||
|
|
||||||
|
|
||||||
def update_nested_dict(dictionary, update_dict):
|
def update_nested_dict(dictionary, update_dict):
|
||||||
# takes 2 dicts and overwrites the first with the second only on the changed balues
|
# takes 2 dicts and overwrites the first with the second only on the changed values
|
||||||
for key, value in update_dict.items():
|
for key, value in update_dict.items():
|
||||||
if key in dictionary and isinstance(value, dict) and isinstance(dictionary[key], dict):
|
if key in dictionary and isinstance(value, dict) and isinstance(dictionary[key], dict):
|
||||||
update_nested_dict(dictionary[key], value)
|
update_nested_dict(dictionary[key], value)
|
||||||
|
|
|
@ -3,6 +3,7 @@ pytest conftest file, for shared fixtures and configuration
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
|
from datetime import datetime, timezone
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
from typing import Dict, Tuple
|
from typing import Dict, Tuple
|
||||||
import hashlib
|
import hashlib
|
||||||
|
@ -138,3 +139,9 @@ def mock_binary_dependencies():
|
||||||
# Mock all binary dependencies as available
|
# Mock all binary dependencies as available
|
||||||
mock_shutil_which.return_value = "/usr/bin/fake_binary"
|
mock_shutil_which.return_value = "/usr/bin/fake_binary"
|
||||||
yield mock_shutil_which
|
yield mock_shutil_which
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def sample_datetime():
|
||||||
|
return datetime(2023, 1, 1, 12, 0, tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from auto_archiver.core import Metadata
|
||||||
|
from auto_archiver.modules.api_db import AAApiDb
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def api_db(setup_module):
|
||||||
|
configs: dict = {
|
||||||
|
"api_endpoint": "https://api.example.com",
|
||||||
|
"api_token": "test-token",
|
||||||
|
"public": False,
|
||||||
|
"author_id": "Someone",
|
||||||
|
"group_id": "123",
|
||||||
|
"use_api_cache": True,
|
||||||
|
"store_results": True,
|
||||||
|
"tags": "[]",
|
||||||
|
}
|
||||||
|
return setup_module(AAApiDb, configs)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def metadata():
|
||||||
|
metadata = Metadata()
|
||||||
|
metadata.set("_processed_at", "2021-01-01T00:00:00")
|
||||||
|
metadata.set_url("https://example.com")
|
||||||
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
|
def test_fetch_no_cache(api_db, metadata):
|
||||||
|
# Test fetch
|
||||||
|
api_db.use_api_cache = False
|
||||||
|
assert api_db.fetch(metadata) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_fetch_fail_status(api_db, metadata):
|
||||||
|
# Test response fail in fetch method
|
||||||
|
with patch("auto_archiver.modules.api_db.api_db.requests.get") as mock_get:
|
||||||
|
mock_get.return_value.status_code = 400
|
||||||
|
mock_get.return_value.json.return_value = {}
|
||||||
|
with patch("loguru.logger.error") as mock_error:
|
||||||
|
assert api_db.fetch(metadata) is False
|
||||||
|
mock_error.assert_called_once_with("AA API FAIL (400): {}")
|
||||||
|
|
||||||
|
|
||||||
|
def test_fetch(api_db, metadata):
|
||||||
|
# Test successful fetch method
|
||||||
|
with patch("auto_archiver.modules.api_db.api_db.requests.get") as mock_get,\
|
||||||
|
patch("auto_archiver.core.metadata.datetime.datetime") as mock_datetime:
|
||||||
|
mock_datetime.now.return_value = "2021-01-01T00:00:00"
|
||||||
|
mock_get.return_value.status_code = 200
|
||||||
|
mock_get.return_value.json.return_value = [{"result": {}}, {"result":
|
||||||
|
{'media': [], 'metadata': {'_processed_at': '2021-01-01T00:00:00', 'url': 'https://example.com'},
|
||||||
|
'status': 'no archiver'}}]
|
||||||
|
assert api_db.fetch(metadata) == metadata
|
||||||
|
|
||||||
|
|
||||||
|
def test_done_success(api_db, metadata):
|
||||||
|
with patch("auto_archiver.modules.api_db.api_db.requests.post") as mock_post:
|
||||||
|
mock_post.return_value.status_code = 201
|
||||||
|
api_db.done(metadata)
|
||||||
|
mock_post.assert_called_once()
|
||||||
|
mock_post.assert_called_once_with("https://api.example.com/interop/submit-archive",
|
||||||
|
json={'author_id': 'Someone', 'url': 'https://example.com',
|
||||||
|
'public': False, 'group_id': '123', 'tags': ['[', ']'], 'result': '{"status": "no archiver", "metadata": {"_processed_at": "2021-01-01T00:00:00", "url": "https://example.com"}, "media": []}'},
|
||||||
|
headers={'Authorization': 'Bearer test-token'})
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import os
|
import os
|
||||||
from typing import Type
|
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from auto_archiver.core import Metadata
|
from auto_archiver.core import Metadata
|
||||||
from auto_archiver.core.extractor import Extractor
|
|
||||||
from auto_archiver.modules.instagram_tbot_extractor import InstagramTbotExtractor
|
from auto_archiver.modules.instagram_tbot_extractor import InstagramTbotExtractor
|
||||||
from tests.extractors.test_extractor_base import TestExtractorBase
|
from tests.extractors.test_extractor_base import TestExtractorBase
|
||||||
|
|
||||||
|
@ -13,82 +11,103 @@ TESTFILES = os.path.join(os.path.dirname(__file__), "testfiles")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def session_file(tmpdir):
|
|
||||||
"""Fixture to create a test session file."""
|
|
||||||
session_file = os.path.join(tmpdir, "test_session.session")
|
|
||||||
with open(session_file, "w") as f:
|
|
||||||
f.write("mock_session_data")
|
|
||||||
return session_file.replace(".session", "")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
|
||||||
def patch_extractor_methods(request, setup_module):
|
def patch_extractor_methods(request, setup_module):
|
||||||
with patch.object(InstagramTbotExtractor, '_prepare_session_file', return_value=None), \
|
with patch.object(InstagramTbotExtractor, '_prepare_session_file', return_value=None), \
|
||||||
patch.object(InstagramTbotExtractor, '_initialize_telegram_client', return_value=None):
|
patch.object(InstagramTbotExtractor, '_initialize_telegram_client', return_value=None):
|
||||||
if hasattr(request, 'cls') and hasattr(request.cls, 'config'):
|
|
||||||
request.cls.extractor = setup_module("instagram_tbot_extractor", request.cls.config)
|
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def mock_sleep():
|
||||||
|
"""Globally mock time.sleep to avoid delays."""
|
||||||
|
with patch("time.sleep") as mock_sleep:
|
||||||
|
yield mock_sleep
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def metadata_sample():
|
def metadata_sample():
|
||||||
m = Metadata()
|
m = Metadata()
|
||||||
m.set_title("Test Title")
|
m.set_title("Test Title")
|
||||||
m.set_timestamp("2021-01-01T00:00:00Z")
|
m.set_timestamp("2021-01-01T00:00:00")
|
||||||
m.set_url("https://www.instagram.com/p/1234567890")
|
m.set_url("https://www.instagram.com/p/1234567890")
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
class TestInstagramTbotExtractor:
|
@pytest.fixture
|
||||||
|
def mock_telegram_client():
|
||||||
|
"""Fixture to mock TelegramClient interactions."""
|
||||||
|
with patch("auto_archiver.modules.instagram_tbot_extractor.client") as mock_client:
|
||||||
|
instance = MagicMock()
|
||||||
|
mock_client.return_value = instance
|
||||||
|
yield instance
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def extractor(setup_module, patch_extractor_methods):
|
||||||
extractor_module = "instagram_tbot_extractor"
|
extractor_module = "instagram_tbot_extractor"
|
||||||
extractor: InstagramTbotExtractor
|
|
||||||
config = {
|
config = {
|
||||||
"api_id": 12345,
|
"api_id": 12345,
|
||||||
"api_hash": "test_api_hash",
|
"api_hash": "test_api_hash",
|
||||||
"session_file": "test_session",
|
"session_file": "test_session",
|
||||||
|
"timeout": 4
|
||||||
|
}
|
||||||
|
extractor = setup_module(extractor_module, config)
|
||||||
|
extractor.client = MagicMock()
|
||||||
|
extractor.session_file = "test_session"
|
||||||
|
return extractor
|
||||||
|
|
||||||
|
|
||||||
|
def test_non_instagram_url(extractor, metadata_sample):
|
||||||
|
metadata_sample.set_url("https://www.youtube.com")
|
||||||
|
assert extractor.download(metadata_sample) is False
|
||||||
|
|
||||||
|
def test_download_success(extractor, metadata_sample):
|
||||||
|
with patch.object(extractor, "_send_url_to_bot", return_value=(MagicMock(), 101)), \
|
||||||
|
patch.object(extractor, "_process_messages", return_value="Sample Instagram post caption"):
|
||||||
|
result = extractor.download(metadata_sample)
|
||||||
|
assert result.is_success()
|
||||||
|
assert result.status == "insta-via-bot: success"
|
||||||
|
assert result.metadata.get("title") == "Sample Instagram post caption"
|
||||||
|
|
||||||
|
|
||||||
|
def test_download_invalid(extractor, metadata_sample):
|
||||||
|
with patch.object(extractor, "_send_url_to_bot", return_value=(MagicMock(), 101)), \
|
||||||
|
patch.object(extractor, "_process_messages", return_value="You must enter a URL to a post"):
|
||||||
|
assert extractor.download(metadata_sample) is False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="Requires authentication.")
|
||||||
|
class TestInstagramTbotExtractorReal(TestExtractorBase):
|
||||||
|
# To run these tests set the TELEGRAM_API_ID and TELEGRAM_API_HASH environment variables, and ensure the session file exists.
|
||||||
|
# Note these are true at this point in time, but changes to source media could be reason for failure.
|
||||||
|
extractor_module = "instagram_tbot_extractor"
|
||||||
|
extractor: InstagramTbotExtractor
|
||||||
|
config = {
|
||||||
|
"api_id": os.environ.get("TELEGRAM_API_ID"),
|
||||||
|
"api_hash": os.environ.get("TELEGRAM_API_HASH"),
|
||||||
|
"session_file": "secrets/anon-insta",
|
||||||
}
|
}
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.mark.parametrize("url, expected_status, message, len_media", [
|
||||||
def mock_telegram_client(self):
|
("https://www.instagram.com/p/C4QgLbrIKXG", "insta-via-bot: success", "Are you new to Bellingcat? - The way we share our investigations is different. 💭\nWe want you to read our story but also learn ou", 6),
|
||||||
"""Fixture to mock TelegramClient interactions."""
|
("https://www.instagram.com/reel/DEVLK8qoIbg/", "insta-via-bot: success", "Our volunteer community is at the centre of many incredible Bellingcat investigations and tools. Stephanie Ladel is one such vol", 3),
|
||||||
with patch("auto_archiver.modules.instagram_tbot_extractor._initialize_telegram_client") as mock_client:
|
# instagram tbot not working (potentially intermittently?) for stories - replace with a live story to retest
|
||||||
instance = MagicMock()
|
# ("https://www.instagram.com/stories/bellingcatofficial/3556336382743057476/", False, "Media not found or unavailable"),
|
||||||
mock_client.return_value = instance
|
# Seems to be working intermittently for highlights
|
||||||
yield instance
|
# ("https://www.instagram.com/stories/highlights/17868810693068139/", "insta-via-bot: success", None, 50),
|
||||||
|
# Marking invalid url as success
|
||||||
def test_extractor_is_initialized(self):
|
("https://www.instagram.com/p/INVALID", "insta-via-bot: success", "Media not found or unavailable", 0),
|
||||||
assert self.extractor is not None
|
("https://www.youtube.com/watch?v=ymCMy8OffHM", False, None, 0),
|
||||||
|
|
||||||
|
|
||||||
@patch("time.sleep")
|
|
||||||
@pytest.mark.parametrize("url, expected_status, bot_responses", [
|
|
||||||
("https://www.instagram.com/p/C4QgLbrIKXG", "insta-via-bot: success", [MagicMock(id=101, media=None, message="Are you new to Bellingcat? - The way we share our investigations is different. 💭\nWe want you to read our story but also learn ou")]),
|
|
||||||
("https://www.instagram.com/reel/DEVLK8qoIbg/", "insta-via-bot: success", [MagicMock(id=101, media=None, message="Our volunteer community is at the centre of many incredible Bellingcat investigations and tools. Stephanie Ladel is one such vol")]),
|
|
||||||
# todo tbot not working for stories :(
|
|
||||||
("https://www.instagram.com/stories/bellingcatofficial/3556336382743057476/", False, [MagicMock(id=101, media=None, message="Media not found or unavailable")]),
|
|
||||||
("https://www.youtube.com/watch?v=ymCMy8OffHM", False, []),
|
|
||||||
("https://www.instagram.com/p/INVALID", False, [MagicMock(id=101, media=None, message="You must enter a URL to a post")]),
|
|
||||||
])
|
])
|
||||||
def test_download(self, mock_sleep, url, expected_status, bot_responses, metadata_sample):
|
def test_download(self, url, expected_status, message, len_media, metadata_sample):
|
||||||
"""Test the `download()` method with various Instagram URLs."""
|
"""Test the `download()` method with various Instagram URLs."""
|
||||||
metadata_sample.set_url(url)
|
metadata_sample.set_url(url)
|
||||||
self.extractor.client = MagicMock()
|
|
||||||
result = self.extractor.download(metadata_sample)
|
result = self.extractor.download(metadata_sample)
|
||||||
pass
|
if expected_status:
|
||||||
# TODO fully mock or use as authenticated test
|
assert result.is_success()
|
||||||
# if expected_status:
|
assert result.status == expected_status
|
||||||
# assert result.is_success()
|
assert result.metadata.get("title") == message
|
||||||
# assert result.status == expected_status
|
assert len(result.media) == len_media
|
||||||
# assert result.metadata.get("title") in [msg.message[:128] for msg in bot_responses if msg.message]
|
else:
|
||||||
# else:
|
assert result is False
|
||||||
# assert result is False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Test story
|
|
||||||
# Test expired story
|
|
||||||
# Test requires login/ access (?)
|
|
||||||
# Test post
|
|
||||||
# Test multiple images?
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# Note this isn't a feeder, but contained as utility of the gsheet feeder module
|
||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from auto_archiver.utils.misc import (
|
||||||
|
mkdir_if_not_exists,
|
||||||
|
expand_url,
|
||||||
|
getattr_or,
|
||||||
|
DateTimeEncoder,
|
||||||
|
dump_payload,
|
||||||
|
get_datetime_from_str,
|
||||||
|
update_nested_dict,
|
||||||
|
calculate_file_hash,
|
||||||
|
random_str,
|
||||||
|
get_timestamp
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def sample_file(tmp_path):
|
||||||
|
file_path = tmp_path / "test.txt"
|
||||||
|
file_path.write_text("test content")
|
||||||
|
return file_path
|
||||||
|
|
||||||
|
|
||||||
|
class TestDirectoryUtils:
|
||||||
|
def test_mkdir_creates_new_directory(self, tmp_path):
|
||||||
|
new_dir = tmp_path / "new_folder"
|
||||||
|
mkdir_if_not_exists(new_dir)
|
||||||
|
assert new_dir.exists()
|
||||||
|
assert new_dir.is_dir()
|
||||||
|
|
||||||
|
def test_mkdir_exists_quietly(self, tmp_path):
|
||||||
|
existing_dir = tmp_path / "existing"
|
||||||
|
existing_dir.mkdir()
|
||||||
|
mkdir_if_not_exists(existing_dir)
|
||||||
|
assert existing_dir.exists()
|
||||||
|
|
||||||
|
class TestURLExpansion:
|
||||||
|
@pytest.mark.parametrize("input_url,expected", [
|
||||||
|
("https://example.com", "https://example.com"),
|
||||||
|
("https://t.co/test", "https://expanded.url")
|
||||||
|
])
|
||||||
|
def test_expand_url(self, input_url, expected):
|
||||||
|
mock_response = Mock()
|
||||||
|
mock_response.url = "https://expanded.url"
|
||||||
|
with patch('requests.get', return_value=mock_response):
|
||||||
|
|
||||||
|
result = expand_url(input_url)
|
||||||
|
assert result == expected
|
||||||
|
|
||||||
|
def test_expand_url_handles_errors(self, caplog):
|
||||||
|
with patch('requests.get', side_effect=Exception("Connection error")):
|
||||||
|
url = "https://t.co/error"
|
||||||
|
result = expand_url(url)
|
||||||
|
assert result == url
|
||||||
|
assert f"Failed to expand url {url}" in caplog.text
|
||||||
|
|
||||||
|
class TestAttributeHandling:
|
||||||
|
class Sample:
|
||||||
|
exists = "value"
|
||||||
|
none = None
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("obj,attr,default,expected", [
|
||||||
|
(Sample(), "exists", "default", "value"),
|
||||||
|
(Sample(), "none", "default", "default"),
|
||||||
|
(Sample(), "missing", "default", "default"),
|
||||||
|
(None, "anything", "fallback", "fallback"),
|
||||||
|
])
|
||||||
|
def test_getattr_or(self, obj, attr, default, expected):
|
||||||
|
# Test gets attribute or returns a default value
|
||||||
|
assert getattr_or(obj, attr, default) == expected
|
||||||
|
|
||||||
|
class TestDateTimeHandling:
|
||||||
|
def test_datetime_encoder(self, sample_datetime):
|
||||||
|
result = json.dumps({"dt": sample_datetime}, cls=DateTimeEncoder)
|
||||||
|
loaded = json.loads(result)
|
||||||
|
assert loaded["dt"] == str(sample_datetime)
|
||||||
|
|
||||||
|
def test_dump_payload(self, sample_datetime):
|
||||||
|
payload = {"timestamp": sample_datetime}
|
||||||
|
result = dump_payload(payload)
|
||||||
|
assert str(sample_datetime) in result
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("dt_str,fmt,expected", [
|
||||||
|
("2023-01-01 12:00:00+00:00", None, datetime(2023, 1, 1, 12, 0, tzinfo=timezone.utc)),
|
||||||
|
("20230101 120000", "%Y%m%d %H%M%S", datetime(2023, 1, 1, 12, 0)),
|
||||||
|
("invalid", None, None),
|
||||||
|
])
|
||||||
|
def test_datetime_from_string(self, dt_str, fmt, expected):
|
||||||
|
result = get_datetime_from_str(dt_str, fmt)
|
||||||
|
if expected is None:
|
||||||
|
assert result is None
|
||||||
|
else:
|
||||||
|
assert result == expected.replace(tzinfo=result.tzinfo)
|
||||||
|
|
||||||
|
class TestDictUtils:
|
||||||
|
@pytest.mark.parametrize("original,update,expected", [
|
||||||
|
({"a": 1}, {"b": 2}, {"a": 1, "b": 2}),
|
||||||
|
({"nested": {"a": 1}}, {"nested": {"b": 2}}, {"nested": {"a": 1, "b": 2}}),
|
||||||
|
({"a": {"b": {"c": 1}}}, {"a": {"b": {"c": 2}}}, {"a": {"b": {"c": 2}}}),
|
||||||
|
])
|
||||||
|
def test_update_nested_dict(self, original, update, expected):
|
||||||
|
update_nested_dict(original, update)
|
||||||
|
assert original == expected
|
||||||
|
|
||||||
|
class TestHashingUtils:
|
||||||
|
def test_file_hashing(self, sample_file):
|
||||||
|
expected = hashlib.sha256(b"test content").hexdigest()
|
||||||
|
assert calculate_file_hash(str(sample_file)) == expected
|
||||||
|
|
||||||
|
def test_large_file_hashing(self, tmp_path):
|
||||||
|
file_path = tmp_path / "large.bin"
|
||||||
|
content = b"0" * 16_000_000 * 2 # 32MB
|
||||||
|
file_path.write_bytes(content)
|
||||||
|
|
||||||
|
expected = hashlib.sha256(content).hexdigest()
|
||||||
|
assert calculate_file_hash(str(file_path)) == expected
|
||||||
|
|
||||||
|
class TestMiscUtils:
|
||||||
|
def test_random_str_length(self):
|
||||||
|
for length in [8, 16, 32]:
|
||||||
|
assert len(random_str(length)) == length
|
||||||
|
|
||||||
|
def test_random_str_raises_too_long(self):
|
||||||
|
with pytest.raises(AssertionError) as exc_info:
|
||||||
|
random_str(64)
|
||||||
|
assert "length must be less than 32 as UUID4 is used" == str(exc_info.value)
|
||||||
|
|
||||||
|
def test_random_str_uniqueness(self):
|
||||||
|
assert random_str() != random_str()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("ts_input,utc,iso,expected_type", [
|
||||||
|
(datetime.now(), True, True, str),
|
||||||
|
("2023-01-01T12:00:00+00:00", False, False, datetime),
|
||||||
|
(1672574400, True, True, str),
|
||||||
|
])
|
||||||
|
def test_timestamp_parsing(self, ts_input, utc, iso, expected_type):
|
||||||
|
result = get_timestamp(ts_input, utc=utc, iso=iso)
|
||||||
|
assert isinstance(result, expected_type)
|
||||||
|
|
||||||
|
def test_invalid_timestamp_returns_none(self):
|
||||||
|
assert get_timestamp("invalid-date") is None
|
Ładowanie…
Reference in New Issue