示例#1
0
    def authenticate(self, **kwargs):
        if 'username' in kwargs:
            return None

        # validate the access token with /me endpoint and get user information
        client = Client(access_token=kwargs.get("access_token"))

        user = client.me()
        if 'name' not in user:
            return None

        user_model = get_user_model()
        metadata = {}
        profile_about, profile_image, profile_location = None, None, None
        if 'json_metadata' in user["account"]:
            metadata = json.loads(user["account"]["json_metadata"])
            profile = metadata.get("profile", {})
            profile_about = profile.get("about")
            profile_image = profile.get("profile_image")
            profile_location = profile.get("location")

        try:
            user = user_model.objects.get(username=user["name"])
        except user_model.DoesNotExist:
            user = user_model.objects.create_user(username=user["name"],
                                                  name=user["name"])
        user.profile_about = profile_about
        user.profile_image = profile_image
        user.profile_location = profile_location
        user.save()

        return user
示例#2
0
    def test_get_login_url(self):
        c = Client("client_id" "client_secret")

        self.assertEqual(
            c.get_login_url("http://localhost", "login"),
            "https://v2.steemconnect.com/oauth2/authorize?client_id"
            "=client_idclient_secret&redirect_uri=http%3A%2F%2Flocalh"
            "ost&scope=login")
示例#3
0
    def test_get_login_url_override_defaults(self):
        c = Client(oauth_base_url="http://foo.bar/oauth2/",
                   client_id="client_id",
                   client_secret="client_secret")

        self.assertEqual(
            c.get_login_url("http://localhost", "login"),
            "http://foo.bar/oauth2/authorize?client_id=client_id&"
            "redirect_uri=http%3A%2F%2Flocalhost&scope=login")
示例#4
0
def login():
    sc_client = ScClient(client_id=SC_CLIENT_ID,
                         client_secret=SC_SECRET,
                         oauth_base_url="https://hivesigner.com/oauth2/",
                         sc2_api_base_url="https://hivesigner.com/api/")
    login_url = sc_client.get_login_url(
        f"{SITE_URL}/gift-codes",
        "login",
    )
    return render_template("login.html", login_url=login_url)
示例#5
0
def login():
    c = Client(
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET,
    )
    auth_url = c.get_login_url(
        "http://127.0.0.1:5000/complete/steemconnect/",
        "login,vote,comment,custom_json",
    )
    return redirect(auth_url)
示例#6
0
 def steemconnect(self, accesstoken=None):
     if self.sc:
         return self.sc
     if accesstoken:
         self.accesstoken = accesstoken
     if self.accesstoken:
         self.sc = Client(access_token=self.accesstoken)
     else:
         self.sc = Client(client_id=self.client_id,
                          client_secret=self.client_secret)
     return self.sc
示例#7
0
  def wrapper (self, *args, **kwargs) :
    username = ''
    access_token = ''
    request = self.request
    if request.method == 'GET' or request.method == 'DELETE':
      if 'username' in request.GET :
        username = request.GET['username']
      if 'access_token' in request.GET :
        access_token = request.GET['access_token']
    else :
      if 'username' in request.data :
        username = request.data['username']
      if 'access_token' in request.data :
        access_token = request.data['access_token']

    if username == '' or access_token == '' :
      raise PermissionDenied

    token = AccessToken.objects.filter(username = username)

    if len(token) == 0 or token[0].token != sha512(access_token) :
      # Validate access token with Steemconnect
      c = Client(access_token = access_token)

      try: 
        user = c.me()
      except:
        return HttpResponse(status=503)

      if user['user'] != username :
        # Wrong username / access_token pair
        raise PermissionDenied

      if len(token) == 0 :
        token = AccessToken(username = username,
                            token = sha512(access_token))
        token.save()
      else :
        # Access token was updated
        token.update(token = sha512(access_token))

    # User is valid, do we need to create a new SteemUser object?
    users = SteemUser.objects.filter(username = username)
    if len(users) == 0 :
      user = SteemUser(username = username)
      user.save()
    else :
      user = users[0]

    kwargs['user'] = user

    return func(self, *args, **kwargs)
示例#8
0
    def test_hot_sign(self):
        c = Client()

        sign_url = c.hot_sign("transfer", {
            "to": "turbot",
            "amount": "0.001 SBD",
            "memo": "selam",
        },
                              redirect_uri="http://localhost")

        self.assertEqual(
            sign_url, "https://v2.steemconnect.com/sign/tra"
            "nsfer?to=turbot&amount=0.001+SBD&me"
            "mo=selam&redirect_uri=http%3A%2F%2F"
            "localhost")
