From a8001ec19dad58e41c4da2e038e9b0ddf6c51fa9 Mon Sep 17 00:00:00 2001 From: Polish Hammer Date: Fri, 2 May 2025 19:01:51 +0200 Subject: [PATCH] new function --- .../radio_conjurer.etc.logrotate | 9 +++ file_search_commqnds.py | 76 +++++++++++++++++++ file_search_functions.py | 51 +++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 conjurer_musician/radio_conjurer.etc.logrotate create mode 100644 file_search_commqnds.py create mode 100644 file_search_functions.py diff --git a/conjurer_musician/radio_conjurer.etc.logrotate b/conjurer_musician/radio_conjurer.etc.logrotate new file mode 100644 index 0000000..ea879af --- /dev/null +++ b/conjurer_musician/radio_conjurer.etc.logrotate @@ -0,0 +1,9 @@ +/home/pi/Conjurer/radio_log.log { + daily + rotate 7 + compress + delaycompress + missingok + notifempty + copytruncate +} diff --git a/file_search_commqnds.py b/file_search_commqnds.py new file mode 100644 index 0000000..0f09bc7 --- /dev/null +++ b/file_search_commqnds.py @@ -0,0 +1,76 @@ +import os +import discord +from discord.ext import commands +import file_search_functions + +class FileSelectView(discord.ui.View): + def __init__(self, files): + super().__init__(timeout=60) + # Create select options for each file + options = [discord.SelectOption(label=os.path.basename(f)[:100], description=f, value=f) for f in files] + self.select = discord.ui.Select( + placeholder="Select files...", + min_values=1, + max_values=len(options), + options=options + ) + self.select.callback = self.select_callback + self.add_item(self.select) + self.selected = [] + + async def select_callback(self, interaction: discord.Interaction): + # Store selected file paths + self.selected = self.select.values + await interaction.response.defer() + + @discord.ui.button(label="Accept", style=discord.ButtonStyle.green) + async def accept_callback(self, button: discord.ui.Button, interaction: discord.Interaction): + # Handle acceptance + if not self.selected: + await interaction.response.send_message("No files selected.", ephemeral=True) + return + # Publish selected files + links = file_search_functions.publish(self.selected) + # Display the returned links + await interaction.response.edit_message(content="Published Links:\n" + "\n".join(links), view=None) + + @discord.ui.button(label="Cancel", style=discord.ButtonStyle.red) + async def cancel_callback(self, button: discord.ui.Button, interaction: discord.Interaction): + # Handle cancellation + await interaction.response.edit_message(content="Operation cancelled.", view=None) + +class FileSearchCog(commands.Cog): + """Cog providing a file search and publish command.""" + + def __init__(self, bot: commands.Bot): + self.bot = bot + + @commands.command(name="findfiles") + async def findfiles(self, ctx: commands.Context, entries: int, *, keywords: str): + """ + Search for files matching keywords and publish selected ones. + + Usage: !findfiles + """ + # Validate entries + if entries < 1 or entries > 10: + await ctx.send("❌ Entries must be between 1 and 10.") + return + # Parse keywords + keyword_list = keywords.split() + # Find matching files + files = file_search_functions.find_matches(entries, keyword_list) + if not files: + await ctx.send("🔍 No matching files found.") + return + # Send a message with a selection UI + view = FileSelectView(files) + file_list = "\n".join(f"{i+1}. {f}" for i, f in enumerate(files)) + await ctx.send( + f"🔍 Found files (select and click Accept or Cancel):\n{file_list}", + view=view + ) + +async def setup(bot: commands.Bot): + """Load the FileSearchCog.""" + await bot.add_cog(FileSearchCog(bot)) diff --git a/file_search_functions.py b/file_search_functions.py new file mode 100644 index 0000000..bf03954 --- /dev/null +++ b/file_search_functions.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +import argparse +import json +import os +import sys +import uuid +from pathlib import Path + +# CONFIGURATION +JSON_DB = '/var/log/share_scan.json' +SHARE_DIR = Path('/var/www/html/share') +BASE_URL = 'https://czernobog.pl/share' + +# Ensure share directory exists +SHARE_DIR.mkdir(parents=True, exist_ok=True) + +def load_db(): + with open(JSON_DB) as f: + return json.load(f)['entries'] + +ENTRIES = load_db() + +def relevancy(path, keywords): + score = 0 + low = path.lower() + for kw in keywords: + if kw.lower() in low: + score += low.count(kw.lower()) + return score + +def find_matches(count, keywords): + scored = [] + for e in ENTRIES: + score = relevancy(e['path'], keywords) + if score > 0: + scored.append((score, e['path'])) + scored.sort(reverse=True, key=lambda x: x[0]) + result = [p for _, p in scored] + return result[:count] + +def publish(paths): + urls = [] + for path in paths: + token = uuid.uuid4().hex + link = SHARE_DIR / token + try: + os.symlink(path, link) + except FileExistsError: + pass + urls.append(f"{BASE_URL}/{token}") + return urls