2020-04-02 09:59:28 -04:00
|
|
|
#!/usr/bin/env python3
|
2013-02-05 09:58:27 -05:00
|
|
|
import sys
|
2013-10-28 10:54:32 -04:00
|
|
|
import os
|
2013-02-05 09:58:27 -05:00
|
|
|
import logging
|
2017-09-29 19:21:18 -04:00
|
|
|
import argparse
|
2017-09-14 05:18:39 -04:00
|
|
|
import json
|
2013-02-05 09:58:27 -05:00
|
|
|
import unicodedata
|
|
|
|
|
2013-10-28 10:54:32 -04:00
|
|
|
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'api'))
|
2013-08-07 11:51:03 -04:00
|
|
|
import zulip
|
2013-02-05 09:58:27 -05:00
|
|
|
|
2021-04-06 18:48:55 -04:00
|
|
|
def write_public_streams() -> None:
|
2013-02-05 09:58:27 -05:00
|
|
|
public_streams = set()
|
|
|
|
|
2021-04-06 18:48:55 -04:00
|
|
|
for stream_name in stream_names:
|
2013-02-05 09:58:27 -05:00
|
|
|
# Zephyr class names are canonicalized by first applying NFKC
|
|
|
|
# normalization and then lower-casing server-side
|
2021-04-06 17:44:46 -04:00
|
|
|
canonical_cls = unicodedata.normalize("NFKC", stream_name).lower()
|
|
|
|
if canonical_cls in ['security', 'login', 'network', 'ops', 'user_locate',
|
|
|
|
'mit', 'moof', 'wsmonitor', 'wg_ctl', 'winlogger',
|
|
|
|
'hm_ctl', 'hm_stat', 'zephyr_admin', 'zephyr_ctl']:
|
2013-02-05 09:58:27 -05:00
|
|
|
# These zephyr classes cannot be subscribed to by us, due
|
|
|
|
# to MIT's Zephyr access control settings
|
|
|
|
continue
|
|
|
|
|
|
|
|
public_streams.add(canonical_cls)
|
|
|
|
|
2021-04-06 18:48:55 -04:00
|
|
|
with open("/home/zulip/public_streams.tmp", "w") as f:
|
|
|
|
f.write(json.dumps(list(public_streams)) + "\n")
|
|
|
|
os.rename("/home/zulip/public_streams.tmp", "/home/zulip/public_streams")
|
2013-02-05 09:58:27 -05:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2013-10-04 13:19:57 -04:00
|
|
|
log_file = "/home/zulip/sync_public_streams.log"
|
2013-02-05 09:58:27 -05:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
log_format = "%(asctime)s: %(message)s"
|
|
|
|
logging.basicConfig(format=log_format)
|
|
|
|
formatter = logging.Formatter(log_format)
|
|
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
file_handler = logging.FileHandler(log_file)
|
|
|
|
file_handler.setFormatter(formatter)
|
|
|
|
logger.addHandler(file_handler)
|
|
|
|
|
2017-09-29 19:21:18 -04:00
|
|
|
parser = zulip.add_default_arguments(argparse.ArgumentParser())
|
|
|
|
options = parser.parse_args()
|
2017-03-20 15:14:38 -04:00
|
|
|
|
|
|
|
zulip_client = zulip.Client(client="ZulipSyncPublicStreamsBot/0.1")
|
2021-04-06 18:48:55 -04:00
|
|
|
backoff = zulip.RandomExponentialBackoff()
|
2017-03-20 15:14:38 -04:00
|
|
|
|
2021-04-06 18:48:55 -04:00
|
|
|
while backoff.keep_going():
|
|
|
|
try:
|
|
|
|
res = zulip_client.register(event_types=["stream"])
|
|
|
|
if res["result"] != "success":
|
|
|
|
backoff.fail()
|
|
|
|
logger.error("Error registering event queue:\n%r", res)
|
|
|
|
continue
|
|
|
|
except Exception:
|
|
|
|
logger.exception("Error registering event queue:")
|
2013-02-05 09:58:27 -05:00
|
|
|
continue
|
|
|
|
|
2021-04-06 18:48:55 -04:00
|
|
|
backoff.succeed()
|
|
|
|
queue_id = res["queue_id"]
|
|
|
|
last_event_id = res["last_event_id"]
|
|
|
|
stream_names = {stream["name"] for stream in res["streams"]}
|
|
|
|
write_public_streams()
|
|
|
|
|
|
|
|
while backoff.keep_going():
|
|
|
|
try:
|
|
|
|
res = zulip_client.get_events(queue_id=queue_id, last_event_id=last_event_id)
|
|
|
|
if res["result"] != "success":
|
|
|
|
backoff.fail()
|
|
|
|
logger.error("Error getting events:\n%r", res)
|
|
|
|
if res["result"] == "error":
|
|
|
|
# Break out to the outer loop to re-register the event queue.
|
|
|
|
break
|
|
|
|
continue
|
|
|
|
except Exception:
|
|
|
|
logger.exception("Error getting events:")
|
|
|
|
continue
|
2013-02-05 09:58:27 -05:00
|
|
|
|
2021-04-06 18:48:55 -04:00
|
|
|
backoff.succeed()
|
|
|
|
for event in res["events"]:
|
|
|
|
last_event_id = max(last_event_id, event["id"])
|
|
|
|
if event["type"] == "stream":
|
|
|
|
if event["op"] == "create":
|
|
|
|
stream_names.update(
|
|
|
|
stream["name"] for stream in event["streams"]
|
|
|
|
)
|
|
|
|
write_public_streams()
|
|
|
|
elif event["op"] == "delete":
|
|
|
|
stream_names.difference_update(
|
|
|
|
stream["name"] for stream in event["streams"]
|
|
|
|
)
|
|
|
|
write_public_streams()
|