Skip to content

Commit 6865bca

Browse files
author
zhanglongbin
committed
Fix the bug of dataflow with ID OpenCSGs/csghub-dataflow#34
1 parent 818da04 commit 6865bca

File tree

89 files changed

+8838
-40594
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+8838
-40594
lines changed

label_studio/core/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
re_path(r'data/local-files/', views.localfiles_data, name='localfiles_data'),
7474
re_path(r'version/', views.version_page, name='version'), # html page
7575
re_path(r'api/version/', views.version_page, name='api-version'), # json response
76+
re_path(r'api/system-config/', views.system_config, name='system-config'), # system config proxy
7677
re_path(r'health/', views.health, name='health'),
7778
re_path(r'metrics/', views.metrics, name='metrics'),
7879
re_path(r'trigger500/', views.TriggerAPIError.as_view(), name='metrics'),

label_studio/core/views.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,30 @@ def feature_flags(request):
275275
def collect_metrics(request):
276276
"""Lightweight endpoint to collect usage metrics from the frontend only when COLLECT_ANALYTICS is enabled"""
277277
return HttpResponse(status=204)
278+
279+
280+
@csrf_exempt
281+
@require_http_methods(['GET'])
282+
def system_config(request):
283+
"""Proxy endpoint to fetch system config from external API"""
284+
try:
285+
# 调用外部API
286+
response = requests.get(
287+
'https://opencsg-stg.com/internal_api/system_config'
288+
)
289+
response.raise_for_status()
290+
291+
# 返回JSON响应
292+
return JsonResponse(response.json(), safe=False)
293+
except requests.exceptions.RequestException as e:
294+
logger.error(f'Error fetching system config: {e}')
295+
return JsonResponse(
296+
{'error': 'Failed to fetch system config', 'detail': str(e)},
297+
status=500
298+
)
299+
except Exception as e:
300+
logger.error(f'Unexpected error in system_config: {e}')
301+
return JsonResponse(
302+
{'error': 'Internal server error', 'detail': str(e)},
303+
status=500
304+
)

