aboutsummaryrefslogtreecommitdiffstats
path: root/cogs/web.py
blob: fcec8f9db8b92110eb6da680199093ad5e31776f (plain) (blame)
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
# This file is part of Senator Sperma
# Licensed under the GPL-3.0 License
# Copyright (C) 2026 Salmonik @ salmonik@tuta.io
# https://codeberg.org/salmonik/senator-sperma

import discord
from discord import Embed
from discord.ext import commands
import requests
from bs4 import BeautifulSoup
import urllib.parse
import pytube
import logging

logger = logging.getLogger(__name__)

class Web(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    def _extract_youtube_title(self, url):
        """Extract YouTube video title if URL is a YouTube link."""
        if not url.startswith('https://www.youtube.com/'):
            return None
            
        logger.info("youtube link")
        try:
            parsed_url = urllib.parse.urlparse(url)
            video_id = urllib.parse.parse_qs(parsed_url.query).get('v', [None])[0]
            if video_id:
                yt = pytube.YouTube(f'https://www.youtube.com/watch?v={video_id}')
                return yt.title
        except Exception:
            pass
        return None

    def _create_button(self, index, link):
        """Create a button for sending search result."""
        button = discord.ui.Button(label=f"Send Result {index}")
        
        async def button_callback(interaction: discord.Interaction):
            await interaction.response.send_message(link.get('href'))
        
        button.callback = button_callback
        return button

    def _process_search_results(self, links, query):
        """Process search results and create embed with buttons."""
        embed = Embed(title="Search Results", description=f"Top results for: {query}", color=0x1E90FF)
        view = discord.ui.View(disable_on_timeout=True)
        
        for i, link in enumerate(links[:5], start=1):
            title = link.text
            youtube_title = self._extract_youtube_title(link.get('href'))
            if youtube_title:
                title = youtube_title
                
            embed.add_field(name=f"Result {i}", value=f"[{title}]({link.get('href')})", inline=False)
            button = self._create_button(i, link)
            view.add_item(button)
            
        return embed, view

    @commands.slash_command(
        name="web",
        description="Search the web using DuckDuckGo"
    )
    async def web(
        self,
        ctx: discord.ApplicationContext,
        query: str
    ):
        await ctx.defer(ephemeral=True)
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
        encoded_query = urllib.parse.quote_plus(query)
        url = f"https://duckduckgo.com/html/?q={encoded_query}"
        response = requests.get(url, headers=headers)

        logger.info(f"Query: {query}")

        if response.status_code != 200:
            await ctx.respond(content=f"Error: {response.status_code}", ephemeral=True)
            logger.error(f"Error: {response.status_code}")
            return

        soup = BeautifulSoup(response.text, 'html.parser')
        links = soup.find_all('a', class_='result__a')
        
        if not links:
            await ctx.respond(content="No results found.", ephemeral=True)
            logger.warning("No results found")
            return

        embed, view = self._process_search_results(links, query)
        await ctx.respond(embed=embed, view=view, ephemeral=True)
        logger.info("Search results sent")

def setup(bot):
    bot.add_cog(Web(bot))