File size: 5,666 Bytes
3f5d6f1
 
 
 
 
 
 
 
 
f43c139
3f5d6f1
 
 
 
 
 
f43c139
3f5d6f1
 
 
 
 
f43c139
 
 
 
08dc6f3
 
 
 
 
 
 
f43c139
3f5d6f1
e5139a2
3f5d6f1
f43c139
 
 
 
 
 
 
 
3f5d6f1
 
 
 
f43c139
0e9d266
 
 
 
f43c139
0e9d266
3f5d6f1
3eedb43
f43c139
 
 
 
 
3f5d6f1
 
0e9d266
 
f43c139
3f5d6f1
f43c139
3f5d6f1
3eedb43
f43c139
 
 
3eedb43
f43c139
 
3eedb43
f43c139
 
3eedb43
3f5d6f1
3eedb43
3f5d6f1
f43c139
 
 
3f5d6f1
f43c139
 
3eedb43
f43c139
 
 
 
 
 
3eedb43
 
3f5d6f1
3eedb43
f43c139
 
 
 
3f5d6f1
3eedb43
 
 
 
 
 
f43c139
 
3f5d6f1
3eedb43
f43c139
 
 
3eedb43
 
 
f43c139
3eedb43
 
f43c139
 
 
 
 
 
3eedb43
3f5d6f1
f43c139
 
 
 
3eedb43
f43c139
 
3eedb43
 
 
 
 
 
3f5d6f1
 
3eedb43
f43c139
 
 
3eedb43
f43c139
3eedb43
f43c139
 
 
 
 
 
 
 
 
 
 
 
 
3eedb43
f43c139
 
 
 
 
 
 
 
 
3eedb43
 
f43c139
3f5d6f1
 
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import os
import requests
import random
import threading
import time
import schedule
import tweepy
import gradio as gr

# Secrets from HF Space environment
HF_TOKEN = os.environ['HF_TOKEN']
CONSUMER_KEY = os.environ['CONSUMER_KEY']
CONSUMER_SECRET = os.environ['CONSUMER_SECRET']
ACCESS_TOKEN = os.environ['ACCESS_TOKEN']
ACCESS_SECRET = os.environ['ACCESS_SECRET']

# LLM API setup
API_URL = "https://router.huggingface.co/v1/chat/completions"
headers = {
    "Authorization": f"Bearer {HF_TOKEN}",
}

def query(payload):
    response = requests.post(API_URL, headers=headers, json=payload)
    return response.json()

 # Topics for posts
topics = [
    "GeoAI as a field and it's application",
    "application of Geology with Tech for exploration",
    "application of AI in geological exploration",
    "Entrepreneurship"
]
# Function to generate a high-quality post using LLM
def generate_post(topic=None):
    if topic is None or topic == "Random":
        topic = random.choice(topics)
    prompt = f"Generate a high-quality, educational, and informative X (Twitter) post under 280 characters showcasing expertise in {topic}. Make it engaging, insightful, and professional. Include relevant hashtags and hashtags shouldn't be more than 2 or not even at all in some post also avoid using - in the post so it looks natural."
    response = query({
        "messages": [{"role": "user", "content": prompt}],
        "model": "deepseek-ai/DeepSeek-V3.2:novita",
        "max_tokens": 200,
        "temperature": 0.8
    })
    post_content = response["choices"][0]["message"]["content"].strip()
    if len(post_content) > 280:
        post_content = post_content[:277] + "..."
    return post_content

# Tweepy v2 Client setup
client = tweepy.Client(
    consumer_key=CONSUMER_KEY,
    consumer_secret=CONSUMER_SECRET,
    access_token=ACCESS_TOKEN,
    access_token_secret=ACCESS_SECRET
)

# Global queue and scheduler state
post_queue = []
scheduler_running = False
scheduler_thread = None

# Function to post to X
def post_to_x(content):
    try:
        response = client.create_tweet(text=content)
        tweet_id = response.data['id']
        return f"Posted! https://x.com/user/status/{tweet_id}"
    except Exception as e:
        return f"Error: {str(e)}"

# Scheduler job β€” posts one item from queue
def scheduled_post_job():
    global post_queue
    if post_queue:
        content = post_queue.pop(0)  # FIFO: first in, first out
        result = post_to_x(content)
        print(f"[Scheduler] {result}\nContent: {content}")
        return result, "\n\n".join(post_queue) if post_queue else "Queue is empty."
    else:
        print("[Scheduler] Queue is empty.")
        return "No post scheduled β€” queue is empty.", "Queue is empty."

# Background scheduler loop
def run_scheduler():
    global scheduler_running
    schedule.every(2).hours.do(scheduled_post_job)
    while scheduler_running:
        schedule.run_pending()
        time.sleep(30)

# Start scheduler
def start_scheduler():
    global scheduler_running, scheduler_thread
    if not scheduler_running:
        scheduler_running = True
        scheduler_thread = threading.Thread(target=run_scheduler, daemon=True)
        scheduler_thread.start()
        return "Scheduler started! Posts every 2 hours from the queue."
    return "Scheduler is already running."

# Stop scheduler
def stop_scheduler():
    global scheduler_running
    scheduler_running = False
    return "Scheduler stopped."

# Clear queue function
def clear_queue():
    global post_queue
    post_queue.clear()
    return "Queue cleared.", "Queue is empty."

# Gradio functions
def generate_new_post(topic):
    content = generate_post(topic)
    return content, gr.update(visible=True)

def add_to_queue(content):
    global post_queue
    stripped = content.strip()
    if stripped and stripped not in post_queue:
        post_queue.append(stripped)
    return (
        "",  # Clear the current post box
        gr.update(visible=False),  # Hide Add button
        "\n\n".join(post_queue) if post_queue else "Queue is empty."
    )

# Gradio Interface
with gr.Blocks(title="X Post Generator & Scheduler") as demo:
    gr.Markdown("# AI/Tech/Startups X Post Generator & Queue Scheduler")
    gr.Markdown("Generate β†’ Review β†’ Add to queue β†’ Start scheduler for automated 2-hour posting.")

    with gr.Row():
        topic_input = gr.Dropdown(choices=["Random"] + topics, value="Random", label="Topic")
        generate_btn = gr.Button("Generate New Post")

    current_post = gr.Textbox(label="Generated Post (Review before adding)", lines=6, interactive=False)
    add_btn = gr.Button("βž• Add to Queue", visible=False)

    queue_display = gr.Textbox(
        label="Post Queue (will be posted in order, every 2 hours)",
        value="Queue is empty.",
        lines=12,
        interactive=False
    )

    with gr.Row():
        start_btn = gr.Button("Start Scheduler")
        stop_btn = gr.Button("Stop Scheduler")
        clear_queue_btn = gr.Button("Clear Queue")

    status_box = gr.Textbox(label="Status", value="Ready", interactive=False)

    # Event bindings
    generate_btn.click(
        generate_new_post,
        inputs=topic_input,
        outputs=[current_post, add_btn]
    )

    add_btn.click(
        add_to_queue,
        inputs=current_post,
        outputs=[current_post, add_btn, queue_display]
    )

    start_btn.click(
        start_scheduler,
        outputs=status_box
    )

    stop_btn.click(
        stop_scheduler,
        outputs=status_box
    )

    clear_queue_btn.click(
        clear_queue,
        outputs=[status_box, queue_display]
    )

demo.launch()