merge #19 to bring us to 2.0

This commit is contained in:
Matt Behrens 2018-07-20 13:18:09 -04:00
commit 2e4c3f92f7
13 changed files with 418 additions and 282 deletions

1
.env
View file

@ -1,4 +1,3 @@
FEDIPLAY_API_BASE_URL="https://cybre.space"
#FEDIPLAY_NO_CHECK_CERTIFICATE=1 #FEDIPLAY_NO_CHECK_CERTIFICATE=1
FEDIPLAY_PLAY_COMMAND="ffplay -v 0 -nostats -hide_banner -autoexit -nodisp {filename}" FEDIPLAY_PLAY_COMMAND="ffplay -v 0 -nostats -hide_banner -autoexit -nodisp {filename}"
#FEDIPLAY_PLAY_COMMAND="afplay {filename}" #FEDIPLAY_PLAY_COMMAND="afplay {filename}"

15
Pipfile
View file

@ -1,26 +1,21 @@
[[source]] [[source]]
url = "https://pypi.python.org/simple" url = "https://pypi.python.org/simple"
verify_ssl = true verify_ssl = true
name = "pypi" name = "pypi"
[packages] [packages]
cssselect = "*" cssselect = "*"
lxml = "*" lxml = "*"
"Mastodon.py" = "*" "mastodon.py" = "*"
youtube_dl = "*" youtube-dl = "*"
python-dotenv = "*" python-dotenv = "*"
click = "*"
"e1839a8" = {path = ".", editable = true}
appdirs = "*"
[dev-packages] [dev-packages]
"e1839a8" = {path = ".", editable = true}
pytest = "*" pytest = "*"
pylint = "*" pylint = "*"
[requires] [requires]
python_version = "3.6" python_version = "3.6"