label_studio/log/label_studio.log

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54269,3 +54269,36 @@ django.db.utils.OperationalError: no such column: htx_user.authorization
5426954269
[2025-08-13 10:50:11,922] [django.server::log_message::213] [INFO] "GET /api/projects/1 HTTP/1.1" 200 1261
5427054270
=======
5427154271
>>>>>>> Stashed changes
54272+
[2025-10-31 09:31:27,179] [django.utils.autoreload::run_with_reloader::667] [INFO] Watching for file changes with StatReloader
54273+
[2025-10-31 09:32:25,942] [django.server::log_message::213] [INFO] "GET / HTTP/1.1" 302 0
54274+
[2025-10-31 09:32:26,443] [django.server::log_message::213] [INFO] "GET /user/login/ HTTP/1.1" 200 27795
54275+
[2025-10-31 09:32:26,577] [django.server::log_message::213] [INFO] "GET /static/css/login.9fac476a05be.css HTTP/1.1" 200 7567
54276+
[2025-10-31 09:32:26,588] [django.server::log_message::213] [INFO] "GET /static/css/fonts.hellix.e39c76045d23.css HTTP/1.1" 200 380
54277+
[2025-10-31 09:32:26,589] [django.server::log_message::213] [INFO] "GET /static/css/main.caad24634e2e.css HTTP/1.1" 200 29909
54278+
[2025-10-31 09:32:27,306] [django.server::log_message::213] [INFO] "GET /static/images/favicon.0d6671e45154.ico HTTP/1.1" 200 6157
54279+
[2025-10-31 09:32:54,586] [django.server::log_message::213] [INFO] "GET /static/fonts/Hellix-Regular.ce7e7fc9354f.woff HTTP/1.1" 200 51972
54280+
[2025-10-31 10:06:03,973] [django.server::log_message::213] [INFO] "GET /docs/api/schema/swagger-ui/ HTTP/1.1" 200 4716
54281+
[2025-10-31 10:06:05,578] [django.server::log_message::213] [INFO] "GET /docs/api/schema/ HTTP/1.1" 200 746339
54282+
[2025-10-31 10:08:17,055] [django.server::log_message::213] [INFO] "GET /docs/api/schema/swagger-ui/ HTTP/1.1" 200 4716
54283+
[2025-10-31 10:08:17,766] [django.server::log_message::213] [INFO] "GET /docs/api/schema/ HTTP/1.1" 200 746339
54284+
[2025-10-31 10:08:23,464] [django.server::log_message::213] [INFO] "GET /docs/api/schema/ HTTP/1.1" 200 402490
54285+
[2025-10-31 10:09:02,184] [django.server::log_message::213] [INFO] "GET /docs/api/ HTTP/1.1" 302 0
54286+
[2025-10-31 10:09:02,246] [django.server::log_message::213] [INFO] "GET /docs/api/schema/redoc/ HTTP/1.1" 200 737
54287+
[2025-10-31 10:09:02,785] [django.server::log_message::213] [INFO] "GET /favicon.ico HTTP/1.1" 301 0
54288+
[2025-10-31 10:09:02,980] [django.server::log_message::213] [INFO] "GET /static/images/favicon.ico HTTP/1.1" 200 6157
54289+
[2025-10-31 10:09:04,236] [django.server::log_message::213] [INFO] "GET /docs/api/schema/ HTTP/1.1" 200 402490
54290+
[2025-10-31 10:12:52,725] [django.server::log_message::213] [INFO] "GET /user/login_reques/[email protected] HTTP/1.1" 302 0
54291+
[2025-10-31 10:12:52,783] [django.server::log_message::213] [INFO] "GET /projects/ HTTP/1.1" 200 34413
54292+
[2025-10-31 10:12:52,940] [django.server::log_message::213] [INFO] "GET /react-app/runtime.js?v=none HTTP/1.1" 200 6175
54293+
[2025-10-31 10:12:52,959] [django.server::log_message::213] [INFO] "GET /static/fonts/Figtree-Regular.ttf HTTP/1.1" 200 40584
54294+
[2025-10-31 10:12:52,961] [django.server::log_message::213] [INFO] "GET /static/fonts/Figtree-SemiBold.ttf HTTP/1.1" 200 40852
54295+
[2025-10-31 10:12:52,964] [django.server::log_message::213] [INFO] "GET /react-app/main.css?v=none HTTP/1.1" 200 181375
54296+
[2025-10-31 10:12:52,969] [django.server::log_message::213] [INFO] "GET /react-app/vendor.js?v=1 HTTP/1.1" 200 281095
54297+
[2025-10-31 10:12:52,990] [django.server::log_message::213] [INFO] "GET /react-app/main.js?v=none HTTP/1.1" 200 2005064
54298+
[2025-10-31 10:12:53,016] [django.server::log_message::213] [INFO] "GET /static/js/jquery.min.6dc493ec57a3.js HTTP/1.1" 200 87464
54299+
[2025-10-31 10:12:53,484] [django.server::log_message::213] [INFO] "GET /api/current-user/whoami HTTP/1.1" 200 388
54300+
[2025-10-31 10:12:53,497] [django.server::log_message::213] [INFO] "GET /api/version HTTP/1.1" 200 403
54301+
[2025-10-31 10:12:53,556] [django.server::log_message::213] [INFO] "GET /api/projects?page=1&page_size=30&include=id%2Ctitle%2Ccreated_by%2Ccreated_at%2Ccolor%2Cis_published%2Cassignment_settings HTTP/1.1" 200 3040
54302+
[2025-10-31 10:12:53,694] [django.server::log_message::213] [INFO] "GET /projects/ HTTP/1.1" 200 34413
54303+
[2025-10-31 10:12:53,764] [django.server::log_message::213] [INFO] "GET /api/projects?ids=31%2C30%2C29%2C28%2C27%2C19%2C18%2C17%2C16%2C15%2C14%2C12%2C11%2C10&include=id%2Cdescription%2Cnum_tasks_with_annotations%2Ctask_number%2Cskipped_annotations_number%2Ctotal_annotations_number%2Ctotal_predictions_number%2Cground_truth_number%2Cfinished_task_number&page_size=30 HTTP/1.1" 200 3022
54304+
[2025-10-31 10:12:55,413] [django.server::log_message::213] [INFO] "GET /sw.js HTTP/1.1" 200 6221

label_studio/organizations/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def get_contributed_to_projects(self, user):
4646
return contributed_to_projects_map.get(user.id, [])
4747

4848
class Meta(UserSerializer.Meta):
49-
fields = UserSerializer.Meta.fields + ('created_projects', 'contributed_to_projects')
49+
fields = UserSerializer.Meta.fields + ('created_projects', 'contributed_to_projects', 'user_name')
5050

5151

5252
class OrganizationMemberListSerializer(DynamicFieldsMixin, serializers.ModelSerializer):

