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)
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('<','').replace('>','').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))
# 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()
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( '<', '').replace('>', '').replace('html', '').replace('<', '') #Preprocessing content #capture links captureLinksString = '' captureLinks = re.search( r'\<?(https?:\/\/?\/[^/]+\W?\@?\S+\W?\S+\w)\>?',
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")
] 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')
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