diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index b090b72..5d071e6 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -15,3 +15,17 @@ ugrade is licensed under the Unlicense. A license copy is provided in LICENSES/U yt-dl is licensed under the Unlicense. A license copy is provided in LICENSES/Unlicense.txt. yt-mpeg is licensed under the Unlicense. A license copy is provided in LICENSES/Unlicense.txt. + +ffconv is licensed under CC BY-SA 4.0. A license copy is provided in LICENSES/CC-BY-SA-3.0.txt. +ffconv-a - Copyright (c) 2019, 2011 Isaac, tripleee + +ffconv-a is licensed under CC BY-SA 4.0. A license copy is provided in LICENSES/CC-BY-SA-4.0.txt. +ffconv-a - Copyright (c) 2019, 2011 Isaac, tripleee + +matrix-upload is licensed under ISC. A license copy is provided in LICENSES/ISC.txt. +Copyright (c) 2018 Damir Jelić + +matrix-decrypt is licensed under ISC. A license copy is provided in LICENSES/ISC.txt. +Copyright (c) 2018 Damir Jelić + +gplopnm - Copyright (c) 2021 Liam Quin (https://www.delightfulcomputing.com/). All Rights Reserved. diff --git a/LICENSES/CC-BY-SA-4.0.txt b/LICENSES/CC-BY-SA-4.0.txt new file mode 100644 index 0000000..4dfebb8 --- /dev/null +++ b/LICENSES/CC-BY-SA-4.0.txt @@ -0,0 +1,349 @@ +Creative Commons Attribution-ShareAlike 4.0 International + +Creative Commons Corporation (“Creative Commons”) is not a law firm and does +not provide legal services or legal advice. Distribution of Creative Commons +public licenses does not create a lawyer-client or other relationship. Creative +Commons makes its licenses and related information available on an “as-is” +basis. Creative Commons gives no warranties regarding its licenses, any material +licensed under their terms and conditions, or any related information. Creative +Commons disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and conditions +that creators and other rights holders may use to share original works of +authorship and other material subject to copyright and certain other rights +specified in the public license below. The following considerations are for +informational purposes only, are not exhaustive, and do not form part of our +licenses. + +Considerations for licensors: Our public licenses are intended for use by +those authorized to give the public permission to use material in ways otherwise +restricted by copyright and certain other rights. Our licenses are irrevocable. +Licensors should read and understand the terms and conditions of the license +they choose before applying it. Licensors should also secure all rights necessary +before applying our licenses so that the public can reuse the material as +expected. Licensors should clearly mark any material not subject to the license. +This includes other CC-licensed material, or material used under an exception +or limitation to copyright. More considerations for licensors. + +Considerations for the public: By using one of our public licenses, a licensor +grants the public permission to use the licensed material under specified +terms and conditions. If the licensor’s permission is not necessary for any +reason–for example, because of any applicable exception or limitation to copyright–then +that use is not regulated by the license. Our licenses grant only permissions +under copyright and certain other rights that a licensor has authority to +grant. Use of the licensed material may still be restricted for other reasons, +including because others have copyright or other rights in the material. A +licensor may make special requests, such as asking that all changes be marked +or described. + +Although not required by our licenses, you are encouraged to respect those +requests where reasonable. More considerations for the public. + +Creative Commons Attribution-ShareAlike 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to +be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike +4.0 International Public License ("Public License"). To the extent this Public +License may be interpreted as a contract, You are granted the Licensed Rights +in consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the Licensor +receives from making the Licensed Material available under these terms and +conditions. + +Section 1 – Definitions. + +a. Adapted Material means material subject to Copyright and Similar Rights +that is derived from or based upon the Licensed Material and in which the +Licensed Material is translated, altered, arranged, transformed, or otherwise +modified in a manner requiring permission under the Copyright and Similar +Rights held by the Licensor. For purposes of this Public License, where the +Licensed Material is a musical work, performance, or sound recording, Adapted +Material is always produced where the Licensed Material is synched in timed +relation with a moving image. + +b. Adapter's License means the license You apply to Your Copyright and Similar +Rights in Your contributions to Adapted Material in accordance with the terms +and conditions of this Public License. + +c. BY-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, +approved by Creative Commons as essentially the equivalent of this Public +License. + +d. Copyright and Similar Rights means copyright and/or similar rights closely +related to copyright including, without limitation, performance, broadcast, +sound recording, and Sui Generis Database Rights, without regard to how the +rights are labeled or categorized. For purposes of this Public License, the +rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + +e. Effective Technological Measures means those measures that, in the absence +of proper authority, may not be circumvented under laws fulfilling obligations +under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, +and/or similar international agreements. + +f. Exceptions and Limitations means fair use, fair dealing, and/or any other +exception or limitation to Copyright and Similar Rights that applies to Your +use of the Licensed Material. + +g. License Elements means the license attributes listed in the name of a Creative +Commons Public License. The License Elements of this Public License are Attribution +and ShareAlike. + +h. Licensed Material means the artistic or literary work, database, or other +material to which the Licensor applied this Public License. + +i. Licensed Rights means the rights granted to You subject to the terms and +conditions of this Public License, which are limited to all Copyright and +Similar Rights that apply to Your use of the Licensed Material and that the +Licensor has authority to license. + +j. Licensor means the individual(s) or entity(ies) granting rights under this +Public License. + +k. Share means to provide material to the public by any means or process that +requires permission under the Licensed Rights, such as reproduction, public +display, public performance, distribution, dissemination, communication, or +importation, and to make material available to the public including in ways +that members of the public may access the material from a place and at a time +individually chosen by them. + +l. Sui Generis Database Rights means rights other than copyright resulting +from Directive 96/9/EC of the European Parliament and of the Council of 11 +March 1996 on the legal protection of databases, as amended and/or succeeded, +as well as other essentially equivalent rights anywhere in the world. + +m. You means the individual or entity exercising the Licensed Rights under +this Public License. Your has a corresponding meaning. + +Section 2 – Scope. + + a. License grant. + +1. Subject to the terms and conditions of this Public License, the Licensor +hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, +irrevocable license to exercise the Licensed Rights in the Licensed Material +to: + +A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + +2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions +and Limitations apply to Your use, this Public License does not apply, and +You do not need to comply with its terms and conditions. + +3. Term. The term of this Public License is specified in Section 6(a). + +4. Media and formats; technical modifications allowed. The Licensor authorizes +You to exercise the Licensed Rights in all media and formats whether now known +or hereafter created, and to make technical modifications necessary to do +so. The Licensor waives and/or agrees not to assert any right or authority +to forbid You from making technical modifications necessary to exercise the +Licensed Rights, including technical modifications necessary to circumvent +Effective Technological Measures. For purposes of this Public License, simply +making modifications authorized by this Section 2(a)(4) never produces Adapted +Material. + + 5. Downstream recipients. + +A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed +Material automatically receives an offer from the Licensor to exercise the +Licensed Rights under the terms and conditions of this Public License. + +B. Additional offer from the Licensor – Adapted Material. Every recipient +of Adapted Material from You automatically receives an offer from the Licensor +to exercise the Licensed Rights in the Adapted Material under the conditions +of the Adapter’s License You apply. + +C. No downstream restrictions. You may not offer or impose any additional +or different terms or conditions on, or apply any Effective Technological +Measures to, the Licensed Material if doing so restricts exercise of the Licensed +Rights by any recipient of the Licensed Material. + +6. No endorsement. Nothing in this Public License constitutes or may be construed +as permission to assert or imply that You are, or that Your use of the Licensed +Material is, connected with, or sponsored, endorsed, or granted official status +by, the Licensor or others designated to receive attribution as provided in +Section 3(a)(1)(A)(i). + + b. Other rights. + +1. Moral rights, such as the right of integrity, are not licensed under this +Public License, nor are publicity, privacy, and/or other similar personality +rights; however, to the extent possible, the Licensor waives and/or agrees +not to assert any such rights held by the Licensor to the limited extent necessary +to allow You to exercise the Licensed Rights, but not otherwise. + +2. Patent and trademark rights are not licensed under this Public License. + +3. To the extent possible, the Licensor waives any right to collect royalties +from You for the exercise of the Licensed Rights, whether directly or through +a collecting society under any voluntary or waivable statutory or compulsory +licensing scheme. In all other cases the Licensor expressly reserves any right +to collect such royalties. + +Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following +conditions. + + a. Attribution. + +1. If You Share the Licensed Material (including in modified form), You must: + +A. retain the following if it is supplied by the Licensor with the Licensed +Material: + +i. identification of the creator(s) of the Licensed Material and any others +designated to receive attribution, in any reasonable manner requested by the +Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + +v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + +B. indicate if You modified the Licensed Material and retain an indication +of any previous modifications; and + +C. indicate the Licensed Material is licensed under this Public License, and +include the text of, or the URI or hyperlink to, this Public License. + +2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner +based on the medium, means, and context in which You Share the Licensed Material. +For example, it may be reasonable to satisfy the conditions by providing a +URI or hyperlink to a resource that includes the required information. + +3. If requested by the Licensor, You must remove any of the information required +by Section 3(a)(1)(A) to the extent reasonably practicable. + +b. ShareAlike.In addition to the conditions in Section 3(a), if You Share +Adapted Material You produce, the following conditions also apply. + +1. The Adapter’s License You apply must be a Creative Commons license with +the same License Elements, this version or later, or a BY-SA Compatible License. + +2. You must include the text of, or the URI or hyperlink to, the Adapter's +License You apply. You may satisfy this condition in any reasonable manner +based on the medium, means, and context in which You Share Adapted Material. + +3. You may not offer or impose any additional or different terms or conditions +on, or apply any Effective Technological Measures to, Adapted Material that +restrict exercise of the rights granted under the Adapter's License You apply. + +Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to +Your use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, +reuse, reproduce, and Share all or a substantial portion of the contents of +the database; + +b. if You include all or a substantial portion of the database contents in +a database in which You have Sui Generis Database Rights, then the database +in which You have Sui Generis Database Rights (but not its individual contents) +is Adapted Material, including for purposes of Section 3(b); and + +c. You must comply with the conditions in Section 3(a) if You Share all or +a substantial portion of the contents of the database. +For the avoidance of doubt, this Section 4 supplements and does not replace +Your obligations under this Public License where the Licensed Rights include +other Copyright and Similar Rights. + +Section 5 – Disclaimer of Warranties and Limitation of Liability. + +a. Unless otherwise separately undertaken by the Licensor, to the extent possible, +the Licensor offers the Licensed Material as-is and as-available, and makes +no representations or warranties of any kind concerning the Licensed Material, +whether express, implied, statutory, or other. This includes, without limitation, +warranties of title, merchantability, fitness for a particular purpose, non-infringement, +absence of latent or other defects, accuracy, or the presence or absence of +errors, whether or not known or discoverable. Where disclaimers of warranties +are not allowed in full or in part, this disclaimer may not apply to You. + +b. To the extent possible, in no event will the Licensor be liable to You +on any legal theory (including, without limitation, negligence) or otherwise +for any direct, special, indirect, incidental, consequential, punitive, exemplary, +or other losses, costs, expenses, or damages arising out of this Public License +or use of the Licensed Material, even if the Licensor has been advised of +the possibility of such losses, costs, expenses, or damages. Where a limitation +of liability is not allowed in full or in part, this limitation may not apply +to You. + +c. The disclaimer of warranties and limitation of liability provided above +shall be interpreted in a manner that, to the extent possible, most closely +approximates an absolute disclaimer and waiver of all liability. + +Section 6 – Term and Termination. + +a. This Public License applies for the term of the Copyright and Similar Rights +licensed here. However, if You fail to comply with this Public License, then +Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under Section +6(a), it reinstates: + +1. automatically as of the date the violation is cured, provided it is cured +within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + +c. For the avoidance of doubt, this Section 6(b) does not affect any right +the Licensor may have to seek remedies for Your violations of this Public +License. + +d. For the avoidance of doubt, the Licensor may also offer the Licensed Material +under separate terms or conditions or stop distributing the Licensed Material +at any time; however, doing so will not terminate this Public License. + + e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +Section 7 – Other Terms and Conditions. + +a. The Licensor shall not be bound by any additional or different terms or +conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed +Material not stated herein are separate from and independent of the terms +and conditions of this Public License. + +Section 8 – Interpretation. + +a. For the avoidance of doubt, this Public License does not, and shall not +be interpreted to, reduce, limit, restrict, or impose conditions on any use +of the Licensed Material that could lawfully be made without permission under +this Public License. + +b. To the extent possible, if any provision of this Public License is deemed +unenforceable, it shall be automatically reformed to the minimum extent necessary +to make it enforceable. If the provision cannot be reformed, it shall be severed +from this Public License without affecting the enforceability of the remaining +terms and conditions. + +c. No term or condition of this Public License will be waived and no failure +to comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a limitation +upon, or waiver of, any privileges and immunities that apply to the Licensor +or You, including from the legal processes of any jurisdiction or authority. + +Creative Commons is not a party to its public licenses. Notwithstanding, Creative +Commons may elect to apply one of its public licenses to material it publishes +and in those instances will be considered the “Licensor.” Except for the limited +purpose of indicating that material is shared under a Creative Commons public +license or as otherwise permitted by the Creative Commons policies published +at creativecommons.org/policies, Creative Commons does not authorize the use +of the trademark “Creative Commons” or any other trademark or logo of Creative +Commons without its prior written consent including, without limitation, in +connection with any unauthorized modifications to any of its public licenses +or any other arrangements, understandings, or agreements concerning use of +licensed material. For the avoidance of doubt, this paragraph does not form +part of the public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/LICENSES/ISC.txt b/LICENSES/ISC.txt new file mode 100644 index 0000000..a6d1964 --- /dev/null +++ b/LICENSES/ISC.txt @@ -0,0 +1,15 @@ +ISC License: + +Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") +Copyright (c) 1995-2003 by Internet Software Consortium + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md index bfa2d9d..b39b8a6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,18 @@ # Scripts -Scripts I made out of necessity. +Scripts I and others have made out of necessity. ## Scripts info -| Script | Info | -|-------------|-----------------------------------------------------| -| pa-rescan | Rescan audio devices (pulseaudio). | -| pip-upgrade | Upgrade all pip packages. | -| scanif | Scan several documents one-by-one with SANE/CUPS. | -| ugrade | Upgrade packages for every package manager. | -| yt-dl | youtube-dl "magic" download. | -| yt-mpeg | Turn wav/cover image into a video optimised for yt. | +| Script | Info | +|----------------|-----------------------------------------------------| +| ffconv | Batch convert mkvs to mp4s. | +| ffconv-a | Batch convert from one format to another. | +| gpltopnm | Convert gpl to ppm. | +| matrix-decrypt | Decrypt matrix attachments that are encrypted. | +| matrix-upload | Upload attachment to matrix homeserver. | +| mkv-cat | Convert multiple videos into one. | +| pa-rescan | Rescan audio devices (pulseaudio). | +| pip-upgrade | Upgrade all pip packages. | +| scanif | Scan several documents one-by-one with SANE/CUPS. | +| ugrade | Upgrade packages for every package manager. | +| yt-dl | youtube-dl "magic" download. | +| yt-mpeg | Turn wav/cover image into a video optimised for yt. | diff --git a/bin/ffconv b/bin/ffconv new file mode 100755 index 0000000..e408ca3 --- /dev/null +++ b/bin/ffconv @@ -0,0 +1,5 @@ +for i in *.mkv; +do name=`echo "$i" | cut -d'.' -f1` + echo "$name" + ffmpeg -i "$i" "${name}.mp4" +done diff --git a/bin/ffconv-a b/bin/ffconv-a new file mode 100755 index 0000000..d972764 --- /dev/null +++ b/bin/ffconv-a @@ -0,0 +1,18 @@ +#!/bin/dash +echo Convert from... +read ext +echo Convert to... +read toext +for i in *.$ext; +do name=`echo "$i" | grep -E '(.+?)(\.[^.]*$|$)'` + echo "$name" + ffmpeg -i "$i" "${name}.$toext" +done +while true; do + read -p "Delete original files? " yn + case $yn in + [Yy]* ) rm *.$ext; exit;; + [Nn]* ) exit;; + * ) printf "Please answer yes or no. ";; + esac +done diff --git a/bin/gpltopnm b/bin/gpltopnm new file mode 100755 index 0000000..49484e5 --- /dev/null +++ b/bin/gpltopnm @@ -0,0 +1,48 @@ +#! /usr/bin/perl -w +use strict; +use List::Util qw[max]; + +# read a GIMP gpl palette file and write out a netpbm PPM image +# +# rename this file to end in .pl (not .txt) and chmod +x thisfile +# +# Liam Quin, https://www.delightfulcomputing.com/ 2021 + +my $inheader = 1; +my @colours; +my $max = 0; +while (<>) { + chomp; + if ($inheader) { + if (m/^GIMP Palette/) { + next; + } + if (m/^NameL/) { + next; + } + if (m/^#/) { + $inheader = 0; + next; + } + } elsif (m/^\s*(\d+)\s+(\d+)\s+(\d+).*$/) { + push @colours, [ $1, $2, $3 ]; + $max = max($max, $1, $2, $3); + } +} + +if (!@colours) { + die "$0: no colours found"; +} + +if ($max <= 0) { + die "$0: max value found is 0 which I think is an all-black palette"; +} + +# our image will be 1 pixel wide... +print "P3\n1 " . scalar(@colours) . "\n"; +print "${max}\n"; + +# now the image data +foreach (@colours) { + print $_->[0], " ", $_->[1], " ", $_->[2], "\n"; +} diff --git a/bin/matrix-decrypt b/bin/matrix-decrypt new file mode 100755 index 0000000..c04eb78 --- /dev/null +++ b/bin/matrix-decrypt @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# matrix_decrypt - Download and decrypt an encrypted attachment +# from a matrix server + +# Copyright © 2019 Damir Jelić +# +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import argparse +import requests +import tempfile +import subprocess + +from urllib.parse import urlparse, parse_qs +from nio.crypto import decrypt_attachment + + +def save_file(data): + """Save data to a temporary file and return its name.""" + tmp_dir = tempfile.gettempdir() + + with tempfile.NamedTemporaryFile( + prefix='plumber-', + dir=tmp_dir, + delete=False + ) as f: + f.write(data) + f.flush() + return f.name + + +def main(): + parser = argparse.ArgumentParser( + description='Download and decrypt matrix attachments' + ) + parser.add_argument('url', help='the url of the attachment') + parser.add_argument('file', nargs='?', help='save attachment to ') + parser.add_argument('--plumber', + help='program that gets called with the ' + 'dowloaded file') + + args = parser.parse_args() + url = urlparse(args.url) + query = parse_qs(url.query) + + if not query["key"] or not query["iv"] or not query["hash"]: + print("Missing decryption argument") + return -1 + + key = query["key"][0] + iv = query["iv"][0] + hash = query["hash"][0] + + http_url = "https://{}{}".format(url.netloc, url.path) + + request = requests.get(http_url) + + if not request.ok: + print("Error downloading file") + return -2 + + plumber = args.plumber + plaintext = decrypt_attachment(request.content, key, hash, iv) + + if args.file is None: + file_name = save_file(plaintext) + if plumber is None: + plumber = "xdg-open" + else: + file_name = args.file + open(file_name, "wb").write(plaintext) + + if plumber is not None: + subprocess.run([plumber, file_name]) + + return 0 + + +if __name__ == "__main__": + main() diff --git a/bin/matrix-upload b/bin/matrix-upload new file mode 100755 index 0000000..25b79f5 --- /dev/null +++ b/bin/matrix-upload @@ -0,0 +1,318 @@ +#!/usr/bin/env -S python3 -u +# Copyright © 2018 Damir Jelić +# +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +import os +import json +import magic +import requests +import argparse +from urllib.parse import urlparse +from itertools import zip_longest +import urllib3 + +from nio import Api, UploadResponse, UploadError +from nio.crypto import encrypt_attachment + +from json.decoder import JSONDecodeError + +urllib3.disable_warnings() + + +def to_stdout(message): + print(json.dumps(message), flush=True) + + +def error(e): + message = { + "type": "status", + "status": "error", + "message": str(e) + } + to_stdout(message) + os.sys.exit() + + +def mime_from_file(file): + try: + t = magic.from_file(file, mime=True) + except AttributeError: + try: + m = magic.open(magic.MIME) + m.load() + t, _ = m.file(file).split(';') + except AttributeError: + error('Your \'magic\' module is unsupported. ' + 'Install either https://github.com/ahupp/python-magic ' + 'or https://github.com/file/file/tree/master/python ' + '(official \'file\' python bindings, available as the ' + 'python-magic package on many distros)') + + raise SystemExit + + return t + + +class Upload(object): + def __init__(self, file, chunksize=1 << 13): + self.file = file + self.filename = os.path.basename(file) + self.chunksize = chunksize + self.totalsize = os.path.getsize(file) + self.mimetype = mime_from_file(file) + self.readsofar = 0 + + def send_progress(self): + message = { + "type": "progress", + "data": self.readsofar + } + to_stdout(message) + + def __iter__(self): + with open(self.file, 'rb') as file: + while True: + data = file.read(self.chunksize) + + if not data: + break + + self.readsofar += len(data) + self.send_progress() + + yield data + + def __len__(self): + return self.totalsize + + +def chunk_bytes(iterable, n): + args = [iter(iterable)] * n + return ( + bytes( + (filter(lambda x: x is not None, chunk)) + ) for chunk in zip_longest(*args) + ) + + +class EncryptedUpload(Upload): + def __init__(self, file, chunksize=1 << 13): + super().__init__(file, chunksize) + self.source_mimetype = self.mimetype + self.mimetype = "application/octet-stream" + + with open(self.filename, "rb") as file: + self.ciphertext, self.file_keys = encrypt_attachment(file.read()) + + def send_progress(self): + message = { + "type": "progress", + "data": self.readsofar + } + to_stdout(message) + + def __iter__(self): + for chunk in chunk_bytes(self.ciphertext, self.chunksize): + self.readsofar += len(chunk) + self.send_progress() + yield chunk + + def __len__(self): + return len(self.ciphertext) + + +class IterableToFileAdapter(object): + def __init__(self, iterable): + self.iterator = iter(iterable) + self.length = len(iterable) + + def read(self, size=-1): + return next(self.iterator, b'') + + def __len__(self): + return self.length + + +def upload_process(args): + file_path = os.path.expanduser(args.file) + thumbnail = None + + try: + if args.encrypt: + upload = EncryptedUpload(file_path) + + if upload.source_mimetype.startswith("image"): + # TODO create a thumbnail + thumbnail = None + else: + upload = Upload(file_path) + + except (FileNotFoundError, OSError, IOError) as e: + error(e) + + try: + url = urlparse(args.homeserver) + except ValueError as e: + error(e) + + upload_url = ("https://{}".format(args.homeserver) + if not url.scheme else args.homeserver) + _, api_path, _ = Api.upload(args.access_token, upload.filename) + upload_url += api_path + + headers = { + "Content-type": upload.mimetype, + } + + proxies = {} + + if args.proxy_address: + user = args.proxy_user or "" + + if args.proxy_password: + user += ":{}".format(args.proxy_password) + + if user: + user += "@" + + proxies = { + "https": "{}://{}{}:{}/".format( + args.proxy_type, + user, + args.proxy_address, + args.proxy_port + ) + } + + message = { + "type": "status", + "status": "started", + "total": upload.totalsize, + "file_name": upload.filename, + } + + if isinstance(upload, EncryptedUpload): + message["mimetype"] = upload.source_mimetype + else: + message["mimetype"] = upload.mimetype + + to_stdout(message) + + session = requests.Session() + session.trust_env = False + + try: + r = session.post( + url=upload_url, + auth=None, + headers=headers, + data=IterableToFileAdapter(upload), + verify=(not args.insecure), + proxies=proxies + ) + except (requests.exceptions.RequestException, OSError) as e: + error(e) + + try: + json_response = json.loads(r.content) + except JSONDecodeError: + error(r.content) + + response = UploadResponse.from_dict(json_response) + + if isinstance(response, UploadError): + error(str(response)) + + message = { + "type": "status", + "status": "done", + "url": response.content_uri + } + + if isinstance(upload, EncryptedUpload): + message["file_keys"] = upload.file_keys + + to_stdout(message) + + return 0 + + +def main(): + parser = argparse.ArgumentParser( + description="Encrypt and upload matrix attachments" + ) + parser.add_argument("file", help="the file that will be uploaded") + parser.add_argument( + "homeserver", + type=str, + help="the address of the homeserver" + ) + parser.add_argument( + "access_token", + type=str, + help="the access token to use for the upload" + ) + parser.add_argument( + "--encrypt", + action="store_const", + const=True, + default=False, + help="encrypt the file before uploading it" + ) + parser.add_argument( + "--insecure", + action="store_const", + const=True, + default=False, + help="disable SSL certificate verification" + ) + parser.add_argument( + "--proxy-type", + choices=[ + "http", + "socks4", + "socks5" + ], + default="http", + help="type of the proxy that will be used to establish a connection" + ) + parser.add_argument( + "--proxy-address", + type=str, + help="address of the proxy that will be used to establish a connection" + ) + parser.add_argument( + "--proxy-port", + type=int, + default=8080, + help="port of the proxy that will be used to establish a connection" + ) + parser.add_argument( + "--proxy-user", + type=str, + help="user that will be used for authentication on the proxy" + ) + parser.add_argument( + "--proxy-password", + type=str, + help="password that will be used for authentication on the proxy" + ) + + args = parser.parse_args() + upload_process(args) + + +if __name__ == "__main__": + main() diff --git a/bin/ugrade b/bin/ugrade index 514556b..909da67 100755 --- a/bin/ugrade +++ b/bin/ugrade @@ -1,6 +1,9 @@ #!/bin/dash -sudo dnf upgrade -y -sudo pacman -Syu -pip-upgrade -sudo npm -g upgrade -sudo yarn global upgrade +sudo dnf upgrade -y && +sudo pacman -Syu && +pip-upgrade && +sudo npm -g upgrade && +sudo npm install -g npm && +sudo yarn global upgrade && +sudo update_rubygems && +sudo gem update --system diff --git a/install.sh b/install.sh deleted file mode 100644 index 3a0438b..0000000 --- a/install.sh +++ /dev/null @@ -1 +0,0 @@ -cp bin/* /usr/local/bin