label_studio/templates/base.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,26 @@
246246
});
247247
})();
248248

249+
// 从URL参数中读取origin并写入Local Storage
250+
(function() {
251+
if (typeof(Storage) !== "undefined") {
252+
try {
253+
var urlParams = new URLSearchParams(window.location.search);
254+
var origin = urlParams.get('origin');
255+
if (origin) {
256+
localStorage.setItem('origin', origin);
257+
console.log('Origin saved to Local Storage from URL:', origin);
258+
// 从URL中移除origin参数,避免在地址栏中显示,防止用户修改URL参数导致Local Storage被覆盖
259+
urlParams.delete('origin');
260+
var newUrl = window.location.pathname + (urlParams.toString() ? '?' + urlParams.toString() : '') + window.location.hash;
261+
window.history.replaceState({}, '', newUrl);
262+
}
263+
} catch (e) {
264+
console.error('Error saving origin to Local Storage:', e);
265+
}
266+
}
267+
})();
268+
249269
</script>
250270
{% endblock %}
251271

label_studio/users/serializers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class Meta:
102102
'active_organization_meta',
103103
'allow_newsletters',
104104
'date_joined',
105+
'user_name'
105106
)
106107

107108

label_studio/users/templates/users/new-ui/user_login.html

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,75 @@
99
const ls_gaclient_id = sessionStorage.getItem('ls_gaclient_id');
1010
__lsa('users.login.view', { ls_gaclient_id });
1111
}, 2000);
12+
13+
// 国际化支持
14+
(function() {
15+
const language = '{{ language|default:"en" }}';
16+
const translations = {
17+
en: {
18+
title: "Log in",
19+
email: "Email Address",
20+
password: "Password",
21+
keepLoggedIn: "Keep me logged in this browser",
22+
submit: "Log in",
23+
noAccount: "Don't have an account?",
24+
signUp: "Sign up"
25+
},
26+
zh: {
27+
title: "登录",
28+
email: "邮箱地址",
29+
password: "密码",
30+
keepLoggedIn: "在此浏览器中保持登录状态",
31+
submit: "登录",
32+
noAccount: "没有账号?",
33+
signUp: "注册"
34+
}
35+
};
36+
37+
const t = translations[language] || translations.en;
38+
39+
// 更新页面文本
40+
const titleEl = document.querySelector('.form-wrapper h2');
41+
if (titleEl) titleEl.textContent = t.title;
42+
43+
const emailLabel = document.querySelector('.input-wrapper label[for="email"], .input-wrapper:first-child label');
44+
if (emailLabel) emailLabel.textContent = t.email;
45+
46+
const passwordLabel = document.querySelector('.input-wrapper label[for="password"], .input-wrapper:nth-child(2) label');
47+
if (passwordLabel) passwordLabel.textContent = t.password;
48+
49+
const keepLoggedInLabel = document.querySelector('label[for="persist_session"]');
50+
if (keepLoggedInLabel) keepLoggedInLabel.textContent = t.keepLoggedIn;
51+
52+
const submitButton = document.querySelector('.login-button, button[type="submit"]');
53+
if (submitButton) {
54+
submitButton.textContent = t.submit;
55+
submitButton.setAttribute('aria-label', t.submit);
56+
}
57+
58+
const noAccountText = document.querySelector('.text-wrapper p');
59+
if (noAccountText) noAccountText.textContent = t.noAccount;
60+
61+
const signUpLink = document.querySelector('.text-wrapper a');
62+
if (signUpLink) signUpLink.textContent = t.signUp;
63+
64+
// 保存语言到sessionStorage
65+
sessionStorage.setItem('language', language);
66+
})();
1267
</script>
1368
{% endblock %}
1469

