def form_valid(self, form): post = form.save(commit=False) post.author = self.request.user tags = self.request.POST.get('tags') tags_list = tags.split(',') post.status = 'submitted' post.save() form.save_m2m() messages.success(self.request, 'Post Submitted and under review') if not self.request.user.username == 'admin': # remember to remove in production user = self.request.user else: user = User.objects.get(username='******') profile = Profile.objects.get(user=user) posting_key = profile.posting_key refresh_token = profile.refresh_token url = "https://v2.steemconnect.com/api/oauth2/token" response_access = requests.post(url, data={ 'refresh_token': refresh_token, 'client_id': 'sportherald.app', 'client_secret': settings.CLIENT_SECRET, 'scope': "vote,comment,offline" }) access_token = response_access.json().get('access_token') c = Client(access_token=access_token) comment = Comment(author=user.username, permlink=post.slug, body=post.body, title=post.title, parent_permlink="sportherald", json_metadata={ "app": "sportherlad.app", 'tags': tags_list }) c.broadcast([comment.to_operation_structure()]) #return JsonResponse({'status': 200, 'slug': post.slug, 'posting_key': posting_key, 'username': user.username}) return HttpResponseRedirect('/')
def create_post(): data_dict = json.loads(request.data) if 'user_id' not in data_dict: raise BadRequest('user_id is mandatory param') if 'title' not in data_dict: raise BadRequest('title is mandatory param') if 'body' not in data_dict: raise BadRequest('body is mandatory param') user_id = data_dict['user_id'] title = data_dict['title'] body = data_dict['body'] force_permlink = data_dict[ 'force_permlink'] if 'force_permlink' in data_dict else '' cover_image_url = data_dict.get('cover_image_url', '') user = User.query.filter_by(user_id=user_id).first() if not user: raise Unauthorized('Not authorized with steemconnect') client = Client(access_token=user.steem_token) permlink = force_permlink or title.lower().replace(' ', '-')\ .replace('_', '-')\ .replace(')', '-')\ .replace('(', '-')\ .encode('ascii', 'ignore') if not permlink or len(permlink) < 4: permlink = str(uuid4()) comment = Comment( user.user_id, permlink, "Make donations/tipping easy <a href=\"http://donatenow.io\">donatenow!</a>", title=title, json_metadata={ "app": app_name, "body": body, "cover_image_url": cover_image_url }) r = client.broadcast([comment.to_operation_structure()]) if 'error_description' in r and r['error_description']: raise BadRequest(r['error_description']) all_posts = get_all(user_id) post = all_posts['posts'][permlink] response = Response(json.dumps(post), mimetype='application/json') response.headers.add('Access-Control-Allow-Origin', '*') return response
def create_poll(request): if not request.user.is_authenticated: return redirect('login') error = False # @todo: create a form class for that. this is very ugly. if request.method == 'POST': if not 'sc_token' in request.session: return redirect("/") required_fields = ["question", "answers[]", "expire-at"] for field in required_fields: if not request.POST.get(field): error = True messages.add_message(request, messages.ERROR, f"{field} field is required.") question = request.POST.get("question") choices = request.POST.getlist("answers[]") expire_at = request.POST.get("expire-at") if question: if not (4 < len(question) < 256): messages.add_message( request, messages.ERROR, "Question text should be between 6-256 chars.") error = True if 'choices' in request.POST: if len(choices) < 2: messages.add_message(request, messages.ERROR, f"At least 2 choices are required.") error = True elif len(choices) > 20: messages.add_message(request, messages.ERROR, f"Maximum number of choices is 20.") error = True if 'expire-at' in request.POST: if expire_at not in ["1_week", "1_month"]: messages.add_message(request, messages.ERROR, f"Invalid expiration value.") error = True if error: return render(request, "add.html") days = 7 if expire_at == "1_week" else 30 # add the question permlink = slugify(question)[0:256] if not permlink: permlink = str(uuid.uuid4()) # @todo: also check for duplicates in the blockchain. # client.get_content() if (Question.objects.filter(permlink=permlink, username=request.user)).exists(): messages.add_message(request, messages.ERROR, "You have already a similar poll.") return redirect('create-poll') question = Question(text=question, username=request.user.username, description=request.POST.get("description"), permlink=permlink, expire_at=now() + timedelta(days=days)) question.save() # add answers attached to it for choice in choices: choice_instance = Choice( question=question, text=choice, ) choice_instance.save() # send it to the steem blockchain sc_client = Client(access_token=request.session.get("sc_token")) comment = Comment(author=request.user.username, permlink=question.permlink, body=get_body( question, choices, request.user.username, permlink, ), title=question.text, parent_permlink=settings.COMMUNITY_TAG, json_metadata={ "tags": settings.DEFAULT_TAGS, "app": f"dpoll/{settings.DPOLL_APP_VERSION}", "content_type": "poll", "question": question.text, "description": question.description or "", "choices": choices, "expire_at": str(question.expire_at), }) comment_options = get_comment_options(comment) resp = sc_client.broadcast([ comment.to_operation_structure(), comment_options.to_operation_structure(), ]) if 'error' in resp: if 'The token has invalid role' in resp.get("error_description"): # expired token auth_logout(request) return redirect('login') messages.add_message(request, messages.ERROR, resp.get("error_description", "error")) question.delete() return redirect('create-poll') return redirect('detail', question.username, question.permlink) return render(request, "add.html")
def vote(request, user, permlink): if request.method != "POST": raise Http404 # django admin users should not be able to vote. if not request.session.get("sc_token"): redirect('logout') try: poll = Question.objects.get(username=user, permlink=permlink) except Question.DoesNotExist: raise Http404 if not request.user.is_authenticated: return redirect('login') choice_id = request.POST.get("choice-id") additional_thoughts = request.POST.get("vote-comment", "") if not choice_id: raise Http404 if Choice.objects.filter(voted_users__username=request.user, question=poll).exists(): messages.add_message(request, messages.ERROR, "You have already voted for this poll!") return redirect("detail", poll.username, poll.permlink) if not poll.is_votable(): messages.add_message(request, messages.ERROR, "This poll is expired!") return redirect("detail", poll.username, poll.permlink) try: choice = Choice.objects.get(pk=int(choice_id)) except Choice.DoesNotExist: raise Http404 choice.voted_users.add(request.user) # send it to the steem blockchain sc_client = Client(access_token=request.session.get("sc_token")) choice_text = choice.text.strip() body = f"Voted for *{choice_text}*." if additional_thoughts: body += f"\n\n{additional_thoughts}" comment = Comment(author=request.user.username, permlink=str(uuid.uuid4()), body=body, parent_author=poll.username, parent_permlink=poll.permlink, json_metadata={ "tags": settings.DEFAULT_TAGS, "app": f"dpoll/{settings.DPOLL_APP_VERSION}", "content_type": "poll_vote", "vote": choice.text }) comment_options = get_comment_options(comment) resp = sc_client.broadcast([ comment.to_operation_structure(), comment_options.to_operation_structure(), ]) if 'error' in resp: messages.add_message(request, messages.ERROR, resp.get("error_description", "error")) choice.voted_users.remove(request.user) return redirect("detail", poll.username, poll.permlink) messages.add_message(request, messages.SUCCESS, "You have successfully voted!") return redirect("detail", poll.username, poll.permlink)
def vote(request, user, permlink): if request.method != "POST": raise Http404 # django admin users should not be able to vote. if not request.session.get("sc_token"): redirect('logout') try: poll = Question.objects.get(username=user, permlink=permlink) except Question.DoesNotExist: raise Http404 if not request.user.is_authenticated: return redirect('login') if poll.allow_multiple_choices: choice_ids = request.POST.getlist("choice-id") else: choice_ids = [ request.POST.get("choice-id"), ] # remove noise choice_ids = [x for x in choice_ids if x is not None] additional_thoughts = request.POST.get("vote-comment", "") if not len(choice_ids): messages.add_message(request, messages.ERROR, "You need to pick a choice to vote.") return redirect("detail", poll.username, poll.permlink) if Choice.objects.filter(voted_users__username=request.user, question=poll).exists(): messages.add_message(request, messages.ERROR, "You have already voted for this poll!") return redirect("detail", poll.username, poll.permlink) if not poll.is_votable(): messages.add_message(request, messages.ERROR, "This poll is expired!") return redirect("detail", poll.username, poll.permlink) for choice_id in choice_ids: try: choice = Choice.objects.get(pk=int(choice_id)) except Choice.DoesNotExist: raise Http404 choice_instances = [] for choice_id in choice_ids: choice = Choice.objects.get(pk=int(choice_id)) choice_instances.append(choice) # send it to the steem blockchain sc_client = Client(access_token=request.session.get("sc_token")) choice_text = "" for c in choice_instances: choice_text += f" - {c.text.strip()}\n" body = f"Voted for \n {choice_text}" if additional_thoughts: body += f"\n\n{additional_thoughts}" comment = Comment(author=request.user.username, permlink=str(uuid.uuid4()), body=body, parent_author=poll.username, parent_permlink=poll.permlink, json_metadata={ "tags": settings.DEFAULT_TAGS, "app": f"dpoll/{settings.DPOLL_APP_VERSION}", "content_type": "poll_vote", "votes": [c.text.strip() for c in choice_instances], }) comment_options = get_comment_options(comment) if not settings.BROADCAST_TO_BLOCKCHAIN: resp = {} else: resp = sc_client.broadcast([ comment.to_operation_structure(), comment_options.to_operation_structure(), ]) # Steemconnect sometimes returns 503. # https://github.com/steemscript/steemconnect/issues/356 if not isinstance(resp, dict): messages.add_message( request, messages.ERROR, "We got an unexpected error from Steemconnect. Please, try again.") return redirect("detail", poll.username, poll.permlink) # Expected way to receive errors on broadcasting if 'error' in resp: messages.add_message(request, messages.ERROR, resp.get("error_description", "error")) return redirect("detail", poll.username, poll.permlink) # register the vote to the database for choice_instance in choice_instances: choice_instance.voted_users.add(request.user) block_id = resp.get("result", {}).get("block_num") trx_id = resp.get("result", {}).get("id") # add trx id and block id to the audit log vote_audit = VoteAudit(question=poll, voter=request.user, block_id=block_id, trx_id=trx_id) vote_audit.save() for choice_instance in choice_instances: vote_audit.choices.add(choice_instance) messages.add_message(request, messages.SUCCESS, "You have successfully voted!") return redirect("detail", poll.username, poll.permlink)
def edit_poll(request, author, permlink): if not request.user.is_authenticated: return redirect('login') try: poll = Question.objects.get( permlink=permlink, username=author, ) except Question.DoesNotExist: raise Http404 if author != request.user.username: raise Http404 if request.method == "GET": poll_data = fetch_poll_data(poll.username, poll.permlink) tags = poll_data.get("tags", []) tags = [tag for tag in tags if tag not in settings.DEFAULT_TAGS] form_data = { "question": poll.text, "description": poll.description, "answers": [c.text for c in Choice.objects.filter(question=poll)], "expire_at": poll.expire_at_humanized, "tags": ",".join(tags), "allow_multiple_choices": poll.allow_multiple_choices } if request.method == 'POST': form_data = copy.copy(request.POST) if 'sc_token' not in request.session: return redirect("/") error, question, choices, expire_at, _, days, tags, \ allow_multiple_choices = validate_input(request) if tags: tags = settings.DEFAULT_TAGS + tags else: tags = settings.DEFAULT_TAGS permlink = poll.permlink if error: form_data.update({ "answers": request.POST.getlist("answers[]"), "expire_at": request.POST.get("expire-at"), "allow_multiple_choices": request.POST.get("allow-multiple-choices"), }) return render(request, "edit.html", {"form_data": form_data}) # add question question = add_or_get_question(request, question, permlink, days, allow_multiple_choices) question.save() # add answers attached to it add_choices(question, choices, flush=True) # send it to the steem blockchain sc_client = Client(access_token=request.session.get("sc_token")) comment = get_comment(request, question, choices, permlink, tags=tags) if not settings.BROADCAST_TO_BLOCKCHAIN: resp = {} else: resp = sc_client.broadcast([ comment.to_operation_structure(), ]) if 'error' in resp: if 'The token has invalid role' in resp.get("error_description"): # expired token auth_logout(request) return redirect('login') messages.add_message(request, messages.ERROR, resp.get("error_description", "error")) question.delete() return redirect('edit', args=(author, permlink)) return redirect('detail', question.username, question.permlink) return render(request, "edit.html", { "form_data": form_data, })
def create_poll(request): if not request.user.is_authenticated: return redirect('login') if request.method == 'POST': form_data = copy.copy(request.POST) if 'sc_token' not in request.session: return redirect("/") error, question, choices, expire_at, permlink, days, tags, \ allow_multiple_choices = validate_input(request) if error: form_data.update({ "answers": request.POST.getlist("answers[]"), "expire_at": request.POST.get("expire-at"), "reward_option": request.POST.get("reward-option"), "allow_multiple_choices": request.POST.get("allow-multiple-choices"), }) return render(request, "add.html", {"form_data": form_data}) if (Question.objects.filter(permlink=permlink, username=request.user)).exists(): messages.add_message(request, messages.ERROR, "You have already a similar poll.") return redirect('create-poll') # add question question = add_or_get_question(request, question, permlink, days, allow_multiple_choices) question.save() # add answers attached to it add_choices(question, choices) # send it to the steem blockchain sc_client = Client(access_token=request.session.get("sc_token")) comment = get_comment(request, question, choices, permlink, tags) comment_options = get_comment_options( comment, reward_option=request.POST.get("reward-option")) if not settings.BROADCAST_TO_BLOCKCHAIN: resp = {} else: resp = sc_client.broadcast([ comment.to_operation_structure(), comment_options.to_operation_structure(), ]) if 'error' in resp: if 'The token has invalid role' in resp.get("error_description"): # expired token auth_logout(request) return redirect('login') messages.add_message(request, messages.ERROR, resp.get("error_description", "error")) question.delete() return redirect('create-poll') return redirect('detail', question.username, question.permlink) return render(request, "add.html")
def vote(self, voter, author, permlink, weight): db = database.Database() result = db.get_user_auth(voter) access_token, refresh_token, expire_on = result[0] dt = datetime.now() c = Client( client_id=CLIENT_ID, client_secret=CLIENT_SECRET, access_token=access_token, ) try: # Verify access_token if dt > expire_on: result = c.refresh_access_token( refresh_token, "login,vote" # scopes ) access_token = result['access_token'] refresh_token = result['refresh_token'] expires_in = result['expires_in'] # Update access token in the DB self.db.update_authentication_tokens( voter, access_token, refresh_token, expires_in, self.timestamp, ) print('Updated access token\n') # Perform vote vote = Vote(voter, author, permlink, weight) result = c.broadcast([vote.to_operation_structure()]) # Log vote if 'error' in result: message = result['error_description'] db.add_to_error_log( voter, author, permlink, weight, message, self.timestamp, ) else: message = 'Succes' print(f"Voter: {voter}\nAuthor: {author}\n" + f"Permlink: {permlink}\nWeight: {weight}\n" + "Upvote succes\n") except Exception as error: db.add_to_error_log( voter, author, permlink, weight, error, self.timestamp, )
def vote(self, voter, author, permlink, weight, type): result = self.db.get_user_auth(voter) access_token, refresh_token, expire_on = result[0] dt = datetime.now() c = Client( client_id=CLIENT_ID, client_secret=CLIENT_SECRET, access_token=access_token, ) try: # Verify access_token if dt > expire_on: access_token = self.refresh_token(refresh_token) result = c.refresh_access_token( refresh_token, "login,vote" # scopes ) access_token = result['access_token'] refresh_token = result['refresh_token'] expires_in = result['expires_in'] self.db.update_authentication_tokens( voter, access_token, refresh_token, expires_in, self.timestamp, ) print('Updated access token\n') # Perform vote if not self.is_already_voted(voter, author, permlink): vote = Vote(voter, author, permlink, weight) result = c.broadcast([vote.to_operation_structure()]) # Log vote if 'error' in result: message = result['error_description'] self.db.add_to_error_log( voter, author, permlink, weight, type, message, self.timestamp, ) else: message = 'Succes' if type == 'vote': self.db.update_log( voter, permlink, message, 'vote_log', ) elif type == 'trail': self.db.update_log( voter, permlink, message, 'trail_log', ) print(f"Voter: {voter}\nAuthor: {author}\n" + f"Permlink: {permlink}\nWeight: {weight}\n" + "Upvote succes\n") except Exception as error: print(voter, author, permlink, weight, error) self.db.add_to_error_log( voter, author, permlink, weight, type, error, self.timestamp, )