mark task as complete unfinsihed

This commit is contained in:
Tenzing Kandang 2026-04-01 19:13:42 +02:00
parent cffb440809
commit 5e2ff7a859
8 changed files with 75 additions and 31 deletions

2
.gitignore vendored
View File

@ -4,4 +4,4 @@
/dvenv
copy.txt
user_location.db
/utils/.env
/bot/.env

Binary file not shown.

40
bot/task.py Normal file
View File

@ -0,0 +1,40 @@
import asyncio, json, datetime, discord
from discord.ui import View, Select
class TaskSelect(Select):
def __init__(self, options):
super().__init__(placeholder="Choose a task to complete...",
min_values=1, max_values=1, options=options)
async def callback(self, interaction: discord.Interaction):
payload = json.loads(self.values[0])
tasklist_id = payload["tasklist_id"]
task_id = payload["task_id"]
await interaction.response.defer(thinking=True)
try:
service = build_tasks_service()
task = await asyncio.to_thread(lambda:
service.tasks().get(tasklist=tasklist_id, task=task_id).execute())
if not task:
await interaction.followup.send("Task not found.", ephemeral=True)
return
now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
body = dict(task)
body["status"] = "completed"
body["completed"] = now
updated = await asyncio.to_thread(lambda: service.tasks().update(tasklist=tasklist_id, task=task_id, body=body).execute())
if updated.get("status") == "completed":
await interaction.followup.send("Failed to mark completed.", ephemeral=True)
except Exception as e:
await interaction.followup.send(f"Error: {e}", ephemeral=True)
class TasksView(View):
def __init__(self, options, timeout=120):
super().__init__(timeout=timeout)
self.add_item(TaskSelect(options))

64
main.py
View File

@ -1,14 +1,15 @@
import os
import discord
import datetime
import discord, asyncio, json, datetime, os
from google_auth_oauthlib.flow import InstalledAppFlow
from utils.weather import OpenWeatherMapAPIClient
from bot.weather import OpenWeatherMapAPIClient
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from discord.ext import commands
from dotenv import load_dotenv
from utils.database import UserLocation
from bot.database import UserLocation
from asyncio import to_thread
from discord import app_commands
from discord.ui import View, Select
from bot.task import TaskSelect, TasksView
load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
@ -61,14 +62,16 @@ async def authenticate():
with open(TOKEN_FILE, 'w') as f:
f.write(credentials.to_json())
print(f"Saved credentials to {TOKEN_FILE} for instant access")
@bot.tree.command(name="daily_tasks", description="Check today's saved tasks")
@bot.tree.command(name="daily_tasks", description="Check today's saved tasks and complete them")
async def today(interaction: discord.Interaction):
await interaction.response.defer(thinking=True)
print(f'Recieved daily_tasks command by {interaction.user.display_name}')
try:
service = build_tasks_service()
tl_res = service.tasklists().list(maxResults=100).execute()
tl_res = await asyncio.to_thread(lambda: service.tasklists().list(maxResults=100).execute())
lists = tl_res.get("items", []) or []
today = datetime.datetime.now(tz=TZ).date()
@ -79,15 +82,16 @@ async def today(interaction: discord.Interaction):
timestamp=datetime.datetime.now(tz=TZ)
)
options = []
added = 0
for tl in lists:
tl_id = tl.get("id")
tl_title = tl.get("title") or "<untitled>"
tasks_res = service.tasks().list(
tasklist=tl_id, showCompleted=True, showHidden=True, maxResults=250).execute() or {}
tasks_res = await asyncio.to_thread(lambda: service.tasks().list(
tasklist=tl_id, showCompleted=True, showHidden=True, maxResults=250).execute() or {})
items = tasks_res.get("items", []) or []
lines = []
for t in items:
if not isinstance(t, dict):
@ -96,35 +100,26 @@ async def today(interaction: discord.Interaction):
due_date = parse_rfc3339_to_local_date(t.get("due"))
completed_date = parse_rfc3339_to_local_date(t.get("completed"))
print("title:", t.get("title"), "due:", t.get("due"), "completed:", t.get("completed"), "status:", t.get("status"))
if due_date != today and completed_date != today:
continue
status = "" if t.get("status") == "completed" else "🔲"
t_id = t.get("id")
title = t.get("title") or "(no title)"
if completed_date == today and t.get("completed"):
completed_short = t["completed"].replace("T", " ").split(".")[0]
lines.append(f"{status} {title} - completed {completed_short}")
else:
if due_date:
lines.append(f"{status} {title} (due {due_date.isoformat()})")
else:
lines.append(f"{status}{title}")
if not lines:
continue
embed.add_field(name=f"{tl_title} - {status} {title}", value=f"ID: {t.get('id')}", inline=False)
value = "\n".join(lines)[:1024]
embed.add_field(name=tl_title, value=value, inline=False)
value = json.dumps({"tasklist_id": tl_id, "task_id": t.get("id")})
options.append(discord.SelectOption(label=(title[:90] or "(no title)"), description=tl_title[:50], value=value))
added += 1
if added == 0:
embed.description = "No tasks due today."
await interaction.followup.send(embed=embed)
return
options = options[:25]
view = TasksView(options, interaction.user.id)
await interaction.followup.send(embed=embed, view=view)
except Exception as e:
await interaction.followup.send(f"An error occured:{e}")
@ -134,6 +129,7 @@ async def today(interaction: discord.Interaction):
async def events(interaction: discord.Interaction):
await interaction.response.defer(thinking=True)
print(f'Recieved weekly_events command by {interaction.user.display_name}')
try:
service = build_calendar_service()
except FileNotFoundError:
@ -246,13 +242,21 @@ async def on_ready():
print(f'Logged in as {bot.user}')
await authenticate()
await bot.tree.sync()
#Liste commandes enregistré
commands = await bot.tree.fetch_commands()
print("Registered Commands:")
for command in commands:
print(f"- {command.name}")
print("- !set_location")
channel = bot.get_channel(1480922508566990879)
if channel:
embed = discord.Embed(
description="Bot is now online and ready to serve! Type / to check available commands"
)
await channel.send(embed=embed)
print("your bot is online and ready to serve !")
bot.run(DISCORD_TOKEN)