From 80dcbc15704afd4d0a164ecb90f129656e3d41ba Mon Sep 17 00:00:00 2001 From: yushunwang <869588058@qq.com> Date: Fri, 26 Jul 2024 09:50:22 +0800 Subject: [PATCH 01/17] fix:avoid generating unnecessary new migration file --- baton/migrations/0001_initial.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/baton/migrations/0001_initial.py b/baton/migrations/0001_initial.py index 59bc2e7d..5d3e7af4 100644 --- a/baton/migrations/0001_initial.py +++ b/baton/migrations/0001_initial.py @@ -13,18 +13,14 @@ class Migration(migrations.Migration): migrations.CreateModel( name="BatonTheme", fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("name", models.CharField(max_length=255, verbose_name="Name")), - ("theme", models.TextField(verbose_name="Theme")), - ("active", models.BooleanField(default=False, verbose_name="Active")), + ("id", models.AutoField(primary_key=True, serialize=False, verbose_name="id")), + ("name", models.CharField(max_length=255, verbose_name="name")), + ("theme", models.TextField(verbose_name="theme")), + ("active", models.BooleanField(default=False, verbose_name="active")), ], + options={ + 'verbose_name': 'admin theme', + 'verbose_name_plural': 'admin themes' + } ), ] From 9466af0c187e5dc609041b06b637d2977748e689 Mon Sep 17 00:00:00 2001 From: ijavadddd Date: Fri, 27 Sep 2024 12:41:47 +0330 Subject: [PATCH 02/17] optimize baton for rtl and rtl languages like ar and fa --- baton/locale/fa/LC_MESSAGES/django.mo | Bin 0 -> 1261 bytes baton/locale/fa/LC_MESSAGES/django.po | 112 ++++++++++++++++++ baton/static/admin/css/rtl.css | 60 ++++++++++ .../app/dist/7a71a48e0bbd982d07192d15f.ttf | Bin 0 -> 34964 bytes baton/static/baton/js_snippets/rtl.js | 12 ++ baton/templates/admin/base_site.html | 7 +- 6 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 baton/locale/fa/LC_MESSAGES/django.mo create mode 100644 baton/locale/fa/LC_MESSAGES/django.po create mode 100644 baton/static/admin/css/rtl.css create mode 100644 baton/static/baton/app/dist/7a71a48e0bbd982d07192d15f.ttf create mode 100644 baton/static/baton/js_snippets/rtl.js diff --git a/baton/locale/fa/LC_MESSAGES/django.mo b/baton/locale/fa/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..63e1b45e7f3a5ef6c9ffb4fd62df76df637884af GIT binary patch literal 1261 zcmZva&1)1%7{+V;SasCZ)s3yU{TB8(2o5Hld|AxH1ts*UWyKVWZrT=02&CI-ZUcYamx=TkNP&#^rZ z1=dm6Y1kv!_q_iKKUgc^39tcv2R;Dzf=|FxU}q421AdG1d+=-UUvMAzAGinnf52V4 z`t|$3VsT&7yJSIbKrjla^Jr}jL&NKgS-yGAV(aAvDO1Hq-FgeBbx_gi{FUX zK^W`VUf*nQXre)9&n^0aQTmqgO`wJn5;U)*E-z6z3XKX)lF#Q!Oh^-jVp82vK@_VB zEpTNVEi0`mw-y>hiI}`C!)ipbQu9MUFw{JQ`tB%6$KTg6EUO0y0|WD zO3bN588QDUbEnCCR8wZj5395cLA0!+uqx*3aU5wQOe03?utKp`NkT|a8j{7Vj&7^6 zajsUJn-~N!9=Z8K-p$P^E_7y+s$X#?>ea+4MIPm5e{ts29iKCuNokZvMYnjtaW6ZC zA{Bn}T=%?NaNXRrOpH^~GE4$IiuUN&sIG~xKqC!o^QtEOU|g-pS{$f+IjW7JCal(F zRXHUkYaT618kwFR5Bz+jt2xe}J63ZBiQOAEfq%?5QX17|AIwZx+^&W_1wahUqs(Q_etx$@gY8QniG7Y($39Qjwpx_lw=ZlbU9;`%V?lA7k7-k6-VOUYT_xLvx67Me zA6&3uUw!@|p;>pUW!GUH!hq(xZn`G6y~L6}3;nUxO7B6;x=1(CvzM-Z_`Q{`+BT}v zCKoqtJH0P5T`zIy;n>`2eQMh8H)zb>-n(b%J-*l`LOrsNc|5wKvI7t9m(^n?w4|Ga bbo8@bO4smea5Y&D*>&6Ir^HN-@@M%G`QD%= literal 0 HcmV?d00001 diff --git a/baton/locale/fa/LC_MESSAGES/django.po b/baton/locale/fa/LC_MESSAGES/django.po new file mode 100644 index 00000000..fd4504ee --- /dev/null +++ b/baton/locale/fa/LC_MESSAGES/django.po @@ -0,0 +1,112 @@ +# baton translations +# Copyright (C) 2024 Otto srl +# This file is distributed under the same license as the django-baton package. +# Stefano Contini , 2024. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 0.1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-09-13 03:26+0330\n" +"PO-Revision-Date: 2024-09-12 17:00+0100\n" +"Last-Translator: Your Name \n" +"Language-Team: fa \n" +"Language: fa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: config.py:9 +msgid "Site administration" +msgstr "مدیریت سایت" + +#: config.py:10 +msgid "Menu" +msgstr "منو" + +#: models.py:5 +msgid "id" +msgstr "" + +#: models.py:6 +msgid "name" +msgstr "" + +#: models.py:7 +#, fuzzy +#| msgid "Theme" +msgid "theme" +msgstr "قالب" + +#: models.py:8 +#, fuzzy +#| msgid "Active" +msgid "active" +msgstr "فعال" + +#: models.py:20 +#, fuzzy +#| msgid "Light theme" +msgid "admin theme" +msgstr "تم روشن" + +#: models.py:21 +#, fuzzy +#| msgid "Light theme" +msgid "admin themes" +msgstr "تم روشن" + +#: templates/admin/base_site.html:5 +msgid "Django site admin" +msgstr "مدیر سایت جنگو" + +#: templates/admin/base_site.html:32 +msgid "Django administration" +msgstr "مدیریت جنگو" + +#: templates/admin/filer/folder/directory_listing.html:4 +msgid "Folders" +msgstr "پوشه‌ها" + +#: templates/admin/filter.html:2 templates/baton/filters/dropdown_filter.html:6 +#: templates/baton/filters/input_filter.html:4 +#: templates/baton/filters/multiple_choice_filter.html:2 +#, python-format +msgid " By %(filter_title)s " +msgstr " بر اساس %(filter_title)s " + +#: templates/baton/ai_stats.html:13 +msgid "Something went wrong" +msgstr "مشکلی پیش آمد" + +#: templates/baton/filters/input_filter.html:18 +#: templates/baton/filters/input_filter.html:31 +msgid "type and press enter..." +msgstr "تایپ کنید و اینتر را بزنید..." + +#: templates/baton/filters/input_filter.html:22 +msgid "Reset" +msgstr "بازنشانی" + +#: templates/baton/footer.html:7 +msgid "Support" +msgstr "پشتیبانی" + +#: templates/baton/footer.html:17 +#, python-format +msgid "Developed by %(powered_by)s" +msgstr "توسعه داده شده توسط %(powered_by)s" + +msgid "Name" +msgstr "نام" + +msgid "Baton" +msgstr "باتون" + +msgid "Filter" +msgstr "فیلتر" + +msgid " Search contents... " +msgstr " جستجوی محتوا... " diff --git a/baton/static/admin/css/rtl.css b/baton/static/admin/css/rtl.css new file mode 100644 index 00000000..9079f1ea --- /dev/null +++ b/baton/static/admin/css/rtl.css @@ -0,0 +1,60 @@ +@font-face { + font-family: 'Yekan'; + src: url('../../app/dist/7a71a48e0bbd982d07192d15f.ttf') format('truetype'); + font-weight: normal; + font-style: normal; + text-rendering: optimizeLegibility; + font-display: auto; +} + +*, body, h1, h2, h3, h4, h5, h6, p, a, input, input::placeholder, select, option { + font-family: "Yekan"; +} +.sidebar-menu ul li a i::before{ + margin-left: 12px; +} + +.sidebar-menu ul span.has-children i::before{ + margin-left: 12px; +} +.sidebar-menu .active:not(.with-active) a { + margin-left: 0!important; +} +.sidebar-menu ul span.has-children::after, .sidebar-menu ul a.has-children::after{ + float: left!important; + rotate: 180deg; + } + +.change-list .changelist-filter-toggler.with-actions, .change-list .changelist-filter-toggler { + position: static!important; + float: left!important; +} + +.change-form #content form.baton-fixed-submit-row .submit-row{ + left: 0!important; +} + +#content form .submit-row input[type=submit] { + margin: 0 10px; +} + +.dashboard .actionlist li::before { + right: -18px; +} + +.dashboard .actionlist { + border-left: none!important; + border-right: 5px solid var(--bs-baton-dashboard-action-list-border-color); + list-style-type: none; + margin-right: .5rem; + margin-top: 1.5rem; + padding-right: 0; +} + +.change-form #content form label{ + text-align: right; +} + +#login-form { + direction: ltr; +} \ No newline at end of file diff --git a/baton/static/baton/app/dist/7a71a48e0bbd982d07192d15f.ttf b/baton/static/baton/app/dist/7a71a48e0bbd982d07192d15f.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8b886d42db3f4e79bc51143ef06a97a0eda48284 GIT binary patch literal 34964 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 z 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 literal 0 HcmV?d00001 diff --git a/baton/static/baton/js_snippets/rtl.js b/baton/static/baton/js_snippets/rtl.js new file mode 100644 index 00000000..89bd346a --- /dev/null +++ b/baton/static/baton/js_snippets/rtl.js @@ -0,0 +1,12 @@ +Baton.translations = { + unsavedChangesAlert: 'تغییرات ذخیره نشده دارید', + uploading: 'در حال آپلود...', + filter: 'فیلتر', + close: 'بستن', + save: 'ذخیره', + search: 'جستجو', + cannotCopyToClipboardMessage: 'امکان کپی کردن به کلیپ‌بورد وجود ندارد، لطفاً دستی این کار را انجام دهید: Ctrl+C، Enter', + retrieveDataError: 'خطایی در بازیابی داده‌ها رخ داد', + lightTheme: 'تم روشن', + darkTheme: 'تم تیره', +} diff --git a/baton/templates/admin/base_site.html b/baton/templates/admin/base_site.html index cbbdb0d0..f011e379 100644 --- a/baton/templates/admin/base_site.html +++ b/baton/templates/admin/base_site.html @@ -21,6 +21,11 @@ {% baton_theme %} + {% if LANGUAGE_BIDI %} + + + {% endif %} + {% endblock extrahead %} {% block branding %} @@ -32,4 +37,4 @@

{{ site_header|default:_('D {% block footer %} {% footer %} -{% endblock footer %} +{% endblock footer %} \ No newline at end of file From 1011acbe13bdc3b4587fe21f56fbd491a7d32001 Mon Sep 17 00:00:00 2001 From: abidibo Date: Mon, 2 Dec 2024 20:52:18 +0100 Subject: [PATCH 03/17] style: fix spacing --- baton/templates/admin/base_site.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/baton/templates/admin/base_site.html b/baton/templates/admin/base_site.html index 840bfa2a..1667c4f6 100644 --- a/baton/templates/admin/base_site.html +++ b/baton/templates/admin/base_site.html @@ -26,8 +26,8 @@ {% endif %} - {% endblock extrahead %} + {% block branding %}

@@ -38,4 +38,4 @@

{% endblock nav-global %} {% block footer %} {% footer %} -{% endblock footer %} \ No newline at end of file +{% endblock footer %} From 67cb29bae30368261d86b86cbc54429a952e4bce Mon Sep 17 00:00:00 2001 From: abidibo Date: Mon, 2 Dec 2024 20:53:28 +0100 Subject: [PATCH 04/17] docs: add image vision to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 51b57d0d..78b42313 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Baton 4.0.* introduces a bunch of new AI functionalities! - automatic translations with django-modeltranslation - text summarization - text corrections +- image vision - image generation It also introduces themes, and makes it easier to customize the application, there is no need to recompile the js app unless you wanto to change primary and secondary colors or you need heavy customization. From db25ec6c61283ecd0b86d0b674cd5f1dca5f1146 Mon Sep 17 00:00:00 2001 From: abidibo Date: Tue, 10 Dec 2024 17:43:38 +0100 Subject: [PATCH 05/17] build: add npm script to start django and webpack bundle --- CONTRIBUTING.md | 2 +- README.md | 4 +- baton/static/baton/app/package-lock.json | 457 ++++++++++++++++++++++- baton/static/baton/app/package.json | 5 +- docs/customization.rst | 2 +- testapp/app/db.sqlite3 | Bin 532480 -> 532480 bytes 6 files changed, 464 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index af9d190b..56bf4c9c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,7 +72,7 @@ Ready to contribute? Here's how to set up `django-baton` for local development. ``` - Start the js app in watch mode:: + Start both the django testapp and the js app (the last one in watch mode):: ``` $ cd baton/static/baton/app diff --git a/README.md b/README.md index 78b42313..b7ce643f 100644 --- a/README.md +++ b/README.md @@ -1142,7 +1142,7 @@ So: If you want to test your live changes, just start the webpack dev server: $ cd django-baton/baton/static/baton/app/ - $ npm run dev + $ npm run dev:baton And inside the `base_site.html` template, make these changes: @@ -1170,7 +1170,7 @@ Switch the baton js path in `base_site.html` -Start the js app in watch mode +Start both the django testapp and the js app (the last one in watch mode): $ cd baton/static/baton/app $ npm install diff --git a/baton/static/baton/app/package-lock.json b/baton/static/baton/app/package-lock.json index 4aeea6b4..fbf7139d 100644 --- a/baton/static/baton/app/package-lock.json +++ b/baton/static/baton/app/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "baton", - "version": "4.0.1", + "version": "4.2.0", "license": "MIT", "dependencies": { "@babel/core": "^7.14.3", @@ -39,6 +39,7 @@ }, "devDependencies": { "babel-eslint": "^10.1.0", + "concurrently": "^9.1.0", "eslint": "^7.27.0", "eslint-config-standard": "^16.0.3", "eslint-plugin-babel": "^5.3.1", @@ -3150,6 +3151,233 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "node_modules/concurrently": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.0.tgz", + "integrity": "sha512-VxkzwMAn4LP7WyMnJNbHN5mKV9L2IbyDjpzemKr99sXNR3GqRNMMHdm7prV1ws9wg7ETj6WUkNOigZVsptwbgg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/concurrently/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/concurrently/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concurrently/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/concurrently/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/concurrently/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/connect-history-api-fallback": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", @@ -9368,6 +9596,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -9876,6 +10113,18 @@ "node": ">=0.10.0" } }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -10814,6 +11063,15 @@ "node": ">=0.8" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", @@ -10874,6 +11132,12 @@ "node": ">=4" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true + }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -14817,6 +15081,170 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concurrently": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.0.tgz", + "integrity": "sha512-VxkzwMAn4LP7WyMnJNbHN5mKV9L2IbyDjpzemKr99sXNR3GqRNMMHdm7prV1ws9wg7ETj6WUkNOigZVsptwbgg==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, "connect-history-api-fallback": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", @@ -19429,6 +19857,15 @@ "glob": "^7.1.3" } }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -19815,6 +20252,12 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, + "shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true + }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -20532,6 +20975,12 @@ "punycode": "^2.1.1" } }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, "trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", @@ -20582,6 +21031,12 @@ } } }, + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/baton/static/baton/app/package.json b/baton/static/baton/app/package.json index e23dc817..577801a9 100644 --- a/baton/static/baton/app/package.json +++ b/baton/static/baton/app/package.json @@ -7,7 +7,9 @@ "stats": "npx webpack --config ./webpack.prod.js --json > stats.json", "compile": "BATON_REVISION=$(git rev-parse HEAD) npx webpack --config ./webpack.prod.js", "watch": "npx webpack --watch --config ./webpack.dev.js", - "dev": "BATON_REVISION=$(git rev-parse HEAD) webpack serve --host 0.0.0.0 --progress --config ./webpack.dev.js", + "dev:baton": "BATON_REVISION=$(git rev-parse HEAD) webpack serve --host 0.0.0.0 --progress --config ./webpack.dev.js", + "dev:django": "cd ../../../../testapp/app && ../../.virtualenv/bin/python manage.py runserver", + "dev": "concurrently \"npm run dev:baton\" \"npm run dev:django\"", "lint": "./node_modules/eslint/bin/eslint.js ." }, "author": "abidibo", @@ -43,6 +45,7 @@ }, "devDependencies": { "babel-eslint": "^10.1.0", + "concurrently": "^9.1.0", "eslint": "^7.27.0", "eslint-config-standard": "^16.0.3", "eslint-plugin-babel": "^5.3.1", diff --git a/docs/customization.rst b/docs/customization.rst index f0358580..f9465320 100644 --- a/docs/customization.rst +++ b/docs/customization.rst @@ -93,6 +93,6 @@ You can also perform live development, in this case: - start the webpack development server :: - $ npm run dev + $ npm run dev:baton Now while you make your changes to the js app (css included), webpack will update the bundle automatically, so just refresh the page and you'll see your changes. diff --git a/testapp/app/db.sqlite3 b/testapp/app/db.sqlite3 index 4750a5153dd3b5e38afe1481864859b06202963d..7ff0c475b4dadca4943e245efe9b0f3116228be2 100644 GIT binary patch delta 360 zcmZoTpwMtYVS+Sc$NeQTalK1`38|R>qcAhQ@m4hQ>ywrp;&a+t1`P0x{F} zGx^LG1&k@vSsyTO6=R;ww2QTqHJR0xRh&_R|s;0{9 z%Vd&cYFd$>n_rlhlbvT;XpmfBnr>=XVvv$s6F9>xbib$6yeSj*0{oo5~Uk3=DM_HPV) dw|KYk^l@i!IdRIcf7@(m@PK{$H*pRw4gj!UKbrsm From 2c117314750ec6d9e176b804cd7b72a3ab4f372f Mon Sep 17 00:00:00 2001 From: abidibo Date: Wed, 11 Dec 2024 12:27:23 +0100 Subject: [PATCH 06/17] feat: add image vision to baton ai image field --- README.md | 62 +++++--- baton/config.py | 1 + baton/fields.py | 79 +++++++++- baton/forms.py | 23 +++ baton/locale/fa/LC_MESSAGES/django.mo | Bin 1261 -> 1273 bytes baton/locale/fa/LC_MESSAGES/django.po | 26 ++-- baton/locale/it/LC_MESSAGES/django.mo | Bin 1055 -> 1126 bytes baton/locale/it/LC_MESSAGES/django.po | 39 ++++- .../app/dist/7a71a48e0bbd982d07192d15f.ttf | Bin 34964 -> 0 bytes baton/static/baton/app/dist/baton.min.js | 2 +- baton/static/baton/app/src/core/AI.js | 52 +++++-- baton/templates/baton/widgets/ai_image.html | 141 +++++++++++++++++- docs/ai.rst | 57 ++++--- testapp/app/db.sqlite3 | Bin 532480 -> 540672 bytes testapp/app/news/admin.py | 16 +- ...image_subject_location_alter_news_image.py | 35 +++++ ...ivity_image_activity_image_alt_and_more.py | 44 ++++++ testapp/app/news/models.py | 6 +- 18 files changed, 492 insertions(+), 91 deletions(-) create mode 100644 baton/forms.py delete mode 100644 baton/static/baton/app/dist/7a71a48e0bbd982d07192d15f.ttf create mode 100644 testapp/app/news/migrations/0007_news_image_subject_location_alter_news_image.py create mode 100644 testapp/app/news/migrations/0008_activity_image_activity_image_alt_and_more.py diff --git a/README.md b/README.md index b7ce643f..0b5353be 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,7 @@ Default value is `True`. ### AI -Django Baton can provide you AI assistance in the admin interface: translations, summarizations, corrections and image generation. You can choose which model to use for each functionality, please note that different models have different prices, see [Baton site](https://www.baton.sqrt64.it). +Django Baton can provide you AI assistance in the admin interface: translations, summarizations, corrections, image generation and image vision. You can choose which model to use for each functionality, please note that different models have different prices, see [Baton site](https://www.baton.sqrt64.it). Django Baton supports native fields (input, textarea) and ckeditor (django-ckeditor package) by default, but provides hooks you can use to add support to any other wysiwyg editor, read more in the [AI](#baton-ai) section. @@ -522,29 +522,6 @@ In this modal you can edit the `words` and `useBulletedList` parameters and perf All default fields and CKEDITOR fields are supported, see AI Hooks section below if you need to support other wysiwyg editors. -### Image vision - -In your `ModelAdmin` classes you can define which images can be described in order to generate an alt text, look at the following example: - -``` python -class MyModelAdmin(admin.ModelAdmin): - # ... - baton_vision_fields = { - "image": [{ - "target": "image_alt", - "chars": 80, - "language": "en", - }], - } -``` - -You have to specify the target field name. You can also optionally specify the follwing parameters: - -- `chars`: max number of characters used in the alt description (approximate, it will not be followed strictly, default is 100) -- `language`: the language of the summary, default is your default language - -With this configuration, one (the number of targets) button will appear near the `image` field, clicking it the calculated image alt text will be inserted in the `image_alt` field. - ### Image Generation Baton provides a new model field and a new image widget which can be used to generate images from text. The image field can be used as a normal image field, but also a new button will appear near it. @@ -566,6 +543,43 @@ There is also another way to add the AI image generation functionality to a norm ``` +### Image vision +There are two ways to activate image vision functionality in Baton, both allow to generate an alt text for the image through the AI. + +The first way is to just use the `BatonAiImageField` and define the `alt_field` attribute (an optionally `alt_chars`, `alt_language`) + +``` python +from baton.fields import BatonAiImageField + +class MyModel(models.Model): + image = BatonAiImageField(verbose_name=_("immagine"), upload_to="news/", alt_field="image_alt", alt_chars=20, alt_language="en") + image_alt = models.CharField(max_length=40, blank=True) +``` + +This method will work only when images are inside inlines. + +The second method consists in defining in the `ModelAdmin` classes which images can be described in order to generate an alt text, look at the following example: + +``` python +class MyModelAdmin(admin.ModelAdmin): + # ... + baton_vision_fields = { + "#id_image": [{ # key must be a selector (useful for inlines) + "target": "image_alt", # target should be the name of a field of the same model + "chars": 80, + "language": "en", + }], + } +``` + +You have to specify the target field name. You can also optionally specify the follwing parameters: + +- `chars`: max number of characters used in the alt description (approximate, it will not be followed strictly, default is 100) +- `language`: the language of the summary, default is your default language + +With this configuration, one (the number of targets) button will appear near the `image` field, clicking it the calculated image alt text will be inserted in the `image_alt` field. +Even this methos should work for inline images. + ### Stats widget Baton provides a new widget which can be used to display stats about AI usage. Just include it in your admin index template: diff --git a/baton/config.py b/baton/config.py index 86786992..c8b41f44 100644 --- a/baton/config.py +++ b/baton/config.py @@ -11,6 +11,7 @@ 'SUPPORT_HREF': 'https://github.com/otto-torino/django-baton/issues', 'COPYRIGHT': 'copyright © 2022 Otto srl', # noqa 'POWERED_BY': 'Otto srl', + 'IMAGE_PREVIEW_WIDTH': 200, 'CONFIRM_UNSAVED_CHANGES': True, 'SHOW_MULTIPART_UPLOADING': True, 'ENABLE_IMAGES_PREVIEW': True, diff --git a/baton/fields.py b/baton/fields.py index 73f373e0..d77e3a1b 100644 --- a/baton/fields.py +++ b/baton/fields.py @@ -1,11 +1,88 @@ from django.db import models + +from django.db.models.fields.files import ImageFieldFile +from django.utils.translation import gettext_lazy as _ +from django.conf import settings +from django.utils.translation import get_language + +from .forms import BatonAiImageFormField from .widgets import BatonAiImageInput +class BatonAiImageFieldFile(ImageFieldFile): + @property + def subject_perc_position(self): + if self.field.subject_location_field and getattr( + self.instance, self.field.subject_location_field): + (cX, cY) = getattr(self.instance, + self.field.subject_location_field).split(',') + + return { + 'x': int(cX), + 'y': int(cY) + } + return None + + @property + def subject_position(self): + perc = self.subject_perc_position + if perc: + return { + 'x': (self.width or 0) * perc.get('x', 0) // 100, + 'y': (self.height or 0) * perc.get('y', 0) // 100 + } + return None + + @property + def sorl(self): + """ shortcut property to use with sorl-thumbnmail crop featur e""" + position = self.subject_perc_position + if position: + x = position.get('x') + y = position.get('y') + # also need -0 + return '%s%% %s%%' % (x, y) + return '50% 50%' + class BatonAiImageField(models.ImageField): + attr_class = BatonAiImageFieldFile + + def __init__(self, + verbose_name=None, + name=None, + width_field=None, + height_field=None, + subject_location_field=None, + alt_field=None, + alt_chars=20, + alt_language=get_language(), + **kwargs): + self.width_field, self.height_field = width_field, height_field + self.subject_location_field = subject_location_field + self.alt_field = alt_field + self.alt_chars = alt_chars + self.alt_language = alt_language + super().__init__(verbose_name, name, **kwargs) + + def deconstruct(self): + name, path, args, kwargs = super().deconstruct() + if self.alt_field: + kwargs['alt_field'] = self.alt_field + kwargs['alt_chars'] = self.alt_chars + kwargs['alt_language'] = self.alt_language + if self.subject_location_field: + kwargs['subject_location_field'] = self.subject_location_field + return name, path, args, kwargs + def formfield(self, **kwargs): d = kwargs # override widget d.update({ 'widget': BatonAiImageInput, + 'form_class': BatonAiImageFormField, + 'alt_field': self.alt_field, + 'alt_chars': self.alt_chars, + 'alt_language': self.alt_language, + 'subject_location_field': self.subject_location_field, + 'help_text':_('Drag the circle or click on the image to set the image subject') if self.subject_location_field else d.get('help_text', ''), }) - return super(BatonAiImageField, self).formfield(**d) + return super().formfield(**d) diff --git a/baton/forms.py b/baton/forms.py new file mode 100644 index 00000000..feb7d9b0 --- /dev/null +++ b/baton/forms.py @@ -0,0 +1,23 @@ +from django.forms.fields import ImageField +from .widgets import BatonAiImageInput +from .config import get_config + + +class BatonAiImageFormField(ImageField): + widget = BatonAiImageInput + + def __init__(self, subject_location_field=None, alt_field=None, alt_chars=20, alt_language='en', *args, **kwargs): + self.subject_location_field = subject_location_field + self.alt_field = alt_field + self.alt_chars = alt_chars + self.alt_language = alt_language + return super().__init__(*args, **kwargs) + + def widget_attrs(self, widget): + attrs = super().widget_attrs(widget) + attrs['subject_location_field'] = self.subject_location_field + attrs['alt_field'] = self.alt_field + attrs['alt_chars'] = self.alt_chars + attrs['alt_language'] = self.alt_language + attrs['preview_width'] = get_config('IMAGE_PREVIEW_WIDTH') + return attrs diff --git a/baton/locale/fa/LC_MESSAGES/django.mo b/baton/locale/fa/LC_MESSAGES/django.mo index 63e1b45e7f3a5ef6c9ffb4fd62df76df637884af..8fbb9802b83bab037bf8a0b378ad1ea2c3c7e390 100644 GIT binary patch delta 543 zcmYk%zfZzI6bJBEsVFM`HX1eNCKnfVHcmtb*wyh*L&?x>@QaQm{iXRD~?!1ln@h$Z-iW{3egN) zg9~uGd)A=rJAs?<3=Y62sKOW64`1OFe23HU7s|e9AJHsPkw&rEKyn!}6toD@IxIms z_!iE?XK2GOI0pAHB?|L!9NJL!J8%wObn|T}?|Xz86AmAS@`qJgA;R47OF?*H3}QyO zhVUFg49b&ttSotTC9#t*lWAsUbf#rZEvGZXWLhq(9Wo;yrn5)Mw9YJp6?Cg7QLy(9 zbj_kIBbU<60`2N~`#RcprFd_VRFOBhAGo|JDvUR|&-i7h##_iV7#{M>o2ZCt;4)t4 zZMi|FQxm1Y?bPJP3A<7BnJ9}Yzd_vhHuJi0_+8+NGUF{28zde;OH@ANr>>}QpYWn1 Js$NDd{{vmHmgN8d delta 523 zcmXxgu}cC`9Ki8+YMPc=mL%424bkQh)D#gyE>TO+5)Ebt33h^BkS!9WI0ywtTVr5} z1z}TvKzmEPL+L-Lt)U_4`%e48?>_I{d%yR7cR#_;VC5s~yB5SaIZNJ<(`u~oAWkrb zWt_rG9Ku_i!Pa2?6(^YY(2rjjz;E>7??8{IUmw6pAu1xwKpi}Xs$dya1FN_~(GKd& zZEwH9XACia!$s_&YB0hr37ki@zJ?LpK-JLhz_B9*ZUrk&Q-\n" "Language-Team: fa \n" @@ -26,6 +26,10 @@ msgstr "مدیریت سایت" msgid "Menu" msgstr "منو" +#: fields.py:75 +msgid "Drag the circle or click on the image to set the image subject" +msgstr "دایره را بکشید یا بر روی تصویر کلیک کنید تا موضوع تصویر تنظیم شود" + #: models.py:5 msgid "id" msgstr "" @@ -58,11 +62,11 @@ msgstr "تم روشن" msgid "admin themes" msgstr "تم روشن" -#: templates/admin/base_site.html:5 +#: templates/admin/base_site.html:6 msgid "Django site admin" msgstr "مدیر سایت جنگو" -#: templates/admin/base_site.html:32 +#: templates/admin/base_site.html:34 msgid "Django administration" msgstr "مدیریت جنگو" @@ -99,14 +103,14 @@ msgstr "پشتیبانی" msgid "Developed by %(powered_by)s" msgstr "توسعه داده شده توسط %(powered_by)s" -msgid "Name" -msgstr "نام" +#~ msgid "Name" +#~ msgstr "نام" -msgid "Baton" -msgstr "باتون" +#~ msgid "Baton" +#~ msgstr "باتون" -msgid "Filter" -msgstr "فیلتر" +#~ msgid "Filter" +#~ msgstr "فیلتر" -msgid " Search contents... " -msgstr " جستجوی محتوا... " +#~ msgid " Search contents... " +#~ msgstr " جستجوی محتوا... " diff --git a/baton/locale/it/LC_MESSAGES/django.mo b/baton/locale/it/LC_MESSAGES/django.mo index a5129937a5e4789c5dec728d1018bee70732b9e9..449675a1103ccd9b3307b057bfd2052ea806da38 100644 GIT binary patch delta 511 zcmYk%J1;~*6bJCRcCj9X*CL1jWaBezBsw30 zicZ6KAWF4Fqx7G<3MV=9n^(@6xvP9uS|20j8-W-^&LFRl!^n4J2#SQL!Z|n%m;ToK zFx+Ff0xw}Ne1v8A3`gM$9D{Fv=U;FF>mRrhiIy1Z>Ri|_!7{U+=SK$;~fZ=={h6dXZJ&H&5!|*|D3A7X4$Phh62TV}Ah(3%1$WTbMSEJeX zaa7-|JDHF_(WKZZqscl_hSeF_tk~vMCYrpZT>F0;dGqL0D=#*ziM7kcmd={(r)cs1 zJ2FxGxU_qC;AE~ilf;IUcIt#J*`l_RlsAo;=M=R$)6~$8IBnS6OQ*?5!jv!A;waXJ la+@UDdn?wY^V%5Q>GoP$o{TwRF9{`_PMJ76XIrb)#4pQ!Vg>*J delta 419 zcmXZYKT88a5QpK}TLNNZZ>gY- zU?YN^pCFxfRu&>y_zv#CkLUgjJ9GCDT}OjaEf@+lMHa~gnI^wPYtx9#;1-6shYQ&A z&(E;R{Uw(11_QkHKA@iWh;@8J?R&?P$Ur{1nB&10u8~UNzj3?h2cj<4!&y8>UEm5M zyhk1QCIfXxLa$*{oE#r S_01X0^\n" "Language-Team: it \n" @@ -26,23 +26,43 @@ msgstr "Amministrazione sito" msgid "Menu" msgstr "Menu" +#: fields.py:75 +msgid "Drag the circle or click on the image to set the image subject" +msgstr "Trascina il cerchio o clicca sull'immagine per impostare la posizione del soggetto" + #: models.py:5 -msgid "Name" -msgstr "Nome" +msgid "id" +msgstr "" #: models.py:6 -msgid "Theme" -msgstr "Tema" +msgid "name" +msgstr "" #: models.py:7 -msgid "Active" +#, fuzzy +#| msgid "Theme" +msgid "theme" +msgstr "Tema" + +#: models.py:8 +#, fuzzy +#| msgid "Active" +msgid "active" msgstr "Attivo" -#: templates/admin/base_site.html:5 +#: models.py:20 +msgid "admin theme" +msgstr "" + +#: models.py:21 +msgid "admin themes" +msgstr "" + +#: templates/admin/base_site.html:6 msgid "Django site admin" msgstr "Amministrazione sito django" -#: templates/admin/base_site.html:27 +#: templates/admin/base_site.html:34 msgid "Django administration" msgstr "Amministrazione django" @@ -79,6 +99,9 @@ msgstr "Supporto" msgid "Developed by %(powered_by)s" msgstr "Sviluppato da %(powered_by)s" +#~ msgid "Name" +#~ msgstr "Nome" + #~ msgid "close" #~ msgstr "chiudi" diff --git a/baton/static/baton/app/dist/7a71a48e0bbd982d07192d15f.ttf b/baton/static/baton/app/dist/7a71a48e0bbd982d07192d15f.ttf deleted file mode 100644 index 8b886d42db3f4e79bc51143ef06a97a0eda48284..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34964 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 z 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 diff --git a/baton/static/baton/app/dist/baton.min.js b/baton/static/baton/app/dist/baton.min.js index aee06c8f..907198ba 100644 --- a/baton/static/baton/app/dist/baton.min.js +++ b/baton/static/baton/app/dist/baton.min.js @@ -1,2 +1,2 @@ /*! For license information please see baton.min.js.LICENSE.txt */ -(()=>{var t={888:(t,e,o)=>{"use strict";var n=o(414),r=o.n(n),a=o(72),i=o.n(a),c=o(668);i()(c.A,{insert:"head",singleton:!1}),c.A.locals;var l=o(305),s=o(692),m=o.n(s);function f(t,e){for(var o=0;o",{class:"navbar-toggler navbar-toggler-right","data-bs-toggle":"collapse"}).html('').click((function(){return m()(document.body).addClass("menu-open")}))),m()("#user-tools").contents().filter((function(){return 3===this.nodeType})).remove();var e=m()("
",{class:"dropdown"}).appendTo(m()("#user-tools")),o=m()("
",{class:"dropdown-menu dropdown-menu-right"}).appendTo(e);if(m()("#user-tools strong").addClass("dropdown-toggle btn btn-default").attr("data-bs-toggle","dropdown").prependTo(e),m()("#user-tools > a").addClass("dropdown-item").appendTo(o),m()("#logout-form").length&&(m()("#logout-form button").css("display","none"),m()("",{class:"dropdown-item","data-item":"logout"}).html(m()("#logout-form button").html()).on("click",(function(){m()("#logout-form").submit()})).appendTo(o)),!t.forceTheme){var n=this,r=m()("html").attr("data-bs-theme"),a=m()("",{class:"dropdown-item dropdown-item-theme"}).html("dark"===r?this.t.get("lightTheme"):this.t.get("darkTheme")).css("cursor","pointer").click((function(){var t=m()("html").attr("data-bs-theme");m()("hmtl").attr("data-theme","dark"===t?"light":"dark"),m()("html").attr("data-bs-theme","dark"===t?"light":"dark"),m()(this).html("dark"===t?n.t.get("darkTheme"):n.t.get("lightTheme")),localStorage.setItem("baton-theme","dark"===t?"light":"dark")}));0===o.find(".dropdown-item-theme").length&&o.append(a)}}},g=function(t){m()("#footer").appendTo("#content"),t.remove&&m()("#footer").remove()},b={init:function(t,e){this.Dispatcher=e,this.t=new p(m()("html").attr("lang")),this.collapsableUserArea=t.collapsableUserArea,this.menuTitle=t.menuTitle,this.searchField=t.searchField,this.appListUrl=t.api.app_list,this.gravatarUrl=t.api.gravatar,this.gravatarDefaultImg=t.gravatarDefaultImg,this.gravatarEnabled=t.gravatarEnabled,this.alwaysCollapsed=m()("#header").hasClass("menu-always-collapsed"),this.fixNodes(),this.brandingClone=m()("#branding").clone(),this.manageBrandingUserTools(),this.addThemeToggle(t),this.searchTimeout=null,this.manageSearchField(),this.fetchData(),this.setHeight();var o=this;m()(window).on("resize",(function(){o.setHeight(),o.manageBrandingUserTools(),o.addThemeToggle(t)}))},fixNodes:function(){var t=m()("
",{class:"container-fluid"});m()("#footer").before(t);var e=m()("
",{class:"row"}).appendTo(t);this.menu=m()("