From b9da9421d1f00b336aa34fd224be30d53c3b7f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cminnonymous=E2=80=9D?= <“minhajulhossain@gmail.com”> Date: Tue, 22 Sep 2020 10:32:50 +0530 Subject: [PATCH] First commit after testing successfully --- Pipfile | 24 ++ Pipfile.lock | 379 ++++++++++++++++++ deploy/after_push | 11 + reverse_image_search_bot/__init__.py | 0 reverse_image_search_bot/bot.py | 69 ++++ reverse_image_search_bot/commands.py | 249 ++++++++++++ reverse_image_search_bot/image_search.py | 294 ++++++++++++++ .../images/example_usage.png | Bin 0 -> 113986 bytes .../images/image_reverse_search_logo.png | Bin 0 -> 12384 bytes reverse_image_search_bot/settings (copy 1).py | 13 + reverse_image_search_bot/settings.py | 9 + .../uploaders/__init__.py | 0 .../uploaders/base_uploader.py | 45 +++ .../uploaders/file_system.py | 44 ++ reverse_image_search_bot/uploaders/ssh.py | 77 ++++ reverse_image_search_bot/utils.py | 29 ++ run_bot.py | 3 + 17 files changed, 1246 insertions(+) create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100755 deploy/after_push create mode 100644 reverse_image_search_bot/__init__.py create mode 100644 reverse_image_search_bot/bot.py create mode 100644 reverse_image_search_bot/commands.py create mode 100644 reverse_image_search_bot/image_search.py create mode 100644 reverse_image_search_bot/images/example_usage.png create mode 100644 reverse_image_search_bot/images/image_reverse_search_logo.png create mode 100644 reverse_image_search_bot/settings (copy 1).py create mode 100644 reverse_image_search_bot/settings.py create mode 100644 reverse_image_search_bot/uploaders/__init__.py create mode 100644 reverse_image_search_bot/uploaders/base_uploader.py create mode 100644 reverse_image_search_bot/uploaders/file_system.py create mode 100644 reverse_image_search_bot/uploaders/ssh.py create mode 100644 reverse_image_search_bot/utils.py create mode 100644 run_bot.py diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..c5c1d30 --- /dev/null +++ b/Pipfile @@ -0,0 +1,24 @@ +[[source]] + +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + + +[packages] + +python-telegram-bot = "*" +"bs4" = "*" +requests = "*" +pillow = "*" +paramiko = "*" +moviepy = "*" + + +[dev-packages] + + + +[requires] + +python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..30bc1df --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,379 @@ +{ + "_meta": { + "hash": { + "sha256": "01ee81fa6fde233a2b6df1bb896a8275b4fe226359af86ed1979b2a7cdebeaf7" + }, + "host-environment-markers": { + "implementation_name": "cpython", + "implementation_version": "3.6.3", + "os_name": "posix", + "platform_machine": "x86_64", + "platform_python_implementation": "CPython", + "platform_release": "4.9.0-deepin13-amd64", + "platform_system": "Linux", + "platform_version": "#1 SMP PREEMPT Deepin 4.9.57-1 (2017-10-19)", + "python_full_version": "3.6.3", + "python_version": "3.6", + "sys_platform": "linux" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.6" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "asn1crypto": { + "hashes": [ + "sha256:654b7db3b120e23474e9a1e5e38d268c77e58a9e17d2cb595456c37309846494", + "sha256:0874981329cfebb366d6584c3d16e913f2a0eb026c9463efcc4aaf42a9d94d70" + ], + "version": "==0.23.0" + }, + "bcrypt": { + "hashes": [ + "sha256:f9210820ee4818d84658ed7df16a7f30c9fba7d8b139959950acef91745cc0f7", + "sha256:b1e8491c6740f21b37cca77bc64677696a3fb9f32360794d57fa8477b7329eda", + "sha256:9eced8962ce3b7124fe20fd358cf8c7470706437fa064b9874f849ad4c5866fc", + "sha256:346d6f84ff0b493dbc90c6b77136df83e81f903f0b95525ee80e5e6d5e4eef84", + "sha256:0f317e4ffbdd15c3c0f8ab5fbd86aa9aabc7bea18b5cc5951b456fe39e9f738c", + "sha256:f7fd3ed3745fe6e81e28dc3b3d76cce31525a91f32a387e1febd6b982caf8cdb", + "sha256:3b4c23300c4eded8895442c003ae9b14328ae69309ac5867e7530de8bdd7875d", + "sha256:34dd60b90b0f6de94a89e71fcd19913a30e83091c8468d0923a93a0cccbfbbff", + "sha256:2788c32673a2ad0062bea850ab73cffc0dba874db10d7a3682b6f2f280553f20", + "sha256:6efd9ca20aefbaf2e7e6817a2c6ed4a50ff6900fafdea1bcb1d0e9471743b144", + "sha256:f2fe545d27a619a552396533cddf70d83cecd880a611cdfdbb87ca6aec52f66b", + "sha256:e22f0997622e1ceec834fd25947dc2ee2962c2133ea693d61805bc867abaf7ea", + "sha256:c906bdb482162e9ef48eea9f8c0d967acceb5c84f2d25574c7d2a58d04861df1", + "sha256:43d1960e7db14042319c46925892d5fa99b08ff21d57482e6f5328a1aca03588", + "sha256:321d4d48be25b8d77594d8324c0585c80ae91ac214f62db9098734e5e7fb280f", + "sha256:ae35dbcb6b011af6c840893b32399252d81ff57d52c13e12422e16b5fea1d0fb", + "sha256:09a3b8c258b815eadb611bad04ca15ec77d86aa9ce56070e1af0d5932f17642a", + "sha256:988cac675e25133d01a78f2286189c1f01974470817a33eaf4cfee573cfb72a5", + "sha256:cb18ffdc861dbb244f14be32c47ab69604d0aca415bee53485fcea4f8e93d5ef", + "sha256:8629ea6a8a59f865add1d6a87464c3c676e60101b8d16ef404d0a031424a8491", + "sha256:a005ed6163490988711ff732386b08effcbf8df62ae93dd1e5bda0714fad8afb", + "sha256:d86da365dda59010ba0d1ac45aa78390f56bf7f992e65f70b3b081d5e5257b09", + "sha256:8569844a5d8e1fdde4d7712a05ab2e6061343ac34af6e7e3d7935b2bd1907bfd", + "sha256:0872eeecdf9a429c1420158500eedb323a132bc5bf3339475151c52414729e70", + "sha256:01477981abf74e306e8ee31629a940a5e9138de000c6b0898f7f850461c4a0a5", + "sha256:49e96267cd9be55a349fd74f9852eb9ae2c427cd7f6455d0f1765d7332292832", + "sha256:9a6fedda73aba1568962f7543a1f586051c54febbc74e87769bad6a4b8587c39", + "sha256:054d6e0acaea429e6da3613fcd12d05ee29a531794d96f6ab959f29a39f33391", + "sha256:67ed1a374c9155ec0840214ce804616de49c3df9c5bc66740687c1c9b1cd9e8d" + ], + "version": "==3.1.4" + }, + "beautifulsoup4": { + "hashes": [ + "sha256:7015e76bf32f1f574636c4288399a6de66ce08fb7b2457f628a8d70c0fbabb11", + "sha256:11a9a27b7d3bddc6d86f59fb76afb70e921a25ac2d6cc55b40d072bd68435a76", + "sha256:808b6ac932dccb0a4126558f7dfdcf41710dd44a4ef497a0bb59a77f9f078e89" + ], + "version": "==4.6.0" + }, + "bs4": { + "hashes": [ + "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a" + ], + "version": "==0.0.1" + }, + "certifi": { + "hashes": [ + "sha256:244be0d93b71e93fc0a0a479862051414d0e00e16435707e5bf5000f92e04694", + "sha256:5ec74291ca1136b40f0379e1128ff80e866597e4e2c1e755739a913bbc3613c0" + ], + "version": "==2017.11.5" + }, + "cffi": { + "hashes": [ + "sha256:2c707e97ad7b0417713543be7cb87315c015bb5dd97903480168d60ebe3e313e", + "sha256:6d8c7e20eb90be9e1ccce8e8dd4ee5163b37289fc5708f9eeafc00adc07ba891", + "sha256:627298d788edcb317b6a01347428501e773f5e8f2988407231c07e50e3f6c1cf", + "sha256:bdd28cf8302eeca1b4c70ec727de384d4f6ea640b0e698934fd9b4c3bc88eeb1", + "sha256:248198cb714fe09f5c60b6acba3675d52199c6142641536796cdf89dd45e5590", + "sha256:c962cb68987cbfb70b034f153bfa467c615c0b55305d39b3237c4bdbdbc8b0f4", + "sha256:401ba2f6c1f1672b6c38670e1c00fa5f84f841edd30c32742dab5c7151cd89bf", + "sha256:1c103c0ee8235c47c4892288b2287014f33e7cb24b9d4a665be3aa744377dcb9", + "sha256:d7461ef8671ae40f991384bbc4a6b1b79f4e7175d8052584be44041996f46517", + "sha256:3ac9be5763238da1d6fa467c43e3f86472626837a478588c94165df09e62e120", + "sha256:d54a7c37f954fdbb971873c935a77ddc33690cec9b7ac254d9f948c43c32fa83", + "sha256:4d9bf1b23896bcd4d042e823f50ad36fb6d8e1e645a3dfb2fe2f070851489b92", + "sha256:61cf049b1c649d8eec360a1a1d09a61c37b9b2d542364506e8feb4afd232363d", + "sha256:ce3da410ae2ab8709565cc3b18fbe9a0eb96ea7b2189416098c48d839ecced84", + "sha256:e72d8b5056f967ecb57e166537408bc913f2f97dc568027fb6342fcfa9f81d64", + "sha256:11a8ba88ef6ae89110ef029dae7f1a293365e50bdd0c6ca973beed80cec95ae4", + "sha256:974f69112721ba2e8a6acd0f6b68a5e11432710a3eca4e4e6f4d7aaf99214ed1", + "sha256:062c66dabc3faf8e0db1ca09a6b8e308846e5d35f43bed1a68c492b0d96ac171", + "sha256:03a9b9efc280dbe6be149a7fa689f59a822df009eee633fdaf55a6f38795861f", + "sha256:8b3d6dc9981cedfb1ddcd4600ec0c7f5ac2c6ad2dc482011c7eecb4ae9c819e0", + "sha256:09b7d195d163b515ef7c2b2e26a689c9816c83d5319cceac6c36ffdab97ab048", + "sha256:943b94667749d1cfcd964e215a20b9c891deae913202ee8eacaf2b94164b155f", + "sha256:89829f5cfbcb5ad568a3d61bd23a8e33ad69b488d8f6a385e0097a4c20742a9b", + "sha256:ba78da7c940b041cdbb5aaff5afe11e8a8f25fe19564c12eefea5c5bd86930ca", + "sha256:a79b15b9bb4726672865cf5b0f63dee4835974a2b11b49652d70d49003f5d1f4", + "sha256:f6799913eb510b682de971ddef062bbb4a200f190e55cae81c413bc1fd4733c1", + "sha256:e7f5ad6b12f21b77d3a37d5c67260e464f4e9068eb0c0622f61d0e30390b31b6", + "sha256:5f96c92d5f5713ccb71e76dfa14cf819c59ecb9778e94bcb541e13e6d96d1ce5", + "sha256:5357b465e3d6b98972b7810f9969c913d365e75b09b7ba813f5f0577fe1ac9f4", + "sha256:75e1de9ba7c155d89bcf67d149b1c741df553c8158536e8d27e63167403159af", + "sha256:ab87dd91c0c4073758d07334c1e5f712ce8fe48f007b86f8238773963ee700a6" + ], + "version": "==1.11.2" + }, + "chardet": { + "hashes": [ + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691", + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae" + ], + "version": "==3.0.4" + }, + "cryptography": { + "hashes": [ + "sha256:69285f5615507b6625f89ea1048addd1d9218585fb886eb90bdebb1d2b2d26f5", + "sha256:6cb1224da391fa90f1be524eafb375b62baf8d3df9690b32e8cc475ccfccee5e", + "sha256:4f385ee7d39ee1ed74f1d6b1da03d0734ea82855a7b28a9e6e88c4091bc58664", + "sha256:a5f2c681fd040ed648513939a1dd2242af19bd5e9e79e53b6dcfa33bdae61217", + "sha256:fc2208d95d9ecc8032f5e38330d5ace2e3b0b998e42b08c30c35b2ab3a4a3bc8", + "sha256:0d39a93cf25edeae1f796bbc5960e587f34513a852564f6345ea4491a86c5997", + "sha256:41f94194ae78f83fd94ca94fb8ad65f92210a76a2421169ffa5c33c3ec7605f4", + "sha256:7a2409f1564c84bcf2563d379c9b6148c5bc6b0ae46e109f6a7b4bebadf551df", + "sha256:55555d784cfdf9033e81f044c0df04babed2aa141213765d960d233b0139e353", + "sha256:9a47a80f65f4feaaf8415a40c339806c7d7d867152ddccc6ca87f707c8b7b565", + "sha256:6fb22f63e17813f3d1d8e30dd1e249e2c34233ba1d3de977fd31cb5db764c7d0", + "sha256:ee245f185fae723133511e2450be08a66c2eebb53ad27c0c19b228029f4748a5", + "sha256:9a2945efcff84830c8e237ab037d0269380d75d400a89cc9e5628e52647e21be", + "sha256:2cfcee8829c5dec55597826d52c26bc26e7ce39adb4771584459d0636b0b7108", + "sha256:33b564196dcd563e309a0b07444e31611368afe3a3822160c046f5e4c3b5cdd7", + "sha256:18d0b0fc21f39b35ea469a82584f55eeecec1f65a92d85af712c425bdef627b3", + "sha256:d18df9cf3f3212df28d445ea82ce702c4d7a35817ef7a38ee38879ffa8f7e857", + "sha256:b984523d28737e373c7c35c8b6db6001537609d47534892de189bebebaa42a47", + "sha256:27a208b9600166976182351174948e128818e7fc95cbdba18143f3106a211546", + "sha256:28e4e9a97713aa47b5ef9c5003def2eb58aec89781ef3ef82b1c2916a8b0639b", + "sha256:a3c180d12ffb1d8ee5b33a514a5bcb2a9cc06cc89aa74038015591170c82f55d", + "sha256:8487524a1212223ca6dc7e2c8913024618f7ff29855c98869088e3818d5f6733", + "sha256:e4d967371c5b6b2e67855066471d844c5d52d210c36c28d49a8507b96e2c5291" + ], + "version": "==2.1.4" + }, + "decorator": { + "hashes": [ + "sha256:73cbaadb8bc4e3c65fe1100773d56331a2d756cc0f5c7b9d8d5d5223fe04f600", + "sha256:953d6bf082b100f43229cf547f4f97f97e970f5ad645ee7601d55ff87afdfe76" + ], + "version": "==4.0.11" + }, + "future": { + "hashes": [ + "sha256:e39ced1ab767b5936646cedba8bcce582398233d6a627067d4c6a454c90cfedb" + ], + "version": "==0.16.0" + }, + "idna": { + "hashes": [ + "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4", + "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f" + ], + "version": "==2.6" + }, + "imageio": { + "hashes": [ + "sha256:89d7692d9f513aa21665af7de94948bc1ef110d812fa66c34bfd486590d986bb" + ], + "version": "==2.1.2" + }, + "moviepy": { + "hashes": [ + "sha256:59d550a81ed1c9f6cf167da6d0707cea52ab250ddc2bc6d48b14ab1fc0ea4a0d", + "sha256:c733967656fa4be4c37ec48af72b63ab2991455aa862321437a013705797c4ab" + ], + "version": "==0.2.3.2" + }, + "numpy": { + "hashes": [ + "sha256:910e7ae5eeee8d322775187692c5c66719cd58d230fbfd57245ea3cf75716910", + "sha256:f5c9ca457057cd5e12ddab36cded8b1f38bf1f45bf550d4ca2839b11ec57f597", + "sha256:d29e72413b66df23c75b9b469253c823698ea2e00f58e9e0df64b7a50696e8ac", + "sha256:539345898a4ae17421c159ae2a350901a5e6ce3da8f24168c6c67b3536e13de8", + "sha256:929928932f91082a168e36984179deddd58f8e98822ad2f33a2955d7c4eec596", + "sha256:62b09f3d1ea01d79c16a6642cb21599f53b9338c59971b2418a573155d2202ec", + "sha256:c4b1914d86c43399438518a2ac8bcba2fb64dd5a18efddded3783b9daae70933", + "sha256:6c6feb0647380db6e1d5d49ef9fb59c42240f25fb8df8b6e82ecb436c7e0621a", + "sha256:da2f47e46d7a93b73891d1981378717dc73c6ad5cc4fd23c934bfea7847fa958", + "sha256:4c767b6d9c9a071bb36ea34eb240ee5192fe0bc4c13be5e6c51e0350a30f7ac0", + "sha256:b2f98838f4bbc3bf23af7e97ffcad18a2dc6bbb0726796781e02b9347af6685f", + "sha256:11fcbed36c101a3b9c4636e791efccba82409ebbedaba938c97be8bdddd029cc", + "sha256:8969c8f987f8bcc3e30c014532cfc20e4a8f86a50c361596e086310853adacb7", + "sha256:2875e8055a1ea8d933b1c9d0f8714c0aa11c097bfadfcb8564c4d868fbf09a41", + "sha256:09b87d652c03508447d0f618e1d3ae57595acd3e0f0c11ac91bf68ed7bdb3a28", + "sha256:9cad35b911e150f00bb8080950c7e9f172714bbd0234f5ab74b4e3e2d9288b37", + "sha256:479863de17f66810db00bccf35289555365da45d3b053ccf539b95ab3b9c24f6", + "sha256:b162c6b044960b4ea0f42be049ce2af1d18c60f82748f0a27bd5ad182a731bf3", + "sha256:fa656dccfa9141774440575a6e7875d08b93f4a332eb5ae40877b26bed291c01", + "sha256:7dfa5b49fb2a080bd0d39bfbcff1177bacb14fcb28c857fd65fd0c18938935de", + "sha256:e8e0e75db757e41463888939d26c8058b4ecd25e563c597e9119f512dc0ee1da", + "sha256:c8dc6aa96882df6323bf9545934e37c6e05959bd789ae4b14d50509b093907aa", + "sha256:36ee86d5adbabc4fa2643a073f93d5504bdfed37a149a3a49f4dde259f35a750" + ], + "version": "==1.13.3" + }, + "olefile": { + "hashes": [ + "sha256:61f2ca0cd0aa77279eb943c07f607438edf374096b66332fae1ee64a6f0f73ad" + ], + "version": "==0.44" + }, + "paramiko": { + "hashes": [ + "sha256:8851e728e8b7590989e68e3936c48ee3ca4dad91d29e3d7ff0305b6c5fc582db", + "sha256:486f637f0a33a4792e0e567be37426c287efaa8c4c4a45e3216f9ce7fd70b1fc" + ], + "version": "==2.4.0" + }, + "pillow": { + "hashes": [ + "sha256:cc6a5ed5b8f9d2f25e4e42d562e0ec4df3ce838f9e9b9d9d9b65fac6fe93a4cc", + "sha256:54898190b538a6c8fa4228e866ff2e7609da1ba9fd1d9cc5dc8ca591d37ce0a8", + "sha256:a336596b06e062b92eb8201a3b5dff07ae01c3a5d08ce5539d2da49b123f2be6", + "sha256:922aeb050bd52d8ce9531ab57fd2440bfe975900e8700fec385fb741c3c557c7", + "sha256:6d814aa655d94c63547fc3208cb6ab886ff1a64c543b31f52658663b1bb3f011", + "sha256:e66080685863444738f08e13081c287e340b6e4f8bd674a2e0da967776ac6f46", + "sha256:575a9b3468c82f38be0419cd39d35001ae95a0cc5226534e45430035fecef583", + "sha256:4fb8ab0f8895fb946454ef6ffe806f49ee387095f2d6112ae24670e5fb8fbcd9", + "sha256:1d742642d01914b7e0cf6fd597a51f57d21fd68f794cf84803e03e72db78a261", + "sha256:59cef683d79b85d55a950c1e61dc7b6be0c45a5074692746354cd9a8ace1cd17", + "sha256:822e4fc261d12fa44d88dadee0e93d59663db94d962d4ffffbf09b1fe5e5be51", + "sha256:a6f43511c79bed431ec2b56e55150b5222c732cd9e5f80e77a44e068e94c71fc", + "sha256:2046a2001e2c413998951cc28aa0dbfd4cff846a12e24c2145d42630d5104094", + "sha256:39c7c9dcf64430091e30ef14d4191b4cae9b7b5ff29762357730aac4866fb189", + "sha256:f2d71951f473744ac617b645b62d0c4df5372ef4618c425646bfe5e2e8878e61", + "sha256:9adcfa2477b7e279ebeee75b49f535518201bbd7d26ca2ef1cf6751cb6e658e8", + "sha256:0e3b56364a2c772c961a8faad8a835d3f24d8848310de035c9e07cc006035cbc", + "sha256:92087cb92a968421f42235f7d8153f4766b6ba213a6efb36b8060f3c9d294569", + "sha256:53eaec751151b5713a15b1cd62b06d0fc16d72f56623c15448728c554c30770b", + "sha256:e595312f67962d6b4fde3b7dffaaaca4becefa522d677676bb57b0ec5f8f921a", + "sha256:dc32362d0cadf18c3aef7040455760106cafe7dd3c211dc27c507e746376bb56", + "sha256:759e5e3e99c4ac87b99e9288a75236c63173d1bb24c8d3f9d9d2c8332fceeb0a", + "sha256:b13106cb83a3b7d1a02fafb94bfafbc980465ba948b76ea1996245959c6783d2", + "sha256:9184b9788a9cf677e53626a4dc141136a22d349a5480479b98defd3cfb5015a4", + "sha256:be803fae6af36639524a0f6861a8cface67bbec66c3416c3eaf592f1d45b8b20", + "sha256:effa82e72f5064439a3d2c7ff615b999eb1c4d65bb1f1e6ee6e2ddb345b3e81e", + "sha256:9dc002a914cefa710dcb9fb204d34f6cd822662047a6038178f5fc9bfa7be961", + "sha256:7b3cf7a80608ed661b77793f64e1f2bd1e77136ad0b750aa2c81fac9c7e2c785", + "sha256:a9bad3405a642649e68568fe9832e8f6ae585354ab0b4ae250816ead11a553a2", + "sha256:4d3dbd93b131013a71b2e98530dd4945a03c7994d42381e44a921dd8bec300bc", + "sha256:9a1514bee2e32e0d4c0f55ba7a20f4387f883e37c7d2db64ca50449ffebe86cc", + "sha256:a9721fe1f6fdfe0c108ea81b1a05dc216f1ec5bb65ef1de1d85fd00494d019e0", + "sha256:e75d745306ec8aac0e6903358fdfc7fb6854febe551ed753ee7a1cad058b61bb", + "sha256:ccc9c1f5ba413fc5ee09bc78de7dd2ad8e189edb48f3bc38acedd04a7f43a0c1", + "sha256:150e24462fd106074a9a63417a55fbb0c633716cef9511f1bd7a773972de14f4", + "sha256:250d8470661fd657c2583672ab5139f40e7f2ef28ecdc90f87563af0b27f6fba", + "sha256:a97c715d44efd5b4aa8d739b8fad88b93ed79f1b33fc2822d5802043f3b1b527", + "sha256:dbefe5aa0882f00f12eceb3fb7df57105cd87fae767ca025db4685b7577c2390", + "sha256:62a7bbf0a1120ff07a99ddedd383779a8d80bd9d363f3964b2b43a26cef6ea50", + "sha256:42b4a67949085ddd4559c3c716a00a275fb45cb2c3a3aeec95c4b94419b7c243", + "sha256:0ac037e6c1746d63a1ea354f0d5974d8f3f984fc0333be373ad193711a89b1e9", + "sha256:8989cbf10ea07fc9982ec86116f6234bb3e44da481874ac94650d6176f60106f", + "sha256:77834551d3e928f3da922ce9dfb5c8db46758ea2f2922d4c5835a5b67a222aff", + "sha256:c00301e807084706bd46a1c56694ee235debe68eaf482c0186edfe07b93a9f6a", + "sha256:0163bd681d3488e2e9c26f4fbbfefcfb7f32259c431bfd2c3bc25574708a8b8c", + "sha256:223b06c337d8d60fb65af3b540ab1fa4644931d61d1fddf6e32f7a0e496685f2", + "sha256:1ab641cb7daf88e88ede8d3b89b7bd68a7099d8671160492d5e6845e24426080" + ], + "version": "==4.3.0" + }, + "pyasn1": { + "hashes": [ + "sha256:f81c96761fca60d64b1c9b79ec2e40cf9495a745cf570613079ef324aeb9672b", + "sha256:7d626683e3d792cccc608da02498aff37ab4f3dafd8905d6bf755d11f9b26b43", + "sha256:e85895087905c65b5b594eb91f7522664c85545b147d5f4d4e7b1b07da8dcbdc", + "sha256:5a0db897b311d265cde49615cf783f1c78613138605cdd0f907ecfa5b2aba3ee", + "sha256:d5cd6ed995dba16fad0c521cfe31cd2d68400b53fcc2bce93326829be73ab6d1", + "sha256:a7efe807c4b83a859e2735c692b92ed7b567cfddc4163763412920041d876c2b", + "sha256:b5a9ca48055b9a20f6d1b3d68e38692e5431c86a0f99ea602e61294e891fee5b", + "sha256:c07d6e587b2f928366b1f67c09bda026a3e6fcc99e80a744dc67f8fca3895626", + "sha256:d84c2aea3cf43780e9e6a19f4e4dddee9f6976519020e64e47c57e5c7a8c3dd2", + "sha256:758cb50abddc03e4563fd9e7f03db56e3e87b58c0bd01247360326e5c0c7ffa5", + "sha256:0d7f6e959fe53f3960a23d73f35e1fce61348b30915b6664309ca756de7c1f89", + "sha256:d258b0a71994f7770599835249cece1caef3c70def868c4915e6e5ca49b67d15" + ], + "version": "==0.4.2" + }, + "pycparser": { + "hashes": [ + "sha256:99a8ca03e29851d96616ad0404b4aad7d9ee16f25c9f9708a11faf2810f7b226" + ], + "version": "==2.18" + }, + "pynacl": { + "hashes": [ + "sha256:64d5132fdb54bcfdcc7a531c03980d630469258d8e70d7594ea0d27366fcf834", + "sha256:aa788cff8c027d7d621806d740fb4759028b0bba6dcdf4f316092698ecaad9ab", + "sha256:352584f80d52d53849037d60b90be787638f86d0234209959f68496300425013", + "sha256:abe8bf8908e735db77fd88b972ab1de240962ef91e6b044942f60cfe5a785107", + "sha256:b83e4232b43a52c8802234d575f992f82c1e9c466acd911983613a3823c4dc4e", + "sha256:c7c165b5d43198751651b33d562e57a7bd55d57062678ad14453ef715be415c4", + "sha256:74101b214305b6856d20593ee7e9f77a8f12e24a19caeda7f5fef3638cd8fe17", + "sha256:df4e44c34f3d4d199a06e1c11b7a7357e9adfdfaab34211991b33a58a155daba", + "sha256:976667758a7eb2e555cefbd131df54eea9967002beb73d06f1943127993db566", + "sha256:77c3b6d6fbf8b2137d41be9aed9eff30232287aeba00a6d353aa48fc9de4c55e", + "sha256:2fda81371b8dae1d18e2df9ce06961b66ef0b4226c6c98287e3e4661d9e64317", + "sha256:5bd2f0652fafd61669cbeb6312e9a87817e2e9613a471c588fd2e108e3119bb8", + "sha256:d0c0ca0a0548ed67301424f143c2b8b9d97956b152f8a56a7ebbdadb2071737d", + "sha256:0a85d5dde05a48377675f0c60d4b96127cc1b70097e24f4a4557ae3fa18a0038", + "sha256:8e194ea19c447c4caa94a84316412ad11cfb61f029d408fd4bdc1164ec694578", + "sha256:c05b6e17903509b6fb24f1c41c9760a33a0e0ed2a5aedc8eb9d988e5226377ce", + "sha256:afd47e36aaad8a3b6b92c98e45ca0e7de9627b51d577920af2e2620794503ea1", + "sha256:ac23923052341f35369be898c9673774937aad500fd5693365e3e5e509cbc664", + "sha256:2a8efeb6d442322836e70e6df0094ce8ea46e156e2b4ea38a86fd553c5665fff", + "sha256:189410422028e7b0543dee6aca3da026bbd66bbad078143c46c5a3faf2733acb", + "sha256:5be1af61b69a8dcc0264777c206305a7156c216ba98f6a7864254dfe60be35cf", + "sha256:a018ee272dc064a50cd799fc265d634c54e64a8bdba7a914877f9e1d32184e5e", + "sha256:45c5bcdf8ddefe2e9381f5d37fe778bbda6991fe7004e0b1ea3570df2fc07207" + ], + "version": "==1.2.0" + }, + "python-telegram-bot": { + "hashes": [ + "sha256:997983e5082dc6aa811bce3a6014731201fc64b0a9c02fdb26beac686029d94b", + "sha256:238c4a88b09d93c52d413bcf7e7fe14dfeb02f5f9222ffe4cafd4bd3d55489a3" + ], + "version": "==8.1.1" + }, + "requests": { + "hashes": [ + "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b", + "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e" + ], + "version": "==2.18.4" + }, + "six": { + "hashes": [ + "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb", + "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9" + ], + "version": "==1.11.0" + }, + "tqdm": { + "hashes": [ + "sha256:1621b3476c2224045d8bd57209aab006612a46ae2cc518b4a92ad988983e4c3d", + "sha256:14baa7a9ea7723d46f60de5f8c6f20e840baa7e3e193bf0d9ec5fe9103a15254" + ], + "version": "==4.11.2" + }, + "urllib3": { + "hashes": [ + "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b", + "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f" + ], + "version": "==1.22" + } + }, + "develop": {} +} diff --git a/deploy/after_push b/deploy/after_push new file mode 100755 index 0000000..dc52f51 --- /dev/null +++ b/deploy/after_push @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -e + +echo files changed: $(git diff $oldrev $newrev --diff-filter=ACDMR --name-only | wc -l) + +umask 002 + +git submodule sync && git submodule update --init --recursive +echo "Restarting reverse_image_search_bot.service" +systemctl --user restart reverse_image_search_bot.service +echo "Restarted" diff --git a/reverse_image_search_bot/__init__.py b/reverse_image_search_bot/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/reverse_image_search_bot/bot.py b/reverse_image_search_bot/bot.py new file mode 100644 index 0000000..307f15d --- /dev/null +++ b/reverse_image_search_bot/bot.py @@ -0,0 +1,69 @@ +import logging +import os +import sys +from threading import Thread + +from telegram import Bot, TelegramError, Update +from telegram.ext import CallbackQueryHandler, CommandHandler, Filters, MessageHandler, Updater + +from . import settings +from .commands import best_match, callback_best_match, gif_image_search, group_image_reply_search, image_search_link, \ + start, sticker_image_search, unknown + +logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO) +logger = logging.getLogger(__name__) + + +def error(bot: Bot, update: Update, error: TelegramError): + """Log all errors from the telegram bot api + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + error (:obj:`telegram.error.TelegramError`): Telegram Api TelegramError Object + """ + logger.warning('Update "%s" caused error "%s"' % (update, error)) + + +def main(): + updater = Updater(settings.TELEGRAM_API_TOKEN) + dispatcher = updater.dispatcher + + def stop_and_restart(): + """Gracefully stop the Updater and replace the current process with a new one.""" + updater.stop() + os.execl(sys.executable, sys.executable, *sys.argv) + + def restart(bot: Bot, update: Update): + """Start the restarting process + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + """ + update.message.reply_text('Bot is restarting...') + logger.info('Gracefully restarting...') + Thread(target=stop_and_restart).start() + + dispatcher.add_handler(CommandHandler("start", start)) + dispatcher.add_handler(CommandHandler("help", start)) + dispatcher.add_handler(CommandHandler('restart', restart, filters=Filters.user(username='@c0sm0s0'))) + dispatcher.add_handler(CommandHandler('reply_search', group_image_reply_search)) + dispatcher.add_handler(CommandHandler('best_match', best_match, pass_args=True)) + dispatcher.add_handler(CallbackQueryHandler(callback_best_match)) + + dispatcher.add_handler(MessageHandler(Filters.sticker, sticker_image_search)) + dispatcher.add_handler(MessageHandler(Filters.photo, image_search_link)) + dispatcher.add_handler(MessageHandler(Filters.video | Filters.document, gif_image_search)) + dispatcher.add_handler(MessageHandler(Filters.command, unknown)) + + # log all errors + dispatcher.add_error_handler(error) + + updater.start_polling() + logger.info('Started bot. Waiting for requests...') + updater.idle() + + +if __name__ == '__main__': + main() diff --git a/reverse_image_search_bot/commands.py b/reverse_image_search_bot/commands.py new file mode 100644 index 0000000..54dc452 --- /dev/null +++ b/reverse_image_search_bot/commands.py @@ -0,0 +1,249 @@ +import io +import os +from tempfile import NamedTemporaryFile +from uuid import uuid4 + +from PIL import Image +from moviepy.video.io.VideoFileClip import VideoFileClip +from telegram import Bot, ChatAction, InlineKeyboardButton, InlineKeyboardMarkup, Update +from telegram.parsemode import ParseMode + +from reverse_image_search_bot.utils import dict_to_str +from .image_search import BingReverseImageSearchEngine, \ + GoogleReverseImageSearchEngine, IQDBReverseImageSearchEngine, \ + TinEyeReverseImageSearchEngine, YandexReverseImageSearchEngine + + +def start(bot: Bot, update: Update): + """Send Start / Help message to client. + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + """ + reply = """*ReVot - Reverse Image Search Bot* + +*How to use me* +Send me images or stickers and I will send you direct reverse image search links for IQDB, Google, TinEy, Yandex and Bing. + +*Commands* +- /help, /start: show a help message with information about the bot and it's usage. + +Thank you for using. +(Beta tester Minhajul \@-@/ and Abhyuday \0-0/) +""" + + update.message.reply_text(reply, parse_mode=ParseMode.MARKDOWN) + + current_dir = os.path.dirname(os.path.realpath(__file__)) + image_dir = os.path.join(current_dir, 'images/example_usage.png') + bot.send_photo(update.message.chat_id, photo=open(image_dir, 'rb'), caption='Example Usage') + + +def group_image_reply_search(bot: Bot, update: Update): + """Reverse search for reply mentions to images in groups + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + """ + print(update.message.reply_to_message.document.file_id) + pass + + +def gif_image_search(bot: Bot, update: Update): + """Send a reverse image search link for the GIF sent to us + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + """ + update.message.reply_text('Please wait for your results ...') + bot.send_chat_action(chat_id=update.message.chat_id, action=ChatAction.TYPING) + + document = update.message.document or update.message.video + video = bot.getFile(document.file_id) + + with NamedTemporaryFile() as video_file: + video.download(out=video_file) + video_clip = VideoFileClip(video_file.name, audio=False) + + with NamedTemporaryFile(suffix='.gif') as gif_file: + video_clip.write_gif(gif_file.name) + + dirname = os.path.dirname(gif_file.name) + file_name = os.path.splitext(gif_file.name)[0] + compressed_gif_path = os.path.join(dirname, file_name + '-min.gif') + + os.system('gifsicle -O3 --lossy=50 -o {dst} {src}'.format(dst=compressed_gif_path, src=gif_file.name)) + if os.path.isfile(compressed_gif_path): + general_image_search(bot, update, compressed_gif_path, 'gif') + else: + general_image_search(bot, update, gif_file.name, 'gif') + + +def sticker_image_search(bot: Bot, update: Update): + """Send a reverse image search link for the image of the sticker sent to us + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + """ + update.message.reply_text('Please wait for your results ...') + bot.send_chat_action(chat_id=update.message.chat_id, action=ChatAction.TYPING) + + sticker_image = bot.getFile(update.message.sticker.file_id) + converted_image = io.BytesIO() + + with io.BytesIO() as image_buffer: + sticker_image.download(out=image_buffer) + with io.BufferedReader(image_buffer) as image_file: + pil_image = Image.open(image_file).convert("RGBA") + pil_image.save(converted_image, 'png') + + general_image_search(bot, update, converted_image, 'png') + + +def image_search_link(bot: Bot, update: Update): + """Send a reverse image search link for the image he sent us to the client + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + """ + update.message.reply_text('Please wait for your results ...') + bot.send_chat_action(chat_id=update.message.chat_id, action=ChatAction.TYPING) + + photo = bot.getFile(update.message.photo[-1].file_id) + with io.BytesIO() as image_buffer: + photo.download(out=image_buffer) + with io.BufferedReader(image_buffer) as image_file: + general_image_search(bot, update, image_file) + + +def general_image_search(bot: Bot, update: Update, image_file, image_extension: str=None): + """Send a reverse image search link for the image sent to us + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + image_file: File like image to search for + image_extension (:obj:`str`): What extension the image should have. Default is 'jpg' + """ + image_extension = image_extension or 'jpg' + + iqdb_search = IQDBReverseImageSearchEngine() + google_search = GoogleReverseImageSearchEngine() + tineye_search = TinEyeReverseImageSearchEngine() + bing_search = BingReverseImageSearchEngine() + yandex_search = YandexReverseImageSearchEngine() + + image_url = iqdb_search.upload_image(image_file, 'irs-' + str(uuid4())[:8] + '.' + image_extension) + + iqdb_url = iqdb_search.get_search_link_by_url(image_url) + google_url = google_search.get_search_link_by_url(image_url) + tineye_url = tineye_search.get_search_link_by_url(image_url) + bing_url = bing_search.get_search_link_by_url(image_url) + yandex_url = yandex_search.get_search_link_by_url(image_url) + + button_list = [[ + InlineKeyboardButton(text='Best Match', callback_data='best_match ' + image_url) + ], [ + InlineKeyboardButton(text='Go To Image', url=image_url) + ], [ + InlineKeyboardButton(text='IQDB', url=iqdb_url), + InlineKeyboardButton(text='GOOGLE', url=google_url), + ], [ + InlineKeyboardButton(text='TINEYE', url=tineye_url), + InlineKeyboardButton(text='BING', url=bing_url), + ], [ + InlineKeyboardButton(text='YANDEX', url=yandex_url), + ]] + + reply = 'You can either use "Best Match" to get your best match right here or search for yourself.' + reply_markup = InlineKeyboardMarkup(button_list) + update.message.reply_text( + text=reply, + reply_markup=reply_markup + ) + + +def callback_best_match(bot: Bot, update: Update): + """Find best matches for an image for a :class:`telegram.callbackquery.CallbackQuery`. + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + """ + bot.answer_callback_query(update.callback_query.id, show_alert=False) + url = update.callback_query.data.split(' ')[1] + best_match(bot, update, [url, ]) + + +def best_match(bot: Bot, update: Update, args: list): + """Find best matches for an image. + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + args (:obj:`list`): List of arguments passed by the user + """ + if not args: + update.message.reply_text('You have to give me an URL to make this work.') + return + tineye = TinEyeReverseImageSearchEngine() + iqdb = IQDBReverseImageSearchEngine() + tineye.search_url = args[0] + iqdb.search_url = args[0] + + chat_id = update.effective_chat.id + message = bot.send_message(chat_id, 'Searching for best match on TinEye...') + + match = tineye.best_match + if not match: + bot.edit_message_text( + text='Nothing found on TinEye, searching on IQDB...', + chat_id=chat_id, + message_id=message.message_id + ) + match = iqdb.best_match + + if match: + reply = ( + 'Best Match:\n' + 'Link: [{website_name}]({website})\n'.format( + website_name=match['website_name'], + website=match['website'], + ) + ) + reply += dict_to_str(match, ignore=['website_name', 'website', 'image_url', 'thumbnail']) + + image_url = match.get('image_url', None) or match.get('website', None) + thumbnail = match.get('image_url', None) or match.get('thumbnail', None) + + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton(text='Open', url=image_url), ], ]) + bot.delete_message(chat_id, message.message_id) + + bot.send_photo(chat_id=chat_id, photo=thumbnail) + bot.send_message( + chat_id=chat_id, + text=reply, + reply_markup=reply_markup, + parse_mode=ParseMode.MARKDOWN + ) + else: + bot.edit_message_text( + text='Nothing found on TinEye nor IQDB.', + chat_id=chat_id, + message_id=message.message_id, + ) + + +def unknown(bot: Bot, update: Update): + """Send a error message to the client if the entered command did not work. + + Args: + bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. + update (:obj:`telegram.update.Update`): Telegram Api Update Object + """ + update.message.reply_text("Sorry, I didn't understand that command.") diff --git a/reverse_image_search_bot/image_search.py b/reverse_image_search_bot/image_search.py new file mode 100644 index 0000000..97f5abe --- /dev/null +++ b/reverse_image_search_bot/image_search.py @@ -0,0 +1,294 @@ +import logging +import os +import re +from importlib import import_module +from urllib.parse import quote_plus + +import requests +from bs4 import BeautifulSoup + +from reverse_image_search_bot.settings import UPLOADER + +uploader_pkg_name, uploader_class_name = UPLOADER['uploader'].rsplit('.', 1) +uploader_module = import_module(uploader_pkg_name) +uploader_class = getattr(uploader_module, uploader_class_name) +uploader = uploader_class(UPLOADER['configuration']) + + +class ReverseImageSearchEngine: + """The base class for reverse image search engines to inherit from. + + Attributes: + url_base (:obj:`str`): The base url of the image search engine eg. `https://www.google.com` + url_path (:obj:`str`): The url path to the actual reverse image search function. The google url would look like + this: `/searchbyimage?&image_url={image_url}` + name (:obj:`str`): Name of thi search engine + search_html (:obj:`str`): The html of the last searched image + search_url (:obj:`str`): The image url of the last searched image + + Args: + url_base (:obj:`str`): The base url of the image search engine eg. `https://www.google.com` + url_path (:obj:`str`): The url path to the actual reverse image search function. It must contain `{image_url}`, + in which the url to the image will be placed. The google url would look like this: + `/searchbyimage?&image_url={image_url}` + name (:obj:`str`, optional): Give the Search engine a name if you want + """ + name = 'Base Reverse Image Search Engine' + logger = logging.getLogger(__name__) + + search_html = None + search_url = None + + def __init__(self, url_base, url_path, name=None): + self.url_base = url_base + self.url_path = url_path + self.name = name + + def get_search_link_by_url(self, url): + """Get the reverse image search link for the given url + + Args: + url (:obj:`str`): Link to the image + + Returns: + :obj:`str`: Generated reverse image search engine for the given image + """ + self.search_url = url + self.search_html = '' + return self.url_base + self.url_path.format(image_url=quote_plus(url)) + + def get_search_link_by_file(self, file_): + """Get the reverse image search link for the given file + + Args: + file_: File like object + + Returns: + :obj:`str`: Generated reverse image search engine for the given image + """ + return self.get_search_link_by_url(self.upload_image(file_)) + + def upload_image(self, image_file, file_name: str = None): + """Upload the given image to the in the settings specified place. + + Args: + image_file: File like object of an image or path to an image + file_name (:obj:`str`): Name of the given file. Can be left empty if image_file is a file path + Returns: + :obj:`str`: Url to the uploaded image + Raises: + ValueError: If the image_file is an file like object and the file_name has not been set. + """ + if not file_name: + if not isinstance(image_file, str): + error_message = 'When image_file is a file like object the file_name must be set.' + self.logger.warning(error_message) + raise ValueError(error_message) + file_name = os.path.basename(image_file) + + uploader.connect() + uploader.upload(image_file, file_name) + uploader.close() + + path = UPLOADER.get('url', None) or UPLOADER['configuration'].get('path', None) or '' + return os.path.join(path, file_name) + + def get_html(self, url=None): + """Get the HTML of the image search site. + + Args: + url (:obj:`str`): Link to the image, if no url is given it takes the last searched image url + + Returns: + :obj:`str`: HTML of the image search site + + Raises: + ValueError: If no url is defined and no last_searched_url is available + """ + if not url: + if not self.search_url: + raise ValueError('No url defined and no last_searched_url available!') + url = self.search_url + if url == self.search_url and self.search_html: + return self.search_html + + request = requests.get(self.get_search_link_by_url(url)) + self.search_html = request.text + return self.search_html + + @property + def best_match(self): + """Get info about the best matching image found + + Notes: + This function must be individually made for every new search engine. This is because every search engine + gives other data. Normally the return value should look something like this: + ``` + { + 'thumbnail': str 'LINK_TO_THUMBNAIL', + 'website': str 'LINK_TO_FOUND_IMAGE', + 'website_name': str 'NAME_OF_WEBSITE_IMAGE_FOUND_ON', + 'size': { + 'width': int 'IMAGE_WIDTH', + 'height': int 'IMAGE_HEIGHT' + }, + 'similarity': float 'SIMILARITY_IN_%_TO_ORIGINAL' + } + ``` + + Returns: + :obj:`dict`: Dictionary of the found image + + Raises: + ValueError: If not image was given to this class yet + """ + return None + + +class GoogleReverseImageSearchEngine(ReverseImageSearchEngine): + """A :class:`ReverseImageSearchEngine` configured for google.com""" + + def __init__(self): + super(GoogleReverseImageSearchEngine, self).__init__( + url_base='https://www.google.com', + url_path='/searchbyimage?&image_url={image_url}', + name='Google' + ) + + +class IQDBReverseImageSearchEngine(ReverseImageSearchEngine): + """A :class:`ReverseImageSearchEngine` configured for iqdb.org""" + + def __init__(self): + super(IQDBReverseImageSearchEngine, self).__init__( + url_base='http://iqdb.org', + url_path='?url={image_url}', + name='iqdb' + ) + + @property + def best_match(self): + if not self.search_html: + if not self.search_url: + raise ValueError('No image given yet!') + self.get_html(self.search_url) + soup = BeautifulSoup(self.search_html, "html.parser") + best_match = soup.find('th', text='Best match') + + if not best_match: + return + table = best_match.find_parent('table') + size_match = re.match('\d*×\d*', table.find('td', text=re.compile('×')).text) + size = size_match[0] + safe = size_match.string.replace(size, '').strip(' []') + + website = table.select('td.image a')[0].attrs['href'] + if not website.startswith('http'): + website = 'http://' + website.lstrip('/ ') + best_match = { + 'thumbnail': self.url_base + table.select('td.image img')[0].attrs['src'], + 'website': website, + 'website_name': table + .find('img', {'class': 'service-icon'}) + .find_parent('td') + .find(text=True, recursive=False) + .strip(), + 'size': { + 'width': int(size.split('×')[0]), + 'height': int(size.split('×')[1]) + }, + 'sfw': safe, + 'similarity': float(re.match('\d*', table.find('td', text=re.compile('similarity')).text)[0]), + 'provided by': '[IQDB](http://iqdb.org/)', + } + + return best_match + + +class TinEyeReverseImageSearchEngine(ReverseImageSearchEngine): + """A :class:`ReverseImageSearchEngine` configured for tineye.com""" + + def __init__(self): + super(TinEyeReverseImageSearchEngine, self).__init__( + url_base='https://tineye.com', + url_path='/search?url={image_url}', + name='TinEye' + ) + + @property + def best_match(self): + """ + + Returns: + + """ + if not self.search_html: + if not self.search_url: + raise ValueError('No image given yet!') + self.get_html(self.search_url) + soup = BeautifulSoup(self.search_html, 'html.parser') + + match = soup.find('div', {'class', 'match'}) + if not match: + return + image_url = match.find('p', {'class': 'image-link'}).find('a').get('href') + + if not self.check_image_availability(image_url): + match = match.find_next('div', {'class', 'match'}) + if not match: + return + image_url = match.find('p', {'class': 'image-link'}).find('a').get('href') + if not self.check_image_availability(image_url): + return + + match_row = match.find_parent('div', {'class': 'match-row'}) + match_thumb = match_row.find('div', {'class': 'match-thumb'}) + info = match_thumb.find('p').text + info = [element.strip() for element in info.split(',')] + + return { + 'thumbnail': match_thumb.find('img').get('src'), + 'website_name': match.find('h4').text, + 'website': match.find('span', text='Found on: ').find_next('a').get('href'), + 'image_url': image_url, + 'type': info[0], + 'size': { + 'width': int(info[1].split('x')[0]), + 'height': int(info[1].split('x')[1]) + }, + 'volume': info[2], + 'provided by': '[TinEye](https://tineye.com/)', + } + + def check_image_availability(self, url: str): + """Check if image is still available + + Args: + url (:obj:`str`): Url to image to check + """ + try: + return requests.head(url) == 200 + except: + pass + + +class BingReverseImageSearchEngine(ReverseImageSearchEngine): + """A :class:`ReverseImageSearchEngine` configured for bing.com""" + + def __init__(self): + super(BingReverseImageSearchEngine, self).__init__( + url_base='https://www.bing.com', + url_path='/images/search?q=imgurl:{image_url}&view=detailv2&iss=sbi', + name='Bing' + ) + + +class YandexReverseImageSearchEngine(ReverseImageSearchEngine): + """A :class:`ReverseImageSearchEngine` configured for yandex.com""" + + def __init__(self): + super(YandexReverseImageSearchEngine, self).__init__( + url_base='https://yandex.com', + url_path='/images/search?url={image_url}&rpt=imageview', + name='Yandex' + ) diff --git a/reverse_image_search_bot/images/example_usage.png b/reverse_image_search_bot/images/example_usage.png new file mode 100644 index 0000000000000000000000000000000000000000..955d161e5ca4ae3e94a0c9479407a2f27afade1c GIT binary patch literal 113986 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

tomm06_yIf6E&r1)$IZ9e&+G4bf*2FF3Wj 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 literal 0 HcmV?d00001 diff --git a/reverse_image_search_bot/images/image_reverse_search_logo.png b/reverse_image_search_bot/images/image_reverse_search_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1f67f11c26d642dc0c1553fbf60bdf8ce6e38e01 GIT binary patch literal 12384 zcmb_i30zah);~81BuYqvYtR4z`|1v{Y6aP%V72nx+qxn_ZBbDPC}o$6SVF~$?XzkX zSzM~mTEwaqMIaaz>jJm|T7)1XSP-Hhgf-up8*KIYY~Opo4}Qtqd*;kJ|2cEc%$b>d zIeX?*^WKAc1AzI5(>&(_aPW}>JX0*9twzRTVY7&s5^$%vO8~n@8j7r|ku>oq`XSb^Q zm^ivN_ckpUrguz^zlEF$f*1eCBCBl|4I1HrVD-KE{4vo z`TsC9_?8_?nqZAsLgUax%Pdocha|UM)@qJx_J*XmT9S^_Kc8-Ih#DRD%)Yw*_ACG% z(39K`Rz9__9%^OPqsFvl+vTiL7}Dx*JUhn;Amwl;PFU8xyTA8s9dDbXc&B&l5j3q5@m2 zqG;=|Gd4XH)hD~893r-8Ok<0tjbG(`we9L;Mx#zOtgJtyF|S8~OdpG2Xn)KEcf@`HaAd19IDQw9B{>yM_7>0~FIECg5*=L||I_h=;wqN_96bjpq( zZ1Tei1HhgbEur@YG1Y4l@SzxB%_`NB|ml`9B^%x!-MyMpx*$^*AGR zUYQD#cp@B&aT_ zj?CS*D*5LD1F%L8YF%Q?mG#!lGY*(<4Yy&KI+$W)jVa>1%h&xtocISEF_gnMh+Dj8 zWhOJvBgHe%eY8zAuA+Pauf&pAw9+Ov-d|W^jn8UUYIE%^BbmB-%mw!2$w| zFB56^E#qKiqm55$yma+ywa-Pwsb0K$PM9so|zHkav{*Cs0jv09UC}?!VeLB0H?rDXOjg#I zDmi`h=C0nryQ2Eu+;BsD*;%#9aZbU#;72bg?42_6hZ3BQqJFVSYTMI?Wq)ADfhk7Z zas3t;1~r|GxwhxD8Q^)8rr-LjMF*xO}p^u_$U z;>-IqW5jc_H=?UwMDGkR6{wT_3faI?a_QKNSedrHIh+L?-Gx4m$1F$D72ZD_lH786 zuwd)h5!Ks+&@n)}tc+6VCv>uNziql49P!zv-e~=gzVGMrwXz|vLPV|g(Ih3R`8eeL zzdP)opisibvpc;D?U)hW;j8DCj9(f+OyWE0A+4AO7IekPYJ~;RQ>uN-I<{w3Rw$s< z`RQJe*OXB@GoSVvky&O#iQRsTXthb(t=!xEssa(%;Xll_wV{-?K{{?h`i|vjj4v_{ zv!H(%XK8Yv>A_N zg3=H&rb-^S-hGC}&lGW$Un&P@2*1P`>=}#JeC;to;m!i}R8W?h)_cw9dyep=U9laU z;ZAtExb$3swYSP&?Pdb=rRS488~{f zTaL#+UL2B3K@5uyF<2#29Sc@0@*@(B-j&y&E)iQstMWrP04 z0E&0Rd-l=^6kWgqK{m8_0A0YQL&iuxr|J`yx+9$}AAae;k8M;Ot2oKS_B={UzVAmOUduLMM+#12~MIdo2_AKZupa% zEbYC`w^K;-hhdf5AByUpnMO=Mn0wcn4W8es0)4s~e{(waB5HQ4epB}2Z>BpP412!s zJqv4p(E8o2pcIas4cAHn;x=mcm#j?G_!bNn%0M*tMF@!d<}Yp?NV(a$aoYG!_UR>s*-LIa`3a9i z4Z=?)f*m~{2C~ENam!3}HXAn$ zMDLVLraWor=mQq&NvJ02;~w| zbkypvkH6m%8sUPCM`^MQG<7S74@FTB-)*nib-Y4SPaWBoSVQ3w^If(=!EI6b@SYPOnI0NP{MzBeK45KE8Vra_@TqkNeK>Y4p6E0C-sTt zs?WAv8i3KO&M+%YsZCZ2kzedc%QOdYf)>FhYmSvQ+71`pRFAJc(i16+U)p1c;y4Q% z>AwpR!bxZ~3jq{nqfN;* zgcn=u%M7l?wx!5VYorR@@rSu=FV{kxB|xnWDC#{$Zvq#%p!!65OPAXmU6I@yO8L-(51P8(MZ#*`np_z`a z<|pkRnH-CjQ`(k4MQdUwYd42DwavSL0b&P^QudPM?14ZhaOsujud%_dAIbyK4mnv( z@K63LCB6SNy8HpQm99WSPQrjKQD_pTmWHBt&loT}6TJsJf-?4l&MZ$1wf1oR_E-H) zXzldjI3D51eJnrg`kiIC_!78+`?S9enS!BqM<@q2^o7m_2gUZL0Gzw!5dR1x8Jk(p zxq8zMffwbp+I*G(d3T$)WrZ02dDCSrBLuS>*QGcBK>G>+e&d5%4L2T6bO*3OG!8u5 zlTz3dyqQX4PH~@OZVF0!hnZbM&vp|!>7*Zjpk;S-r@>F}@6K^~ z5!kxBwGrVzdGW)p0W4TK5`maN<|881iXH#7OLfoN4b+#~c<_-+XG(i6x9GPVE}BHt zBB~de6RQrCZ4DU^b5|9DsL}Ta>^ymB|F$%5G!`1HHc~&3O0~)9*9TUPfE{y>Nso;? zNXA`#iKTY&UOZ_*pyNOsDLR1zimtRJ99UhmZ4!#vGiGZx*h6= zh*3#$m(`2(*zwC(X)=Y+LJDr5<_^X#%Eom>{MOwu1$OROkJ@Q~xKE?!kB&ZrNXW~S zXrJx5^U)jx-u~RNS1N|H&^6Hwp1tGW_2{6p)iK;ml0G=NbSA*lPH#Kx0=^GO8QT}gN%%@r#`=JeMM_>q?{#K)luC!gsSy@vt6hRivK*)xPnk-&X zK`J^iL5+dVdrv`z5Uq@ZyNO?H2hq!zWB{#3B)ZK`fXVa}WYlT26k zfI@`Z^A`44CYL8#p};62rbi(h%N?&aS@E(-+7R`i#2QR_=P#V_l4d(Zy+~u&Q}=EU zLidk23nCEO0XjCJ!-LgN zhqCWXWY4`-=EocvG>Oa4Iez4?hdXEx@fsB=s}ZNgT|$``uweT#1*7rH_O zT)B6HEzUW1IDanUPVGR~wy#^A+W#fgDDzWx2!S~Ak0*HwV-V>AvZsLm06L$8HXkt$ zA;pdGBq=jcsUb}p)>`oA#bc80a$DBGOp*$HtD|@&u8g}#EER>r?B+3@Ls-NF93E_O zi;HGj)5NC@q-C)c3O+X%XI`luy|(noIkh zKe@$GKKE`_>90+fnsVLk%%ErmTyZLx!8z2gP^=Mt>zz$Mpk~jR~70&L6<$L!WMGHldRbLy<4U zH+w;HSxZ89k1yMTGh-{8lILTt z-gm*W-CeB)Uw2bT#e+VYr`AMv+o07XkASfkU~&IFoNfWK(I{mL=iq)zi&+%25;_GO z8-{HhBG>TAI_X$M8T}D{FS@?`{LJne%mI7D&87M%KFAJYguREz8JEUlbEW+lM5t7= zMU-v{3+@X6mq1g@5LxI-o^)-Q6|?UN#{ngV#3FeD$UP|aB%qI!^*4phy+II(byEE7 z!wu>bz??!MZoDvhxU;(Z~~=y&fR952fo(7 zC#QEm{&lZ1`lL@6*(2p43)tc4#j79q01a9x54?kR*7orM__JB@^~96$HR z;aZ0Y8{ILbOH5}0)Hk_ay%)ixYFLfBg4fr4bGqFMa|~Q&7Q5l;+tc+O?kEmKahYaV zIu2VjSUYe|Bh=mO@p(ZE{Mh%=vD=N0l3XcNqmH?GpRU6!lA`TLg>hAtY`&p*M1wyD z;VOuaq?K2?yV@5FQQn|HxzS-1bz1N@xlQ<%oR)VX^;0*N7A)IkLOR<9eURG=>R%Wd zZ|CQ+@dyE2_We4Iy8pcW?zN2Q4&CQ9y%4f`RhdbVeWI1;xR9c76U^+VQ;U6aCt7J4aex~f*q!i|Mu_`0$6RS(|f zejppwqR7d9mWpOa2a^|;oL_8sT7{4tm5!m|qo|UJI7l>4A)^<>MkkhJh8UuT3bAK# zAMkt0YdTI<8r&lpf@Az3v0B@>$P^u&pWrp@(D9VC_grZIGoO@qwYHm~_#gHhc8iXi z&V!QGGo}x>UIWt2c+NXwmfIo8IV(D4Jugx1tW@NlXbr8W=<4%FUf4YLiq9E&=wQ-G z%}_k`0`0w{-8?n!PFyArKNNNj=PSR*#fC=C0#x}4Ib*SCcW9hTCGE;2w*TmdGd?D; zAmK>+z7PY2!65tRc84h($9=m=?YO+GPvEe{yxhL`NSz!Pfcg~1p~T&bho+-5X;U9c zakii#Bi*+w?4l=--Kl3V>N>is>GF`rvtMpr5AL`nYryTTxI5*SECZSj6Q}w)>(%Jw zsjaa6n-B-mc7Mq%ka~jJcc6MBW^?aA=)kItB+(IfKRee8n)^a#1?FcQ>9M(j0eLzh zG>bv9vZ3aIgY;p>BP2V&6*?-N2^Vi9EQdt?35X z#03jE2kMvK471|E1>9=lS;YL0G{5330Lx6EaU(gc_%Z(Z-OF|);N{cHO#*kD*3Ul? zUjgz`(0YqhtC^DzT-m<~@sOlb9rO508-dp0E^LiDXN4X!+CCuJD*2h}z_n>o1BfWe zIjUoO3C=kBy7Q2DP|9 zN<61=Qbe!%CLWK~VAi7teN`LOIk)UA2IGLCd4f|d4@sU5U3!MBA{I~^CHxLgrtpNB zOgA5oxZw(aE^A2e_@~E{^dnb?w)DpB(_iSq@iGeM zt83M(96c~YZ3QM7g_hl9&#YRmTCVQ?EE=~@V1G;^T$Pi3LL|7V(B&taVmx&f7w$Oz{(w9g z%X?V0Hhe6a*5dI3JYSh>m7HgNIVdu>7tA&r+9!6^SdZz$r*ur#!vRxMzuMxVZRsvDc&ewLwS6->19w%p1N2)K zq_4Z+vew*L=d-c6uv-X9n-Cavg(|a^*gNZYjl=!^g&Z~pWjqKT6)_hd8|eCe4jw*l_nliHG)$c>HfL0Q)dPKW43nS4o*a5#`}go@4TdId~tcb8EJbJ z_$!zCx#XiGs4MyE*^ggbYBDDkcYwcq>AVq-A}Bbrui~e`T9XXnGQE3j*twb2p&26h z=o%iNuLEygLtU8u+wYo0`^o6Uvt?_-9_Y?<=#TY0d45oVz=pOp(-@|geZ`drkKK>g zNR#o(DlS@+TQdTes>wjdT-7Dki~=j21#m^svAZ(mi(WcBzqbNkVU%hd?rK;v{ow9r zE~Zjm2ypP&-IgO8XW4yL7Q%vz-z0eZP-YI|PIE)(I(CtJ2x!-VnqHx=xlq;%9Zvn5 z>ZyZI?n0j8MfMe40NLGWJ0mg3`lKGMv_TlIXqF|N>QLskgQl+N68(V|=y@Q-%fJ}U zf;+ellIiao=SDn}*jgh1$xM1Y(U)nDUB;UkwjeILgok2y6rE?P$@RwrFW3xf*>Zh; zFwT46C2g^Vy;A+u_QTBh(}m$+h0HeQ#IAfh$7l{WQc z{&bYbvfW$k>wDpIkyS;1nvFZ23|vM*t27rhmmbLQ!)H47eaDN-XI%*C{i_#%u#)^1 z0Owi&LAkbQn=7xQ7YcWbkM)?CTNN=qBbPK0%V!&JzBWghdXjip;4$3jHe4m&P#TNY zROeYqGEXEbW})Tjb!VMH<&QOou|~Q~awN}jn)9?FplBo<3nrzK`|#15J;sW= zPoz+&graxqzu&k7H)e>RPE$`3FR3Z*KmnkceB=DdME^mk8Y5+kkF{fPQN`h;lV4~r zl&r;=Tx*LSf_xrv?2)cb4el);Aw;$8IcMGN{PA4Ij=5yM!tzH!Fyh-A1@Fm?til0g3riu#>jfqyNE|Wd{DXxYW7}HqocjxUo?jQY zlKehlG}$tfZogKX%EKA#RmiCWHJNAdj1h+min2(az*vCh#RdA2oC}eshTwJS>(Vyl z&0=k0_B=FMoLWw z*MCR&3uM1z{{slY#HfFX=MBPJ@Gyu89tQDS@E}&?cm?sl0VriSjOrPHgz!HCq_OEs zJpU^|qMjLB9H`&%yg{&|iPw@C!*6m$LB9VW$gzSUa2O6xCbUJEs=%KTkdNWOZ(|dN zfWjF9(dOBs4GBhVe@!3&{{_z*g#QGfQ9UYt9nTvC5zZ!Wg(`;(v;gsTDfWgLE2Eu_ z1jbd~LNI#jYa@Yf$BY$?B{NopKzxS~(539)F9_HOwY`Do4FdB02|%Llcl89|pA-HZ zpb?LhB}Jhx?ehknHwdo*>`@;NM*ConkFx$7fQ)nFFf-0g#**>nw-Ah@%{aG_VoRf8co4-TvWSn9IH9p*!r~=CY9#a& z$1Zv^p-#e+kT4v23d{m%Bw*W~qWQv0R*~oMsR>f7L+-m{6B`TKUT@!H>z<KE6OnBPcqg;&k7se~fJuaIVZ8k?+Lb00GuX+t z(&r6MR?^{NtsU&R!R6bDDuuf8DWfw^QofZT6jlDn_=PXGJf0B5p`n8rLYitq3`2+v zHDd^sstHntKxg710BRRq+=u71*dN=5MWmGRAB-XWP)Hv#x3S=15kl_jK)f~6i@~kD z$lT|G={pTGNrmj4KtHDElfKNtUwERayh1jUQlU6En6v6>$h{82oE`i$yZqwM%-M$RM^!KLh?DCYL+@qS?sBXPGi2HPzXh!+=U<+=w>plMwh!FKMFpuOA5j ykdiO>t4EsQ`p<+*8Q#B=_=?I`gsamcDW5Sj*A6L9#GeTOd^lyMXZmEtrvC$=z51sB literal 0 HcmV?d00001 diff --git a/reverse_image_search_bot/settings (copy 1).py b/reverse_image_search_bot/settings (copy 1).py new file mode 100644 index 0000000..c025cdf --- /dev/null +++ b/reverse_image_search_bot/settings (copy 1).py @@ -0,0 +1,13 @@ +TELEGRAM_API_TOKEN = '1261335554:AAEaPdqhclx4Ja_s40lIq1frOZz1cWYeY8g' + +UPLOADER = { + 'uploader': 'reverse_image_search_bot.uploaders.ssh.SSHUploader', + 'url': 'http://207.46.226.161', + 'configuration': { + 'host': '207.46.226.161', + 'user': 'revotadmin', + 'password': 'C0sm0s0101010', + 'upload_dir': '/home/revotadmin/ReVot/upload_tel/', + 'key_filename': '/home/revotadmin/.ssh/id_rsa.pub', + } +} diff --git a/reverse_image_search_bot/settings.py b/reverse_image_search_bot/settings.py new file mode 100644 index 0000000..b27ae9b --- /dev/null +++ b/reverse_image_search_bot/settings.py @@ -0,0 +1,9 @@ +TELEGRAM_API_TOKEN = '1261335554:AAEaPdqhclx4Ja_s40lIq1frOZz1cWYeY8g' + +UPLOADER = { + 'uploader': 'reverse_image_search_bot.uploaders.file_system.FileSystemUploader', + 'url': 'http://207.46.226.161:8080', + 'configuration': { + 'path': '/home/revotadmin/ReVot/', + } +} diff --git a/reverse_image_search_bot/uploaders/__init__.py b/reverse_image_search_bot/uploaders/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/reverse_image_search_bot/uploaders/base_uploader.py b/reverse_image_search_bot/uploaders/base_uploader.py new file mode 100644 index 0000000..d4dbe04 --- /dev/null +++ b/reverse_image_search_bot/uploaders/base_uploader.py @@ -0,0 +1,45 @@ +class UploaderBase: + """Base class for other uploader's to inherit from to ensure to use the same methods and attributes. + + Attributes: + configuration (:obj:`dict`): Configuration of this uploader + Args: + configuration (:obj:`dict`): Configuration of this uploader + connect (:obj:`bool`): If the uploader should directly connect to the server + """ + + _mandatory_configuration = {} + """(:obj:`dict`): Mandatory configuration settings. + + Usage: + {'some_key': type}: + - 'some_key' is a key name like 'host' + - type is a python object like :class:`str` + """ + + def __init__(self, configuration: dict, connect: bool=False): + for key, type_ in self._mandatory_configuration.items(): + if key not in configuration: + raise KeyError('Configuration must contain key: "%s"' % key) + if not isinstance(configuration[key], type_): + raise TypeError('Configuration key "%s" must be instance of "%s"' % (key, type_)) + + self.configuration = configuration + if connect: + self.connect() + + def connect(self): + """Connect to the server defined in the configuration""" + pass + + def close(self): + """Close connection to the server""" + pass + + def upload(self, file): + """Upload a file to the server + + Args: + file: file like object or a path to a file + """ + pass diff --git a/reverse_image_search_bot/uploaders/file_system.py b/reverse_image_search_bot/uploaders/file_system.py new file mode 100644 index 0000000..0446ad4 --- /dev/null +++ b/reverse_image_search_bot/uploaders/file_system.py @@ -0,0 +1,44 @@ +import os +from tempfile import NamedTemporaryFile + +from .base_uploader import UploaderBase + + +class FileSystemUploader(UploaderBase): + """Save files on file system + """ + + _mandatory_configuration = {'path': str} + + def upload(self, file, filename: str = None, save_path: str = None): + """Upload file to the ssh server + + Args: + file: Path to file on file system or file like object. If a file path is given the file is copied to the new + place not moved. + filename (:obj:`str`): New filename, must be set if file is a file like object + save_path (:obj:`str`): Directory where to save the file. Joins with the configurations path. Creates + directory if it does not exist yet. + """ + is_file_object = bool(getattr(file, 'read', False)) + if is_file_object: + if filename is None: + raise ValueError('filename must be set when file is a file like object') + with NamedTemporaryFile(delete=False) as new_file: + file.seek(0) + new_file.write(file.read()) + + real_file = new_file.name + filename = filename + else: + real_file = file + filename = filename or os.path.basename(real_file) + + save_dir = os.path.join(self.configuration['path'], save_path) if save_path else \ + self.configuration['path'] + save_path = os.path.join(save_dir, filename) + os.makedirs(save_dir, exist_ok=True) + + os.system('cp {src} {dst} && chmod 664 {dst}'.format(src=real_file, dst=save_path)) + if is_file_object: + os.unlink(real_file) diff --git a/reverse_image_search_bot/uploaders/ssh.py b/reverse_image_search_bot/uploaders/ssh.py new file mode 100644 index 0000000..fc92fc6 --- /dev/null +++ b/reverse_image_search_bot/uploaders/ssh.py @@ -0,0 +1,77 @@ +import os +from tempfile import NamedTemporaryFile + +import paramiko + +from .base_uploader import UploaderBase + + +class SSHUploader(UploaderBase): + """Upload files to an ssh server via paramiko http://www.paramiko.org/ + + Attributes: + configuration (:obj:`dict`): Configuration of this uploader + ssh (:obj:`paramiko.client.SSHClient`): Connection to the ssh server + sftp (:obj:`paramiko.sftp_client.SFTPClient`): Connection via sftp to the ssh server + Args: + configuration (:obj:`dict`): Configuration of this uploader. Must contain these key: host, user, password, + key_filename, upload_dir, ssh_authentication + connect (:obj:`bool`): If the uploader should directly connect to the server + """ + + _mandatory_configuration = {'host': str, 'user': str, 'password': str, 'upload_dir': str} + + def __init__(self, configuration: dict, connect: bool = False): + self.ssh = None + self.sftp = None + + super().__init__(configuration, connect) + + def connect(self): + self.ssh = paramiko.SSHClient() + self.ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts"))) + + if self.configuration.get('key_filename', None): + self.ssh.connect(self.configuration['host'], + username=self.configuration['user'], + password=self.configuration['password'], + key_filename=self.configuration['key_filename']) + else: + self.ssh.connect(self.configuration['host'], + username=self.configuration['user'], + password=self.configuration['password']) + self.sftp = self.ssh.open_sftp() + + def close(self): + self.sftp.close() + self.ssh.close() + + def upload(self, file, filename: str = None, upload_dir: str = None): + """Upload file to the ssh server + + Args: + file: Path to file on file system or a file like object + filename (:obj:`str`): Filename on the server. This is mandatory if your file is a file like object. + upload_dir (:obj:`str`): Upload directory on server. Joins with the configurations upload_dir + """ + is_file_object = bool(getattr(file, 'read', False)) + if is_file_object: + if filename is None: + raise ValueError('filename must be set when file is a file like object') + with NamedTemporaryFile(delete=False) as new_file: + file.seek(0) + new_file.write(file.read()) + + real_file = new_file.name + filename = filename + else: + real_file = file + filename = filename or os.path.basename(real_file) + + upload_dir = os.path.join(self.configuration['upload_dir'], upload_dir) if upload_dir else \ + self.configuration['upload_dir'] + upload_path = os.path.join(upload_dir, filename) + + self.sftp.put(real_file, upload_path) + if is_file_object: + os.unlink(real_file) diff --git a/reverse_image_search_bot/utils.py b/reverse_image_search_bot/utils.py new file mode 100644 index 0000000..70c8c47 --- /dev/null +++ b/reverse_image_search_bot/utils.py @@ -0,0 +1,29 @@ +def dict_to_str(items: dict, depth: int = 0, ignore: list = None): + """Generate string from dict. + + Notes: + Dict can be multidimensional. + + Args: + items (:obj:`dict`): + depth (:obj:`int`): How many whitespaces come in front of the new line times 2 + ignore (:obj:`list`): List of keys to ignore + + Returns: + :obj:`str`: String with the information generated by the given dict + """ + ignore = ignore or [] + result = '\n' if depth else '' + for index, (name, value) in enumerate(items.items()): + result += ' ' * depth + if name not in ignore and value: + value_str = value + if isinstance(value, list): + value_str = ', '.join(value) + elif isinstance(value, dict): + value_str = dict_to_str(value, depth + 1) + result += '{name}: {value}'.format(name=name.capitalize(), value=value_str) + if index + 1 < len(items): + result += '\n' + + return result diff --git a/run_bot.py b/run_bot.py new file mode 100644 index 0000000..dacf547 --- /dev/null +++ b/run_bot.py @@ -0,0 +1,3 @@ +from reverse_image_search_bot import bot +if __name__ == '__main__': + bot.main()