From 950a93362184321cab21464956b822687815b2ed Mon Sep 17 00:00:00 2001 From: Matt Behrens Date: Sat, 17 Mar 2018 18:06:43 -0400 Subject: [PATCH] modularize and pylint --- Pipfile | 1 + Pipfile.lock | 304 ++++++++++++++++++++++++++----------------- fediplay.py | 142 -------------------- fediplay/__init__.py | 0 fediplay/__main__.py | 5 + fediplay/main.py | 35 +++++ fediplay/mastodon.py | 73 +++++++++++ fediplay/queue.py | 83 ++++++++++++ setup.py | 2 +- 9 files changed, 383 insertions(+), 262 deletions(-) delete mode 100644 fediplay.py create mode 100644 fediplay/__init__.py create mode 100644 fediplay/__main__.py create mode 100644 fediplay/main.py create mode 100644 fediplay/mastodon.py create mode 100644 fediplay/queue.py diff --git a/Pipfile b/Pipfile index 75bc3d7..f4b2536 100644 --- a/Pipfile +++ b/Pipfile @@ -17,6 +17,7 @@ youtube-dl = "*" "e1839a8" = {path = ".", editable = true} pytest = "*" +pylint = "*" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index 20a0972..3f2d84e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,20 +1,7 @@ { "_meta": { "hash": { - "sha256": "419607891ddd2c5415c6ff0be4e972d0c2269c9df3fe14fea431a8930da3f692" - }, - "host-environment-markers": { - "implementation_name": "cpython", - "implementation_version": "3.6.4", - "os_name": "posix", - "platform_machine": "x86_64", - "platform_python_implementation": "CPython", - "platform_release": "16.7.0", - "platform_system": "Darwin", - "platform_version": "Darwin Kernel Version 16.7.0: Tue Jan 30 11:27:06 PST 2018; root:xnu-3789.73.11~1/RELEASE_X86_64", - "python_full_version": "3.6.4", - "python_version": "3.6", - "sys_platform": "darwin" + "sha256": "f0d0df34026363f209c1bda09fac7757ccdd8e90d348cba74e5aa278850abe5d" }, "pipfile-spec": 6, "requires": { @@ -38,90 +25,93 @@ }, "chardet": { "hashes": [ - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691", - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae" + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" ], "version": "==3.0.4" }, "cssselect": { "hashes": [ - "sha256:3b5103e8789da9e936a68d993b70df732d06b8bb9a337a05ed4eb52c17ef7206", - "sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204" + "sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204", + "sha256:3b5103e8789da9e936a68d993b70df732d06b8bb9a337a05ed4eb52c17ef7206" ], + "index": "pypi", "version": "==1.0.3" }, "decorator": { "hashes": [ - "sha256:94d1d8905f5010d74bbbd86c30471255661a14187c45f8d7f3e5aa8540fdb2e5", - "sha256:7d46dd9f3ea1cf5f06ee0e4e1277ae618cf48dfb10ada7c8427cd46c42702a0e" + "sha256:7d46dd9f3ea1cf5f06ee0e4e1277ae618cf48dfb10ada7c8427cd46c42702a0e", + "sha256:94d1d8905f5010d74bbbd86c30471255661a14187c45f8d7f3e5aa8540fdb2e5" ], "version": "==4.2.1" }, "idna": { "hashes": [ - "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4", - "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f" + "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f", + "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4" ], "version": "==2.6" }, "lxml": { "hashes": [ - "sha256:41f59cbdab232f11680d5d4dec9f2e6782fd24d78e37ee833447702e34e675f4", - "sha256:e7e41d383f19bab9d57f5f3b18d158655bcd682e7e723f441b9e183e1e35a6b5", - "sha256:155521c337acecf8202091cff85bb9f709f238130ebadf04280fb1db11f5ad8b", - "sha256:d2c985d2460b81c6ca5feb8b86f1bc594ad59405d0bdf68626b85852b701553c", - "sha256:950e63387514aa1b881eba5ac6cb2ec51a118b3dafe99dd80ca19d8fb0142f30", - "sha256:470d7ce41e8047208ba1a376560bad17f1468df1f3097bc83902b26cfafdbb0c", - "sha256:e608839a5ee2180164424ccf279c8e2d9bbe8816d002c58fd97d6b621ba4aa94", - "sha256:87a66bcadac270fc010cb029022a93fc722bf1204a8b03e782d4c790f0edf7ca", - "sha256:2dedfeeecc2d5a939cf622602f5a1ce443ca82407f386880f739f1a9f08053ad", - "sha256:ba05732e4bcf59e948f61588851dcf620fd60d5bbd9d704203e5f59bbaa60219", - "sha256:2190266059fec3c5a55f9d6c30532c64c6d414d3228909c0af573fe4907e78d1", - "sha256:dd291debfaa535d9cb6cee8d7aca2328775e037d02d13f1634e57f49bc302cc4", - "sha256:29a36e354c39b2e24bc4ee103de53417ebb80f976a6ab9e8d093d559e2ac03e1", - "sha256:e37427d5a27eefbcfc48847e0b37f348113fac7280bc857421db39ffc6372570", - "sha256:b106d4d2383382399ad82108fd187e92f40b1c90f55c2d36bbcb1c44bcf940fc", - "sha256:0ee07da52d240f1dc3c83eef5cd5f1b7f018226c1121f2a54d446645779a6d17", - "sha256:3b33549fb8f91b38a7500078242b03cca513f3412a2cdae722e89bf83f95971d", - "sha256:4c12e90886d9c53ab434c8d0cebea122321cce19614c3c6b6d1a7700d7cc6212", - "sha256:79322000279cda10b53c374d53ca632ead3bc51c6aebf8e62c8fa93a4d08b750", - "sha256:6cba398eb37e0631e60e0e080c101cfe91769b2c8267105b64b4625e2581ea21", - "sha256:49a655956f8de69e1258bc0fcfc43eb3bd1e038655784d77d1869b4b81444e37", - "sha256:af8a5373241d09b8fc53e0490e1719ce5dc90a21b19db89b6596c1adcdd52270", - "sha256:e6b6698415c7e8d227a47a3b1038e1b37c2b438a1b48c2db7ad9e74ddbcd1149", - "sha256:155c916cf2645b4a8f2bd5d09065e92d1b67b8d464bdc001e0b524af84bedf6f", - "sha256:fa7320679ced5e25b20203d157280680fc84eb783b6cc650cb0c98e1858b7dd3", - "sha256:4187c4b0cefc3353181db048c51f42c489d9ac51e40b86c4851dc0671372971d", - "sha256:d5d29663e979e83b3fc361e97200f959cddb3a14797391d15273d84a5a8ae44b", - "sha256:940caef1ec7c78e0c34b0f6b94fe42d0f2022915ffc78643d28538a5cfd0f40e" + "sha256:0aa44ffdeaaf6ba45d61980bb2c07e87d4dcac7a8b5b9d458124bc1adcda5233", + "sha256:0af9c9267b1257319d49e9c1e9abbf92a99f965bee3c4733e0f0f7578985182d", + "sha256:0cddc6cde79e1932efc71d9974a4418184ad0b8ca46c633ad772b2c5eaf36b3c", + "sha256:124a9d529eec5e10f307eb237df3efc43dd1fb7ebdb5da5e480c4ed372648b6b", + "sha256:1d1e45584353e4d563685874707fc8c85cdd11b0ef3b79d77bb38046134d68a9", + "sha256:2812bc45a7f53f366217b76a1c53e6728fbfa7f7524d16a321ea8f7131428bd1", + "sha256:29697224b2df76edf7c2de9bcd90a26dd28fe85c5fd7f0171cae84f8383b227e", + "sha256:36ffb216e2f361a5a0a7e219aea6cd44da11c64061baed273944aae21223186c", + "sha256:4626d699551f66687e5f7e7f9b79bfce611e12edebfb9fec276e2df8ec46541e", + "sha256:4c21d7304d37715e6aed756e4d0c374c99c9bb1fa8d64f546b95474b17ac23de", + "sha256:57be98177ce784495dff53f40620995ad0a56456246ed9d51977e595de58e12e", + "sha256:62bfcd0629991e1c1257ffd28df2ab31a5c44da4c06823c26ec0f472723a84ca", + "sha256:71ac6dac6835de75aaf531cae9ffa447dae0783ba1f43bf6eaccfad3680a5b9c", + "sha256:7769ac9203ebe6d8db16904c54d57d77360fcc1926ed7afaa86b04050e4afa5b", + "sha256:7d96fbb5f23a62300aa9bef7d286cd61aca8902357619c8708c0290aba5df73f", + "sha256:88583c6565c9299f617238a500f1a47510bac54daff7872d6a343f13361b659e", + "sha256:8f52c4c8f1cf15419193026e731f34a3260a3ce7977b875ba1eb2517b8a3f660", + "sha256:95b82fdfdaac71640b281da6b9a2c3700177ba5190a786881b184de744ad55de", + "sha256:988d55112f196e12341b7c5138841c2b4f21f871eaa8f138c6ac4c46f28899f9", + "sha256:9e08918b744b89d30750eca8598f37ae75b16202870db678fde970d85afed3e3", + "sha256:b46f31e806f6884bd1053ad1d78ecaca6d1bc5dd94a1b783a6ff0bb4b3a60962", + "sha256:c18f316cad969111b1ff9e84c82fbc9ae6f25f35701118182d384585940cdf80", + "sha256:cef79715f2335bfc1ef7082bcb8b2bac87271431653455221a9127fde146208c", + "sha256:cf63f590090404c52f179b7ceacb7cd549de3a1697bcfe2f79be180b2801d109", + "sha256:d06260e6102b2f18dbee3736185cd6a2e1c88c0fad782bf8e9d7a7a1b24e02b0", + "sha256:d0dc3e5737adcc9a23fd3d3d3072b887fefb48143309563f412ef7b0ebdfdb30", + "sha256:dd98d4f88ce0abda2b02c1542d1de22dd342023f3ba09874bd95841283f29433", + "sha256:f04b184984c23e0caac3c55eac2fe2dbb88726a5a1b35e23715eff6f29a4705c" ], - "version": "==4.1.1" + "index": "pypi", + "version": "==4.2.0" }, "mastodon.py": { "hashes": [ "sha256:22097bb5e3f473ddcf1fa40392753170da0cae9cb8b73b8baf40d31b15493613", "sha256:ca3db745a07d74c985cdeeee7c3937bf8b389aef69b89d66c7ddcfed8ffbffeb" ], + "index": "pypi", "version": "==1.2.2" }, "python-dateutil": { "hashes": [ - "sha256:95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c", - "sha256:891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca" + "sha256:07009062406cffd554a9b4135cd2ff167c9bf6b7aac61fe946c93e69fad1bbd8", + "sha256:8f95bb7e6edbb2456a51a1fb58c8dca942024b4f5844cae62c90aa88afe6e300" ], - "version": "==2.6.1" + "version": "==2.7.0" }, "pytz": { "hashes": [ - "sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe", - "sha256:f93ddcdd6342f94cea379c73cddb5724e0d6d0a1c91c9bdef364dc0368ba4fda", - "sha256:61242a9abc626379574a166dc0e96a66cd7c3b27fc10868003fa210be4bff1c9", - "sha256:ba18e6a243b3625513d85239b3e49055a2f0318466e0b8a92b8fb8ca7ccdf55f", "sha256:07edfc3d4d2705a20a6e99d97f0c4b61c800b8232dc1c04d87e8554f130148dd", "sha256:3a47ff71597f821cd84a162e71593004286e5be07a340fd462f0d33a760782b5", + "sha256:410bcd1d6409026fbaa65d9ed33bf6dd8b1e94a499e32168acfc7b332e4095c0", "sha256:5bd55c744e6feaa4d599a6cbd8228b4f8f9ba96de2c38d56f08e534b3c9edf0d", + "sha256:61242a9abc626379574a166dc0e96a66cd7c3b27fc10868003fa210be4bff1c9", "sha256:887ab5e5b32e4d0c86efddd3d055c1f363cbaa583beb8da5e22d2fa2f64d51ef", - "sha256:410bcd1d6409026fbaa65d9ed33bf6dd8b1e94a499e32168acfc7b332e4095c0" + "sha256:ba18e6a243b3625513d85239b3e49055a2f0318466e0b8a92b8fb8ca7ccdf55f", + "sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe", + "sha256:f93ddcdd6342f94cea379c73cddb5724e0d6d0a1c91c9bdef364dc0368ba4fda" ], "version": "==2018.3" }, @@ -134,8 +124,8 @@ }, "six": { "hashes": [ - "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb", - "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9" + "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", + "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" ], "version": "==1.11.0" }, @@ -148,17 +138,25 @@ }, "youtube-dl": { "hashes": [ - "sha256:5f61ed33df754784cfd5b3c1f5b64f44d398123cf887245cb8921d7f531b82c0", - "sha256:4a789f65b931e421fd24513fd5355310fbba787985a0465e0f9de75ec41e59b8" + "sha256:128bdde31602b2dcd95679419ee846ab916290edb7751a240f18d231609956b9", + "sha256:70451e4d51165f06c3836b796277f1a6c49c220afa7fcfbd4e786d07b8d3201b" ], - "version": "==2018.3.3" + "index": "pypi", + "version": "==2018.3.14" } }, "develop": { + "astroid": { + "hashes": [ + "sha256:a92c1197dd496ef2470e73e1c296fc02a719907ee07259744e26a13bda9d4862", + "sha256:b76e5109ff0f386dd229673ca1323d21b1e9bb9c38eaed2cf830882dd7628be2" + ], + "version": "==1.6.2" + }, "attrs": { "hashes": [ - "sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450", - "sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9" + "sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9", + "sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450" ], "version": "==17.4.0" }, @@ -171,22 +169,23 @@ }, "chardet": { "hashes": [ - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691", - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae" + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" ], "version": "==3.0.4" }, "cssselect": { "hashes": [ - "sha256:3b5103e8789da9e936a68d993b70df732d06b8bb9a337a05ed4eb52c17ef7206", - "sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204" + "sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204", + "sha256:3b5103e8789da9e936a68d993b70df732d06b8bb9a337a05ed4eb52c17ef7206" ], + "index": "pypi", "version": "==1.0.3" }, "decorator": { "hashes": [ - "sha256:94d1d8905f5010d74bbbd86c30471255661a14187c45f8d7f3e5aa8540fdb2e5", - "sha256:7d46dd9f3ea1cf5f06ee0e4e1277ae618cf48dfb10ada7c8427cd46c42702a0e" + "sha256:7d46dd9f3ea1cf5f06ee0e4e1277ae618cf48dfb10ada7c8427cd46c42702a0e", + "sha256:94d1d8905f5010d74bbbd86c30471255661a14187c45f8d7f3e5aa8540fdb2e5" ], "version": "==4.2.1" }, @@ -196,51 +195,102 @@ }, "idna": { "hashes": [ - "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4", - "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f" + "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f", + "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4" ], "version": "==2.6" }, + "isort": { + "hashes": [ + "sha256:1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af", + "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8", + "sha256:ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497" + ], + "version": "==4.3.4" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:0ce34342b419bd8f018e6666bfef729aec3edf62345a53b537a4dcc115746a33", + "sha256:1b668120716eb7ee21d8a38815e5eb3bb8211117d9a90b0f8e21722c0758cc39", + "sha256:209615b0fe4624d79e50220ce3310ca1a9445fd8e6d3572a896e7f9146bbf019", + "sha256:27bf62cb2b1a2068d443ff7097ee33393f8483b570b475db8ebf7e1cba64f088", + "sha256:27ea6fd1c02dcc78172a82fc37fcc0992a94e4cecf53cb6d73f11749825bd98b", + "sha256:2c1b21b44ac9beb0fc848d3993924147ba45c4ebc24be19825e57aabbe74a99e", + "sha256:2df72ab12046a3496a92476020a1a0abf78b2a7db9ff4dc2036b8dd980203ae6", + "sha256:320ffd3de9699d3892048baee45ebfbbf9388a7d65d832d7e580243ade426d2b", + "sha256:50e3b9a464d5d08cc5227413db0d1c4707b6172e4d4d915c1c70e4de0bbff1f5", + "sha256:5276db7ff62bb7b52f77f1f51ed58850e315154249aceb42e7f4c611f0f847ff", + "sha256:61a6cf00dcb1a7f0c773ed4acc509cb636af2d6337a08f362413c76b2b47a8dd", + "sha256:6ae6c4cb59f199d8827c5a07546b2ab7e85d262acaccaacd49b62f53f7c456f7", + "sha256:7661d401d60d8bf15bb5da39e4dd72f5d764c5aff5a86ef52a042506e3e970ff", + "sha256:7bd527f36a605c914efca5d3d014170b2cb184723e423d26b1fb2fd9108e264d", + "sha256:7cb54db3535c8686ea12e9535eb087d32421184eacc6939ef15ef50f83a5e7e2", + "sha256:7f3a2d740291f7f2c111d86a1c4851b70fb000a6c8883a59660d95ad57b9df35", + "sha256:81304b7d8e9c824d058087dcb89144842c8e0dea6d281c031f59f0acf66963d4", + "sha256:933947e8b4fbe617a51528b09851685138b49d511af0b6c0da2539115d6d4514", + "sha256:94223d7f060301b3a8c09c9b3bc3294b56b2188e7d8179c762a1cda72c979252", + "sha256:ab3ca49afcb47058393b0122428358d2fbe0408cf99f1b58b295cfeb4ed39109", + "sha256:bd6292f565ca46dee4e737ebcc20742e3b5be2b01556dafe169f6c65d088875f", + "sha256:cb924aa3e4a3fb644d0c463cad5bc2572649a6a3f68a7f8e4fbe44aaa6d77e4c", + "sha256:d0fc7a286feac9077ec52a927fc9fe8fe2fabab95426722be4c953c9a8bede92", + "sha256:ddc34786490a6e4ec0a855d401034cbd1242ef186c20d79d2166d6a4bd449577", + "sha256:e34b155e36fa9da7e1b7c738ed7767fc9491a62ec6af70fe9da4a057759edc2d", + "sha256:e5b9e8f6bda48460b7b143c3821b21b452cb3a835e6bbd5dd33aa0c8d3f5137d", + "sha256:e81ebf6c5ee9684be8f2c87563880f93eedd56dd2b6146d8a725b50b7e5adb0f", + "sha256:eb91be369f945f10d3a49f5f9be8b3d0b93a4c2be8f8a5b83b0571b8123e0a7a", + "sha256:f460d1ceb0e4a5dcb2a652db0904224f367c9b3c1470d5a7683c0480e582468b" + ], + "version": "==1.3.1" + }, "lxml": { "hashes": [ - "sha256:41f59cbdab232f11680d5d4dec9f2e6782fd24d78e37ee833447702e34e675f4", - "sha256:e7e41d383f19bab9d57f5f3b18d158655bcd682e7e723f441b9e183e1e35a6b5", - "sha256:155521c337acecf8202091cff85bb9f709f238130ebadf04280fb1db11f5ad8b", - "sha256:d2c985d2460b81c6ca5feb8b86f1bc594ad59405d0bdf68626b85852b701553c", - "sha256:950e63387514aa1b881eba5ac6cb2ec51a118b3dafe99dd80ca19d8fb0142f30", - "sha256:470d7ce41e8047208ba1a376560bad17f1468df1f3097bc83902b26cfafdbb0c", - "sha256:e608839a5ee2180164424ccf279c8e2d9bbe8816d002c58fd97d6b621ba4aa94", - "sha256:87a66bcadac270fc010cb029022a93fc722bf1204a8b03e782d4c790f0edf7ca", - "sha256:2dedfeeecc2d5a939cf622602f5a1ce443ca82407f386880f739f1a9f08053ad", - "sha256:ba05732e4bcf59e948f61588851dcf620fd60d5bbd9d704203e5f59bbaa60219", - "sha256:2190266059fec3c5a55f9d6c30532c64c6d414d3228909c0af573fe4907e78d1", - "sha256:dd291debfaa535d9cb6cee8d7aca2328775e037d02d13f1634e57f49bc302cc4", - "sha256:29a36e354c39b2e24bc4ee103de53417ebb80f976a6ab9e8d093d559e2ac03e1", - "sha256:e37427d5a27eefbcfc48847e0b37f348113fac7280bc857421db39ffc6372570", - "sha256:b106d4d2383382399ad82108fd187e92f40b1c90f55c2d36bbcb1c44bcf940fc", - "sha256:0ee07da52d240f1dc3c83eef5cd5f1b7f018226c1121f2a54d446645779a6d17", - "sha256:3b33549fb8f91b38a7500078242b03cca513f3412a2cdae722e89bf83f95971d", - "sha256:4c12e90886d9c53ab434c8d0cebea122321cce19614c3c6b6d1a7700d7cc6212", - "sha256:79322000279cda10b53c374d53ca632ead3bc51c6aebf8e62c8fa93a4d08b750", - "sha256:6cba398eb37e0631e60e0e080c101cfe91769b2c8267105b64b4625e2581ea21", - "sha256:49a655956f8de69e1258bc0fcfc43eb3bd1e038655784d77d1869b4b81444e37", - "sha256:af8a5373241d09b8fc53e0490e1719ce5dc90a21b19db89b6596c1adcdd52270", - "sha256:e6b6698415c7e8d227a47a3b1038e1b37c2b438a1b48c2db7ad9e74ddbcd1149", - "sha256:155c916cf2645b4a8f2bd5d09065e92d1b67b8d464bdc001e0b524af84bedf6f", - "sha256:fa7320679ced5e25b20203d157280680fc84eb783b6cc650cb0c98e1858b7dd3", - "sha256:4187c4b0cefc3353181db048c51f42c489d9ac51e40b86c4851dc0671372971d", - "sha256:d5d29663e979e83b3fc361e97200f959cddb3a14797391d15273d84a5a8ae44b", - "sha256:940caef1ec7c78e0c34b0f6b94fe42d0f2022915ffc78643d28538a5cfd0f40e" + "sha256:0aa44ffdeaaf6ba45d61980bb2c07e87d4dcac7a8b5b9d458124bc1adcda5233", + "sha256:0af9c9267b1257319d49e9c1e9abbf92a99f965bee3c4733e0f0f7578985182d", + "sha256:0cddc6cde79e1932efc71d9974a4418184ad0b8ca46c633ad772b2c5eaf36b3c", + "sha256:124a9d529eec5e10f307eb237df3efc43dd1fb7ebdb5da5e480c4ed372648b6b", + "sha256:1d1e45584353e4d563685874707fc8c85cdd11b0ef3b79d77bb38046134d68a9", + "sha256:2812bc45a7f53f366217b76a1c53e6728fbfa7f7524d16a321ea8f7131428bd1", + "sha256:29697224b2df76edf7c2de9bcd90a26dd28fe85c5fd7f0171cae84f8383b227e", + "sha256:36ffb216e2f361a5a0a7e219aea6cd44da11c64061baed273944aae21223186c", + "sha256:4626d699551f66687e5f7e7f9b79bfce611e12edebfb9fec276e2df8ec46541e", + "sha256:4c21d7304d37715e6aed756e4d0c374c99c9bb1fa8d64f546b95474b17ac23de", + "sha256:57be98177ce784495dff53f40620995ad0a56456246ed9d51977e595de58e12e", + "sha256:62bfcd0629991e1c1257ffd28df2ab31a5c44da4c06823c26ec0f472723a84ca", + "sha256:71ac6dac6835de75aaf531cae9ffa447dae0783ba1f43bf6eaccfad3680a5b9c", + "sha256:7769ac9203ebe6d8db16904c54d57d77360fcc1926ed7afaa86b04050e4afa5b", + "sha256:7d96fbb5f23a62300aa9bef7d286cd61aca8902357619c8708c0290aba5df73f", + "sha256:88583c6565c9299f617238a500f1a47510bac54daff7872d6a343f13361b659e", + "sha256:8f52c4c8f1cf15419193026e731f34a3260a3ce7977b875ba1eb2517b8a3f660", + "sha256:95b82fdfdaac71640b281da6b9a2c3700177ba5190a786881b184de744ad55de", + "sha256:988d55112f196e12341b7c5138841c2b4f21f871eaa8f138c6ac4c46f28899f9", + "sha256:9e08918b744b89d30750eca8598f37ae75b16202870db678fde970d85afed3e3", + "sha256:b46f31e806f6884bd1053ad1d78ecaca6d1bc5dd94a1b783a6ff0bb4b3a60962", + "sha256:c18f316cad969111b1ff9e84c82fbc9ae6f25f35701118182d384585940cdf80", + "sha256:cef79715f2335bfc1ef7082bcb8b2bac87271431653455221a9127fde146208c", + "sha256:cf63f590090404c52f179b7ceacb7cd549de3a1697bcfe2f79be180b2801d109", + "sha256:d06260e6102b2f18dbee3736185cd6a2e1c88c0fad782bf8e9d7a7a1b24e02b0", + "sha256:d0dc3e5737adcc9a23fd3d3d3072b887fefb48143309563f412ef7b0ebdfdb30", + "sha256:dd98d4f88ce0abda2b02c1542d1de22dd342023f3ba09874bd95841283f29433", + "sha256:f04b184984c23e0caac3c55eac2fe2dbb88726a5a1b35e23715eff6f29a4705c" ], - "version": "==4.1.1" + "index": "pypi", + "version": "==4.2.0" }, "mastodon.py": { "hashes": [ "sha256:22097bb5e3f473ddcf1fa40392753170da0cae9cb8b73b8baf40d31b15493613", "sha256:ca3db745a07d74c985cdeeee7c3937bf8b389aef69b89d66c7ddcfed8ffbffeb" ], + "index": "pypi", "version": "==1.2.2" }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, "pluggy": { "hashes": [ "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff" @@ -254,31 +304,40 @@ ], "version": "==1.5.2" }, + "pylint": { + "hashes": [ + "sha256:34ab1a62fbdd48059d082f5a52b7e719a39b757a53ecbf0b2b7169b9c6a2cc28", + "sha256:c77311859e0c2d7932095f30d2b1bfdc4b6fe111f534450ba727a52eae330ef2" + ], + "index": "pypi", + "version": "==1.8.3" + }, "pytest": { "hashes": [ - "sha256:8970e25181e15ab14ae895599a0a0e0ade7d1f1c4c8ca1072ce16f25526a184d", - "sha256:9ddcb879c8cc859d2540204b5399011f842e5e8823674bf429f70ada281b3cc6" + "sha256:062027955bccbc04d2fcd5d79690947e018ba31abe4c90b2c6721abec734261b", + "sha256:117bad36c1a787e1a8a659df35de53ba05f9f3398fb9e4ac17e80ad5903eb8c5" ], - "version": "==3.4.1" + "index": "pypi", + "version": "==3.4.2" }, "python-dateutil": { "hashes": [ - "sha256:95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c", - "sha256:891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca" + "sha256:07009062406cffd554a9b4135cd2ff167c9bf6b7aac61fe946c93e69fad1bbd8", + "sha256:8f95bb7e6edbb2456a51a1fb58c8dca942024b4f5844cae62c90aa88afe6e300" ], - "version": "==2.6.1" + "version": "==2.7.0" }, "pytz": { "hashes": [ - "sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe", - "sha256:f93ddcdd6342f94cea379c73cddb5724e0d6d0a1c91c9bdef364dc0368ba4fda", - "sha256:61242a9abc626379574a166dc0e96a66cd7c3b27fc10868003fa210be4bff1c9", - "sha256:ba18e6a243b3625513d85239b3e49055a2f0318466e0b8a92b8fb8ca7ccdf55f", "sha256:07edfc3d4d2705a20a6e99d97f0c4b61c800b8232dc1c04d87e8554f130148dd", "sha256:3a47ff71597f821cd84a162e71593004286e5be07a340fd462f0d33a760782b5", + "sha256:410bcd1d6409026fbaa65d9ed33bf6dd8b1e94a499e32168acfc7b332e4095c0", "sha256:5bd55c744e6feaa4d599a6cbd8228b4f8f9ba96de2c38d56f08e534b3c9edf0d", + "sha256:61242a9abc626379574a166dc0e96a66cd7c3b27fc10868003fa210be4bff1c9", "sha256:887ab5e5b32e4d0c86efddd3d055c1f363cbaa583beb8da5e22d2fa2f64d51ef", - "sha256:410bcd1d6409026fbaa65d9ed33bf6dd8b1e94a499e32168acfc7b332e4095c0" + "sha256:ba18e6a243b3625513d85239b3e49055a2f0318466e0b8a92b8fb8ca7ccdf55f", + "sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe", + "sha256:f93ddcdd6342f94cea379c73cddb5724e0d6d0a1c91c9bdef364dc0368ba4fda" ], "version": "==2018.3" }, @@ -291,8 +350,8 @@ }, "six": { "hashes": [ - "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb", - "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9" + "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", + "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" ], "version": "==1.11.0" }, @@ -303,12 +362,19 @@ ], "version": "==1.22" }, + "wrapt": { + "hashes": [ + "sha256:d4d560d479f2c21e1b5443bbd15fe7ec4b37fe7e53d335d3b9b0a7b1226fe3c6" + ], + "version": "==1.10.11" + }, "youtube-dl": { "hashes": [ - "sha256:5f61ed33df754784cfd5b3c1f5b64f44d398123cf887245cb8921d7f531b82c0", - "sha256:4a789f65b931e421fd24513fd5355310fbba787985a0465e0f9de75ec41e59b8" + "sha256:128bdde31602b2dcd95679419ee846ab916290edb7751a240f18d231609956b9", + "sha256:70451e4d51165f06c3836b796277f1a6c49c220afa7fcfbd4e786d07b8d3201b" ], - "version": "==2018.3.3" + "index": "pypi", + "version": "==2018.3.14" } } } diff --git a/fediplay.py b/fediplay.py deleted file mode 100644 index c308f2d..0000000 --- a/fediplay.py +++ /dev/null @@ -1,142 +0,0 @@ -from os import environ, umask -import shlex -from subprocess import run -from threading import Thread, Lock - -from lxml.etree import HTML -import mastodon -Mastodon = mastodon.Mastodon -from youtube_dl import YoutubeDL -from youtube_dl.utils import DownloadError - -class Queue(object): - def __init__(self): - self.lock = Lock() - self.playing = False - self.queue = [] - - def add(self, url): - filename = Getter().get(url) - - with self.lock: - self.queue.append(filename) - if not self.playing: - self._play(self.queue.pop(0), self._play_finished) - - def _play(self, filename, cb_complete): - self.playing = True - - def run_thread(filename, cb_complete): - print('==> Playing', filename) - play_command = build_play_command(filename) - print('[executing]', play_command) - run(play_command, shell=True) - print('==> Playback complete') - cb_complete() - - thread = Thread(target=run_thread, args=(filename, cb_complete)) - thread.start() - - def _play_finished(self): - with self.lock: - self.playing = False - if len(self.queue) > 0: - self._play(self.queue.pop(0), self._play_finished) - -class Getter(object): - def _progress_hook(self, progress): - if progress['status'] == 'finished': - self.filename = progress['filename'] - - def get(self, url): - options = { - 'format': 'mp3/mp4', - 'nocheckcertificate': 'FEDIPLAY_NO_CHECK_CERTIFICATE' in environ, - 'progress_hooks': [self._progress_hook] - } - with YoutubeDL(options) as downloader: - downloader.download([url]) - - return self.filename - -class StreamListener(mastodon.StreamListener): - def __init__(self): - self.queue = Queue() - - def on_update(self, status): - tags = extract_tags(status) - if 'fediplay' in tags: - links = extract_links(status) - for link in links: - try: - print('==> Trying', link) - self.queue.add(link) - return - except DownloadError: - pass - -def register(api_base_url): - old_umask = umask(0o77) - Mastodon.create_app('fediplay', api_base_url=api_base_url, to_file='clientcred.secret') - umask(old_umask) - -def login(client, grant_code): - old_umask = umask(0o77) - client.log_in(code=grant_code, to_file='usercred.secret') - umask(old_umask) - -def stream(api_base_url): - client = Mastodon(client_id='clientcred.secret', access_token='usercred.secret', api_base_url=api_base_url) - listener = StreamListener() - print('==> Streaming from', api_base_url) - client.stream_user(listener) - -def extract_tags(toot): - return [tag['name'] for tag in toot['tags']] - -def link_is_internal(link): - classes = link.attrib.get('class', '').split(' ') - if classes: - return 'mention' in classes - - return False - -def extract_links(toot): - html = HTML(toot['content']) - all_links = html.cssselect('a') - return [link.attrib['href'] for link in all_links if not link_is_internal(link)] - -def build_play_command(filename): - escaped_filename = shlex.quote(filename) - template = environ.get( - 'FEDIPLAY_PLAY_COMMAND', - 'ffplay -v 0 -nostats -hide_banner -autoexit -nodisp {filename}' - ) - return template.format(filename=escaped_filename) - -def main(): - from getpass import getpass - from os import path - from sys import exit - - api_base_url = environ.get('FEDIPLAY_API_BASE_URL') - if not api_base_url: - print('FEDIPLAY_API_BASE_URL environment variable not set') - exit(1) - - if not path.exists('clientcred.secret'): - print('==> No clientcred.secret; registering application') - register(api_base_url) - - if not path.exists('usercred.secret'): - print('==> No usercred.secret; logging in') - client = Mastodon(client_id='clientcred.secret', api_base_url=api_base_url) - print("Open this page in your browser and follow the instructions to get the code you need, then paste it here") - print(client.auth_request_url()) - grant_code = input('Code? ') - login(client, grant_code) - - stream(api_base_url) - -if __name__ == '__main__': - main() diff --git a/fediplay/__init__.py b/fediplay/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fediplay/__main__.py b/fediplay/__main__.py new file mode 100644 index 0000000..24e1e55 --- /dev/null +++ b/fediplay/__main__.py @@ -0,0 +1,5 @@ +'''Hook for running fediplay module as a script.''' + +from fediplay.main import main + +main() diff --git a/fediplay/main.py b/fediplay/main.py new file mode 100644 index 0000000..1572407 --- /dev/null +++ b/fediplay/main.py @@ -0,0 +1,35 @@ +'''Entry point for command-line interface.''' + +from os import path, environ +import sys + +from mastodon import Mastodon + +from fediplay.mastodon import stream, register, login + +def main(): + '''Run fediplay command-line interface.''' + + api_base_url = environ.get('FEDIPLAY_API_BASE_URL') + if not api_base_url: + print('FEDIPLAY_API_BASE_URL environment variable not set') + sys.exit(1) + + if not path.exists('clientcred.secret'): + print('==> No clientcred.secret; registering application') + register(api_base_url) + + if not path.exists('usercred.secret'): + print('==> No usercred.secret; logging in') + client = Mastodon(client_id='clientcred.secret', api_base_url=api_base_url) + + print('Open this page in your browser and follow the instructions.') + print('Paste the code here.') + print('') + print(client.auth_request_url()) + print('') + + grant_code = input('Code: ') + login(client, grant_code) + + stream(api_base_url) diff --git a/fediplay/mastodon.py b/fediplay/mastodon.py new file mode 100644 index 0000000..69af7f4 --- /dev/null +++ b/fediplay/mastodon.py @@ -0,0 +1,73 @@ +'''Mastodon interface.''' + +from os import umask + +from lxml.etree import HTML # pylint: disable=no-name-in-module +import mastodon +from youtube_dl.utils import DownloadError + +from fediplay.queue import Queue + +Mastodon = mastodon.Mastodon + +class StreamListener(mastodon.StreamListener): + '''Listens to a Mastodon timeline and adds links the given Queue.''' + + def __init__(self, queue): + self.queue = queue + + def on_update(self, status): + tags = extract_tags(status) + if 'fediplay' in tags: + links = extract_links(status) + for link in links: + try: + print('==> Trying', link) + self.queue.add(link) + return + except DownloadError: + pass + +def register(api_base_url): + '''Register fediplay to a Mastodon server and save the client credentials.''' + + old_umask = umask(0o77) + Mastodon.create_app('fediplay', api_base_url=api_base_url, to_file='clientcred.secret') + umask(old_umask) + +def login(client, grant_code): + '''Log in to a Mastodon server and save the user credentials.''' + + old_umask = umask(0o77) + client.log_in(code=grant_code, to_file='usercred.secret') + umask(old_umask) + +def stream(api_base_url): + '''Stream statuses and add them to a queue.''' + + client = Mastodon(client_id='clientcred.secret', access_token='usercred.secret', + api_base_url=api_base_url) + listener = StreamListener(Queue()) + print('==> Streaming from', api_base_url) + client.stream_user(listener) + +def extract_tags(toot): + '''Extract tags from a toot.''' + + return [tag['name'] for tag in toot['tags']] + +def link_is_internal(link): + '''Determines if a link is internal to the Mastodon instance.''' + + classes = link.attrib.get('class', '').split(' ') + if classes: + return 'mention' in classes + + return False + +def extract_links(toot): + '''Extract all external links from a toot.''' + + html = HTML(toot['content']) + all_links = html.cssselect('a') + return [link.attrib['href'] for link in all_links if not link_is_internal(link)] diff --git a/fediplay/queue.py b/fediplay/queue.py new file mode 100644 index 0000000..4733646 --- /dev/null +++ b/fediplay/queue.py @@ -0,0 +1,83 @@ +'''The play queue.''' + +from os import environ +import shlex +from subprocess import run +from threading import Thread, Lock + +from youtube_dl import YoutubeDL + +class Queue(object): + '''The play queue.''' + + # pylint: disable=too-few-public-methods + + def __init__(self): + self.lock = Lock() + self.playing = False + self.queue = [] + + def add(self, url): + '''Fetches the url and adds the resulting audio to the play queue.''' + + filename = Getter().get(url) + + with self.lock: + self.queue.append(filename) + if not self.playing: + self._play(self.queue.pop(0), self._play_finished) + + def _play(self, filename, cb_complete): + self.playing = True + + def _run_thread(filename, cb_complete): + print('==> Playing', filename) + play_command = build_play_command(filename) + print('[executing]', play_command) + run(play_command, shell=True) + print('==> Playback complete') + cb_complete() + + thread = Thread(target=_run_thread, args=(filename, cb_complete)) + thread.start() + + def _play_finished(self): + with self.lock: + self.playing = False + if self.queue: + self._play(self.queue.pop(0), self._play_finished) + +class Getter(object): + '''Fetches music from a url.''' + + # pylint: disable=too-few-public-methods + + def __init__(self): + self.filename = None + + def _progress_hook(self, progress): + if progress['status'] == 'finished': + self.filename = progress['filename'] + + def get(self, url): + '''Fetches music from the given url.''' + + options = { + 'format': 'mp3/mp4', + 'nocheckcertificate': 'FEDIPLAY_NO_CHECK_CERTIFICATE' in environ, + 'progress_hooks': [self._progress_hook] + } + with YoutubeDL(options) as downloader: + downloader.download([url]) + + return self.filename + +def build_play_command(filename): + '''Builds a play command for the given filename.''' + + escaped_filename = shlex.quote(filename) + template = environ.get( + 'FEDIPLAY_PLAY_COMMAND', + 'ffplay -v 0 -nostats -hide_banner -autoexit -nodisp {filename}' + ) + return template.format(filename=escaped_filename) diff --git a/setup.py b/setup.py index acff5fa..fd6da03 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ setup( ], entry_points={ 'console_scripts': [ - 'fediplay = fediplay:main' + 'fediplay = fediplay.main:main' ] } )