def subscribe(self, post_url, callback=None, pickle=True, timeout=None): post_id, post_site, post_type = fetch_post_id_and_site_from_url( post_url) if post_site not in GlobalVars.site_id_dict: log( "warning", "unknown site {} when subscribing to {}".format( post_site, post_url)) return if post_type == "answer": question_id = datahandling.get_post_site_id_link( (post_id, post_site, post_type)) if question_id is None: return else: question_id = post_id site_id = GlobalVars.site_id_dict[post_site] action = "{}-question-{}".format(site_id, question_id) max_time = (time.time() + timeout) if timeout else None if action in self.posts and callback: _, _, _, _, callbacks = self.posts[action] callbacks.append((callback, max_time)) else: self.posts[action] = (post_id, post_site, post_type, post_url, [(callback, max_time)] if callback else []) self.socket.send(action) if pickle: Tasks.do(self._save)
def check_websocket_for_deletion(self, post_site_id, timeout): time_to_check = time.time() + timeout post_id = post_site_id[0] post_type = post_site_id[2] if post_type == "answer": question_id = str(get_post_site_id_link(post_site_id)) if question_id is None: return else: question_id = post_id post_site = post_site_id[1] if post_site not in GlobalVars.site_id_dict: return site_id = GlobalVars.site_id_dict[post_site] ws = websocket.create_connection("ws://qa.sockets.stackexchange.com/") ws.send(site_id + "-question-" + question_id) while time.time() < time_to_check: ws.settimeout(time_to_check - time.time()) try: a = ws.recv() except websocket.WebSocketTimeoutException: return False if a is not None and a != "": try: d = json.loads(json.loads(a)["data"]) except: continue if d["a"] == "post-deleted" and str(d["qId"]) == question_id and ((post_type == "answer" and "aId" in d and str(d["aId"]) == post_id) or post_type == "question"): return True return False
def subscribe(self, post_url=None, hostname=None, site_id=None, question_id=None, pickle=True, timeout=DEFAULT_TIMEOUT, max_time=None, from_time=None): if GlobalVars.no_edit_watcher: return if post_url and not ((hostname or site_id) and question_id): post_id, hostname, post_type = fetch_post_id_and_site_from_url(post_url) if post_type == "answer": question_id = datahandling.get_post_site_id_link((post_id, hostname, post_type)) if question_id is None: log("warning", "Unable to get question ID when subscribing to: hostname: " "{} :: post ID:{} when subscribing to {}".format(hostname, post_id, post_url)) return else: question_id = post_id if post_type != "question": log("warning", "tried to edit-watch non-question: hostname: " "{} :: post ID:{} when subscribing to {}".format(hostname, question_id, post_url)) return if not site_id or not hostname: with GlobalVars.site_id_dict_lock: if not site_id and hostname: site_id = GlobalVars.site_id_dict.get(hostname) if site_id and not hostname: hostname = GlobalVars.site_id_dict_by_id.get(site_id) if not site_id or not hostname: log("warning", "unable to determine a valid site ID or hostname when subscribing to question ID " "{}:: site_id:{}:: hostname:{}:: post_url:{}".format(question_id, site_id, hostname, post_url)) return question_ids = question_id if type(question_ids) != list: question_ids = [question_id] now = time.time() if from_time: now = from_time if not max_time: max_time = now + timeout updated = None to_subscribe = [] with self.posts_lock: for question_id in question_ids: action = "{}-question-{}".format(site_id, question_id) if action not in self.posts: self.posts[action] = (site_id, hostname, question_id, max_time) to_subscribe.append(action) else: old_max_time = self.posts[action][2] if max_time > old_max_time: self.posts[action] = (site_id, hostname, question_id, max_time) elif updated is None: updated = False for action in to_subscribe: print('scheduling subscription to action:', action) Tasks.do(self._subscribe, action) if updated and pickle: self._schedule_save()
def subscribe(self, post_url, callback=None, pickle=True, timeout=None): post_id, post_site, post_type = fetch_post_id_and_site_from_url(post_url) if post_site not in GlobalVars.site_id_dict: log("warning", "unknown site {} when subscribing to {}".format(post_site, post_url)) return if post_type == "answer": question_id = datahandling.get_post_site_id_link((post_id, post_site, post_type)) if question_id is None: return else: question_id = post_id site_id = GlobalVars.site_id_dict[post_site] action = "{}-question-{}".format(site_id, question_id) max_time = (time.time() + timeout) if timeout else None if action not in self.posts: self.posts[action] = (post_id, post_site, post_type, post_url, [(callback, max_time)] if callback else []) try: self.socket.send(action) except websocket.WebSocketException: log('error', 'DeletionWatcher failed on sending {}'.format(action)) elif callback: _, _, _, _, callbacks = self.posts[action] callbacks.append((callback, max_time)) else: return if pickle: Tasks.do(self._save)
def check_websocket_for_deletion(self, post_site_id, post_url, timeout): time_to_check = time.time() + timeout post_id = post_site_id[0] post_type = post_site_id[2] if post_type == "answer": question_id = str(datahandling.get_post_site_id_link(post_site_id)) if question_id is None: return else: question_id = post_id post_site = post_site_id[1] if post_site not in GlobalVars.site_id_dict: return site_id = GlobalVars.site_id_dict[post_site] ws = websocket.create_connection("wss://qa.sockets.stackexchange.com/") ws.send(site_id + "-question-" + question_id) while time.time() < time_to_check: ws.settimeout(time_to_check - time.time()) try: a = ws.recv() except websocket.WebSocketTimeoutException: t_metasmoke = Thread( name="metasmoke send deletion stats", target=metasmoke.Metasmoke.send_deletion_stats_for_post, args=(post_url, False)) t_metasmoke.start() return False if a is not None and a != "": try: action = json.loads(a)["action"] if action == "hb": ws.send("hb") continue else: d = json.loads(json.loads(a)["data"]) except: continue if d["a"] == "post-deleted" and str(d["qId"]) == question_id \ and ((post_type == "answer" and "aId" in d and str(d["aId"]) == post_id) or post_type == "question"): t_metasmoke = Thread(name="metasmoke send deletion stats", target=metasmoke.Metasmoke. send_deletion_stats_for_post, args=(post_url, True)) t_metasmoke.start() return True t_metasmoke = Thread( name="metasmoke send deletion stats", target=metasmoke.Metasmoke.send_deletion_stats_for_post, args=(post_url, False)) t_metasmoke.start() return False
def check_websocket_for_deletion(self, post_site_id, post_url, timeout): time_to_check = time.time() + timeout post_id = post_site_id[0] post_type = post_site_id[2] if post_type == "answer": question_id = str(datahandling.get_post_site_id_link(post_site_id)) if question_id is None: return else: question_id = post_id post_site = post_site_id[1] if post_site not in GlobalVars.site_id_dict: return site_id = GlobalVars.site_id_dict[post_site] ws = websocket.create_connection("ws://qa.sockets.stackexchange.com/") ws.send(site_id + "-question-" + question_id) while time.time() < time_to_check: ws.settimeout(time_to_check - time.time()) try: a = ws.recv() except websocket.WebSocketTimeoutException: t_metasmoke = Thread(name="metasmoke send deletion stats", target=metasmoke.Metasmoke.send_deletion_stats_for_post, args=(post_url, False)) t_metasmoke.start() return False if a is not None and a != "": try: action = json.loads(a)["action"] if action == "hb": ws.send("hb") continue else: d = json.loads(json.loads(a)["data"]) except: continue if d["a"] == "post-deleted" and str(d["qId"]) == question_id \ and ((post_type == "answer" and "aId" in d and str(d["aId"]) == post_id) or post_type == "question"): t_metasmoke = Thread(name="metasmoke send deletion stats", target=metasmoke.Metasmoke.send_deletion_stats_for_post, args=(post_url, True)) t_metasmoke.start() return True t_metasmoke = Thread(name="metasmoke send deletion stats", target=metasmoke.Metasmoke.send_deletion_stats_for_post, args=(post_url, False)) t_metasmoke.start() return False
def subscribe(self, post_url, callback=None, pickle=True, timeout=None): if GlobalVars.no_deletion_watcher: return post_id, post_site, post_type = fetch_post_id_and_site_from_url( post_url) if post_site not in GlobalVars.site_id_dict: log( "warning", "unknown site {} when subscribing to {}".format( post_site, post_url)) return if post_type == "answer": question_id = datahandling.get_post_site_id_link( (post_id, post_site, post_type)) if question_id is None: return else: question_id = post_id site_id = GlobalVars.site_id_dict[post_site] action = "{}-question-{}".format(site_id, question_id) max_time = (time.time() + timeout) if timeout else None if action not in self.posts: self.posts[action] = (post_id, post_site, post_type, post_url, [(callback, max_time)] if callback else []) try: self.socket.send(action) except websocket.WebSocketException: log('error', 'DeletionWatcher failed on sending {}'.format(action)) elif callback: _, _, _, _, callbacks = self.posts[action] callbacks.append((callback, max_time)) else: return if pickle: Tasks.do(self._save)
def subscribe(self, post_url, callback=None, pickle=True, timeout=None): if GlobalVars.no_deletion_watcher: return post_id, post_site, post_type = fetch_post_id_and_site_from_url( post_url) with GlobalVars.site_id_dict_lock: site_id = GlobalVars.site_id_dict.get(post_site, None) if not site_id: log( "warning", "unknown site {} when subscribing to {}".format( post_site, post_url)) return if post_type == "answer": question_id = datahandling.get_post_site_id_link( (post_id, post_site, post_type)) if question_id is None: return else: question_id = post_id action = "{}-question-{}".format(site_id, question_id) max_time = (time.time() + timeout) if timeout else None with self.posts_lock: if action not in self.posts: self.posts[action] = (post_id, post_site, post_type, post_url, [(callback, max_time)] if callback else []) Tasks.do(self._subscribe, action) elif callback: _, _, _, _, callbacks = self.posts[action] callbacks.append((callback, max_time)) else: return if pickle: self._schedule_save()