python
1import tkinter as tk 2from googleapiclient.discovery import build 3from googleapiclient.errors import HttpError 4import webbrowser 5from datetime import datetime, timezone 6 7def search_channels(api_key, search_keyword):8 youtube = build('youtube', 'v3', developerKey=api_key)9 10 try:11 search_response = youtube.search().list(12 q=search_keyword,13 type='channel',14 part='id,snippet',15 maxResults=1016 ).execute()17 18 channel_list = []19 for search_result in search_response.get('items', []):20 channel_id = search_result['id']['channelId']21 channel_info = get_channel_info(youtube, channel_id)22 channel_list.append(channel_info)23 print(f"Channel Info: {channel_info}")24 25 return channel_list 26 27 except HttpError as e:28 print(f"An HTTP error {e.resp.status} occurred:\n{e.content}")29 return []30 31def get_channel_info(youtube, channel_id):32 try:33 channel_response = youtube.channels().list(34 id=channel_id,35 part='id,snippet,statistics'36 ).execute()37 38 channel_info = {39 'id': channel_id,40 'title': channel_response['items'][0]['snippet']['title'],41 'subscribers': int(channel_response['items'][0]['statistics'].get('subscriberCount', 0)),42 'publishedAt': channel_response['items'][0]['snippet'].get('publishedAt', '')43 }44 45 return channel_info 46 47 except HttpError as e:48 print(f"An HTTP error {e.resp.status} occurred:\n{e.content}")49 return {'id': channel_id, 'title': 'N/A', 'subscribers': 0, 'publishedAt': 'N/A'}50 51def filter_channels(channels):52 try:53 filtered_channels = []54 for channel in channels:55 subscribers = channel['subscribers']56 published_at = channel['publishedAt']57 age_in_days = calculate_age_in_days(published_at)58 59 if (60 subscribers <= 1000 and61 not channel.get('memberships') and62 age_in_days < 36563 ):64 filtered_channels.append(channel)65 66 return filtered_channels 67 68 except Exception as e:69 print(f"An error occurred: {e}")70 import traceback 71 traceback.print_exc()72 return [] # 例外が発生した場合、空のリストを返す73 74 75def calculate_age_in_days(published_at):76 # 'publishedAt' から日付を取得し、現在の日付との差を計算77 # ここで datetime モジュールを使用78 from datetime import datetime, timezone 79 80 try:81 published_date = datetime.fromisoformat(published_at.replace("Z", "+00:00"))82 except ValueError as e:83 print(f"Invalid isoformat string: {published_at}")84 return -185 86 current_date = datetime.utcnow().replace(tzinfo=timezone.utc)87 age_in_days = (current_date - published_date).days 88 89 return age_in_days 90 91def on_search_button_click():92 api_key = entry_api_key.get()93 search_keyword = entry_search.get()94 95 channels = search_channels(api_key, search_keyword)96 filtered_channels = filter_channels(channels)97 display_results(filtered_channels)98 99result_text = None # グローバル変数として定義100 101def display_results(channels):102 result_text.delete(1.0, tk.END)103 104 # チャンネル情報とボタンを一つずつ挿入105 for i, channel in enumerate(channels, start=1):106 result_text.insert(tk.END, f"Channel {i}:\n")107 result_text.insert(tk.END, f" Title: {channel['title']}\n")108 result_text.insert(tk.END, f" Subscribers: {channel['subscribers']}\n")109 result_text.insert(tk.END, f" Published At: {channel['publishedAt']}\n\n")110 111 # チャンネルに対するボタンを作成112 button = tk.Button(root, text=f"Open Channel {i}", command=lambda id=channel['id']: open_channel(id))113 button.pack()114 115def open_channel(channel_id):116 url = f"https://www.youtube.com/channel/{channel_id}"117 webbrowser.open(url)118 119def change_page(delta):120 global current_page, channels # グローバル変数を使用することを明示121 current_page = (current_page + delta) % num_pages 122 start_index = current_page * 15123 end_index = (current_page + 1) * 15124 display_results(channels[start_index:end_index])125 126# GUIの作成127root = tk.Tk()128root.title("YouTube Channel Viewer")129 130# APIキー入力欄131label_api_key = tk.Label(root, text="YouTube API Key:")132label_api_key.pack()133entry_api_key = tk.Entry(root)134entry_api_key.insert(tk.END, "API")135entry_api_key.pack()136 137# 検索キーワード入力欄138label_search = tk.Label(root, text="Search Keyword:")139label_search.pack()140entry_search = tk.Entry(root)141entry_search.insert(tk.END, "Vtuber")142entry_search.pack()143 144# 検索ボタン145search_button = tk.Button(root, text="Search", command=on_search_button_click)146search_button.pack()147 148# ページャー149current_page = 0150num_pages = 1151page_label = tk.Label(root, text="Page 1 of 1")152page_label.pack()153 154# 結果表示用のTextウィジェット155result_text = tk.Text(root, height=20, width=50)156result_text.pack() # pylint: disable=undefined-variable157 158# 初回の表示を行うための仮のデータ159channels = [{'id': 'placeholder', 'title': 'Loading...', 'subscribers': 0, 'publishedAt': ''}]160display_results(channels)161 162# GUI起動163root.mainloop()164 165

0 コメント