Exemple #1
0
    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('/')
Exemple #2
0
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
Exemple #3
0
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")
Exemple #4
0
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)
Exemple #5
0
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)
Exemple #6
0
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,
    })
Exemple #7
0
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,
        )
Exemple #9
0
    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,
            )