Example #1
0
    def create(self, serializer):
        # TODO Зарефатороить или вынести в отдельный модуль
        # методы создания постов и комментариев
        tx = self.request.data.get('tx')
        updater = BaseUpdater(self.request.data.get('blockchain'))

        rpc = Steem(updater.blockchain.wss)

        try:
            r = rpc.broadcast(tx)
        except RPCError as e:
            operation = tx['operations'][0][1]
            operation['body'] = operation['body'][:100]

            logger.warning('%s: %s' % (e, pprint.pformat(operation)))

            return Response(str(e), status.HTTP_400_BAD_REQUEST)

        operation = r['operations'][0][1]

        p = rpc.get_content({
            'permlink': operation['permlink'],
            'author': operation['author']
        })

        post = updater.upgrade_post(p)

        return Response(self.serializer_action_classes['list'](post).data)
Example #2
0
    def create(self, serializer):
        tx = self.request.data.get('tx')
        updater = BaseUpdater(self.request.data.get('blockchain'))

        rpc = Steem(updater.blockchain.wss)

        try:
            r = rpc.broadcast(tx)
        except RPCError as e:
            logger.warning('%s: %s' %
                           (e, pprint.pformat(tx['operations'][0][1])))
            return Response(str(e), status.HTTP_400_BAD_REQUEST)

        operation = r['operations'][0][1]

        comm = rpc.get_content({
            'permlink': operation['permlink'],
            'author': operation['author']
        })

        page = None

        author = updater.get_author(comm.parent_author)

        if Page.objects.filter(permlink=comm.parent_permlink).exists():
            # Если это коммект к посту
            page = Page.objects.get(author=author,
                                    permlink=comm.parent_permlink)
        else:
            parent_comm = Comment.objects.get(author=author,
                                              permlink=comm.parent_permlink)

        if page is not None:
            comment = updater.get_comment_ins(comm, page, parent=None)
        else:
            comment = updater.get_comment_ins(comm,
                                              parent_comm.page,
                                              parent=parent_comm)

        comment.save()

        return Response(self.serializer_class(comment).data)
                titleWithNoSlash = formattedTitle.group(1).replace("/","")
            except AttributeError:
                print ("No slashes in title")

            steemFormattedSlugDetectedPost = str(formattedTitleVar).replace('(', '').replace(')', '').replace("'",'').replace(",",'')
            #turn hyphens to spaces in title
            titleWithNoSpaces = titleWithNoSlash.replace("-"," ")
            #try:
                #print (titleWithNoSpaces)
                    #formattedTitle = preformattedTitle.group(1)
                    #print (html2text.html2text(str(formattedTitle)))
            #except IndexError:
            #    print ('')

            #get new post
            post = steem.get_content(str(preformattedTitle.group(1)))

            #strip new post content of annoying characters
            postFormattedStillHasMarkDown = (html2text.html2text(post["body"]))
            postFormatted = str(postFormattedStillHasMarkDown).replace("*","").replace("#","").replace("\\","").replace(">","").replace("_","").replace('"','').replace('&lt;','').replace('&gt;','').replace('html','').replace('<','')

            #Preprocessing content
            #capture links
            captureLinksString = ''
            captureLinks = re.search(r'\<?(https?:\/\/?\/[^/]+\W?\@?\S+\W?\S+\w)\>?',str(postFormatted))

            #filter out links
            precaptureContent = re.sub(r'\<?(https?:\/\/?\/[^/]+\W?\@?\S+\W?\S+\w)\>?','',str(postFormatted))
            captureContent = re.sub(r'\!|\[|\]|\(|\)','',str(precaptureContent))

Example #4
0
# storage.put_container('posts', headers={'X-Container-Read': '.r:*'})
# Page.objects.filter(position__isnull=False, position_text__isnull=False).update(has_point=True)
#from itertools import chain
#from apps.pages.models import Page

