워드프레스와 유튜브관리를 위한 일정관리 프로그램 만들기

일정관리? 필요한가?

블로그든 유튜브든 뭐든 꾸준하게 하는 것이 관건이다. 항상 블로그를 하다가 초반에만 불타오르고 별다른 수확이 없으니 금방 접어버리는 경우가 상당히 많다 유튜브도 마찬가지…

그래봐야 안좋은 혹은 안되는 방향으로 길게 운영하면 의미 없지않냐

~이라고 말하는 사람도 있지만 그걸 알려면 혹은 깨달으려면 일단은 슬프게도 일정기간 이상은 운영을 해야 한다는 부분이다.

안그러면 나의 나쁜 습관으로 구린 포스팅을 하는지 유튜브를 하는지 반응이 있는지 없는지 객관적으로 판단하지 못 하니까 말이다. 인간은 참 ㅠ

어떻게 만들건데?

일정관리 앱이나 프로그램은 많이있다.

문제는 대다수의 프로그램은 내가 기록을 해야 한다는 부분이다.

매우 치명적이다. 본인의 일정도 관리 못 하는 사람이 어떤 작업이 끝나고 다음을 위해서 기록하고 기약을 하는 행위를 할 수 없는 노릇이다.

에초에 그렇게 일정을 관리할 수 있는 사람은 그러한 도구가 없어서 어느정도 관리가 되겠지…

내가 프로그램에 제공 해줄 수 있는 부분은 최초 블로그와, 유튜브만들 당시의 링크들뿐이다. 주기적으로 기입해야하는 고생스러운 일은 못 한다.

  • 워드프레스에는 사이트맵을 만드는 기능이 있다. 이것으로 체크가 가능할 것이다.
  • 유튜브에는 해당 채널에서 동영상의 목록을 가져올 수 있는 API가있다.
  • 텔레그램에서 API를 사용해서 메세지를 보낼 수 있다.

재료는 다 갖추어 졌다.

만들자!

워드프레스 – 코드

뭐든지 한꺼번에 만들면 힘들다. 일단은 워드프레스먼저 처리하도록하자.

돌아가는 방식은 이렇다

  • 사이트맵 방문
  • 수집하여 엑셀로 저장
  • 저장된 파일에서 마지막 날짜를 가져오고 비교

