diff --git a/cogs/gem.py b/cogs/gem.py index 2d7e9491e25e104ec5184bd8a3b30ddbe9030006..3ee2078df8e87589b347fbd985379827bfa588fa 100644 --- a/cogs/gem.py +++ b/cogs/gem.py @@ -1,46 +1,43 @@ import discord from discord.ext import commands -import asyncio -import configparser +from dotenv import load_dotenv import requests import logging -config = configparser.ConfigParser() -config.read('config.ini') -GEMINI_API_KEY = config['GOOGLE']['GEMINI_API_KEY'] +GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") class GemCog(commands.Cog): def __init__(self, bot): self.bot = bot - @commands.hybrid_command(name="gem", description="Ask a question to Gemini Pro") - async def ask_gemini_slash(self, ctx, question: str): - try: - headers = {'Authorization': f'Bearer {GEMINI_API_KEY}'} - response = requests.post( - 'https://api.gemini.com/v1/completions', - headers=headers, - json={'prompt': question} - ) - response.raise_for_status() - data = response.json() + @commands.hybrid_command(name="gem", description="Ask a question to Gemini Pro") + async def ask_gemini_slash(self, ctx, question: str): + try: + headers = {'Authorization': f'Bearer {GEMINI_API_KEY}'} + response = requests.post( + 'https://api.gemini.com/v1/completions', + headers=headers, + json={'prompt': question} + ) + response.raise_for_status() + data = response.json() - if 'choices' in data and len(data['choices']) > 0: - answer = data['choices'][0]['text'] - embed = discord.Embed( - title="Gem says:", description=answer) - await ctx.send(embed=embed) - else: - logging.error( - "The API response format for Gemini Pro has changed, Unable to extract response.") - await ctx.send("Unexpected response from gem <:SatisfiedCheems:1230175084912840734>") - except requests.exceptions.RequestException as e: - logging.error(f"404 from gem: {e}") - await ctx.send("An error returned while trying to communicate with Gemini Pro, Try again.") - except Exception as e: - logging.error(f"Random error in 'gem' command: {e}") - await ctx.send("Gem is not working at the moment.") + if 'choices' in data and len(data['choices']) > 0: + answer = data['choices'][0]['text'] + embed = discord.Embed(title="Gem says:", description=answer) + await ctx.send(embed=embed) + else: + logging.error( + "The API response format for Gemini Pro has changed, Unable to extract response.") + await ctx.send("Unexpected response from gem <:SatisfiedCheems:1230175084912840734>") + except requests.exceptions.RequestException as e: # Moved except block out of the if/else + logging.error(f"Error communicating with Gemini API: {e}") + await ctx.send("An error occurred while communicating with Gemini Pro. Try again.") + except Exception as e: # Moved except block out of the if/else + logging.error(f"Random error in 'gem' command: {e}") + await ctx.send("Gem is not working at the moment.") - async def setup(bot): - await bot.add_cog(GemCog(bot)) + +async def setup(bot): + await bot.add_cog(GemCog(bot)) diff --git a/cogs/imagesearch.py b/cogs/imagesearch.py index 6854563e44adcb01fb6af55bdb939f377999c259..38b0ef7997c75d8cbf5fd76148afbbeee22d8b0f 100644 --- a/cogs/imagesearch.py +++ b/cogs/imagesearch.py @@ -1,13 +1,12 @@ +import discord from discord.ext import commands +from dotenv import load_dotenv from google_images_search import GoogleImagesSearch import logging import asyncio - -config = configparser.ConfigParser() -config.read('config.ini') -GCS_DEVELOPER_KEY = config['GOOGLE']['GCS_DEVELOPER_KEY'] -GCS_CX = config['GOOGLE']['GCS_CX'] +GCS_DEVELOPER_KEY = os.getenv("GCS_DEVELOPER_KEY") +GCS_CX = os.getenv("GCS_CX") class ImageCog(commands.Cog): @@ -23,7 +22,7 @@ class ImageCog(commands.Cog): 'num': 5, 'safe': 'off', } - self.gis.async_search(search_params=_search_params) + await self.gis.async_search(search_params=_search_params) if not self.gis.results(): await ctx.send("No images found for your search.") @@ -38,11 +37,11 @@ class ImageCog(commands.Cog): embed.set_image(url=self.gis.results()[current_page].url) return embed - message = await ctx.send(embed=embed) - await message.add_reaction('⬅ï¸') - await message.add_reaction('âž¡ï¸') + message = await ctx.send(embed=create_embed()) + await message.add_reaction('⬅ï¸') + await message.add_reaction('âž¡ï¸') - def check(reaction, user): + def check(reaction, user): return user == ctx.author and str(reaction.emoji) in ['⬅ï¸', 'âž¡ï¸'] and reaction.message == message while True: @@ -53,77 +52,6 @@ class ImageCog(commands.Cog): current_page -= 1 elif str(reaction.emoji) == 'âž¡ï¸' and current_page < total_pages: current_page += 1 - embed.set_image(url=self.gis.results() - [current_page * 5].url) - embed.title = f"Results for '{ - query}' ({current_page+1}/{total_pages+1})" - await message.edit(embed=embed) - await message.remove_reaction(reaction, ctx.author) - - except asyncio.TimeoutError: - await message.clear_reactions() - break - except Exception as e: - logging.error(f"Error during image search: {e}") - await ctx.send("An error occured while searching for '{query}'.") - - async def setup(bot): - await bot.add_cog(ImageCog(bot)) -import discord -from discord.ext import commands -from google_images_search import GoogleImagesSearch -import logging -import asyncio - - -config = configparser.ConfigParser() -config.read('config.ini') -GCS_DEVELOPER_KEY = config['GOOGLE']['GCS_DEVELOPER_KEY'] -GCS_CX = config['GOOGLE']['GCS_CX'] - - -class ImageCog(commands.Cog): - def __init__(self, bot): - self.bot = bot - self.gis = GoogleImagesSearch(GCS_DEVELOPER_KEY, GCS_CX) - - @commands.hybrid_command(name='image', description="Search for images from Google.") - async def search_image(self, ctx, *, query): - try: - _search_params = { - 'q': query, - 'num': 5, - 'safe': 'off', - } - self.gis.async_search(search_params=_search_params) - - if not self.gis.results(): - await ctx.send("No images found for your search.") - return - - current_page = 0 - total_pages = (len(self.gis.results()) - 1) // 5 - - def create_embed(): - embed = discord.Embed(title=f"Image search Results for '{query}' ({current_page+1}/{total_pages+1})") - embed.set_image(url=self.gis.results()[current_page].url) - return embed - - message = await ctx.send(embed=embed) - await message.add_reaction('⬅ï¸') - await message.add_reaction('âž¡ï¸') - - def check(reaction, user): - return user == ctx.author and str(reaction.emoji) in ['⬅ï¸', 'âž¡ï¸'] and - - while True: - try: - reaction, _ = await self.bot.wait_for('reaction_add', timeout=60.0, check=check) - - if str(reaction.emoji) == '⬅ï¸' and current_page > 0: - current_page -= 1 - elif str(reaction.emoji) == 'âž¡ï¸' and current_page < total_pages: - current_page += 1 await message.edit(embed=create_embed()) await message.remove_reaction(reaction, ctx.author) @@ -131,9 +59,11 @@ class ImageCog(commands.Cog): except asyncio.TimeoutError: await message.clear_reactions() break - except Exception as e: - logging.error(f"Error during image search: {e}") - await ctx.send("An error occured while searching for '{query}'.") - async def setup(bot): - await bot.add_cog(ImageCog(bot)) + except Exception as e: + logging.error(f"Error during image search: {e}") + await ctx.send(f"An error occurred while searching for '{query}'.") + + +async def setup(bot): + await bot.add_cog(ImageCog(bot)) diff --git a/cogs/todo.md b/cogs/todo.md index 381556843cbd313bf473e6fb9c1ff1b854386321..0b8cc699111dc341f70af72d56d3c94ec46565e4 100644 --- a/cogs/todo.md +++ b/cogs/todo.md @@ -4,7 +4,7 @@ - [x] Gem -- [ ] websearch -- [ ] imagesearch -- [x] videosearch -- [ ] embedcreat +- [X] websearch +- [X] imagesearch +- [X] videosearch +- [ ] embedcreate diff --git a/cogs/video.py b/cogs/video.py index 5a8e898b7a8136e96f493e996ef37e5438bc8f8e..ab6292afb7dc54be970d8d68c5bda5edcfe2330d 100644 --- a/cogs/video.py +++ b/cogs/video.py @@ -1,5 +1,75 @@ +import discord from discord.ext import commands -import requests +from dotenv import load_dotenv +from googleapiclient.discovery import build import asyncio import logging +YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY") + + +class VideoCog(commands.Cog): + def __init__(self, bot): + self.bot = bot + self.youtube = build('youtube', 'v3', developerKey=YOUTUBE_API_KEY) + + @commands.hybrid_command(name='video', description="search youtube videos.") + async def search_video(self, ctx, *, query): + try: + request = self.youtube.search().list( + part="snippet", + maxResults=10, + q=query, + type='video' + ) + response = request.execute() + + if not response['items']: + await ctx.send("No videos found for your query.") + return + + current_page = 0 + total_pages = len(response['items']) - 1 + + def create_embed(): + item = response['items'][current_page] + video_id = item['id']['videoId'] + video_url = f"https://www.youtube.com/watch?v={video_id}" + embed = discord.Embed( + title=item['snippet']['title'], url=video_url) + embed.set_image(url=item['snippet'] + ['thumbnails']['high']['url']) + embed.set_footer( + text=f"Page {current_page+1} of {total_pages+1}") + return embed + + message = await ctx.send(embed=create_embed()) + await message.add_reaction('⬅ï¸') + await message.add_reaction('âž¡ï¸') + + def check(reaction, user): + return user == ctx.author and str(reaction.emoji) in ['⬅ï¸', 'âž¡ï¸'] and reaction.message == message + + while True: + try: + reaction, _ = await self.bot.wait_for('reaction_add', timeout=60.0, check=check) + + if str(reaction.emoji) == '⬅ï¸' and current_page > 0: + current_page -= 1 + elif str(reaction.emoji) == 'âž¡ï¸' and current_page < total_pages: + current_page += 1 + + await message.edit(embed=create_embed()) + await message.remove_reaction(reaction, ctx.author) + + except asyncio.TimeoutError: + await message.clear_reactions() + break + + except Exception as e: + logging.error(f"Error during video search: {e}") + await ctx.send("An error occurred while searching for videos.") + + +async def setup(bot): + await bot.add_cog(VideoCog(bot)) diff --git a/cogs/web.py b/cogs/web.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..11917babe712d78e77b65459c810f49a823dc041 100644 --- a/cogs/web.py +++ b/cogs/web.py @@ -0,0 +1,78 @@ +import discord +from discord.ext import commands +from dotenv import load_dotenv +import requests +import logging +import asyncio + + +GCS_DEVELOPER_KEY = os.getenv("GCS_DEVELOPER_KEY") +GCS_CX = os.getenv("GCS_CX") + + +class WebSearchCog(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @commands.hybrid_command(name='search', description="Search google") + async def search_web(self, ctx, *, query): + try: + search_params = { + 'q': query, + 'cx': GCS_CX, + 'key': GCS_DEVELOPER_KEY, + 'num': 10, + } + response = requests.get( + "https://www.googleapis.com/customsearch/v1", params=search_params) + response.raise_for_status() + data = response.json() + + if 'items' not in data: + await ctx.send("No results found for your search") + return + + current_page = 0 + total_pages = len(data['items']) - 1 + + def create_embed(): + item = data['items'][current_page] + embed = discord.Embed( + title=item['title'], url=item['link'], description=item['snippet']) + embed.set_footer( + text=f"Page {current_page+1} of {total_pages+1}") + return embed + + message = await ctx.send(embed=create_embed()) + await message.add_reaction('⬅ï¸') + await message.add_reaction('âž¡ï¸') + + def check(reaction, user): + return user == ctx.author and str(reaction.emoji) in ['⬅ï¸', 'âž¡ï¸'] and reaction.message == message + + while True: + try: + reaction, _ = await self.bot.wait_for('reaction_add', timeout=60.0, check=check) + + if str(reaction.emoji) == '⬅ï¸' and current_page > 0: + current_page -= 1 + elif str(reaction.emoji) == 'âž¡ï¸' and current_page < total_pages: + current_page += 1 + + await message.edit(embed=create_embed()) + await message.remove_reaction(reaction, ctx.author) + + except asyncio.TimeoutError: + await message.clear_reactions() + break + + except requests.exceptions.RequestException as e: + logging.error(f"Error during web search: {e}") + await ctx.send("An error occurred while searching the web.") + except Exception as e: + logging.error(f"Unexpected error in web search: {e}") + await ctx.send("An unexpected error occurred.") + + +async def setup(bot): + await bot.add_cog(WebSearchCog(bot)) diff --git a/main.py b/main.py index ccf7fc735f3b05594900dcd9e9f8ffae54d7ee9a..5d3461369c4298361d876dc075ce38ed035bb5f8 100644 --- a/main.py +++ b/main.py @@ -1,191 +1,70 @@ import discord from discord.ext import commands +import os import asyncio -import configparser import logging -import requests -from google_images_search import GoogleImagesSearch -from googleapiclient.discovery import build -from googleapiclient import errors -# Logging configuration +from logging.handlers import RotatingFileHandler +from discord.ext.commands import errors +from dotenv import load_dotenv + +load_dotenv() + logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') -# Configuration -config = configparser.ConfigParser() -config.read('config.ini') -# Discord config -TOKEN = config['DISCORD']['TOKEN'] -ROLE_ID = int(config['DISCORD']['ROLE_ID']) -LOG_CHANNEL_ID = int(config['DISCORD']['LOG_CHANNEL_ID']) -WELCOME_CHANNEL_ID = int(config['DISCORD']['WELCOME_CHANNEL_ID']) -ROLE_DURATION_SECONDS = 604800 -# Google Images Search config -GCS_DEVELOPER_KEY = config['GOOGLE']['GCS_DEVELOPER_KEY'] -GCS_CX = config['GOOGLE']['GCS_CX'] -YOUTUBE_API_KEY = config['GOOGLE']['YOUTUBE_API_KEY'] -GEMINI_API_KEY = config['GOOGLE']['GEMINI_API_KEY'] -# Discord bot setup + intents = discord.Intents.default() intents.members = True intents.message_content = True bot = commands.Bot(command_prefix='!', intents=intents) -gis = GoogleImagesSearch(GCS_DEVELOPER_KEY, GCS_CX) -youtube = build('youtube', 'v3', developerKey=YOUTUBE_API_KEY) - -# New member join event - - -@bot.event -async def on_member_join(member): - try: - logging.info(f"New member joined: {member.name} (ID: {member.id})") - - role = discord.utils.get(member.guild.roles, id=ROLE_ID) - if role is None: - raise ValueError(f"Role with ID {ROLE_ID} not found.") - - logging.info(f"Assigning role '{role.name}' to {member.name}") - await member.add_roles(role) - - welcome_channel = bot.get_channel(WELCOME_CHANNEL_ID) - if welcome_channel: - logging.info(f"Sending welcome message to #{welcome_channel.name}") - await welcome_channel.send( - f"aha ! <:rizzhotsexy:1195895549199663275> , { - member.mention} Looks like you been given the <@&{ROLE_ID}> Role, for 7 days !" - ) - else: - logging.error( - f"Welcome channel (ID: {WELCOME_CHANNEL_ID}) not found.") - - log_channel = bot.get_channel(LOG_CHANNEL_ID) - if log_channel: - logging.info(f"Sending log message to #{log_channel.name}") - await log_channel.send( - f"User {member.mention} (ID: { - member.id}) has been assigned the \"New Victim\" role for 7 days." - ) - else: - logging.error(f"Log channel (ID: {LOG_CHANNEL_ID}) not found.") - - logging.info(f"Waiting for {ROLE_DURATION_SECONDS} seconds...") - await asyncio.sleep(ROLE_DURATION_SECONDS) - - logging.info(f"Removing role '{role.name}' from {member.name}") - await member.remove_roles(role) - - except discord.Forbidden as e: - logging.error(f"Forbidden error: {e} (Missing permissions?)") - except ValueError as ve: - logging.error(ve) - except Exception as e: - logging.error(f"Unexpected error: {e}") - - -@bot.command(name='search') -async def search_web(ctx, *, query): - try: - # Perform the search - search_params = { - 'q': query, - 'cx': GCS_CX, # Use your Custom Search Engine ID - 'key': GCS_DEVELOPER_KEY, - 'num': 1, # Get top 3 results - } - response = requests.get("https://www.googleapis.com/customsearch/v1", params=search_params) - response.raise_for_status() # Raise an exception for bad responses - data = response.json() - - # Check if results were found - if 'items' not in data: - raise ValueError("No results found for your query.") - - # Format and send results - for item in data['items']: - await ctx.send(f"**{item['title']}**\n{item['link']}\n{item['snippet']}\n") - - except requests.exceptions.RequestException as e: - logging.error(f"Error during web search: {e}") - await ctx.send("An error occurred while searching the web.") - except ValueError as ve: - logging.error(f"Error during web search: {ve}") - await ctx.send(str(ve)) - except Exception as e: - logging.error(f"Error during web search: {e}") - await ctx.send("An error occurred while searching the web.") - -@bot.command(name='video') -async def search_video(ctx, *, query): - try: - # Search for videos - request = youtube.search().list( - part="snippet", - maxResults=1, - q=query, - type='video' - ) - response = request.execute() - - # Check if results were found - if not response['items']: - raise ValueError("No videos found for your query.") - - # Extract and send video URL - video_id = response['items'][0]['id']['videoId'] - video_url = f"https://www.youtube.com/watch?v={video_id}" - await ctx.send(video_url) - - except ValueError as ve: - logging.error(f"Error during video search: {ve}") - await ctx.send(str(ve)) - except Exception as e: - logging.error(f"Error during video search: {e}") - await ctx.send("An error occurred while searching for videos.") - - - -class EmbedModal(discord.ui.Modal, title='Create Embed'): - title = discord.ui.TextInput(label='Embed Title', style=discord.TextStyle.short, required=True) - description = discord.ui.TextInput(label='Description', style=discord.TextStyle.paragraph, required=True) - color = discord.ui.TextInput(label='Color (hex or name)', style=discord.TextStyle.short, required=False) - thumbnail = discord.ui.TextInput(label='Thumbnail URL', style=discord.TextStyle.short, required=False) - image = discord.ui.TextInput(label='Image URL', style=discord.TextStyle.short, required=False) - author_name = discord.ui.TextInput(label='Author Name', style=discord.TextStyle.short, required=False) - author_icon = discord.ui.TextInput(label='Author Icon URL', style=discord.TextStyle.short, required=False) - footer_text = discord.ui.TextInput(label='Footer Text', style=discord.TextStyle.short, required=False) - footer_icon = discord.ui.TextInput(label='Footer Icon URL', style=discord.TextStyle.short, required=False) - - async def on_submit(self, interaction: discord.Interaction): - embed = discord.Embed(title=self.title.value, description=self.description.value) - if self.color.value: +logger = logging.getLogger('discord') +logger.setLevel(logging.INFO) +handler = RotatingFileHandler( + filename='bot.log', + encoding='utf-8', + maxBytes=32 * 1024 * 1024, + backupCount=5 +) +dt_fmt = '%Y-%m-%d %H:%M:%S' +formatter = logging.Formatter( + '[{asctime}] [{levelname:<8}] {name}: {message}', dt_fmt, style='{') +handler.setFormatter(formatter) +logger.addHandler(handler) + +TOKEN = os.getenv("DISCORD_BOT_TOKEN") +MESSAGE_CHANNEL_ID = int(os.getenv("MESSAGE_CHANNEL_ID")) + +async def load_cogs(): + for filename in os.listdir("./cogs"): + if filename.endswith(".py"): try: - embed.color = discord.Color.from_str(self.color.value) - except ValueError: - pass # Use default color - if self.thumbnail.value: - embed.set_thumbnail(url=self.thumbnail.value) - if self.image.value: - embed.set_image(url=self.image.value) - if self.author_name.value or self.author_icon.value: - embed.set_author(name=self.author_name.value, icon_url=self.author_icon.value) - if self.footer_text.value or self.footer_icon.value: - embed.set_footer(text=self.footer_text.value, icon_url=self.footer_icon.value) + await bot.load_extension(f"cogs.{filename[:-3]}") + logging.info(f"Loaded cog: {filename[:-3]}") + except (errors.ExtensionNotFound, errors.ExtensionFailed) as e: + logging.error(f"Failed to load cog '{filename[:-3]}': {e}") - await interaction.response.send_message(embed=embed, ephemeral=True) +@bot.event +async def on_ready(): + await load_cogs() + await bot.tree.sync() + logging.info(f'Logged in as {bot.user.name} (ID: {bot.user.id})') + channel = bot.get_channel(MESSAGE_CHANNEL_ID) + if channel: + await channel.send("mamahuevooo") + else: + logging.error(f"Channel is not found (ID: {MESSAGE_CHANNEL_ID})") -@bot.slash_command(description="Create a custom embed") -async def create_embed(ctx): - """Slash command to trigger the embed creation modal.""" - if not ctx.author.guild_permissions.manage_messages: # Permissions check - await ctx.respond("You don't have permission to use this command.", ephemeral=True) - return - await ctx.send_modal(EmbedModal()) +@bot.event +async def on_command_error(ctx, error): + if isinstance(error, commands.MissingPermissions): + await ctx.send("You have no perms to use this command.") + else: + logging.error(f"An error occurred: {error}") + await ctx.send("An error occurred while processing this command...") bot.run(TOKEN) - diff --git a/pyhub/bin/Activate.ps1 b/pyhub/bin/Activate.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..b49d77ba44b24fe6d69f6bbe75139b3b5dc23075 --- /dev/null +++ b/pyhub/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/pyhub/bin/activate b/pyhub/bin/activate new file mode 100644 index 0000000000000000000000000000000000000000..af038af7595247763d3057fdc2a1a51fd9ed9426 --- /dev/null +++ b/pyhub/bin/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath "/home/tay/Git/pyhub/pyhub") +else + # use the path as-is + export VIRTUAL_ENV="/home/tay/Git/pyhub/pyhub" +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(pyhub) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(pyhub) " + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/pyhub/bin/activate.csh b/pyhub/bin/activate.csh new file mode 100644 index 0000000000000000000000000000000000000000..a1fb09205189a62c75098df9ba3b83ae7d9469ef --- /dev/null +++ b/pyhub/bin/activate.csh @@ -0,0 +1,27 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. + +# Created by Davide Di Blasi <davidedb@gmail.com>. +# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com> + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/home/tay/Git/pyhub/pyhub" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(pyhub) $prompt" + setenv VIRTUAL_ENV_PROMPT "(pyhub) " +endif + +alias pydoc python -m pydoc + +rehash diff --git a/pyhub/bin/activate.fish b/pyhub/bin/activate.fish new file mode 100644 index 0000000000000000000000000000000000000000..beb58daf248b7696513d761c8472d0d05becea1c --- /dev/null +++ b/pyhub/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source <venv>/bin/activate.fish" *from fish* +# (https://fishshell.com/). You cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/tay/Git/pyhub/pyhub" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) "(pyhub) " (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT "(pyhub) " +end diff --git a/pyhub/bin/dotenv b/pyhub/bin/dotenv new file mode 100755 index 0000000000000000000000000000000000000000..ae9d01e70ab517c2d56906eb6800c45110003ada --- /dev/null +++ b/pyhub/bin/dotenv @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from dotenv.__main__ import cli +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli()) diff --git a/pyhub/bin/get_gprof b/pyhub/bin/get_gprof new file mode 100755 index 0000000000000000000000000000000000000000..4debe2124aa13eb4406bcd7a93ca03cf41c81c49 --- /dev/null +++ b/pyhub/bin/get_gprof @@ -0,0 +1,75 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# +# Author: Mike McKerns (mmckerns @caltech and @uqfoundation) +# Copyright (c) 2008-2016 California Institute of Technology. +# Copyright (c) 2016-2024 The Uncertainty Quantification Foundation. +# License: 3-clause BSD. The full license text is available at: +# - https://github.com/uqfoundation/dill/blob/master/LICENSE +''' +build profile graph for the given instance + +running: + $ get_gprof <args> <instance> + +executes: + gprof2dot -f pstats <args> <type>.prof | dot -Tpng -o <type>.call.png + +where: + <args> are arguments for gprof2dot, such as "-n 5 -e 5" + <instance> is code to create the instance to profile + <type> is the class of the instance (i.e. type(instance)) + +For example: + $ get_gprof -n 5 -e 1 "import numpy; numpy.array([1,2])" + +will create 'ndarray.call.png' with the profile graph for numpy.array([1,2]), +where '-n 5' eliminates nodes below 5% threshold, similarly '-e 1' eliminates +edges below 1% threshold +''' + +if __name__ == "__main__": + import sys + if len(sys.argv) < 2: + print ("Please provide an object instance (e.g. 'import math; math.pi')") + sys.exit() + # grab args for gprof2dot + args = sys.argv[1:-1] + args = ' '.join(args) + # last arg builds the object + obj = sys.argv[-1] + obj = obj.split(';') + # multi-line prep for generating an instance + for line in obj[:-1]: + exec(line) + # one-line generation of an instance + try: + obj = eval(obj[-1]) + except Exception: + print ("Error processing object instance") + sys.exit() + + # get object 'name' + objtype = type(obj) + name = getattr(objtype, '__name__', getattr(objtype, '__class__', objtype)) + + # profile dumping an object + import dill + import os + import cProfile + #name = os.path.splitext(os.path.basename(__file__))[0] + cProfile.run("dill.dumps(obj)", filename="%s.prof" % name) + msg = "gprof2dot -f pstats %s %s.prof | dot -Tpng -o %s.call.png" % (args, name, name) + try: + res = os.system(msg) + except Exception: + print ("Please verify install of 'gprof2dot' to view profile graphs") + if res: + print ("Please verify install of 'gprof2dot' to view profile graphs") + + # get stats + f_prof = "%s.prof" % name + import pstats + stats = pstats.Stats(f_prof, stream=sys.stdout) + stats.strip_dirs().sort_stats('cumtime') + stats.print_stats(20) #XXX: save to file instead of print top 20? + os.remove(f_prof) diff --git a/pyhub/bin/get_objgraph b/pyhub/bin/get_objgraph new file mode 100755 index 0000000000000000000000000000000000000000..f01f9655acac61cfd4972150f08c5e600805e565 --- /dev/null +++ b/pyhub/bin/get_objgraph @@ -0,0 +1,54 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# +# Author: Mike McKerns (mmckerns @caltech and @uqfoundation) +# Copyright (c) 2008-2016 California Institute of Technology. +# Copyright (c) 2016-2024 The Uncertainty Quantification Foundation. +# License: 3-clause BSD. The full license text is available at: +# - https://github.com/uqfoundation/dill/blob/master/LICENSE +""" +display the reference paths for objects in ``dill.types`` or a .pkl file + +Notes: + the generated image is useful in showing the pointer references in + objects that are or can be pickled. Any object in ``dill.objects`` + listed in ``dill.load_types(picklable=True, unpicklable=True)`` works. + +Examples:: + + $ get_objgraph ArrayType + Image generated as ArrayType.png +""" + +import dill as pickle +#pickle.debug.trace(True) +#import pickle + +# get all objects for testing +from dill import load_types +load_types(pickleable=True,unpickleable=True) +from dill import objects + +if __name__ == "__main__": + import sys + if len(sys.argv) != 2: + print ("Please provide exactly one file or type name (e.g. 'IntType')") + msg = "\n" + for objtype in list(objects.keys())[:40]: + msg += objtype + ', ' + print (msg + "...") + else: + objtype = str(sys.argv[-1]) + try: + obj = objects[objtype] + except KeyError: + obj = pickle.load(open(objtype,'rb')) + import os + objtype = os.path.splitext(objtype)[0] + try: + import objgraph + objgraph.show_refs(obj, filename=objtype+'.png') + except ImportError: + print ("Please install 'objgraph' to view object graphs") + + +# EOF diff --git a/pyhub/bin/gimages b/pyhub/bin/gimages new file mode 100755 index 0000000000000000000000000000000000000000..1f7fcbdacdc79cfcc0c10c3ce97e9cd42bee9d14 --- /dev/null +++ b/pyhub/bin/gimages @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from google_images_search.cli import cli +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli()) diff --git a/pyhub/bin/isort b/pyhub/bin/isort new file mode 100755 index 0000000000000000000000000000000000000000..1636719dc33a389a6a9007b3d3f622c7eb07823b --- /dev/null +++ b/pyhub/bin/isort @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from isort.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/pyhub/bin/isort-identify-imports b/pyhub/bin/isort-identify-imports new file mode 100755 index 0000000000000000000000000000000000000000..e047fdcd7ea73afd2eb7eaf7f402fea23c658ff1 --- /dev/null +++ b/pyhub/bin/isort-identify-imports @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from isort.main import identify_imports_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(identify_imports_main()) diff --git a/pyhub/bin/normalizer b/pyhub/bin/normalizer new file mode 100755 index 0000000000000000000000000000000000000000..ff7a3ddbd9a8a182231b22d407baea7a65c1ce1b --- /dev/null +++ b/pyhub/bin/normalizer @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from charset_normalizer.cli import cli_detect +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli_detect()) diff --git a/pyhub/bin/pip b/pyhub/bin/pip new file mode 100755 index 0000000000000000000000000000000000000000..69b5072c011639c113985199ebbe75c69a36d158 --- /dev/null +++ b/pyhub/bin/pip @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/pyhub/bin/pip3 b/pyhub/bin/pip3 new file mode 100755 index 0000000000000000000000000000000000000000..69b5072c011639c113985199ebbe75c69a36d158 --- /dev/null +++ b/pyhub/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/pyhub/bin/pip3.12 b/pyhub/bin/pip3.12 new file mode 100755 index 0000000000000000000000000000000000000000..69b5072c011639c113985199ebbe75c69a36d158 --- /dev/null +++ b/pyhub/bin/pip3.12 @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/pyhub/bin/pyfiglet b/pyhub/bin/pyfiglet new file mode 100755 index 0000000000000000000000000000000000000000..cb55496e98a8d59eef20f75cbe8ece18fb9106ba --- /dev/null +++ b/pyhub/bin/pyfiglet @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pyfiglet import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/pyhub/bin/pylint b/pyhub/bin/pylint new file mode 100755 index 0000000000000000000000000000000000000000..84010f0357284120e61535ded4d547170a9689e4 --- /dev/null +++ b/pyhub/bin/pylint @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pylint import run_pylint +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run_pylint()) diff --git a/pyhub/bin/pylint-config b/pyhub/bin/pylint-config new file mode 100755 index 0000000000000000000000000000000000000000..f5923d6dd17125097b8d6e818d61b6b39f6a4348 --- /dev/null +++ b/pyhub/bin/pylint-config @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pylint import _run_pylint_config +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(_run_pylint_config()) diff --git a/pyhub/bin/pyreverse b/pyhub/bin/pyreverse new file mode 100755 index 0000000000000000000000000000000000000000..4f4bcb530ad055ad5513e8014440f0f2a4689ff7 --- /dev/null +++ b/pyhub/bin/pyreverse @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pylint import run_pyreverse +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run_pyreverse()) diff --git a/pyhub/bin/pyrsa-decrypt b/pyhub/bin/pyrsa-decrypt new file mode 100755 index 0000000000000000000000000000000000000000..cfe19b043fc8690b6056cde4ba45436ab250ffa3 --- /dev/null +++ b/pyhub/bin/pyrsa-decrypt @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import decrypt +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(decrypt()) diff --git a/pyhub/bin/pyrsa-encrypt b/pyhub/bin/pyrsa-encrypt new file mode 100755 index 0000000000000000000000000000000000000000..1fc41af570a7ebc64b6716b381db23754b11b6b2 --- /dev/null +++ b/pyhub/bin/pyrsa-encrypt @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import encrypt +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(encrypt()) diff --git a/pyhub/bin/pyrsa-keygen b/pyhub/bin/pyrsa-keygen new file mode 100755 index 0000000000000000000000000000000000000000..a46e381b8561374958293daabc61bc9ed7807281 --- /dev/null +++ b/pyhub/bin/pyrsa-keygen @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import keygen +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(keygen()) diff --git a/pyhub/bin/pyrsa-priv2pub b/pyhub/bin/pyrsa-priv2pub new file mode 100755 index 0000000000000000000000000000000000000000..399f87ffda082d9fb8433f82ff8d63cbe3b96bd6 --- /dev/null +++ b/pyhub/bin/pyrsa-priv2pub @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.util import private_to_public +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(private_to_public()) diff --git a/pyhub/bin/pyrsa-sign b/pyhub/bin/pyrsa-sign new file mode 100755 index 0000000000000000000000000000000000000000..80494c93b58b3d2a91da1d6743b0eace153b4967 --- /dev/null +++ b/pyhub/bin/pyrsa-sign @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import sign +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(sign()) diff --git a/pyhub/bin/pyrsa-verify b/pyhub/bin/pyrsa-verify new file mode 100755 index 0000000000000000000000000000000000000000..2595b6173a1e69ef4c5a0037d9979f5f7eb2d775 --- /dev/null +++ b/pyhub/bin/pyrsa-verify @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import verify +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(verify()) diff --git a/pyhub/bin/python b/pyhub/bin/python new file mode 120000 index 0000000000000000000000000000000000000000..b8a0adbbb97ea11f36eb0c6b2a3c2881e96f8e26 --- /dev/null +++ b/pyhub/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/pyhub/bin/python3 b/pyhub/bin/python3 new file mode 120000 index 0000000000000000000000000000000000000000..ae65fdaa12936b0d7525b090d198249fa7623e66 --- /dev/null +++ b/pyhub/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/pyhub/bin/python3.12 b/pyhub/bin/python3.12 new file mode 120000 index 0000000000000000000000000000000000000000..b8a0adbbb97ea11f36eb0c6b2a3c2881e96f8e26 --- /dev/null +++ b/pyhub/bin/python3.12 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/pyhub/bin/symilar b/pyhub/bin/symilar new file mode 100755 index 0000000000000000000000000000000000000000..64092be67fd2894813f215691f7c621477166a4c --- /dev/null +++ b/pyhub/bin/symilar @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pylint import run_symilar +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run_symilar()) diff --git a/pyhub/bin/undill b/pyhub/bin/undill new file mode 100755 index 0000000000000000000000000000000000000000..3ae46440a15efcefee64fbcb386e5786f88962f8 --- /dev/null +++ b/pyhub/bin/undill @@ -0,0 +1,22 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# +# Author: Mike McKerns (mmckerns @caltech and @uqfoundation) +# Copyright (c) 2008-2016 California Institute of Technology. +# Copyright (c) 2016-2024 The Uncertainty Quantification Foundation. +# License: 3-clause BSD. The full license text is available at: +# - https://github.com/uqfoundation/dill/blob/master/LICENSE +""" +unpickle the contents of a pickled object file + +Examples:: + + $ undill hello.pkl + ['hello', 'world'] +""" + +if __name__ == '__main__': + import sys + import dill + for file in sys.argv[1:]: + print (dill.load(open(file,'rb'))) + diff --git a/pyhub/bin/wsdump b/pyhub/bin/wsdump new file mode 100755 index 0000000000000000000000000000000000000000..cac93d955f0041ffa8f85fd27bb9dab31841d962 --- /dev/null +++ b/pyhub/bin/wsdump @@ -0,0 +1,8 @@ +#!/home/tay/Git/pyhub/pyhub/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from websocket._wsdump import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/pyhub/lib64 b/pyhub/lib64 new file mode 120000 index 0000000000000000000000000000000000000000..7951405f85a569efbacc12fccfee529ef1866602 --- /dev/null +++ b/pyhub/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/pyhub/pyvenv.cfg b/pyhub/pyvenv.cfg new file mode 100644 index 0000000000000000000000000000000000000000..80220d6a11100c91d24f4e19ee16ecea5c127ee1 --- /dev/null +++ b/pyhub/pyvenv.cfg @@ -0,0 +1,5 @@ +home = /usr/bin +include-system-site-packages = false +version = 3.12.3 +executable = /usr/bin/python3.12 +command = /usr/bin/python3 -m venv /home/tay/Git/pyhub/pyhub diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..dd518731b5f0fee5bafa84633c78c2d2a3428577 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,50 @@ +aiohttp==3.9.5 +aiosignal==1.3.1 +astroid==3.2.2 +attrs==23.2.0 +cachetools==5.3.3 +certifi==2024.2.2 +charset-normalizer==3.3.2 +click==8.1.7 +colorama==0.4.6 +configparser==7.0.0 +dill==0.3.8 +discord.py==2.3.2 +frozenlist==1.4.1 +google-api-core==2.19.0 +google-api-python-client==2.48.0 +google-auth==2.29.0 +google-auth-httplib2==0.2.0 +Google-Images-Search==1.4.6 +googleapis-common-protos==1.63.0 +httplib2==0.22.0 +idna==3.7 +isort==5.13.2 +mccabe==0.7.0 +multidict==6.0.5 +oauthlib==3.2.2 +pillow==10.3.0 +platformdirs==4.2.2 +praw==7.7.1 +prawcore==2.4.0 +proto-plus==1.23.0 +protobuf==4.25.3 +pyasn1==0.6.0 +pyasn1_modules==0.4.0 +pyfiglet==0.8.post1 +pylint==3.2.2 +pyparsing==3.1.2 +python-dotenv==1.0.1 +python-resize-image==1.1.20 +requests==2.32.3 +requests-oauthlib==1.3.1 +rsa==4.9 +six==1.16.0 +termcolor==1.1.0 +tomlkit==0.12.5 +tweepy==4.14.0 +update-checker==0.18.0 +uritemplate==4.1.1 +urllib3==2.2.1 +websocket-client==1.8.0 +yarl==1.9.4