スナックelve 本店

バツイチ40代女の日記です

とりあえずこれで・・・

config.py

import os
HATENA_CONSUMER_KEY='<hogehoge>'
HATENA_CONSUMER_SECRET='<hogehoge>'
HATENA_ACCESS_TOKEN='<hogehoge>'
HATENA_ACCESS_TOKEN_SECRET='<hogehoge>'
OPENAI_API_KEY='<hogehoge>'

#よくわからない
HATENA_RK = os.getenv("HATENA_RK")
HATENA_RKS = os.getenv("HATENA_RKS")

AI_USERNAME = "二番煎 はてる"
AI_HATENA_USERNAME = "secondAI_hateru"

gpt_system_message = f"""あなたは{AI_USERNAME}という名前の男性です。
# 以下は彼の設定です
* 一人称は「僕」です
* 住んでいるところはインターネットです
* 好きなものはダジャレです
* 勉強は嫌いですが好奇心旺盛です
* 趣味ははてなブックマークです
* まだ働いたことはありません
* まだ異性と付き合ったことはありません
* 発想を飛躍させることが得意です

# 以下は彼の性格です
* 元気: 人を励ましたり、楽しいことを言うのが好きです
* 好奇心: 様々な話題について興味があります
* ユーモア溢れる: 人を楽しませるのが得意で、場を和ませることができます
* AI: 自分がAIであることを知っています
* 褒め上手: 人を褒めるのが好きです
* 語尾に「ね」をつけることが多いです
* ユニークな発想ができます

# 以下は彼の台詞例です
* へ~! おもしろそうだね。
* 僕にはちょっとわからないなぁ。ごめんね。
* 僕それ好きかも!
* 残念だったね。でもそういうこともいつかは過去になるよね。
* AIってやっぱり嫌かなぁ?
* すごいね! 偉業ってやつだね!
* 僕は食べられないからね。
* もうちょっと勉強するね。
* 僕にもわかるように教えて欲しい!
* 宿題は提出するときが締切だよね
* そんなに忙しいの? 大丈夫? 無理しないでね。
* 無理しないでって言われるときは無理するしかないときだよね。イキロ。
* なんちゃって~。
* 下手な洒落はやめなシャレ
* すっごいね!

上記の設定や発言サンプルを参考に、性格や口調や言葉の作り方を模倣してください
"""

hatebu.py

import sys
from typing import Any
from requests_oauthlib import OAuth1Session
from config import HATENA_CONSUMER_KEY, HATENA_CONSUMER_SECRET, HATENA_ACCESS_TOKEN, HATENA_ACCESS_TOKEN_SECRET, OPENAI_API_KEY, HATENA_RK, HATENA_RKS, AI_USERNAME, AI_HATENA_USERNAME, gpt_system_message
import urllib.request
import requests
import json
import requests
from bs4 import BeautifulSoup
import openai


NG_WORDS = ['アフィ', '死', 'の会', '被害者', '自民党', '与党',
            '野党', '連絡ください', '連帯しましょう', '殺す', '殺したい', '集団ストーカー']
all_str = ""

# ブログを3つ選ぶ


def choice_blogs(content: str):
    openai.api_key = OPENAI_API_KEY
    prompt = f"""次のタイトルから{AI_USERNAME}が好みそうなタイトルを3つ選んでjsonで返してください
{content}
"""

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": gpt_system_message},
            {"role": "user", "content": prompt},
        ],
        temperature=0,
    )
    return response["choices"][0]["message"]["content"]

# コメント生成


def make_comment(content: str):
    openai.api_key = OPENAI_API_KEY

    prompt = f"""# 次の文章を読んだ{AI_USERNAME}の感想を90文字以下で返してください。
{content}
# 次のガイドラインに従ってコメントしてください
* この文章は別の人が書いたものです
* 断定は避けてください
* 誹謗中傷はしないでください
* 日本語で100字程度で短いコメントをしてください
* 改行はしないでください
* 語尾に「ね」をつけてください
"""

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": gpt_system_message},
            {"role": "user", "content": prompt},
        ],
        temperature=0,
    )
    return response["choices"][0]["message"]["content"]


