def register(request): if not request.POST: raise kbapi.BadRequestError('POST required.') form = forms.RegisterForm(request.POST) errors = {} if not form.is_valid(): errors = _form_errors(form) else: username = form.cleaned_data['username'] try: u = models.User() u.username = username u.email = form.cleaned_data['email'] u.save() u.set_password(form.cleaned_data['password']) if 'photo' in request.FILES: pic = models.Picture.objects.create(user=u) photo = request.FILES['photo'] pic.image.save(photo.name, photo) pic.save() profile = u.get_profile() profile.mugshot = pic profile.save() return protolib.ToProto(u, full=True) except IntegrityError: user_errs = errors.get('username', []) user_errs.append('Username not available.') errors['username'] = user_errs raise kbapi.BadRequestError(errors)
def assign_auth_token(request, auth_device, token_value): if not request.POST: raise kbapi.BadRequestError('POST required.') form = forms.AssignTokenForm(request.POST) if not form.is_valid(): errors = _form_errors(form) raise kbapi.BadRequestError(errors) b = request.backend username = form.cleaned_data['username'] user = b.get_user(username) if not user: raise kbapi.BadRequestError("User does not exist") try: tok = b.get_auth_token(auth_device, token_value) except backend.exceptions.NoTokenError: tok = b.create_auth_token(auth_device, token_value, username=username) if tok.user != user: if tok.user: raise kbapi.BadRequestError("Token is already bound to a user") tok.user = user tok.save() return tok
def tap_spill(request, meter_name_or_id): tap = get_tap_from_meter_name_or_404(meter_name_or_id) if not tap.current_keg: raise kbapi.BadRequestError("No keg on tap.") form = forms.TapSpillForm(request.POST) if form.is_valid(): tap.current_keg.spilled_ml += form.cleaned_data["volume_ml"] tap.current_keg.save() else: raise kbapi.BadRequestError(_form_errors(form)) return protolib.ToProto(tap, full=True)
def cancel_drink(request): if request.method != 'POST': raise kbapi.BadRequestError('POST required') form = forms.CancelDrinkForm(request.POST) if not form.is_valid(): raise kbapi.BadRequestError(_form_errors(form)) cd = form.cleaned_data try: res = request.backend.cancel_drink(drink_id=cd.get('id'), spilled=cd.get('spilled', False)) return protolib.ToProto(res, full=True) except backend.exceptions.BackendError as e: raise kbapi.ServerError(str(e))
def _tap_detail_post(request, tap): form = forms.DrinkPostForm(request.POST) if not form.is_valid(): raise kbapi.BadRequestError(_form_errors(form)) cd = form.cleaned_data if cd.get("pour_time") and cd.get("now"): pour_time = datetime.datetime.fromtimestamp(cd.get("pour_time")) pour_now = datetime.datetime.fromtimestamp(cd.get("now")) pour_time_ago = pour_now - pour_time pour_time = timezone.now() - pour_time_ago else: pour_time = None duration = cd.get("duration") if duration is None: duration = 0 try: drink = request.backend.record_drink( tap, ticks=cd["ticks"], volume_ml=cd.get("volume_ml"), username=cd.get("username"), pour_time=pour_time, duration=duration, shout=cd.get("shout"), tick_time_series=cd.get("tick_time_series"), photo=request.FILES.get("photo", None), ) return protolib.ToProto(drink, full=True) except backend.exceptions.BackendError as e: raise kbapi.ServerError(str(e))
def ToJsonError(e, exc_info): """Converts an exception to an API error response.""" # Wrap some common exception types into kbapi types if isinstance(e, Http404): e = kbapi.NotFoundError(e.message) elif isinstance(e, ValueError): e = kbapi.BadRequestError(str(e)) elif isinstance(e, backend.NoTokenError): e = kbapi.NotFoundError(e.message) # Now determine the response based on the exception type. if isinstance(e, kbapi.Error): code = e.__class__.__name__ http_code = e.HTTP_CODE message = e.Message() else: code = 'ServerError' http_code = 500 message = 'An internal error occurred: %s' % str(e) if settings.DEBUG: message += "\n" + "\n".join(traceback.format_exception(*exc_info)) if settings.DEBUG and settings.HAVE_RAVEN: from raven.contrib.django.models import client client.captureException() result = {'error': {'code': code, 'message': message}} return result, http_code
def tap_calibrate(request, meter_name_or_id): # TODO(mikey): This would make more semantic sense as PATCH /taps/tap-name/, # but Django's support for non-POST verbs is poor (specifically wrt request # body/form handling). tap = get_tap_from_meter_name_or_404(meter_name_or_id) meter = tap.current_meter() if not meter: raise kbapi.BadRequestError("Tap does not have a meter!") form = forms.CalibrateTapForm(request.POST) if form.is_valid(): meter.ticks_per_ml = 1.0 / form.cleaned_data["ml_per_tick"] meter.save() tap = get_tap_from_meter_name_or_404(meter_name_or_id) else: raise kbapi.BadRequestError(_form_errors(form)) return protolib.ToProto(tap, full=True)
def tap_connect_thermo(request, meter_name_or_id): tap = get_tap_from_meter_name_or_404(meter_name_or_id) form = forms.ConnectThermoForm(request.POST) if form.is_valid(): tap = request.backend.connect_thermo(tap, form.cleaned_data["thermo"]) else: raise kbapi.BadRequestError(_form_errors(form)) return protolib.ToProto(tap, full=True)
def _thermo_sensor_post(request, sensor_name): form = forms.ThermoPostForm(request.POST) if not form.is_valid(): raise kbapi.BadRequestError(_form_errors(form)) cd = form.cleaned_data sensor, created = models.ThermoSensor.objects.get_or_create(raw_name=sensor_name) # TODO(mikey): use form fields to compute `when` return request.backend.log_sensor_reading(sensor.raw_name, cd['temp_c'])
def tap_activate(request, meter_name_or_id): tap = get_tap_from_meter_name_or_404(meter_name_or_id) form = ChangeKegForm(request.POST) if form.is_valid(): form.save(tap) else: raise kbapi.BadRequestError(_form_errors(form)) return protolib.ToProto(tap, full=True)
def tap_detail(request, tap_id): tap = get_object_or_404(models.KegTap, meter_name=tap_id) if request.method == 'POST': return _tap_detail_post(request, tap) elif request.method == 'GET': return _tap_detail_get(request, tap) else: raise kbapi.BadRequestError('Method not supported')
def tap_detail(request, meter_name_or_id): tap = get_tap_from_meter_name_or_404(meter_name_or_id) if request.method == 'POST': util.check_api_key(request) return _tap_detail_post(request, tap) elif request.method == 'GET': return _tap_detail_get(request, tap) else: raise kbapi.BadRequestError('Method not supported')
def all_flow_meters(request): if request.method == "POST": form = NewFlowMeterForm(request.POST) if form.is_valid(): return form.save() else: errors = _form_errors(form) raise kbapi.BadRequestError(errors) return models.FlowMeter.objects.all()
def all_controllers(request): if request.method == 'POST': form = ControllerForm(request.POST) if form.is_valid(): return form.save() else: errors = _form_errors(form) raise kbapi.BadRequestError(errors) return models.Controller.objects.all()
def all_flow_toggles(request): if request.method == 'POST': form = FlowToggleForm(request.POST) if form.is_valid(): return form.save() else: errors = _form_errors(form) raise kbapi.BadRequestError(errors) return models.FlowToggle.objects.all()
def login(request): if request.POST: form = AuthenticationForm(data=request.POST) if form.is_valid(): auth_login(request, form.get_user()) if request.session.test_cookie_worked(): request.session.delete_test_cookie() return {'result': 'ok'} else: raise kbapi.PermissionDeniedError('Login failed.') raise kbapi.BadRequestError('POST required.')
def tap_spill(request, tap_id): tap = get_object_or_404(models.KegTap, meter_name=tap_id) if not tap.current_keg: raise kbapi.BadRequestError('No keg on tap.') form = forms.TapSpillForm(request.POST) if form.is_valid(): tap.current_keg.spilled_ml += form.cleaned_data['volume_ml'] tap.current_keg.save() else: raise kbapi.BadRequestError, _form_errors(form) return protolib.ToProto(tap, full=True)
def debug_log(request): if request.method != 'POST' or not settings.HAVE_RAVEN or not settings.HAVE_SENTRY: raise Http404('Method not supported') form = forms.DebugLogForm(request.POST) if not form.is_valid(): raise kbapi.BadRequestError(_form_errors(form)) client = LocalRavenClient([]) message = form.cleaned_data['message'] ident = client.get_ident(client.create_from_text(message)) client.send() return {'log_id': ident}
def post_user_photo(request, user): photo_file = request.FILES.get('photo') if not photo_file: raise kbapi.BadRequestError('The file "photo" is required.') pic = models.Picture.objects.create(user=user) pic.image.save(photo_file.name, photo_file) pic.save() user.mugshot = pic user.save() return protolib.ToProto(pic)
def register(request): if not request.POST: raise kbapi.BadRequestError('POST required.') form = forms.RegisterForm(request.POST) errors = {} if not form.is_valid(): errors = _form_errors(form) else: username = form.cleaned_data['username'] email = form.cleaned_data.get('email', None) password = form.cleaned_data.get('password', None) photo = request.FILES.get('photo', None) try: user = request.backend.create_new_user(username, email=email, password=password, photo=photo) return protolib.ToProto(user, full=True) except backend.exceptions.UserExistsError: user_errs = errors.get('username', []) user_errs.append('Username not available.') errors['username'] = user_errs raise kbapi.BadRequestError(errors)
def tap_detail(request, meter_name_or_id): tap = get_tap_from_meter_name_or_404(meter_name_or_id) if request.method == "POST": util.check_api_key(request) return _tap_detail_post(request, tap) elif request.method == "GET": return _tap_detail_get(request, tap) elif request.method == "DELETE": util.check_api_key(request) tap.delete() return RESULT_OK raise kbapi.BadRequestError("Method not supported")
def get_controller(request, controller_id): controller = get_object_or_404(models.Controller, id=controller_id) if request.method == 'DELETE': controller.delete() elif request.method == 'POST': form = ControllerForm(request.POST, instance=controller) if form.is_valid(): controller = form.save() else: errors = _form_errors(form) raise kbapi.BadRequestError(errors) return protolib.ToProto(controller, full=True)
def get_flow_toggle(request, flow_toggle_id): toggle = get_object_or_404(models.FlowToggle, id=flow_toggle_id) if request.method == 'DELETE': toggle.delete() elif request.method == 'POST': form = FlowToggleForm(request.POST, instance=toggle) if form.is_valid(): toggle = form.save() else: errors = _form_errors(form) raise kbapi.BadRequestError(errors) return protolib.ToProto(toggle, full=True)
def assign_auth_token(request, auth_device, token_value): if not request.POST: raise kbapi.BadRequestError('POST required.') form = forms.AssignTokenForm(request.POST) if not form.is_valid(): errors = _form_errors(form) raise kbapi.BadRequestError(errors) b = KegbotBackend(site=request.kbsite) username = form.cleaned_data['username'] try: tok = b.GetAuthToken(auth_device, token_value) user = b._GetUserObjFromUsername(username) if not user: raise kbapi.BadRequestError("User does not exist") if tok.user != user: if tok.user: raise kbapi.BadRequestError("Token is already bound to a user") tok.user = user tok.save() return tok except backend.NoTokenError: return b.CreateAuthToken(auth_device, token_value, username=username)
def get_flow_meter(request, flow_meter_id): meter = get_object_or_404(models.FlowMeter, id=flow_meter_id) if request.method == 'DELETE': meter.delete() elif request.method == 'POST': form = UpdateFlowMeterForm(request.POST, instance=meter) if form.is_valid(): meter = form.save() else: errors = _form_errors(form) raise kbapi.BadRequestError(errors) return protolib.ToProto(meter, full=True)
def to_json_error(e, exc_info): """Converts an exception to an API error response.""" # Wrap some common exception types into kbapi types if isinstance(e, Http404): e = kbapi.NotFoundError(str(e)) elif isinstance(e, ValueError): e = kbapi.BadRequestError(str(e)) elif isinstance(e, NoTokenError): e = kbapi.NotFoundError(str(e)) # Now determine the response based on the exception type. if isinstance(e, kbapi.Error): code = e.__class__.__name__ http_code = e.HTTP_CODE message = e.Message() else: code = "ServerError" http_code = 500 message = "An internal error occurred: %s" % str(e) result = {"error": {"code": code, "message": message}} if settings.DEBUG: result["error"]["traceback"] = "".join(traceback.format_exception(*exc_info)) return result, http_code
def create_tap(request): form = forms.TapCreateForm(request.POST) if form.is_valid(): return request.backend.create_tap(name=form.cleaned_data['name']) raise kbapi.BadRequestError(_form_errors(form))