# Получить все теги
#for tag in set(t for t in chain.from_iterable([i.meta['tags'] for i in Page.objects.filter(meta__tags__isnull=False)])):
#    print(tag)

from piston.steem import Steem

s = Steem('wss://steemd.steemit.com')

p = s.get_content({'author': 'acro999', 'permlink': '1'})
print(p.export())

exit()
Example #5
0
for filename in files_to_translate:
    with open(os.path.join(proj_dir, filename)) as f:
        filecontent = f.read()
        content += file_summary.format(filename=filename,
                                       filecontent=filecontent)
        files.append((filename, filecontent))

post_body = body.format(content=content)

print(post_body)
p = steem.post(title=title,
               body=post_body,
               permlink=permlink,
               author=USER,
               category='test')
post_id = '@{user}/{permlink}'.format(user=USER, permlink=permlink)

c = steem.get_content(post_id)

line_counter = 0
for filename, filecontent in files:
    for line in filecontent.split('\n'):
        if line and line.strip():
            line_counter += 1
            comment = '{} - ```{}```'.format(line_counter, line)
            print(comment)
            print(c.reply(comment, author=USER))
            sleep(19)

print('end')
            except AttributeError:
                print("No slashes in title")

            steemFormattedSlugDetectedPost = str(formattedTitleVar).replace(
                '(', '').replace(')', '').replace("'", '').replace(",", '')
            #turn hyphens to spaces in title
            titleWithNoSpaces = titleWithNoSlash.replace("-", " ")
            #try:
            #print (titleWithNoSpaces)
            #formattedTitle = preformattedTitle.group(1)
            #print (html2text.html2text(str(formattedTitle)))
            #except IndexError:
            #    print ('')

            #get new post
            post = steem.get_content(str(preformattedTitle.group(1)))

            #strip new post content of annoying characters
            postFormattedStillHasMarkDown = (html2text.html2text(post["body"]))
            postFormatted = str(postFormattedStillHasMarkDown).replace(
                "*", "").replace("#", "").replace("\\", "").replace(
                    ">", "").replace("_", "").replace('"', '').replace(
                        '&lt;', '').replace('&gt;',
                                            '').replace('html',
                                                        '').replace('<', '')

            #Preprocessing content
            #capture links
            captureLinksString = ''
            captureLinks = re.search(
                r'\<?(https?:\/\/?\/[^/]+\W?\@?\S+\W?\S+\w)\>?',
Example #7
0
def main() :
    global args
    config = Configuration()

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="Command line tool to interact with the Steem network"
    )

    """
        Default settings for all tools
    """
    parser.add_argument(
        '--node',
        type=str,
        default=config["node"],
        help='Websocket URL for public Steem API (default: "wss://this.piston.rocks/")'
    )
    parser.add_argument(
        '--rpcuser',
        type=str,
        default=config["rpcuser"],
        help='Websocket user if authentication is required'
    )
    parser.add_argument(
        '--rpcpassword',
        type=str,
        default=config["rpcpassword"],
        help='Websocket password if authentication is required'
    )
    parser.add_argument(
        '--nobroadcast',
        action='store_true',
        help='Do not broadcast anything'
    )
    parser.add_argument(
        '--verbose', '-v',
        type=int,
        default=3,
        help='Verbosity'
    )
    subparsers = parser.add_subparsers(help='sub-command help')

    """
        Command "set"
    """
    setconfig = subparsers.add_parser('set', help='Set configuration')
    setconfig.add_argument(
        'key',
        type=str,
        choices=["default_author",
                 "default_voter",
                 "node",
                 "rpcuser",
                 "rpcpassword",
                 "default_vote_weight",
                 "list_sorting",
                 "categories_sorting",
                 "limit",
                 "post_category"],
        help='Configuration key'
    )
    setconfig.add_argument(
        'value',
        type=str,
        help='Configuration value'
    )
    setconfig.set_defaults(command="set")

    """
        Command "config"
    """
    configconfig = subparsers.add_parser('config', help='show local configuration')
    configconfig.set_defaults(command="config")

    """
        Command "addkey"
    """
    addkey = subparsers.add_parser('addkey', help='Add a new key to the wallet')
    addkey.add_argument(
        'wifkeys',
        nargs='*',
        type=str,
        help='the private key in wallet import format (wif)'
    )
    addkey.set_defaults(command="addkey")

    """
        Command "listkeys"
    """
    listkeys = subparsers.add_parser('listkeys', help='List available keys in your wallet')
    listkeys.set_defaults(command="listkeys")

    """
        Command "listaccounts"
    """
    listaccounts = subparsers.add_parser('listaccounts', help='List available accounts in your wallet')
    listaccounts.set_defaults(command="listaccounts")

    """
        Command "list"
    """
    parser_list = subparsers.add_parser('list', help='List posts on Steem')
    parser_list.set_defaults(command="list")
    parser_list.add_argument(
        '--start',
        type=str,
        help='Start list from this identifier (pagination)'
    )
    parser_list.add_argument(
        '--category',
        type=str,
        help='Only posts with in this category'
    )
    parser_list.add_argument(
        '--sort',
        type=str,
        default=config["list_sorting"],
        choices=["trending", "created", "active", "cashout", "payout", "votes", "children", "hot"],
        help='Sort posts'
    )
    parser_list.add_argument(
        '--limit',
        type=int,
        default=config["limit"],
        help='Limit posts by number'
    )

    """
        Command "categories"
    """
    parser_categories = subparsers.add_parser('categories', help='Show categories')
    parser_categories.set_defaults(command="categories")
    parser_categories.add_argument(
        '--sort',
        type=str,
        default=config["categories_sorting"],
        choices=["trending", "best", "active", "recent"],
        help='Sort categories'
    )
    parser_categories.add_argument(
        'category',
        nargs="?",
        type=str,
        help='Only categories used by this author'
    )
    parser_categories.add_argument(
        '--limit',
        type=int,
        default=config["limit"],
        help='Limit categories by number'
    )

    """
        Command "read"
    """
    parser_read = subparsers.add_parser('read', help='Read a post on Steem')
    parser_read.set_defaults(command="read")
    parser_read.add_argument(
        'post',
        type=str,
        help='@author/permlink-identifier of the post to read (e.g. @xeroc/python-steem-0-1)'
    )
    parser_read.add_argument(
        '--full',
        action='store_true',
        help='Show full header information (YAML formated)'
    )
    parser_read.add_argument(
        '--comments',
        action='store_true',
        help='Also show all comments'
    )
    parser_read.add_argument(
        '--parents',
        type=int,
        default=0,
        help='Show x parents for the reply'
    )
    parser_read.add_argument(
        '--format',
        type=str,
        default=config["format"],
        help='Format post',
        choices=["markdown", "raw"],
    )

    """
        Command "post"
    """
    parser_post = subparsers.add_parser('post', help='Post something new')
    parser_post.set_defaults(command="post")
    parser_post.add_argument(
        '--author',
        type=str,
        required=False,
        default=config["default_author"],
        help='Publish post as this user (requires to have the key installed in the wallet)'
    )
    parser_post.add_argument(
        '--permlink',
        type=str,
        required=False,
        help='The permlink (together with the author identifies the post uniquely)'
    )
    parser_post.add_argument(
        '--category',
        default=config["post_category"],
        type=str,
        help='Specify category'
    )
    parser_post.add_argument(
        '--title',
        type=str,
        required=False,
        help='Title of the post'
    )
    parser_post.add_argument(
        '--file',
        type=str,
        default=None,
        help='Filename to open. If not present, or "-", stdin will be used'
    )

    """
        Command "reply"
    """
    reply = subparsers.add_parser('reply', help='Reply to an existing post')
    reply.set_defaults(command="reply")
    reply.add_argument(
        'replyto',
        type=str,
        help='@author/permlink-identifier of the post to reply to (e.g. @xeroc/python-steem-0-1)'
    )
    reply.add_argument(
        '--author',
        type=str,
        required=False,
        default=config["default_author"],
        help='Publish post as this user (requires to have the key installed in the wallet)'
    )
    reply.add_argument(
        '--permlink',
        type=str,
        required=False,
        help='The permlink (together with the author identifies the post uniquely)'
    )
    reply.add_argument(
        '--title',
        type=str,
        required=False,
        help='Title of the post'
    )
    reply.add_argument(
        '--file',
        type=str,
        required=False,
        help='Send file as responds. If "-", read from stdin'
    )

    """
        Command "edit"
    """
    parser_edit = subparsers.add_parser('edit', help='Edit to an existing post')
    parser_edit.set_defaults(command="edit")
    parser_edit.add_argument(
        'post',
        type=str,
        help='@author/permlink-identifier of the post to edit to (e.g. @xeroc/python-steem-0-1)'
    )
    parser_edit.add_argument(
        '--author',
        type=str,
        required=False,
        default=config["default_author"],
        help='Post an edit as another author'
    )
    parser_edit.add_argument(
        '--file',
        type=str,
        required=False,
        help='Patch with content of this file'
    )
    parser_edit.add_argument(
        '--replace',
        action='store_true',
        help="Don't patch but replace original post (will make you lose votes)"
    )

    """
        Command "upvote"
    """
    parser_upvote = subparsers.add_parser('upvote', help='Upvote a post')
    parser_upvote.set_defaults(command="upvote")
    parser_upvote.add_argument(
        'post',
        type=str,
        help='@author/permlink-identifier of the post to upvote to (e.g. @xeroc/python-steem-0-1)'
    )
    parser_upvote.add_argument(
        '--voter',
        type=str,
        required=False,
        default=config["default_voter"],
        help='The voter account name'
    )
    parser_upvote.add_argument(
        '--weight',
        type=float,
        default=config["default_vote_weight"],
        required=False,
        help='Actual weight (from 0.1 to 100.0)'
    )

    """
        Command "downvote"
    """
    parser_downvote = subparsers.add_parser('downvote', help='Downvote a post')
    parser_downvote.set_defaults(command="downvote")
    parser_downvote.add_argument(
        '--voter',
        type=str,
        required=False,
        help='The voter account name'
    )
    parser_downvote.add_argument(
        'post',
        type=str,
        help='@author/permlink-identifier of the post to downvote to (e.g. @xeroc/python-steem-0-1)'
    )
    parser_downvote.add_argument(
        '--weight',
        type=float,
        default=config["default_vote_weight"],
        required=False,
        help='Actual weight (from 0.1 to 100.0)'
    )

    """
        Command "replies"
    """
    replies = subparsers.add_parser('replies', help='Show recent replies to your posts')
    replies.set_defaults(command="replies")
    replies.add_argument(
        '--author',
        type=str,
        required=False,
        default=config["default_author"],
        help='Show replies to this author'
    )
    replies.add_argument(
        '--limit',
        type=int,
        default=config["limit"],
        help='Limit posts by number'
    )

    """
        Command "transfer"
    """
    parser_transfer = subparsers.add_parser('transfer', help='Transfer STEEM')
    parser_transfer.set_defaults(command="transfer")
    parser_transfer.add_argument(
        'to',
        type=str,
        help='Recepient'
    )
    parser_transfer.add_argument(
        'amount',
        type=str,
        help='Amount to transfer including asset (e.g.: 100.000 STEEM)'
    )
    parser_transfer.add_argument(
        'memo',
        type=str,
        nargs="?",
        default="",
        help='Optional memo'
    )
    parser_transfer.add_argument(
        '--account',
        type=str,
        required=False,
        default=config["default_author"],
        help='Transfer from this account'
    )

    """
        Command "powerup"
    """
    parser_powerup = subparsers.add_parser('powerup', help='Power up (vest STEEM as STEEM POWER)')
    parser_powerup.set_defaults(command="powerup")
    parser_powerup.add_argument(
        'amount',
        type=str,
        help='Amount to powerup including asset (e.g.: 100.000 STEEM)'
    )
    parser_powerup.add_argument(
        '--account',
        type=str,
        required=False,
        default=config["default_author"],
        help='Powerup from this account'
    )
    parser_powerup.add_argument(
        '--to',
        type=str,
        required=False,
        default=config["default_author"],
        help='Powerup this account'
    )

    """
        Command "powerdown"
    """
    parser_powerdown = subparsers.add_parser('powerdown', help='Power down (start withdrawing STEEM from STEEM POWER)')
    parser_powerdown.set_defaults(command="powerdown")
    parser_powerdown.add_argument(
        'amount',
        type=str,
        help='Amount to powerdown including asset (e.g.: 100.000 VESTS)'
    )
    parser_powerdown.add_argument(
        '--account',
        type=str,
        required=False,
        default=config["default_author"],
        help='powerdown from this account'
    )

    """
        Command "balance"
    """
    parser_balance = subparsers.add_parser('balance', help='Power down (start withdrawing STEEM from STEEM POWER)')
    parser_balance.set_defaults(command="balance")
    parser_balance.add_argument(
        'account',
        type=str,
        nargs="*",
        default=config["default_author"],
        help='balance from this account'
    )

    """
        Parse Arguments
    """
    args = parser.parse_args()

    # Logging
    log = logging.getLogger("piston")
    verbosity = ["critical",
                 "error",
                 "warn",
                 "info",
                 "debug"][int(min(args.verbose, 4))]
    log.setLevel(getattr(logging, verbosity.upper()))
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch = logging.StreamHandler()
    ch.setLevel(getattr(logging, verbosity.upper()))
    ch.setFormatter(formatter)
    log.addHandler(ch)

    # GrapheneAPI logging
    if args.verbose > 4:
        verbosity = ["critical",
                     "error",
                     "warn",
                     "info",
                     "debug"][int(min((args.verbose - 4), 4))]
        gphlog = logging.getLogger("graphenebase")
        gphlog.setLevel(getattr(logging, verbosity.upper()))
        gphlog.addHandler(ch)
    if args.verbose > 8:
        verbosity = ["critical",
                     "error",
                     "warn",
                     "info",
                     "debug"][int(min((args.verbose - 8), 4))]
        gphlog = logging.getLogger("grapheneapi")
        gphlog.setLevel(getattr(logging, verbosity.upper()))
        gphlog.addHandler(ch)

    rpc_not_required = ["set", "config", ""]
    if args.command not in rpc_not_required and args.command:
        steem = Steem(
            args.node,
            args.rpcuser,
            args.rpcpassword,
            nobroadcast=args.nobroadcast
        )

    if args.command == "set":
        config[args.key] = args.value

    if args.command == "config":
        t = PrettyTable(["Key", "Value"])
        t.align = "l"
        for key in config.store:
            t.add_row([key, config[key]])
        print(t)

    elif args.command == "addkey":
        wallet = Wallet(steem.rpc)
        if len(args.wifkeys):
            for wifkey in args.wifkeys:
                pub = (wallet.addPrivateKey(wifkey))
                if pub:
                    print(pub)
        else:
            import getpass
            wifkey = ""
            while True:
                wifkey = getpass.getpass('Private Key (wif) [Enter to quit]:')
                if not wifkey:
                    break
                pub = (wallet.addPrivateKey(wifkey))
                if pub:
                    print(pub)

        name = wallet.getAccountFromPublicKey(pub)
        print("Setting new default user: %s" % name)
        print("You can change these settings with:")
        print("    piston set default_author x")
        print("    piston set default_voter x")
        config["default_author"] = name
        config["default_voter"] = name

    elif args.command == "listkeys":
        t = PrettyTable(["Available Key"])
        t.align = "l"
        for key in Wallet(steem.rpc).getPublicKeys():
            t.add_row([key])
        print(t)

    elif args.command == "listaccounts":
        t = PrettyTable(["Name", "Available Key"])
        t.align = "l"
        for account in Wallet(steem.rpc).getAccounts():
            t.add_row(account)
        print(t)

    elif args.command == "reply":
        from textwrap import indent
        parent = steem.get_content(args.replyto)
        if parent["id"] == "0.0.0":
            print("Can't find post %s" % args.replyto)
            return

        reply_message = indent(parent["body"], "> ")

        post = frontmatter.Post(reply_message, **{
            "title": args.title if args.title else "Re: " + parent["title"],
            "author": args.author if args.author else "required",
            "replyto": args.replyto,
        })

        meta, message = yaml_parse_file(args, initial_content=post)

        for required in ["author", "title"]:
            if (required not in meta or
                    not meta[required] or
                    meta[required] == "required"):
                print("'%s' required!" % required)
                # TODO, instead of terminating here, send the user back
                # to the EDITOR
                return

        pprint(steem.reply(
            meta["replyto"],
            message,
            title=meta["title"],
            author=args.author
        ))

    elif args.command == "post" or args.command == "yaml":
        post = frontmatter.Post("", **{
            "title": args.title if args.title else "required",
            "author": args.author if args.author else "required",
            "category": args.category if args.category else "required",
        })

        meta, body = yaml_parse_file(args, initial_content=post)

        if not body:
            print("Empty body! Not posting!")
            return

        for required in ["author", "title", "category"]:
            if (required not in meta or
                    not meta[required] or
                    meta[required] == "required"):
                print("'%s' required!" % required)
                # TODO, instead of terminating here, send the user back
                # to the EDITOR
                return

        pprint(steem.post(
            meta["title"],
            body,
            author=meta["author"],
            category=meta["category"]
        ))

    elif args.command == "edit":
        original_post = steem.get_content(args.post)

        edited_message = None
        if original_post["id"] == "0.0.0":
            print("Can't find post %s" % args.post)
            return

        post = frontmatter.Post(original_post["body"], **{
            "title": original_post["title"] + " (immutable)",
            "author": original_post["author"] + " (immutable)"
        })

        meta, edited_message = yaml_parse_file(args, initial_content=post)
        pprint(steem.edit(
            args.post,
            edited_message,
            replace=args.replace
        ))

    elif args.command == "upvote" or args.command == "downvote":
        if args.command == "downvote":
            weight = -float(args.weight)
        else:
            weight = +float(args.weight)
        if not args.voter:
            print("Not voter provided!")
            return
        pprint(steem.vote(
            args.post,
            weight,
            voter=args.voter
        ))

    elif args.command == "read":
        post_author, post_permlink = resolveIdentifier(args.post)

        if args.parents:
            # FIXME inconsistency, use @author/permlink instead!
            dump_recursive_parents(
                steem.rpc,
                post_author,
                post_permlink,
                args.parents,
                format=args.format
            )

        if not args.comments and not args.parents:
            post = steem.get_content(args.post)

            if post["id"] == "0.0.0":
                print("Can't find post %s" % args.post)
                return
            if args.format == "markdown":
                body = markdownify(post["body"])
            else:
                body = post["body"]

            if args.full:
                meta = post.copy()
                meta.pop("body", None)  # remove body from meta
                yaml = frontmatter.Post(body, **meta)
                print(frontmatter.dumps(yaml))
            else:
                print(body)

        if args.comments:
            dump_recursive_comments(
                steem.rpc,
                post_author,
                post_permlink,
                format=args.format
            )

    elif args.command == "categories":
        categories = steem.get_categories(
            args.sort,
            begin=args.category,
            limit=args.limit
        )
        t = PrettyTable(["name", "discussions", "payouts"])
        t.align = "l"
        for category in categories:
            t.add_row([
                category["name"],
                category["discussions"],
                category["total_payouts"],
            ])
        print(t)

    elif args.command == "list":
        list_posts(
            steem.get_posts(
                limit=args.limit,
                sort=args.sort,
                category=args.category,
                start=args.start
            )
        )

    elif args.command == "replies":
        discussions = steem.get_replies(args.author)
        list_posts(discussions[0:args.limit])

    elif args.command == "transfer":
        pprint(steem.transfer(
            args.to,
            args.amount,
            memo=args.memo,
            account=args.account
        ))

    elif args.command == "powerup":
        pprint(steem.transfer_to_vesting(
            args.amount,
            account=args.account,
            to=args.to
        ))

    elif args.command == "powerdown":
        pprint(steem.withdraw_vesting(
            args.amount,
            account=args.account,
        ))

    elif args.command == "balance":
        t = PrettyTable(["Account", "STEEM", "SBD", "VESTS"])
        t.align = "r"
        if isinstance(args.account, str):
            args.account = [args.account]
        for a in args.account:
            b = steem.get_balances(a)
            t.add_row([
                a,
                b["balance"],
                b["sbd_balance"],
                b["vesting_shares"],
            ])
        print(t)

    else:
        print("No valid command given")
