def publish_board(board): players = Player.get_top_for_board(board, limit=5) publish( str(board.id), HttpStreamFormat('event: update\ndata: %s\n\n' % _board_json(board, players, pretty=False)))
def document_changes(request, document_id): gchannel = 'document-{}'.format(document_id) if request.method == 'GET': link = False sse = False if request.GET.get('link') == 'true': link = True sse = True else: accept = request.META.get('HTTP_ACCEPT') if accept and accept.find('text/event-stream') != -1: sse = True after = None last_id = request.grip.last.get(gchannel) if last_id: after = int(last_id) if after is None and sse: last_id = request.META.get('Last-Event-ID') if last_id: after = int(last_id) if after is None and sse: last_id = request.GET.get('lastEventId') if last_id: after = int(last_id) if after is None: afterstr = request.GET.get('after') if afterstr: after = int(afterstr) try: doc = Document.objects.get(eid=document_id) if after is not None: if after > doc.version: return HttpResponseNotFound('version in the future') changes = DocumentChange.objects.filter( document=doc, version__gt=after).order_by('version')[:50] out = [c.export() for c in changes] if len(out) > 0: last_version = out[-1]['version'] else: last_version = after else: out = [] last_version = doc.version except Document.DoesNotExist: if after is not None and after > 0: return HttpResponseNotFound('version in the future') out = [] last_version = 0 if sse: body = '' if not link: body += 'event: opened\ndata:\n\n' for i in out: event = 'id: {}\nevent: change\ndata: {}\n\n'.format( i['version'], json.dumps(i)) body += event resp = HttpResponse(body, content_type='text/event-stream') parsed = urlparse.urlparse(reverse('document-changes', args=[document_id])) instruct = request.grip.start_instruct() instruct.set_next_link('{}?link=true&after={}'.format( parsed.path, last_version)) if len(out) < 50: instruct.set_hold_stream() instruct.add_channel(Channel(gchannel, prev_id=str(last_version))) instruct.set_keep_alive('event: keep-alive\ndata:\n\n; format=cstring', 20) return resp else: return JsonResponse({'changes': out}) elif request.method == 'POST': opdata = json.loads(request.POST['op']) for i in opdata: if not isinstance(i, int) and not isinstance(i, basestring): return HttpResponseBadRequest('invalid operation'); op = TextOperation(opdata) request_id = request.POST['request-id'] parent_version = int(request.POST['parent-version']) doc = _doc_get_or_create(document_id) saved = False with transaction.atomic(): doc = Document.objects.select_for_update().get(id=doc.id) try: # already submitted? c = DocumentChange.objects.get( document=doc, request_id=request_id, parent_version=parent_version) except DocumentChange.DoesNotExist: changes_since = DocumentChange.objects.filter( document=doc, version__gt=parent_version, version__lte=doc.version).order_by('version') for c in changes_since: op2 = TextOperation(json.loads(c.data)) try: op, _ = TextOperation.transform(op, op2) except: return HttpResponseBadRequest( 'unable to transform against version {}'.format(c.version)) try: doc.content = op(doc.content) except: return HttpResponseBadRequest( 'unable to apply {} to version {}'.format( json.dumps(op.ops), doc.version)) next_version = doc.version + 1 c = DocumentChange( document=doc, version=next_version, request_id=request_id, parent_version=parent_version, data=json.dumps(op.ops)) c.save() doc.version = next_version doc.save() saved = True if saved: event = 'id: {}\nevent: change\ndata: {}\n\n'.format( c.version, json.dumps(c.export())) publish( gchannel, HttpStreamFormat(event), id=str(c.version), prev_id=str(c.version - 1)) return JsonResponse({'version': c.version}) else: return HttpResponseNotAllowed(['GET', 'POST'])
def hit(req, inbox_id): try: inbox = db.inbox_get(inbox_id) except redis_ops.InvalidId: return HttpResponseBadRequest('Bad Request: Invalid id\n') except redis_ops.ObjectDoesNotExist: return HttpResponseNotFound('Not Found\n') except: return HttpResponse('Service Unavailable\n', status=503) response_mode = inbox.get('response_mode') if not response_mode: response_mode = 'auto' # pubsubhubbub verify request? hub_challenge = req.GET.get('hub.challenge') if response_mode == 'wait' or (response_mode == 'wait-verify' and hub_challenge): respond_now = False else: respond_now = True item = _req_to_item(req) if hub_challenge: item['type'] = 'hub-verify' else: item['type'] = 'normal' try: item_id, prev_id, item_created = db.inbox_append_item(inbox_id, item) db.inbox_clear_expired_items(inbox_id) except redis_ops.InvalidId: return HttpResponseBadRequest('Bad Request: Invalid id\n') except redis_ops.ObjectDoesNotExist: return HttpResponseNotFound('Not Found\n') except: return HttpResponse('Service Unavailable\n', status=503) item['id'] = item_id item['created'] = item_created item = _convert_item(item, respond_now) hr_headers = dict() hr_headers['Content-Type'] = 'application/json' hr = dict() hr['last_cursor'] = item_id hr['items'] = [item] hr_body = json.dumps(hr) + '\n' hs_body = json.dumps(item) + '\n' formats = list() formats.append(HttpResponseFormat(headers=hr_headers, body=hr_body)) formats.append(HttpStreamFormat(hs_body)) publish(grip_prefix + 'inbox-%s' % inbox_id, formats, id=item_id, prev_id=prev_id) if respond_now: if hub_challenge: return HttpResponse(hub_challenge) else: return HttpResponse('Ok\n') else: # wait for the user to respond db.request_add_pending(inbox_id, item_id) set_hold_longpoll(req, grip_prefix + 'wait-%s-%s' % (inbox_id, item_id)) return HttpResponse('Service Unavailable\n', status=503, content_type='text/html')
def publish_worker(): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(('127.0.0.1', 5004)) while True: data, addr = sock.recvfrom(65536) pub.publish('music', Item(HttpStreamFormat(data)))
def document_changes(request, document_id): url = REPLICA_URLS[CURRENT_PRIMARY]+'/api/documents/{}/changes/'.format(document_id) print('url here goes', url) if request.method == 'GET': gchannel = 'document-{}'.format(document_id) link = False sse = False if request.GET.get('link') == 'true': link = True sse = True else: accept = request.META.get('HTTP_ACCEPT') if accept and accept.find('text/event-stream') != -1: sse = True after = None last_id = request.grip.last.get(gchannel) if last_id: after = int(last_id) if after is None and sse: last_id = request.META.get('Last-Event-ID') if last_id: after = int(last_id) if after is None and sse: last_id = request.GET.get('lastEventId') if last_id: after = int(last_id) if after is None: afterstr = request.GET.get('after') if afterstr: after = int(afterstr) payload = request.GET.dict() payload['from-master'] = True response = requests.get(url, payload) resp_content = json.loads(response.text) if "success" in resp_content: if resp_content["success"]: response = HttpResponse(resp_content['body'], content_type='text/event-stream') parsed = urlparse(reverse('document-changes', args=[document_id])) instruct = request.grip.start_instruct() instruct.set_next_link('{}?link=true&after={}'.format(parsed.path, resp_content['last_version'])) if len(resp_content['out']) < 50: instruct.set_hold_stream() instruct.add_channel(Channel(resp_content['gchannel'], prev_id=str(resp_content['last_version']))) instruct.set_keep_alive('event: keep-alive\ndata:\n\n; format=cstring', 20) else: response = HttpResponseNotFound('version in the future') elif request.method == 'POST': payload = request.POST.dict() payload['from-master'] = True response = requests.post(url, payload) print('\n\n-----',response,response.status_code,'\n\n') if response.status_code == 200: resp_content = json.loads(response.text) print('resp',resp_content) if "success" in resp_content: if resp_content["success"]: publish( resp_content['gchannel'], HttpStreamFormat(json.loads(resp_content['event'])), id=str(resp_content['version']), prev_id=str(resp_content['version']-1)) response = JsonResponse({'version': resp_content['version']}) elif response.status_code == 500: response = HttpResponseBadRequest(response.text) else: response = HttpResponseNotFound('invalid') return response
def document_change(request, document_id): if request.method == 'GET': link = False sse = False if request.GET.get('link') == 'true': link = True sse = True else: accept = request.META.get('HTTP_ACCEPT') if accept and accept.find('text/event-stream') != -1: sse = True after = None grip_last = request.META.get('HTTP_GRIP_LAST') if grip_last: at = grip_last.find('last-id=') if at == -1: raise ValueError('invalid Grip-Last header') at += 8 after = int(grip_last[at:]) if after is None and sse: last_id = request.META.get('Last-Event-ID') if last_id: after = int(last_id) if after is None and sse: last_id = request.GET.get('lastEventId') if last_id: after = int(last_id) if after is None: afterstr = request.GET.get('after') if afterstr: after = int(afterstr) try: doc = Document.objects.get(eid=document_id) if after is not None: if after > doc.version: return HttpResponseNotFound('version in the future') changes = DocumentChange.objects.filter( document=doc, version__gt=after).order_by('version')[:50] out = [c.export() for c in changes] if len(out) > 0: last_version = out[-1]['version'] else: last_version = after else: out = [] last_version = doc.version except Document.DoesNotExist: if after is not None and after > 0: return HttpResponseNotFound('version in the future') out = [] last_version = 0 if sse: body = '' if not link: body += 'event: opened\ndata:\n\n' for i in out: event = 'id: %d\nevent: change\ndata: %s\n\n' % ( i['version'], json.dumps(i)) body += event resp = HttpResponse(body, content_type='text/event-stream') parsed = urlparse(reverse('document-changes', args=[document_id])) resp['Grip-Link'] = '<%s?link=true&after=%d>; rel=next' % ( parsed.path, last_version) if len(out) < 50: resp['Grip-Hold'] = 'stream' resp['Grip-Channel'] = 'document-%s; prev-id=%s' % ( document_id, last_version) resp['Grip-Keep-Alive'] = 'event: keep-alive\\ndata:\\n\\n; format=cstring; timeout=20' # print(resp.content) return resp else: return JsonResponse({'changes': out}) elif request.method == 'POST': opdata = json.loads(request.POST['op']) for i in opdata: if not isinstance(i, int) and not isinstance(i, str): return HttpResponseBadRequest('invalid operation'); op = TextOperation(opdata) request_id = request.POST['request-id'] parent_version = int(request.POST['parent-version']) doc = _doc_get_or_create(document_id) saved = False with transaction.atomic(): doc = Document.objects.select_for_update().get(id=doc.id) try: # already submitted? c = DocumentChange.objects.get( document=doc, request_id=request_id, parent_version=parent_version) except DocumentChange.DoesNotExist: changes_since = DocumentChange.objects.filter( document=doc, version__gt=parent_version, version__lte=doc.version).order_by('version') for c in changes_since: op2 = TextOperation(json.loads(c.data)) try: op, _ = TextOperation.transform(op, op2) except: return HttpResponseBadRequest( 'unable to transform against version %d' % c.version) try: doc.content = op(doc.content) except: return HttpResponseBadRequest( 'unable to apply %s to version %d' % ( json.dumps(op.ops), doc.version)) next_version = doc.version + 1 c = DocumentChange( document=doc, version=next_version, request_id=request_id, parent_version=parent_version, data=json.dumps(op.ops)) c.save() doc.version = next_version doc.save() saved = True if saved: event = 'id: %d\nevent: change\ndata: %s\n\n' % ( c.version, json.dumps(c.export())) publish( 'document-%s' % document_id, HttpStreamFormat(event), id=str(c.version), prev_id=str(c.version - 1)) return JsonResponse({'version': c.version}) else: return HttpResponseNotAllowed(['GET', 'POST'])
def item(request, headline_id): h = get_object_or_404(Headline, pk=headline_id) hchannel = str(headline_id) if request.wscontext: ws = request.wscontext if ws.is_opening(): ws.accept() ws.subscribe(hchannel) while ws.can_recv(): message = ws.recv() if message is None: ws.close() break return HttpResponse() elif request.method == 'GET': if request.META.get('HTTP_ACCEPT') == 'text/event-stream': resp = HttpResponse(content_type='text/event-stream') set_hold_stream(request, hchannel) return resp else: wait = request.META.get('HTTP_WAIT') if wait: wait = int(wait) if wait < 1: wait = None if wait > 300: wait = 300 inm = request.META.get('HTTP_IF_NONE_MATCH') etag = '"%s"' % calendar.timegm(h.date.utctimetuple()) if inm == etag: resp = HttpResponseNotModified() if wait: set_hold_longpoll(request, hchannel, timeout=wait) else: resp = _json_response(h.to_data()) resp['ETag'] = etag return resp elif request.method == 'PUT': hdata = json.loads(request.read()) h.type = hdata['type'] h.title = hdata.get('title', '') h.text = hdata.get('text', '') h.save() hdata = h.to_data() hjson = json.dumps(hdata) etag = '"%s"' % calendar.timegm(h.date.utctimetuple()) rheaders = {'Content-Type': 'application/json', 'ETag': etag} hpretty = json.dumps(hdata, indent=4) + '\n' formats = [] formats.append(HttpResponseFormat(body=hpretty, headers=rheaders)) formats.append(HttpStreamFormat('event: update\ndata: %s\n\n' % hjson)) formats.append(WebSocketMessageFormat(hjson)) publish(hchannel, formats) resp = _json_response(hdata) resp['ETag'] = etag return resp else: return HttpResponseNotAllowed(['GET', 'PUT'])