1570
{% block user_content %}
1671
<div class="form-wrapper">
17-
<h2>Log in</h2>
72+
<h2 data-i18n="login.title">Log in</h2>
1873
<form id="login-form" action="{% url 'user-login' %}?next={{ next }}" method="post">
1974
{% csrf_token %}
2075
<div class="input-wrapper">
21-
<label>Email Address</label>
76+
<label data-i18n="login.email">Email Address</label>
2277
<input type="text" class="lsf-input-ls" name="email" id="email" value="{{ form.data.email }}">
2378
</div>
2479
<div class="input-wrapper">
25-
<label>Password</label>
80+
<label data-i18n="login.password">Password</label>
2681
<input type="password" class="lsf-input-ls" name="password" id="password">
2782
</div>
2883
{% if form.non_field_errors %}
@@ -34,15 +89,15 @@ <h2>Log in</h2>
3489
{% endif %}
3590
<div class="form-group">
3691
<input type="checkbox" id="persist_session" name="persist_session" class="lsf-checkbox-ls" checked="checked" style="width: auto;" />
37-
<label for="persist_session">Keep me logged in this browser</label>
92+
<label for="persist_session" data-i18n="login.keepLoggedIn">Keep me logged in this browser</label>
3893
</div>
39-
<button type="submit" aria-label="Log In" class="login-button">Log in</button>
94+
<button type="submit" aria-label="Log In" class="login-button" data-i18n="login.submit">Log in</button>
4095
</form>
4196
</div>
4297
{% if not settings.DISABLE_SIGNUP_WITHOUT_LINK %}
4398
<div class="text-wrapper">
44-
<p class="">Don't have an account?</p>
45-
<a href="{% url 'user-signup' %}{% querystring %}">Sign up</a>
99+
<p class="" data-i18n="login.noAccount">Don't have an account?</p>
100+
<a href="{% url 'user-signup' %}{% querystring %}" data-i18n="login.signUp">Sign up</a>
46101
</div>
47102
{% endif %}
48103
{% endblock %}

label_studio/users/templates/users/user_login.html

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
{% extends 'users/user_base.html' %}
22

33
{% block user_content %}
4+
<script nonce="{{request.csp_nonce}}">
5+
// 国际化支持
6+
(function() {
7+
const language = '{{ language|default:"en" }}';
8+
const translations = {
9+
en: {
10+
email: "Email",
11+
password: "Password",
12+
keepLoggedIn: "Keep me logged in this browser",
13+
submit: "Log in"
14+
},
15+
zh: {
16+
email: "邮箱",
17+
password: "密码",
18+
keepLoggedIn: "在此浏览器中保持登录状态",
19+
submit: "登录"
20+
}
21+
};
22+
23+
const t = translations[language] || translations.en;
24+
25+
// 更新页面文本
26+
const emailInput = document.querySelector('input[name="email"]');
27+
if (emailInput) emailInput.setAttribute('placeholder', t.email);
28+
29+
const passwordInput = document.querySelector('input[name="password"]');
30+
if (passwordInput) passwordInput.setAttribute('placeholder', t.password);
31+
32+
const keepLoggedInLabel = document.querySelector('label[for="persist_session"]');
33+
if (keepLoggedInLabel) keepLoggedInLabel.textContent = t.keepLoggedIn;
34+
35+
const submitButton = document.querySelector('button[type="submit"]');
36+
if (submitButton) {
37+
submitButton.textContent = t.submit;
38+
submitButton.setAttribute('aria-label', t.submit);
39+
}
40+
41+
// 保存语言到sessionStorage
42+
sessionStorage.setItem('language', language);
43+
})();
44+
</script>
445
<form id="login-form" action="{% url 'user-login' %}?next={{ next }}" method="post">
546
{% csrf_token %}
647
<p><input type="text" class="lsf-input-ls" name="email" id="email" placeholder="Email" value="{{ form.data.email }}"></p>
@@ -19,4 +60,27 @@
1960
<p><button type="submit" aria-label="Log In" class="lsf-button-ls lsf-button-ls_look_primary">Log in</button></p>
2061
</form>
2162

63+
{% if origin %}
64+
<script nonce="{{request.csp_nonce}}">
65+
// 将origin写入Local Storage
66+
(function() {
67+
if (typeof(Storage) !== "undefined") {
68+
try {
69+
localStorage.setItem('origin', '{{ origin }}');
70+
console.log('Origin saved to Local Storage:', '{{ origin }}');
71+
// 从URL中移除origin参数,避免在地址栏中显示,防止用户修改URL参数导致Local Storage被覆盖
72+
var urlParams = new URLSearchParams(window.location.search);
73+
if (urlParams.has('origin')) {
74+
urlParams.delete('origin');
75+
var newUrl = window.location.pathname + (urlParams.toString() ? '?' + urlParams.toString() : '') + window.location.hash;
76+
window.history.replaceState({}, '', newUrl);
77+
}
78+
} catch (e) {
79+
console.error('Error saving origin to Local Storage:', e);
80+
}
81+
}
82+
})();
83+
</script>
84+
{% endif %}
85+
2286
{% endblock %}

0 commit comments

Comments
 (0)