Пример #1
0
def print_report(date):
    pb = Publisher()
    report = pb.generate_report(date)
    if report:
        print(report['body'])
    else:
        print('\n'.join(pb.get_all_points()))
Пример #2
0
    def test_get_daily(self):
        with open('./input_data/db_range.json') as sample:
            data = json.load(sample)
        pb = Publisher({
            "reward": {
                "medals": [
                    "http://i.imgur.com/hv0zL8U.png",
                    "http://i.imgur.com/xe9CD0S.png",
                    "http://i.imgur.com/50zpz2p.png"
                ],
                "pool":
                10
            }
        })

        print(pb.get_rank(data))
        print('\n'.join(pb.generate_report(data)))

        pass
Пример #3
0
class GuideDog:
    log = logging.getLogger(__name__)

    def __init__(self, config, db):
        self.config = config
        self.db = db
        keypath = os.path.expanduser(self.config['keyfile_path'])
        with open(keypath) as key_file:
            key_file_json = json.load(key_file)
            self.steem = Steem(keys=key_file_json['krguidedog'])

        self.message1 = readFile(self.config['guidedog']['mild_warning_file'])
        self.message2 = readFile(
            self.config['guidedog']['moderate_warning_file'])
        self.message3 = readFile(self.config['guidedog']['hard_warning_file'])
        self.copyright = readFile(self.config['guidedog']['copyright_file'])
        self.copyright_eng = readFile(
            self.config['guidedog']['copyright_file_eng'])

        self.last_daily_report = None
        self.daily_report_generator = Publisher(self.db)
        self.daily_report_timestamp = None

    def claim_reward(self):
        self.steem.claim_reward_balance(account='krguidedog')

    def reputation(self, number, precision=2):
        rep = int(number)
        if rep == 0:
            return 25
        score = max([math.log10(abs(rep)) - 9, 0]) * 9 + 25
        if rep < 0:
            score = 50 - score
        return round(score, precision)

    def create_post(self, post_id, body, author='krguidedog'):
        comment = self.steem.commit.post(title='',
                                         body=body,
                                         author=author,
                                         permlink=None,
                                         reply_identifier=post_id,
                                         json_metadata=None,
                                         comment_options=None,
                                         community=None,
                                         tags=None,
                                         beneficiaries=None,
                                         self_vote=False)
        post_item = comment['operations'][0][1]
        post_id = '@%s/%s' % (post_item['author'], post_item['permlink'])

        limit = 3
        while True:
            sleep(1)
            try:
                double_check = Post(post_id)
                return comment
            except Exception as e:
                limit -= 1
                if limit == 0:
                    raise 'Posting check failure'
                else:
                    self.log.info(
                        'Failed to confirm the post creation. retry ' + limit)

    def vote(self, post_id, power, voter):
        try:
            self.steem.commit.vote(post_id, power, voter)
            self.log.info('%s voted on %s with %s percentage' %
                          (voter, post_id, power))
        except Exception as e:
            self.log.info("Failed to vote: " + str(e))
            pass

    def transfer(self, send_to, amount, memo):
        try:
            self.steem.commit.transfer(
                to=send_to,
                amount=amount,
                asset='SBD',
                account=self.config['guidedog']['account'],
                memo=memo)
            self.log.info('Transferred %s to %s: %s' % (amount, send_to, memo))
        except Exception as e:
            self.log.info("Failed to transfer: " + str(e))
            raise

    def resteem(self, post_id, resteemer):
        try:
            self.steem.commit.resteem(post_id, resteemer)
            self.log.info('Resteemed %s by %s' % (post_id, resteemer))
        except Exception as e:
            self.log.info("Failed to resteem: " + str(e))
            pass

    def daily_report(self):
        last_daily_report = None
        try:
            with open("db/daily_report", "r") as f:
                last_daily_report = f.read().splitlines()[0]
        except:
            self.log.info('Failed to read daily_report file!!')
            return
        try:
            theday = datetime.now() - timedelta(days=1)
            if last_daily_report == theday.strftime("%d %b %Y"):
                # Already created until the last available day
                return
            newday = datetime.strptime(last_daily_report,
                                       "%d %b %Y") + timedelta(days=1)
            result = self.daily_report_generator.generate_report(
                newday.strftime("%d %b %Y"))
            if result == None:
                self.log.info('No activiey is found in ' +
                              newday.strftime("%d %b %Y"))
            else:
                self.log.info('Creating a daily report for ' +
                              newday.strftime("%d %b %Y"))
                comment_options = {
                    'max_accepted_payout': '0.000 SBD',
                    'percent_steem_dollars': 0,
                    'allow_votes': True,
                    'allow_curation_rewards': True,
                    'extensions': []
                }
                comment = self.steem.commit.post(title=result['title'],
                                                 body=result['body'],
                                                 author='krguidedog',
                                                 permlink=str(uuid.uuid4()),
                                                 reply_identifier=None,
                                                 json_metadata=None,
                                                 comment_options=None,
                                                 community=None,
                                                 tags='kr krguidedog antispam',
                                                 beneficiaries=None,
                                                 self_vote=False)

            # All succeeded. Update the last report day
            with open("db/daily_report", "w") as f:
                f.write(newday.strftime("%d %b %Y"))

        except Exception as e:
            self.log.info(e)
            self.log.info('Failed to create a daily report for ' +
                          newday.strftime("%d %b %Y"))
            #traceback.print_exc(file=sys.stdout)
            return

    def work(self):
        data = self.db.queue_get('post')
        if data:
            try:
                self.handle_post(data['data'])
                self.db.queue_finish('post', data)
            except Exception as e:
                self.log.error('Failed: post (will retry)')
                self.log.error(data)
                self.log.error(e)

        data = self.db.queue_get('vote')
        if data:
            try:
                self.log.info(data)
                voting = data['data']
                self.vote(voting['post_id'], voting['power'], voting['voter'])
                self.db.queue_finish('vote', data)
            except Exception as e:
                self.log.error('Failed: vote (will retry)')
                self.log.error(data)
                self.log.error(e)

        data = self.db.queue_get('transfer')
        if data:
            try:
                transfer = data['data']
                self.transfer(transfer['send_to'], transfer['amount'],
                              transfer['memo'])
                self.db.queue_finish('transfer', data)
            except Exception as e:
                self.log.error('Failed: transfer (will retry)')
                self.log.error(data)
                self.log.error(e)

        data = self.db.queue_get('resteem')
        if data:
            try:
                resteem = data['data']
                self.resteem(resteem['post_id'], resteem['resteemer'])
                self.db.queue_finish('resteem', data)
            except Exception as e:
                self.log.error('Failed: resteem (will retry)')
                self.log.error(data)
                self.log.error(e)

        self.daily_report()
        # Prevent wasting the donated funds
        #self.claim_reward()

    def handle_post(self, post):
        self.log.info(
            "New Command [%s -> %s -> %s] : %s" %
            (post['author'], post['bot_signal'], post['parent_author'], post))
        if post['signal_type'] == 'spam':
            if self.db.is_reported(post):
                self.log.info('Skip request: already reported')
                return
            rep = self.reputation(
                self.steem.get_account(post['author'])['reputation'])
            if rep < 35:
                self.log.info('Skip request: reputation is too low (%s, %s) ' %
                              (post['author'], rep))
                return

            self.process_spam(
                post,
                self.db.get_reported_count(post['parent_author']) + 1)

        elif post['signal_type'] == 'praise':
            if self.db.is_already_consumed_comment(post):
                self.log.info('Skip request: already consumed comment')
                return

            point = self.db.get_usable_point(post['author'])
            self.log.info('Praise request - user: %s point: %s' %
                          (post['author'], point))
            if post['author'] in self.config["praise_curator"]:
                self.leave_praise(post)
            elif point >= 1:
                self.leave_praise(post)
                self.db.use_point(post['author'], 1)
            else:
                self.log.info('Not enough point! %s %s' %
                              (post['author'], point))
                # self.send_no_point_alarm(post)
        elif post['signal_type'] == 'promote':
            if self.db.is_promoted(post):
                self.log.info('Skip request: already promoted')
                return

            point = self.db.get_usable_point(post['author'])
            self.log.info('Promote request - user: %s point: %s' %
                          (post['author'], point))
            if post['author'] in self.config["promote_curator"]:
                self.promote(post)
            elif point >= 1:
                self.promote(post)
                self.db.use_point(post['author'], 1)
            else:
                self.log.info('Not enough point! %s %s' %
                              (post['author'], point))
                self.send_no_point_alarm(post)
        elif post['signal_type'] == 'welcome':
            if post['author'] not in self.config["welcome_curator"]:
                self.log.info('Skip request: Not allowed user')
                return
            if self.db.is_welcomed(post):
                self.log.info('Skip request: already welcomed')
                return

            rep = self.reputation(
                self.steem.get_account(post['parent_author'])['reputation'])
            if rep > 50:
                self.log.info(
                    'Skip request: reputation is too high (%s, %s) ' %
                    (post['parent_author'], rep))
                return
            self.log.info('Welcome %s (%s)!' % (post['parent_author'], rep))
            self.welcome(post)
        else:
            pass

    def generate_warning_message(self, post, reported_count):
        if post['bot_signal'] == "@저작권안내":
            greet = ('저작권 안내입니다.' if reported_count <= 1 else '%s 번째 안내입니다.' %
                     reported_count)
            greet_eng = ('this is the %s copyright warning.' %
                         ordinal(reported_count))
            lines = [
                'https://i.imgur.com/2PPRCJq.png',
                '#### Hey @%s, %s' % (post['parent_author'], greet_eng)
            ]
            lines.extend(self.copyright_eng)
            lines.append('---')
            lines.append('#### 안녕하세요 @%s님, %s' %
                         (post['parent_author'], greet))
            lines.extend(self.copyright)
            return '\n'.join(lines)
        else:
            if reported_count <= 5:
                greet = ('Nice to meet you!' if reported_count <= 1 else
                         'We have met %s times already!' % reported_count)
                lines = [
                    sys_random.choice(self.config['guidedog']['mild_photo']),
                    '## Woff, woff!',
                    '#### Hello @%s, %s' % (post['parent_author'], greet)
                ]
                lines.extend(self.message1)
                return '\n'.join(lines)
            elif reported_count <= 10:
                greet = ('We have met %s times already!' % reported_count)
                lines = [
                    sys_random.choice(
                        self.config['guidedog']['moderate_photo']),
                    '#### Hello @%s, %s' % (post['parent_author'], greet)
                ]
                lines.extend(self.message2)
                return '\n'.join(lines)
            else:
                greet = ('We have met %s times already!' % reported_count)
                lines = [
                    sys_random.choice(self.config['guidedog']['hard_photo']),
                    '#### Hey @%s, %s' % (post['parent_author'], greet)
                ]
                lines.extend(self.message3)
                return '\n'.join(lines)

    def vote_on_post(self, post, supporters):
        post = post['operations'][0][1]
        self.supporters_vote(post['author'], post['permlink'], supporters)

    def supporters_vote(self, author, permlink, supporters):
        votes = self.steem.get_active_votes(author, permlink)
        voters = set()
        for vote in votes:
            voters.add(vote['voter'])

        for supporter in supporters:
            # Skip already voted supporters
            if not supporter['account'] in voters:
                voting_power = self.steem.get_account(
                    supporter['account'])['voting_power']
                if voting_power > supporter['voteOver']:
                    self.db.queue_push(
                        'vote', {
                            'power': supporter['weight'],
                            'post_id': '@%s/%s' % (author, permlink),
                            'voter': supporter['account']
                        })
            else:
                self.log.info('%s already voted' % supporter)

    def process_spam(self, post, reported_count):
        my_comment = self.create_post(
            post['parent_post_id'],
            self.generate_warning_message(post, reported_count))
        self.db.store_report(post)
        self.vote_on_post(my_comment, self.config['spam_supporters'])
        if reported_count > 10:
            self.supporters_vote(post['parent_author'],
                                 post['parent_permlink'],
                                 self.config['spam_downvoters'])

    def generate_benefit_message(self, post):
        reward = "0.4 SBD"
        rt = [
            '멋진', '섹시한', '훈훈한', '시크한', '알흠다운', '황홀한', '끝내주는', '요염한', '흥분되는',
            '짱재밌는', '잊지못할', '감동적인', '배꼽잡는', '러블리한', '쏘쿨한', '분위기있는'
        ]
        pet = sys_random.choice(self.config['guidedog']['pets'])
        pet_name = '<a href="/%s">%s</a>' % (pet['parent'], pet['name'])
        pet_photo = sys_random.choice(pet['photo'])
        if post['bot_signal'] == '@칭찬해':
            msg = (
                '%s @%s님 안녕하세요! %s 입니다. %s @%s님 소개로 왔어요. 칭찬이 아주 자자 하시더라구요!! '
                '%s 글 올려주신것 너무 감사해요. 작은 선물로 %s를 보내드립니다 ^^' %
                (sys_random.choice(rt), post['parent_author'], pet_name,
                 sys_random.choice(rt), post['author'], sys_random.choice(rt),
                 reward))
        elif post['bot_signal'] == '@축하해':
            msg = (
                ('%s @%s님 안녕하세요! %s 입니다. %s @%s님이 그러는데 정말 %s 일이 있으시다고 하더라구요!! '
                 '정말 축하드려요!! 기분좋은 날 맛좋은 ' +
                 sys_random.choice(['개껌 하나', '개밥 한그릇', '개뼈다구 하나']) +
                 ' 사드시라고 %s를 보내드립니다 ^^') %
                (sys_random.choice(rt), post['parent_author'], pet_name,
                 sys_random.choice(rt), post['author'], sys_random.choice(rt),
                 reward))
        elif post['bot_signal'] == '@감사해':
            msg = (
                '%s @%s님 안녕하세요! %s 입니다. %s @%s님이 너무너무 고마워 하셔서 저도 같이 감사드리려고 이렇게 왔어요!! '
                '%s 하루 보내시라고 %s를 보내드립니다 ^^' %
                (sys_random.choice(rt), post['parent_author'], pet_name,
                 sys_random.choice(rt), post['author'], sys_random.choice(rt),
                 reward))
        elif post['bot_signal'] == '@위로해':
            msg = (
                ('@%s님 안녕하세요. %s 입니다. @%s께 이야기 다 들었습니다. ' + sys_random.choice(
                    ['세상사 다 그런것 아닐까요?. ', '인생지사 새옹지마라고 하잖아요. ']) +
                 '힘든일이 있으면 반드시 좋은일도 있대요! 기운 내시라고 %s를 보내드립니다.') %
                (post['parent_author'], pet_name, post['author'], reward))
        elif post['bot_signal'] == '@홍보해':
            msg = ((
                '@%s님 안녕하세요. %s 입니다. @%s님이 이 글을 너무 좋아하셔서, 저에게 홍보를 부탁 하셨습니다.' +
                ' 이 글은 @krguidedog에 의하여 리스팀 되었으며, 가이드독 서포터들로부터 보팅을 받으셨습니다. 축하드립니다!'
            ) % (
                post['parent_author'],
                pet_name,
                post['author'],
            ))
        msg = ('<table><tr><td>%s</td><td>%s</td></tr></table>' %
               (pet_photo, msg))
        return msg

    def leave_praise(self, post):
        my_comment = self.create_post(post['parent_post_id'],
                                      self.generate_benefit_message(post))
        self.db.store_praise(post)
        self.vote_on_post(my_comment, self.config['praise_supporters'])

        # Push transfer to queue
        self.db.queue_push(
            'transfer', {
                'send_to':
                post['parent_author'],
                'amount':
                0.4,
                'memo':
                '@%s 님께서 가이드독 활동을 통해 모은 포인트로 감사의 표시를 하였습니다.'
                '해당 글을 확인해 주세요! https://steemit.com/%s' %
                (post['author'], post['parent_post_id'])
            })

    def promote(self, post):
        my_comment = self.create_post(post['parent_post_id'],
                                      self.generate_benefit_message(post))
        self.db.store_promote(post)
        self.vote_on_post(my_comment, self.config['praise_supporters'])
        self.db.queue_push(
            'resteem', {
                'post_id': post['parent_post_id'],
                'resteemer': self.config['guidedog']['account']
            })
        self.supporters_vote(post['parent_author'], post['parent_permlink'],
                             self.config['promotion_supporters'])

    def welcome(self, post):
        # Message
        message = [
            "### @%s님 스팀잇에 오신것을 환영합니다!" % post['parent_author'],
            "스팀잇 정착을 도와드리기 위하여 @%s님의 부탁을 받고 찾아온 @easysteemit 입니다. 힘찬 출발을 응원하는 의미로 서포터 보팅을 해드립니다."
            % post['author'], "", "### [이지스팀잇]",
            "@easysteemit은 처음에는 낮설고 복잡해 보일수 있는 스팀잇을 더욱 쉽게 접할수 있도록 만들어진 스팀잇 안내서입니다. @easysteemit 을 팔로우하시고 필요한 것들을 하나하나 익혀보세요! 스팀잇 활동이 더욱 더 즐거워질거에요 :)",
            "",
            "<a href='/@easysteemit'><img src='https://steemitimages.com/300x0/https://steemitimages.com/DQmZmqw2L61Rrnvy92WAH5xSnn3Ud1ZcMJWWFcff141DPqV/daemoon.png'></a>"
        ]
        # Process
        my_comment = self.create_post(post['parent_post_id'],
                                      '\n'.join(message), 'easysteemit')
        self.db.store_welcome(post)
        self.supporters_vote(post['parent_author'], post['parent_permlink'],
                             self.config['welcome_supporters'])

    def send_no_point_alarm(self, post):
        memo = '가이드독 포인트가 부족합니다. 스팸글 신고를 통해 포인트를 쌓아주세요. 자세한 정보는 다음 링크에서 확인해 주세요. https://steemit.com/kr/@asbear/33kqka-kr'
        self.db.queue_push('transfer', {
            'send_to': post['author'],
            'amount': 0.001,
            'memo': memo
        })