사실 저장부분은 필요없지만 따로 만들프로그램이 있어서 저렇게 만들었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def save_new_posts_to_excel(filename, sitemap_url):
    # 1. Fetch XML content from the provided sitemap URL
    response = requests.get(sitemap_url)
    xml_tree = ET.ElementTree(ET.fromstring(response.content))
 
    # Extract posts and last modification date
    posts = []
    for elem in xml_tree.findall(“{http://www.sitemaps.org/schemas/sitemap/0.9}url”):
        url = elem.find(“{http://www.sitemaps.org/schemas/sitemap/0.9}loc”).text
        lastmod_elem = elem.find(“{http://www.sitemaps.org/schemas/sitemap/0.9}lastmod”)
        lastmod = lastmod_elem.text if lastmod_elem is not None else “Unknown”
        posts.append({“url”: url, “lastmod”: lastmod})
 
    # Convert to DataFrame
    df_new_posts = pd.DataFrame(posts)
 
    # 2. Check if the directory exists based on the current working directory, if not create it
    directory_path = os.path.join(os.getcwd(), “results”“WordPress”)
    if not os.path.exists(directory_path):
        os.makedirs(directory_path)
 
    # Check if the file exists
    filepath = os.path.join(directory_path, f“{filename}.xlsx”)
    if os.path.exists(filepath):
        # Load the existing data
        df_existing = pd.read_excel(filepath)
 
        # Filter out new posts that already exist in the previous dataset based on URL
        df_new_posts = df_new_posts[~df_new_posts[‘url’].isin(df_existing[‘url’])]
 
        # Merge new posts with the existing ones
        df_final = pd.concat([df_new_posts, df_existing])
    else:
        df_final = df_new_posts
 
    # 3. Save to Excel
    df_final.to_excel(filepath, index=False)
 
    return f“Saved to {filepath}”
cs

접속해서 파일을 만들고 저장하는 코드이다. 문제는 사이트맵의 설정이 달라지면 작동을 안하는듯하다. 나는 그냥 주소+포스트ID로 사이트맵을 만들기로 통일을 해버렸다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def check_last_post_age(filename, days = 2):
    # 1. Create the file path
    directory_path = os.path.join(os.getcwd(), “results”“WordPress”)
    filepath = os.path.join(directory_path, f“{filename}.xlsx”)
 
    # 2. Check if the file exists
    if not os.path.exists(filepath):
        return False
 
    # 3. Load the data and find the latest lastmod date
    df = pd.read_excel(filepath)
    if ‘lastmod’ not in df.columns:
        return False
 
    # Filter out rows where lastmod is “Unknown” or NaN
    df = df[df[‘lastmod’!= “Unknown”]
    df.dropna(subset=[‘lastmod’], inplace=True)
 
    if df.empty:
        return True
 
    # Convert the ‘lastmod’ column to datetime and find the latest date
    df[‘lastmod’= pd.to_datetime(df[‘lastmod’])
    latest_date = df[‘lastmod’].max()
 
    # 4. Check if the latest date is more than 2 days ago
    two_days_ago = datetime.now(pytz.utc)  timedelta(days=days)
    if latest_date <= two_days_ago:
        return True
    else:
        return False
cs

파일을 확인해서 날짜를 비교하는 부분이다. 트루반환할때만 알람을 받을 목적이다.

유튜브 – 코드

단순하게 API로 재생목록을 받아와서 처리한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def fetch_youtube_videos(filename, channel_id, API_KEY):
    youtube = build(‘youtube’‘v3’, developerKey=API_KEY)
 
    directory_path = os.path.join(os.getcwd(), “results”“YouTube”)
    filepath = os.path.join(directory_path, f“{filename}.xlsx”)
 
    if not os.path.exists(directory_path):
        os.makedirs(directory_path)
 
    # 파일이 존재하는지 확인하고, 존재하면 최신 동영상 5개만 가져옴
    max_results = 5 if os.path.exists(filepath) else 50
 
    try:
        response = youtube.channels().list(part=‘contentDetails’, id=channel_id).execute()
 
        # Check if ‘items’ key exists in the response
        if ‘items’ not in response or not response[‘items’]:
            print(f“No data found for channel ID: {channel_id}”)
            return
 
        uploads_id = response[‘items’][0][‘contentDetails’][‘relatedPlaylists’][‘uploads’]
        video_list = []
        next_page_token = None
        while len(video_list) < max_results:
            response = youtube.playlistItems().list(
                playlistId=uploads_id, part=‘snippet’, maxResults=max_results, pageToken=next_page_token
            ).execute()
 
            for item in response[‘items’]:
                video = {
                    “title”: item[‘snippet’][‘title’],
                    “url”“https://www.youtube.com/watch?v=” + item[‘snippet’][‘resourceId’][‘videoId’],
                    “publishedAt”: item[‘snippet’][‘publishedAt’]
                }
                video_list.append(video)
 
            next_page_token = response.get(‘nextPageToken’)
            if not next_page_token:
                break
 
        df_new = pd.DataFrame(video_list)
 
        if os.path.exists(filepath):
            df_old = pd.read_excel(filepath)
            df_final = pd.concat([df_new, df_old]).drop_duplicates(subset=[‘url’], ignore_index=True)
        else:
            df_final = df_new
 
        df_final.to_excel(filepath, index=False)
        #print(f”Saved to {filepath}”)
 
    except HttpError as e:
        print(f“An HTTP error {e.resp.status} occurred: {e.content}”)
 
def check_last_video_age(filename, days = 2):
    # 1. Create the file path
    directory_path = os.path.join(os.getcwd(), “results”“YouTube”)
    filepath = os.path.join(directory_path, f“{filename}.xlsx”)
 
    # 2. Check if the file exists
    if not os.path.exists(filepath):
        return False
 
    # 3. Load the data and find the latest publishedAt date
    df = pd.read_excel(filepath)
    if ‘publishedAt’ not in df.columns:
        return False
 
    # Filter out rows where publishedAt is “Unknown” or NaN
    df = df[df[‘publishedAt’!= “Unknown”]
    df.dropna(subset=[‘publishedAt’], inplace=True)
 
    if df.empty:
        return True
 
    # Convert the ‘publishedAt’ column to datetime and find the latest date
    df[‘publishedAt’= pd.to_datetime(df[‘publishedAt’])
    latest_date = df[‘publishedAt’].max()
 
    # 4. Check if the latest date is more than 2 days ago
    two_days_ago = datetime.now(pytz.utc)  timedelta(days=days)
    if latest_date <= two_days_ago:
        return True
    else:
        return False
cs

최초 처음 접근하는 채널같은경우엔 재생목록 50개를 받아오고 이후부터는 5개만 재생목록을 받아온다. API에 제한이 있는데 얼마나 있는지를 잘 모르겠어서 줄였다.

메인 – 코드

실질적으로 컨트롤 해주는 부분이다.

일단 어디를 감시할건지를 정해놓는 엑셀파일부터 만들어 놓고. 여기서 데이터를 가져와서 돌리는 식이다.

노베이스 개발자 히코 워드프레스와 유튜브관리를 위한 일정관리 프로그램 만들기

대략 이런 형태이다 옆쪽에 며칠이 지나야 알람이 올지를 정해놓는 열이 있는데 짤렸다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import os
import pandas as pd
import pytz
from datetime import datetime
from w_main import save_new_posts_to_excel, check_last_post_age
from y_main import fetch_youtube_videos, check_last_video_age
from botTest import send_telegram_message
from openpyxl import load_workbook
 
# Load the data from Data.xlsx
data_df = pd.read_excel(“Data.xlsx”)
 
# Filter rows where Class is “W”
w_data_df = data_df[data_df[“Class”== “W”]
y_data_df = data_df[data_df[“Class”== “Y”]  # Filtering for YouTube
 
# API_KEY 시트의 A1 셀의 값을 가져옵니다.
wb = load_workbook(filename=“Data.xlsx”, read_only=True)
ws = wb[“API_KEY”]
API_KEY = ws.cell(row=1, column=1).value
wb.close()
 
def generate_message(filename, title, platform=“WordPress”):
    if platform == “WordPress”:
        directory_path = os.path.join(os.getcwd(), “results”“WordPress”)
    else:  # platform == “YouTube”
        directory_path = os.path.join(os.getcwd(), “results”“YouTube”)
 
    filepath = os.path.join(directory_path, f“{filename}.xlsx”)
    df = pd.read_excel(filepath)
 
    date_column = ‘lastmod’ if platform == “WordPress” else ‘publishedAt’
 
    if df[date_column].nunique() == 1 and (df[date_column].iloc[0== “Unknown” or pd.isna(df[date_column].iloc[0])):
        return f“{title} – 신규 글을 작성해주세요.”
 
    df[date_column] = pd.to_datetime(df[date_column])
    elapsed_days = (datetime.now(pytz.utc)  df[date_column].max()).days
    return f“{title} – 작성한지 {elapsed_days}일이 경과했습니다. 글을 작성해주세요.”
 
# Iterate over the filtered rows for WordPress
for _, row in w_data_df.iterrows():
    title = row[“Title”]
    address = row[“Address”]
    Alarm = row[“Alarm”]
 
    if Alarm == “”:
        Alarm = 2
 
    # Update the data
    filename = title
    print(f“Updating {title} for WordPress…”)
    save_new_posts_to_excel(filename, address)
 
    # Check the last post age
    check_result = check_last_post_age(filename, Alarm)
    if check_result:
        message = generate_message(filename, title)
        send_telegram_message(message)
        print(message)
 
# Iterate over the filtered rows for YouTube
for _, row in y_data_df.iterrows():
    title = row[“Title”]
    address = row[“Address”]
    Alarm = row[“Alarm”]
 
    if Alarm == “”:
        Alarm = 2
 
    # Update the data
    filename = title
    print(f“Updating {title} for YouTube…”)
    fetch_youtube_videos(filename, address, API_KEY)
 
    # Check the last video age
    check_result = check_last_video_age(filename, Alarm)
    if check_result:
        message = generate_message(filename, title, platform=“YouTube”)
        send_telegram_message(message)
        print(message)
 
cs

텔레그램 메세지받는 부분은 안올릴거다 검색해보면 봇 만드는거부터 자세하게나오니 그거보고 따라하는게 좋을듯하다.

결과물

노베이스 개발자 히코 워드프레스와 유튜브관리를 위한 일정관리 프로그램 만들기
노베이스 개발자 히코 워드프레스와 유튜브관리를 위한 일정관리 프로그램 만들기

아주 잘 작동해서 만족했다.

코드는 역시 GPT가 다 만들어주었다. 막히는 부분이있으면 GPT한테 물어보는게 빠를것!