Ejemplo n.º 1
0
 def scrape_id(self, id, since=None):
   # excluding replies was a personal choice. i haven't made an easy setting for this yet
   toots = self.mastodon.account_statuses(id, since_id=since, exclude_replies=self.exclude_replies)
   # if this fails, there are no new toots and we just return old pointer
   try:
     new_since_id = toots[0]['id']
   except:
     return since
   bufferfile = 'buffer.txt'
   corpusfile = 'corpus/%s.txt' % id
   i = 0
   with open(bufferfile, 'w') as output:
     while toots != None:
       # writes current amount of scraped toots without breaking line
       i = i + len(toots)
       sys.stdout.write('\r%d' % i)
       sys.stdout.flush()
       filtered_toots = list(filter(lambda x: x['spoiler_text'] == "" and x['reblog'] is None and x['visibility'] in ["public", "unlisted"], toots))
       for toot in filtered_toots:
         output.write(html_strip_tags(toot['content'], True, chr(31))+'\n')
       toots = self.mastodon.fetch_next(toots)
     # buffer is appended to the top of old corpus
     if os.path.exists(corpusfile):
       with open(corpusfile,'r') as old_corpus:
         output.write(old_corpus.read())
     directory = os.path.dirname(corpusfile)
     if not os.path.exists(directory):
       os.makedirs(directory)
     os.rename(bufferfile,corpusfile)
     sys.stdout.write('\n')
     sys.stdout.flush()
   return new_since_id
Ejemplo n.º 2
0
 def post_response(self, mention, user):
     msg = html_strip_tags(mention["content"])
     rsp = random.choice(self.responses)
     tgt = user["acct"]
     if tgt in ["*****@*****.**", "*****@*****.**"
                ] and rsp.find("rides") >= 0:
         rsp = rsp.replace(r"foot", "tail")
     if tgt in ["*****@*****.**", "*****@*****.**"
                ] and rsp.find("leg") >= 0:
         rsp = rsp.replace(r"leg", "tail")
     irt = mention["id"]
     vis = mention["visibility"]
     print("Received toot from {}: {}".format(tgt, msg))
     try:
         tgt_rec = self.recents[tgt]
     except KeyError:
         tgt_rec = 0
     if "mom?" in msg or "moms?" in msg:
         self.mastodon.status_post(
             "{} *holds up a picture of @[email protected]".format(tgt),
             in_reply_to_id=irt,
             visibility=vis)
     else:
         if tgt_rec < self.max_recents or vis == 'direct':
             print("Responding with {} visibility: {}".format(vis, rsp))
             self.mastodon.status_post("@{} *{}*".format(tgt, rsp),
                                       in_reply_to_id=irt,
                                       visibility=vis)
             if vis != 'direct':
                 self.recents[tgt] = tgt_rec + 1
                 print("self.recents updated: ", end="")
                 pprint(self.recents)
         else:
             print("...but I've responded to {} too recently.".format(tgt))
Ejemplo n.º 3
0
    def post_reply(self, mention, user):
        if self.reply_to_mentions == True:
            msg = html_strip_tags(mention["content"], True, chr(31))
            rsp = self.generate(300)
            tgt = user["acct"]
            irt = mention["id"]
            vis = mention["visibility"]
            print("Received toot from {}: {}".format(
                tgt, msg.replace(chr(31), "\n")))
            if (tgt not in self.recent_replies.keys()
                    or self.recent_replies[tgt] < self.max_replies
                    or self.max_replies == -1):
                print("Responding with {} visibility: {}".format(vis, rsp))
                final_rsp = "@{} {}".format(tgt, rsp)
                final_rsp = final_rsp[:500]
                self.mastodon.status_post(final_rsp,
                                          in_reply_to_id=irt,
                                          visibility=vis)
                if tgt in self.recent_replies.keys():
                    self.recent_replies[tgt] = self.recent_replies[tgt] + 1
                else:
                    self.recent_replies[tgt] = 1
            else:
                print("...but I've talked to them too much recently.")
        else:
            pass

        @interval(300)
        def reset_replies(self):
            self.recent_replies = {}
Ejemplo n.º 4
0
 def post_reply(self, mention, user):
     msg = html_strip_tags(mention["content"])
     rsp = self.generate(400)
     tgt = user["acct"]
     irt = mention["id"]
     vis = mention["visibility"]
     print("Received toot from {}: {}".format(tgt, msg))
     print("Responding with {} visibility: {}".format(vis, rsp))
     final_rsp = "@{} {}".format(tgt, rsp)
     final_rsp = final_rsp[:500]
     self.mastodon.status_post(final_rsp,
                               in_reply_to_id=irt,
                               visibility=vis)
