diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ceb4735 --- /dev/null +++ b/LICENSE @@ -0,0 +1,195 @@ + +Non-Profit Open Software License 3.0 + +This Non-Profit Open Software License ("Non-Profit OSL") version 3.0 (the +"License") applies to any original work of authorship (the "Original Work") +whose owner (the "Licensor") has placed the following licensing notice adjacent +to the copyright notice for the Original Work: + +Licensed under the Non-Profit Open Software License version 3.0 + +1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, +non-exclusive, sublicensable license, for the duration of the copyright, to +do the following: + +a) to reproduce the Original Work in copies, either alone or as part of a +collective work; + +b) to translate, adapt, alter, transform, modify, or arrange the Original +Work, thereby creating derivative works ("Derivative Works") based upon the +Original Work; + +c) to distribute or communicate copies of the Original Work and Derivative +Works to the public, with the proviso that copies of Original Work or Derivative +Works that You distribute or communicate shall be licensed under this Non-Profit +Open Software License or as provided in section 17(d); + + d) to perform the Original Work publicly; and + + e) to display the Original Work publicly. + +2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, +non-exclusive, sublicensable license, under patent claims owned or controlled +by the Licensor that are embodied in the Original Work as furnished by the +Licensor, for the duration of the patents, to make, use, sell, offer for sale, +have made, and import the Original Work and Derivative Works. + +3) Grant of Source Code License. The term "Source Code" means the preferred +form of the Original Work for making modifications to it and all available +documentation describing how to modify the Original Work. Licensor agrees +to provide a machine-readable copy of the Source Code of the Original Work +along with each copy of the Original Work that Licensor distributes. Licensor +reserves the right to satisfy this obligation by placing a machine-readable +copy of the Source Code in an information repository reasonably calculated +to permit inexpensive and convenient access by You for as long as Licensor +continues to distribute the Original Work. + +4) Exclusions From License Grant. Neither the names of Licensor, nor the names +of any contributors to the Original Work, nor any of their trademarks or service +marks, may be used to endorse or promote products derived from this Original +Work without express prior permission of the Licensor. Except as expressly +stated herein, nothing in this License grants any license to Licensor's trademarks, +copyrights, patents, trade secrets or any other intellectual property. No +patent license is granted to make, use, sell, offer for sale, have made, or +import embodiments of any patent claims other than the licensed claims defined +in Section 2. No license is granted to the trademarks of Licensor even if +such marks are included in the Original Work. Nothing in this License shall +be interpreted to prohibit Licensor from licensing under terms different from +this License any Original Work that Licensor otherwise would have a right +to license. + +5) External Deployment. The term "External Deployment" means the use, distribution, +or communication of the Original Work or Derivative Works in any way such +that the Original Work or Derivative Works may be used by anyone other than +You, whether those works are distributed or communicated to those persons +or made available as an application intended for use over a network. As an +express condition for the grants of license hereunder, You must treat any +External Deployment by You of the Original Work or a Derivative Work as a +distribution under section 1(c). + +6) Attribution Rights. You must retain, in the Source Code of any Derivative +Works that You create, all copyright, patent, or trademark notices from the +Source Code of the Original Work, as well as any notices of licensing and +any descriptive text identified therein as an "Attribution Notice." You must +cause the Source Code for any Derivative Works that You create to carry a +prominent Attribution Notice reasonably calculated to inform recipients that +You have modified the Original Work. + +7) Warranty of Provenance and Disclaimer of Warranty. The Original Work is +provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either +express or implied, including, without limitation, the warranties of non-infringement, +merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO +THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY +constitutes an essential part of this License. No license to the Original +Work is granted by this License except under this disclaimer. + +8) Limitation of Liability. Under no circumstances and under no legal theory, +whether in tort (including negligence), contract, or otherwise, shall the +Licensor be liable to anyone for any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License +or the use of the Original Work including, without limitation, damages for +loss of goodwill, work stoppage, computer failure or malfunction, or any and +all other commercial damages or losses. This limitation of liability shall +not apply to the extent applicable law prohibits such limitation. + +9) Acceptance and Termination. If, at any time, You expressly assented to +this License, that assent indicates your clear and irrevocable acceptance +of this License and all of its terms and conditions. If You distribute or +communicate copies of the Original Work or a Derivative Work, You must make +a reasonable effort under the circumstances to obtain the express assent of +recipients to the terms of this License. This License conditions your rights +to undertake the activities listed in Section 1, including your right to create +Derivative Works based upon the Original Work, and doing so without honoring +these terms and conditions is prohibited by copyright law and international +treaty. Nothing in this License is intended to affect copyright exceptions +and limitations (including "fair use" or "fair dealing"). This License shall +terminate immediately and You may no longer exercise any of the rights granted +to You by this License upon your failure to honor the conditions in Section +1(c). + +10) Termination for Patent Action. This License shall terminate automatically +and You may no longer exercise any of the rights granted to You by this License +as of the date You commence an action, including a cross-claim or counterclaim, +against Licensor or any licensee alleging that the Original Work infringes +a patent. This termination provision shall not apply for an action alleging +patent infringement by combinations of the Original Work with other software +or hardware. + +11) Jurisdiction, Venue and Governing Law. Any action or suit relating to +this License may be brought only in the courts of a jurisdiction wherein the +Licensor resides or in which Licensor conducts its primary business, and under +the laws of that jurisdiction excluding its conflict-of-law provisions. The +application of the United Nations Convention on Contracts for the International +Sale of Goods is expressly excluded. Any use of the Original Work outside +the scope of this License or after its termination shall be subject to the +requirements and penalties of copyright or patent law in the appropriate jurisdiction. +This section shall survive the termination of this License. + +12) Attorneys' Fees. In any action to enforce the terms of this License or +seeking damages relating thereto, the prevailing party shall be entitled to +recover its costs and expenses, including, without limitation, reasonable +attorneys' fees and costs incurred in connection with such action, including +any appeal of such action. This section shall survive the termination of this +License. + +13) Miscellaneous. If any provision of this License is held to be unenforceable, +such provision shall be reformed only to the extent necessary to make it enforceable. + +14) Definition of "You" in This License. "You" throughout this License, whether +in upper or lower case, means an individual or a legal entity exercising rights +under, and complying with all of the terms of, this License. For legal entities, +"You" includes any entity that controls, is controlled by, or is under common +control with you. For purposes of this definition, "control" means (i) the +power, direct or indirect, to cause the direction or management of such entity, +whether by contract or otherwise, or (ii) ownership of fifty percent (50%) +or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +15) Right to Use. You may use the Original Work in all ways not otherwise +restricted or conditioned by this License or by law, and Licensor promises +not to interfere with or be responsible for such uses by You. + +16) Modification of This License. This License is Copyright © 2005 Lawrence +Rosen. Permission is granted to copy, distribute, or communicate this License +without modification. Nothing in this License permits You to modify this License +as applied to the Original Work or to Derivative Works. However, You may modify +the text of this License and copy, distribute or communicate your modified +version (the "Modified License") and apply it to other original works of authorship +subject to the following conditions: (i) You may not indicate in any way that +your Modified License is the "Open Software License" or "OSL" and you may +not use those names in the name of your Modified License; (ii) You must replace +the notice specified in the first paragraph above with the notice "Licensed +under " or with a notice of your own that is +not confusingly similar to the notice in this License; and (iii) You may not +claim that your original works are open source software unless your Modified +License has been approved by Open Source Initiative (OSI) and You comply with +its license review and certification process. + +17) Non-Profit Amendment. The name of this amended version of the Open Software +License ("OSL 3.0") is "Non-Profit Open Software License 3.0". The original +OSL 3.0 license has been amended as follows: + +(a) Licensor represents and declares that it is a not-for-profit organization +that derives no revenue whatsoever from the distribution of the Original Work +or Derivative Works thereof, or from support or services relating thereto. + +(b) The first sentence of Section 7 ["Warranty of Provenance"] of OSL 3.0 +has been stricken. For Original Works licensed under this Non-Profit OSL 3.0, +LICENSOR OFFERS NO WARRANTIES WHATSOEVER. + +(c) In the first sentence of Section 8 ["Limitation of Liability"] of this +Non-Profit OSL 3.0, the list of damages for which LIABILITY IS LIMITED now +includes "direct" damages. + +(d) The proviso in Section 1(c) of this License now refers to this "Non-Profit +Open Software License" rather than the "Open Software License". You may distribute +or communicate the Original Work or Derivative Works thereof under this Non-Profit +OSL 3.0 license only if You make the representation and declaration in paragraph +(a) of this Section 17. Otherwise, You shall distribute or communicate the +Original Work or Derivative Works thereof only under the OSL 3.0 license and +You shall publish clear licensing notices so stating. Also by way of clarification, +this License does not authorize You to distribute or communicate works under +this Non-Profit OSL 3.0 if You received them under the original OSL 3.0 license. + +(e) Original Works licensed under this license shall reference "Non-Profit +OSL 3.0" in licensing notices to distinguish them from works licensed under +the original OSL 3.0 license. diff --git a/README.md b/README.md index 4d6c51b..7becdc9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,20 @@ # mstdn-block -Manage instance blocks on mastodon \ No newline at end of file +Manage instance blocks on mastodon + +Note: currently only import and export commands are supported + +## Installation +`pip install -r requirements.txt` +`cp block.py path/to/mastodon/root` + +## Usage +If the path to a csv file is not specified, 'blocks.csv' in the current directory will be used. + +### Import blocklist in csv format + +`./block.py import [path/to/csv]` + +### Export blocklist in csv format + +`./block.py export [path/to/csv]` diff --git a/block.py b/block.py new file mode 100644 index 0000000..c4f7f58 --- /dev/null +++ b/block.py @@ -0,0 +1,178 @@ + +#!/usr/bin/env python3 +''' +Mastodon Block Manager v0.1 +by Izalia Mae @Izalia@barkshark.xyz + +requirements: +pygresql==5.1 +envbash==1.1.2 +''' +import sys +import os +import csv +import datetime + +from os import environ as env +from os.path import dirname, exists + +from pg import DB +from envbash import load_envbash + + +def dbconn(): + try: + load_envbash('.env.production') + + except FileNotFoundError: + print('Could not find ".env.production" in current directory.') + sys.exit(1) + + dbhost = env.get('DB_HOST', 'localhost') + dbport = int(env.get('DB_PORT', 5432)) + dbname = env.get('DB_NAME', 'mastodon_production') + dbuser = env.get('DB_USER', env.get('USER')) + dbpass = boolean(env.get('DB_PASS')) + + if type(dbpass) == str: + return DB(dbname=dbname, host=dbhost, port=dbport, user=dbuser, passwd=dbpass) + + else: + return DB(dbname=dbname, host=dbhost, port=dbport, user=dbuser) + + +def boolean(raw_val): + val = raw_val.lower() if raw_val not in [None, True, False, 0, 1] else raw_val + + if val in [True, False]: + return val + + elif val in ['t', 'true', 'yes', 'enable', 'enabled', '1', 1]: + return True + + elif val in ['f', 'false', 'no', 'disable', 'disabled', '0', 0, '', None]: + return False + + else: + return val + + +def dump(data): + db = dbconn() + + if not data or not exists(dirname(data[0])): + print('Path doesn\'t exist. Saving to current directory instead as "block.csv"') + filename = 'block.csv' + + else: + filename = data[0] + + domains = db.query('SELECT * FROM public.domain_blocks;').dictresult() + + with open(filename, 'w') as csvfile: + blocks = csv.writer(csvfile, delimiter=':') + + blocks.writerow(['#domain', 'severity', 'reject media', 'reject reports', 'private comment', 'public comment']) + + for domain in domains: + blocks.writerow([ + domain['domain'], + domain['severity'], + boolean(domain['reject_media']), + boolean(domain['reject_reports']), + domain['private_comment'], + domain['public_comment'] + ]) + + db.close() + return 'Done! :3' + + +def load(data): + ''' + 0 silence + 1 suspend + 2 none + ''' + db = dbconn() + + if not data or not exists(data[0]): + print('Path doesn\'t exist. Saving to current directory instead as "block.csv"') + filename = 'block.csv' + + else: + filename = data[0] + + csvfile = csv.reader(open(filename), delimiter=':') + + for row in csvfile: + rowquery = db.query(f'SELECT * FROM public.domain_blocks WHERE domain = \'{row[0]}\';').dictresult() + rowdata = rowquery[0] if rowquery else None + + if row[0].startswith('#'): + pass + + elif rowdata: + date = datetime.datetime.now() + + update = [ + int(rowdata['severity'])==int(row[1]), + boolean(rowdata['reject_media'])==boolean(row[2]), + boolean(rowdata['reject_reports'])==boolean(row[3]), + rowdata['private_comment']==row[4], + rowdata['public_comment']==row[5] + ] + + if False in update: + db.update('public.domain_blocks', {'id': rowdata['id']}, + severity=row[1], + reject_media=row[2], + reject_reports=row[3], + private_comment=row[4], + public_comment=row[5], + updated_at=date + ) + print(f'Updated block for {row[0]}') + + else: + date = datetime.datetime.now() + db.insert('public.domain_blocks', + domain=row[0], + severity=row[1], + reject_media=row[2], + reject_reports=row[3], + private_comment=row[4], + public_comment=row[5], + created_at=date, + updated_at=date + ) + print(f'Created new block for {row[0]}') + + db.close() + return 'Done! :3' + + +def main(): + arg = sys.argv + + cmdhelp = '''Mastodon Blocklist Manager + +import Import a blocklist +export Export the blocklist to csv +''' + + tasks = { + 'export': dump, + 'import': load + } + + if len(arg) < 2 or arg[1] not in tasks: + return cmdhelp + + msg = tasks[arg[1]](None if len(arg) < 3 else arg[2:]) + + return msg + + +if __name__ == '__main__': + print(main()) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6c68bd4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pygresql==5.1 +envbash==1.1.2