remarkbox/remarkbox/scripts/modify_node.py
Russell Ballestrini 91a2a77711 time to open sause & place into public domain!
Merry Christmas!

I AM READY

I love you all!

	new file:   .gitignore
	new file:   MANIFEST.in
	new file:   Makefile
	new file:   README.rst
	new file:   development.ini
	new file:   index.html
	new file:   index2.html
	new file:   journal.rst
	new file:   readme-postgres-notes.rst
	new file:   readme-themes.rst
	new file:   remarkbox/__init__.py
	new file:   remarkbox/lib/__init__.py
	new file:   remarkbox/lib/mail.py
	new file:   remarkbox/lib/mail_messages.py
	new file:   remarkbox/lib/notify.py
	new file:   remarkbox/lib/render.py
	new file:   remarkbox/lib/svgtar/__init__.py
	new file:   remarkbox/lib/svgtar/svg.py
	new file:   remarkbox/models/__init__.py
	new file:   remarkbox/models/event.py
	new file:   remarkbox/models/meta.py
	new file:   remarkbox/models/namespace.py
	new file:   remarkbox/models/namespace_request.py
	new file:   remarkbox/models/namespace_user.py
	new file:   remarkbox/models/node.py
	new file:   remarkbox/models/node_cache.py
	new file:   remarkbox/models/notification.py
	new file:   remarkbox/models/oauth.py
	new file:   remarkbox/models/pay_what_you_can.py
	new file:   remarkbox/models/uri.py
	new file:   remarkbox/models/user.py
	new file:   remarkbox/models/vote.py
	new file:   remarkbox/models/watcher.py
	new file:   remarkbox/routes.py
	new file:   remarkbox/scripts/__init__.py
	new file:   remarkbox/scripts/alembic/README
	new file:   remarkbox/scripts/alembic/env.py
	new file:   remarkbox/scripts/alembic/script.py.mako
	new file:   remarkbox/scripts/alembic/versions/00211ed642cc_add_ip_address_column_to_rb_node.py
	new file:   remarkbox/scripts/alembic/versions/0208c10ea67f_create_new_node_cache_table.py
	new file:   remarkbox/scripts/alembic/versions/04e52337756e_autogenerated_indicies.py
	new file:   remarkbox/scripts/alembic/versions/051f8b810f26_namespace_ignore_query_string.py
	new file:   remarkbox/scripts/alembic/versions/1040ee4836af_namespace_description.py
	new file:   remarkbox/scripts/alembic/versions/184a349cd589_uri_accessed_timestamp.py
	new file:   remarkbox/scripts/alembic/versions/256468780798_root_nodes_to_namespace_.py
	new file:   remarkbox/scripts/alembic/versions/2e00b92495e4_node_disabled_timestamp.py
	new file:   remarkbox/scripts/alembic/versions/3ee195d142fb_add_subscription_type_to_namespace.py
	new file:   remarkbox/scripts/alembic/versions/40ded1163f95_add_user_surrogate_columns.py
	new file:   remarkbox/scripts/alembic/versions/43c1e5a99d4e_new_namespace_column_3.py
	new file:   remarkbox/scripts/alembic/versions/4aeda8e797ab_new_namespace_column_for_stylesheet_uris.py
	new file:   remarkbox/scripts/alembic/versions/503a2cef2378_root_stats.py
	new file:   remarkbox/scripts/alembic/versions/591800942adf_node_data_html_column.py
	new file:   remarkbox/scripts/alembic/versions/59592cf325fb_stylesheet_timestamp.py
	new file:   remarkbox/scripts/alembic/versions/5a5d0b68db78_add_root_id_field.py
	new file:   remarkbox/scripts/alembic/versions/6a440d3921d2_added_email_id_column_to_user_table.py
	new file:   remarkbox/scripts/alembic/versions/6bbc92ccc112_add_changed_column_to_node_table.py
	new file:   remarkbox/scripts/alembic/versions/6db39621f46c_namespace_group_conversations.py
	new file:   remarkbox/scripts/alembic/versions/6fc1d0cf350c_notification_columns_to_rb_user_table.py
	new file:   remarkbox/scripts/alembic/versions/76deff88cfd6_create_graph_depth_column_on_node_model.py
	new file:   remarkbox/scripts/alembic/versions/771ef7c868de_added_created_timestamp_column_to_.py
	new file:   remarkbox/scripts/alembic/versions/7a3a4755b4a8_add_hide_unless_approved_column.py
	new file:   remarkbox/scripts/alembic/versions/87fbd2b4e06e_namespace_theme_embed_column.py
	new file:   remarkbox/scripts/alembic/versions/953d42406dbb_namespace_public_column.py
	new file:   remarkbox/scripts/alembic/versions/98a90d2add21_namespace_model.py
	new file:   remarkbox/scripts/alembic/versions/98ced5f6ff36_stripe_id_for_user.py
	new file:   remarkbox/scripts/alembic/versions/a26302bcfa25_add_created_timestamp_column_to_oauth_.py
	new file:   remarkbox/scripts/alembic/versions/a38c12eeff2d_locked_rb_node.py
	new file:   remarkbox/scripts/alembic/versions/a738d6859f18_new_namespace_columns_2.py
	new file:   remarkbox/scripts/alembic/versions/aa2dfb4decda_hide_powered_by_column.py
	new file:   remarkbox/scripts/alembic/versions/b132ec968f0c_pay_what_you_can_table.py
	new file:   remarkbox/scripts/alembic/versions/ba8e83a3b8fd_namespace_stylesheet_embed_column.py
	new file:   remarkbox/scripts/alembic/versions/c9793937e756_make_all_verified_namespace_request_.py
	new file:   remarkbox/scripts/alembic/versions/c97ddfcbc406_approve_column.py
	new file:   remarkbox/scripts/alembic/versions/cbdf3cd4ccba_avatar_size_in_namespace.py
	new file:   remarkbox/scripts/alembic/versions/d1a0ab4f617f_add_has_uri_to_node.py
	new file:   remarkbox/scripts/alembic/versions/f5f88293428a_add_mathjax_column_to_rb_namespace.py
	new file:   remarkbox/scripts/alembic/versions/f7b42b2024fb_namespace_reverse_node_order.py
	new file:   remarkbox/scripts/alembic/versions/fa8402aa1a00_add_link_protection_column_to_namespace.py
	new file:   remarkbox/scripts/dump_sqlite3_to_csv.sh
	new file:   remarkbox/scripts/init_db.py
	new file:   remarkbox/scripts/invalidate_node_cache.py
	new file:   remarkbox/scripts/json_import.py
	new file:   remarkbox/scripts/load_csv_into_postgres.sh
	new file:   remarkbox/scripts/merge_dupes.py
	new file:   remarkbox/scripts/modify_namespace.py
	new file:   remarkbox/scripts/modify_node.py
	new file:   remarkbox/scripts/modify_uris.py
	new file:   remarkbox/scripts/modify_user.py
	new file:   remarkbox/scripts/recompute_node_depths.py
	new file:   remarkbox/scripts/safe_approve_all_nodes.py
	new file:   remarkbox/scripts/send_node_digest_notifications.py
	new file:   remarkbox/static/css/common.css
	new file:   remarkbox/static/css/embed.css
	new file:   remarkbox/static/css/pygments.css
	new file:   remarkbox/static/favicon.ico
	new file:   remarkbox/static/img/remarkbox-logo.png
	new file:   remarkbox/static/img/remarkbox-minified.png
	new file:   remarkbox/static/js/custom.js
	new file:   remarkbox/static/js/iframe-resizer/ie8.polyfils.map
	new file:   remarkbox/static/js/iframe-resizer/ie8.polyfils.min.js
	new file:   remarkbox/static/js/iframe-resizer/iframeResizer.contentWindow.js
	new file:   remarkbox/static/js/iframe-resizer/iframeResizer.contentWindow.map
	new file:   remarkbox/static/js/iframe-resizer/iframeResizer.contentWindow.min.js
	new file:   remarkbox/static/js/iframe-resizer/iframeResizer.js
	new file:   remarkbox/static/js/iframe-resizer/iframeResizer.map
	new file:   remarkbox/static/js/iframe-resizer/iframeResizer.min.js
	new file:   remarkbox/static/js/iframe-resizer/index.js
	new file:   remarkbox/static/js/iframe-resizer/readme.rst
	new file:   remarkbox/static/js/jquery-2.1.3.min.js
	new file:   remarkbox/static/theme/readme.rst
	new file:   remarkbox/templates/base.j2
	new file:   remarkbox/templates/billing.j2
	new file:   remarkbox/templates/dynamic-remarkbox.css.j2
	new file:   remarkbox/templates/edit-node.j2
	new file:   remarkbox/templates/embed-iframe.txt.j2
	new file:   remarkbox/templates/home.j2
	new file:   remarkbox/templates/join-or-log-in.j2
	new file:   remarkbox/templates/list-namespace-owners.j2
	new file:   remarkbox/templates/list-namespace-requests.j2
	new file:   remarkbox/templates/list-nodes.j2
	new file:   remarkbox/templates/list-notifications.j2
	new file:   remarkbox/templates/mail_digest_html.j2
	new file:   remarkbox/templates/mail_digest_text.j2
	new file:   remarkbox/templates/mail_immediate_html.j2
	new file:   remarkbox/templates/mail_immediate_text.j2
	new file:   remarkbox/templates/mail_snippet_html.j2
	new file:   remarkbox/templates/mail_snippet_text.j2
	new file:   remarkbox/templates/namespace-settings.j2
	new file:   remarkbox/templates/new.j2
	new file:   remarkbox/templates/rss.xml.j2
	new file:   remarkbox/templates/setup-namespace.j2
	new file:   remarkbox/templates/show-count.j2
	new file:   remarkbox/templates/show-node.j2
	new file:   remarkbox/templates/show-node2.j2
	new file:   remarkbox/templates/sitemap.xml.j2
	new file:   remarkbox/templates/snippets/add-to-slack.j2
	new file:   remarkbox/templates/snippets/create.j2
	new file:   remarkbox/templates/snippets/csrf.j2
	new file:   remarkbox/templates/snippets/email.j2
	new file:   remarkbox/templates/snippets/flash-alerts.j2
	new file:   remarkbox/templates/snippets/forms.j2
	new file:   remarkbox/templates/snippets/google-analytics.j2
	new file:   remarkbox/templates/snippets/javascript-includes.j2
	new file:   remarkbox/templates/snippets/owner-key-comment.j2
	new file:   remarkbox/templates/snippets/phone-menu.j2
	new file:   remarkbox/templates/snippets/powered-by.j2
	new file:   remarkbox/templates/snippets/search.j2
	new file:   remarkbox/templates/snippets/snippets.j2
	new file:   remarkbox/templates/snippets/stripe.j2
	new file:   remarkbox/templates/snippets/stylesheet-includes.j2
	new file:   remarkbox/templates/snippets/submit.j2
	new file:   remarkbox/templates/update-card.j2
	new file:   remarkbox/templates/user-settings.j2
	new file:   remarkbox/templates/user-watching.j2
	new file:   remarkbox/tests/test_models.py
	new file:   remarkbox/tests/test_render.py
	new file:   remarkbox/tests/test_views.py
	new file:   remarkbox/views/__init__.py
	new file:   remarkbox/views/authenticated/__init__.py
	new file:   remarkbox/views/authenticated/authenticated.py
	new file:   remarkbox/views/authenticated/lock.py
	new file:   remarkbox/views/authenticated/notifications.py
	new file:   remarkbox/views/authenticated/oauth.py
	new file:   remarkbox/views/authenticated/stripe.py
	new file:   remarkbox/views/authenticated/topsecret.py
	new file:   remarkbox/views/authenticated/watch.py
	new file:   remarkbox/views/authentication.py
	new file:   remarkbox/views/list_nodes.py
	new file:   remarkbox/views/misc.py
	new file:   remarkbox/views/modify_node.py
	new file:   remarkbox/views/new_thread.py
	new file:   remarkbox/views/reply_node.py
	new file:   requirements-dev.txt
	new file:   requirements-prod.txt
	new file:   requirements-test.txt
	new file:   requirements.py3.txt
	new file:   requirements.txt
	new file:   setup.py
	new file:   test.ini