Ejemplo n.º 5
0
    def scrape_account(self, account, since=None):
        # excluding replies was a personal choice. i haven't made an easy
        # setting for this yet
        toots = self.mastodon.account_statuses(
            account, since_id=since, exclude_replies=self.exclude_replies)
        # if this fails, there are no new toots and we just return old pointer
        try:
            since = toots[0].id
        except IndexError:
            return since

        total = 0
        count = 0
        buffer = ""
        while toots is not None and len(toots) > 0:
            for toot in toots:
                total += 1
                if (toot.spoiler_text == "" and toot.reblog is None
                        and toot.visibility in ["public", "unlisted"]):
                    content = html_strip_tags(toot.content,
                                              linebreaks=True).strip() + "\n"
                    if re.search("@\w", content) is None:
                        buffer += content
                        count += 1
            toots = self.mastodon.fetch_next(toots)

        self.log("scrape_account",
                 "scraped {} toots from {}".format(total, account))
        self.log("scrape_account",
                 "added {} toots to the corpus".format(count, account))

        corpusfile = "corpus/{}.txt".format(account)

        directory = os.path.dirname(corpusfile)
        if not os.path.exists(directory):
            os.makedirs(directory)

        # buffer is appended to the top of old corpus
        try:
            f = open(corpusfile, "r+")
            buffer += f.read()
            f.seek(0)
        except OSError:
            f = open(corpusfile, "a+")
        f.write(buffer)
        f.truncate()
        f.close()

        return since
Ejemplo n.º 6
0
    def on_reply(self, mention, user):
        msg = html_strip_tags(mention.content, linebreaks=True)
        msg = remove_prefix(msg.strip(), "@tts").strip()
        msg = msg.replace("@", "@\u200b")

        self.log("on_reply",
                 "Received toot from {}: \"{}\"".format(user.acct, msg))

        if "!delete" in msg and user.acct == self.config.admin:
            self.log("on_reply",
                     "Deleting toot: {}".format(mention.in_reply_to_id))
            self.mastodon.status_delete(mention.in_reply_to_id)
            return

        with tempfile.NamedTemporaryFile(suffix=".wav") as af:
            subprocess.check_call([
                "espeak",
                msg,
                "-w",
                af.name,
            ])

            with tempfile.NamedTemporaryFile(suffix=".mp4") as vf:
                subprocess.check_call([
                    "ffmpeg",
                    "-i",
                    af.name,
                    "-i",
                    "speechbot.png",
                    "-profile:v",
                    "baseline",
                    "-pix_fmt",
                    "yuv420p",
                    "-y",
                    "-hide_banner",
                    "-nostats",
                    "-loglevel",
                    "panic",
                    vf.name,
                ])

                self.log("on_reply", "Generated video, posting...")

                media = self.mastodon.media_post(vf.name)
                self.mastodon.status_post("@{} {}".format(user.acct, msg),
                                          in_reply_to_id=mention,
                                          visibility=mention.visibility,
                                          media_ids=media)
Ejemplo n.º 7
0
    def add_toot_to_corpus(self, toot):

        if toot['reblog']:
            return False

        if toot['spoiler_text']:
            return False

        text_content = ananas.html_strip_tags(toot['content'])

        db_conn = self.connect_to_sqlite()
        cursor = db_conn.cursor()

        try:
            toot_input = (toot['id'], text_content)
            cursor.execute("INSERT INTO toots VALUES (?, ?)", toot_input)
            db_conn.commit()
        except sqlite3.IntegrityError:
            pass  # Toot is already in DB, nevermind

        return True
Ejemplo n.º 8
0
    def on_reply(self, mention, user):
        msg = html_strip_tags(mention.content, linebreaks=True)
        self.log("on_reply",
                 "Received toot from {}: \"{}\"".format(user.acct, msg))

        if "!delete" in msg and user.acct == self.config.admin:
            self.log("on_reply",
                     "Deleting toot: {}".format(mention.in_reply_to_id))
            self.mastodon.status_delete(mention.in_reply_to_id)
            return

        if "!followme" in msg:
            self.mastodon.account_follow(user.id)
            self.reply_toot(mention, user, "kapow!")
            return

        if "!unfollowme" in msg:
            self.mastodon.account_unfollow(user.id)
            self.reply_toot(mention, user, "kabam!")
            return

        matches = re.search(
            r"(?:gimme|can i get)(?: some| a)?(?: uh+)? (\")?(?P<s>(?(1).*(?=\")|\w+))",
            msg,
            flags=re.IGNORECASE)
        if matches is not None:
            s = matches.group("s")
            if s in self.corpus:
                response = "too lazy, giving up."
                for _ in range(0, 100):
                    r = self.model.make_short_sentence(400, tries=100)
                    if s in r:
                        response = r
                        break
            else:
                response = "no."
        else:
            response = self.model.make_short_sentence(400, tries=100)

        self.reply_toot(mention, user, response)
