script/utils/dump_public_toots.py
changeset 1557 7c67caaafdeb
equal deleted inserted replaced
1556:5f9b76ecccf0 1557:7c67caaafdeb
       
     1 #!/usr/bin/env python
       
     2 """
       
     3 Dump public toots
       
     4 """
       
     5 
       
     6 # import sqlite3
       
     7 
       
     8 # con = sqlite3.connect("registered_app.db")
       
     9 
       
    10 # cur = con.cursor()
       
    11 # cur.execute("CREATE TABLE registered_app(title, year, score)")
       
    12 
       
    13 
       
    14 import argparse
       
    15 import collections
       
    16 from sqlalchemy import Column, Integer, String, create_engine, UniqueConstraint, select
       
    17 from sqlalchemy.orm import declarative_base, Session
       
    18 from mastodon import Mastodon
       
    19 import socket
       
    20 import requests.packages.urllib3.util.connection as urllib3_cn
       
    21 import requests
       
    22 
       
    23 
       
    24 Base = declarative_base()
       
    25 
       
    26 # Disable ipv6
       
    27 
       
    28 
       
    29 def allowed_gai_family():
       
    30     """
       
    31      https://github.com/shazow/urllib3/blob/master/urllib3/util/connection.py
       
    32     """
       
    33     return socket.AF_INET
       
    34 
       
    35 urllib3_cn.allowed_gai_family = allowed_gai_family
       
    36 
       
    37 class RegisteredApp(Base):
       
    38     """RegisteredApp"""
       
    39 
       
    40     __tablename__ = "registered_app"
       
    41     __table_args__ = (UniqueConstraint("url", "name", name="_url_name_uc"),)
       
    42 
       
    43     id = Column(Integer, primary_key=True)
       
    44     url = Column(String)
       
    45     name = Column(String)
       
    46     key = Column(String, unique=True, index=True)
       
    47     secret = Column(String)
       
    48 
       
    49     def __repr__(self):
       
    50         return f"RegisteredApp(id={self.id!r}, url={self.url!r}, name={self.name!r})"
       
    51 
       
    52 
       
    53 AppKeySecret = collections.namedtuple(
       
    54     "AppKeySecret", ("key", "secret", "url"), defaults=(None, None, None)
       
    55 )
       
    56 
       
    57 def get_application_secret(name, url, db_con):
       
    58     """Get the application id and secret
       
    59 
       
    60     Args:
       
    61         name (String): The name of the application
       
    62         url (String): The mastodon base url (without http(s))
       
    63         db_con (Connection): The database connection
       
    64 
       
    65     Returns:
       
    66         AppKeySecret: The application secret
       
    67     """
       
    68     # get existing secret keys
       
    69     stmt = select(RegisteredApp).where(
       
    70         RegisteredApp.url == url, RegisteredApp.name == name
       
    71     )
       
    72     result = db_con.execute(stmt).fetchone()
       
    73 
       
    74     if result:
       
    75         return AppKeySecret(key=result.key, secret=result.secret, url=url)
       
    76 
       
    77     (client_id, client_secret) = Mastodon.create_app(
       
    78         name,
       
    79         api_base_url = f'https://{url}'
       
    80     )
       
    81 
       
    82     registered_app = RegisteredApp(name=name, url=url, key=client_id, secret=client_secret)
       
    83     with Session(db_con) as session:
       
    84         session.add(registered_app)
       
    85         session.commit()
       
    86 
       
    87     return AppKeySecret(key=client_id, secret=client_secret, url=url)
       
    88 
       
    89 def get_public_statuses(appKeySecret, tag, limit=40):
       
    90     mastodon = Mastodon(client_id=appKeySecret.key, client_secret=appKeySecret.secret, api_base_url=f'https://{appKeySecret.url}')
       
    91     results = mastodon.timeline_hashtag(hashtag=tag, limit=limit)
       
    92     while results:
       
    93         for status in results:
       
    94             print("-------------------------")
       
    95             print(repr(status))
       
    96         results = mastodon.fetch_next(results)
       
    97 
       
    98 
       
    99 def parse_arg():
       
   100     """
       
   101     parse args
       
   102     """
       
   103     parser = argparse.ArgumentParser(
       
   104         prog="dump_public_toots",
       
   105         description="Dump the latest public toots",
       
   106         epilog="dump only public toots",
       
   107     )
       
   108     parser.add_argument(
       
   109         "-d",
       
   110         "--database",
       
   111         dest="database",
       
   112         default="registered_apps.sqlite",
       
   113         help="The path to the registered apps db",
       
   114     )
       
   115     parser.add_argument(
       
   116         "-u", "--url", dest="url", help="The mastodon base url", required=True
       
   117     )
       
   118     parser.add_argument(
       
   119         "-n", "--name", dest="name", help="The application name", required=True
       
   120     )
       
   121     parser.add_argument(
       
   122         "-t", "--tag", dest="tag", help="The tag to search", required=True
       
   123     )
       
   124     parser.add_argument(
       
   125         "-l", "--limit", dest="limit", help="page size", required=False, default=40
       
   126     )
       
   127 
       
   128 
       
   129     return parser.parse_args()
       
   130 
       
   131 
       
   132 if __name__ == "__main__":
       
   133 
       
   134     options = parse_arg()
       
   135 
       
   136     # req = requests.get(f"https://{options.url}/api/v1/timelines/tag/{options.tag}/")
       
   137     # print(req.text)
       
   138 
       
   139 
       
   140     app_db_eng = create_engine(f"sqlite+pysqlite:///{options.database}", future=True)
       
   141 
       
   142     with app_db_eng.connect() as app_db_con:
       
   143         Base.metadata.create_all(app_db_con)
       
   144 
       
   145         keySecret = get_application_secret(options.name, options.url, app_db_con)
       
   146 
       
   147         get_public_statuses(keySecret, options.tag, options.limit)
       
   148 
       
   149         app_db_con.commit()
       
   150