k-mktr commited on
Commit
6216e00
β€’
1 Parent(s): 4ceb2fd

Create model_suggestions.py

Browse files
Files changed (1) hide show
  1. model_suggestions.py +141 -0
model_suggestions.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from nc_py_api import Nextcloud
2
+ import json
3
+ from typing import Dict, List
4
+ import os
5
+ import time
6
+ from datetime import datetime
7
+ import threading
8
+ import arena_config
9
+ import re
10
+
11
+ # Initialize Nextcloud client
12
+ nc = Nextcloud(
13
+ nextcloud_url=arena_config.NEXTCLOUD_URL,
14
+ nc_auth_user=arena_config.NEXTCLOUD_USERNAME,
15
+ nc_auth_pass=arena_config.NEXTCLOUD_PASSWORD
16
+ )
17
+
18
+ SUGGESTIONS_FILE = "model_suggestions.json"
19
+ NEXTCLOUD_SUGGESTIONS_PATH = "/gpu_poor_model_suggestions.json"
20
+
21
+ def validate_model_url(url: str) -> bool:
22
+ """Validate if the provided URL matches the expected HuggingFace format."""
23
+ pattern = r'^hf\.co/[\w-]+/[\w\.-]+(?:-GGUF)?:Q[0-9]+(?:_[A-Z0-9_]+)?$'
24
+ return bool(re.match(pattern, url))
25
+
26
+ def load_suggestions() -> Dict:
27
+ """Load suggestions from local file or initialize if not exists."""
28
+ if os.path.exists(SUGGESTIONS_FILE):
29
+ with open(SUGGESTIONS_FILE, 'r') as f:
30
+ return json.load(f)
31
+ return {
32
+ "suggestions": {},
33
+ "last_updated": datetime.now().isoformat()
34
+ }
35
+
36
+ def save_suggestions(suggestions: Dict) -> None:
37
+ """Save suggestions to both local file and Nextcloud."""
38
+ with open(SUGGESTIONS_FILE, 'w') as f:
39
+ json.dump(suggestions, f, indent=2)
40
+
41
+ # Upload to Nextcloud
42
+ try:
43
+ nc.files.upload(
44
+ NEXTCLOUD_SUGGESTIONS_PATH,
45
+ json.dumps(suggestions, indent=2).encode('utf-8')
46
+ )
47
+ except Exception as e:
48
+ print(f"Error uploading to Nextcloud: {e}")
49
+
50
+ def add_suggestion(model_url: str) -> str:
51
+ """Add a new model suggestion or update existing one."""
52
+ if not validate_model_url(model_url):
53
+ return "❌ Invalid model URL format. Please use the format: hf.co/username/model-name-GGUF:Q4_K_M"
54
+
55
+ suggestions = load_suggestions()
56
+
57
+ if model_url in suggestions["suggestions"]:
58
+ suggestions["suggestions"][model_url]["count"] += 1
59
+ suggestions["suggestions"][model_url]["last_suggested"] = datetime.now().isoformat()
60
+ message = f"✨ Model suggestion updated! This model has been suggested {suggestions['suggestions'][model_url]['count']} times."
61
+ else:
62
+ suggestions["suggestions"][model_url] = {
63
+ "count": 1,
64
+ "first_suggested": datetime.now().isoformat(),
65
+ "last_suggested": datetime.now().isoformat()
66
+ }
67
+ message = "βœ… New model suggestion recorded successfully!"
68
+
69
+ suggestions["last_updated"] = datetime.now().isoformat()
70
+ save_suggestions(suggestions)
71
+
72
+ return message
73
+
74
+ def get_suggestions_html() -> str:
75
+ """Generate HTML table of model suggestions."""
76
+ suggestions = load_suggestions()
77
+
78
+ # Sort suggestions by count (descending)
79
+ sorted_suggestions = sorted(
80
+ suggestions["suggestions"].items(),
81
+ key=lambda x: x[1]["count"],
82
+ reverse=True
83
+ )
84
+
85
+ html = """
86
+ <style>
87
+ .suggestions-table {
88
+ width: 100%;
89
+ border-collapse: collapse;
90
+ font-family: Arial, sans-serif;
91
+ }
92
+ .suggestions-table th, .suggestions-table td {
93
+ border: 1px solid #ddd;
94
+ padding: 8px;
95
+ text-align: left;
96
+ }
97
+ .suggestions-table th {
98
+ background-color: rgba(255, 255, 255, 0.1);
99
+ font-weight: bold;
100
+ }
101
+ .rank-column {
102
+ width: 60px;
103
+ text-align: center;
104
+ }
105
+ .count-badge {
106
+ background-color: rgba(34, 87, 122, 0.7);
107
+ color: white;
108
+ padding: 4px 8px;
109
+ border-radius: 12px;
110
+ font-size: 0.9em;
111
+ }
112
+ .description-column {
113
+ font-size: 0.9em;
114
+ color: #888;
115
+ }
116
+ </style>
117
+ <table class='suggestions-table'>
118
+ <tr>
119
+ <th class='rank-column'>Rank</th>
120
+ <th>Model URL</th>
121
+ <th>Suggestions</th>
122
+ <th>First Suggested</th>
123
+ <th>Last Suggested</th>
124
+ </tr>
125
+ """
126
+
127
+ for index, (model_url, data) in enumerate(sorted_suggestions, start=1):
128
+ rank_display = {1: "πŸ₯‡", 2: "πŸ₯ˆ", 3: "πŸ₯‰"}.get(index, f"{index}")
129
+
130
+ html += f"""
131
+ <tr>
132
+ <td class='rank-column'>{rank_display}</td>
133
+ <td>{model_url}</td>
134
+ <td><span class="count-badge">{data['count']}</span></td>
135
+ <td>{data['first_suggested'].split('T')[0]}</td>
136
+ <td>{data['last_suggested'].split('T')[0]}</td>
137
+ </tr>
138
+ """
139
+
140
+ html += "</table>"
141
+ return html