Ejemplo n.º 9
0
    def handle_roll(self, mention, user):
        raw = html_strip_tags(mention["content"])
        username = user["acct"]

        self.log("handle_roll",
                 "Parsing dice in '{}' from @{}".format(raw, username))
        message = ""
        try:
            rolls = parse_dice(raw)
        except Exception as e:
            self.report_error("{}\n{}".format(repr(e), traceback.format_exc()))
            rolls = []

        if len(rolls) == 0:
            rolls = [('r', 1, 6)]
            message = "I'm confused, so I'm just going to roll a d6.\n"
            return  # TODO cheeky message?
        else:
            self.log("debug", "rolls: {}".format(rolls))

        for i, r in enumerate(rolls):
            try:
                #r = fixup_tree(r)
                line = "Rolling {}: ".format(spec_dice(r))
                dice = roll_dice(r)
                expr = sum_dice(dice)
                sum = eval_dice(dice)
                line += "{} = {}".format(visit_dice(dice),
                                         visit_sum_dice(expr))
                if (not isinstance(expr, int)):
                    line += " = {}".format(sum)
                message = line + "\n"
            except SillyDiceError as e:
                message += str(e) + "\n"

        self.mastodon.status_post("@{}\n{}".format(username, message),
                                  in_reply_to_id=mention["id"],
                                  visibility=mention["visibility"])
Ejemplo n.º 10
0
    def respond_weather(self, status, user):
        try:
            # post a reply of the form "@<user account>"
            global location
            username = user["acct"]
            msg_rec = html_strip_tags(status["content"], True, chr(31))

            bs = BeautifulSoup(status["content"], "lxml")
            # strip out mentions
            for mention in status["mentions"]:
                for a in bs.find_all(href=mention["url"]):
                    a.extract()
            # put all the lines in a list
            for br in bs.find_all("br"):
                br.replace_with('\n')
            #  then replace consecutive p tags with a double newline
            Input = [Input.text for Input in bs.find_all('p')]
            Input = '\n\n'.join(Input)
            #  finally split all the lines up at the newlines we just added
            Input = [
                Input.strip() for line in Input.splitlines() if Input.strip()
            ]

            if len(Input) == 0:

                msg_date = "The weatherbot can query the weather conditions in the next three days" + '\n========\n' + "1.Please @ Weatherbot + 'location' + ',' + 'Today' or 'Tomorrow' or 'Day After Tomorrow' to query (e.g. London,Today)" + '\n========\n' + "2.If the query result is not in the desired area, please @ Weatherbot + ’location’ + ',' + 'country code' + 'Today' or 'Tomorrow' or 'Day After Tomorrow'(e.g. London,GB,Today). The country code query address: https://www.iso.org/iso-3166-country-codes.html"

                self.mastodon.toot(msg_date)

            else:

                # According to "," split list elements
                location_date = Input[0].split(",")

                # If the length of the returned list after element separation is 1, it means that there is no "," in the original list; the purpose of user input is to query the location Id

                if len(location_date) == 2:
                    location = location_date[0].capitalize()
                    print(location_date[0], location_date[1])

                    tm_hour, tm_min = self.get_time()
                    if location_date[1].capitalize() == "Today":
                        msg = self.today(tm_hour, tm_min)
                        self.mastodon.toot("@{} {}".format(
                            username, '\n' + msg))
                    elif location_date[1].capitalize() == "Tomorrow":
                        msg = self.tomorrow(tm_hour, tm_min)
                        self.mastodon.toot("@{} {}".format(
                            username, '\n' + msg))
                    elif location_date[1].title() == "Day After Tomorrow":
                        msg = self.the_day_after_tomorrow(tm_hour, tm_min)
                        self.mastodon.toot("@{} {}".format(
                            username, '\n' + msg))

                # Otherwise, the user's purpose is to check weather conditions
                elif len(location_date) == 3:

                    url = APIURL_locid + location_date[0].capitalize(
                    ) + "&range=" + location_date[1].lower() + KEY
                    locid_res = requests.get(url)
                    locid_res_json = locid_res.json()

                    location = locid_res_json["location"][0]["id"]
                    print(location_date[0], location, location_date[1],
                          location_date[2])

                    tm_hour, tm_min = self.get_time()
                    if location_date[2].capitalize() == "Today":
                        msg = self.today(tm_hour, tm_min)
                        self.mastodon.toot("@{} {}".format(
                            username, '\n' + msg))
                    elif location_date[2].capitalize() == "Tomorrow":
                        msg = self.tomorrow(tm_hour, tm_min)
                        self.mastodon.toot("@{} {}".format(
                            username, '\n' + msg))
                    elif location_date[2].title() == "Day After Tomorrow":
                        msg = self.the_day_after_tomorrow(tm_hour, tm_min)
                        self.mastodon.toot("@{} {}".format(
                            username, '\n' + msg))
        except:
            msg = "This location is not found or Your input is incorrect, please re-enter"
            self.mastodon.toot("@{} {}".format(username, '\n' + msg))

        print("Received toot from {}: {}".format(
            username, msg_rec.replace(chr(31), "\n")))