Example #8
0
]

content = ''
files = []

for filename in files_to_translate:
    with open(os.path.join(proj_dir, filename)) as f:
        filecontent = f.read()
        content += file_summary.format(filename=filename, filecontent=filecontent)
        files.append((filename, filecontent))

post_body = body.format(content=content)

print(post_body)
p = steem.post(title=title, body=post_body, permlink=permlink, author=USER, category='test')
post_id = '@{user}/{permlink}'.format(user=USER, permlink=permlink)

c = steem.get_content(post_id)

line_counter = 0
for filename, filecontent in files:
    for line in filecontent.split('\n'):
        if line and line.strip():
            line_counter += 1
            comment = '{} - ```{}```'.format(line_counter, line)
            print(comment)
            print(c.reply(comment, author=USER))
            sleep(19)

print('end')
Example #9
0
File: sync.py Project: avral/mapala
class BaseUpdater:
    """ Class for update objects in Mpala database """
    def __init__(self, db_connect=False):
        self.blockchain = BlockChain.current()
        self.db = BlockChainDB() if db_connect else None
        self.rpc = Steem(self.blockchain.wss)

    def comment(self, comment):
        """ Update or create comment """
        post = Post(comment, steem_instance=self.rpc)

        try:
            if post.is_comment():
                self.upgrade_comment(post)
            else:
                if post.parent_permlink == APP_FETCH_FROM:
                    self.upgrade_post(post)

        except PostDoesNotExist:
            pass
        except BannedAccount:
            logger.warning('banned account %s' % post.author)

    def vote(self, vote):
        if (Page.on_bc.filter(permlink=vote['permlink']).exists()
                and UserBlockChain.on_bc.filter(username=vote['author'])):
            # Обновляем каждый пост по которому кто то голосует
            self.update_post(vote['author'], vote['permlink'])

        if vote['voter'] in CURATORS:
            # В одном потоке работает паравозик
            locomotive_upvote(vote)

    def upgrade_comment(self, comm):
        author = self.get_author(comm.parent_author)
        page = None

        if Page.objects.filter(permlink=comm.parent_permlink,
                               author=author).exists():
            page = Page.objects.get(
                permlink=comm.parent_permlink,
                author=author,
            )
        else:
            parent_comm = Comment.objects.filter(
                permlink=comm.parent_permlink,
                author=author,
            ).first()

        if page is not None:
            comment = self.get_comment_ins(comm, page, parent=None)
        else:
            if parent_comm is None:
                return None

            comment = self.get_comment_ins(comm,
                                           parent_comm.page,
                                           parent=parent_comm)

        comment.save()

    def aware(self, date):
        return timezone.make_aware(date, timezone.get_current_timezone())

    def fetch(self, last_update=None):
        self.posts, self.count = self.db.get_posts_with_comments(last_update)

        return self.count

    def fetch_post(self, permlink):
        self.posts = self.db.get_post_by_permlink(permlink)

    def update_post(self, author, permlink):
        """ Обновляет пост по автору и пермлинку """
        post = self.rpc.get_content({'permlink': permlink, 'author': author})

        return self.upgrade_post(post)

    def upgrade_post(self, p):
        """ Обновляет пост в соответствии с принимаемым Post() """
        payout = float(p.total_payout_value)
        pending_payout = float(p.total_pending_payout_value)

        author = self.get_author(p.author)

        post = {
            'permlink': p.permlink,
            'author': self.get_author(p.author),
            'defaults': {
                'title': p.title,
                'updated_at': self.aware(p.last_update),
                'created_at': self.aware(p.created),
                'author': author,
                'permlink': p.permlink,
                'body': p.body,
                'meta': p.meta,
                'total_payout_value': payout,
                'total_pending_payout_value': pending_payout,
                'blockchain': self.blockchain,
            }
        }

        if coord_exists(p.meta):
            position_text, lat, lng = get_position(p.meta)

            post['defaults']['position_text'] = position_text
            post['defaults']['position'] = Point(lng, lat)
            post['defaults']['has_point'] = True
        else:
            post['defaults']['has_point'] = False

        post, created = Page.objects.update_or_create(**post)

        if created:
            logger.info('Created post in {}: {}/{}'.format(
                post.blockchain, post.author, post.permlink))

        return post

    def upgrade_comments(self, post_ins, items):
        def make_tree(ins):
            nodes = [
                self.get_comment_ins(i, post_ins, parent=ins) for i in items
                if i.parent_permlink == ins.permlink
            ]

            return [make_tree(ins) for ins in nodes]

        post_permlink = post_ins.permlink

        root_ns = [n for n in items if n.parent_permlink == post_permlink]

        for root in root_ns:
            make_tree(self.get_comment_ins(root, post_ins, parent=None))

    def upgrade(self):
        created_posts = []
        i = 0
        for items in self.posts:
            try:
                # В каждой итерации запрос к базе
                post_data = next(p for p in items
                                 if p.parent_permlink == APP_FETCH_FROM)
                try:
                    post_ins = self.upgrade_post(post_data)
                    created_posts.append(post_ins)
                except:
                    logging.exception('Ошибка апгрейда поста',
                                      post_data.permlink)

                    continue

                try:
                    self.upgrade_comments(post_ins, items)
                except:
                    logging.exception('Ошибка загрузки комментариев',
                                      post_data.permlink)

                i += 1
            except Exception as e:
                logging.exception('Ошибка выборки поста')

        return created_posts

    def get_comment_ins(self, data, post, **kwargs):
        comm = {
            'page': post,
            'updated_at': self.aware(data.last_update),
            'created_at': self.aware(data.created),
            'body': data.body
        }

        comm.update(**kwargs)

        return Comment.objects.update_or_create(permlink=data.permlink,
                                                author=self.get_author(
                                                    data.author),
                                                defaults=comm)[0]

    def get_author(self, username):
        if username in BAN_LIST and self.blockchain.name == 'golos':
            raise BannedAccount()

        try:
            user_bc = UserBlockChain.objects.get(username=username.lower(),
                                                 blockchain=self.blockchain)
        except ObjectDoesNotExist:
            user, _ = User.objects.get_or_create(
                username='******'.format(username,
                                                    self.blockchain.name))

            UserBlockChain.objects.create(username=username,
                                          blockchain=self.blockchain,
                                          user=user)

            return user

        return user_bc.user