2021-12-26 07:44:05 -05:00

176 lines
4.8 KiB
Python

from pyramid.paster import bootstrap, setup_logging
from ..models import get_node_by_uri, get_node_by_id
from . import base_parser
# edit node.
from os import environ
from tempfile import NamedTemporaryFile
from subprocess import call
ANSI_ESCAPES = {
"HEADER": "\033[95m",
"OKBLUE": "\033[94m",
"OKGREEN": "\033[92m",
"WARNING": "\033[93m",
"FAIL": "\033[91m",
"DISABLED": "\033[37m",
"ENDC": "\033[0m",
"BOLD": "\033[1m",
"UNDERLINE": "\033[4m",
}
def ansi(msg, codes=None):
msg = str(msg)
if codes:
for code in codes:
msg = ANSI_ESCAPES[code] + msg
msg += ANSI_ESCAPES["ENDC"]
return msg
def color_node(node):
# if node.spam:
# return ansi(node.id, 'FAIL')
if node.disabled == True:
return ansi(node.id, codes=["DISABLED"])
elif node.verified == False:
return ansi(node.id, codes=["WARNING"])
else:
return ansi(node.id, codes=["OKGREEN"])
def traverse(node):
"""stolen from here: http://www.saltycrane.com/blog/2008/08/python-recursion-example-navigate-tree-data/"""
print(" " * traverse.level + str(color_node(node)))
for child in node.children:
traverse.level += 2
traverse(child)
traverse.level -= 2
def edit_node(node):
EDITOR = environ.get("EDITOR", "vim")
with NamedTemporaryFile(suffix=".md") as tf:
tf.write(node.data)
tf.flush()
call([EDITOR, tf.name])
# do the parsing with `tf` using regular File operations.
# for instance:
tf.seek(0)
new_node_data = tf.read()
if new_node_data and new_node_data != node.data:
node.data = new_node_data
def info_node(node):
from collections import OrderedDict
node_dict = OrderedDict(sorted(node.__dict__.items(), key=lambda t: t[0]))
for key, value in node_dict.items():
print("{}: {}".format(key, value))
if node.uri:
print(node.uri.data)
def get_arg_parser():
parser = base_parser("Modify a Node.")
parser.add_argument("-u", "--uri", type=unicode, default=None)
parser.add_argument("-i", "--id", type=unicode, default=None)
parser.add_argument("--show", default=False, action="store_true")
parser.add_argument("--info", default=False, action="store_true")
parser.add_argument("--move", default=False, metavar="NEW-PARENT-ID")
parser.add_argument("--edit", default=False, action="store_true")
parser.add_argument("--disable", default=False, action="store_true")
parser.add_argument("--enable", default=False, action="store_true")
parser.add_argument("--delete", default=False, action="store_true")
parser.add_argument("--spam", default=False, action="store_true")
return parser
def main():
parser = get_arg_parser()
args = parser.parse_args()
setup_logging(args.config)
if args.uri and args.id:
print("do not pass both -u and -i flags.")
exit(1)
action_flag_count = sum(
[
args.show,
args.info,
bool(args.move),
args.disable,
args.enable,
args.spam,
args.delete,
args.edit,
]
)
if action_flag_count != 1:
if action_flag_count == 0:
parser.print_help()
else:
print("only pass one action flag.")
exit(1)
with bootstrap(args.config) as env, env["request"].tm as tm:
request = env["request"]
node = None
if args.uri is not None:
node = get_node_by_uri(request.dbsession, args.uri)
elif args.id is not None:
node = get_node_by_id(request.dbsession, args.id)
if node is None:
print("No such, node. Check the id or uri.")
exit(1)
if args.show:
traverse.level = 1
traverse(node)
if args.info:
info_node(node)
if args.delete:
if (
raw_input("Delete node '{}' forever? [yes, no]: ".format(node.id))
== "yes"
):
request.dbsession.delete(node)
request.dbsession.flush()
else:
if args.move:
parent = get_node_by_id(request.dbsession, args.move)
if parent is None:
print(
"The new parent id ({}) does not exist.".format(args.new_parent)
)
exit(0)
node.parent_id = parent.id
node.root_id = parent.id
node.namespace = parent.namespace
if node.title:
node.title = ""
if args.edit:
edit_node(node)
if args.disable:
node.disable()
if args.enable:
node.enable()
request.dbsession.add(node)
request.dbsession.flush()