417
Pipfile.lock generated
View file

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "f73fe1eabc45c7e9153c6512b0a96453287660e8a6c78539eb32a539211d71eb" "sha256": "689c6732fa9aa8271279bee02d6c37463ab8acad0817b1c9aa1b0e2349f8d694"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -16,12 +16,64 @@
] ]
}, },
"default": { "default": {
"appdirs": {
"hashes": [
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
],
"index": "pypi",
"version": "==1.4.3"
},
"asn1crypto": {
"hashes": [
"sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87",
"sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49"
],
"version": "==0.24.0"
},
"certifi": { "certifi": {
"hashes": [ "hashes": [
"sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296", "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7",
"sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d" "sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0"
], ],
"version": "==2018.1.18" "version": "==2018.4.16"
},
"cffi": {
"hashes": [
"sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743",
"sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef",
"sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50",
"sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f",
"sha256:3bb6bd7266598f318063e584378b8e27c67de998a43362e8fce664c54ee52d30",
"sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93",
"sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257",
"sha256:495c5c2d43bf6cebe0178eb3e88f9c4aa48d8934aa6e3cddb865c058da76756b",
"sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3",
"sha256:57b2533356cb2d8fac1555815929f7f5f14d68ac77b085d2326b571310f34f6e",
"sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc",
"sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04",
"sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6",
"sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359",
"sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596",
"sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b",
"sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd",
"sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95",
"sha256:a6a5cb8809091ec9ac03edde9304b3ad82ad4466333432b16d78ef40e0cce0d5",
"sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e",
"sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6",
"sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca",
"sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31",
"sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1",
"sha256:ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2",
"sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085",
"sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801",
"sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4",
"sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184",
"sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917",
"sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f",
"sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb"
],
"version": "==1.11.5"
}, },
"chardet": { "chardet": {
"hashes": [ "hashes": [
@ -30,6 +82,38 @@
], ],
"version": "==3.0.4" "version": "==3.0.4"
}, },
"click": {
"hashes": [
"sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
"sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b"
],
"index": "pypi",
"version": "==6.7"
},
"cryptography": {
"hashes": [
"sha256:21af753934f2f6d1a10fe8f4c0a64315af209ef6adeaee63ca349797d747d687",
"sha256:27bb401a20a838d6d0ea380f08c6ead3ccd8c9d8a0232dc9adcc0e4994576a66",
"sha256:29720c4253263cff9aea64585adbbe85013ba647f6e98367efff9db2d7193ded",
"sha256:2a35b7570d8f247889784010aac8b384fd2e4a47b33e15c4a60b45a7c1944120",
"sha256:42c531a6a354407f42ee07fda5c2c0dc822cf6d52744949c182f2b295fbd4183",
"sha256:5eb86f03f9c4f0ac2336ac5431271072ddf7ecc76b338e26366732cfac58aa19",
"sha256:67f7f57eae8dede577f3f7775957f5bec93edd6bdb6ce597bb5b28e1bdf3d4fb",
"sha256:6ec84edcbc966ae460560a51a90046503ff0b5b66157a9efc61515c68059f6c8",
"sha256:7ba834564daef87557e7fcd35c3c3183a4147b0b3a57314e53317360b9b201b3",
"sha256:7d7f084cbe1fdb82be5a0545062b59b1ad3637bc5a48612ac2eb428ff31b31ea",
"sha256:82409f5150e529d699e5c33fa8fd85e965104db03bc564f5f4b6a9199e591f7c",
"sha256:87d092a7c2a44e5f7414ab02fb4145723ebba411425e1a99773531dd4c0e9b8d",
"sha256:8c56ef989342e42b9fcaba7c74b446f0cc9bed546dd00034fa7ad66fc00307ef",
"sha256:9449f5d4d7c516a6118fa9210c4a00f34384cb1d2028672100ee0c6cce49d7f6",
"sha256:bc2301170986ad82d9349a91eb8884e0e191209c45f5541b16aa7c0cfb135978",
"sha256:c132bab45d4bd0fff1d3fe294d92b0a6eb8404e93337b3127bdec9f21de117e6",
"sha256:c3d945b7b577f07a477700f618f46cbc287af3a9222cd73035c6ef527ef2c363",
"sha256:cee18beb4c807b5c0b178f4fa2fae03cef9d51821a358c6890f8b23465b7e5d2",
"sha256:d01dfc5c2b3495184f683574e03c70022674ca9a7be88589c5aba130d835ea90"
],
"version": "==2.3"
},
"cssselect": { "cssselect": {
"hashes": [ "hashes": [
"sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204", "sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204",
@ -40,66 +124,80 @@
}, },
"decorator": { "decorator": {
"hashes": [ "hashes": [
"sha256:7d46dd9f3ea1cf5f06ee0e4e1277ae618cf48dfb10ada7c8427cd46c42702a0e", "sha256:2c51dff8ef3c447388fe5e4453d24a2bf128d3a4c32af3fabef1f01c6851ab82",
"sha256:94d1d8905f5010d74bbbd86c30471255661a14187c45f8d7f3e5aa8540fdb2e5" "sha256:c39efa13fbdeb4506c476c9b3babf6a718da943dab7811c206005a4a956c080c"
], ],
"version": "==4.2.1" "version": "==4.3.0"
},
"e1839a8": {
"editable": true,
"path": "."
},
"http-ece": {
"hashes": [
"sha256:2f31a0640c31a0c2934ab1e37005dd9a559ae854a16304f9b839e062074106cc"
],
"version": "==1.0.5"
}, },
"idna": { "idna": {
"hashes": [ "hashes": [
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f", "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4" "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
], ],
"version": "==2.6" "version": "==2.7"
}, },
"lxml": { "lxml": {
"hashes": [ "hashes": [
"sha256:0aa44ffdeaaf6ba45d61980bb2c07e87d4dcac7a8b5b9d458124bc1adcda5233", "sha256:0941f4313208c07734410414d8308812b044fd3fb98573454e3d3a0d2e201f3d",
"sha256:0af9c9267b1257319d49e9c1e9abbf92a99f965bee3c4733e0f0f7578985182d", "sha256:0b18890aa5730f9d847bc5469e8820f782d72af9985a15a7552109a86b01c113",
"sha256:0cddc6cde79e1932efc71d9974a4418184ad0b8ca46c633ad772b2c5eaf36b3c", "sha256:21f427945f612ac75576632b1bb8c21233393c961f2da890d7be3927a4b6085f",
"sha256:124a9d529eec5e10f307eb237df3efc43dd1fb7ebdb5da5e480c4ed372648b6b", "sha256:24cf6f622a4d49851afcf63ac4f0f3419754d4e98a7a548ab48dd03c635d9bd3",
"sha256:1d1e45584353e4d563685874707fc8c85cdd11b0ef3b79d77bb38046134d68a9", "sha256:2dc6705486b8abee1af9e2a3761e30a3cb19e8276f20ca7e137ee6611b93707c",
"sha256:2812bc45a7f53f366217b76a1c53e6728fbfa7f7524d16a321ea8f7131428bd1", "sha256:2e43b2e5b7d2b9abe6e0301eef2c2c122ab45152b968910eae68bdee2c4cfae0",
"sha256:29697224b2df76edf7c2de9bcd90a26dd28fe85c5fd7f0171cae84f8383b227e", "sha256:329a6d8b6d36f7d6f8b6c6a1db3b2c40f7e30a19d3caf62023c9d6a677c1b5e1",
"sha256:36ffb216e2f361a5a0a7e219aea6cd44da11c64061baed273944aae21223186c", "sha256:423cde55430a348bda6f1021faad7235c2a95a6bdb749e34824e5758f755817a",
"sha256:4626d699551f66687e5f7e7f9b79bfce611e12edebfb9fec276e2df8ec46541e", "sha256:4651ea05939374cfb5fe87aab5271ed38c31ea47997e17ec3834b75b94bd9f15",
"sha256:4c21d7304d37715e6aed756e4d0c374c99c9bb1fa8d64f546b95474b17ac23de", "sha256:4be3bbfb2968d7da6e5c2cd4104fc5ec1caf9c0794f6cae724da5a53b4d9f5a3",
"sha256:57be98177ce784495dff53f40620995ad0a56456246ed9d51977e595de58e12e", "sha256:622f7e40faef13d232fb52003661f2764ce6cdef3edb0a59af7c1559e4cc36d1",
"sha256:62bfcd0629991e1c1257ffd28df2ab31a5c44da4c06823c26ec0f472723a84ca", "sha256:664dfd4384d886b239ef0d7ee5cff2b463831079d250528b10e394a322f141f9",
"sha256:71ac6dac6835de75aaf531cae9ffa447dae0783ba1f43bf6eaccfad3680a5b9c", "sha256:697c0f58ac637b11991a1bc92e07c34da4a72e2eda34d317d2c1c47e2f24c1b3",
"sha256:7769ac9203ebe6d8db16904c54d57d77360fcc1926ed7afaa86b04050e4afa5b", "sha256:6ec908b4c8a4faa7fe1a0080768e2ce733f268b287dfefb723273fb34141475f",
"sha256:7d96fbb5f23a62300aa9bef7d286cd61aca8902357619c8708c0290aba5df73f", "sha256:7ec3fe795582b75bb49bb1685ffc462dbe38d74312dac07ce386671a28b5316b",
"sha256:88583c6565c9299f617238a500f1a47510bac54daff7872d6a343f13361b659e", "sha256:8c39babd923c431dcf1e5874c0f778d3a5c745a62c3a9b6bd755efd489ee8a1d",
"sha256:8f52c4c8f1cf15419193026e731f34a3260a3ce7977b875ba1eb2517b8a3f660", "sha256:949ca5bc56d6cb73d956f4862ba06ad3c5d2808eac76304284f53ae0c8b2334a",
"sha256:95b82fdfdaac71640b281da6b9a2c3700177ba5190a786881b184de744ad55de", "sha256:9f0daddeefb0791a600e6195441910bdf01eac470be596b9467e6122b51239a6",
"sha256:988d55112f196e12341b7c5138841c2b4f21f871eaa8f138c6ac4c46f28899f9", "sha256:a359893b01c30e949eae0e8a85671a593364c9f0b8162afe0cb97317af0953bf",
"sha256:9e08918b744b89d30750eca8598f37ae75b16202870db678fde970d85afed3e3", "sha256:ad5d5d8efed59e6b1d4c50c1eac59fb6ecec91b2073676af1e15fc4d43e9b6c5",
"sha256:b46f31e806f6884bd1053ad1d78ecaca6d1bc5dd94a1b783a6ff0bb4b3a60962", "sha256:bc1a36f95a6b3667c09b34995fc3a46a82e4cf0dc3e7ab281e4c77b15bd7af05",
"sha256:c18f316cad969111b1ff9e84c82fbc9ae6f25f35701118182d384585940cdf80", "sha256:be37b3f55b6d7d923f43bf74c356fc1878eb36e28505f38e198cb432c19c7b1a",
"sha256:cef79715f2335bfc1ef7082bcb8b2bac87271431653455221a9127fde146208c", "sha256:c45bca5e544eb75f7500ffd730df72922eb878a2f0213b0dc5a5f357ded3a85d",
"sha256:cf63f590090404c52f179b7ceacb7cd549de3a1697bcfe2f79be180b2801d109", "sha256:ccee7ebbb4735ebc341d347fca9ee09f2fa6c0580528c1414bc4e1d31372835c",
"sha256:d06260e6102b2f18dbee3736185cd6a2e1c88c0fad782bf8e9d7a7a1b24e02b0", "sha256:dc62c0840b2fc7753550b40405532a3e125c0d3761f34af948873393aa688160",
"sha256:d0dc3e5737adcc9a23fd3d3d3072b887fefb48143309563f412ef7b0ebdfdb30", "sha256:f7d9d5aa1c7e54167f1a3cba36b5c52c7c540f30952c9bd7d9302a1eda318424"
"sha256:dd98d4f88ce0abda2b02c1542d1de22dd342023f3ba09874bd95841283f29433",
"sha256:f04b184984c23e0caac3c55eac2fe2dbb88726a5a1b35e23715eff6f29a4705c"
], ],
"index": "pypi", "index": "pypi",
"version": "==4.2.0" "version": "==4.2.3"
}, },
"mastodon.py": { "mastodon.py": {
"hashes": [ "hashes": [
"sha256:22097bb5e3f473ddcf1fa40392753170da0cae9cb8b73b8baf40d31b15493613", "sha256:0d426c37795ed24cdf7affec7b3465cb76f9afc3f1d4dfbfd389b0b4459dbf4d",
"sha256:ca3db745a07d74c985cdeeee7c3937bf8b389aef69b89d66c7ddcfed8ffbffeb" "sha256:339a60c4ea505dd5b6c8f6ac076ce40f9e7bdfcd72d9466869da8bf631e4b9f5"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.2.2" "version": "==1.3.0"
},
"pycparser": {
"hashes": [
"sha256:99a8ca03e29851d96616ad0404b4aad7d9ee16f25c9f9708a11faf2810f7b226"
],
"version": "==2.18"
}, },
"python-dateutil": { "python-dateutil": {
"hashes": [ "hashes": [
"sha256:07009062406cffd554a9b4135cd2ff167c9bf6b7aac61fe946c93e69fad1bbd8", "sha256:1adb80e7a782c12e52ef9a8182bebeb73f1d7e24e374397af06fb4956c8dc5c0",
"sha256:8f95bb7e6edbb2456a51a1fb58c8dca942024b4f5844cae62c90aa88afe6e300" "sha256:e27001de32f627c22380a688bcc43ce83504a7bc5da472209b4c70f02829f0b8"
], ],
"version": "==2.7.0" "version": "==2.7.3"
}, },
"python-dotenv": { "python-dotenv": {
"hashes": [ "hashes": [
@ -111,24 +209,17 @@
}, },
"pytz": { "pytz": {
"hashes": [ "hashes": [
"sha256:07edfc3d4d2705a20a6e99d97f0c4b61c800b8232dc1c04d87e8554f130148dd", "sha256:a061aa0a9e06881eb8b3b2b43f05b9439d6583c206d0a6c340ff72a7b6669053",
"sha256:3a47ff71597f821cd84a162e71593004286e5be07a340fd462f0d33a760782b5", "sha256:ffb9ef1de172603304d9d2819af6f5ece76f2e85ec10692a524dd876e72bf277"
"sha256:410bcd1d6409026fbaa65d9ed33bf6dd8b1e94a499e32168acfc7b332e4095c0",
"sha256:5bd55c744e6feaa4d599a6cbd8228b4f8f9ba96de2c38d56f08e534b3c9edf0d",
"sha256:61242a9abc626379574a166dc0e96a66cd7c3b27fc10868003fa210be4bff1c9",
"sha256:887ab5e5b32e4d0c86efddd3d055c1f363cbaa583beb8da5e22d2fa2f64d51ef",
"sha256:ba18e6a243b3625513d85239b3e49055a2f0318466e0b8a92b8fb8ca7ccdf55f",
"sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe",
"sha256:f93ddcdd6342f94cea379c73cddb5724e0d6d0a1c91c9bdef364dc0368ba4fda"
], ],
"version": "==2018.3" "version": "==2018.5"
}, },
"requests": { "requests": {
"hashes": [ "hashes": [
"sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b", "sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1",
"sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e" "sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a"
], ],
"version": "==2.18.4" "version": "==2.19.1"
}, },
"six": { "six": {
"hashes": [ "hashes": [
@ -139,74 +230,41 @@
}, },
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b", "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf",
"sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f" "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5"
], ],
"version": "==1.22" "version": "==1.23"
}, },
"youtube-dl": { "youtube-dl": {
"hashes": [ "hashes": [
"sha256:128bdde31602b2dcd95679419ee846ab916290edb7751a240f18d231609956b9", "sha256:3300689ccc6cd22b8229e0c9cbb9f2cfcceaa3cef871a8e83c6a456623bb44e5",
"sha256:70451e4d51165f06c3836b796277f1a6c49c220afa7fcfbd4e786d07b8d3201b" "sha256:e4f81d38d2c7b8fa6fa069cd0f0096835dcaab91e74a4ca760625b76e0c614b4"
], ],
"index": "pypi", "index": "pypi",
"version": "==2018.3.14" "version": "==2018.7.10"
} }
}, },
"develop": { "develop": {
"astroid": { "astroid": {
"hashes": [ "hashes": [
"sha256:a92c1197dd496ef2470e73e1c296fc02a719907ee07259744e26a13bda9d4862", "sha256:0a0c484279a5f08c9bcedd6fa9b42e378866a7dcc695206b92d59dc9f2d9760d",
"sha256:b76e5109ff0f386dd229673ca1323d21b1e9bb9c38eaed2cf830882dd7628be2" "sha256:218e36cf8d98a42f16214e8670819ce307fa707d1dcf7f9af84c7aede1febc7f"
], ],
"version": "==1.6.2" "version": "==2.0.1"
},
"atomicwrites": {
"hashes": [
"sha256:240831ea22da9ab882b551b31d4225591e5e447a68c5e188db5b89ca1d487585",
"sha256:a24da68318b08ac9c9c45029f4a10371ab5b20e4226738e150e6e7c571630ae6"
],
"version": "==1.1.5"
}, },
"attrs": { "attrs": {
"hashes": [ "hashes": [
"sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9", "sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265",
"sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450" "sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b"
], ],
"version": "==17.4.0" "version": "==18.1.0"
},
"certifi": {
"hashes": [
"sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296",
"sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d"
],
"version": "==2018.1.18"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"cssselect": {
"hashes": [
"sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204",
"sha256:3b5103e8789da9e936a68d993b70df732d06b8bb9a337a05ed4eb52c17ef7206"
],
"index": "pypi",
"version": "==1.0.3"
},
"decorator": {
"hashes": [
"sha256:7d46dd9f3ea1cf5f06ee0e4e1277ae618cf48dfb10ada7c8427cd46c42702a0e",
"sha256:94d1d8905f5010d74bbbd86c30471255661a14187c45f8d7f3e5aa8540fdb2e5"
],
"version": "==4.2.1"
},
"e1839a8": {
"editable": true,
"path": "."
},
"idna": {
"hashes": [
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f",
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4"
],
"version": "==2.6"
}, },
"isort": { "isort": {
"hashes": [ "hashes": [
@ -250,48 +308,6 @@
], ],
"version": "==1.3.1" "version": "==1.3.1"
}, },
"lxml": {
"hashes": [
"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"
],
"index": "pypi",
"version": "==4.2.0"
},
"mastodon.py": {
"hashes": [
"sha256:22097bb5e3f473ddcf1fa40392753170da0cae9cb8b73b8baf40d31b15493613",
"sha256:ca3db745a07d74c985cdeeee7c3937bf8b389aef69b89d66c7ddcfed8ffbffeb"
],
"index": "pypi",
"version": "==1.2.2"
},
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
@ -299,64 +315,45 @@
], ],
"version": "==0.6.1" "version": "==0.6.1"
}, },
"more-itertools": {
"hashes": [
"sha256:2b6b9893337bfd9166bee6a62c2b0c9fe7735dcf85948b387ec8cba30e85d8e8",
"sha256:6703844a52d3588f951883005efcf555e49566a48afd4db4e965d69b883980d3",
"sha256:a18d870ef2ffca2b8463c0070ad17b5978056f403fb64e3f15fe62a52db21cc0"
],
"version": "==4.2.0"
},
"pluggy": { "pluggy": {
"hashes": [ "hashes": [
"sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff",
"sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c", "sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c",
"sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5", "sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5"
"sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff"
], ],
"version": "==0.6.0" "version": "==0.6.0"
}, },
"py": { "py": {
"hashes": [ "hashes": [
"sha256:8cca5c229d225f8c1e3085be4fcf306090b00850fefad892f9d96c7b6e2f310f", "sha256:3fd59af7435864e1a243790d322d763925431213b6b8529c6ca71081ace3bbf7",
"sha256:ca18943e28235417756316bfada6cd96b23ce60dd532642690dcfdaba988a76d" "sha256:e31fb2767eb657cbde86c454f02e99cb846d3cd9d61b318525140214fdc0e98e"
], ],
"version": "==1.5.2" "markers": "python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.1.*'",
"version": "==1.5.4"
}, },
"pylint": { "pylint": {
"hashes": [ "hashes": [
"sha256:34ab1a62fbdd48059d082f5a52b7e719a39b757a53ecbf0b2b7169b9c6a2cc28", "sha256:248a7b19138b22e6390cba71adc0cb03ac6dd75a25d3544f03ea1728fa20e8f4",
"sha256:c77311859e0c2d7932095f30d2b1bfdc4b6fe111f534450ba727a52eae330ef2" "sha256:9cd70527ef3b099543eeabeb5c80ff325d86b477aa2b3d49e264e12d12153bc8"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.8.3" "version": "==2.0.0"
}, },
"pytest": { "pytest": {
"hashes": [ "hashes": [
"sha256:062027955bccbc04d2fcd5d79690947e018ba31abe4c90b2c6721abec734261b", "sha256:0453c8676c2bee6feb0434748b068d5510273a916295fd61d306c4f22fbfd752",
"sha256:117bad36c1a787e1a8a659df35de53ba05f9f3398fb9e4ac17e80ad5903eb8c5" "sha256:4b208614ae6d98195430ad6bde03641c78553acee7c83cec2e85d613c0cd383d"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.4.2" "version": "==3.6.3"
},
"python-dateutil": {
"hashes": [
"sha256:07009062406cffd554a9b4135cd2ff167c9bf6b7aac61fe946c93e69fad1bbd8",
"sha256:8f95bb7e6edbb2456a51a1fb58c8dca942024b4f5844cae62c90aa88afe6e300"
],
"version": "==2.7.0"
},
"pytz": {
"hashes": [
"sha256:07edfc3d4d2705a20a6e99d97f0c4b61c800b8232dc1c04d87e8554f130148dd",
"sha256:3a47ff71597f821cd84a162e71593004286e5be07a340fd462f0d33a760782b5",
"sha256:410bcd1d6409026fbaa65d9ed33bf6dd8b1e94a499e32168acfc7b332e4095c0",
"sha256:5bd55c744e6feaa4d599a6cbd8228b4f8f9ba96de2c38d56f08e534b3c9edf0d",
"sha256:61242a9abc626379574a166dc0e96a66cd7c3b27fc10868003fa210be4bff1c9",
"sha256:887ab5e5b32e4d0c86efddd3d055c1f363cbaa583beb8da5e22d2fa2f64d51ef",
"sha256:ba18e6a243b3625513d85239b3e49055a2f0318466e0b8a92b8fb8ca7ccdf55f",
"sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe",
"sha256:f93ddcdd6342f94cea379c73cddb5724e0d6d0a1c91c9bdef364dc0368ba4fda"
],
"version": "==2018.3"
},
"requests": {
"hashes": [
"sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
"sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
],
"version": "==2.18.4"
}, },
"six": { "six": {
"hashes": [ "hashes": [
@ -365,26 +362,40 @@
], ],
"version": "==1.11.0" "version": "==1.11.0"
}, },
"urllib3": { "typed-ast": {
"hashes": [ "hashes": [
"sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b", "sha256:0948004fa228ae071054f5208840a1e88747a357ec1101c17217bfe99b299d58",
"sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f" "sha256:10703d3cec8dcd9eef5a630a04056bbc898abc19bac5691612acba7d1325b66d",
"sha256:1f6c4bd0bdc0f14246fd41262df7dfc018d65bb05f6e16390b7ea26ca454a291",
"sha256:25d8feefe27eb0303b73545416b13d108c6067b846b543738a25ff304824ed9a",
"sha256:29464a177d56e4e055b5f7b629935af7f49c196be47528cc94e0a7bf83fbc2b9",
"sha256:2e214b72168ea0275efd6c884b114ab42e316de3ffa125b267e732ed2abda892",
"sha256:3e0d5e48e3a23e9a4d1a9f698e32a542a4a288c871d33ed8df1b092a40f3a0f9",
"sha256:519425deca5c2b2bdac49f77b2c5625781abbaf9a809d727d3a5596b30bb4ded",
"sha256:57fe287f0cdd9ceaf69e7b71a2e94a24b5d268b35df251a88fef5cc241bf73aa",
"sha256:668d0cec391d9aed1c6a388b0d5b97cd22e6073eaa5fbaa6d2946603b4871efe",
"sha256:68ba70684990f59497680ff90d18e756a47bf4863c604098f10de9716b2c0bdd",
"sha256:6de012d2b166fe7a4cdf505eee3aaa12192f7ba365beeefaca4ec10e31241a85",
"sha256:79b91ebe5a28d349b6d0d323023350133e927b4de5b651a8aa2db69c761420c6",
"sha256:8550177fa5d4c1f09b5e5f524411c44633c80ec69b24e0e98906dd761941ca46",
"sha256:898f818399cafcdb93cbbe15fc83a33d05f18e29fb498ddc09b0214cdfc7cd51",
"sha256:94b091dc0f19291adcb279a108f5d38de2430411068b219f41b343c03b28fb1f",
"sha256:a26863198902cda15ab4503991e8cf1ca874219e0118cbf07c126bce7c4db129",
"sha256:a8034021801bc0440f2e027c354b4eafd95891b573e12ff0418dec385c76785c",
"sha256:bc978ac17468fe868ee589c795d06777f75496b1ed576d308002c8a5756fb9ea",
"sha256:c05b41bc1deade9f90ddc5d988fe506208019ebba9f2578c622516fd201f5863",
"sha256:c9b060bd1e5a26ab6e8267fd46fc9e02b54eb15fffb16d112d4c7b1c12987559",
"sha256:edb04bdd45bfd76c8292c4d9654568efaedf76fe78eb246dde69bdb13b2dad87",
"sha256:f19f2a4f547505fe9072e15f6f4ae714af51b5a681a97f187971f50c283193b6"
], ],
"version": "==1.22" "markers": "python_version < '3.7' and implementation_name == 'cpython'",
"version": "==1.1.0"
}, },
"wrapt": { "wrapt": {
"hashes": [ "hashes": [
"sha256:d4d560d479f2c21e1b5443bbd15fe7ec4b37fe7e53d335d3b9b0a7b1226fe3c6" "sha256:d4d560d479f2c21e1b5443bbd15fe7ec4b37fe7e53d335d3b9b0a7b1226fe3c6"
], ],
"version": "==1.10.11" "version": "==1.10.11"
},
"youtube-dl": {
"hashes": [
"sha256:128bdde31602b2dcd95679419ee846ab916290edb7751a240f18d231609956b9",
"sha256:70451e4d51165f06c3836b796277f1a6c49c220afa7fcfbd4e786d07b8d3201b"
],
"index": "pypi",
"version": "==2018.3.14"
} }
} }
} }

View file

@ -2,6 +2,16 @@
A Mastodon client that automatically plays your friends' music as they toot links to it. A Mastodon client that automatically plays your friends' music as they toot links to it.
## What's new in 2.0
If you've been using fediplay before, the all-new version 2.0 will be a little different!
- You now specify the instance you want to stream from on the command line, instead of setting it in the environment. fediplay has been upgraded with the power of [Click](http://click.pocoo.org/) to give it a more modern command-line interface.
- We use [appdirs](https://github.com/ActiveState/appdirs) to store your credentials in your operating system's user config directory, and downloaded music files in your operating system's user cache directory. If you already have `.secret` files from an earlier version, we'll move and rename them automatically for you.
Be sure to follow all the instructions, including re-running `pipenv install` to update the installed dependencies.
## Getting started ## Getting started
fediplay comes configured to use `ffplay` from [FFmpeg](https://ffmpeg.org/) to actually play music. fediplay comes configured to use `ffplay` from [FFmpeg](https://ffmpeg.org/) to actually play music.
@ -10,13 +20,19 @@ fediplay comes configured to use `ffplay` from [FFmpeg](https://ffmpeg.org/) to
- On Windows, `ffplay` is part of the [Scoop](http://scoop.sh/) `ffmpeg` package. - On Windows, `ffplay` is part of the [Scoop](http://scoop.sh/) `ffmpeg` package.
Edit `.env` and set `FEDIPLAY_API_BASE_URL` to your Mastodon instance. Use `pipenv install` from [Pipenv](https://docs.pipenv.org/) to install the Python dependencies and set up the fediplay script inside the virtual environment.
Use `pipenv install` from [Pipenv](https://docs.pipenv.org/) to install the Python dependencies. You can use the fediplay script with either `pipenv run fediplay` or by entering the Pipenv shell with `pipenv shell` and just running `fediplay`.
## Registering and logging in
To register fediplay to your instance, use `fediplay register example.com`.
To log in to your instance, use `fediplay login example.com`.
## Streaming ## Streaming
Use `pipenv run python -m fediplay` to start the stream. You'll need to log in the first time. Use `fediplay stream example.com` to start the stream. You'll need to log in the first time.
Toots that include the hashtag #fediplay and have as their first link something that [youtube-dl](https://rg3.github.io/youtube-dl/) can play, will! Toots that include the hashtag #fediplay and have as their first link something that [youtube-dl](https://rg3.github.io/youtube-dl/) can play, will!

View file

@ -0,0 +1,3 @@
'''A Mastodon client for playing your friends' music.'''
from fediplay.cli import cli

View file

@ -1,5 +1,5 @@
'''Hook for running fediplay module as a script.''' '''Hook for running fediplay module as a script.'''
from fediplay.main import main from fediplay.cli import cli
main() cli()

120
fediplay/cli.py Normal file
View file

@ -0,0 +1,120 @@
'''Entry point for command-line interface.'''
import os
import sys
import appdirs
import click
from mastodon import Mastodon
import fediplay.mastodon as mastodon
path = os.path
dirs = appdirs.AppDirs('fediplay', 'zigg')
def build_usercred_filename(instance):
'''Generate a usercred filename from an instance name.'''
return path.join(dirs.user_config_dir, instance + '.usercred.secret')
def build_clientcred_filename(instance):
'''Generate a clientcred filename from an instance name.'''
return path.join(dirs.user_config_dir, instance + '.clientcred.secret')
def ensure_dirs():
'''Make sure the application directories exist.'''
if not path.exists(dirs.user_config_dir):
os.makedirs(dirs.user_config_dir)
if not path.exists(dirs.user_cache_dir):
os.makedirs(dirs.user_cache_dir)
def ensure_usercred(instance):
'''Ensure the usercred file exists.'''
usercred = build_usercred_filename(instance)
if path.exists(usercred):
return usercred
if path.exists('usercred.secret'):
click.echo('==> Migrating usercred.secret to ' + usercred)
os.rename('usercred.secret', usercred)
return usercred
click.echo(usercred + ' does not exist; try `fediplay login`')
sys.exit(1)
def ensure_clientcred(instance):
'''Ensure the clientcred file exists.'''
clientcred = build_clientcred_filename(instance)
if path.exists(clientcred):
return clientcred
if path.exists('clientcred.secret'):
click.echo('==> Migrating clientcred.secret to ' + clientcred)
os.rename('clientcred.secret', clientcred)
return clientcred
click.echo(clientcred + ' does not exist; try `fediplay register`')
sys.exit(1)
@click.group()
def cli():
'''Command-line interface group.'''
ensure_dirs()
pass
@cli.command()
@click.argument('instance')
def register(instance):
'''Register fediplay to the instance.'''
clientcred = build_clientcred_filename(instance)
if path.exists(clientcred):
click.echo(clientcred + ' already exists')
sys.exit(1)
mastodon.register(instance, clientcred)
@cli.command()
@click.argument('instance')
def login(instance):
'''Log in to the instance.'''
clientcred = ensure_clientcred(instance)
usercred = build_usercred_filename(instance)
if path.exists(usercred):
click.echo(usercred + ' already exists')
sys.exit(1)
client = mastodon.build_client(instance, clientcred)
click.echo('Open this page in your browser and follow the instructions.')
click.echo('Paste the code here.')
click.echo('')
click.echo(mastodon.get_auth_request_url(client))
click.echo('')
grant_code = input('Code: ')
mastodon.login(client, grant_code, usercred)
@cli.command()
@click.argument('instance')
def stream(instance):
'''Stream music from the instance.'''
clientcred = ensure_clientcred(instance)
usercred = ensure_usercred(instance)
mastodon.stream(instance, clientcred, usercred, cache_dir=dirs.user_cache_dir)

View file

@ -4,13 +4,15 @@ from os import getenv
from dotenv import load_dotenv, find_dotenv from dotenv import load_dotenv, find_dotenv
def api_base_url():
return getenv('FEDIPLAY_API_BASE_URL')
def no_check_certificate(): def no_check_certificate():
'''Returns whether fediplay should check TLS certificates.'''
return bool(getenv('FEDIPLAY_NO_CHECK_CERTIFICATE')) return bool(getenv('FEDIPLAY_NO_CHECK_CERTIFICATE'))
def play_command(): def play_command():
'''Returns the play command fediplay should use to play a file.'''
return (getenv('FEDIPLAY_PLAY_COMMAND') or return (getenv('FEDIPLAY_PLAY_COMMAND') or
'ffplay -v 0 -nostats -hide_banner -autoexit -nodisp {filename}') 'ffplay -v 0 -nostats -hide_banner -autoexit -nodisp {filename}')

View file

@ -1,36 +0,0 @@
'''Entry point for command-line interface.'''
from os import path
import sys
from mastodon import Mastodon
import fediplay.env as env
from fediplay.mastodon import stream, register, login
def main():
'''Run fediplay command-line interface.'''
api_base_url = env.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)

View file

@ -2,6 +2,7 @@
from os import umask from os import umask
import click
from lxml.etree import HTML # pylint: disable=no-name-in-module from lxml.etree import HTML # pylint: disable=no-name-in-module
import mastodon import mastodon
from youtube_dl.utils import DownloadError from youtube_dl.utils import DownloadError
@ -10,6 +11,12 @@ from fediplay.queue import Queue
Mastodon = mastodon.Mastodon Mastodon = mastodon.Mastodon
def api_base_url(instance):
'''Create an API base url from an instance name.'''
return 'https://' + instance
class StreamListener(mastodon.StreamListener): class StreamListener(mastodon.StreamListener):
'''Listens to a Mastodon timeline and adds links the given Queue.''' '''Listens to a Mastodon timeline and adds links the given Queue.'''
@ -22,33 +29,42 @@ class StreamListener(mastodon.StreamListener):
links = extract_links(status) links = extract_links(status)
for link in links: for link in links:
try: try:
print('==> Trying', link) click.echo('==> Trying {}'.format(link))
self.queue.add(link) self.queue.add(link)
return return
except DownloadError: except DownloadError:
pass pass
def register(api_base_url): def register(instance, clientcred):
'''Register fediplay to a Mastodon server and save the client credentials.''' '''Register fediplay to a Mastodon server and save the client credentials.'''
old_umask = umask(0o77) saved_umask = umask(0o77)
Mastodon.create_app('fediplay', api_base_url=api_base_url, to_file='clientcred.secret') Mastodon.create_app('fediplay', scopes=['read'], api_base_url=api_base_url(instance), to_file=clientcred)
umask(old_umask) umask(saved_umask)
def login(client, grant_code): def build_client(instance, clientcred, usercred=None):
'''Builds a Mastodon client.'''
return Mastodon(client_id=clientcred, access_token=usercred, api_base_url=api_base_url(instance))
def get_auth_request_url(client):
'''Gets an authorization request URL from a Mastodon instance.'''
return client.auth_request_url(scopes=['read'])
def login(client, grant_code, usercred):
'''Log in to a Mastodon server and save the user credentials.''' '''Log in to a Mastodon server and save the user credentials.'''
old_umask = umask(0o77) saved_umask = umask(0o77)
client.log_in(code=grant_code, to_file='usercred.secret') client.log_in(code=grant_code, scopes=['read'], to_file=usercred)
umask(old_umask) umask(saved_umask)
def stream(api_base_url): def stream(instance, clientcred, usercred, cache_dir='.'):
'''Stream statuses and add them to a queue.''' '''Stream statuses and add them to a queue.'''
client = Mastodon(client_id='clientcred.secret', access_token='usercred.secret', client = build_client(instance, clientcred, usercred)
api_base_url=api_base_url) listener = StreamListener(Queue(cache_dir))
listener = StreamListener(Queue()) click.echo('==> Streaming from {}'.format(instance))
print('==> Streaming from', api_base_url)
client.stream_user(listener) client.stream_user(listener)
def extract_tags(toot): def extract_tags(toot):

View file

@ -1,27 +1,31 @@
'''The play queue.''' '''The play queue.'''
from os import path
import shlex import shlex
from subprocess import run from subprocess import run
from threading import Thread, Lock from threading import Thread, Lock
from youtube_dl import YoutubeDL import click
from youtube_dl import YoutubeDL, utils
import fediplay.env as env import fediplay.env as env
class Queue(object): class Queue(object):
'''The play queue.''' '''The play queue.'''
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
def __init__(self): def __init__(self, cache_dir):
self.lock = Lock() self.lock = Lock()
self.playing = False self.playing = False
self.queue = [] self.queue = []
self.cache_dir = cache_dir
def add(self, url): def add(self, url):
'''Fetches the url and adds the resulting audio to the play queue.''' '''Fetches the url and adds the resulting audio to the play queue.'''
filenames = Getter().get(url) filenames = Getter(self.cache_dir).get(url)
with self.lock: with self.lock:
self.queue.extend(filenames) self.queue.extend(filenames)
@ -32,11 +36,10 @@ class Queue(object):
self.playing = True self.playing = True
def _run_thread(filename, cb_complete): def _run_thread(filename, cb_complete):
print('==> Playing', filename)
play_command = build_play_command(filename) play_command = build_play_command(filename)
print('[executing]', play_command) click.echo('==> Playing {} with {}'.format(filename, play_command))
run(play_command, shell=True) run(play_command, shell=True)
print('==> Playback complete') click.echo('==> Playback complete')
cb_complete() cb_complete()
thread = Thread(target=_run_thread, args=(filename, cb_complete)) thread = Thread(target=_run_thread, args=(filename, cb_complete))
@ -53,8 +56,10 @@ class Getter(object):
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
def __init__(self): def __init__(self, cache_dir):
self.filename = None
self.filenames = [] self.filenames = []
self.cache_dir = cache_dir
def _progress_hook(self, progress): def _progress_hook(self, progress):
if progress['status'] == 'downloading' and progress['filename'] not in self.filenames: if progress['status'] == 'downloading' and progress['filename'] not in self.filenames:
@ -66,6 +71,7 @@ class Getter(object):
options = { options = {
'format': 'mp3/mp4', 'format': 'mp3/mp4',
'nocheckcertificate': env.no_check_certificate(), 'nocheckcertificate': env.no_check_certificate(),
'outtmpl': path.join(self.cache_dir, utils.DEFAULT_OUTTMPL),
'progress_hooks': [self._progress_hook] 'progress_hooks': [self._progress_hook]
} }
with YoutubeDL(options) as downloader: with YoutubeDL(options) as downloader:

View file

@ -2,17 +2,20 @@ from setuptools import setup
setup( setup(
name='fediplay', name='fediplay',
version='0.1', version='2.0',
py_modules=['fediplay'], py_modules=['fediplay'],
install_requires=[ install_requires=[
'Mastodon.py', 'appdirs',
'click',
'cssselect', 'cssselect',
'lxml', 'lxml',
'Mastodon.py',
'python-dotenv',
'youtube-dl' 'youtube-dl'
], ],
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
'fediplay = fediplay.main:main' 'fediplay = fediplay:cli'
] ]
} }
) )

View file

@ -3,6 +3,7 @@ from os import environ
from fediplay.mastodon import extract_links from fediplay.mastodon import extract_links
from fediplay.queue import build_play_command from fediplay.queue import build_play_command
def test_extract_links(): def test_extract_links():
toot = { toot = {
'content': "<p><a href=\"https://cybre.space/tags/nowplaying\" class=\"mention hashtag\" rel=\"tag\">#<span>nowplaying</span></a> <a href=\"https://cybre.space/tags/fediplay\" class=\"mention hashtag\" rel=\"tag\">#<span>fediplay</span></a> Grimes ft. Janelle Mon\u00e1e - Venus Fly <a href=\"https://www.youtube.com/watch?v=eTLTXDHrgtw\" rel=\"nofollow noopener\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"ellipsis\">youtube.com/watch?v=eTLTXDHrgt</span><span class=\"invisible\">w</span></a></p>" 'content': "<p><a href=\"https://cybre.space/tags/nowplaying\" class=\"mention hashtag\" rel=\"tag\">#<span>nowplaying</span></a> <a href=\"https://cybre.space/tags/fediplay\" class=\"mention hashtag\" rel=\"tag\">#<span>fediplay</span></a> Grimes ft. Janelle Mon\u00e1e - Venus Fly <a href=\"https://www.youtube.com/watch?v=eTLTXDHrgtw\" rel=\"nofollow noopener\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"ellipsis\">youtube.com/watch?v=eTLTXDHrgt</span><span class=\"invisible\">w</span></a></p>"