def add_favorite_user(request, user_id=None): """ 指定されたIDのユーザをログインユーザのフェイバリットに登録します。 指定IDのユーザを除くユーザだけが作成を行うことができます。(user!=request.user) JSONで返されるFavoriteUserインスタンスは以下の状態になっています。 user: ログインユーザ target: 指定されたIDのUserインスタンス @param user_id: ユーザID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (指定されたユーザがログインユーザの場合) @return: 404レスポンス (指定されたIDのユーザが存在しない場合) @return: 200レスポンス (成功。FavoriteUserインスタンスをJSONで出力) """ target = get_object_or_404(User, pk=user_id) user_is_active_or_404(target) if target == request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") if not FavoriteUser.objects.reach_limit(request.user): try: fav = FavoriteUser.objects.get(user=request.user, target=target) except: fav = FavoriteUser.objects.create(user=request.user, target=target) data = serializers.serialize("json", [fav]) return HttpResponse(data, mimetype="application/javascript") else: message = u"申し訳ありません。フェイバリットメンバーにできるのは%s人までです。" % FavoriteUser.objects.limit request.user.message_set.create(message=message) return render_to_response_of_class(HttpResponseForbidden, "403.html")
def register_direction(request, recipe_id=None): """ 指定されたIDのレシピに関する作り方データを新規作成します。 レシピを作成したユーザだけが作成を行うことができます。(recipe.user==request.user) @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (指定されたレシピの作成者がログインユーザではない場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 200レスポンス (成功。DirectionインスタンスをJSONで出力) """ recipe = get_object_or_404(Recipe, pk=recipe_id) if recipe.user != request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") form = forms.DirectionForm(request.POST, request.FILES) if not form.is_valid(): json = simplejson.dumps({"status":"error", "message":"form is not valid."}) direction = None else: direction = form.save(commit=False) recipe.add_direction(direction) direction.save() d = {"status":"success", "message":"", "direction":{"pk":direction.id, "fields":{"text":direction.text, "photo":direction.photo and direction.photo.url or ""}}} json = simplejson.dumps(d) if direction.photo: data = "<textarea>%s</textarea>" % json else: data = json return HttpResponse(data, mimetype="text/html")
def submit_recipe_to_contest(request, recipe_id): """ 指定されたIDのレシピをPOSTのcontestの値で指定されたお題に投稿します。 レシピの作成ユーザだけが行うことができます。 成功後のレシピは以下の状態になります。 contest: 指定されたIDのContestインスタンス @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 403レスポンス (ログインユーザが作成者ではない場合) @return: 403レスポンス (TODO: 指定のお題が存在しない場合) @return: 200レスポンス (レシピのJSONデータを返す。成功した場合) """ recipe = get_object_or_404(Recipe, pk=recipe_id) if request.user != recipe.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") contest_id = request.POST.get("contest", None) if contest_id: contest = Contest.objects.get(pk=contest_id) recipe.contest = contest recipe.save() json = serializers.serialize("json", [contest]) else: json = "" return HttpResponse(json, mimetype="application/json")
def sort_directions(request, recipe_id=None): """ 指定されたIDのレシピにひもづく作り方データを並べ替えます。 レシピを作成したユーザだけが行うことができます。(recipe.user==request.user) POSTのdirection[]の値リストに含まれる、作り方IDの順序通りになります。 @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 403レスポンス (指定されたレシピの作成者がログインユーザではない場合) @return: 200レスポンス (成功。DirectionインスタンスをJSONで出力) """ recipe = get_object_or_404(Recipe, pk=recipe_id) if recipe.user != request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") direction_ids = request.POST.getlist("direction[]") direction_dict = {} for direction in recipe.direction_set.all(): direction_dict[direction.id] = direction for i, direction_id in enumerate(direction_ids): direction = direction_dict[int(direction_id)] direction.number = i direction.save() json = simplejson.dumps(direction_ids) return HttpResponse(json, mimetype="application/json")
def edit_recipe(request, recipe_id=None): """ 指定されたIDのレシピデータの変更を行います。 レシピを作成したユーザだけが変更を行うことができます。(recipe.user==request.user) forms.RecipeFormで定義された値を受け取ります。 また、複数の素材データ(食材:foodパラメータのリストと分量:quantityパラメータのリスト)を JSON文字列にエンコードします。 素材データはrecipe.decode_ingredients()でタプル(食材名,分量)のリストに 復元することができます。 @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (指定されたレシピの作成者がログインユーザではない場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 302レスポンス (レシピ閲覧ページへ。成功した場合) """ recipe = get_object_or_404(Recipe, pk=recipe_id) if request.user != recipe.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") recipe.encode_ingredients(request.POST.getlist("food"), request.POST.getlist("quantity")) form = forms.RecipeForm(request.POST, request.FILES, instance=recipe) if form.is_valid(): recipe = form.save() request.user.message_set.create(message=u"レシピを保存しました。") return HttpResponseRedirect(reverse("recipes-show", kwargs={"recipe_id":recipe.id})) else: return render_edit_recipe_page(request, recipe, form)
def validate(request, key=None): """ ユーザをアクティベートします。 指定されたkeyを持つUserProfileインスタンスを検索し、そのuserインスタンスの is_activeをTrueに設定します。 UserProfileインスタンスのkey_issued_atが2日以上古い場合、403エラーを返します。 @context created_user: アクティベートされたユーザ @context profile: ユーザプロファイル @param key: バリデーションキー @return: 200レスポンス (成功。) @return: 403レスポンス (UserProfileインスタンスのkey_issued_atが2日以上古い場合) @return: 404レスポンス (該当のUserProfileインスタンスが存在しない場合) """ profile = get_object_or_404(UserProfile, validation_key=key) if not profile.validate(key): return render_to_response_of_class(HttpResponseForbidden, "403.html") profile.disable_validation_key() profile.save() user = profile.user user.is_active = True user.save() d = {"created_user":user, "profile":profile} return render_to_response("registration/new_success.html", d, RequestContext(request))
def show_recipe(request, recipe_id=None): """ 指定されたIDのレシピ詳細ページを出力します。 レシピがis_draft == Trueの場合、作成したユーザのみ見ることができます。 @param recipe_id: RecipeインスタンスのID @context recipe: Recipeインスタンス (recipe.id == recipe_id) @return: 403レスポンス (recipe.is_draft == True and request.user != recipe.user の場合) @return: 404レスポンス (指定されたIDのRecipeインスタンスが存在しない場合) @return: 404レスポンス (指定レシピの作成ユーザがis_active=Falseの場合 ただしレシピが商品化決定している場合を除く) @return: 200レスポンス (成功。詳細ページを表示) """ recipe = get_object_or_404(Recipe, pk=recipe_id) recipe_user = recipe.user if not recipe.is_awarded: user_is_active_or_404(recipe_user) if recipe.is_draft and request.user != recipe_user: return render_to_response_of_class(HttpResponseForbidden, "403.html") recipe.set_request_user(request.user) comment_form = None profile = recipe_user.get_profile() if not profile.deny_comment: comment_form = forms.CommentForm() submit_form = forms.SubmitToContestForm() d = {"recipe":recipe, "comment_form":comment_form, "submit_form":submit_form} return render_to_response("recipes/recipe.html", d, RequestContext(request))
def delete_direction(request, recipe_id=None, direction_id=None): """ 指定されたIDの作り方データを削除します。 レシピを作成したユーザだけが行うことができます。(recipe.user==request.user) @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 403レスポンス (指定されたレシピの作成者がログインユーザではない場合) @return: 403レスポンス (指定の作り方が指定のレシピにひもづいていない場合) @return: 200レスポンス (成功。DirectionインスタンスをJSONで出力) """ recipe = get_object_or_404(Recipe, pk=recipe_id) if recipe.user != request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") direction = get_object_or_404(Direction, pk=direction_id) if recipe != direction.recipe: return render_to_response_of_class(HttpResponseForbidden, "403.html") json = serializers.serialize("json", [direction]) direction.delete(); return HttpResponse(json, mimetype="application/json")
def show_recipe_for_print(request, recipe_id=None): """ 指定されたIDのレシピ詳細ページ(印刷向け)を出力します。 条件はshow_recipeと同じです。 """ recipe = get_object_or_404(Recipe, pk=recipe_id) if not recipe.is_awarded: user_is_active_or_404(recipe.user) if recipe.is_draft and request.user != recipe.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") recipe.set_request_user(request.user) d = {"recipe":recipe} return render_to_response("recipes/recipe_print.html", d, RequestContext(request))
def vote_to_recipe(request, recipe_id=None): """ 指定されたIDのレシピに投票します。 レシピ作成者ではないユーザだけが行うことができます。 @param recipe_id: レシピID @return: 403レスポンス (ログインユーザがレシピの作成者である場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合、または作成者がis_active=Falseの場合) @return: 200レスポンス (成功。VoteインスタンスをJSONで出力) """ recipe = get_object_or_404(Recipe, pk=recipe_id) user_is_active_or_404(recipe.user) if recipe.user == request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") vote = recipe.vote(request.user) recipe.save() data = serializers.serialize("json", [vote]) if vote else '{}' return HttpResponse(data, mimetype="application/json")
def approve_comment(request, comment_id): """ コメントを承認します。これにより他のユーザにコメントが見えるようになります。 承認できるのはコメント先のレシピを作成したユーザだけです。 @param comment_id: コメントID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (ログインユーザがレシピの作成者でない場合) @return: 404レスポンス (指定されたIDのコメントが存在しない場合) @return: 200レスポンス (成功。コメントのJSONデータを返す) """ comment = get_object_or_404(Comment, pk=comment_id) if request.user != comment.owner: return render_to_response_of_class(HttpResponseForbidden, "403.html") comment.approve() comment.save() json = serializers.serialize("json", [comment]) return HttpResponse(json, mimetype="application/json")
def comment_to_recipe(request, recipe_id=None): """ 指定されたIDのレシピにコメントします。 ログインユーザだけが行うことができます。 POSTする項目はCommentFormの定義に従います。 作成成功時、ログインユーザがレシピの作成者の場合は、is_moderatedはTrueになります。 それ以外の場合はFalseになり、レシピ閲覧画面に表示されません。 @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (指定レシピの作成者がprofile.deny_comment == Trueの場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合、または作成者がis_active=Falseの場合) @return: 200レスポンス (not form.is_valid()の場合、フォームを再表示) @return: 302レスポンス (成功。レシピ閲覧ページにリダイレクトする) """ recipe = get_object_or_404(Recipe, pk=recipe_id) recipe_user = recipe.user user_is_active_or_404(recipe_user) profile = recipe_user.get_profile() if profile.deny_comment: return render_to_response_of_class(HttpResponseForbidden, "403.html") form = forms.CommentForm(request.POST, request.FILES) if not form.is_valid(): message = u"コメント内容に問題があります。" request.user.message_set.create(message=message) d = {"recipe":recipe, "comment_form":form, "submit_form":forms.SubmitToContestForm()} return render_to_response("recipes/recipe.html", d, RequestContext(request)) comment = form.save(commit=False) comment.user = request.user comment.recipe = recipe comment.owner = recipe_user if recipe_user == request.user: comment.approve() message = u"コメントが登録されました。" else: message = u"コメントを受け付けました。%s さんが承認すると表示されます。" % recipe_user.first_name comment.save() request.user.message_set.create(message=message) return HttpResponseRedirect(reverse("recipes-show", kwargs={"recipe_id":recipe.id}))
def edit_recipe(request, recipe_id=None): """ 指定されたIDのレシピの編集画面を表示します。 レシピを作成したユーザだけが表示を行うことができます。(recipe.user==request.user) @param recipe_id: レシピID @context recipe: Recipeインスタンス @context directions: クエリセット。recipe.direction_set.all() @context form: RecipeFormインスタンス @context direction_form: DirectionFormインスタンス @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (指定されたレシピの作成者がログインユーザではない場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 200レスポンス (成功。フォームを表示) """ recipe = get_object_or_404(Recipe, pk=recipe_id) if request.user != recipe.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") form = forms.RecipeForm(instance=recipe, editing=True) return render_edit_recipe_page(request, recipe, form)
def comment_to_recipe(request, recipe_id=None): """ 指定されたIDのレシピにコメントします。 POSTする項目はCommentFormの定義に従います。 作成成功時、is_moderatedはTrueになります。 @param recipe_id: レシピID @return: 403レスポンス (指定レシピの作成者がprofile.deny_comment == Trueの場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合、または作成者がis_active=Falseの場合) @return: 200レスポンス (not form.is_valid()の場合、フォームを再表示) @return: 302レスポンス (成功。レシピ閲覧ページにリダイレクトする) """ recipe = get_object_or_404(Recipe, pk=recipe_id) recipe_user = recipe.user user_is_active_or_404(recipe_user) profile = recipe_user.get_profile() if profile.deny_comment: return render_to_response_of_class(HttpResponseForbidden, "403.html") form = forms.CommentForm(request.POST, request.FILES) if not form.is_valid(): message = u"内容に問題があります。" request.user.message_set.create(message=message) d = {"recipe":recipe, "comment_form":form, "submit_form":forms.SubmitToContestForm()} return render_to_response("recipes/recipe.html", d, RequestContext(request)) comment = form.save(commit=False) if request.user.is_authenticated(): comment.user = request.user comment.recipe = recipe comment.owner = recipe_user if recipe_user == request.user: comment.approve() message = u"写真が登録されました。" else: message = u"写真が登録されました。" comment.save() from django.contrib import messages messages.add_message(request, messages.INFO, message=message) return HttpResponseRedirect(reverse("recipes-show", kwargs={"recipe_id":recipe.id}))
def delete_comment(request, comment_id): """ コメントを削除します。 削除できるのはコメントしたユーザかコメント先のレシピを作成したユーザだけです。 @param comment_id: コメントID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 404レスポンス (指定されたIDのコメントが存在しない場合) @return: 403レスポンス (ログインユーザがレシピ、コメントの作成者でない場合) @return: 200レスポンス (成功。コメントのJSONデータが返ります) """ comment = get_object_or_404(Comment, pk=comment_id) if request.user not in (comment.owner, comment.user): return render_to_response_of_class(HttpResponseForbidden, "403.html") json = serializers.serialize("json", [comment]) if comment.is_moderated: recipe = comment.recipe recipe.delete_comment(comment) recipe.save() comment.delete() return HttpResponse(json, mimetype="application/json")
def toggle_recipe_open_state(request, recipe_id=None): """ 指定されたIDのレシピの公開状態を変更します。 レシピが下書き状態(is_draft==True)の場合、公開状態(is_draft==False)に変更します。 公開状態の場合、下書き状態に変更します。 レシピを作成したユーザだけが状態の変更を行うことができます。(recipe.user==request.user) @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (指定されたレシピの作成者がログインユーザではない場合 商品化が決定している場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 200レスポンス (JSONが返される。成功した場合) """ recipe = get_object_or_404(Recipe, pk=recipe_id) if request.user != recipe.user or recipe.is_awarded: return render_to_response_of_class(HttpResponseForbidden, "403.html") recipe.toggle_open_state() recipe.save() data = serializers.serialize("json", [recipe]) # TODO: 情報を削減 return HttpResponse(data, mimetype="application/json")
def delete_recipe(request, recipe_id=None): """ 指定されたIDのレシピを削除します。 レシピを作成したユーザだけが行うことができます。(recipe.user==request.user) @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (指定されたレシピの作成者がログインユーザではない場合 商品化が決定している場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 302レスポンス (POSTのredirect_pathの値、 またはsettings.LOGIN_REDIRECT_URLへ。成功した場合) """ redirect_path = request.POST.get("redirect_path", settings.LOGIN_REDIRECT_URL) recipe = get_object_or_404(Recipe, pk=recipe_id) if recipe.user != request.user or recipe.is_awarded: return render_to_response_of_class(HttpResponseForbidden, "403.html") message = u"%s を削除しました。" % recipe.name recipe.delete() request.user.message_set.create(message=message) return HttpResponseRedirect(redirect_path)
def submit_recipe(request, contest_id=None, recipe_id=None): """ 指定されたIDのお題に指定されたIDのレシピを投稿します。 投稿されたレシピは、recipe.contest = contestとなります。 レシピの作成者でなければ投稿を行うことはできません。 @param contest_id: ContestインスタンスのID @param recipe_id: RecipeインスタンスのID @return: 200レスポンス (成功。JSONを返す) @return: 302レスポンス (ログインしていない場合。ログインページへ) @return: 403レスポンス (request.user != recipe.user の場合) @return: 404レスポンス (指定されたIDのRecipe, Contestインスタンスが存在しない場合) """ contest = get_object_or_404(Contest, pk=contest_id) recipe = get_object_or_404(Recipe, pk=recipe_id) if recipe.user != request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") recipe.contest = contest recipe.save() data = serializers.serialize("json", [recipe]) return HttpResponse(data, mimetype="application/javascript")
def remove_favorite_user(request, user_id=None): """ 指定されたIDのユーザをログインユーザのフェイバリットから削除します。 該当のFavoriteUserインスタンスを作成したユーザだけが削除を行うことが出来ます。 成功した場合、削除されたFavoriteRecipeインスタンスがJSONで返ります。 @param user_id: ユーザID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (FavoriteUserインスタンスを作成していない場合) @return: 404レスポンス (指定されたIDのユーザをフェイバリットにしていない場合) @return: 200レスポンス (成功。FavoriteUserインスタンスをJSONで出力) """ target = get_object_or_404(User, pk=user_id) if target == request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") try: fav = FavoriteUser.objects.get(user=request.user, target=target) data = serializers.serialize("json", [fav]) fav.delete() except: raise Http404 return HttpResponse(data, mimetype="application/javascript")
def remove_favorite_recipe(request, recipe_id=None): """ 指定されたIDのレシピをログインユーザのフェイバリットから削除します。 該当のFavoriteRecipeインスタンスを作成したユーザだけが削除を行うことができます。 成功した場合、削除されたFavoriteRecipeインスタンスがJSONで返ります。 @param recipe_id: レシピID @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (ログインユーザがレシピの作成者である場合) @return: 403レスポンス (ログインユーザが該当のFavoriteRecipeインスタンスを作成していない場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合) @return: 200レスポンス (成功。FavoriteRecipeインスタンスをJSONで出力) """ recipe = get_object_or_404(Recipe, pk=recipe_id) if recipe.user == request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") try: fav = FavoriteRecipe.objects.get(user=request.user, recipe=recipe) data = serializers.serialize("json", [fav]) fav.delete() except: raise Http404 return HttpResponse(data, mimetype="application/json")
def validate_change_email(request, user_id=None, key=None): """ メールアドレス変更を行います。 @param user_id: 変更を行うユーザのID @param key: 変更のためのバリデーションキー @return: 403レスポンス (キーが正しくない場合) @return: 200レスポンス (成功) """ user = get_object_or_404(User, pk=user_id) profile = user.get_profile() if profile.validate(key): profile.disable_validation_key() profile.save() user.email = profile.pending_email user.username = forms.email_to_username(user.email) user.save() d = {"title":u"メールアドレスの変更完了", "text":u"メールアドレスの変更が完了しました。"} return render_to_response("base_message.html", d, RequestContext(request)) else: return render_to_response_of_class(HttpResponseForbidden, "403.html")
def add_favorite_recipe(request, recipe_id=None): """ 指定されたIDのレシピをログインユーザのフェイバリットに登録します。 レシピを作成したユーザを除くユーザだけが作成を行うことができます。(recipe.user!=request.user) JSONで返されるFavoriteRecipeインスタンスは以下の状態になっています。 user: ログインユーザ recipe: 指定されたIDのRecipeインスタンス @param recipe_id: レシピID @context favorite_recipe: 作成されたFavoriteRecipeインスタンス @return: 302レスポンス (ログインページへ。ログインしていない場合) @return: 403レスポンス (指定されたレシピの作成者がログインユーザの場合) @return: 404レスポンス (指定されたIDのレシピが存在しない場合、または作成者がis_active=Falseの場合) @return: 200レスポンス (成功。FavoriteRecipeインスタンスをJSONで出力) """ recipe = get_object_or_404(Recipe, pk=recipe_id) user_is_active_or_404(recipe.user) if recipe.user == request.user: return render_to_response_of_class(HttpResponseForbidden, "403.html") fav = recipe.favorite(request.user) data = serializers.serialize("json", [fav]) return HttpResponse(data, mimetype="application/json")