예제 #1
0
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)))
예제 #2
0
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'])
예제 #3
0
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')
예제 #4
0
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		
예제 #6
0
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'])
예제 #7
0
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'])