Spaces:
Running
Running
File size: 5,410 Bytes
6216e00 90f246e 6216e00 90f246e 6216e00 90f246e 6216e00 |
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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
from nc_py_api import Nextcloud
import json
from typing import Dict, List
import os
import time
from datetime import datetime
import threading
import arena_config
import re
# Initialize Nextcloud client
nc = Nextcloud(
nextcloud_url=arena_config.NEXTCLOUD_URL,
nc_auth_user=arena_config.NEXTCLOUD_USERNAME,
nc_auth_pass=arena_config.NEXTCLOUD_PASSWORD
)
SUGGESTIONS_FILE = "model_suggestions.json"
NEXTCLOUD_SUGGESTIONS_PATH = "/gpu_poor_model_suggestions.json"
def validate_model_url(url: str) -> bool:
"""Validate if the provided URL matches the expected HuggingFace format."""
pattern = r'^hf\.co/[\w-]+/[\w\.-]+(?:-GGUF)?:Q[0-9]+(?:_[A-Z0-9_]+)?$'
return bool(re.match(pattern, url))
def load_suggestions() -> Dict:
"""Load suggestions from Nextcloud, fallback to local file, or initialize if neither exists."""
suggestions = None
# First try to load from Nextcloud
try:
remote_data = nc.files.download(NEXTCLOUD_SUGGESTIONS_PATH)
if remote_data:
suggestions = json.loads(remote_data.decode('utf-8'))
# Update local file with Nextcloud data
with open(SUGGESTIONS_FILE, 'w') as f:
json.dump(suggestions, f, indent=2)
return suggestions
except Exception as e:
print(f"Could not load from Nextcloud: {e}")
# If Nextcloud fails, try local file
if os.path.exists(SUGGESTIONS_FILE):
try:
with open(SUGGESTIONS_FILE, 'r') as f:
suggestions = json.load(f)
return suggestions
except Exception as e:
print(f"Could not load from local file: {e}")
# If both fail, initialize new suggestions
suggestions = {
"suggestions": {},
"last_updated": datetime.now().isoformat()
}
# Save the new suggestions to both local and Nextcloud
save_suggestions(suggestions)
return suggestions
def save_suggestions(suggestions: Dict) -> None:
"""Save suggestions to both local file and Nextcloud."""
with open(SUGGESTIONS_FILE, 'w') as f:
json.dump(suggestions, f, indent=2)
# Upload to Nextcloud
try:
nc.files.upload(
NEXTCLOUD_SUGGESTIONS_PATH,
json.dumps(suggestions, indent=2).encode('utf-8')
)
except Exception as e:
print(f"Error uploading to Nextcloud: {e}")
def add_suggestion(model_url: str) -> str:
"""Add a new model suggestion or update existing one."""
if not validate_model_url(model_url):
return "β Invalid model URL format. Please use the format: hf.co/username/model-name-GGUF:Q4_K_M"
suggestions = load_suggestions()
if model_url in suggestions["suggestions"]:
suggestions["suggestions"][model_url]["count"] += 1
suggestions["suggestions"][model_url]["last_suggested"] = datetime.now().isoformat()
message = f"β¨ Model suggestion updated! This model has been suggested {suggestions['suggestions'][model_url]['count']} times."
else:
suggestions["suggestions"][model_url] = {
"count": 1,
"first_suggested": datetime.now().isoformat(),
"last_suggested": datetime.now().isoformat()
}
message = "β
New model suggestion recorded successfully!"
suggestions["last_updated"] = datetime.now().isoformat()
save_suggestions(suggestions)
return message
def get_suggestions_html() -> str:
"""Generate HTML table of model suggestions."""
suggestions = load_suggestions()
# Sort suggestions by count (descending)
sorted_suggestions = sorted(
suggestions["suggestions"].items(),
key=lambda x: x[1]["count"],
reverse=True
)
html = """
<style>
.suggestions-table {
width: 100%;
border-collapse: collapse;
font-family: Arial, sans-serif;
}
.suggestions-table th, .suggestions-table td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
.suggestions-table th {
background-color: rgba(255, 255, 255, 0.1);
font-weight: bold;
}
.rank-column {
width: 60px;
text-align: center;
}
.count-badge {
background-color: rgba(34, 87, 122, 0.7);
color: white;
padding: 4px 8px;
border-radius: 12px;
font-size: 0.9em;
}
.description-column {
font-size: 0.9em;
color: #888;
}
</style>
<table class='suggestions-table'>
<tr>
<th class='rank-column'>Rank</th>
<th>Model URL</th>
<th>Suggestions</th>
<th>First Suggested</th>
<th>Last Suggested</th>
</tr>
"""
for index, (model_url, data) in enumerate(sorted_suggestions, start=1):
rank_display = {1: "π₯", 2: "π₯", 3: "π₯"}.get(index, f"{index}")
html += f"""
<tr>
<td class='rank-column'>{rank_display}</td>
<td>{model_url}</td>
<td><span class="count-badge">{data['count']}</span></td>
<td>{data['first_suggested'].split('T')[0]}</td>
<td>{data['last_suggested'].split('T')[0]}</td>
</tr>
"""
html += "</table>"
return html |