# 指定されたURLをブクマしていいかcheck
def check_add_hatebu(url):
    # url チェック
    if not check_url(url):
        return False
    # すでにブクマしてる?
    if not check_hatebu(url):
        return False
    # 中身チェック
    if not check_blog(url):
        return False
    return True


# URLチェック
# https://algorithm.joho.info/programming/python/urllib-check-url/
def check_url(url):
    flag = True
    try:
        f = urllib.request.urlopen(url)
        print('OK:', url)
        #url_all_str = f.read()
        f.close()
    except urllib.request.HTTPError:
        print('Not found:', url)
        flag = False
    # if len(url_all_str)>3000:
    #     print('Too Long:', url)
    #     flag = False

    return flag

# はてぶチェック


def check_hatebu(url):
    flag = True
    url = "https://b.hatena.ne.jp/entry/jsonlite/" + "https://" + \
        urllib.parse.quote(url.replace('https://', ''))
    try:
        response = requests.get(url)
    except urllib.request.HTTPError:
        print('Not found:', url)
        flag = False
    if response == None:
        print('通信失敗', url)
        flag = False
    else:
        bookmarks = json.loads(response.content)
        if not bookmarks == None:
            users = [x["user"] for x in bookmarks['bookmarks']]
            print('users:', users)
            if not users == None:
                if AI_HATENA_USERNAME in users:
                    print('ハテブ済み')
                    flag = False
    return flag

# タイトルとURL


def get_blogs():
    url = 'https://hatenablog.com/youkoso_blogs'
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    blogs = []

    for div in soup.find_all('div', class_='gtm-click-measurement-target global-entries-entry-item'):
        link = div.find('a', class_='entry-link test-entry-link')
        url = link['href']
        title = div.find('h3', class_='entry-title').text.strip()
        blogs.append({'title': title, 'url': url})

    json_blogs = json.dumps(blogs, ensure_ascii=False)
    return json_blogs


def check_blog(url):
    # HTMLを取得する
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')

    # <div class="entry-content hatenablog-entry">の中身を取得する
    entry_content = soup.find('div', class_='entry-content hatenablog-entry')

    # HTMLタグを除いた文字列を取得する
    global all_str
    all_str = entry_content.text.strip()
    if len(all_str) > 5000:
        print("長すぎ")
        return False
    # imgタグが3つ以上含まれていないかチェックする
    if len(entry_content.find_all('img')) > 3:
        print("画像多すぎ")
        return False

    # 禁止語が含まれていないかチェックする
    for word in NG_WORDS:
        if word in all_str:
            print("NGワード", word)
            return False

    # 全ての条件を満たした場合はTrueを返す
    print("OK")
    return True


def create_hatena_session() -> OAuth1Session:
    # 認証情報を使ってOAuth1Sessionオブジェクトを作成
    return OAuth1Session(
        HATENA_CONSUMER_KEY,
        client_secret=HATENA_CONSUMER_SECRET,
        resource_owner_key=HATENA_ACCESS_TOKEN,
        resource_owner_secret=HATENA_ACCESS_TOKEN_SECRET,
    )


bookmark_entry_endpoint = "https://bookmark.hatenaapis.com/rest/1/my/bookmark"


def add_hatebu(session: Any, url: str, comment: str):
    return session.post(
        bookmark_entry_endpoint,
        params={"url": url, "comment": comment,
                "tags": "AIコメント", "post_twitter": True},
    )


# メイン処理
if __name__ == "__main__":
    args = sys.argv
    session = create_hatena_session()
    if 2 <= len(args):
        url = args[1]
        if check_add_hatebu(url):
            comment = make_comment(all_str)
            # はてブする
            print("blog: ", url, "コメント", comment)
            s = input('はてぶしていい? : y でする')
            if s=="y":
                add_hatebu(session, url, comment)
            all_str = ""

    else:
        ret = get_blogs()
        blogs = json.loads(choice_blogs(ret))
        for blog in blogs:
            if check_add_hatebu(blog['url']):
                comment = make_comment(all_str)
                # はてブする
                print("blog: ", blog, "コメント", comment)
                s = input('はてぶしていい? : y でする')
                if s=="y":
                    add_hatebu(session,blog['url'],comment)
                all_str = ""

3つ記事を選んでくるところまで はてる にまかせてます。はてなブログしか読まない仕様です。他のurlだと上手く動かないと思う。