示例#9
0
    def test_me(self):
        def request_callback(request):
            self.assertEqual(request.url,
                             "https://v2.steemconnect.com/api/me/")

            return 200, {}, json.dumps({"access_token": "foo"})

        c = Client(access_token="foo")
        responses.add_callback(
            responses.POST,
            'https://v2.steemconnect.com/api/me/',
            callback=request_callback,
        )

        c.me()
示例#10
0
 def update_access_token(self, secret):
     "This function should be used if access_token expires."
     tokens = Client.get_refresh_token(code=self.code, app_secret=secret)
     access_token = tokens["access_token"]
     SteemConnectUser.objects.filter(user=self.user).update(
         access_token=access_token)
     return access_token
示例#11
0
    def test_hot_sign_without_redirect_uri(self):
        c = Client()

        sign_url = c.hot_sign(
            "transfer",
            {
                "to": "turbot",
                "amount": "0.001 SBD",
                "memo": "selam",
            },
        )

        self.assertEqual(
            sign_url, "https://v2.steemconnect.com/sign/tra"
            "nsfer?to=turbot&amount=0.001+SBD&me"
            "mo=selam")
示例#12
0
 def steemconnect(self, accesstoken=None):
     ''' Initializes the SteemConnect Client
     class
     '''
     if self.sc is not None:
         return self.sc
     if accesstoken is not None:
         self.accesstoken = accesstoken
     if self.accesstoken is None:
         self.sc = Client(client_id=self.client_id,
                          client_secret=self.client_secret)
     else:
         self.sc = Client(access_token=self.accesstoken,
                          client_id=self.client_id,
                          client_secret=self.client_secret)
     return self.sc
示例#13
0
def get_sc_client():
    global _sc_client
    if not _sc_client:
        _sc_client = Client(client_id=settings.SC_CLIENT_ID,
                            client_secret=settings.SC_CLIENT_SECRET)

    return _sc_client
示例#14
0
class LoginSignup(View):
    client = Client(client_id=settings.CLIENT_ID,
                    redirect_url=settings.REDIRECT_URL,
                    code=settings.CODE,
                    scope=settings.SCOPE)

    def get(self, request, *args, **kwargs):
        code = request.GET["code"]
        tokens = self.client.get_refresh_token(code, settings.APP_SECRET)
        username = tokens["username"]
        access_token = tokens["access_token"]
        refresh_token = tokens["refresh_token"]
        user, created = User.objects.get_or_create(username=username)
        if SteemConnectUser.objects.filter(user=user).exists():
            SteemConnectUser.objects.filter(user=user).update(
                code=code,
                access_token=access_token,
                refresh_token=refresh_token)
        else:
            SteemConnectUser(user=user,
                             code=code,
                             access_token=access_token,
                             refresh_token=refresh_token).save()
        login(request,
              user,
              backend="django.contrib.auth.backends.ModelBackend")
        return HttpResponseRedirect(settings.LOGIN_REDIRECT)
示例#15
0
def gift_codes():
    sc_client = ScClient(access_token=request.args.get("access_token"),
                         oauth_base_url="https://hivesigner.com/oauth2/",
                         sc2_api_base_url="https://hivesigner.com/api/")
    me = sc_client.me()
    if 'error' in me:
        return "Invalid access token"

    # if the user already claimed their gift codes,
    # then there is no need to create new gift codes
    if g.infestor.gift_code_manager.get_gift_code_count_by_user(
            me["account"]["name"]) > 0:
        gift_codes = g.infestor.gift_code_manager.get_gift_codes_by_user(
            me["account"]["name"])
        return render_template("gift_codes.html",
                               user=me,
                               gift_codes=gift_codes)

    # quick hack
    # no need to fill all account data into Lighthive.helpers.Account
    # since all we're interested in is reputation figure.
    acc = Account(client=g.lightsteem_client)
    acc.raw_data = {"reputation": me["account"]["reputation"]}

    gift_code_count = 0
    if acc.reputation() < g.minimum_rep:
        error = "Your reputation is not enough to claim a free account."
        return render_template("gift_codes.html", error=error)
    else:
        gift_code_count += 1
        # check if the account is eligible for the bonus
        if OPERATOR_WITNESS in me["account"]["witness_votes"]:
            gift_code_count += 1

    # create gift_codes based on the *gift_code_count*
    for i in range(gift_code_count):
        code = random.randint(1000000, 999999999)
        g.infestor.gift_code_manager.add_code(
            code, created_for=me["account"]["name"])
    gift_codes = g.infestor.gift_code_manager.get_gift_codes_by_user(
        me["account"]["name"])

    return render_template("gift_codes.html",
                           user=me,
                           gift_codes=gift_codes,
                           error=None)
