asd
This commit is contained in:
parent
8818d216a3
commit
ae3080b0de
@ -105,19 +105,121 @@ async def get_user_guilds(
|
|||||||
):
|
):
|
||||||
"""Get all guilds the user is an admin of."""
|
"""Get all guilds the user is an admin of."""
|
||||||
try:
|
try:
|
||||||
# This would normally fetch guilds from Discord API or the bot
|
# First, try to use the real implementation from api_server.py
|
||||||
# For now, we'll return a mock response
|
try:
|
||||||
# TODO: Replace mock data with actual API call to Discord
|
# Import the dashboard_get_user_guilds function from api_server
|
||||||
guilds = [
|
from api_service.api_server import dashboard_get_user_guilds
|
||||||
Guild(id="123456789", name="My Awesome Server", icon_url="https://cdn.discordapp.com/icons/123456789/abc123def456ghi789jkl012mno345pqr.png"),
|
|
||||||
Guild(id="987654321", name="Another Great Server", icon_url="https://cdn.discordapp.com/icons/987654321/zyx987wvu654tsr321qpo098mlk765jih.png")
|
# Call the function with the user
|
||||||
]
|
guilds_data = await dashboard_get_user_guilds(user)
|
||||||
return guilds
|
|
||||||
|
# Convert the data to Guild objects
|
||||||
|
guilds = []
|
||||||
|
for guild in guilds_data:
|
||||||
|
# Create icon URL if icon is available
|
||||||
|
icon_url = None
|
||||||
|
if guild.get('icon'):
|
||||||
|
icon_url = f"https://cdn.discordapp.com/icons/{guild['id']}/{guild['icon']}.png"
|
||||||
|
|
||||||
|
guilds.append(Guild(
|
||||||
|
id=guild['id'],
|
||||||
|
name=guild['name'],
|
||||||
|
icon_url=icon_url
|
||||||
|
))
|
||||||
|
|
||||||
|
log.info(f"Successfully fetched {len(guilds)} guilds for user {user.get('user_id')} using api_server implementation")
|
||||||
|
return guilds
|
||||||
|
|
||||||
|
except ImportError as e:
|
||||||
|
log.warning(f"Could not import dashboard_get_user_guilds from api_server: {e}")
|
||||||
|
# Fall back to direct implementation
|
||||||
|
except Exception as e:
|
||||||
|
log.warning(f"Error using dashboard_get_user_guilds from api_server: {e}")
|
||||||
|
# Fall back to direct implementation
|
||||||
|
|
||||||
|
# Direct implementation as fallback
|
||||||
|
from global_bot_accessor import get_bot_instance
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
|
# Check if settings_manager is available
|
||||||
|
bot = get_bot_instance()
|
||||||
|
if not bot or not bot.pg_pool:
|
||||||
|
log.warning("Bot instance or PostgreSQL pool not available for get_user_guilds")
|
||||||
|
# Fall back to mock data since we can't access the real data
|
||||||
|
log.info("Using mock data for user guilds as fallback")
|
||||||
|
return [
|
||||||
|
Guild(id="123456789", name="My Awesome Server (Mock)", icon_url=None),
|
||||||
|
Guild(id="987654321", name="Another Great Server (Mock)", icon_url=None)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Get Discord API URLs from environment or use defaults
|
||||||
|
DISCORD_API_URL = "https://discord.com/api/v10"
|
||||||
|
DISCORD_USER_GUILDS_URL = f"{DISCORD_API_URL}/users/@me/guilds"
|
||||||
|
|
||||||
|
# Get access token from user
|
||||||
|
access_token = user.get('access_token')
|
||||||
|
if not access_token:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Access token not found in user session"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create headers for Discord API request
|
||||||
|
user_headers = {'Authorization': f'Bearer {access_token}'}
|
||||||
|
|
||||||
|
# Create a temporary aiohttp session
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
# 1. Fetch guilds user is in from Discord
|
||||||
|
log.debug(f"Fetching user guilds from {DISCORD_USER_GUILDS_URL}")
|
||||||
|
async with session.get(DISCORD_USER_GUILDS_URL, headers=user_headers) as resp:
|
||||||
|
if resp.status == 401:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Discord API authentication failed. Please log in again."
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
user_guilds = await resp.json()
|
||||||
|
log.debug(f"Fetched {len(user_guilds)} guilds for user {user.get('user_id')}")
|
||||||
|
|
||||||
|
# 2. Get bot guilds from the bot instance
|
||||||
|
bot_guild_ids = set()
|
||||||
|
if bot.guilds:
|
||||||
|
bot_guild_ids = {guild.id for guild in bot.guilds}
|
||||||
|
log.debug(f"Bot is in {len(bot_guild_ids)} guilds")
|
||||||
|
else:
|
||||||
|
log.warning("Bot has no guilds or bot.guilds is not accessible")
|
||||||
|
|
||||||
|
# 3. Filter user guilds
|
||||||
|
manageable_guilds = []
|
||||||
|
ADMINISTRATOR_PERMISSION = 0x8
|
||||||
|
for guild in user_guilds:
|
||||||
|
guild_id = int(guild['id'])
|
||||||
|
permissions = int(guild['permissions'])
|
||||||
|
|
||||||
|
if (permissions & ADMINISTRATOR_PERMISSION) == ADMINISTRATOR_PERMISSION and guild_id in bot_guild_ids:
|
||||||
|
# Create icon URL if icon is available
|
||||||
|
icon_url = None
|
||||||
|
if guild.get('icon'):
|
||||||
|
icon_url = f"https://cdn.discordapp.com/icons/{guild['id']}/{guild['icon']}.png"
|
||||||
|
|
||||||
|
manageable_guilds.append(Guild(
|
||||||
|
id=guild['id'],
|
||||||
|
name=guild['name'],
|
||||||
|
icon_url=icon_url
|
||||||
|
))
|
||||||
|
|
||||||
|
log.info(f"Found {len(manageable_guilds)} manageable guilds for user {user.get('user_id')}")
|
||||||
|
return manageable_guilds
|
||||||
|
|
||||||
|
except HTTPException:
|
||||||
|
# Re-raise HTTP exceptions
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(f"Error getting user guilds: {e}")
|
log.error(f"Error getting user guilds: {e}")
|
||||||
|
# Return a more user-friendly error message
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
detail=f"Error getting user guilds: {str(e)}"
|
detail="Failed to retrieve your Discord servers. Please try again later."
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.get("/guilds/{guild_id}/channels", response_model=List[Channel])
|
@router.get("/guilds/{guild_id}/channels", response_model=List[Channel])
|
||||||
|
@ -467,7 +467,7 @@ function loadUserGuilds() {
|
|||||||
serverListContainer.innerHTML = ''; // Clear loading state
|
serverListContainer.innerHTML = ''; // Clear loading state
|
||||||
|
|
||||||
if (!guilds || guilds.length === 0) {
|
if (!guilds || guilds.length === 0) {
|
||||||
serverListContainer.innerHTML = '<p>No servers found where you have admin permissions.</p>';
|
serverListContainer.innerHTML = '<div class="alert alert-info">No servers found where you have admin permissions.</div>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,18 +477,64 @@ function loadUserGuilds() {
|
|||||||
guildElement.style.cursor = 'pointer';
|
guildElement.style.cursor = 'pointer';
|
||||||
guildElement.dataset.guildId = guild.id;
|
guildElement.dataset.guildId = guild.id;
|
||||||
|
|
||||||
const iconElement = document.createElement('img');
|
// Check if we have an icon URL
|
||||||
iconElement.className = 'server-icon';
|
if (guild.icon_url) {
|
||||||
iconElement.src = guild.icon_url || 'img/default-icon.png'; // Provide a default icon path
|
// Create an image element for the server icon
|
||||||
iconElement.alt = `${guild.name} icon`;
|
const iconElement = document.createElement('img');
|
||||||
iconElement.width = 50;
|
iconElement.className = 'server-icon';
|
||||||
iconElement.height = 50;
|
iconElement.src = guild.icon_url;
|
||||||
|
iconElement.alt = `${guild.name} icon`;
|
||||||
|
iconElement.width = 50;
|
||||||
|
iconElement.height = 50;
|
||||||
|
|
||||||
|
// Add error handling for icon loading
|
||||||
|
iconElement.onerror = function() {
|
||||||
|
console.log(`Failed to load icon for server ${guild.name}, using text fallback`);
|
||||||
|
// Replace the img with a text-based fallback
|
||||||
|
const fallbackIcon = createTextFallbackIcon(guild.name);
|
||||||
|
this.parentNode.replaceChild(fallbackIcon, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
guildElement.appendChild(iconElement);
|
||||||
|
} else {
|
||||||
|
// No icon URL provided, use text-based fallback immediately
|
||||||
|
const fallbackIcon = createTextFallbackIcon(guild.name);
|
||||||
|
guildElement.appendChild(fallbackIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to create a text-based fallback icon
|
||||||
|
function createTextFallbackIcon(serverName) {
|
||||||
|
const fallbackDiv = document.createElement('div');
|
||||||
|
fallbackDiv.className = 'server-icon-fallback';
|
||||||
|
fallbackDiv.style.width = '50px';
|
||||||
|
fallbackDiv.style.height = '50px';
|
||||||
|
fallbackDiv.style.backgroundColor = '#5865F2'; // Discord blue
|
||||||
|
fallbackDiv.style.borderRadius = '50%';
|
||||||
|
fallbackDiv.style.display = 'flex';
|
||||||
|
fallbackDiv.style.alignItems = 'center';
|
||||||
|
fallbackDiv.style.justifyContent = 'center';
|
||||||
|
fallbackDiv.style.color = 'white';
|
||||||
|
fallbackDiv.style.fontWeight = 'bold';
|
||||||
|
fallbackDiv.style.fontSize = '18px';
|
||||||
|
|
||||||
|
// Get the first letter of each word in the server name
|
||||||
|
const initials = serverName
|
||||||
|
.split(' ')
|
||||||
|
.map(word => word.charAt(0))
|
||||||
|
.join('')
|
||||||
|
.substring(0, 2)
|
||||||
|
.toUpperCase();
|
||||||
|
|
||||||
|
fallbackDiv.textContent = initials;
|
||||||
|
|
||||||
|
return fallbackDiv;
|
||||||
|
}
|
||||||
|
|
||||||
const nameElement = document.createElement('span');
|
const nameElement = document.createElement('span');
|
||||||
nameElement.className = 'server-name';
|
nameElement.className = 'server-name';
|
||||||
nameElement.textContent = guild.name;
|
nameElement.textContent = guild.name;
|
||||||
|
|
||||||
guildElement.appendChild(iconElement);
|
// Icon is already appended in the icon creation logic above
|
||||||
guildElement.appendChild(nameElement);
|
guildElement.appendChild(nameElement);
|
||||||
|
|
||||||
guildElement.addEventListener('click', () => {
|
guildElement.addEventListener('click', () => {
|
||||||
@ -514,8 +560,33 @@ function loadUserGuilds() {
|
|||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Error loading user guilds:', error);
|
console.error('Error loading user guilds:', error);
|
||||||
serverListContainer.innerHTML = '<p class="text-danger">Error loading servers. Please try again.</p>';
|
|
||||||
Toast.error('Failed to load your servers.');
|
// Create a more detailed error message with troubleshooting steps
|
||||||
|
let errorMessage = '<div class="alert alert-danger">';
|
||||||
|
errorMessage += '<h4>Error Loading Servers</h4>';
|
||||||
|
errorMessage += '<p>We encountered a problem while trying to load your servers. This could be due to:</p>';
|
||||||
|
errorMessage += '<ul>';
|
||||||
|
errorMessage += '<li>Database connection issues</li>';
|
||||||
|
errorMessage += '<li>Discord API rate limiting</li>';
|
||||||
|
errorMessage += '<li>Missing bot configuration</li>';
|
||||||
|
errorMessage += '</ul>';
|
||||||
|
errorMessage += '<p>Troubleshooting steps:</p>';
|
||||||
|
errorMessage += '<ol>';
|
||||||
|
errorMessage += '<li>Refresh the page and try again</li>';
|
||||||
|
errorMessage += '<li>Check that the bot is properly configured with database access</li>';
|
||||||
|
errorMessage += '<li>Ensure the Discord bot token is properly set</li>';
|
||||||
|
errorMessage += '</ol>';
|
||||||
|
errorMessage += '<button id="retry-load-guilds" class="btn btn-primary">Retry</button>';
|
||||||
|
errorMessage += '</div>';
|
||||||
|
|
||||||
|
serverListContainer.innerHTML = errorMessage;
|
||||||
|
|
||||||
|
// Add event listener to the retry button
|
||||||
|
document.getElementById('retry-load-guilds').addEventListener('click', () => {
|
||||||
|
loadUserGuilds(); // Retry loading guilds
|
||||||
|
});
|
||||||
|
|
||||||
|
Toast.error('Failed to load your servers. See details on screen.');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user