Spaces:
Running
Running
File size: 6,409 Bytes
6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 90f246e baac06c 90f246e baac06c 90f246e baac06c 90f246e baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 baac06c 6216e00 dcde71a 6216e00 dcde71a 6216e00 baac06c dcde71a 6216e00 baac06c 6216e00 dcde71a 6216e00 dcde71a 6216e00 dcde71a 6216e00 dcde71a 6216e00 baac06c dcde71a 6216e00 dcde71a 6216e00 dcde71a 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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
from nc_py_api import Nextcloud
import json
from typing import Dict
from datetime import datetime
import os
import re
import config
# Initialize Nextcloud client
nc = Nextcloud(
nextcloud_url=config.NEXTCLOUD_URL,
nc_auth_user=config.NEXTCLOUD_USERNAME,
nc_auth_pass=config.NEXTCLOUD_PASSWORD
)
def validate_model_url(url: str) -> bool:
"""
Validate if the provided URL matches the expected format.
Accepts both direct Ollama models and HuggingFace GGUF models.
"""
# Pattern for HuggingFace GGUF models
hf_pattern = r'^hf\.co/[\w-]+/[\w\.-]+(?:-GGUF)?:Q[0-9]+(?:_[A-Z0-9_]+)?$'
# Pattern for direct Ollama models
ollama_pattern = r'^[\w\.-]+(?::\d+(?:\.\d+)?[b])?(?:-[\w-]+)?:Q[0-9]+(?:_[A-Z0-9_]+)?$'
return bool(re.match(hf_pattern, url) or re.match(ollama_pattern, url))
def load_suggestions() -> Dict:
"""Load suggestions from Nextcloud with local file fallback."""
try:
# Try to load from Nextcloud
remote_data = nc.files.download(config.NEXTCLOUD_SUGGESTIONS_PATH)
if remote_data:
suggestions = json.loads(remote_data.decode('utf-8'))
# Update local cache
with open('model_suggestions.json', 'w') as f:
json.dump(suggestions, f, indent=2)
return suggestions
except Exception as e:
print(f"Could not load from Nextcloud: {e}")
# Try local cache
if os.path.exists('model_suggestions.json'):
try:
with open('model_suggestions.json', 'r') as f:
return json.load(f)
except Exception as e:
print(f"Could not load from local cache: {e}")
# Initialize new suggestions if both attempts fail
return {
"suggestions": {},
"last_updated": datetime.now().isoformat(),
"total_suggestions": 0
}
def save_suggestions(suggestions: Dict) -> bool:
"""Save suggestions to both Nextcloud and local cache."""
try:
# Update metadata
suggestions["last_updated"] = datetime.now().isoformat()
suggestions["total_suggestions"] = sum(s["count"] for s in suggestions["suggestions"].values())
# Save to Nextcloud
json_data = json.dumps(suggestions, indent=2)
nc.files.upload(config.NEXTCLOUD_SUGGESTIONS_PATH, json_data.encode('utf-8'))
# Update local cache
with open('model_suggestions.json', 'w') as f:
json.dump(suggestions, f, indent=2)
return True
except Exception as e:
print(f"Error saving suggestions: {e}")
return False
def add_suggestion(model_url: str) -> str:
"""Add or update a model suggestion with validation."""
# Validate model URL format
if not validate_model_url(model_url):
return ("β Invalid model URL format. Please use either:\n"
"- Ollama format: model-name:Q4_K_M\n"
"- HuggingFace format: hf.co/username/model-name-GGUF:Q4_K_M")
# Check if model is already approved
if model_url in dict(config.get_approved_models()):
return "βΉοΈ This model is already in the arena!"
suggestions = load_suggestions()
current_time = datetime.now().isoformat()
if model_url in suggestions["suggestions"]:
suggestions["suggestions"][model_url].update({
"count": suggestions["suggestions"][model_url]["count"] + 1,
"last_suggested": current_time
})
message = (f"β¨ Model suggestion updated! "
f"This model has been suggested {suggestions['suggestions'][model_url]['count']} times.")
else:
suggestions["suggestions"][model_url] = {
"count": 1,
"first_suggested": current_time,
"last_suggested": current_time
}
message = "β
New model suggestion recorded successfully!"
if save_suggestions(suggestions):
return message
return "β Error saving suggestion. Please try again later."
def get_suggestions_html() -> str:
"""Generate HTML table of model suggestions with improved styling."""
suggestions = load_suggestions()
# Sort suggestions by count (descending) and last suggested date
sorted_suggestions = sorted(
suggestions["suggestions"].items(),
key=lambda x: (x[1]["count"], x[1]["last_suggested"]),
reverse=True
)
stats_header = f"""
<div class="stats-header">
Total Suggestions: {suggestions.get("total_suggestions", 0)} | Last Updated: {suggestions.get("last_updated", "Never").split("T")[0]}
</div>
"""
html = f"""
<style>
.suggestions-table {{
width: 100%;
border-collapse: collapse;
font-family: Arial, sans-serif;
margin-top: 20px;
}}
.suggestions-table th, .suggestions-table td {{
border: 1px solid #ddd;
padding: 12px;
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;
}}
.stats-header {{
font-size: 0.9em;
color: #888;
margin-bottom: 10px;
}}
</style>
{stats_header}
<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 |