示例#16
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
示例#17
0
    def test_refresh_access_token(self):
        def request_callback(request):
            self.assertEqual(request.url,
                             "https://v2.steemconnect.com/api/oauth2/token/")

            self.assertEqual(
                request.body,
                'refresh_token=refresh_token&client_id=client_id&'
                'client_secret=client_secret&scope=login')
            return 200, {}, json.dumps({"access_token": "foo"})

        c = Client(client_id="client_id", client_secret="client_secret")
        responses.add_callback(
            responses.POST,
            'https://v2.steemconnect.com/api/oauth2/token/',
            callback=request_callback,
        )

        c.refresh_access_token("refresh_token", "login")
示例#18
0
    def test_get_access_token(self):
        def request_callback(request):
            self.assertEqual(request.url,
                             "https://v2.steemconnect.com/api/oauth2/token/")

            self.assertEqual(
                request.body,
                'grant_type=authorization_code&code=code&client_id='
                'client_id&client_secret=client_secret')
            return 200, {}, json.dumps({"access_token": "foo"})

        c = Client(client_id="client_id", client_secret="client_secret")
        responses.add_callback(
            responses.POST,
            'https://v2.steemconnect.com/api/oauth2/token/',
            callback=request_callback,
        )

        c.get_access_token("code")
示例#19
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('/')
示例#20
0
def get_sc_client():
    global _sc_client
    if not _sc_client:
        _sc_client = Client(
            client_id=settings.SC_CLIENT_ID,
            client_secret=settings.SC_CLIENT_SECRET,
            oauth_base_url="https://hivesigner.com/oauth2/",
            sc2_api_base_url="https://hivesigner.com/api/",
        )

    return _sc_client
示例#21
0
    def authenticate(self, request, **kwargs):

        if 'username' in kwargs:
            return None

        # validate the access token with /me endpoint and get user information
        client = Client(access_token=kwargs.get("access_token"))

        user = client.me()
        if 'name' not in user:
            return None

        user_model = get_user_model()
        try:
            user_instance = user_model.objects.get(username=user["name"])
            user_instance.save()
        except user_model.DoesNotExist:
            user_instance = user_model.objects.create_user(
                username=user["name"])
        return user_instance
示例#22
0
from flask import Flask, request
from steemconnect.client import Client

app = Flask(__name__)

client_id = "your.app"
client_secret = "your_secret"

c = Client(client_id=client_id, client_secret=client_secret)


@app.route('/')
def index():
    login_url = c.get_login_url(
        "http://*****:*****@app.route('/welcome')
def welcome():
    c.access_token = request.args.get("access_token")
    return "Welcome <strong>%s</strong>!" % c.me()["name"]
示例#23
0
def get_client(request):
    community_model = request.community_model
    return Client(client_id=community_model.client_id,
                  redirect_url=community_model.redirect_url,
                  code=True,
                  scope=community_model.scope)
示例#24
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)
示例#25
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")
示例#26
0
def login_complete():
    token = request.args['access_token']
    c = Client(access_token=token, )
    user_info = c.me()
    create_or_update_user(user_info['name'], token)
    return redirect(FE_URL.format(user_info['name']))
示例#27
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")
示例#28
0
from steem.account import Account
from steem.amount import Amount
from steemconnect.client import Client
from steemconnect.operations import Follow, Unfollow, Mute, ClaimRewardBalance, Comment, CommentOptions, Vote
import requests, json, os, random, string

St_username = ""
Tag = ''
s = Steem()
c = Converter()
app = Flask(__name__)
assist = Assistant(app, route='/api', project_id=os.environ.get('project_id'))
app.config['INTEGRATIONS'] = ['ACTIONS_ON_GOOGLE']  # To enable Rich Messages
posts = s.get_discussions_by_trending({"limit": "8"
                                       })  # To cache the top 8 trending posts
sc = Client(client_id=os.environ.get('client_id'),
            client_secret=os.environ.get('client_secret'))


class Steemian:
    def __init__(self, St_username):
        self.username = St_username
        self.data = Account(self.username)
        self.reputation = str(self.data.rep)
        self.upvoteworth = self.calculate_voteworth()
        self.steempower = self.calculate_steempower(True)
        self.availablesp = self.calculate_steempower(
            False)  # To get the amount of Steempower that can be delegated
        self.wallet = self.data.balances
        self.accountworth = self.calculate_accountworth()
        self.steemprice = self.cmc_price(
            '1230')  # To get the price of Steem form coinmarketcap
示例#29
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)
示例#30
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,
    })