Compare commits

..

462 Commits

Author SHA1 Message Date
smilerz
762b83934a Remove unsupported platform from Docker build 2025-12-12 09:26:52 -06:00
smilerz
ae820877d5 Merge pull request #4308 from smilerz/upstream-pr-20251212-043308
Sync 7 commits from fork: chore(deps): bump boto3 from 1.42.4 to 1.42.5 in the pip-patches group
2025-12-12 08:33:21 -06:00
GitHub Action
0d1b37997a Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-12-12 04:33:08 +00:00
dependabot[bot]
8990f4bbcb chore(deps): bump boto3 from 1.42.4 to 1.42.5 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.42.4 to 1.42.5
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.42.4...1.42.5)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.42.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 04:26:07 +00:00
dependabot[bot]
c265b9a729 chore(deps): bump recipe-scrapers in the pip-minors group
Bumps the pip-minors group with 1 update: [recipe-scrapers](https://github.com/hhursev/recipe-scrapers).


Updates `recipe-scrapers` from 15.10.0 to 15.11.0
- [Release notes](https://github.com/hhursev/recipe-scrapers/releases)
- [Commits](https://github.com/hhursev/recipe-scrapers/compare/15.10.0...15.11.0)

---
updated-dependencies:
- dependency-name: recipe-scrapers
  dependency-version: 15.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-11 04:33:49 +00:00
dependabot[bot]
6625943701 chore(deps): bump pytubefix in the pip-patches group
Bumps the pip-patches group with 1 update: [pytubefix](https://github.com/juanbindez/pytubefix).


Updates `pytubefix` from 10.3.5 to 10.3.6
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v10.3.5...v10.3.6)

---
updated-dependencies:
- dependency-name: pytubefix
  dependency-version: 10.3.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-11 04:28:08 +00:00
dependabot[bot]
788c2088f8 chore(deps): bump pytest from 9.0.0 to 9.0.2 in the pip-pytest group
Bumps the pip-pytest group with 1 update: [pytest](https://github.com/pytest-dev/pytest).


Updates `pytest` from 9.0.0 to 9.0.2
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/9.0.0...9.0.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 04:30:34 +00:00
dependabot[bot]
629e9dc881 chore(deps): bump django-treebeard in the pip-minors group
Bumps the pip-minors group with 1 update: [django-treebeard](https://github.com/django-treebeard/django-treebeard).


Updates `django-treebeard` from 4.7.1 to 4.8.0
- [Changelog](https://github.com/django-treebeard/django-treebeard/blob/master/CHANGES.md)
- [Commits](https://github.com/django-treebeard/django-treebeard/compare/4.7.1...4.8.0)

---
updated-dependencies:
- dependency-name: django-treebeard
  dependency-version: 4.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 04:25:58 +00:00
dependabot[bot]
ec2ee2bfad chore(deps): bump boto3 from 1.42.0 to 1.42.4 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.42.0 to 1.42.4
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.42.0...1.42.4)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.42.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-09 04:31:50 +00:00
dependabot[bot]
b24f1da8b5 chore(deps): bump pytest from 8.4.2 to 9.0.0
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.4.2 to 9.0.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.4.2...9.0.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-09 04:26:28 +00:00
smilerz
88a1099f06 Merge pull request #4293 from smilerz/upstream-pr-20251208-043911
Sync 4 commits from fork: chore(deps): bump boto3 from 1.41.5 to 1.42.0 in the pip-minors group
2025-12-08 08:06:42 -06:00
GitHub Action
bf574c16f4 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-12-08 04:39:11 +00:00
dependabot[bot]
6cac9a71ed chore(deps): bump boto3 from 1.41.5 to 1.42.0 in the pip-minors group
Bumps the pip-minors group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.41.5 to 1.42.0
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.41.5...1.42.0)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-08 04:32:24 +00:00
dependabot[bot]
6858a60fb1 chore(deps): bump django from 4.2.26 to 4.2.27 in the pip-patches group
Bumps the pip-patches group with 1 update: [django](https://github.com/django/django).


Updates `django` from 4.2.26 to 4.2.27
- [Commits](https://github.com/django/django/compare/4.2.26...4.2.27)

---
updated-dependencies:
- dependency-name: django
  dependency-version: 4.2.27
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-08 04:27:00 +00:00
dependabot[bot]
01f1c8c5c8 chore(deps): bump beautifulsoup4 in the pip-patches group
Bumps the pip-patches group with 1 update: [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/).


Updates `beautifulsoup4` from 4.14.2 to 4.14.3

---
updated-dependencies:
- dependency-name: beautifulsoup4
  dependency-version: 4.14.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-04 04:23:22 +00:00
smilerz
e45d25beb4 Merge pull request #4278 from smilerz/upstream-pr-20251202-002017
Sync 20 commits from fork: regenerate yarn.lock
2025-12-01 18:27:14 -06:00
smilerz
bec1580991 Merge pull request #324 from smilerz/dependabot/npm_and_yarn/vue/codemirror/autocomplete-6.20.0
chore(deps): bump @codemirror/autocomplete from 6.19.1 to 6.20.0 in /vue
2025-12-01 18:22:41 -06:00
GitHub Action
f453995aa3 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-12-02 00:20:17 +00:00
dependabot[bot]
cfe163d5a6 chore(deps): bump @codemirror/autocomplete from 6.19.1 to 6.20.0 in /vue
Bumps [@codemirror/autocomplete](https://github.com/codemirror/autocomplete) from 6.19.1 to 6.20.0.
- [Changelog](https://github.com/codemirror/autocomplete/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/autocomplete/compare/6.19.1...6.20.0)

---
updated-dependencies:
- dependency-name: "@codemirror/autocomplete"
  dependency-version: 6.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-02 00:19:32 +00:00
smilerz
51c3ce4c56 regenerate yarn.lock 2025-12-01 18:13:43 -06:00
smilerz
77fd354a22 update yarn.lock 2025-12-01 18:13:00 -06:00
dependabot[bot]
c2a42c572c chore(deps-dev): bump workbox-webpack-plugin from 7.3.0 to 7.4.0 in /vue
Bumps [workbox-webpack-plugin](https://github.com/googlechrome/workbox) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/googlechrome/workbox/releases)
- [Commits](https://github.com/googlechrome/workbox/compare/v7.3.0...v7.4.0)

---
updated-dependencies:
- dependency-name: workbox-webpack-plugin
  dependency-version: 7.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 18:13:00 -06:00
smilerz
0bd53daed7 Merge pull request #328 from smilerz/dependabot/npm_and_yarn/vue/workbox-navigation-preload-7.4.0
chore(deps-dev): bump workbox-navigation-preload from 7.3.0 to 7.4.0 in /vue
2025-12-01 16:50:04 -06:00
smilerz
6358ac8b18 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-navigation-preload-7.4.0 2025-12-01 16:46:58 -06:00
smilerz
02eca7a50c updated lock file 2025-12-01 16:37:17 -06:00
smilerz
f45e847ad2 Merge pull request #320 from smilerz/dependabot/npm_and_yarn/vue/workbox-window-7.4.0
chore(deps): bump workbox-window from 7.3.0 to 7.4.0 in /vue
2025-12-01 15:24:27 -06:00
smilerz
5555c48bcb Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-window-7.4.0 2025-12-01 15:21:03 -06:00
smilerz
295e0a12e7 Merge pull request #329 from smilerz/dependabot/npm_and_yarn/vue/workbox-background-sync-7.4.0
chore(deps-dev): bump workbox-background-sync from 7.3.0 to 7.4.0 in /vue
2025-12-01 15:19:43 -06:00
smilerz
b2402acccf Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-navigation-preload-7.4.0 2025-12-01 15:17:53 -06:00
smilerz
167cf1b693 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-background-sync-7.4.0 2025-12-01 15:16:28 -06:00
smilerz
606ba1fa45 Merge pull request #339 from smilerz/dependabot/npm_and_yarn/vue/node-forge-1.3.2
chore(deps): bump node-forge from 1.3.1 to 1.3.2 in /vue
2025-12-01 15:16:08 -06:00
dependabot[bot]
c4ec9c9b0f chore(deps): bump node-forge from 1.3.1 to 1.3.2 in /vue
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 20:45:10 +00:00
smilerz
c2ec3b94a9 Merge pull request #327 from smilerz/dependabot/npm_and_yarn/vue/workbox-precaching-7.4.0
chore(deps-dev): bump workbox-precaching from 7.3.0 to 7.4.0 in /vue
2025-12-01 14:13:46 -06:00
smilerz
163deaff28 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-window-7.4.0 2025-12-01 14:11:04 -06:00
smilerz
cf14bf2f68 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-precaching-7.4.0 2025-12-01 14:10:22 -06:00
smilerz
12facb53e4 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-navigation-preload-7.4.0 2025-12-01 14:09:59 -06:00
smilerz
89b8598cd7 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-background-sync-7.4.0 2025-12-01 14:09:16 -06:00
smilerz
33db1e49a1 Merge pull request #319 from smilerz/dependabot/npm_and_yarn/vue/prettier-3.7.1
chore(deps-dev): bump prettier from 3.6.2 to 3.7.1 in /vue
2025-12-01 13:18:37 -06:00
dependabot[bot]
96c89f7def chore(deps-dev): bump prettier from 3.6.2 to 3.7.1 in /vue
Bumps [prettier](https://github.com/prettier/prettier) from 3.6.2 to 3.7.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.6.2...3.7.1)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.7.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 19:15:13 +00:00
smilerz
a536f58daa Merge pull request #318 from smilerz/dependabot/npm_and_yarn/vue/npm-patches-34df835779
chore(deps): bump the npm-patches group in /vue with 4 updates
2025-12-01 13:11:59 -06:00
dependabot[bot]
cb0372343f chore(deps): bump the npm-patches group in /vue with 4 updates
Bumps the npm-patches group in /vue with 4 updates: [@codemirror/view](https://github.com/codemirror/view), [axios](https://github.com/axios/axios), [@vue/compiler-sfc](https://github.com/vuejs/core/tree/HEAD/packages/compiler-sfc) and [webpack-bundle-tracker](https://github.com/django-webpack/webpack-bundle-tracker).


Updates `@codemirror/view` from 6.38.6 to 6.38.8
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/compare/6.38.6...6.38.8)

Updates `axios` from 1.13.1 to 1.13.2
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.13.1...v1.13.2)

Updates `@vue/compiler-sfc` from 3.5.22 to 3.5.25
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/commits/v3.5.25/packages/compiler-sfc)

Updates `webpack-bundle-tracker` from 3.2.1 to 3.2.2
- [Release notes](https://github.com/django-webpack/webpack-bundle-tracker/releases)
- [Commits](https://github.com/django-webpack/webpack-bundle-tracker/compare/v3.2.1...v3.2.2)

---
updated-dependencies:
- dependency-name: "@codemirror/view"
  dependency-version: 6.38.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: axios
  dependency-version: 1.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/compiler-sfc"
  dependency-version: 3.5.25
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: webpack-bundle-tracker
  dependency-version: 3.2.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 19:08:39 +00:00
smilerz
748377b11c Merge pull request #321 from smilerz/dependabot/npm_and_yarn/vue/workbox-expiration-7.4.0
chore(deps-dev): bump workbox-expiration from 7.3.0 to 7.4.0 in /vue
2025-12-01 12:47:08 -06:00
smilerz
714d4f799b Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-expiration-7.4.0 2025-12-01 12:43:59 -06:00
smilerz
218d591f35 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-window-7.4.0 2025-12-01 12:43:54 -06:00
smilerz
1bb92428a7 Merge pull request #322 from smilerz/dependabot/npm_and_yarn/vue/core-js-3.47.0
chore(deps): bump core-js from 3.46.0 to 3.47.0 in /vue
2025-12-01 12:33:22 -06:00
smilerz
ccf29db1d3 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-background-sync-7.4.0 2025-12-01 12:30:25 -06:00
smilerz
de19818429 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-navigation-preload-7.4.0 2025-12-01 12:30:21 -06:00
smilerz
01e736bccc Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-precaching-7.4.0 2025-12-01 12:30:18 -06:00
smilerz
5f717d4e70 Merge branch 'working' into dependabot/npm_and_yarn/vue/core-js-3.47.0 2025-12-01 12:30:07 -06:00
smilerz
f79fb4dbc1 Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-expiration-7.4.0 2025-12-01 12:30:03 -06:00
smilerz
bd1926c57b Merge branch 'working' into dependabot/npm_and_yarn/vue/workbox-window-7.4.0 2025-12-01 12:30:01 -06:00
dependabot[bot]
6bebb04015 chore(deps): bump django-tables2 in the pip-minors group
Bumps the pip-minors group with 1 update: [django-tables2](https://github.com/jieter/django-tables2).


Updates `django-tables2` from 2.7.5 to 2.8.0
- [Changelog](https://github.com/jieter/django-tables2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jieter/django-tables2/compare/v2.7.5...v2.8.0)

---
updated-dependencies:
- dependency-name: django-tables2
  dependency-version: 2.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 05:19:57 +00:00
dependabot[bot]
a72bc2ddd6 chore(deps): bump boto3 from 1.41.3 to 1.41.5 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.41.3 to 1.41.5
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.41.3...1.41.5)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.41.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 05:09:31 +00:00
dependabot[bot]
44951bf648 chore(deps-dev): bump workbox-background-sync in /vue
Bumps [workbox-background-sync](https://github.com/googlechrome/workbox) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/googlechrome/workbox/releases)
- [Commits](https://github.com/googlechrome/workbox/compare/v7.3.0...v7.4.0)

---
updated-dependencies:
- dependency-name: workbox-background-sync
  dependency-version: 7.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 04:59:40 +00:00
dependabot[bot]
b1fc780f44 chore(deps-dev): bump workbox-navigation-preload in /vue
Bumps [workbox-navigation-preload](https://github.com/googlechrome/workbox) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/googlechrome/workbox/releases)
- [Commits](https://github.com/googlechrome/workbox/compare/v7.3.0...v7.4.0)

---
updated-dependencies:
- dependency-name: workbox-navigation-preload
  dependency-version: 7.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 04:59:31 +00:00
dependabot[bot]
cfb20edb9f chore(deps-dev): bump workbox-precaching from 7.3.0 to 7.4.0 in /vue
Bumps [workbox-precaching](https://github.com/googlechrome/workbox) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/googlechrome/workbox/releases)
- [Commits](https://github.com/googlechrome/workbox/compare/v7.3.0...v7.4.0)

---
updated-dependencies:
- dependency-name: workbox-precaching
  dependency-version: 7.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 04:59:24 +00:00
dependabot[bot]
0753be9d12 chore(deps): bump core-js from 3.46.0 to 3.47.0 in /vue
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.46.0 to 3.47.0.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.47.0/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-version: 3.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 04:58:26 +00:00
dependabot[bot]
db05479cbe chore(deps-dev): bump workbox-expiration from 7.3.0 to 7.4.0 in /vue
Bumps [workbox-expiration](https://github.com/googlechrome/workbox) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/googlechrome/workbox/releases)
- [Commits](https://github.com/googlechrome/workbox/compare/v7.3.0...v7.4.0)

---
updated-dependencies:
- dependency-name: workbox-expiration
  dependency-version: 7.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 04:58:06 +00:00
dependabot[bot]
c850737d24 chore(deps): bump workbox-window from 7.3.0 to 7.4.0 in /vue
Bumps [workbox-window](https://github.com/googlechrome/workbox) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/googlechrome/workbox/releases)
- [Commits](https://github.com/googlechrome/workbox/compare/v7.3.0...v7.4.0)

---
updated-dependencies:
- dependency-name: workbox-window
  dependency-version: 7.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 04:57:59 +00:00
dependabot[bot]
333ba1b3f0 chore(deps): bump boto3 from 1.41.0 to 1.41.3 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.41.0 to 1.41.3
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.41.0...1.41.3)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.41.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-28 04:25:10 +00:00
dependabot[bot]
cf31d3aea4 chore(deps): bump the pip-minors group with 2 updates
Bumps the pip-minors group with 2 updates: [boto3](https://github.com/boto/boto3) and [redis](https://github.com/redis/redis-py).


Updates `boto3` from 1.40.76 to 1.41.0
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.76...1.41.0)

Updates `redis` from 7.0.1 to 7.1.0
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](https://github.com/redis/redis-py/compare/v7.0.1...v7.1.0)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
- dependency-name: redis
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-27 04:27:04 +00:00
dependabot[bot]
27ad2b5a85 chore(deps): bump the pip-patches group with 2 updates
Bumps the pip-patches group with 2 updates: [pytubefix](https://github.com/juanbindez/pytubefix) and [redis](https://github.com/redis/redis-py).


Updates `pytubefix` from 10.3.4 to 10.3.5
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v10.3.4...v10.3.5)

Updates `redis` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](https://github.com/redis/redis-py/compare/v7.0.0...v7.0.1)

---
updated-dependencies:
- dependency-name: pytubefix
  dependency-version: 10.3.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: redis
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-25 04:28:25 +00:00
dependabot[bot]
c76dfeefe4 chore(deps): bump redis from 6.4.0 to 7.0.0
Bumps [redis](https://github.com/redis/redis-py) from 6.4.0 to 7.0.0.
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](https://github.com/redis/redis-py/compare/v6.4.0...v7.0.0)

---
updated-dependencies:
- dependency-name: redis
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 04:48:43 +00:00
dependabot[bot]
9caf1d4029 chore(deps): bump the pip-patches group with 3 updates
Bumps the pip-patches group with 3 updates: [boto3](https://github.com/boto/boto3), [django-allauth](https://github.com/sponsors/pennersr) and [pytubefix](https://github.com/juanbindez/pytubefix).


Updates `boto3` from 1.40.75 to 1.40.76
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.75...1.40.76)

Updates `django-allauth` from 65.13.0 to 65.13.1
- [Commits](https://github.com/sponsors/pennersr/commits)

Updates `pytubefix` from 10.3.3 to 10.3.4
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v10.3.3...v10.3.4)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.76
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: django-allauth
  dependency-version: 65.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: pytubefix
  dependency-version: 10.3.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 04:34:19 +00:00
smilerz
e432f6a625 Merge pull request #4244 from smilerz/upstream-pr-20251121-044244
Upstream pr 20251121 044244
2025-11-21 08:21:44 -06:00
smilerz
ade2c8c63a Merge branch 'tandoor-1' into upstream-pr-20251121-044244 2025-11-21 08:21:36 -06:00
GitHub Action
9c13a20cda Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-11-21 04:42:44 +00:00
dependabot[bot]
f9f0aed2d8 chore(deps): bump pytubefix in the pip-minors group
Bumps the pip-minors group with 1 update: [pytubefix](https://github.com/juanbindez/pytubefix).


Updates `pytubefix` from 10.2.1 to 10.3.3
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v10.2.1...v10.3.3)

---
updated-dependencies:
- dependency-name: pytubefix
  dependency-version: 10.3.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-21 04:36:11 +00:00
dependabot[bot]
1b4b2f401d chore(deps): bump boto3 from 1.40.74 to 1.40.75 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.74 to 1.40.75
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.74...1.40.75)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.75
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-21 04:30:15 +00:00
dependabot[bot]
a7bf8e452a chore(deps): bump pytest-asyncio in the pip-pytest group
Bumps the pip-pytest group with 1 update: [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio).


Updates `pytest-asyncio` from 1.2.0 to 1.3.0
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v1.2.0...v1.3.0)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-version: 1.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-18 04:33:07 +00:00
dependabot[bot]
c00fe4ac68 chore(deps): bump boto3 from 1.40.73 to 1.40.74 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.73 to 1.40.74
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.73...1.40.74)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.74
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-18 04:28:18 +00:00
dependabot[bot]
14c439b8e7 chore(deps): bump pillow from 11.3.0 to 12.0.0
Bumps [pillow](https://github.com/python-pillow/Pillow) from 11.3.0 to 12.0.0.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/11.3.0...12.0.0)

---
updated-dependencies:
- dependency-name: pillow
  dependency-version: 12.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-17 04:34:42 +00:00
dependabot[bot]
2c03451597 chore(deps): bump boto3 from 1.40.70 to 1.40.73 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.70 to 1.40.73
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.70...1.40.73)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.73
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-17 04:28:37 +00:00
dependabot[bot]
e85ebc0cab chore(deps): bump django-crispy-forms in the pip-minors group
Bumps the pip-minors group with 1 update: [django-crispy-forms](https://github.com/django-crispy-forms/django-crispy-forms).


Updates `django-crispy-forms` from 2.4 to 2.5
- [Release notes](https://github.com/django-crispy-forms/django-crispy-forms/releases)
- [Changelog](https://github.com/django-crispy-forms/django-crispy-forms/blob/main/CHANGELOG.md)
- [Commits](https://github.com/django-crispy-forms/django-crispy-forms/compare/2.4...2.5)

---
updated-dependencies:
- dependency-name: django-crispy-forms
  dependency-version: '2.5'
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-14 04:30:25 +00:00
dependabot[bot]
ea10333b23 chore(deps): bump boto3 from 1.40.69 to 1.40.70 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.69 to 1.40.70
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.69...1.40.70)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.70
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-14 04:25:02 +00:00
smilerz
e773cffa76 Merge pull request #4230 from smilerz/upstream-pr-20251113-043248
Sync 3 commits from fork: chore(deps): bump recipe-scrapers in the pip-minors group
2025-11-13 07:56:39 -06:00
GitHub Action
b795d72e39 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-11-13 04:32:48 +00:00
dependabot[bot]
be6c548ac1 chore(deps): bump recipe-scrapers in the pip-minors group
Bumps the pip-minors group with 1 update: [recipe-scrapers](https://github.com/hhursev/recipe-scrapers).


Updates `recipe-scrapers` from 15.9.0 to 15.10.0
- [Release notes](https://github.com/hhursev/recipe-scrapers/releases)
- [Commits](https://github.com/hhursev/recipe-scrapers/compare/15.9.0...15.10.0)

---
updated-dependencies:
- dependency-name: recipe-scrapers
  dependency-version: 15.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-13 04:26:12 +00:00
dependabot[bot]
23396821db chore(deps): bump markdown from 3.9 to 3.10 in the pip-minors group
Bumps the pip-minors group with 1 update: [markdown](https://github.com/Python-Markdown/markdown).


Updates `markdown` from 3.9 to 3.10
- [Release notes](https://github.com/Python-Markdown/markdown/releases)
- [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md)
- [Commits](https://github.com/Python-Markdown/markdown/compare/3.9.0...3.10.0)

---
updated-dependencies:
- dependency-name: markdown
  dependency-version: '3.10'
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-11 04:32:59 +00:00
dependabot[bot]
78c04e4b2d chore(deps): bump boto3 from 1.40.68 to 1.40.69 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.68 to 1.40.69
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.68...1.40.69)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.69
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-11 04:27:28 +00:00
smilerz
61a1d72d7e Merge pull request #4221 from smilerz/upstream-pr-20251110-045354
Sync 2 commits from fork: chore(deps): bump the pip-patches group with 4 updates
2025-11-10 12:55:46 -06:00
GitHub Action
ede6c52d63 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-11-10 04:53:54 +00:00
dependabot[bot]
372c904a96 chore(deps): bump the pip-patches group with 4 updates
Bumps the pip-patches group with 4 updates: [boto3](https://github.com/boto/boto3), [django](https://github.com/django/django), [django-webpack-loader](https://github.com/django-webpack/django-webpack-loader) and [icalendar](https://github.com/collective/icalendar).


Updates `boto3` from 1.40.65 to 1.40.68
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.65...1.40.68)

Updates `django` from 4.2.25 to 4.2.26
- [Commits](https://github.com/django/django/compare/4.2.25...4.2.26)

Updates `django-webpack-loader` from 3.2.1 to 3.2.2
- [Release notes](https://github.com/django-webpack/django-webpack-loader/releases)
- [Changelog](https://github.com/django-webpack/django-webpack-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/django-webpack/django-webpack-loader/compare/3.2.1...3.2.2)

Updates `icalendar` from 6.3.1 to 6.3.2
- [Release notes](https://github.com/collective/icalendar/releases)
- [Changelog](https://github.com/collective/icalendar/blob/main/CHANGES.rst)
- [Commits](https://github.com/collective/icalendar/compare/v6.3.1...v6.3.2)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.68
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: django
  dependency-version: 4.2.26
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: django-webpack-loader
  dependency-version: 3.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: icalendar
  dependency-version: 6.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 04:47:06 +00:00
dependabot[bot]
b500c97440 chore(deps): bump the pip-minors group with 2 updates
Bumps the pip-minors group with 2 updates: [django-allauth](https://github.com/sponsors/pennersr) and [pytubefix](https://github.com/juanbindez/pytubefix).


Updates `django-allauth` from 65.12.1 to 65.13.0
- [Commits](https://github.com/sponsors/pennersr/commits)

Updates `pytubefix` from 10.0.0 to 10.2.1
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v10.0.0...v10.2.1)

---
updated-dependencies:
- dependency-name: django-allauth
  dependency-version: 65.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
- dependency-name: pytubefix
  dependency-version: 10.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 04:38:32 +00:00
smilerz
daaf55c50f Merge pull request #4214 from smilerz/upstream-pr-20251107-043533
Sync 6 commits from fork: chore(deps): bump pytubefix from 9.5.1 to 10.0.0
2025-11-07 07:32:07 -06:00
GitHub Action
79358f0e58 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-11-07 04:35:33 +00:00
dependabot[bot]
e3fa6c656e chore(deps): bump pytubefix from 9.5.1 to 10.0.0
Bumps [pytubefix](https://github.com/juanbindez/pytubefix) from 9.5.1 to 10.0.0.
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v9.5.1...v10.0.0)

---
updated-dependencies:
- dependency-name: pytubefix
  dependency-version: 10.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-07 04:29:05 +00:00
dependabot[bot]
1521810537 chore(deps): bump boto3 from 1.40.64 to 1.40.65 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.64 to 1.40.65
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.64...1.40.65)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.65
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-07 04:24:37 +00:00
dependabot[bot]
67e8a2a835 chore(deps): bump bleach from 6.2.0 to 6.3.0 in the pip-minors group
Bumps the pip-minors group with 1 update: [bleach](https://github.com/mozilla/bleach).


Updates `bleach` from 6.2.0 to 6.3.0
- [Changelog](https://github.com/mozilla/bleach/blob/main/CHANGES)
- [Commits](https://github.com/mozilla/bleach/compare/v6.2.0...v6.3.0)

---
updated-dependencies:
- dependency-name: bleach
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-04 04:54:40 +00:00
dependabot[bot]
f770048c99 chore(deps): bump boto3 from 1.40.63 to 1.40.64 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.63 to 1.40.64
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.63...1.40.64)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.64
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-04 04:49:17 +00:00
dependabot[bot]
4d2db238cb chore(deps): bump python-dotenv in the pip-minors group
Bumps the pip-minors group with 1 update: [python-dotenv](https://github.com/theskumar/python-dotenv).


Updates `python-dotenv` from 1.1.1 to 1.2.1
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/theskumar/python-dotenv/compare/v1.1.1...v1.2.1)

---
updated-dependencies:
- dependency-name: python-dotenv
  dependency-version: 1.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 04:46:14 +00:00
dependabot[bot]
4e21d46120 chore(deps): bump the pip-patches group with 2 updates
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: boto3
  dependency-version: 1.40.63
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 04:36:59 +00:00
smilerz
1c5c69ba5c Merge pull request #4208 from smilerz/upstream-pr-20251102-203440
Sync 8 commits from fork: chore(deps): bump axios from 1.12.2 to 1.13.1 in /vue
2025-11-02 15:09:20 -06:00
GitHub Action
ebc7e3c6ac Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-11-02 20:34:40 +00:00
smilerz
f260f3ffcb Merge pull request #268 from smilerz/dependabot/npm_and_yarn/vue/core-js-3.46.0
chore(deps): bump core-js from 3.45.1 to 3.46.0 in /vue
2025-11-02 14:28:54 -06:00
smilerz
ef12579ee8 Merge branch 'working' into dependabot/npm_and_yarn/vue/core-js-3.46.0 2025-11-02 14:25:48 -06:00
dependabot[bot]
82e70c39d3 chore(deps): bump axios from 1.12.2 to 1.13.1 in /vue
Bumps [axios](https://github.com/axios/axios) from 1.12.2 to 1.13.1.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.12.2...v1.13.1)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.13.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-02 20:05:35 +00:00
smilerz
7174a611ac Merge branch 'working' into dependabot/npm_and_yarn/vue/core-js-3.46.0 2025-11-02 14:03:44 -06:00
dependabot[bot]
75607c7835 chore(deps): bump @codemirror/commands from 6.8.1 to 6.10.0 in /vue
Bumps [@codemirror/commands](https://github.com/codemirror/commands) from 6.8.1 to 6.10.0.
- [Changelog](https://github.com/codemirror/commands/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/commands/compare/6.8.1...6.10.0)

---
updated-dependencies:
- dependency-name: "@codemirror/commands"
  dependency-version: 6.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-02 20:00:24 +00:00
smilerz
dc58f00106 Merge branch 'working' into dependabot/npm_and_yarn/vue/core-js-3.46.0 2025-11-02 13:55:28 -06:00
smilerz
74774b917a Merge pull request #267 from smilerz/dependabot/npm_and_yarn/vue/codemirror/lang-markdown-6.5.0
chore(deps): bump @codemirror/lang-markdown from 6.3.4 to 6.5.0 in /vue
2025-11-02 13:55:18 -06:00
dependabot[bot]
e9a0b5216d chore(deps): bump core-js from 3.45.1 to 3.46.0 in /vue
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.45.1 to 3.46.0.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.46.0/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-version: 3.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-02 19:46:44 +00:00
dependabot[bot]
79997c5dd0 chore(deps): bump @codemirror/lang-markdown from 6.3.4 to 6.5.0 in /vue
Bumps [@codemirror/lang-markdown](https://github.com/codemirror/lang-markdown) from 6.3.4 to 6.5.0.
- [Changelog](https://github.com/codemirror/lang-markdown/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lang-markdown/compare/6.3.4...6.5.0)

---
updated-dependencies:
- dependency-name: "@codemirror/lang-markdown"
  dependency-version: 6.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-02 19:46:41 +00:00
smilerz
d866e1e7e1 Merge pull request #266 from smilerz/dependabot/npm_and_yarn/vue/npm-patches-56ed010613
chore(deps): bump the npm-patches group in /vue with 4 updates
2025-11-02 13:44:36 -06:00
smilerz
46fdee0acb Merge branch 'working' into dependabot/npm_and_yarn/vue/npm-patches-56ed010613 2025-11-02 13:33:39 -06:00
smilerz
4829b9fe62 Merge pull request #244 from smilerz/dependabot/docker/python-3.12.12-alpine3.21
chore(deps): bump python from 3.12-alpine3.21 to 3.12.12-alpine3.21
2025-11-02 13:30:51 -06:00
smilerz
7b437a0383 Merge branch 'working' into dependabot/docker/python-3.12.12-alpine3.21 2025-11-02 13:27:20 -06:00
dependabot[bot]
d7def5a37a chore(deps): bump the npm-patches group in /vue with 4 updates
Bumps the npm-patches group in /vue with 4 updates: [@codemirror/autocomplete](https://github.com/codemirror/autocomplete), [@codemirror/view](https://github.com/codemirror/view), [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser) and [typescript](https://github.com/microsoft/TypeScript).


Updates `@codemirror/autocomplete` from 6.19.0 to 6.19.1
- [Changelog](https://github.com/codemirror/autocomplete/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/autocomplete/compare/6.19.0...6.19.1)

Updates `@codemirror/view` from 6.38.4 to 6.38.6
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/compare/6.38.4...6.38.6)

Updates `@babel/eslint-parser` from 7.28.4 to 7.28.5
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.28.5/eslint/babel-eslint-parser)

Updates `typescript` from 5.9.2 to 5.9.3
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.9.2...v5.9.3)

---
updated-dependencies:
- dependency-name: "@codemirror/autocomplete"
  dependency-version: 6.19.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@codemirror/view"
  dependency-version: 6.38.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@babel/eslint-parser"
  dependency-version: 7.28.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: typescript
  dependency-version: 5.9.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-02 19:20:01 +00:00
smilerz
13bb916c85 fixes syntax error in service worker file 2025-11-02 13:15:07 -06:00
smilerz
169522f401 updated sw.js to handle script_name correctly 2025-11-02 13:01:21 -06:00
smilerz
8774e7c2f0 Merge branch 'working' into dependabot/docker/python-3.12.12-alpine3.21 2025-11-02 12:59:14 -06:00
smilerz
7440a433ba Merge pull request #4207 from smilerz/upstream-pr-20251031-043335
Sync 7 commits from fork: chore(deps): bump boto3 from 1.40.59 to 1.40.60 in the pip-patches group
2025-11-02 12:58:07 -06:00
GitHub Action
72b9728540 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-10-31 04:33:35 +00:00
dependabot[bot]
d6224ac2e4 chore(deps): bump boto3 from 1.40.59 to 1.40.60 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.59 to 1.40.60
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.59...1.40.60)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.60
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-31 04:26:19 +00:00
smilerz
f8ddf6af72 Merge branch 'working' into dependabot/docker/python-3.12.12-alpine3.21 2025-10-28 07:56:10 -05:00
dependabot[bot]
665e208932 chore(deps): bump boto3 from 1.40.58 to 1.40.59 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.58 to 1.40.59
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.58...1.40.59)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.59
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-28 04:29:03 +00:00
dependabot[bot]
48616ebbcf chore(deps): bump boto3 from 1.40.55 to 1.40.58 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.55 to 1.40.58
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.55...1.40.58)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.58
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 04:47:47 +00:00
dependabot[bot]
4b0734c988 chore(deps): bump the pip-patches group with 2 updates
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: boto3
  dependency-version: 1.40.55
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-21 04:34:23 +00:00
dependabot[bot]
28e7103dae chore(deps): bump the pip-patches group with 3 updates
Bumps the pip-patches group with 3 updates: [boto3](https://github.com/boto/boto3), [cryptography](https://github.com/pyca/cryptography) and [django-allauth](https://github.com/sponsors/pennersr).


Updates `boto3` from 1.40.51 to 1.40.54
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.51...1.40.54)

Updates `cryptography` from 46.0.1 to 46.0.3
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/46.0.1...46.0.3)

Updates `django-allauth` from 65.12.0 to 65.12.1
- [Commits](https://github.com/sponsors/pennersr/commits)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.54
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: cryptography
  dependency-version: 46.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: django-allauth
  dependency-version: 65.12.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 04:52:15 +00:00
dependabot[bot]
990e86f717 chore(deps): bump cryptography from 45.0.7 to 46.0.1
Bumps [cryptography](https://github.com/pyca/cryptography) from 45.0.7 to 46.0.1.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/45.0.7...46.0.1)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 46.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-17 04:42:38 +00:00
dependabot[bot]
85e93169b5 chore(deps): bump boto3 from 1.40.50 to 1.40.51 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.50 to 1.40.51
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.50...1.40.51)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.51
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-17 04:38:04 +00:00
smilerz
0e3a5611c6 Merge pull request #4164 from smilerz/upstream-pr-20251014-045347
Sync 4 commits from fork: chore(deps): bump aiohttp from 3.12.15 to 3.13.0 in the pip-minors group
2025-10-14 16:00:13 -05:00
GitHub Action
31b9fe1605 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-10-14 04:53:47 +00:00
dependabot[bot]
7963342574 chore(deps): bump aiohttp from 3.12.15 to 3.13.0 in the pip-minors group
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-14 04:47:10 +00:00
dependabot[bot]
80264c2822 chore(deps): bump the pip-patches group with 3 updates
Bumps the pip-patches group with 3 updates: [boto3](https://github.com/boto/boto3), [psycopg2-binary](https://github.com/psycopg/psycopg2) and [python-ldap](https://github.com/python-ldap/python-ldap).


Updates `boto3` from 1.40.49 to 1.40.50
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.49...1.40.50)

Updates `psycopg2-binary` from 2.9.10 to 2.9.11
- [Changelog](https://github.com/psycopg/psycopg2/blob/master/NEWS)
- [Commits](https://github.com/psycopg/psycopg2/compare/2.9.10...2.9.11)

Updates `python-ldap` from 3.4.4 to 3.4.5
- [Release notes](https://github.com/python-ldap/python-ldap/releases)
- [Changelog](https://github.com/python-ldap/python-ldap/blob/python-ldap-3.4.5/CHANGES)
- [Commits](https://github.com/python-ldap/python-ldap/compare/python-ldap-3.4.4...python-ldap-3.4.5)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.50
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: psycopg2-binary
  dependency-version: 2.9.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: python-ldap
  dependency-version: 3.4.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-14 04:41:35 +00:00
dependabot[bot]
9be9c5874f chore(deps): bump the pip-minors group with 2 updates
Bumps the pip-minors group with 2 updates: [django-allauth](https://github.com/sponsors/pennersr) and [django-oauth-toolkit](https://github.com/django-oauth/django-oauth-toolkit).


Updates `django-allauth` from 65.11.2 to 65.12.0
- [Commits](https://github.com/sponsors/pennersr/commits)

Updates `django-oauth-toolkit` from 3.0.1 to 3.1.0
- [Release notes](https://github.com/django-oauth/django-oauth-toolkit/releases)
- [Changelog](https://github.com/django-oauth/django-oauth-toolkit/blob/master/CHANGELOG.md)
- [Commits](https://github.com/django-oauth/django-oauth-toolkit/compare/3.0.1...3.1.0)

---
updated-dependencies:
- dependency-name: django-allauth
  dependency-version: 65.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
- dependency-name: django-oauth-toolkit
  dependency-version: 3.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 04:52:04 +00:00
dependabot[bot]
8115ed383b chore(deps): bump boto3 from 1.40.46 to 1.40.49 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.46 to 1.40.49
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.46...1.40.49)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.49
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 04:46:25 +00:00
dependabot[bot]
81152f626e chore(deps): bump python from 3.12-alpine3.21 to 3.12.12-alpine3.21
Bumps python from 3.12-alpine3.21 to 3.12.12-alpine3.21.

---
updated-dependencies:
- dependency-name: python
  dependency-version: 3.12.12-alpine3.21
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 04:34:19 +00:00
smilerz
4f7c480a8a Merge pull request #4144 from smilerz/upstream-pr-20251010-045056
Sync 7 commits from fork: chore(deps): bump pytest-cov from 6.3.0 to 7.0.0
2025-10-10 07:40:54 -05:00
GitHub Action
9d30664c14 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-10-10 04:50:56 +00:00
dependabot[bot]
cca86956cd chore(deps): bump pytest-cov from 6.3.0 to 7.0.0
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 6.3.0 to 7.0.0.
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v6.3.0...v7.0.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-10 04:43:46 +00:00
dependabot[bot]
bd0e06bdd6 chore(deps): bump boto3 from 1.40.45 to 1.40.46 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.45 to 1.40.46
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.45...1.40.46)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.46
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-10 04:39:24 +00:00
dependabot[bot]
e2581a3276 chore(deps): bump the pip-patches group with 2 updates
Bumps the pip-patches group with 2 updates: [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) and [boto3](https://github.com/boto/boto3).


Updates `beautifulsoup4` from 4.14.0 to 4.14.2

Updates `boto3` from 1.40.44 to 1.40.45
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.44...1.40.45)

---
updated-dependencies:
- dependency-name: beautifulsoup4
  dependency-version: 4.14.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: boto3
  dependency-version: 1.40.45
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-07 04:32:26 +00:00
dependabot[bot]
eef8d8d1be chore(deps): bump beautifulsoup4 in the pip-minors group
Bumps the pip-minors group with 1 update: [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/).


Updates `beautifulsoup4` from 4.13.5 to 4.14.0

---
updated-dependencies:
- dependency-name: beautifulsoup4
  dependency-version: 4.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 04:50:48 +00:00
dependabot[bot]
5fce383bb3 chore(deps): bump boto3 from 1.40.41 to 1.40.44 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.41 to 1.40.44
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.41...1.40.44)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.44
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 04:45:24 +00:00
dependabot[bot]
317c67d01c chore(deps): bump boto3 from 1.40.40 to 1.40.41 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.40 to 1.40.41
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.40...1.40.41)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.41
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-03 04:40:05 +00:00
smilerz
03e4904506 Merge pull request #4107 from smilerz/upstream-pr-20251002-002024
Sync 4 commits from fork: chore(deps): bump django in the pip group across 1 directory
2025-10-01 19:25:04 -05:00
smilerz
0461155b5d Merge pull request #225 from smilerz/dependabot/npm_and_yarn/vue/npm-patches-47266e4737
chore(deps): bump the npm-patches group in /vue with 4 updates
2025-10-01 19:21:39 -05:00
GitHub Action
cd3d3d3389 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-10-02 00:20:24 +00:00
dependabot[bot]
fde96522e8 chore(deps): bump the npm-patches group in /vue with 4 updates
Bumps the npm-patches group in /vue with 4 updates: [@codemirror/view](https://github.com/codemirror/view), [axios](https://github.com/axios/axios), [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser) and [@vue/compiler-sfc](https://github.com/vuejs/core/tree/HEAD/packages/compiler-sfc).


Updates `@codemirror/view` from 6.38.1 to 6.38.3
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/compare/6.38.1...6.38.3)

Updates `axios` from 1.12.0 to 1.12.2
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.12.0...v1.12.2)

Updates `@babel/eslint-parser` from 7.28.0 to 7.28.4
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.28.4/eslint/babel-eslint-parser)

Updates `@vue/compiler-sfc` from 3.5.20 to 3.5.22
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/commits/v3.5.22/packages/compiler-sfc)

---
updated-dependencies:
- dependency-name: "@codemirror/view"
  dependency-version: 6.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: axios
  dependency-version: 1.12.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@babel/eslint-parser"
  dependency-version: 7.28.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/compiler-sfc"
  dependency-version: 3.5.22
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-02 00:18:25 +00:00
smilerz
9ccfa6732a Merge pull request #226 from smilerz/dependabot/npm_and_yarn/vue/codemirror/autocomplete-6.19.0
chore(deps): bump @codemirror/autocomplete from 6.18.6 to 6.19.0 in /vue
2025-10-01 19:14:47 -05:00
smilerz
244f63c07c Merge branch 'working' into dependabot/npm_and_yarn/vue/codemirror/autocomplete-6.19.0 2025-10-01 19:11:32 -05:00
dependabot[bot]
f3df30a727 chore(deps): bump django in the pip group across 1 directory
Bumps the pip group with 1 update in the / directory: [django](https://github.com/django/django).


Updates `django` from 4.2.24 to 4.2.25
- [Commits](https://github.com/django/django/compare/4.2.24...4.2.25)

---
updated-dependencies:
- dependency-name: django
  dependency-version: 4.2.25
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 23:04:42 +00:00
dependabot[bot]
de377e30b0 chore(deps): bump @codemirror/autocomplete from 6.18.6 to 6.19.0 in /vue
Bumps [@codemirror/autocomplete](https://github.com/codemirror/autocomplete) from 6.18.6 to 6.19.0.
- [Changelog](https://github.com/codemirror/autocomplete/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/autocomplete/compare/6.18.6...6.19.0)

---
updated-dependencies:
- dependency-name: "@codemirror/autocomplete"
  dependency-version: 6.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 04:26:02 +00:00
dependabot[bot]
ded9fd4223 chore(deps): bump boto3 from 1.40.39 to 1.40.40 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.39 to 1.40.40
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.39...1.40.40)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.40
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-30 04:33:27 +00:00
dependabot[bot]
b8e77668aa chore(deps): bump the pip-patches group with 2 updates
Bumps the pip-patches group with 2 updates: [boto3](https://github.com/boto/boto3) and [pyyaml](https://github.com/yaml/pyyaml).


Updates `boto3` from 1.40.36 to 1.40.39
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.36...1.40.39)

Updates `pyyaml` from 6.0.2 to 6.0.3
- [Release notes](https://github.com/yaml/pyyaml/releases)
- [Changelog](https://github.com/yaml/pyyaml/blob/6.0.3/CHANGES)
- [Commits](https://github.com/yaml/pyyaml/compare/6.0.2...6.0.3)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.39
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: pyyaml
  dependency-version: 6.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 05:29:41 +00:00
smilerz
1f0eea5789 Merge pull request #4075 from smilerz/upstream-pr-20250926-045524
Sync 6 commits from fork: chore(deps): bump whitenoise from 6.10.0 to 6.11.0
2025-09-26 07:35:20 -05:00
GitHub Action
49e50c2834 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-26 04:55:24 +00:00
dependabot[bot]
176172c262 chore(deps): bump whitenoise from 6.10.0 to 6.11.0
Bumps [whitenoise](https://github.com/evansd/whitenoise) from 6.10.0 to 6.11.0.
- [Changelog](https://github.com/evansd/whitenoise/blob/main/docs/changelog.rst)
- [Commits](https://github.com/evansd/whitenoise/compare/6.10.0...6.11.0)

---
updated-dependencies:
- dependency-name: whitenoise
  dependency-version: 6.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-26 04:48:32 +00:00
dependabot[bot]
ec1a32f126 chore(deps): bump django-cors-headers from 4.8.0 to 4.9.0
Bumps [django-cors-headers](https://github.com/adamchainz/django-cors-headers) from 4.8.0 to 4.9.0.
- [Changelog](https://github.com/adamchainz/django-cors-headers/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/adamchainz/django-cors-headers/compare/4.8.0...4.9.0)

---
updated-dependencies:
- dependency-name: django-cors-headers
  dependency-version: 4.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-26 04:44:11 +00:00
dependabot[bot]
8c5c19fa81 chore(deps): bump boto3 from 1.40.35 to 1.40.36 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.35 to 1.40.36
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.35...1.40.36)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.36
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-26 04:39:35 +00:00
dependabot[bot]
d6ccec99b0 chore(deps): bump lxml from 6.0.1 to 6.0.2 in the pip-patches group
Bumps the pip-patches group with 1 update: [lxml](https://github.com/lxml/lxml).


Updates `lxml` from 6.0.1 to 6.0.2
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-6.0.1...lxml-6.0.2)

---
updated-dependencies:
- dependency-name: lxml
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-25 04:35:22 +00:00
dependabot[bot]
102a0976e5 chore(deps): bump boto3 from 1.40.34 to 1.40.35 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.34 to 1.40.35
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.34...1.40.35)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.35
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-23 04:34:40 +00:00
smilerz
1082f65e75 Merge pull request #4061 from smilerz/upstream-pr-20250922-044204
Sync 2 commits from fork: chore(deps): bump pytest-asyncio in the pip-pytest group
2025-09-22 07:24:30 -05:00
dependabot[bot]
a187331b6d chore(deps): bump boto3 from 1.40.31 to 1.40.34 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.31 to 1.40.34
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.31...1.40.34)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.34
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 12:22:45 +00:00
GitHub Action
9a5fb5cb80 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-22 04:42:04 +00:00
dependabot[bot]
42e4fe24b9 chore(deps): bump pytest-asyncio in the pip-pytest group
Bumps the pip-pytest group with 1 update: [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio).


Updates `pytest-asyncio` from 1.1.1 to 1.2.0
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v1.1.1...v1.2.0)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-version: 1.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 04:36:00 +00:00
dependabot[bot]
fa33819414 chore(deps): bump the pip-patches group with 2 updates
Bumps the pip-patches group with 2 updates: [boto3](https://github.com/boto/boto3) and [pytubefix](https://github.com/juanbindez/pytubefix).


Updates `boto3` from 1.40.30 to 1.40.31
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.30...1.40.31)

Updates `pytubefix` from 9.5.0 to 9.5.1
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v9.5.0...v9.5.1)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.31
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: pytubefix
  dependency-version: 9.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-19 04:35:53 +00:00
smilerz
06351b0c16 Merge pull request #4049 from smilerz/upstream-pr-20250917-044956
Sync 1 commit from fork: chore(deps): bump whitenoise in the pip-minors group
2025-09-17 06:58:53 -05:00
GitHub Action
5285e6424f Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-17 04:49:56 +00:00
dependabot[bot]
3202a290dc chore(deps): bump whitenoise in the pip-minors group
Bumps the pip-minors group with 1 update: [whitenoise](https://github.com/evansd/whitenoise).


Updates `whitenoise` from 6.9.0 to 6.10.0
- [Changelog](https://github.com/evansd/whitenoise/blob/main/docs/changelog.rst)
- [Commits](https://github.com/evansd/whitenoise/compare/6.9.0...6.10.0)

---
updated-dependencies:
- dependency-name: whitenoise
  dependency-version: 6.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-17 04:43:01 +00:00
smilerz
b70617eada Merge pull request #4045 from smilerz/upstream-pr-20250916-135127
Sync 4 commits from fork: chore(deps): bump pytest-asyncio in the pip-pytest group
2025-09-16 08:55:11 -05:00
GitHub Action
9ce924ce1f Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-16 13:51:27 +00:00
dependabot[bot]
60c85832d6 chore(deps): bump pytest-asyncio in the pip-pytest group
Bumps the pip-pytest group with 1 update: [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio).


Updates `pytest-asyncio` from 1.1.0 to 1.1.1
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-version: 1.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-16 13:50:35 +00:00
dependabot[bot]
0d96c6a380 chore(deps): bump django-cors-headers in the pip-minors group
Bumps the pip-minors group with 1 update: [django-cors-headers](https://github.com/adamchainz/django-cors-headers).


Updates `django-cors-headers` from 4.7.0 to 4.8.0
- [Changelog](https://github.com/adamchainz/django-cors-headers/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/adamchainz/django-cors-headers/compare/4.7.0...4.8.0)

---
updated-dependencies:
- dependency-name: django-cors-headers
  dependency-version: 4.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-16 13:44:29 +00:00
dependabot[bot]
7225cbdd61 chore(deps): bump boto3 from 1.40.29 to 1.40.30 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.29 to 1.40.30
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.29...1.40.30)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.30
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-16 04:39:52 +00:00
smilerz
098d29deeb Merge pull request #196 from smilerz/dependabot/npm_and_yarn/vue/npm_and_yarn-16c0b19af7
chore(deps): bump axios from 1.11.0 to 1.12.0 in /vue in the npm_and_yarn group across 1 directory
2025-09-15 08:34:35 -05:00
dependabot[bot]
4ce8e0c6a1 chore(deps): bump axios
Bumps the npm_and_yarn group with 1 update in the /vue directory: [axios](https://github.com/axios/axios).


Updates `axios` from 1.11.0 to 1.12.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.11.0...v1.12.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.12.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 13:31:18 +00:00
smilerz
8d770217a2 Merge pull request #4037 from smilerz/upstream-pr-20250915-045713
Sync 2 commits from fork: chore(deps): bump pytest-cov from 6.2.1 to 6.3.0 in the pip-pytest group
2025-09-15 08:26:00 -05:00
GitHub Action
462f2aa10a Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-15 04:57:13 +00:00
dependabot[bot]
1d5af4e48a chore(deps): bump pytest-cov from 6.2.1 to 6.3.0 in the pip-pytest group
Bumps the pip-pytest group with 1 update: [pytest-cov](https://github.com/pytest-dev/pytest-cov).


Updates `pytest-cov` from 6.2.1 to 6.3.0
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v6.2.1...v6.3.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 04:51:09 +00:00
dependabot[bot]
e62d392eee chore(deps): bump the pip-patches group with 2 updates
Bumps the pip-patches group with 2 updates: [boto3](https://github.com/boto/boto3) and [django-allauth](https://github.com/sponsors/pennersr).


Updates `boto3` from 1.40.26 to 1.40.29
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.26...1.40.29)

Updates `django-allauth` from 65.11.1 to 65.11.2
- [Commits](https://github.com/sponsors/pennersr/commits)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: django-allauth
  dependency-version: 65.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 04:46:13 +00:00
smilerz
e0473b748d Merge pull request #4028 from smilerz/upstream-pr-20250912-132527
Sync 2 commits from fork: chore(deps): bump markdown from 3.8.2 to 3.9 in the pip-minors group
2025-09-12 08:46:53 -05:00
GitHub Action
1da214a53f Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-12 13:25:27 +00:00
smilerz
86f46297c6 fixed wildcard in dependabot config 2025-09-12 08:20:01 -05:00
smilerz
136bd9d848 add vue and vue* to ignore rule in dependabot 2025-09-12 08:20:00 -05:00
dependabot[bot]
4b7ddc263c chore(deps): bump markdown from 3.8.2 to 3.9 in the pip-minors group
Bumps the pip-minors group with 1 update: [markdown](https://github.com/Python-Markdown/markdown).


Updates `markdown` from 3.8.2 to 3.9
- [Release notes](https://github.com/Python-Markdown/markdown/releases)
- [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md)
- [Commits](https://github.com/Python-Markdown/markdown/compare/3.8.2...3.9.0)

---
updated-dependencies:
- dependency-name: markdown
  dependency-version: '3.9'
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-12 04:37:47 +00:00
dependabot[bot]
f1f4e5f1a6 chore(deps): bump boto3 from 1.40.25 to 1.40.26 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.25 to 1.40.26
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.25...1.40.26)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.26
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-12 04:32:14 +00:00
smilerz
2a8c57ba10 Merge pull request #4020 from smilerz/upstream-pr-20250909-044442
Sync 1 commit from fork: chore(deps): bump boto3 from 1.40.24 to 1.40.25 in the pip-patches group
2025-09-09 08:15:34 -05:00
GitHub Action
280f8776c5 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-09 04:44:43 +00:00
dependabot[bot]
82d3f45090 chore(deps): bump boto3 from 1.40.24 to 1.40.25 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.24 to 1.40.25
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.24...1.40.25)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.25
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-09 04:37:08 +00:00
smilerz
edeb9b062a Merge pull request #4015 from smilerz/upstream-pr-20250908-150858
Sync 3 commits from fork: chore(deps): bump pytest from 8.4.1 to 8.4.2 in the pip-pytest group
2025-09-08 10:38:51 -05:00
GitHub Action
3b717664b8 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-08 15:08:58 +00:00
dependabot[bot]
bf3d5a8835 chore(deps): bump pytest from 8.4.1 to 8.4.2 in the pip-pytest group
Bumps the pip-pytest group with 1 update: [pytest](https://github.com/pytest-dev/pytest).


Updates `pytest` from 8.4.1 to 8.4.2
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.4.1...8.4.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 8.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 15:02:10 +00:00
dependabot[bot]
5cf061af30 chore(deps): bump django from 4.2.23 to 4.2.24
Bumps [django](https://github.com/django/django) from 4.2.23 to 4.2.24.
- [Commits](https://github.com/django/django/compare/4.2.23...4.2.24)

---
updated-dependencies:
- dependency-name: django
  dependency-version: 4.2.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 14:57:25 +00:00
dependabot[bot]
f3c72dc102 chore(deps): bump boto3 from 1.40.21 to 1.40.24 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.21 to 1.40.24
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.21...1.40.24)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 14:52:49 +00:00
smilerz
0b771f49fd Merge pull request #175 from smilerz/smilerz-patch-1
Remove comments from CodeQL analysis configuration
2025-09-08 09:49:27 -05:00
smilerz
b072aa4f9a Merge branch 'working' into smilerz-patch-1 2025-09-08 09:44:40 -05:00
smilerz
3a782d8114 Refactor CodeQL analysis configuration
Removed paths-ignore configuration and updated query options for CodeQL analysis.
2025-09-08 09:35:47 -05:00
smilerz
81eccea140 Update codeql-analysis.yml 2025-09-08 09:30:05 -05:00
smilerz
0f33ee5052 Re-add security-extended queries for CodeQL analysis 2025-09-08 09:21:03 -05:00
smilerz
825efd4eb9 Add security-extended queries to CodeQL workflow 2025-09-08 09:15:43 -05:00
smilerz
3d2758c6ad Update CodeQL queries format in workflow 2025-09-08 09:11:18 -05:00
smilerz
2f52413a7c Update queries format in CodeQL workflow 2025-09-08 09:09:54 -05:00
smilerz
b1d3159bd8 Simplify queries configuration in CodeQL workflow 2025-09-08 09:07:00 -05:00
smilerz
fcdf564d2b Remove comments from CodeQL analysis configuration 2025-09-08 08:41:32 -05:00
smilerz
823efe5050 Fix syntax for using security-extended query 2025-09-08 08:36:06 -05:00
smilerz
b88e012759 Update syntax in codeql-analysis.yml 2025-09-08 08:23:51 -05:00
smilerz
82a00bd388 Merge pull request #4008 from smilerz/upstream-pr-20250905-044308
Sync 1 commit from fork: chore(deps): bump cryptography in the pip-patches group
2025-09-05 07:57:08 -05:00
smilerz
a187fa2c8c Merge branch 'tandoor-1' into upstream-pr-20250905-044308 2025-09-05 07:56:54 -05:00
GitHub Action
d8b786a25a Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-05 04:43:08 +00:00
dependabot[bot]
55485e105e chore(deps): bump cryptography in the pip-patches group
Bumps the pip-patches group with 1 update: [cryptography](https://github.com/pyca/cryptography).


Updates `cryptography` from 45.0.6 to 45.0.7
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/45.0.6...45.0.7)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 45.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-05 04:36:25 +00:00
smilerz
293d8d6680 Merge pull request #4001 from smilerz/upstream-pr-20250904-141319
Sync 4 commits from fork: chore(deps): bump boto3 from 1.40.20 to 1.40.21 in the pip-patches group
2025-09-04 09:17:21 -05:00
GitHub Action
2eacacb021 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-09-04 14:13:19 +00:00
smilerz
459586ff77 Merge pull request #163 from smilerz/dependabot/npm_and_yarn/vue/npm-patches-287502959c
chore(deps): bump the npm-patches group in /vue with 8 updates
2025-09-04 09:10:23 -05:00
smilerz
3ed8d8ae98 Merge branch 'working' into dependabot/npm_and_yarn/vue/npm-patches-287502959c 2025-09-04 09:06:59 -05:00
dependabot[bot]
d77d62e806 chore(deps): bump boto3 from 1.40.20 to 1.40.21 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.20 to 1.40.21
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.20...1.40.21)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 14:05:52 +00:00
dependabot[bot]
eab8db2734 chore(deps): bump pytubefix from 9.4.1 to 9.5.0 in the pip-minors group
Bumps the pip-minors group with 1 update: [pytubefix](https://github.com/juanbindez/pytubefix).


Updates `pytubefix` from 9.4.1 to 9.5.0
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v9.4.1...v9.5.0)

---
updated-dependencies:
- dependency-name: pytubefix
  dependency-version: 9.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-03 01:07:01 +00:00
dependabot[bot]
623ce16801 chore(deps): bump the npm-patches group in /vue with 8 updates
Bumps the npm-patches group in /vue with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [@codemirror/lang-markdown](https://github.com/codemirror/lang-markdown) | `6.3.3` | `6.3.4` |
| [@vue/cli](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli) | `5.0.8` | `5.0.9` |
| [@vue/cli-plugin-babel](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-babel) | `5.0.8` | `5.0.9` |
| [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-eslint) | `5.0.8` | `5.0.9` |
| [@vue/cli-plugin-pwa](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-pwa) | `5.0.8` | `5.0.9` |
| [@vue/cli-plugin-typescript](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-typescript) | `5.0.8` | `5.0.9` |
| [@vue/cli-service](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-service) | `5.0.8` | `5.0.9` |
| [@vue/compiler-sfc](https://github.com/vuejs/core/tree/HEAD/packages/compiler-sfc) | `3.5.18` | `3.5.20` |


Updates `@codemirror/lang-markdown` from 6.3.3 to 6.3.4
- [Changelog](https://github.com/codemirror/lang-markdown/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lang-markdown/compare/6.3.3...6.3.4)

Updates `@vue/cli` from 5.0.8 to 5.0.9
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.9/packages/@vue/cli)

Updates `@vue/cli-plugin-babel` from 5.0.8 to 5.0.9
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.9/packages/@vue/cli-plugin-babel)

Updates `@vue/cli-plugin-eslint` from 5.0.8 to 5.0.9
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.9/packages/@vue/cli-plugin-eslint)

Updates `@vue/cli-plugin-pwa` from 5.0.8 to 5.0.9
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.9/packages/@vue/cli-plugin-pwa)

Updates `@vue/cli-plugin-typescript` from 5.0.8 to 5.0.9
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.9/packages/@vue/cli-plugin-typescript)

Updates `@vue/cli-service` from 5.0.8 to 5.0.9
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.9/packages/@vue/cli-service)

Updates `@vue/compiler-sfc` from 3.5.18 to 3.5.20
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/commits/v3.5.20/packages/compiler-sfc)

---
updated-dependencies:
- dependency-name: "@codemirror/lang-markdown"
  dependency-version: 6.3.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/cli"
  dependency-version: 5.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/cli-plugin-babel"
  dependency-version: 5.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/cli-plugin-eslint"
  dependency-version: 5.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/cli-plugin-pwa"
  dependency-version: 5.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/cli-plugin-typescript"
  dependency-version: 5.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/cli-service"
  dependency-version: 5.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/compiler-sfc"
  dependency-version: 3.5.20
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 11:21:23 +00:00
dependabot[bot]
dfac02cc53 chore(deps): bump the pip-patches group with 2 updates
Bumps the pip-patches group with 2 updates: [boto3](https://github.com/boto/boto3) and [django-allauth](https://github.com/sponsors/pennersr).


Updates `boto3` from 1.40.17 to 1.40.20
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.17...1.40.20)

Updates `django-allauth` from 65.11.0 to 65.11.1
- [Commits](https://github.com/sponsors/pennersr/commits)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: django-allauth
  dependency-version: 65.11.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 08:33:26 +00:00
smilerz
b99e461e10 Merge pull request #3979 from smilerz/upstream-pr-20250829-045007
Sync 2 commits from fork: chore(deps): bump django-allauth in the pip-minors group
2025-08-29 08:18:15 -05:00
GitHub Action
9f66ca34d9 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-29 04:50:07 +00:00
dependabot[bot]
53e075953d chore(deps): bump django-allauth in the pip-minors group
Bumps the pip-minors group with 1 update: [django-allauth](https://github.com/sponsors/pennersr).


Updates `django-allauth` from 65.10.0 to 65.11.0
- [Commits](https://github.com/sponsors/pennersr/commits)

---
updated-dependencies:
- dependency-name: django-allauth
  dependency-version: 65.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-29 04:43:29 +00:00
dependabot[bot]
d060629477 chore(deps): bump boto3 from 1.40.16 to 1.40.17 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.16 to 1.40.17
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.16...1.40.17)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-29 04:38:01 +00:00
smilerz
b7b34c775c Merge pull request #3976 from smilerz/upstream-pr-20250828-163118
Sync 7 commits from fork: chore(deps): bump the npm-minors group in /vue with 2 updates
2025-08-28 11:48:32 -05:00
GitHub Action
2f2b07cb4c Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-28 16:31:18 +00:00
smilerz
900e6abc6d Merge pull request #147 from smilerz/dependabot/npm_and_yarn/vue/npm-minors-010af39555
chore(deps): bump the npm-minors group in /vue with 2 updates
2025-08-28 11:26:02 -05:00
dependabot[bot]
63458261a8 chore(deps): bump the npm-minors group in /vue with 2 updates
Bumps the npm-minors group in /vue with 2 updates: [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) and [typescript](https://github.com/microsoft/TypeScript).


Updates `core-js` from 3.44.0 to 3.45.1
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.45.1/packages/core-js)

Updates `typescript` from 5.8.3 to 5.9.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.8.3...v5.9.2)

---
updated-dependencies:
- dependency-name: core-js
  dependency-version: 3.45.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-minors
- dependency-name: typescript
  dependency-version: 5.9.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 16:18:50 +00:00
smilerz
65776080a6 updated brace-expansion 2025-08-28 11:05:32 -05:00
dependabot[bot]
1016a9b9dc chore(deps): bump the pip-patches group across 1 directory with 3 updates
Bumps the pip-patches group with 3 updates in the / directory: [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/), [boto3](https://github.com/boto/boto3) and [lxml](https://github.com/lxml/lxml).


Updates `beautifulsoup4` from 4.13.4 to 4.13.5

Updates `boto3` from 1.40.15 to 1.40.16
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.15...1.40.16)

Updates `lxml` from 6.0.0 to 6.0.1
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-6.0.0...lxml-6.0.1)

---
updated-dependencies:
- dependency-name: beautifulsoup4
  dependency-version: 4.13.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: boto3
  dependency-version: 1.40.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: lxml
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 15:25:30 +00:00
smilerz
c518bcde8f use freezegun to freeze time so that date based searches work consistently 2025-08-28 10:19:14 -05:00
smilerz
17f49c3827 Merge pull request #152 from smilerz/smilerz-patch-1
Disable warnings in Django testing step
2025-08-28 08:35:26 -05:00
smilerz
48e0cb6588 Disable warnings in Django testing step 2025-08-28 08:31:18 -05:00
smilerz
bb09928d73 supress warnings during CI 2025-08-28 08:27:41 -05:00
smilerz
2b8f10a2a7 Refactor test_search_date to use fixed UTC reference date
Because:
- Timezone-dependent tests caused inconsistent results
- CI and local runs could differ near day boundaries
- Workflow concurrency settings needed cleanup

Refactors test_search_date and found_recipe to use a fixed UTC reference date for all recipe creation and queries, eliminating timezone issues. Removes concurrency blocks from workflows for clarity and reliability. Affects .github/workflows/dependabot-automerge.yml, docker-publish.yml, push-orchestrator.yml, and test_recipe_full_text_search.py. No breaking changes, but test results now deterministic across environments.
2025-08-28 07:28:20 -05:00
smilerz
db0ddf2a60 added concurrency to workflows 2025-08-27 22:04:57 -05:00
smilerz
51849937bb added debug message to test 2025-08-27 21:50:58 -05:00
smilerz
e640ccb603 Merge pull request #3973 from smilerz/upstream-pr-20250828-023533
Sync 1 commit from fork: Refactor connector hooks to use DTOs, update manager and tests
2025-08-27 21:44:22 -05:00
GitHub Action
1e812a8ef5 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-28 02:35:33 +00:00
smilerz
2c186ab72e Refactor connector hooks to use DTOs, update manager and tests
Because:
- Connector hooks needed safe, serializable DTOs
- Manager and tests required updates for new DTO interface
- Code style and clarity improvements were needed
- Redundant date test logic removed

Refactors connector interface and manager to use UserDTO and ShoppingListEntryDTO.
Updates connector manager logic and tests to match new DTO signatures.
Improves code style in test_recipe_full_text_search.py and removes unnecessary date test block.
Breaking change: downstream connectors must update hook signatures.
2025-08-27 20:58:47 -05:00
smilerz
a6aa162527 Merge pull request #3969 from smilerz/upstream-pr-20250825-124428
Sync 3 commits from fork: chore(deps): bump django-allauth in the pip-minors group
2025-08-25 07:47:17 -05:00
GitHub Action
fd2be921d0 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-25 12:44:29 +00:00
dependabot[bot]
5710dcc85f chore(deps): bump django-allauth in the pip-minors group
Bumps the pip-minors group with 1 update: [django-allauth](https://github.com/sponsors/pennersr).


Updates `django-allauth` from 65.10.0 to 65.11.0
- [Commits](https://github.com/sponsors/pennersr/commits)

---
updated-dependencies:
- dependency-name: django-allauth
  dependency-version: 65.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-25 12:38:03 +00:00
dependabot[bot]
64bfd89225 chore(deps): bump django-debug-toolbar from 5.2.0 to 6.0.0
Bumps [django-debug-toolbar](https://github.com/django-commons/django-debug-toolbar) from 5.2.0 to 6.0.0.
- [Release notes](https://github.com/django-commons/django-debug-toolbar/releases)
- [Changelog](https://github.com/django-commons/django-debug-toolbar/blob/main/docs/changes.rst)
- [Commits](https://github.com/django-commons/django-debug-toolbar/compare/5.2.0...6.0.0)

---
updated-dependencies:
- dependency-name: django-debug-toolbar
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-25 12:30:55 +00:00
dependabot[bot]
41fd7334dc chore(deps): bump boto3 from 1.40.12 to 1.40.15 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.12 to 1.40.15
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.12...1.40.15)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-25 09:03:03 +00:00
smilerz
1afae2b77c Merge pull request #3958 from smilerz/upstream-pr-20250822-053647
Sync 2 commits from fork: chore(deps): bump the pip-patches group with 2 updates
2025-08-22 06:46:07 -05:00
GitHub Action
9b1ff9fd6e Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-22 05:36:47 +00:00
dependabot[bot]
64b4f8c1d1 chore(deps): bump the pip-patches group with 2 updates
Bumps the pip-patches group with 2 updates: [boto3](https://github.com/boto/boto3) and [requests](https://github.com/psf/requests).


Updates `boto3` from 1.40.11 to 1.40.12
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.11...1.40.12)

Updates `requests` from 2.32.4 to 2.32.5
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.4...v2.32.5)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: requests
  dependency-version: 2.32.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-22 05:30:22 +00:00
dependabot[bot]
d03e991cdc chore(deps): bump boto3 from 1.40.10 to 1.40.11 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.10 to 1.40.11
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.10...1.40.11)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-19 17:16:01 +00:00
smilerz
dfe73d2f95 Merge pull request #3945 from smilerz/upstream-pr-20250818-081648
Sync 1 commit from fork: chore(deps): bump boto3 from 1.40.7 to 1.40.10 in the pip-patches group
2025-08-18 08:26:32 -05:00
GitHub Action
dfb0aa9609 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-18 08:16:48 +00:00
dependabot[bot]
79805cea66 chore(deps): bump boto3 from 1.40.7 to 1.40.10 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.7 to 1.40.10
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.7...1.40.10)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 08:10:11 +00:00
smilerz
89130998a4 Merge pull request #3939 from smilerz/upstream-pr-20250815-052458
Sync 2 commits from fork: chore(deps): bump redis from 6.3.0 to 6.4.0 in the pip-minors group
2025-08-15 08:14:15 -05:00
GitHub Action
ec11a81d1e Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-15 05:24:58 +00:00
dependabot[bot]
92d7993137 chore(deps): bump redis from 6.3.0 to 6.4.0 in the pip-minors group
Bumps the pip-minors group with 1 update: [redis](https://github.com/redis/redis-py).


Updates `redis` from 6.3.0 to 6.4.0
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](https://github.com/redis/redis-py/compare/v6.3.0...v6.4.0)

---
updated-dependencies:
- dependency-name: redis
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-15 05:18:12 +00:00
dependabot[bot]
2ea8792568 chore(deps): bump boto3 from 1.40.6 to 1.40.7 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.6 to 1.40.7
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.6...1.40.7)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-15 05:12:39 +00:00
smilerz
4148fe6d28 Merge pull request #3936 from smilerz/upstream-pr-20250813-135943
Sync 3 commits from fork: chore(deps): bump the npm-patches group in /vue with 2 updates (#104)
2025-08-13 09:27:04 -05:00
GitHub Action
7aea9e2927 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-13 13:59:43 +00:00
dependabot[bot]
37df1ddccd chore(deps): bump the npm-patches group in /vue with 2 updates (#104)
Bumps the npm-patches group in /vue with 2 updates: [@codemirror/view](https://github.com/codemirror/view) and [@vue/compiler-sfc](https://github.com/vuejs/core/tree/HEAD/packages/compiler-sfc).


Updates `@codemirror/view` from 6.38.0 to 6.38.1
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/compare/6.38.0...6.38.1)

Updates `@vue/compiler-sfc` from 3.5.17 to 3.5.18
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/commits/v3.5.18/packages/compiler-sfc)

---
updated-dependencies:
- dependency-name: "@codemirror/view"
  dependency-version: 6.38.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-patches
- dependency-name: "@vue/compiler-sfc"
  dependency-version: 3.5.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: smilerz <smilerz@gmail.com>
2025-08-13 08:54:07 -05:00
dependabot[bot]
df64277c7f chore(deps): bump the npm-minors group in /vue with 2 updates (#105)
Bumps the npm-minors group in /vue with 2 updates: [axios](https://github.com/axios/axios) and [typescript](https://github.com/microsoft/TypeScript).


Updates `axios` from 1.10.0 to 1.11.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.10.0...v1.11.0)

Updates `typescript` from 5.1.6 to 5.8.3
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.1.6...v5.8.3)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-minors
- dependency-name: typescript
  dependency-version: 5.8.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: smilerz <smilerz@gmail.com>
2025-08-13 13:05:10 +00:00
dependabot[bot]
0505da4f83 chore(deps): bump redis from 6.2.0 to 6.3.0 in the pip-minors group
Bumps the pip-minors group with 1 update: [redis](https://github.com/redis/redis-py).


Updates `redis` from 6.2.0 to 6.3.0
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](https://github.com/redis/redis-py/compare/v6.2.0...v6.3.0)

---
updated-dependencies:
- dependency-name: redis
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 05:15:34 +00:00
smilerz
b268ccedd8 Merge pull request #3934 from smilerz/upstream-pr-20250812-125815
Sync 1 commit from fork: chore(deps): bump boto3 from 1.40.5 to 1.40.6 in the pip-patches group
2025-08-12 07:59:11 -05:00
GitHub Action
80a60a5b13 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-12 12:58:15 +00:00
dependabot[bot]
46ace24f53 chore(deps): bump boto3 from 1.40.5 to 1.40.6 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.40.5 to 1.40.6
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.5...1.40.6)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 12:52:00 +00:00
smilerz
d0542d02da Merge pull request #3931 from smilerz/upstream-pr-20250811-130526
Sync 1 commit from fork: chore(deps): bump recipe-scrapers in the pip-minors group
2025-08-11 08:07:36 -05:00
GitHub Action
b050ca7714 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-11 13:05:26 +00:00
dependabot[bot]
b0684d679c chore(deps): bump recipe-scrapers in the pip-minors group
Bumps the pip-minors group with 1 update: [recipe-scrapers](https://github.com/hhursev/recipe-scrapers).


Updates `recipe-scrapers` from 15.8.0 to 15.9.0
- [Release notes](https://github.com/hhursev/recipe-scrapers/releases)
- [Commits](https://github.com/hhursev/recipe-scrapers/compare/15.8.0...15.9.0)

---
updated-dependencies:
- dependency-name: recipe-scrapers
  dependency-version: 15.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 12:58:42 +00:00
smilerz
76c642239f Merge pull request #3930 from smilerz/upstream-pr-20250811-072606
Sync 1 commit from fork: chore(deps): bump the pip-patches group with 3 updates
2025-08-11 07:50:18 -05:00
GitHub Action
2542a0c6f8 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-11 07:26:07 +00:00
dependabot[bot]
dbacb315da chore(deps): bump the pip-patches group with 3 updates
Bumps the pip-patches group with 3 updates: [boto3](https://github.com/boto/boto3), [cryptography](https://github.com/pyca/cryptography) and [djangorestframework](https://github.com/encode/django-rest-framework).


Updates `boto3` from 1.40.0 to 1.40.5
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.40.0...1.40.5)

Updates `cryptography` from 45.0.5 to 45.0.6
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/45.0.5...45.0.6)

Updates `djangorestframework` from 3.16.0 to 3.16.1
- [Release notes](https://github.com/encode/django-rest-framework/releases)
- [Commits](https://github.com/encode/django-rest-framework/compare/3.16.0...3.16.1)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: cryptography
  dependency-version: 45.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: djangorestframework
  dependency-version: 3.16.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 07:19:44 +00:00
smilerz
66ec659354 Merge pull request #3918 from smilerz/upstream-pr-20250808-051522
Sync 1 commit from fork: chore(deps): bump boto3 from 1.39.17 to 1.40.0 in the pip-minors group
2025-08-08 07:18:36 -05:00
GitHub Action
25f9188fc1 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-08 05:15:22 +00:00
dependabot[bot]
aaf297e63f chore(deps): bump boto3 from 1.39.17 to 1.40.0 in the pip-minors group
Bumps the pip-minors group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.39.17 to 1.40.0
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.39.17...1.40.0)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.40.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 05:08:51 +00:00
smilerz
03a74ec5ec Merge pull request #3900 from smilerz/upstream-pr-20250804-065404
Sync 2 commits from fork: chore(deps): bump the pip-patches group with 2 updates
2025-08-04 07:49:34 -05:00
GitHub Action
83f3c4f657 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-08-04 06:54:04 +00:00
dependabot[bot]
3725f4ea0e chore(deps): bump the pip-patches group with 2 updates
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.12.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: boto3
  dependency-version: 1.39.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-04 06:47:38 +00:00
dependabot[bot]
debc8aef69 chore(deps): bump boto3 from 1.39.14 to 1.39.15 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.39.14 to 1.39.15
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.39.14...1.39.15)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.39.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 04:50:08 +00:00
smilerz
b3e0235a9e Merge pull request #3857 from smilerz/upstream-pr-20250730-052740
Sync 4 commits from fork: chore(deps): bump pytubefix from 9.3.0 to 9.4.1 in the pip-minors group
2025-07-31 11:27:21 -05:00
GitHub Action
c0972dd390 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-07-30 05:27:40 +00:00
dependabot[bot]
d90cadcb9c chore(deps): bump pytubefix from 9.3.0 to 9.4.1 in the pip-minors group
Bumps the pip-minors group with 1 update: [pytubefix](https://github.com/juanbindez/pytubefix).


Updates `pytubefix` from 9.3.0 to 9.4.1
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v9.3.0...v9.4.1)

---
updated-dependencies:
- dependency-name: pytubefix
  dependency-version: 9.4.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 05:21:26 +00:00
dependabot[bot]
e40d61c7ef chore(deps): bump lxml from 5.4.0 to 6.0.0
Bumps [lxml](https://github.com/lxml/lxml) from 5.4.0 to 6.0.0.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-5.4.0...lxml-6.0.0)

---
updated-dependencies:
- dependency-name: lxml
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-29 06:36:04 +00:00
dependabot[bot]
6aaac55017 chore(deps): bump boto3 from 1.39.13 to 1.39.14 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.39.13 to 1.39.14
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.39.13...1.39.14)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.39.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-29 06:31:46 +00:00
dependabot[bot]
d28a4ef3a0 chore(deps): bump boto3 from 1.39.10 to 1.39.13 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.39.10 to 1.39.13
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.39.10...1.39.13)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.39.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 06:22:21 +00:00
smilerz
09c8271289 include body in PR link 2025-07-25 17:02:52 -05:00
smilerz
57fea5698e Merge pull request #3850 from smilerz/upstream-pr-20250725-215052
Sync 1 commit from fork: Refactor requirements.txt and workflow automation
2025-07-25 16:56:20 -05:00
GitHub Action
30930734d8 Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-07-25 21:50:52 +00:00
smilerz
50db2e31cf fixed link for PR 2025-07-25 16:45:26 -05:00
smilerz
ec5b8e93a9 Rename workflow to Stage Branch for PR and update file name
Because:
- Workflow now stages a branch and opens an issue for manual PR
- Name and file should reflect current function

Renames workflow to 'Stage Branch for PR' and file to stage-branch-for-pr.yml. No breaking changes. Affects: .github/workflows/stage-branch-for-pr.yml
2025-07-25 16:34:19 -05:00
smilerz
8f0ff70813 Refactor requirements.txt and workflow automation
Because:
- requirements.txt was unsorted, making review and maintenance harder
- Workflow PR instructions were manual and unclear

Alphabetized requirements.txt main and dev sections, preserving all version pins and comments. Updated .github/workflows/create-upstream-pr.yml to open a GitHub issue for manual PR tracking, replacing console instructions. No breaking changes. requirements.txt, .github/workflows/create-upstream-pr.yml.
2025-07-25 16:18:15 -05:00
smilerz
99c5b22745 Fix: filter infra files and skip PR if no code changes or commits
Because:
- Infra-only changes should not trigger PRs
- PRs should only be created for real code changes

Filters infra files from file count and summary. Skips PR creation if no code files or commits. Affects create-upstream-pr.yml. No breaking changes.
2025-07-25 11:01:35 -05:00
smilerz
6678b3ccfe Fix multi-line output for changes_summary in workflow
Because:
- GitHub Actions requires heredoc for multi-line outputs
- Previous output format caused file command errors

Uses heredoc for changes_summary in summarize_changes step. Affects create-upstream-pr.yml. No breaking changes.
2025-07-25 10:40:52 -05:00
smilerz
41d95bc0f5 Update PR summary to list changed files
Because:
- PR summary did not enumerate changed files
- Improved clarity for reviewers

Adds formatted file list to changes summary in create-upstream-pr.yml. Removes redundant separator in PR body. No breaking changes. Affects only workflow file.
2025-07-25 10:20:35 -05:00
smilerz
d58a2a2823 Merge pull request #3849 from smilerz/upstream-pr-20250725-130828
Sync 26 commits from fork: chore(deps): bump boto3 from 1.39.9 to 1.39.10 in the pip-patches group
2025-07-25 08:24:34 -05:00
GitHub Action
47569858fb Restore upstream infrastructure files for PR
- Removed fork-specific .gitattributes
- Restored upstream .github/workflows/
- Restored upstream cookbook/version_info.py
2025-07-25 13:08:28 +00:00
smilerz
33c161c836 Update upstream PR workflow to filter infra-only commits
Because:
- Commits touching only infra files (all .github, cookbook/version_info.py, .gitattributes) should not be included in PR content
- Only commits with non-infra file changes still different from upstream should be included

Affects .github/workflows/create-upstream-pr.yml. No breaking changes. No test code affected.
2025-07-25 08:02:28 -05:00
dependabot[bot]
8f568c0425 chore(deps): bump boto3 from 1.39.9 to 1.39.10 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.39.9 to 1.39.10
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.39.9...1.39.10)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.39.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-25 04:36:50 +00:00
smilerz
2e36378f2d use github app token everywhere 2025-07-24 16:32:54 -05:00
smilerz
143bfa97b6 fix syntax error in create-upstream-pr.yml 2025-07-24 16:08:18 -05:00
smilerz
70285d8b14 Update streamline upstream PR workflow and remove file filter
Because:
- Infra file restore must occur before merge to avoid conflicts
- Redundant code file filtering step was unnecessary after infra reset

Moves infra file restore before merge in .github/workflows/create-upstream-pr.yml.
Removes filter step and updates downstream logic to use all changed files.
Improves comments and step clarity. No breaking changes.
2025-07-24 15:57:57 -05:00
smilerz
7fb6379d71 Update create-upstream-pr workflow for correct branch and infra sync
Because:
- Previous workflow had duplicate and out-of-order steps
- Needed to ensure correct branch creation, upstream merge, and infra file reset

Refactors workflow to:
- Create branch and push to fork
- Merge upstream/tandoor-1 into new branch
- Restore infra files from upstream and push again
- Removes duplicate and redundant steps

Affects: .github/workflows/create-upstream-pr.yml
No breaking changes. No test code affected.
2025-07-24 13:51:51 -05:00
smilerz
a4aff4551f dewubgging output added 2025-07-24 11:36:41 -05:00
dependabot[bot]
000395fbd2 chore(deps): bump form-data in /vue in the npm_and_yarn group (#89)
Bumps the npm_and_yarn group in /vue with 1 update: [form-data](https://github.com/form-data/form-data).


Updates `form-data` from 4.0.3 to 4.0.4
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](https://github.com/form-data/form-data/compare/v4.0.3...v4.0.4)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: smilerz <smilerz@gmail.com>
2025-07-24 16:25:12 +00:00
smilerz
339032de14 disable fine grained permissions for troubleshooting 2025-07-24 11:04:45 -05:00
smilerz
30f5071e37 force actions to run 2025-07-24 10:50:15 -05:00
smilerz
701a74b68c Update PR workflow to use GitHub App token for branch push
Because:
- GitHub Actions cannot push workflow file changes with default GITHUB_TOKEN
- GitHub App token is required for workflow file updates

Adds a step to generate a GitHub App token and uses it for pushing the branch. Follows the pattern from dependabot-automerge.yml. Affects create-upstream-pr.yml. No breaking changes. All PRs will now be able to push workflow file changes if needed.
2025-07-24 10:23:05 -05:00
smilerz
6a6ef9b13e update actions permissions to write 2025-07-24 10:03:09 -05:00
smilerz
8c333063be add workflow write permissions to create-upstream-pr.yml 2025-07-24 08:27:02 -05:00
smilerz
1ea59a76c2 Refactor PR workflow to exclude infra files
Because:
- PRs must never add, modify, or delete infrastructure files
- Infra file logic, counting, and removal is not needed
- Reset infra files to upstream state before push

Removes all logic for infra file tracking, counting, and removal. Now only code files are included in PRs. Infra files are always reset to upstream/tandoor-1 before push. Affects create-upstream-pr.yml. No breaking changes. All PRs will now be infra-clean by construction.
2025-07-24 07:31:42 -05:00
dependabot[bot]
dcfbb71d89 chore(deps): bump pytest-asyncio in the pip-pytest group
Bumps the pip-pytest group with 1 update: [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio).


Updates `pytest-asyncio` from 1.0.0 to 1.1.0
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v1.0.0...v1.1.0)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-version: 1.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 05:10:38 +00:00
dependabot[bot]
74a0650f11 chore(deps): bump boto3 from 1.39.8 to 1.39.9 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.39.8 to 1.39.9
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.39.8...1.39.9)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.39.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-22 06:07:42 +00:00
dependabot[bot]
a870cafd2c chore(deps): bump boto3 from 1.39.4 to 1.39.8 in the pip-patches group
Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3).


Updates `boto3` from 1.39.4 to 1.39.8
- [Release notes](https://github.com/boto/boto3/releases)
- [Commits](https://github.com/boto/boto3/compare/1.39.4...1.39.8)

---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.39.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-21 05:56:50 +00:00
smilerz
7b856e4556 fixed syntax error 2025-07-20 11:22:46 -05:00
smilerz
d28918df94 Fix PR title/body output propagation in workflow
Because:
- PR title and body were not set as outputs in github-script step
- Downstream steps require outputs for correct PR instructions
- Each line under 72 chars

Adds core.setOutput for prTitle and prBody in build_pr_content. Affects .github/workflows/create-upstream-pr.yml. No breaking changes.
2025-07-20 11:06:12 -05:00
smilerz
5d3a93e4c4 Refactor PR title and body generation in workflow
Because:
- Old logic tried to find a PR for the triggering commit, which never exists
- Upstream maintainers need a summary of all commits in the branch
- Each line under 72 chars

Removes get_trigger_pr step and builds PR title/body from commit list. Affects .github/workflows/create-upstream-pr.yml. No breaking changes.
2025-07-20 10:36:18 -05:00
smilerz
9703d9db35 Update workflow to guide manual PR creation after branch push
Because:
- Automated PR creation from forks is blocked by GitHub permissions
- Users need clear, actionable instructions to open PRs manually

Removes automated PR creation and related steps. Adds a step to print a direct PR link and suggested title/body after branch push. Only .github/workflows/create-upstream-pr.yml affected. No breaking changes.
2025-07-18 14:43:00 -05:00
smilerz
c6ff2e3c58 Fix jq array output in file filter step
Because:
- Downstream steps require valid JSON arrays for code/infrastructure files
- Previous jq usage could produce malformed output

Updates .github/workflows/create-upstream-pr.yml to use 'jq -sc' for correct array output in code/infrastructure file filtering. No breaking changes. No follow-up required.
2025-07-18 14:01:58 -05:00
smilerz
813aa85554 Fix: Output code_files and infra_files as JSON arrays
Because:
- GitHub Actions scripts require valid JSON for file lists
- Prevents JSON.parse errors in github-script steps

Now uses jq to emit code_files and infra_files as JSON arrays in filter_files step. Affects .github/workflows/create-upstream-pr.yml. No breaking changes.
2025-07-18 12:56:57 -05:00
smilerz
61b18c9442 Update workflow to remove infrastructure files before fork push
Because:
- GitHub Actions cannot push workflow files from forks due to permission restrictions
- Prevents workflow errors and keeps upstream infrastructure intact

Adds a step to remove .github, cookbook/version_info.py, and .gitattributes before pushing to fork. Only code changes are pushed for upstream PR. Affects .github/workflows/create-upstream-pr.yml. No breaking changes.
2025-07-18 12:31:15 -05:00
smilerz
d4d968f399 Remove legacy upstream-pr workflow
Because:
- Only create-upstream-pr.yml should be used for upstream PR automation
- upstream-pr.yml enforced divergence checks and manual sync, causing confusion

Deletes .github/workflows/upstream-pr.yml. Ensures only the updated workflow logic is used. No breaking changes. No impact on code or tests.
2025-07-18 11:32:03 -05:00
smilerz
d22669272a Fix workflow to only block on merge conflicts
Because:
- Diverged branches are not a blocker if merge is clean
- Previous logic blocked on divergence, not actual conflicts

Updates .github/workflows/create-upstream-pr.yml to only fail if a merge conflict occurs during upstream merge. No longer blocks or warns on branch divergence alone. No breaking changes. Workflow now matches real merge safety requirements.
2025-07-18 11:16:35 -05:00
smilerz
871074ef45 Fix workflow: restore infra files before merge
Because:
- Merge conflicts in infrastructure files caused manual intervention
- Upstream infra files must always be preferred to avoid drift

Moves 'Restore upstream infrastructure files' step before 'Merge upstream branch' in create-upstream-pr.yml. Ensures .github/workflows/ and cookbook/version_info.py are always restored from upstream before merging. No breaking changes. Affects .github/workflows/create-upstream-pr.yml only.
2025-07-18 11:00:08 -05:00
smilerz
2954334e1f refactored: update create-upstream-pr workflow 2025-07-18 07:45:07 -05:00
dependabot[bot]
1879cb20bc chore(deps): bump django-allauth in the pip-minors group
Bumps the pip-minors group with 1 update: [django-allauth](https://github.com/sponsors/pennersr).


Updates `django-allauth` from 65.9.0 to 65.10.0
- [Commits](https://github.com/sponsors/pennersr/commits)

---
updated-dependencies:
- dependency-name: django-allauth
  dependency-version: 65.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-18 05:51:13 +00:00
smilerz
42b36e4bee add ingredient context setting to UserPreferenceStore 2025-07-14 19:15:53 -05:00
smilerz
4370232031 reverted updated pluralization on DRF Autoschema 2025-07-14 18:40:34 -05:00
smilerz
4bbf408a68 Fix infra-only divergence detection in workflow
Because:
- Previous logic did not strictly list files ahead in upstream
- Needed accurate detection for infra-only divergence

Updates .github/workflows/create-upstream-pr.yml to use git log --name-only refs/remotes/upstream/tandoor-1 ^working for correct file listing. No breaking changes. Infra-only divergence now correctly detected.
2025-07-14 14:32:37 -05:00
smilerz
cb06de7f89 Update infra divergence logic and sync dependencies
Because:
- Divergence in infra files should not block PRs
- Dependency tree needed deduplication and updates
- Each line under 72 chars

.github/workflows/create-upstream-pr.yml: Adds logic to skip divergence errors if only infrastructure files differ. vue/package.json, vue/yarn.lock: Adds/updates several dependencies and synchronizes lockfile. No breaking changes. No test code affected.
2025-07-14 14:07:54 -05:00
smilerz
763f53f579 update accidentally changed files during rebase 2025-07-14 12:33:13 -05:00
smilerz
69fb501b37 rebase fixes 2025-07-14 12:03:46 -05:00
smilerz
ee027863ed Update upgrade for body-parser, brace-expansion, lodash.template
Because:
- Security advisories for these packages
- Vue 2 compatibility limits further upgrades

Upgrades body-parser to 1.20.3, brace-expansion to 1.1.12, lodash.template to 4.5.0
in vue/package.json and vue/yarn.lock. No breaking changes. Remaining advisories
require major upgrades incompatible with Vue 2.
2025-07-14 11:58:17 -05:00
smilerz
7e9abcc3ee update create-upstream-pr.yml workflow 2025-07-14 11:58:17 -05:00
smilerz
f5fe770991 Update Node.js to 20 in CI and Docker workflows
Because:
- Node.js 18 is deprecated and no longer supported
- Ensures CI and Docker builds use the latest LTS version

Updates .github/workflows/ci.yml and docker-publish.yml to use only Node.js 20. Removes Node.js 18 from matrix and build steps. No breaking changes expected. All CI and container builds now standardized on Node.js 20.
2025-07-14 11:58:16 -05:00
smilerz
91921d2179 refine upstream PR workflow 2025-07-14 11:58:16 -05:00
dependabot[bot]
cba0ad2862 chore(deps): bump the pip-patches group with 2 updates
---
updated-dependencies:
- dependency-name: boto3
  dependency-version: 1.39.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
- dependency-name: aiohttp
  dependency-version: 3.12.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip-patches
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:58:16 -05:00
dependabot[bot]
d613e8c5d2 chore(deps): bump pytubefix from 9.2.2 to 9.3.0 in the pip-minors group
---
updated-dependencies:
- dependency-name: pytubefix
  dependency-version: 9.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:58:15 -05:00
smilerz
92b06c47d5 Merge upstream changes while preserving custom workflows and version info
- Updated all upstream changes from tandoor-1
- Preserved custom GitHub workflows and version_info.py
- Comprehensive sync excluding only protected files
2025-07-14 11:58:15 -05:00
smilerz
d547607feb Update .gitattributes with custom merge driver for complete file protection 2025-07-14 11:58:14 -05:00
smilerz
400f025169 Add .gitattributes for selective merge control 2025-07-14 11:58:14 -05:00
smilerz
7372f7513c WIP: build workflow to create upstream PR on docker publish 2025-07-14 11:58:13 -05:00
smilerz
de509aca9f Update auto-merge workflow to use official actions/create-github-app-token
Because:
- Primary GitHub action is preferred over 3rd party for token generation
- actions/create-github-app-token is not deprecated and is the recommended approach

Replaces tibdex/github-app-token with actions/create-github-app-token in dependabot-automerge.yml. Updates input keys to match official action. No breaking changes. Only .github/workflows/dependabot-automerge.yml affected.
2025-07-14 11:58:12 -05:00
smilerz
46abee647f remove devcontainer updates in dependabot.yml 2025-07-14 11:58:12 -05:00
smilerz
378e503ea4 update offical github actions to pinned versions 2025-07-14 11:58:11 -05:00
smilerz
a7c54c4b96 remvoe labels from npm-patches 2025-07-14 11:58:10 -05:00
smilerz
71b64f61d0 update github workflow permissions 2025-07-14 11:58:10 -05:00
smilerz
6ae3245a79 Update GitHub Actions security with SHA pinning and minimal permissions
Because:
- Actions used version tags vulnerable to supply chain attacks
- Workflows lacked minimal permission scoping for security
- Required immutable references per security best practices

Pins all GitHub Actions to latest SHA commits with version comments across 5 workflow files. Adds minimal permissions at workflow and job levels following principle of least privilege. Updates ci.yml, codeql-analysis.yml, dependabot-automerge.yml, docker-publish.yml, push-orchestrator.yml. Enhances dependabot.yml with automerge labels for npm patches. No breaking changes.
2025-07-14 11:58:08 -05:00
smilerz
e2c058db1c update dependabot configuration 2025-07-14 11:58:06 -05:00
dependabot[bot]
7aa476f822 chore(deps): bump recipe-scrapers in the pip-minors group
Bumps the pip-minors group with 1 update: [recipe-scrapers](https://github.com/hhursev/recipe-scrapers).


Updates `recipe-scrapers` from 15.7.0 to 15.8.0
- [Release notes](https://github.com/hhursev/recipe-scrapers/releases)
- [Commits](https://github.com/hhursev/recipe-scrapers/compare/15.7.0...15.8.0)

---
updated-dependencies:
- dependency-name: recipe-scrapers
  dependency-version: 15.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:58:06 -05:00
smilerz
77e60643f9 update dependabot 2025-07-14 11:58:05 -05:00
smilerz
85e5613254 fixed tibdex/github-app-token@v2.1.0 2025-07-14 11:58:05 -05:00
smilerz
04f5fe02d5 Refactor GitHub Actions workflow architecture
Because:
- Push events triggered CI on every push causing redundant runs
- Docker builds ran unnecessarily when CI failed
- Dependabot automerge lacked proper validation and security
- Workflow files had inconsistent naming and structure

Restructures CI/CD pipeline with push orchestrator controlling workflow execution.
Adds conditional CI execution based on PR merge detection. Updates dependabot
automerge with enhanced validation, bot token usage, and security restrictions.
Renames docker-publish-fork.yml to docker-publish.yml for clarity. Removes
duplicate validate-pr-labels.yml logic now handled in dependabot workflow.
Downgrades recipe-scrapers to 15.7.0 for compatibility. Affects all GitHub
Actions workflows and requirements.txt.
2025-07-14 11:58:02 -05:00
dependabot[bot]
b0b773fe44 chore(deps): bump recipe-scrapers in the pip-minors group
Bumps the pip-minors group with 1 update: [recipe-scrapers](https://github.com/hhursev/recipe-scrapers).


Updates `recipe-scrapers` from 15.7.0 to 15.8.0
- [Release notes](https://github.com/hhursev/recipe-scrapers/releases)
- [Commits](https://github.com/hhursev/recipe-scrapers/compare/15.7.0...15.8.0)

---
updated-dependencies:
- dependency-name: recipe-scrapers
  dependency-version: 15.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:58:01 -05:00
smilerz
75f884161e Update requirements.txt 2025-07-14 11:58:01 -05:00
smilerz
658f9e0c7b downgrade to python 3.12 2025-07-14 11:58:00 -05:00
dependabot[bot]
2e15a91c08 chore(deps): bump recipe-scrapers in the pip-minors group
Bumps the pip-minors group with 1 update: [recipe-scrapers](https://github.com/hhursev/recipe-scrapers).


Updates `recipe-scrapers` from 15.7.0 to 15.8.0
- [Release notes](https://github.com/hhursev/recipe-scrapers/releases)
- [Commits](https://github.com/hhursev/recipe-scrapers/compare/15.7.0...15.8.0)

---
updated-dependencies:
- dependency-name: recipe-scrapers
  dependency-version: 15.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:58:00 -05:00
smilerz
29b463fa4a testing 2025-07-14 11:58:00 -05:00
dependabot[bot]
eea53c71ab chore(deps): bump the pip-minors group with 2 updates
Bumps the pip-minors group with 2 updates: [recipe-scrapers](https://github.com/hhursev/recipe-scrapers) and [pytubefix](https://github.com/juanbindez/pytubefix).


Updates `recipe-scrapers` from 15.7.0 to 15.8.0
- [Release notes](https://github.com/hhursev/recipe-scrapers/releases)
- [Commits](https://github.com/hhursev/recipe-scrapers/compare/15.7.0...15.8.0)

Updates `pytubefix` from 9.1.1 to 9.2.2
- [Release notes](https://github.com/juanbindez/pytubefix/releases)
- [Commits](https://github.com/juanbindez/pytubefix/compare/v9.1.1...v9.2.2)

---
updated-dependencies:
- dependency-name: recipe-scrapers
  dependency-version: 15.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
- dependency-name: pytubefix
  dependency-version: 9.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip-minors
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:57:59 -05:00
smilerz
a6ca6075ad troubleshooting tasks 2025-07-14 11:57:59 -05:00
smilerz
811c5e51ba test behavior of push trigger with file filter 2025-07-14 11:57:58 -05:00
dependabot[bot]
e4e2da8790 chore(deps)(deps): bump python from 3.12-alpine3.21 to 3.13-alpine3.21
Bumps python from 3.12-alpine3.21 to 3.13-alpine3.21.

---
updated-dependencies:
- dependency-name: python
  dependency-version: 3.13-alpine3.21
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:57:58 -05:00
smilerz
a3c3740805 Update dependabot.yml 2025-07-14 11:57:57 -05:00
smilerz
abf203db7e Add push trigger for Dependabot Docker builds
Because:
- Dependabot dependency updates need immediate Docker builds
- Workflow_run trigger has delays and complexity
- Direct push events are more reliable for automation

Adds push trigger on working branch for dependency files and workflows. Updates conditional logic to handle push events from dependabot[bot]. Removes comment header from dependabot.yml and adds dependencies label.
2025-07-14 11:57:57 -05:00
dependabot[bot]
b824b1112c chore(deps): bump peter-evans/create-or-update-comment
Bumps [peter-evans/create-or-update-comment](https://github.com/peter-evans/create-or-update-comment) from 3.1.0 to 4.0.0.
- [Release notes](https://github.com/peter-evans/create-or-update-comment/releases)
- [Commits](23ff15729e...71345be026)

---
updated-dependencies:
- dependency-name: peter-evans/create-or-update-comment
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:57:56 -05:00
smilerz
d75e568ad6 Fix Dependabot workflow trigger events
Because:
- Workflow only ran on labeled/opened events
- PR updates (synchronize) weren't triggering auto-merge
- Reopened PRs needed workflow re-execution

Adds synchronize and reopened events to pull_request_target trigger in dependabot-automerge.yml. Ensures workflow runs when Dependabot updates PRs with new commits or when PRs are reopened.
2025-07-14 11:57:56 -05:00
smilerz
555e3aa095 Update Dependabot automerge workflow and config
Because:
- Auto-approve action needed integrated review message
- Previous automerge action was suboptimal
- Dependabot label naming inconsistency

Replaces alexwilson/enable-github-automerge-action with daneden/enable-automerge-action for better author validation. Adds review message to hmarr/auto-approve-action. Updates dependabot.yml label from github-actions to github_actions for consistency.
2025-07-14 11:57:55 -05:00
smilerz
cc2dc072a0 Optimize Docker workflow to prevent skipped jobs
Because:
- Workflow triggered on all branches creating many skipped jobs
- Branch filtering at trigger level is more efficient
- Redundant head_branch check was unnecessary

Adds branches filter to workflow_run trigger and simplifies conditional logic in docker-publish-fork.yml. Prevents workflow from starting on non-working branches, eliminating skipped job clutter.
2025-07-14 11:57:55 -05:00
smilerz
f47142acbe Update Dependabot merge method from SQUASH to REBASE
Because:
- SQUASH blocks sequential PRs when branches become out-of-date
- REBASE provides linear history without blocking issues
- GitHub auto-merge handles branch updates automatically with REBASE

Changes merge-method in dependabot-automerge.yml workflow. Eliminates need for manual branch update logic and prevents sequential PR conflicts.
2025-07-14 11:57:54 -05:00
smilerz
b3deccc8ea Fix Dependabot merge method parameter
Because:
- API expects uppercase merge method value
- squash was invalid, causing workflow failures
- GitHub GraphQL requires SQUASH not squash

Changes merge-method from squash to SQUASH in dependabot-automerge.yml workflow. Fixes PullRequestMergeMethod validation error.
2025-07-14 11:57:54 -05:00
smilerz
4609d25c32 Update Dependabot to run daily for pip packages
Because:
- Weekly updates were too slow for critical dependencies
- Recipe-scrapers needed faster patch deployment
- Custom workflow was security risk with manual approval

Changes Dependabot pip schedule from weekly to daily in dependabot.yml. Reduces patch cooldown to 1 day. Removes custom auto-update-recipe-scrapers.yml workflow to consolidate all updates through secure Dependabot flow. Adds artifact retention to CI workflow.
2025-07-14 11:57:53 -05:00
smilerz
90f018479a Fix Dependabot workflow permissions error
Because:
- pull_request events have read-only token permissions
- Dependabot auto-merge was failing with access errors
- Workflow needs write permissions for PR approval

Changes pull_request to pull_request_target in dependabot-automerge.yml workflow. This provides necessary write permissions for auto-approval and merge actions triggered by Dependabot PRs.
2025-07-14 11:57:52 -05:00
smilerz
c5f78aebdc pin peter-evans/create-or-update-comment version to v4.0.0 2025-07-14 11:57:52 -05:00
smilerz
9572211cac Update GitHub workflows and dependency management
Because:
- Dependabot automerge needed dedicated workflow
- Recipe scrapers automation was complex and error-prone
- CodeQL analysis had unnecessary matrix complexity
- Development dependencies needed proper separation

Adds dependabot-automerge.yml and validate-pr-labels.yml workflows.
Refactors auto-update-recipe-scrapers.yml to simplify update logic.
Removes matrix strategy from codeql-analysis.yml for clarity.
Updates dependabot.yml to exclude pytest from grouped updates.
Moves django-debug-toolbar to development section in requirements.txt.
Adds Python 3.13 to CI test matrix.
2025-07-14 11:57:50 -05:00
dependabot[bot]
09e82be391 chore(deps)(deps): bump stefanzweifel/git-auto-commit-action from 5 to 6 (#33)
Bumps [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action) from 5 to 6.
- [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases)
- [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stefanzweifel/git-auto-commit-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: stefanzweifel/git-auto-commit-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:57:50 -05:00
smilerz
8258c6ee53 enable dependabot 2025-07-14 11:57:49 -05:00
smilerz
9b7529956e disable dependabot 2025-07-14 11:57:48 -05:00
smilerz
876f477005 Fix factory datetime fields and update test deps
Because:
- MealPlan factory used future_date for DateTimeField model
- Deprecated Faker API caused test failures
- Arithmetic error in recipe factory loop
- Test dependencies needed compatibility updates

Fixes cookbook/tests/factories/__init__.py to use proper datetime
methods for MealPlan from_date/to_date fields. Updates deprecated
FakerFactory to modern Faker instance. Corrects arithmetic bug in
RecipeFactory step generation. Updates test dependencies including
pytest 8.3.5 and pytest-factoryboy 2.6.0. Improves code formatting
across test files. Adds pytest-specific dependabot grouping.
2025-07-14 11:57:47 -05:00
smilerz
1f16cd9bf4 Re-enable dependabot updates by removing global ignores
Because:
- Universal ignore patterns block all dependency management
- Testing configuration changes now complete
- Selective Vue major version blocks still needed

Removes global "dependency-name: *" ignore patterns from all ecosystems in .github/dependabot.yml. Restores automatic dependency updates while preserving Vue/Pinia major version restrictions.
2025-07-14 11:57:46 -05:00
smilerz
9c90bb67c2 Disable all dependabot updates and reorganize config
Because:
- All dependency updates need temporary blocking for testing
- Configuration sections lack consistent ordering
- Ecosystem-specific settings scattered throughout

Adds universal ignore pattern to all package ecosystems in .github/dependabot.yml. Reorders configuration blocks for consistency and removes redundant vue label from npm ecosystem.
2025-07-14 11:57:46 -05:00
smilerz
e6ba81cb9c Update dependabot.yml 2025-07-14 11:57:45 -05:00
smilerz
aa5d3e4a5c Fix dependabot config by removing unsupported cooldowns
Because:
- GitHub Actions ecosystem doesn't support cooldown feature
- Docker ecosystem doesn't support cooldown configuration
- Unsupported options cause dependabot validation errors

Removes cooldown blocks from github-actions and docker ecosystems in .github/dependabot.yml. Fixes configuration validation errors for ecosystems that don't support cooldown timing controls.
2025-07-14 11:57:45 -05:00
smilerz
9f3c24cb6a Fix invalid dependabot syntax with Vue ignore pattern
Because:
- update-types array syntax invalid in allow configuration
- Complex allow rules failed to constrain major updates
- Single ignore rule provides clearer dependency control

Removes invalid allow rules with update-types arrays and adds vue* major version ignore in .github/dependabot.yml. Fixes syntax error while preventing breaking Vue upgrades.
2025-07-14 11:57:45 -05:00
smilerz
a11c1b9ffe Optimize dependabot and CI workflow configurations
Because:
- Unlimited PRs create review bottlenecks
- Ungrouped updates generate excessive notifications
- Missing cooldowns cause rapid-fire dependency updates
- CI needs to validate PRs against working branch

Adds PR limits, dependency grouping, and cooldowns to .github/dependabot.yml. Updates ci.yml to test PRs against working branch. Adds docker build concurrency control.
2025-07-14 11:57:43 -05:00
smilerz
6d157e9129 Refactor recipe-scrapers updates to daily automation
Because:
- Manual merge workflow creates unnecessary review overhead
- Daily checks ensure faster security and feature updates
- Single workflow eliminates dependabot conflicts

Replaces auto-merge-recipe-scrapers.yml with auto-update-recipe-scrapers.yml. Implements daily PyPI checks, automatic requirements.txt updates, and PR creation with automerge labels.
2025-07-14 11:57:42 -05:00
smilerz
245925f2e0 Add comprehensive dependabot automation config
Because:
- Inconsistent commit messages break automation workflows
- Missing labels prevent automated categorization
- Limited ecosystems lack Docker dependency updates
- Need unlimited PRs for complete dependency coverage

Adds unlimited PR limits, standardized commit prefixes, automerge labels, and Docker ecosystem to .github/dependabot.yml. Removes recipe-scrapers ignore and enables full automation support.
2025-07-14 11:57:42 -05:00
smilerz
11067cb9ff Fix dependabot config with duplicate pip ecosystems
Because:
- GitHub Dependabot rejects overlapping package ecosystems
- Multiple pip configs for same directory cause failures
- Consolidated config maintains functionality

Removes duplicate pip ecosystem from .github/dependabot.yml. Eliminates daily recipe-scrapers config in favor of single weekly pip ecosystem with ignore pattern.
2025-07-14 11:57:41 -05:00
smilerz
ad38afe1f0 Refactor Docker workflow to run only after CI success
Because:
- Unnecessary Docker builds on every push waste resources
- Docker builds should only trigger after passing CI
- Workflow naming should reflect fork-specific purpose

Renames docker-publish-beta.yml to docker-publish-fork.yml and changes trigger from push events to workflow_run completion. Adds conditional logic to build only when CI passes on working branch.
2025-07-14 11:57:41 -05:00
smilerz
ef8d2cc743 Add CI workflows and update dependency management
Because:
- Repository lacked automated testing infrastructure
- Dependabot needed recipe-scrapers daily updates
- CodeQL security scanning was missing
- Alpine base image needed update

Adds comprehensive CI workflow with Python/Node matrix testing, caching for staticfiles,
and Vue unit tests in .github/workflows/ci.yml. Adds CodeQL security analysis workflow
with JavaScript and Python language support in .github/workflows/codeql-analysis.yml.
Adds auto-merge workflow for recipe-scrapers Dependabot PRs in
.github/workflows/auto-merge-recipe-scrapers.yml. Updates .github/dependabot.yml to
enable daily recipe-scrapers updates and weekly updates for other dependencies.
Updates Dockerfile to use Alpine 3.21 base image. Reverts recipe-scrapers to 15.5.0.

Affected files: .github/dependabot.yml, .github/workflows/*, Dockerfile, requirements.txt
2025-07-14 11:57:40 -05:00
dependabot[bot]
4a398181ec Bump docker/build-push-action from 5 to 6 (#4)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:57:39 -05:00
dependabot[bot]
809364090d Bump actions/setup-node from 3 to 4 (#3)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:57:38 -05:00
dependabot[bot]
f5531894e5 Bump actions/checkout from 3 to 4 (#5)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 11:57:38 -05:00
smilerz
019e507f6e add dependabot configuration file 2025-07-14 11:57:37 -05:00
smilerz
5cdb49b870 update formating 2025-07-14 11:57:36 -05:00
smilerz
61e3fa5b4f more twiddling 2025-07-14 11:57:34 -05:00
smilerz
bdfeef3763 remove pre-generating staticfiles 2025-07-14 11:57:34 -05:00
smilerz
b665811a5e add console statements for SCRIPT_NAME variables 2025-07-14 11:57:33 -05:00
smilerz
7218ab7870 update migrations 2025-07-14 11:57:33 -05:00
smilerz
dad03c8e3d regen openapi 2025-07-14 11:57:32 -05:00
smilerz
02ba32cade update API name 2025-07-14 11:57:30 -05:00
smilerz
0fe1ff0e1b python client generation 2025-07-14 11:57:29 -05:00
smilerz
5784abbd9d regen openapi
fix various merge errors
2025-07-14 11:57:28 -05:00
smilerz
a25dac0ad5 allow passing PK to nested serializer instead of object 2025-07-14 11:57:27 -05:00
smilerz
5766d2a6cb reorder migration 2025-07-14 11:57:27 -05:00
smilerz
299f48eb8e commented out DB settings for testing 2025-07-14 11:57:26 -05:00
smilerz
bd7011c0ef commented out testing config in settings.py 2025-07-14 11:57:26 -05:00
smilerz
b8e7ff7ea5 rebase 2025-07-14 11:57:25 -05:00
smilerz
4646b441ae regen openapi and migrations after rebase 2025-07-14 11:57:23 -05:00
smilerz
0db0905a89 fixed substitute display 2025-07-14 11:57:23 -05:00
smilerz
24f1ed585a fixed displaying substitutes 2025-07-14 11:57:22 -05:00
smilerz
2148fd95d2 added ignore shopping to ingredient context menu 2025-07-14 11:57:21 -05:00
smilerz
6e0d478e8e added SubstiteBadge on Cookbook Slider 2025-07-14 11:57:21 -05:00
smilerz
e6e86af878 temporarily removing migration until ready to merge 2025-07-14 11:57:20 -05:00
smilerz
5a57672c86 fixed context menu display on ShoppingModal 2025-07-14 11:57:20 -05:00
smilerz
bfea4f3483 added stub for ingredient context menu and preference to toggle it on 2025-07-14 11:57:18 -05:00
smilerz
7af970de0a fixed substitute display 2025-07-14 11:57:18 -05:00
smilerz
37c36eb673 added SubstiteBadge on Cookbook Slider 2025-07-14 11:57:17 -05:00
smilerz
2639c3ba6b temporarily removing migration until ready to merge 2025-07-14 11:57:17 -05:00
smilerz
d6f2610fa1 fixed context menu display on ShoppingModal 2025-07-14 11:57:16 -05:00
smilerz
7fc46aae45 added stub for ingredient context menu and preference to toggle it on 2025-07-14 11:57:15 -05:00
smilerz
8aacd9f2b3 created never_used_food filter 2025-07-14 11:57:13 -05:00
smilerz
7deca69075 rebase from develop 2025-07-14 11:57:12 -05:00
smilerz
e07dc34bf2 created never_used_food filter 2025-07-14 11:57:11 -05:00
smilerz
1412c5912b changed never_used_food to ignore substitutions when filtering onhand 2025-07-14 11:57:10 -05:00
smilerz
427e20a0b2 rebase from develop 2025-07-14 11:57:09 -05:00
smilerz
4febdeb2bf rebase 2025-07-14 11:57:08 -05:00
smilerz
036fe20cfd regen openapi and migrations after rebase 2025-07-14 11:57:06 -05:00
smilerz
cd106d28d0 fixed substitute display 2025-07-14 11:57:06 -05:00
smilerz
abbba50c1e fixed displaying substitutes 2025-07-14 11:57:05 -05:00
smilerz
6c0f2cf1e8 added ignore shopping to ingredient context menu 2025-07-14 11:57:04 -05:00
smilerz
b505821b29 added SubstiteBadge on Cookbook Slider 2025-07-14 11:57:03 -05:00
smilerz
00734f12e6 temporarily removing migration until ready to merge 2025-07-14 11:57:03 -05:00
smilerz
a8819e7f42 fixed context menu display on ShoppingModal 2025-07-14 11:57:02 -05:00
smilerz
fad9989a18 added stub for ingredient context menu and preference to toggle it on 2025-07-14 11:57:01 -05:00
smilerz
be5e2e2d66 fixed substitute display 2025-07-14 11:57:00 -05:00
smilerz
36a5802c91 added SubstiteBadge on Cookbook Slider 2025-07-14 11:57:00 -05:00
smilerz
cee95719d4 temporarily removing migration until ready to merge 2025-07-14 11:56:59 -05:00
smilerz
4dab2be02d fixed context menu display on ShoppingModal 2025-07-14 11:56:59 -05:00
smilerz
f168e09cf4 added stub for ingredient context menu and preference to toggle it on 2025-07-14 11:56:58 -05:00
smilerz
c3873754fc regen openapi 2025-07-14 11:56:47 -05:00
smilerz
9916e58b37 prettier, isort, black, flake8 configured with rational defaults
instructions for VSCode written
2025-07-14 11:56:46 -05:00
smilerz
2196c1dfa5 autoformat and linting for python (autopep8 and flake8)
instructions to setup for VSCode
2025-07-14 11:56:45 -05:00
smilerz
3da2c6c279 fix docker build action 2025-07-14 11:56:43 -05:00
smilerz
f54a58ebbb updated docker build 2025-07-14 11:56:43 -05:00
smilerz
e9f46f7088 updated actions 2025-07-14 11:56:42 -05:00
smilerz
f06cf23111 updated docker build action 2025-07-14 11:56:42 -05:00
smilerz
a4b582b4cc fix docker build action 2025-07-14 11:56:42 -05:00
smilerz
56b4b01038 updated docker build 2025-07-14 11:56:41 -05:00
smilerz
9aba66634e add manual docker build to gihub actions 2025-07-14 11:56:41 -05:00
smilerz
63ddd66306 updated actions 2025-07-14 11:56:40 -05:00
smilerz
232e832c1d updated docker build action 2025-07-14 11:56:40 -05:00
smilerz
5e91709421 regen openapi and migrations after rebase 2025-07-14 11:56:38 -05:00
smilerz
d37ea1e473 fixed substitute display 2025-07-14 11:56:38 -05:00
smilerz
096ff5d0d8 fixed displaying substitutes 2025-07-14 11:56:37 -05:00
smilerz
e20f59a66a added ignore shopping to ingredient context menu 2025-07-14 11:56:29 -05:00
smilerz
2cb44c8933 added SubstiteBadge on Cookbook Slider 2025-07-14 11:56:28 -05:00
smilerz
64703c8497 temporarily removing migration until ready to merge 2025-07-14 11:56:28 -05:00
smilerz
d6e74a2ef5 fixed context menu display on ShoppingModal 2025-07-14 11:56:27 -05:00
smilerz
b1d491165e added stub for ingredient context menu and preference to toggle it on 2025-07-14 11:56:26 -05:00
smilerz
e94c3a2355 fixed substitute display 2025-07-14 11:56:25 -05:00
smilerz
71b05e16f8 change shopping status on api to SerialMethod over annotation 2025-07-14 11:56:24 -05:00
smilerz
4beed65983 added SubstiteBadge on Cookbook Slider 2025-07-14 11:56:23 -05:00
smilerz
ca03fcff33 temporarily removing migration until ready to merge 2025-07-14 11:56:23 -05:00
smilerz
d3333322c4 fixed context menu display on ShoppingModal 2025-07-14 11:56:22 -05:00
smilerz
2b8172f25c added get_substitutes api, finished context menu 2025-07-14 11:56:21 -05:00
smilerz
9496292816 added stub for ingredient context menu and preference to toggle it on 2025-07-14 11:56:19 -05:00
smilerz
cf32549a22 changed never_used_food to ignore substitutions when filtering onhand 2025-07-14 11:56:18 -05:00
smilerz
13abf6da82 rebase from develop 2025-07-14 11:56:17 -05:00
smilerz
c72f697d57 personal changes to github actions 2025-07-14 11:56:15 -05:00
vabene1111
03cfe18acd reverted api plan ical having optional parameters 2025-07-14 11:56:14 -05:00
smilerz
9939ef76c1 change all naive datetimes to timezone aware dateimes 2025-07-14 11:56:11 -05:00
smilerz
ae387507f7 Update build-docker.yml
update docker build to use node 20
2025-07-14 11:07:00 -05:00
smilerz
969443acd1 Merge pull request #3823 from smilerz/upstream/tandoor-1
Prepare tandoor-1 branch for maintenance updates
2025-07-14 11:01:40 -05:00
smilerz
3606612135 Add ingredient context features and update dependencies
Because:
- Missing never_used_food parameter broke recipe search filtering
- Users needed ingredient substitute functionality
- Ingredient context menu was incomplete for recipe management
- PDF viewer and dependencies required updates for compatibility
- Development tools needed formatting and linting improvements

Adds never_used_food QueryParam to RecipeViewSet for proper search filtering. Implements ingredient substitutes API endpoint and ingredient_context user preference field. Creates IngredientContextMenu component and Substitute badge for enhanced recipe management. Updates PDF.js from legacy version to modern web-based implementation with SVG icons and improved localization. Refreshes Vue dependencies including security updates and formatting tools. Adds comprehensive test coverage for nested serializers and search functionality. Updates VS Code settings for better development workflow.
2025-07-13 17:02:21 -05:00
smilerz
1ee48edfb5 Update Docker workflow for tandoor-v1 maintenance branch
Because:
- Workflow needed to target specific tandoor-1 branch
- Maintenance builds required different notification messaging
- Multiple workflows needed to be disabled for focused maintenance

Updates build-docker.yml to trigger only on tandoor-1 branch pushes with tandoor-v1 tags.
Adds maintenance-specific Discord notification job. Disables other CI workflows by
restricting to 'disabled' branch. Affects .github/workflows/ files for Docker builds,
CI, and CodeQL analysis.
2025-07-13 13:44:46 -05:00
1269 changed files with 86299 additions and 173821 deletions

View File

@@ -1,7 +1,7 @@
FROM python:3.13-alpine3.22
FROM python:3.10-alpine3.18
#Install all dependencies.
RUN apk add --no-cache postgresql-libs postgresql-client gettext zlib libjpeg libwebp libxml2-dev libxslt-dev openldap git yarn libgcc libstdc++ nginx tini envsubst nodejs npm
RUN apk add --no-cache postgresql-libs postgresql-client gettext zlib libjpeg libwebp libxml2-dev libxslt-dev openldap git yarn
#Print all logs without buffering it.
ENV PYTHONUNBUFFERED 1
@@ -19,10 +19,8 @@ RUN \
if [ `apk --print-arch` = "armv7" ]; then \
printf "[global]\nextra-index-url=https://www.piwheels.org/simple\n" > /etc/pip.conf ; \
fi
RUN apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev xmlsec-dev xmlsec build-base g++ curl rust && \
python -m pip install --upgrade pip && \
pip debug -v && \
pip install wheel==0.45.1 && \
pip install setuptools_rust==1.10.2 && \
pip install -r /tmp/pip-tmp/requirements.txt --no-cache-dir &&\
RUN apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev && \
echo -n "INPUT ( libldap.so )" > /usr/lib/libldap_r.so && \
pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt && \
rm -rf /tmp/pip-tmp && \
apk --purge del .build-deps

View File

@@ -20,10 +20,6 @@
"ms-python.python"
]
}
},
"containerEnv": {
"CSRF_TRUSTED_ORIGINS": "http://localhost:8000,http://localhost:8080"
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.

View File

@@ -29,4 +29,3 @@ vue/babel.config*
vue/package.json
vue/tsconfig.json
vue/src/utils/openapi
venv

View File

@@ -6,9 +6,6 @@
# random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
SECRET_KEY=
# your default timezone See https://timezonedb.com/time-zones for a list of timezones
TZ=Europe/Berlin
# allowed hosts (see documentation), should be set to your hostname(s) but might be * (default) for some proxies/providers
# ALLOWED_HOSTS=recipes.mydomain.com

12
.github/FUNDING.yml vendored
View File

@@ -1,12 +0,0 @@
# These are supported funding model platforms
github: [vabene1111]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -1,26 +1,92 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: weekly
- package-ecosystem: "pip"
directory: "/"
open-pull-requests-limit: 20
schedule:
interval: "monthly"
interval: "daily"
cooldown:
semver-major-days: 30
semver-minor-days: 7
semver-patch-days: 3
exclude:
- "recipe-scrapers"
directory: "/"
groups:
pip-patches:
exclude-patterns: ["pytest*"]
update-types: ["patch"]
pip-minors:
exclude-patterns: ["pytest*"]
update-types: ["minor"]
pip-pytest:
patterns: ["pytest*"]
update-types: ["minor", "patch"]
commit-message:
prefix: "chore"
include: "scope"
labels:
- "python"
- "dependencies"
- "automerge"
- package-ecosystem: "npm"
directory: "/vue3/"
open-pull-requests-limit: 20
schedule:
interval: "monthly"
cooldown:
semver-major-days: 30
semver-minor-days: 3
semver-patch-days: 3
directory: "vue"
ignore:
- dependency-name: "vue"
update-types: ["version-update:semver-major"]
- dependency-name: "vue*"
update-types: ["version-update:semver-major"]
- dependency-name: "pinia"
update-types: ["version-update:semver-major"]
groups:
npm-patches:
patterns: ["*"]
update-types: ["patch"]
npm-minors:
patterns: ["*"]
update-types: ["minor"]
commit-message:
prefix: "chore"
include: "scope"
labels:
- "javascript"
- "dependencies"
- package-ecosystem: "github-actions"
directory: "/"
open-pull-requests-limit: 20
schedule:
interval: "monthly"
interval: "weekly"
directory: "/.github/"
groups:
actions-updates:
patterns: ["*"]
update-types: ["patch", "minor"]
commit-message:
prefix: "chore"
include: "scope"
labels:
- "github_actions"
- "dependencies"
- "automerge"
- package-ecosystem: "docker"
open-pull-requests-limit: 5
schedule:
interval: "weekly"
directory: "/"
commit-message:
prefix: "chore"
include: "scope"
labels:
- "docker"
- "dependencies"

View File

@@ -0,0 +1,112 @@
name: Build Docker Container with open data plugin installed
on:
push:
branches: [disabled]
jobs:
build-container:
name: Build ${{ matrix.name }} Container
runs-on: ubuntu-latest
if: github.repository_owner == 'TandoorRecipes'
continue-on-error: ${{ matrix.continue-on-error }}
permissions:
contents: read
packages: write
strategy:
matrix:
include:
# Standard build config
- name: Standard
dockerfile: Dockerfile
platforms: linux/amd64,linux/arm64
suffix: ""
continue-on-error: false
steps:
- uses: actions/checkout@v4
- name: Get version number
id: get_version
run: |
if [[ "$GITHUB_REF" = refs/tags/* ]]; then
echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" = refs/heads/beta ]]; then
echo VERSION=beta >> $GITHUB_OUTPUT
else
echo VERSION=develop >> $GITHUB_OUTPUT
fi
# clone open data plugin
- name: clone open data plugin repo
uses: actions/checkout@master
with:
repository: TandoorRecipes/open_data_plugin
ref: master
path: ./recipes/plugins/open_data_plugin
# Build Vue frontend
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: yarn
cache-dependency-path: vue/yarn.lock
- name: Install dependencies
working-directory: ./vue
run: yarn install --frozen-lockfile
- name: Build dependencies
working-directory: ./vue
run: yarn build
- name: Setup Open Data Plugin Links
working-directory: ./recipes/plugins/open_data_plugin
run: python setup_repo.py
- name: Build Open Data Frontend
working-directory: ./recipes/plugins/open_data_plugin/vue
run: yarn build
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
if: github.secret_source == 'Actions'
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
vabene1111/recipes
ghcr.io/TandoorRecipes/recipes
flavor: |
latest=false
suffix=${{ matrix.suffix }}
tags: |
type=raw,value=latest,suffix=-open-data-plugin,enable=${{ startsWith(github.ref, 'refs/tags/') }}
type=semver,suffix=-open-data-plugin,pattern={{version}}
type=semver,suffix=-open-data-plugin,pattern={{major}}.{{minor}}
type=semver,suffix=-open-data-plugin,pattern={{major}}
type=ref,suffix=-open-data-plugin,event=branch
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.dockerfile }}
pull: true
push: ${{ github.secret_source == 'Actions' }}
platforms: ${{ matrix.platforms }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -1,6 +1,8 @@
name: Build Docker Container
on: push
on:
push:
branches: [tandoor-1]
jobs:
build-container:
@@ -23,28 +25,17 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Get version number
id: get_version
run: |
if [[ "$GITHUB_REF" = refs/tags/* ]]; then
echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" = refs/heads/beta ]]; then
echo VERSION=beta >> $GITHUB_OUTPUT
else
echo VERSION=develop >> $GITHUB_OUTPUT
fi
# Build Vue 3 frontend
# Build Vue frontend
- uses: actions/setup-node@v4
with:
node-version: '22'
node-version: '20'
cache: yarn
cache-dependency-path: vue3/yarn.lock
cache-dependency-path: vue/yarn.lock
- name: Install dependencies
working-directory: ./vue3
working-directory: ./vue
run: yarn install --frozen-lockfile
- name: Build dependencies
working-directory: ./vue3
working-directory: ./vue
run: yarn build
- name: Set up QEMU
@@ -75,11 +66,8 @@ jobs:
latest=false
suffix=${{ matrix.suffix }}
tags: |
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') }}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=ref,event=branch
type=raw,value=tandoor-v1-{{date 'YYYYMMDD'}}
type=raw,value=tandoor-v1
- name: Build and Push
uses: docker/build-push-action@v5
with:
@@ -93,34 +81,3 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
notify-stable:
name: Notify Stable
runs-on: ubuntu-latest
needs: build-container
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Set tag name
run: |
# Strip "refs/tags/" prefix
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
# Send stable discord notification
- name: Discord notification
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_RELEASE_WEBHOOK }}
uses: Ilshidur/action-discord@0.4.0
with:
args: '🚀 Version {{ VERSION }} of tandoor has been released 🥳 Check it out https://github.com/vabene1111/recipes/releases/tag/{{ VERSION }}'
notify-beta:
name: Notify Beta
runs-on: ubuntu-latest
needs: build-container
if: github.ref == 'refs/heads/beta'
steps:
# Send beta discord notification
- name: Discord notification
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_BETA_WEBHOOK }}
uses: Ilshidur/action-discord@0.4.0
with:
args: '🚀 The Tandoor 2 Image has been updated! 🥳'

View File

@@ -1,6 +1,11 @@
name: Continuous Integration
on: [push, pull_request]
on:
push:
branches: [disabled]
pull_request:
branches: [disabled]
jobs:
build:
@@ -9,13 +14,14 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.12"]
node-version: ["22"]
python-version: ["3.10"]
node-version: ["18"]
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@v1.5.1
- uses: awalsh128/cache-apt-pkgs-action@v1.4.3
with:
packages: libsasl2-dev python3-dev libxml2-dev libxmlsec1-dev libxslt-dev libxmlsec1-openssl libxslt-dev libldap2-dev libssl-dev gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev xmlsec-dev xmlsec build-base g++ curl
packages: libsasl2-dev python3-dev libxml2-dev libxmlsec1-dev libxslt-dev libxmlsec1-openssl libldap2-dev libssl-dev gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev xmlsec-dev xmlsec build-base g++ curl
version: 1.0
# Setup python & dependencies
@@ -36,9 +42,10 @@ jobs:
with:
path: |
./cookbook/static
./vue/webpack-stats.json
./staticfiles
key: |
${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue3/src/*') }}
${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue/src/*') }}
# Build Vue frontend & Dependencies
- name: Set up Node ${{ matrix.node-version }}
@@ -47,28 +54,30 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
cache: "yarn"
cache-dependency-path: ./vue3/yarn.lock
cache-dependency-path: ./vue/yarn.lock
- name: Install Vue dependencies
if: steps.django_cache.outputs.cache-hit != 'true'
working-directory: ./vue3
working-directory: ./vue
run: yarn install
- name: Build Vue dependencies
if: steps.django_cache.outputs.cache-hit != 'true'
working-directory: ./vue3
working-directory: ./vue
run: yarn build
- name: Compile Django StaticFiles
if: steps.django_cache.outputs.cache-hit != 'true'
run: |
python3 manage.py collectstatic --noinput
python3 manage.py collectstatic_js_reverse
- uses: actions/cache/save@v4
if: steps.django_cache.outputs.cache-hit != 'true'
with:
path: |
./cookbook/static
./vue/webpack-stats.json
./staticfiles
key: |
${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue/src/*') }}

View File

@@ -2,9 +2,10 @@ name: "Code scanning - action"
on:
push:
branches: [disabled]
pull_request:
schedule:
- cron: '0 13 * * 2'
branches: [disabled]
jobs:
CodeQL-Build:

235
.github/workflows/create-upstream-pr.yml vendored Normal file
View File

@@ -0,0 +1,235 @@
name: Create Upstream PR
on:
workflow_run:
workflows: ["Push Workflow"]
types:
- completed
branches: [working]
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
create-upstream-pr:
runs-on: ubuntu-latest
concurrency:
group: upstream-pr
cancel-in-progress: true
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
steps:
- name: Generate GitHub App token (for branch push)
id: generate_token_push
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.BOT_APP_ID }}
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
- name: Checkout fork
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.generate_token_push.outputs.token }}
- name: Setup git user
run: |
git config user.name "GitHub Action"
git config user.email "action@github.com"
- name: Add upstream remote
run: |
git remote get-url upstream || git remote add upstream https://github.com/TandoorRecipes/recipes.git
git fetch upstream
- name: Ensure jq is available
run: |
if ! command -v jq &> /dev/null; then
sudo apt-get update && sudo apt-get install -y jq
fi
- name: Create upstream PR branch
id: create_branch
run: |
BRANCH_NAME="upstream-pr-$(date +%Y%m%d-%H%M%S)"
git checkout -b "$BRANCH_NAME" || { echo "❌ Failed to create branch $BRANCH_NAME"; exit 1; }
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
echo "✅ Created branch: $BRANCH_NAME"
- name: Restore upstream infrastructure files
id: restore_infra
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
git checkout "$BRANCH_NAME"
git rm .gitattributes || echo " .gitattributes not present, skipping removal."
git checkout upstream/tandoor-1 -- .github/workflows/ || echo " No workflows to restore."
git checkout upstream/tandoor-1 -- cookbook/version_info.py || echo " No version_info.py to restore."
git add .
if ! git diff --cached --quiet; then
git commit -m $'Restore upstream infrastructure files for PR\n\n- Removed fork-specific .gitattributes\n- Restored upstream .github/workflows/\n- Restored upstream cookbook/version_info.py'
echo "✅ Infrastructure files restored and committed."
else
echo " No infrastructure changes to commit."
fi
- name: Push branch to fork (after infra commit)
env:
GITHUB_TOKEN: ${{ steps.generate_token_push.outputs.token }}
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
echo "Pushing branch $BRANCH_NAME after infra file restore."
git push --set-upstream https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git "$BRANCH_NAME"
echo "✅ Branch pushed: $BRANCH_NAME (infra files)"
- name: Merge upstream branch
id: merge_upstream
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
git checkout "$BRANCH_NAME"
if git merge --no-edit upstream/tandoor-1; then
echo "✅ Merged upstream/tandoor-1 into $BRANCH_NAME"
if ! git diff --cached --quiet || [ -n "$(git log origin/$BRANCH_NAME..$BRANCH_NAME --oneline)" ]; then
echo "merge_commit=true" >> $GITHUB_OUTPUT
else
echo "merge_commit=false" >> $GITHUB_OUTPUT
fi
else
echo "❌ Merge conflict detected during merge with upstream/tandoor-1. Please resolve conflicts manually." >&2
exit 1
fi
- name: Push branch to fork (after merge)
if: steps.merge_upstream.outputs.merge_commit == 'true'
env:
GITHUB_TOKEN: ${{ steps.generate_token_push.outputs.token }}
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
echo "Pushing branch $BRANCH_NAME after merge."
git push https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git "$BRANCH_NAME"
echo "✅ Branch pushed: $BRANCH_NAME (after merge)"
- name: Get commit list
id: get_commits
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
COMMITS_RAW=$(git log upstream/tandoor-1..$BRANCH_NAME --oneline)
if [ -z "$COMMITS_RAW" ]; then
echo "has_changes=false" >> $GITHUB_OUTPUT
echo "✅ No commits to contribute - exiting gracefully"
exit 0
fi
echo "commits_raw<<EOF" >> $GITHUB_OUTPUT
printf "%s\n" "$COMMITS_RAW" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "has_changes=true" >> $GITHUB_OUTPUT
- name: Get changed files
id: get_files
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
CHANGED_FILES=$(git diff upstream/tandoor-1..$BRANCH_NAME --name-only)
echo "changed_files<<EOF" >> $GITHUB_OUTPUT
printf "%s\n" "$CHANGED_FILES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
CODE_COUNT=$(echo "$CHANGED_FILES" | grep -c '^' || true)
echo "code_count=$CODE_COUNT" >> $GITHUB_OUTPUT
- name: Summarize changes
id: summarize_changes
run: |
CODE_COUNT=${{ steps.get_files.outputs.code_count }}
CHANGES_SUMMARY="Modified $CODE_COUNT code files"
echo "changes_summary=$CHANGES_SUMMARY" >> $GITHUB_OUTPUT
- name: Prepare commit subjects and JSON
id: prepare_commits
run: |
COMMITS_RAW="${{ steps.get_commits.outputs.commits_raw }}"
CODE_FILES=( $(echo "${{ steps.get_files.outputs.changed_files }}") )
FILTERED_COMMITS_JSON="[]"
COMMIT_SUBJECTS_ARRAY=()
INFRA_PATTERNS='^\.github/|^cookbook/version_info\.py$|^\.gitattributes$'
while IFS= read -r commit_line; do
if [ -z "$commit_line" ]; then continue; fi
COMMIT_SHA=$(echo "$commit_line" | cut -d' ' -f1)
COMMIT_SUBJECT=$(echo "$commit_line" | cut -d' ' -f2-)
mapfile -t COMMIT_FILES < <(git diff-tree --no-commit-id --name-only -r "$COMMIT_SHA" | grep -Ev "$INFRA_PATTERNS")
# Only include commit if it touches at least one non-infra file that is still different
INCLUDE_COMMIT=false
for file in "${COMMIT_FILES[@]}"; do
for code_file in "${CODE_FILES[@]}"; do
if [ "$file" = "$code_file" ]; then
INCLUDE_COMMIT=true
break 2
fi
done
done
if [ "$INCLUDE_COMMIT" = true ]; then
COMMIT_SUBJECTS_ARRAY+=("- $COMMIT_SUBJECT")
FILES_JSON=$(printf '%s\n' "${COMMIT_FILES[@]}" | jq -R . | jq -s .)
COMMIT_JSON=$(jq -n --arg sha "$COMMIT_SHA" --arg subject "$COMMIT_SUBJECT" --argjson files "$FILES_JSON" '{sha: $sha, subject: $subject, files: $files}')
FILTERED_COMMITS_JSON=$(echo "$FILTERED_COMMITS_JSON" | jq --argjson item "$COMMIT_JSON" '. + [$item]')
fi
done <<< "$COMMITS_RAW"
echo 'commits_json<<EOF' >> $GITHUB_OUTPUT
printf "%s\n" "$FILTERED_COMMITS_JSON" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
echo "commit_subjects<<EOF" >> $GITHUB_OUTPUT
printf '%s\n' "${COMMIT_SUBJECTS_ARRAY[@]}" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
- name: Build PR content
if: steps.get_commits.outputs.has_changes == 'true'
id: build_pr_content
uses: actions/github-script@v7
env:
COMMITS_JSON: ${{ steps.prepare_commits.outputs.commits_json }}
CHANGES_SUMMARY: ${{ steps.summarize_changes.outputs.changes_summary }}
BRANCH_NAME: ${{ steps.create_branch.outputs.branch_name }}
GITHUB_REPOSITORY: ${{ github.repository }}
with:
github-token: ${{ steps.generate_token_push.outputs.token }}
script: |
const commits = JSON.parse(process.env.COMMITS_JSON || '[]');
const changesSummary = process.env.CHANGES_SUMMARY || 'Changes from fork';
const branchName = process.env.BRANCH_NAME || '';
const repo = process.env.GITHUB_REPOSITORY || '';
const [owner, reponame] = repo.split('/');
const nCommits = commits.length;
let prTitle = 'Sync ' + nCommits + ' commit' + (nCommits !== 1 ? 's' : '') + ' from fork:';
if (nCommits > 0) {
prTitle += ' ' + commits[0].subject;
}
let prBody = `This PR syncs ${nCommits} commit${nCommits !== 1 ? 's' : ''} from branch ${branchName}.\n\n`;
prBody += `**Changes Summary:**\n${changesSummary}\n\n`;
prBody += `Commits included:\n`;
for (const c of commits) {
prBody += `- ${c.subject} ([${c.sha}](https://github.com/${owner}/${reponame}/commit/${c.sha}))\n`;
}
prBody += `\n---\n`;
core.setOutput('prTitle', prTitle);
core.setOutput('prBody', prBody);
- name: Print PR creation instructions
if: steps.get_commits.outputs.has_changes == 'true'
env:
BRANCH_NAME: ${{ steps.create_branch.outputs.branch_name }}
PR_TITLE: ${{ steps.build_pr_content.outputs.prTitle }}
PR_BODY: ${{ steps.build_pr_content.outputs.prBody }}
run: |
echo "✅ Branch pushed: $BRANCH_NAME"
echo
echo "To create a pull request, open:"
echo "https://github.com/TandoorRecipes/recipes/compare/tandoor-1...${{ github.repository_owner }}:$BRANCH_NAME?expand=1"
echo
echo "Suggested PR title:"
echo "$PR_TITLE"
echo
echo "Suggested PR body:"
echo "$PR_BODY"

View File

@@ -0,0 +1,68 @@
name: Dependabot Auto-merge
on:
pull_request_target:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
validate:
if: contains(github.event.pull_request.labels.*.name, 'automerge') && github.event.pull_request.user.login != 'dependabot[bot]'
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Remove automerge label
uses: actions-ecosystem/action-remove-labels@d05162525702062b6bdef750ed8594fc024b3ed7 # v1.3.0
with:
labels: automerge
- name: Add invalid label
uses: actions-ecosystem/action-add-labels@1a9c3715c0037e96b97bb38cb4c4b56a1f1d4871 # v1.1.0
with:
labels: invalid
- name: Comment restriction
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
with:
issue-number: ${{ github.event.pull_request.number }}
body: |
⚠️ **Automerge Restriction Notice**
The `automerge` label has been removed from this PR because it has restricted use. Only PRs created by `dependabot[bot]` are allowed to use the automerge functionality.
If you believe this is an error, please contact a repository maintainer.
auto-merge:
if: github.actor == 'dependabot[bot]' && contains(github.event.pull_request.labels.*.name, 'automerge')
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Generate token
id: generate_token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.BOT_APP_ID }}
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
- name: Auto-approve PR
uses: hmarr/auto-approve-action@b40d6c9ed2fa10c9a2749eca7eb004418a705501 # v4.0.0
with:
github-token: ${{ steps.generate_token.outputs.token }}
review-message: |
🤖 **Dependabot Auto-merge**
This PR has been automatically approved and enabled for auto-merge. It will be merged automatically once all required checks pass.
- name: Enable auto-merge
uses: daneden/enable-automerge-action@f8558b65c5b8d8bfb592c4e74e3d491624a38fbd # v1.0.0
with:
github-token: ${{ steps.generate_token.outputs.token }}
allowed-author: "dependabot[bot]"
merge-method: REBASE # Allowed values: MERGE | SQUASH | REBASE

75
.github/workflows/docker-publish.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
name: publish docker image
on:
workflow_dispatch:
workflow_call:
permissions:
contents: read
packages: write
jobs:
build-container:
concurrency:
group: docker-build-${{ github.ref }}
name: Build Tandoor Container
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.continue-on-error }}
permissions:
contents: read
packages: write
strategy:
matrix:
include:
# Standard build config
- name: Standard
dockerfile: Dockerfile
platforms: linux/amd64
suffix: ""
continue-on-error: false
steps:
- uses: actions/checkout@v4
- name: Get version number
id: get_version
run: |
echo VERSION=latest >> $GITHUB_OUTPUT
# Build Vue frontend
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: yarn
cache-dependency-path: vue/yarn.lock
- name: Install dependencies
working-directory: ./vue
run: yarn install --frozen-lockfile
- name: Build dependencies
working-directory: ./vue
run: yarn build
- name: Set up QEMU
uses: docker/setup-qemu-action@05340d1c670183e7caabdb33ae9f1c80fae3b0c2 # v3.1.0
- name: Set up Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.7.1
- name: Login to Docker Hub
uses: docker/login-action@3d100841f68d4548bf57e52eb27bd33ec5069f55 # v3.3.0
with:
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
- name: Docker Metadata
id: meta
uses: docker/metadata-action@be19121bfd18b9c1ac415d9571d4f67b9b357886 # v5.6.0
with:
images: |
smilerz/recipes
tags: |
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and Push
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.10.0
with:
context: .
file: ${{ matrix.dockerfile }}
pull: true
push: true
platforms: ${{ matrix.platforms }}
tags: '${{ steps.meta.outputs.tags }}'
cache-from: type=gha
cache-to: type=gha,mode=max

57
.github/workflows/push-orchestrator.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: Push Workflow
on:
push:
branches: [working]
permissions:
contents: read
jobs:
detect-pr-merge:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
pr_merged: ${{ steps.detect_pr.outputs.result }}
steps:
- name: Check if commit is part of a PR
id: detect_pr
uses: actions/github-script@v7
with:
script: |
const prs = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: context.sha
});
const pr = prs.data.find(pr => pr.merged_at);
const merged = pr ? 'true' : 'false';
// Set the output explicitly
core.setOutput('pr_merged', merged);
return merged;
run-ci:
needs: detect-pr-merge
if: needs.detect-pr-merge.outputs.pr_merged != 'true'
permissions:
contents: read
actions: write
uses: ./.github/workflows/ci.yml
secrets: inherit
docker-publish:
permissions:
contents: read
packages: write
needs: [detect-pr-merge, run-ci]
if: |
needs.detect-pr-merge.outputs.pr_merged == 'true' ||
needs.run-ci.result == 'success'
uses: ./.github/workflows/docker-publish.yml
secrets: inherit

View File

@@ -0,0 +1,268 @@
name: Stage Branch for PR
on:
workflow_run:
workflows: ["Push Workflow"]
types:
- completed
branches: [working]
workflow_dispatch:
permissions:
contents: write
pull-requests: write
issues: write
jobs:
create-upstream-pr:
runs-on: ubuntu-latest
concurrency:
group: upstream-pr
cancel-in-progress: true
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
steps:
- name: Generate GitHub App token (for branch push)
id: generate_token_push
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.BOT_APP_ID }}
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
- name: Checkout fork
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.generate_token_push.outputs.token }}
- name: Setup git user
run: |
git config user.name "GitHub Action"
git config user.email "action@github.com"
- name: Add upstream remote
run: |
git remote get-url upstream || git remote add upstream https://github.com/TandoorRecipes/recipes.git
git fetch upstream
- name: Ensure jq is available
run: |
if ! command -v jq &> /dev/null; then
sudo apt-get update && sudo apt-get install -y jq
fi
- name: Create upstream PR branch
id: create_branch
run: |
BRANCH_NAME="upstream-pr-$(date +%Y%m%d-%H%M%S)"
git checkout -b "$BRANCH_NAME" || { echo "❌ Failed to create branch $BRANCH_NAME"; exit 1; }
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
echo "✅ Created branch: $BRANCH_NAME"
- name: Restore upstream infrastructure files
id: restore_infra
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
git checkout "$BRANCH_NAME"
git rm .gitattributes || echo " .gitattributes not present, skipping removal."
git checkout upstream/tandoor-1 -- .github/workflows/ || echo " No workflows to restore."
git checkout upstream/tandoor-1 -- cookbook/version_info.py || echo " No version_info.py to restore."
git add .
if ! git diff --cached --quiet; then
git commit -m $'Restore upstream infrastructure files for PR\n\n- Removed fork-specific .gitattributes\n- Restored upstream .github/workflows/\n- Restored upstream cookbook/version_info.py'
echo "✅ Infrastructure files restored and committed."
else
echo " No infrastructure changes to commit."
fi
- name: Push branch to fork (after infra commit)
env:
GITHUB_TOKEN: ${{ steps.generate_token_push.outputs.token }}
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
echo "Pushing branch $BRANCH_NAME after infra file restore."
git push --set-upstream https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git "$BRANCH_NAME"
echo "✅ Branch pushed: $BRANCH_NAME (infra files)"
- name: Merge upstream branch
id: merge_upstream
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
git checkout "$BRANCH_NAME"
if git merge --no-edit upstream/tandoor-1; then
echo "✅ Merged upstream/tandoor-1 into $BRANCH_NAME"
if ! git diff --cached --quiet || [ -n "$(git log origin/$BRANCH_NAME..$BRANCH_NAME --oneline)" ]; then
echo "merge_commit=true" >> $GITHUB_OUTPUT
else
echo "merge_commit=false" >> $GITHUB_OUTPUT
fi
else
echo "❌ Merge conflict detected during merge with upstream/tandoor-1. Please resolve conflicts manually." >&2
exit 1
fi
- name: Push branch to fork (after merge)
if: steps.merge_upstream.outputs.merge_commit == 'true'
env:
GITHUB_TOKEN: ${{ steps.generate_token_push.outputs.token }}
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
echo "Pushing branch $BRANCH_NAME after merge."
git push https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git "$BRANCH_NAME"
echo "✅ Branch pushed: $BRANCH_NAME (after merge)"
- name: Get commit list
id: get_commits
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
COMMITS_RAW=$(git log upstream/tandoor-1..$BRANCH_NAME --oneline)
if [ -z "$COMMITS_RAW" ]; then
echo "has_changes=false" >> $GITHUB_OUTPUT
echo "✅ No commits to contribute - exiting gracefully"
exit 0
fi
echo "commits_raw<<EOF" >> $GITHUB_OUTPUT
printf "%s\n" "$COMMITS_RAW" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "has_changes=true" >> $GITHUB_OUTPUT
- name: Get changed files
id: get_files
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
INFRA_PATTERNS='^\.github/|^cookbook/version_info\.py$|^\.gitattributes$'
CHANGED_FILES=$(git diff upstream/tandoor-1..$BRANCH_NAME --name-only | grep -Ev "$INFRA_PATTERNS" || true)
echo "changed_files<<EOF" >> $GITHUB_OUTPUT
printf "%s\n" "$CHANGED_FILES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
CODE_COUNT=$(echo "$CHANGED_FILES" | grep -c '^' || true)
echo "code_count=$CODE_COUNT" >> $GITHUB_OUTPUT
- name: Summarize changes
id: summarize_changes
run: |
CODE_COUNT=${{ steps.get_files.outputs.code_count }}
CHANGED_FILES="${{ steps.get_files.outputs.changed_files }}"
if [ "$CODE_COUNT" -eq 0 ]; then
CHANGES_SUMMARY="No code files changed. No PR required."
else
CHANGES_SUMMARY="Modified $CODE_COUNT code files"
CHANGES_SUMMARY+=$'\nFiles changed:'
CHANGES_SUMMARY+=$'\n'$(echo "$CHANGED_FILES" | sed '/^$/d; s/^/- /')
fi
echo "changes_summary<<EOF" >> $GITHUB_OUTPUT
echo "$CHANGES_SUMMARY" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Prepare commit subjects and JSON
id: prepare_commits
run: |
COMMITS_RAW="${{ steps.get_commits.outputs.commits_raw }}"
CODE_FILES=( $(echo "${{ steps.get_files.outputs.changed_files }}") )
FILTERED_COMMITS_JSON="[]"
COMMIT_SUBJECTS_ARRAY=()
INFRA_PATTERNS='^\.github/|^cookbook/version_info\.py$|^\.gitattributes$'
while IFS= read -r commit_line; do
if [ -z "$commit_line" ]; then continue; fi
COMMIT_SHA=$(echo "$commit_line" | cut -d' ' -f1)
COMMIT_SUBJECT=$(echo "$commit_line" | cut -d' ' -f2-)
mapfile -t COMMIT_FILES < <(git diff-tree --no-commit-id --name-only -r "$COMMIT_SHA" | grep -Ev "$INFRA_PATTERNS")
# Only include commit if it touches at least one non-infra file that is still different
INCLUDE_COMMIT=false
for file in "${COMMIT_FILES[@]}"; do
for code_file in "${CODE_FILES[@]}"; do
if [ "$file" = "$code_file" ]; then
INCLUDE_COMMIT=true
break 2
fi
done
done
if [ "$INCLUDE_COMMIT" = true ]; then
COMMIT_SUBJECTS_ARRAY+=("- $COMMIT_SUBJECT")
FILES_JSON=$(printf '%s\n' "${COMMIT_FILES[@]}" | jq -R . | jq -s .)
COMMIT_JSON=$(jq -n --arg sha "$COMMIT_SHA" --arg subject "$COMMIT_SUBJECT" --argjson files "$FILES_JSON" '{sha: $sha, subject: $subject, files: $files}')
FILTERED_COMMITS_JSON=$(echo "$FILTERED_COMMITS_JSON" | jq --argjson item "$COMMIT_JSON" '. + [$item]')
fi
done <<< "$COMMITS_RAW"
echo 'commits_json<<EOF' >> $GITHUB_OUTPUT
printf "%s\n" "$FILTERED_COMMITS_JSON" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
echo "commit_subjects<<EOF" >> $GITHUB_OUTPUT
printf '%s\n' "${COMMIT_SUBJECTS_ARRAY[@]}" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
- name: Build PR content
if: steps.get_commits.outputs.has_changes == 'true'
id: build_pr_content
uses: actions/github-script@v7
env:
COMMITS_JSON: ${{ steps.prepare_commits.outputs.commits_json }}
CHANGES_SUMMARY: ${{ steps.summarize_changes.outputs.changes_summary }}
BRANCH_NAME: ${{ steps.create_branch.outputs.branch_name }}
GITHUB_REPOSITORY: ${{ github.repository }}
with:
github-token: ${{ steps.generate_token_push.outputs.token }}
script: |
const commits = JSON.parse(process.env.COMMITS_JSON || '[]');
const changesSummary = process.env.CHANGES_SUMMARY || 'Changes from fork';
const branchName = process.env.BRANCH_NAME || '';
const repo = process.env.GITHUB_REPOSITORY || '';
const [owner, reponame] = repo.split('/');
const nCommits = commits.length;
let prTitle = 'Sync ' + nCommits + ' commit' + (nCommits !== 1 ? 's' : '') + ' from fork:';
if (nCommits > 0) {
prTitle += ' ' + commits[0].subject;
}
let prBody = `This PR syncs ${nCommits} commit${nCommits !== 1 ? 's' : ''} from branch ${branchName}.\n\n`;
prBody += `**Changes Summary:**\n${changesSummary}\n\n`;
prBody += `Commits included:\n`;
for (const c of commits) {
prBody += `- ${c.subject} ([${c.sha}](https://github.com/${owner}/${reponame}/commit/${c.sha}))\n`;
}
core.setOutput('prTitle', prTitle);
core.setOutput('prBody', prBody);
- name: Open issue for PR checklist
if: steps.get_files.outputs.code_count != '0' && steps.prepare_commits.outputs.commit_subjects != ''
uses: actions/github-script@v7
env:
BRANCH_NAME: ${{ steps.create_branch.outputs.branch_name }}
PR_TITLE: ${{ steps.build_pr_content.outputs.prTitle }}
PR_BODY: ${{ steps.build_pr_content.outputs.prBody }}
GITHUB_REPOSITORY: ${{ github.repository }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const branch = process.env.BRANCH_NAME || '';
const prTitle = process.env.PR_TITLE || '';
const prBody = process.env.PR_BODY || '';
const repo = process.env.GITHUB_REPOSITORY || '';
const [owner, reponame] = repo.split('/');
const prLink = `https://github.com/TandoorRecipes/recipes/compare/tandoor-1...${owner}:${branch}?expand=1&title=${encodeURIComponent(prTitle)}`;
const issueTitle = `Manual Upstream PR Checklist: ${branch}`;
const issueBody = [
`A new branch is ready for upstream PR submission.`,
'',
`- [ ] Submit PR: [Create PR](${prLink})`,
'- [ ] PR merged',
'- [ ] Branch deleted',
'',
'**Suggested PR title:**',
'```',
prTitle,
'```',
'**Suggested PR body:**',
'```',
prBody,
'```',
].join('\n');
await github.rest.issues.create({
owner,
repo: reponame,
title: issueTitle,
body: issueBody
});

12
.gitignore vendored
View File

@@ -75,10 +75,8 @@ cookbook/static/vue
vue/webpack-stats.json
/docker-compose.override.yml
vue/node_modules
/recipes/plugins
vetur.config.js
cookbook/static/vue
vue/webpack-stats.json
plugins
vue3/node_modules
cookbook/templates/sw.js
vue/.yarn
vue3/.vite
@@ -87,8 +85,4 @@ vue3/.vite
vetur.config.js
venv/
.idea/easy-i18n.xml
cookbook/static/vue3
vue3/node_modules
cookbook/tests/other/docs/reports/tests/tests.html
cookbook/tests/other/docs/reports/tests/pytest.xml
vue3/src/plugins
cookbook/static/vue3

6
.idea/prettier.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PrettierConfiguration">
<option name="myConfigurationMode" value="AUTOMATIC" />
</component>
</project>

2
.idea/recipes.iml generated
View File

@@ -18,7 +18,7 @@
<excludeFolder url="file://$MODULE_DIR$/staticfiles" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (recipes)" jdkType="Python SDK" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">

2
.idea/vcs.xml generated
View File

@@ -2,7 +2,5 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/recipes/plugins/enterprise_plugin" vcs="Git" />
<mapping directory="$PROJECT_DIR$/recipes/plugins/open_data_plugin" vcs="Git" />
</component>
</project>

62
.idea/watcherTasks.xml generated
View File

@@ -5,7 +5,7 @@
<option name="arguments" value="-m flake8 $FilePath$ --config $ContentRoot$\.flake8" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="NEVER" />
<option name="exitCodeBehavior" value="ALWAYS" />
<option name="fileExtension" value="py" />
<option name="immediateSync" value="false" />
<option name="name" value="Flake8 Watcher" />
@@ -27,65 +27,5 @@
<option name="workingDir" value="" />
<envs />
</TaskOptions>
<TaskOptions isEnabled="false">
<option name="arguments" value="-m isort $FilePath$" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="ERROR" />
<option name="fileExtension" value="py" />
<option name="immediateSync" value="false" />
<option name="name" value="isort Watcher" />
<option name="output" value="$FilePath$" />
<option name="outputFilters">
<array />
</option>
<option name="outputFromStdout" value="false" />
<option name="program" value="$PyInterpreterDirectory$/python" />
<option name="runOnExternalChanges" value="false" />
<option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="false" />
<option name="workingDir" value="" />
<envs />
</TaskOptions>
<TaskOptions isEnabled="false">
<option name="arguments" value="-m yapf -i $FilePath$" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="NEVER" />
<option name="fileExtension" value="py" />
<option name="immediateSync" value="false" />
<option name="name" value="YAPF" />
<option name="output" value="$FilePath$" />
<option name="outputFilters">
<array />
</option>
<option name="outputFromStdout" value="false" />
<option name="program" value="$PyInterpreterDirectory$/python" />
<option name="runOnExternalChanges" value="false" />
<option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="false" />
<option name="workingDir" value="" />
<envs />
</TaskOptions>
<TaskOptions isEnabled="false">
<option name="arguments" value="--cwd $ProjectFileDir$\vue prettier -w --config $ProjectFileDir$\.prettierrc $FilePath$" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="ERROR" />
<option name="fileExtension" value="*" />
<option name="immediateSync" value="true" />
<option name="name" value="Prettier" />
<option name="output" value="" />
<option name="outputFilters">
<array />
</option>
<option name="outputFromStdout" value="false" />
<option name="program" value="yarn" />
<option name="runOnExternalChanges" value="true" />
<option name="scopeName" value="Prettier" />
<option name="trackOnlyRoot" value="false" />
<option name="workingDir" value="" />
<envs />
</TaskOptions>
</component>
</project>

30
.vscode/launch.json vendored
View File

@@ -1,18 +1,18 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Django",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver"],
"django": true,
"justMyCode": true
},
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Django",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver"],
"django": true,
"justMyCode": true
},
{
"name": "Python: Debug Tests",
"type": "debugpy",
@@ -24,7 +24,7 @@
"console": "integratedTerminal",
"env": {
// coverage and pytest can't both be running at the same time
"PYTEST_ADDOPTS": "--no-cov -n 0"
"PYTEST_ADDOPTS": "--no-cov"
},
"django": true,
"justMyCode": true

25
.vscode/settings.json vendored
View File

@@ -1,14 +1,15 @@
{
"python.testing.pytestArgs": [
"cookbook/tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[python]": {
"editor.defaultFormatter": "eeyore.yapf",
},
"yapf.args": [],
"isort.args": []
"python.testing.pytestArgs": ["cookbook/tests"],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[python]": {
"editor.defaultFormatter": "eeyore.yapf"
},
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"yapf.args": [],
"isort.args": []
}

154
.vscode/tasks.json vendored
View File

@@ -1,83 +1,75 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Run Migrations",
"type": "shell",
"command": "python3 manage.py migrate"
},
{
"label": "Collect Static Files",
"type": "shell",
"command": "python3 manage.py collectstatic",
"dependsOn": ["Yarn Build"]
},
{
"label": "Setup Dev Server",
"dependsOn": ["Run Migrations"]
},
{
"label": "Run Dev Server",
"type": "shell",
"dependsOn": ["Setup Dev Server"],
"command": "DEBUG=1 python3 manage.py runserver"
},
{
"label": "Yarn Install",
"type": "shell",
"command": "yarn install --force",
"options": {
"cwd": "${workspaceFolder}/vue3"
}
},
{
"label": "Generate API",
"type": "shell",
"command": "openapi-generator-cli generate -g typescript-fetch -i http://127.0.0.1:8000/openapi/",
"options": {
"cwd": "${workspaceFolder}/vue3/src/openapi"
}
},
{
"label": "Yarn Dev",
"type": "shell",
"command": "yarn dev",
"dependsOn": ["Yarn Install"],
"options": {
"cwd": "${workspaceFolder}/vue3"
}
},
{
"label": "Yarn Build",
"type": "shell",
"command": "yarn build",
"dependsOn": ["Yarn Install"],
"options": {
"cwd": "${workspaceFolder}/vue3"
"version": "2.0.0",
"tasks": [
{
"label": "Run Migrations",
"type": "shell",
"command": "python3 manage.py migrate",
},
"group": "build"
},
{
"label": "Setup Tests",
"dependsOn": ["Run Migrations", "Collect Static Files"]
},
{
"label": "Run all pytests",
"type": "shell",
"command": "python3 -m pytest cookbook/tests",
"dependsOn": ["Setup Tests"],
"group": "test"
},
{
"label": "Setup Documentation Dependencies",
"type": "shell",
"command": "pip install mkdocs-material mkdocs-include-markdown-plugin"
},
{
"label": "Serve Documentation",
"type": "shell",
"command": "mkdocs serve",
"dependsOn": ["Setup Documentation Dependencies"]
}
]
}
{
"label": "Collect Static Files",
"type": "shell",
"command": "python3 manage.py collectstatic",
"dependsOn": ["Yarn Build"],
},
{
"label": "Setup Dev Server",
"dependsOn": ["Run Migrations", "Yarn Build"],
},
{
"label": "Run Dev Server",
"type": "shell",
"dependsOn": ["Setup Dev Server"],
"command": "python3 manage.py runserver",
},
{
"label": "Yarn Install",
"type": "shell",
"command": "yarn install",
"options": {
"cwd": "${workspaceFolder}/vue"
}
},
{
"label": "Yarn Serve",
"type": "shell",
"command": "yarn serve",
"dependsOn": ["Yarn Install"],
"options": {
"cwd": "${workspaceFolder}/vue"
}
},
{
"label": "Yarn Build",
"type": "shell",
"command": "yarn build",
"dependsOn": ["Yarn Install"],
"options": {
"cwd": "${workspaceFolder}/vue"
},
"group": "build",
},
{
"label": "Setup Tests",
"dependsOn": ["Run Migrations", "Collect Static Files"],
},
{
"label": "Run all pytests",
"type": "shell",
"command": "python3 -m pytest cookbook/tests",
"dependsOn": ["Setup Tests"],
"group": "test",
},
{
"label": "Setup Documentation Dependencies",
"type": "shell",
"command": "pip install mkdocs-material mkdocs-include-markdown-plugin",
},
{
"label": "Serve Documentation",
"type": "shell",
"command": "mkdocs serve",
"dependsOn": ["Setup Documentation Dependencies"],
}
]
}

View File

@@ -1,14 +1,15 @@
FROM python:3.13-alpine3.22
FROM python:3.12.12-alpine3.21
#Install all dependencies.
RUN apk add --no-cache postgresql-libs postgresql-client gettext zlib libjpeg libwebp libxml2-dev libxslt-dev openldap git libgcc libstdc++ nginx tini envsubst nodejs npm
RUN apk add --no-cache postgresql-libs postgresql-client gettext zlib libjpeg libwebp libxml2-dev libxslt-dev openldap git
#Print all logs without buffering it.
ENV PYTHONUNBUFFERED=1 \
DOCKER=true
ENV PYTHONUNBUFFERED 1
ENV DOCKER true
#This port will be used by gunicorn.
EXPOSE 80 8080
EXPOSE 8080
#Create app dir and install requirements.
RUN mkdir /opt/recipes
@@ -16,27 +17,24 @@ WORKDIR /opt/recipes
COPY requirements.txt ./
RUN \
if [ `apk --print-arch` = "armv7" ]; then \
printf "[global]\nextra-index-url=https://www.piwheels.org/simple\n" > /etc/pip.conf ; \
fi
# remove Development dependencies from requirements.txt
RUN sed -i '/# Development/,$d' requirements.txt
RUN apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev xmlsec-dev xmlsec build-base g++ curl rust && \
RUN apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev xmlsec-dev xmlsec build-base && \
echo -n "INPUT ( libldap.so )" > /usr/lib/libldap_r.so && \
python -m venv venv && \
/opt/recipes/venv/bin/python -m pip install --upgrade pip && \
venv/bin/pip debug -v && \
venv/bin/pip install wheel==0.45.1 && \
venv/bin/pip install setuptools_rust==1.10.2 && \
venv/bin/pip install wheel==0.42.0 && \
venv/bin/pip install setuptools_rust==1.9.0 && \
venv/bin/pip install -r requirements.txt --no-cache-dir &&\
apk --purge del .build-deps
#Copy project and execute it.
COPY . ./
# delete default nginx config and link it to tandoors config
# create symlinks to access and error log to show them on stdout
RUN rm -rf /etc/nginx/http.d && \
ln -s /opt/recipes/http.d /etc/nginx/http.d && \
ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log
# commented for now https://github.com/TandoorRecipes/recipes/issues/3478
#HEALTHCHECK --interval=30s \
# --timeout=5s \
@@ -50,4 +48,4 @@ RUN /opt/recipes/venv/bin/python version.py
RUN find . -type d -name ".git" | xargs rm -rf
RUN chmod +x boot.sh
ENTRYPOINT ["/sbin/tini", "--", "/opt/recipes/boot.sh"]
ENTRYPOINT ["/opt/recipes/boot.sh"]

View File

@@ -23,7 +23,6 @@
<a href="https://docs.tandoor.dev/install/docker/" target="_blank" rel="noopener noreferrer">Installation</a> •
<a href="https://docs.tandoor.dev/" target="_blank" rel="noopener noreferrer">Docs</a> •
<a href="https://app.tandoor.dev/accounts/login/?demo" target="_blank" rel="noopener noreferrer">Demo</a> •
<a href="https://community.tandoor.dev" target="_blank" rel="noopener noreferrer">Community</a> •
<a href="https://discord.gg/RhzBrfWgtp" target="_blank" rel="noopener noreferrer">Discord</a>
</p>
@@ -82,13 +81,13 @@ Share some information on how you use Tandoor to help me improve the application
<table>
<tr>
<td><a href="https://community.tandoor.dev">Community</a></td>
<td>Get support, share best practices, discuss feature ideas, and meet other Tandoor users.</td>
<td><a href="https://discord.gg/RhzBrfWgtp">Discord</a></td>
<td>We have a public Discord server that anyone can join. This is where all our developers and contributors hang out and where we make announcements</td>
</tr>
<tr>
<td><a href="https://discord.gg/RhzBrfWgtp">Discord</a></td>
<td>We have a public Discord server that anyone can join. This is where all our developers and contributors hang out and where we make announcements</td>
<td><a href="https://twitter.com/TandoorRecipes">Twitter</a></td>
<td>You can follow our Twitter account to get updates on new features or releases</td>
</tr>
</table>

36
boot.sh Executable file → Normal file
View File

@@ -1,21 +1,11 @@
#!/bin/sh
source venv/bin/activate
# these are envsubst in the nginx config, make sure they default to something sensible when unset
export TANDOOR_PORT="${TANDOOR_PORT:-8080}"
export MEDIA_ROOT=${MEDIA_ROOT:-/opt/recipes/mediafiles};
export STATIC_ROOT=${STATIC_ROOT:-/opt/recipes/staticfiles};
TANDOOR_PORT="${TANDOOR_PORT:-8080}"
GUNICORN_WORKERS="${GUNICORN_WORKERS:-3}"
GUNICORN_THREADS="${GUNICORN_THREADS:-2}"
GUNICORN_LOG_LEVEL="${GUNICORN_LOG_LEVEL:-'info'}"
PLUGINS_BUILD="${PLUGINS_BUILD:-0}"
if [ "${TANDOOR_PORT}" -eq 80 ]; then
echo "TANDOOR_PORT set to 8080 because 80 is now taken by the integrated nginx"
TANDOOR_PORT=8080
fi
NGINX_CONF_FILE=/opt/recipes/nginx/conf.d/Recipes.conf
display_warning() {
echo "[WARNING]"
@@ -24,6 +14,11 @@ display_warning() {
echo "Checking configuration..."
# Nginx config file must exist if gunicorn is not active
if [ ! -f "$NGINX_CONF_FILE" ] && [ $GUNICORN_MEDIA -eq 0 ]; then
display_warning "Nginx configuration file could not be found at the default location!\nPath: ${NGINX_CONF_FILE}"
fi
# SECRET_KEY (or a valid file at SECRET_KEY_FILE) must be set in .env file
if [ -f "${SECRET_KEY_FILE}" ]; then
@@ -84,31 +79,20 @@ echo "Database is ready"
echo "Migrating database"
python manage.py migrate
if [ "${PLUGINS_BUILD}" -eq 1 ]; then
echo "Running yarn build at startup because PLUGINS_BUILD is enabled"
python plugin.py
fi
python manage.py migrate
echo "Collecting static files, this may take a while..."
python manage.py collectstatic_js_reverse
python manage.py collectstatic --noinput
echo "Done"
chmod -R 755 ${MEDIA_ROOT:-/opt/recipes/mediafiles}
chmod -R 755 /opt/recipes/mediafiles
ipv6_disable=$(cat /sys/module/ipv6/parameters/disable)
# prepare nginx config
envsubst '$MEDIA_ROOT $STATIC_ROOT $TANDOOR_PORT' < /opt/recipes/http.d/Recipes.conf.template > /opt/recipes/http.d/Recipes.conf
# start nginx
echo "Starting nginx"
nginx
echo "Starting gunicorn"
# Check if IPv6 is enabled, only then run gunicorn with ipv6 support
if [ "$ipv6_disable" -eq 0 ]; then
exec gunicorn -b "[::]:$TANDOOR_PORT" --workers $GUNICORN_WORKERS --threads $GUNICORN_THREADS --access-logfile - --error-logfile - --log-level $GUNICORN_LOG_LEVEL recipes.wsgi

View File

@@ -7,11 +7,10 @@ from django.utils import translation
from django_scopes import scopes_disabled
from treebeard.admin import TreeAdmin
from treebeard.forms import movenodeform_factory
from allauth.account.decorators import secure_admin_login
from cookbook.managers import DICTIONARY
from .models import (BookmarkletImport, Comment, CookLog, CustomFilter, Food, ImportLog, Ingredient, InviteLink,
from .models import (BookmarkletImport, Comment, CookLog, Food, ImportLog, Ingredient, InviteLink,
Keyword, MealPlan, MealType, NutritionInformation, Property, PropertyType,
Recipe, RecipeBook, RecipeBookEntry, RecipeImport, SearchPreference, ShareLink,
ShoppingListEntry, ShoppingListRecipe, Space, Step, Storage,
@@ -19,8 +18,6 @@ from .models import (BookmarkletImport, Comment, CookLog, CustomFilter, Food, Im
TelegramBot, Unit, UnitConversion, UserFile, UserPreference, UserSpace,
ViewLog, ConnectorConfig)
admin.site.login = secure_admin_login(admin.site.login)
class CustomUserAdmin(UserAdmin):
def has_add_permission(self, request, obj=None):
@@ -106,13 +103,6 @@ class ConnectorConfigAdmin(admin.ModelAdmin):
admin.site.register(ConnectorConfig, ConnectorConfigAdmin)
class CustomFilterAdmin(admin.ModelAdmin):
list_display = ('id', 'type', 'name')
admin.site.register(CustomFilter, CustomFilterAdmin)
class SyncAdmin(admin.ModelAdmin):
list_display = ('storage', 'path', 'active', 'last_checked')
search_fields = ('storage__name', 'path')

View File

@@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Optional
from cookbook.models import ShoppingListEntry, User, ConnectorConfig
from cookbook.models import ConnectorConfig, ShoppingListEntry, User
@dataclass
@@ -12,10 +12,7 @@ class UserDTO:
@staticmethod
def create_from_user(instance: User) -> 'UserDTO':
return UserDTO(
username=instance.username,
first_name=instance.first_name if instance.first_name else None
)
return UserDTO(username=instance.username, first_name=instance.first_name if instance.first_name else None)
@dataclass
@@ -42,6 +39,7 @@ class ShoppingListEntryDTO:
# A Connector is 'destroyed' & recreated each time 'any' ConnectorConfig in a space changes.
class Connector(ABC):
@abstractmethod
def __init__(self, config: ConnectorConfig):
pass

View File

@@ -7,14 +7,14 @@ from dataclasses import dataclass
from enum import Enum
from logging import Logger
from types import UnionType
from typing import List, Any, Dict, Optional, Type
from typing import Any, Dict, List, Optional, Type
from django.conf import settings
from django_scopes import scope
from cookbook.connectors.connector import Connector, ShoppingListEntryDTO
from cookbook.connectors.homeassistant import HomeAssistant
from cookbook.models import ShoppingListEntry, Space, ConnectorConfig
from cookbook.models import ConnectorConfig, ShoppingListEntry, Space
REGISTERED_CLASSES: UnionType | Type = ShoppingListEntry
@@ -58,7 +58,10 @@ class ConnectorManager(metaclass=Singleton):
self._logger = logging.getLogger("recipes.connector")
self._logger.debug("ConnectorManager initializing")
self._queue = queue.Queue(maxsize=settings.EXTERNAL_CONNECTORS_QUEUE_SIZE)
self._worker = threading.Thread(target=self.worker, args=(0, self._queue,), daemon=True)
self._worker = threading.Thread(target=self.worker, args=(
0,
self._queue,
), daemon=True)
self._worker.start()
# Called by post save & post delete signals

View File

@@ -5,14 +5,16 @@ from urllib.parse import urljoin
from aiohttp import request, ClientResponseError
from cookbook.connectors.connector import Connector, ShoppingListEntryDTO
from cookbook.models import ConnectorConfig
from cookbook.connectors.connector import Connector
from cookbook.models import ShoppingListEntry, ConnectorConfig, Space
class HomeAssistant(Connector):
_config: ConnectorConfig
_logger: Logger
_required_foreign_keys = ("food", "unit", "created_by")
def __init__(self, config: ConnectorConfig):
if not config.token or not config.url or not config.todo_entity:
raise ValueError("config for HomeAssistantConnector in incomplete")
@@ -32,7 +34,7 @@ class HomeAssistant(Connector):
response.raise_for_status()
return await response.json()
async def on_shopping_list_entry_created(self, shopping_list_entry: ShoppingListEntryDTO) -> None:
async def on_shopping_list_entry_created(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
if not self._config.on_shopping_list_entry_created_enabled:
return
@@ -53,15 +55,20 @@ class HomeAssistant(Connector):
except ClientResponseError as err:
self._logger.warning(f"received an exception from the api: {err.request_info.url=}, {err.request_info.method=}, {err.status=}, {err.message=}, {type(err)=}")
async def on_shopping_list_entry_updated(self, shopping_list_entry: ShoppingListEntryDTO) -> None:
async def on_shopping_list_entry_updated(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
if not self._config.on_shopping_list_entry_updated_enabled:
return
pass
async def on_shopping_list_entry_deleted(self, shopping_list_entry: ShoppingListEntryDTO) -> None:
async def on_shopping_list_entry_deleted(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
if not self._config.on_shopping_list_entry_deleted_enabled:
return
if not all(k in shopping_list_entry._state.fields_cache for k in self._required_foreign_keys):
# Sometimes the food foreign key is not loaded, and we cant load it from an async process
self._logger.debug("required property was not present in ShoppingListEntry")
return
item, _ = _format_shopping_list_entry(shopping_list_entry)
self._logger.debug(f"removing {item=} from {self._config.todo_entity}")
@@ -81,19 +88,19 @@ class HomeAssistant(Connector):
pass
def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntryDTO) -> Tuple[str, str]:
item = shopping_list_entry.food_name
if shopping_list_entry.amount:
def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry) -> Tuple[str, str]:
item = shopping_list_entry.food.name
if shopping_list_entry.amount > 0:
item += f" ({shopping_list_entry.amount:.2f}".rstrip('0').rstrip('.')
if shopping_list_entry.base_unit:
item += f" {shopping_list_entry.base_unit})"
elif shopping_list_entry.unit_name:
item += f" {shopping_list_entry.unit_name})"
if shopping_list_entry.unit and shopping_list_entry.unit.base_unit and len(shopping_list_entry.unit.base_unit) > 0:
item += f" {shopping_list_entry.unit.base_unit})"
elif shopping_list_entry.unit and shopping_list_entry.unit.name and len(shopping_list_entry.unit.name) > 0:
item += f" {shopping_list_entry.unit.name})"
else:
item += ")"
description = "From TandoorRecipes"
if shopping_list_entry.created_by.first_name:
if shopping_list_entry.created_by.first_name and len(shopping_list_entry.created_by.first_name) > 0:
description += f", by {shopping_list_entry.created_by.first_name}"
else:
description += f", by {shopping_list_entry.created_by.username}"

View File

@@ -1,5 +1,6 @@
from datetime import datetime
from allauth.account.forms import ResetPasswordForm, SignupForm
from allauth.socialaccount.forms import SignupForm as SocialSignupForm
from django import forms
@@ -13,6 +14,7 @@ from hcaptcha.fields import hCaptchaField
from .models import Comment, InviteLink, Keyword, Recipe, SearchPreference, Space, Storage, Sync, User, UserPreference, ConnectorConfig
class SelectWidget(widgets.Select):
class Media:
js = ('custom/js/form_select.js',)
@@ -21,6 +23,49 @@ class SelectWidget(widgets.Select):
class MultiSelectWidget(widgets.SelectMultiple):
class Media:
js = ('custom/js/form_multiselect.js',)
# Yes there are some stupid browsers that still dont support this but
# I dont support people using these browsers.
class DateWidget(forms.DateInput):
input_type = 'date'
def __init__(self, **kwargs):
kwargs["format"] = "%Y-%m-%d"
super().__init__(**kwargs)
class UserNameForm(forms.ModelForm):
prefix = 'name'
class Meta:
model = User
fields = ('first_name', 'last_name')
help_texts = {'first_name': _('Both fields are optional. If none are given the username will be displayed instead')}
class ExternalRecipeForm(forms.ModelForm):
file_path = forms.CharField(disabled=True, required=False)
file_uid = forms.CharField(disabled=True, required=False)
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['keywords'].queryset = Keyword.objects.filter(space=space).all()
class Meta:
model = Recipe
fields = ('name', 'description', 'servings', 'working_time', 'waiting_time', 'file_path', 'file_uid', 'keywords')
labels = {
'name': _('Name'), 'keywords': _('Keywords'), 'working_time': _('Preparation time in minutes'), 'waiting_time': _('Waiting time (cooking/baking) in minutes'),
'file_path': _('Path'), 'file_uid': _('Storage UID'),
}
widgets = {'keywords': MultiSelectWidget}
field_classes = {'keywords': SafeModelMultipleChoiceField, }
class ImportExportBase(forms.Form):
DEFAULT = 'DEFAULT'
PAPRIKA = 'PAPRIKA'
@@ -52,6 +97,7 @@ class ImportExportBase(forms.Form):
(PLANTOEAT, 'Plantoeat'), (COOKBOOKAPP, 'CookBookApp'), (COPYMETHAT, 'CopyMeThat'), (PDF, 'PDF'), (MELARECIPES, 'Melarecipes'),
(COOKMATE, 'Cookmate'), (REZEPTSUITEDE, 'Recipesuite.de'), (GOURMET, 'Gourmet')))
class MultipleFileInput(forms.ClearableFileInput):
allow_multiple_selected = True
@@ -75,6 +121,8 @@ class ImportForm(ImportExportBase):
files = MultipleFileField(required=True)
duplicates = forms.BooleanField(help_text=_('To prevent duplicates recipes with the same name as existing ones are ignored. Check this box to import everything.'),
required=False)
class ExportForm(ImportExportBase):
recipes = forms.ModelMultipleChoiceField(widget=MultiSelectWidget, queryset=Recipe.objects.none(), required=False)
all = forms.BooleanField(required=False)
@@ -85,7 +133,125 @@ class ExportForm(ImportExportBase):
super().__init__(*args, **kwargs)
self.fields['recipes'].queryset = Recipe.objects.filter(space=space).all()
from .models import InviteLink, SearchPreference, Space, User, UserPreference
class CommentForm(forms.ModelForm):
prefix = 'comment'
class Meta:
model = Comment
fields = ('text',)
labels = {'text': _('Add your comment: '), }
widgets = {'text': forms.Textarea(attrs={'rows': 2, 'cols': 15}), }
class StorageForm(forms.ModelForm):
username = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password'}), required=False)
password = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}),
required=False,
help_text=_('Leave empty for dropbox and enter app password for nextcloud.'))
token = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}),
required=False,
help_text=_('Leave empty for nextcloud and enter api token for dropbox.'))
class Meta:
model = Storage
fields = ('name', 'method', 'username', 'password', 'token', 'url', 'path')
help_texts = {'url': _('Leave empty for dropbox and enter only base url for nextcloud (<code>/remote.php/webdav/</code> is added automatically)'), }
class ConnectorConfigForm(forms.ModelForm):
enabled = forms.BooleanField(
help_text="Is the connector enabled",
required=False,
)
on_shopping_list_entry_created_enabled = forms.BooleanField(
help_text="Enable action for ShoppingListEntry created events",
required=False,
)
on_shopping_list_entry_updated_enabled = forms.BooleanField(
help_text="Enable action for ShoppingListEntry updated events",
required=False,
)
on_shopping_list_entry_deleted_enabled = forms.BooleanField(
help_text="Enable action for ShoppingListEntry deleted events",
required=False,
)
supports_description_field = forms.BooleanField(
help_text="Does the connector todo entity support the description field",
initial=True,
required=False,
)
update_token = forms.CharField(
widget=forms.TextInput(attrs={'autocomplete': 'update-token', 'type': 'password'}),
required=False,
help_text=_('<a href="https://www.home-assistant.io/docs/authentication/#your-account-profile">Long Lived Access Token</a> for your HomeAssistant instance')
)
url = forms.URLField(
required=False,
help_text=_('Something like http://homeassistant.local:8123/api'),
)
class Meta:
model = ConnectorConfig
fields = (
'name', 'type', 'enabled', 'on_shopping_list_entry_created_enabled', 'on_shopping_list_entry_updated_enabled',
'on_shopping_list_entry_deleted_enabled', 'supports_description_field', 'url', 'todo_entity',
)
help_texts = {
'url': _('http://homeassistant.local:8123/api for example'),
}
class SyncForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['storage'].queryset = Storage.objects.filter(space=space).all()
class Meta:
model = Sync
fields = ('storage', 'path', 'active')
field_classes = {'storage': SafeModelChoiceField, }
labels = {'storage': _('Storage'), 'path': _('Path'), 'active': _('Active')}
class BatchEditForm(forms.Form):
search = forms.CharField(label=_('Search String'))
keywords = forms.ModelMultipleChoiceField(queryset=Keyword.objects.none(), required=False, widget=MultiSelectWidget)
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['keywords'].queryset = Keyword.objects.filter(space=space).all().order_by('id')
class ImportRecipeForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['keywords'].queryset = Keyword.objects.filter(space=space).all()
class Meta:
model = Recipe
fields = ('name', 'keywords', 'file_path', 'file_uid')
labels = {'name': _('Name'), 'keywords': _('Keywords'), 'file_path': _('Path'), 'file_uid': _('File ID'), }
widgets = {'keywords': MultiSelectWidget}
field_classes = {'keywords': SafeModelChoiceField, }
class InviteLinkForm(forms.ModelForm):
@@ -173,3 +339,38 @@ class UserCreateForm(forms.Form):
name = forms.CharField(label='Username')
password = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
password_confirm = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
class SearchPreferenceForm(forms.ModelForm):
prefix = 'search'
trigram_threshold = forms.DecimalField(min_value=0.01,
max_value=1,
decimal_places=2,
widget=NumberInput(attrs={'class': "form-control-range", 'type': 'range'}),
help_text=_('Determines how fuzzy a search is if it uses trigram similarity matching (e.g. low values mean more typos are ignored).'))
preset = forms.CharField(widget=forms.HiddenInput(), required=False)
class Meta:
model = SearchPreference
fields = ('search', 'lookup', 'unaccent', 'icontains', 'istartswith', 'trigram', 'fulltext', 'trigram_threshold')
help_texts = {
'search': _('Select type method of search. Click <a href="/docs/search/">here</a> for full description of choices.'), 'lookup':
_('Use fuzzy matching on units, keywords and ingredients when editing and importing recipes.'), 'unaccent':
_('Fields to search ignoring accents. Selecting this option can improve or degrade search quality depending on language'), 'icontains':
_("Fields to search for partial matches. (e.g. searching for 'Pie' will return 'pie' and 'piece' and 'soapie')"), 'istartswith':
_("Fields to search for beginning of word matches. (e.g. searching for 'sa' will return 'salad' and 'sandwich')"), 'trigram':
_("Fields to 'fuzzy' search. (e.g. searching for 'recpie' will find 'recipe'.) Note: this option will conflict with 'web' and 'raw' methods of search."),
'fulltext':
_("Fields to full text search. Note: 'web', 'phrase', and 'raw' search methods only function with fulltext fields."),
}
labels = {
'search': _('Search Method'), 'lookup': _('Fuzzy Lookups'), 'unaccent': _('Ignore Accent'), 'icontains': _("Partial Match"), 'istartswith': _("Starts With"),
'trigram': _("Fuzzy Search"), 'fulltext': _("Full Text")
}
widgets = {
'search': SelectWidget, 'unaccent': MultiSelectWidget, 'icontains': MultiSelectWidget, 'istartswith': MultiSelectWidget, 'trigram': MultiSelectWidget, 'fulltext':
MultiSelectWidget,
}

View File

@@ -109,7 +109,7 @@ class AutomationEngine:
Moves a string that should never be treated as a unit to next token and optionally replaced with default unit
e.g. NEVER_UNIT: param1: egg, param2: None would modify ['1', 'egg', 'white'] to ['1', '', 'egg', 'white']
or NEVER_UNIT: param1: egg, param2: pcs would modify ['1', 'egg', 'yolk'] to ['1', 'pcs', 'egg', 'yolk']
:param1 tokens: string that should never be considered a unit, will be moved to token[2]
:param1 string: string that should never be considered a unit, will be moved to token[2]
:param2 (optional) unit as string: will insert unit string into token[1]
:return: unit as string (possibly changed by automation)
"""
@@ -135,7 +135,7 @@ class AutomationEngine:
new_unit = self.never_unit[tokens[1].lower()]
never_unit = True
except KeyError:
return tokens, never_unit
return tokens
else:
if a := Automation.objects.annotate(param_1_lower=Lower('param_1')).filter(space=self.request.space, type=Automation.NEVER_UNIT, param_1_lower__in=[
tokens[1].lower(), alt_unit.lower()], disabled=False).order_by('order').first():
@@ -144,7 +144,7 @@ class AutomationEngine:
if never_unit:
tokens.insert(1, new_unit)
return tokens, never_unit
return tokens
def apply_transpose_automation(self, string):
"""

View File

@@ -1,102 +0,0 @@
# custom processing for schema
# reason: DRF writable nested needs ID's to decide if a nested object should be created or updated
# the API schema/client make ID's read only by default and strips them entirely in request objects (with COMPONENT_SPLIT_REQUEST enabled)
# change the schema to make IDs optional but writable so they are included in the request
def custom_postprocessing_hook(result, generator, request, public):
for c in result['components']['schemas'].keys():
# handle schemas used by the client to do requests on the server
if 'properties' in result['components']['schemas'][c] and 'id' in result['components']['schemas'][c]['properties']:
# make ID field not read only so it's not stripped from the request on the client
result['components']['schemas'][c]['properties']['id']['readOnly'] = False
# make ID field not required
if 'required' in result['components']['schemas'][c] and 'id' in result['components']['schemas'][c]['required']:
result['components']['schemas'][c]['required'].remove('id')
return result
# TODO remove below once legacy API has been fully deprecated
from drf_spectacular.openapi import AutoSchema # noqa: E402 isort: skip
import functools # noqa: E402 isort: skip
import re # noqa: E402 isort: skip
class LegacySchema(AutoSchema):
operation_id_base = None
@functools.cached_property
def path(self):
path = re.sub(pattern=self.path_prefix, repl='', string=self.path, flags=re.IGNORECASE)
# remove path variables
return re.sub(pattern=r'\{[\w\-]+\}', repl='', string=path)
def get_operation_id(self):
"""
Compute an operation ID from the view type and get_operation_id_base method.
"""
method_name = getattr(self.view, 'action', self.method.lower())
if self._is_list_view():
action = 'list'
elif method_name not in self.method_mapping:
action = self._to_camel_case(method_name)
else:
action = self.method_mapping[self.method.lower()]
name = self.get_operation_id_base(action)
return action + name
def get_operation_id_base(self, action):
"""
Compute the base part for operation ID from the model, serializer or view name.
"""
model = getattr(getattr(self.view, 'queryset', None), 'model', None)
if self.operation_id_base is not None:
name = self.operation_id_base
# Try to deduce the ID from the view's model
elif model is not None:
name = model.__name__
# Try with the serializer class name
elif self.get_serializer() is not None:
name = self.get_serializer().__class__.__name__
if name.endswith('Serializer'):
name = name[:-10]
# Fallback to the view name
else:
name = self.view.__class__.__name__
if name.endswith('APIView'):
name = name[:-7]
elif name.endswith('View'):
name = name[:-4]
# Due to camel-casing of classes and `action` being lowercase, apply title in order to find if action truly
# comes at the end of the name
if name.endswith(action.title()): # ListView, UpdateAPIView, ThingDelete ...
name = name[:-len(action)]
if action == 'list' and not name.endswith('s'): # listThings instead of listThing
name += 's'
return name
def get_serializer(self):
view = self.view
if not hasattr(view, 'get_serializer'):
return None
try:
return view.get_serializer()
except Exception:
return None
def _to_camel_case(self, snake_str):
components = snake_str.split('_')
# We capitalize the first letter of each component except the first one
# with the 'title' method and join them together.
return components[0] + ''.join(x.title() for x in components[1:])

View File

@@ -37,7 +37,7 @@ def get_filetype(name):
def is_file_type_allowed(filename, image_only=False):
is_file_allowed = False
allowed_file_types = ['.pdf', '.docx', '.xlsx', '.css', '.mp4', '.mov']
allowed_file_types = ['.pdf', '.docx', '.xlsx']
allowed_image_types = ['.png', '.jpg', '.jpeg', '.gif', '.webp']
check_list = allowed_image_types
if not image_only:
@@ -50,18 +50,6 @@ def is_file_type_allowed(filename, image_only=False):
return is_file_allowed
def strip_image_meta(image_object, file_format):
image_object = Image.open(image_object)
data = list(image_object.getdata())
image_without_exif = Image.new(image_object.mode, image_object.size)
image_without_exif.putdata(data)
im_io = BytesIO()
image_without_exif.save(im_io, file_format)
return im_io
# TODO this whole file needs proper documentation, refactoring, and testing
# TODO also add env variable to define which images sizes should be compressed
# filetype argument can not be optional, otherwise this function will treat all images as if they were a jpeg
@@ -72,21 +60,9 @@ def handle_image(request, image_object, filetype):
except Exception:
return None
file_format = None
if filetype == '.jpeg' or filetype == '.jpg':
file_format = 'JPEG'
if filetype == '.png':
file_format = 'PNG'
if filetype == '.webp':
file_format = 'WEBP'
if (image_object.size / 1000) > 500: # if larger than 500 kb compress
if filetype == '.jpeg' or filetype == '.jpg':
return rescale_image_jpeg(image_object)
if filetype == '.png':
return rescale_image_png(image_object)
else:
return strip_image_meta(image_object, file_format)
# TODO webp and gifs bypass the scaling and metadata checks, fix
return image_object

View File

@@ -58,8 +58,7 @@ class IngredientParser:
def parse_fraction(self, x):
if len(x) == 1 and 'fraction' in unicodedata.decomposition(x):
frac_split = unicodedata.decomposition(x[-1:]).split()
return (float((frac_split[1]).replace('003', ''))
/ float((frac_split[3]).replace('003', '')))
return (float((frac_split[1]).replace('003', '')) / float((frac_split[3]).replace('003', '')))
else:
frac_split = x.split('/')
if not len(frac_split) == 2:
@@ -78,12 +77,7 @@ class IngredientParser:
did_check_frac = False
end = 0
while (end < len(x) and (x[end] in string.digits
or (
(x[end] == '.' or x[end] == ',' or x[end] == '/')
and end + 1 < len(x)
and x[end + 1] in string.digits
))):
while (end < len(x) and (x[end] in string.digits or ((x[end] == '.' or x[end] == ',' or x[end] == '/') and end + 1 < len(x) and x[end + 1] in string.digits))):
end += 1
if end > 0:
if "/" in x[:end]:
@@ -107,8 +101,9 @@ class IngredientParser:
if unit is not None and unit.strip() == '':
unit = None
if unit is not None and (unit.startswith('(') or unit.startswith(
'-')): # i dont know any unit that starts with ( or - so its likely an alternative like 1L (500ml) Water or 2-3
if unit is not None and (
unit.startswith('(') or unit.startswith('-')
): # i dont know any unit that starts with ( or - so its likely an alternative like 1L (500ml) Water or 2-3
unit = None
note = x
return amount, unit, note
@@ -176,6 +171,7 @@ class IngredientParser:
# if something like this is detected move it to the beginning so the parser can handle it
if len(ingredient) < 1000 and re.search(r'^([^\W\d_])+(.)*[1-9](\d)*\s*([^\W\d_])+', ingredient):
match = re.search(r'[1-9](\d)*\s*([^\W\d_])+', ingredient)
print(f'reording from {ingredient} to {ingredient[match.start():match.end()] + " " + ingredient.replace(ingredient[match.start():match.end()], "")}')
ingredient = ingredient[match.start():match.end()] + ' ' + ingredient.replace(ingredient[match.start():match.end()], '')
# if the string contains parenthesis early on remove it and place it at the end
@@ -210,46 +206,39 @@ class IngredientParser:
# three arguments if it already has a unit there can't be
# a fraction for the amount
if len(tokens) > 2:
never_unit_applied = False
if not self.ignore_rules:
tokens, never_unit_applied = self.automation.apply_never_unit_automation(tokens)
if never_unit_applied:
unit = tokens[1]
food, note = self.parse_food(tokens[2:])
else:
try:
if unit is not None:
# a unit is already found, no need to try the second argument for a fraction
# probably not the best method to do it, but I didn't want to make an if check and paste the exact same thing in the else as already is in the except
raise ValueError
# try to parse second argument as amount and add that, in case of '2 1/2' or '2 ½'
if tokens[1]:
amount += self.parse_fraction(tokens[1])
# assume that units can't end with a comma
if len(tokens) > 3 and not tokens[2].endswith(','):
# try to use third argument as unit and everything else as food, use everything as food if it fails
try:
food, note = self.parse_food(tokens[3:])
unit = tokens[2]
except ValueError:
food, note = self.parse_food(tokens[2:])
else:
tokens = self.automation.apply_never_unit_automation(tokens)
try:
if unit is not None:
# a unit is already found, no need to try the second argument for a fraction
# probably not the best method to do it, but I didn't want to make an if check and paste the exact same thing in the else as already is in the except
raise ValueError
# try to parse second argument as amount and add that, in case of '2 1/2' or '2 ½'
amount += self.parse_fraction(tokens[1])
# assume that units can't end with a comma
if len(tokens) > 3 and not tokens[2].endswith(','):
# try to use third argument as unit and everything else as food, use everything as food if it fails
try:
food, note = self.parse_food(tokens[3:])
unit = tokens[2]
except ValueError:
food, note = self.parse_food(tokens[2:])
except ValueError:
# assume that units can't end with a comma
if not tokens[1].endswith(','):
# try to use second argument as unit and everything else as food, use everything as food if it fails
try:
food, note = self.parse_food(tokens[2:])
if unit is None:
unit = tokens[1]
else:
note = tokens[1]
except ValueError:
food, note = self.parse_food(tokens[1:])
else:
else:
food, note = self.parse_food(tokens[2:])
except ValueError:
# assume that units can't end with a comma
if not tokens[1].endswith(','):
# try to use second argument as unit and everything else as food, use everything as food if it fails
try:
food, note = self.parse_food(tokens[2:])
if unit is None:
unit = tokens[1]
else:
note = tokens[1]
except ValueError:
food, note = self.parse_food(tokens[1:])
else:
food, note = self.parse_food(tokens[1:])
else:
# only two arguments, first one is the amount
# which means this is the food
@@ -270,7 +259,6 @@ class IngredientParser:
if food and not self.ignore_rules:
food = self.automation.apply_food_automation(food)
if len(food) > Food._meta.get_field('name').max_length: # test if food name is to long
# try splitting it at a space and taking only the first arg
if len(food.split()) > 1 and len(food.split()[0]) < Food._meta.get_field('name').max_length:

View File

@@ -7,9 +7,7 @@ class StyleTreeprocessor(Treeprocessor):
def run_processor(self, node):
for child in node:
if child.tag == "table":
child.set("class", "markdown-table")
if child.tag == "th" or child.tag == "td":
child.set("class", "markdown-table-cell")
child.set("class", "table table-bordered")
if child.tag == "img":
child.set("class", "img-fluid")
self.run_processor(child)

View File

@@ -6,8 +6,6 @@ from cookbook.models import (Food, FoodProperty, Property, PropertyType, Superma
SupermarketCategory, SupermarketCategoryRelation, Unit, UnitConversion)
import re
from recipes.settings import DEBUG
class OpenDataImportResponse:
total_created = 0
@@ -341,7 +339,7 @@ class OpenDataImporter:
obj_dict = {
'name': self.data[datatype][k]['name'],
'plural_name': self.data[datatype][k]['plural_name'] if self.data[datatype][k]['plural_name'] != '' else None,
'supermarket_category_id': self.slug_id_cache['category'][self.data[datatype][k]['store_category']] if self.data[datatype][k]['store_category'] in self.slug_id_cache['category'] else None,
'supermarket_category_id': self.slug_id_cache['category'][self.data[datatype][k]['store_category']],
'fdc_id': re.sub(r'\D', '', self.data[datatype][k]['fdc_id']) if self.data[datatype][k]['fdc_id'] != '' else None,
'open_data_slug': k,
'properties_food_unit_id': None,
@@ -369,28 +367,12 @@ class OpenDataImporter:
create_list.append({'data': obj_dict})
if self.update_existing and len(update_list) > 0:
try:
model_type.objects.bulk_update(update_list, field_list)
od_response.total_updated += len(update_list)
except Exception:
if DEBUG:
print('========= LOAD FOOD FAILED ============')
print(update_list)
print(existing_data_names)
print(existing_data_slugs)
traceback.print_exc()
model_type.objects.bulk_update(update_list, field_list)
od_response.total_updated += len(update_list)
if len(create_list) > 0:
try:
Food.load_bulk(create_list, None)
od_response.total_created += len(create_list)
except Exception:
if DEBUG:
print('========= LOAD FOOD FAILED ============')
print(create_list)
print(existing_data_names)
print(existing_data_slugs)
traceback.print_exc()
Food.load_bulk(create_list, None)
od_response.total_created += len(create_list)
# --------------- PROPERTY STUFF -----------------------
model_type = Property

View File

@@ -160,15 +160,18 @@ class GroupRequiredMixin(object):
def dispatch(self, request, *args, **kwargs):
if not has_group_permission(request.user, self.groups_required):
if not request.user.is_authenticated:
messages.add_message(request, messages.ERROR, _('You are not logged in and therefore cannot view this page!'))
messages.add_message(request, messages.ERROR,
_('You are not logged in and therefore cannot view this page!'))
return HttpResponseRedirect(reverse_lazy('account_login') + '?next=' + request.path)
else:
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
messages.add_message(request, messages.ERROR,
_('You do not have the required permissions to view this page!'))
return HttpResponseRedirect(reverse_lazy('index'))
try:
obj = self.get_object()
if obj.get_space() != request.space:
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
messages.add_message(request, messages.ERROR,
_('You do not have the required permissions to view this page!'))
return HttpResponseRedirect(reverse_lazy('index'))
except AttributeError:
pass

View File

@@ -44,17 +44,13 @@ class FoodPropertyHelper:
if i.food is not None:
conversions = uch.get_conversions(i)
for pt in property_types:
# if a property could be calculated with an actual value
found_property = False
# if food has a value for the given property type (no matter if conversion is possible)
has_property_value = False
if i.food.properties_food_amount == 0 or i.food.properties_food_unit is None and not (i.amount == 0 or i.no_amount): # if food is configured incorrectly
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': {'id': i.food.id, 'name': i.food.name}, 'value': None}
if i.food.properties_food_amount == 0 or i.food.properties_food_unit is None: # if food is configured incorrectly
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': i.food.name, 'value': None}
computed_properties[pt.id]['missing_value'] = True
else:
for p in i.food.properties.all():
if p.property_type == pt and p.property_amount is not None:
has_property_value = True
for c in conversions:
if c.unit == i.food.properties_food_unit:
found_property = True
@@ -62,19 +58,12 @@ class FoodPropertyHelper:
computed_properties[pt.id]['food_values'] = self.add_or_create(
computed_properties[p.property_type.id]['food_values'], c.food.id, (c.amount / i.food.properties_food_amount) * p.property_amount, c.food)
if not found_property:
# if no amount and food does not exist yet add it but don't count as missing
if i.amount == 0 or i.no_amount and i.food.id not in computed_properties[pt.id]['food_values']:
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': {'id': i.food.id, 'name': i.food.name}, 'value': 0}
# if amount is present but unit is missing indicate it in the result
elif i.unit is None:
if i.food.id not in computed_properties[pt.id]['food_values']:
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': {'id': i.food.id, 'name': i.food.name}, 'value': 0}
computed_properties[pt.id]['food_values'][i.food.id]['missing_unit'] = True
if i.amount == 0: # don't count ingredients without an amount as missing
computed_properties[pt.id]['missing_value'] = computed_properties[pt.id]['missing_value'] or False # don't override if another food was already missing
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': i.food.name, 'value': 0}
else:
computed_properties[pt.id]['missing_value'] = True
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': {'id': i.food.id, 'name': i.food.name}, 'value': None}
if has_property_value and i.unit is not None:
computed_properties[pt.id]['food_values'][i.food.id]['missing_conversion'] = {'base_unit': {'id': i.unit.id, 'name': i.unit.name}, 'converted_unit': {'id': i.food.properties_food_unit.id, 'name': i.food.properties_food_unit.name}}
computed_properties[pt.id]['food_values'][i.food.id] = {'id': i.food.id, 'food': i.food.name, 'value': None}
return computed_properties
@@ -85,5 +74,5 @@ class FoodPropertyHelper:
if key in d and d[key]['value']:
d[key]['value'] += value
else:
d[key] = {'id': food.id, 'food': {'id': food.id, 'name': food.name}, 'value': value}
d[key] = {'id': food.id, 'food': food.name, 'value': value}
return d

View File

@@ -9,8 +9,7 @@ from django.utils import timezone, translation
from cookbook.helper.HelperFunctions import Round, str2bool
from cookbook.managers import DICTIONARY
from cookbook.models import (CookLog, CustomFilter, Food, Keyword, Recipe, SearchFields,
SearchPreference, ViewLog)
from cookbook.models import CookLog, CustomFilter, Food, Keyword, Recipe, SearchFields, SearchPreference, ViewLog
from recipes import settings
@@ -22,11 +21,8 @@ class RecipeSearch():
self._request = request
self._queryset = None
if f := params.get('filter', None):
custom_filter = (
CustomFilter.objects.filter(id=f, space=self._request.space)
.filter(Q(created_by=self._request.user) | Q(shared=self._request.user) | Q(recipebook__shared=self._request.user))
.first()
)
custom_filter = (CustomFilter.objects.filter(id=f, space=self._request.space).filter(
Q(created_by=self._request.user) | Q(shared=self._request.user) | Q(recipebook__shared=self._request.user)).first())
if custom_filter:
self._params = {**json.loads(custom_filter.search)}
self._original_params = {**(params or {})}
@@ -38,7 +34,7 @@ class RecipeSearch():
else:
self._params = {**(params or {})}
if self._request.user.is_authenticated:
CACHE_KEY = f'search_pref_{request.user.id}'
CACHE_KEY = f"search_pref_{request.user.id}"
cached_result = cache.get(CACHE_KEY, default=None)
if cached_result is not None:
self._search_prefs = cached_result
@@ -47,64 +43,43 @@ class RecipeSearch():
cache.set(CACHE_KEY, self._search_prefs, timeout=10)
else:
self._search_prefs = SearchPreference()
self._string = self._params.get('query').strip(
) if self._params.get('query', None) else None
self._rating = self._params.get('rating', None)
self._rating_gte = self._params.get('rating_gte', None)
self._rating_lte = self._params.get('rating_lte', None)
self._string = self._params.get("query").strip() if self._params.get("query", None) else None
self._rating = self._params.get("rating", None)
self._keywords = {
'or': self._params.get('keywords_or', None) or self._params.get('keywords', None),
'and': self._params.get('keywords_and', None),
'or_not': self._params.get('keywords_or_not', None),
'and_not': self._params.get('keywords_and_not', None)
"or": self._params.get("keywords_or", None) or self._params.get("keywords", None),
"and": self._params.get("keywords_and", None),
"or_not": self._params.get("keywords_or_not", None),
"and_not": self._params.get("keywords_and_not", None),
}
self._foods = {
'or': self._params.get('foods_or', None) or self._params.get('foods', None),
'and': self._params.get('foods_and', None),
'or_not': self._params.get('foods_or_not', None),
'and_not': self._params.get('foods_and_not', None)
"or": self._params.get("foods_or", None) or self._params.get("foods", None),
"and": self._params.get("foods_and", None),
"or_not": self._params.get("foods_or_not", None),
"and_not": self._params.get("foods_and_not", None),
}
self._books = {
'or': self._params.get('books_or', None) or self._params.get('books', None),
'and': self._params.get('books_and', None),
'or_not': self._params.get('books_or_not', None),
'and_not': self._params.get('books_and_not', None)
"or": self._params.get("books_or", None) or self._params.get("books", None),
"and": self._params.get("books_and", None),
"or_not": self._params.get("books_or_not", None),
"and_not": self._params.get("books_and_not", None),
}
self._steps = self._params.get('steps', None)
self._units = self._params.get('units', None)
self._internal = str2bool(self._params.get('internal', None))
self._sort_order = self._params.get('sort_order', None)
if self._sort_order == 'random':
self._random = True
self.sort_order = None
else:
self._random = str2bool(self._params.get('random', False))
self._new = str2bool(self._params.get('new', False))
self._num_recent = int(self._params.get('num_recent', 0))
self._include_children = str2bool(
self._params.get('include_children', None))
self._timescooked = self._params.get('timescooked', None)
self._timescooked_gte = self._params.get('timescooked_gte', None)
self._timescooked_lte = self._params.get('timescooked_lte', None)
self._createdon = self._params.get('createdon', None)
self._createdon_gte = self._params.get('createdon_gte', None)
self._createdon_lte = self._params.get('createdon_lte', None)
self._updatedon = self._params.get('updatedon', None)
self._updatedon_gte = self._params.get('updatedon_gte', None)
self._updatedon_lte = self._params.get('updatedon_lte', None)
self._viewedon_gte = self._params.get('viewedon_gte', None)
self._viewedon_lte = self._params.get('viewedon_lte', None)
self._cookedon_gte = self._params.get('cookedon_gte', None)
self._cookedon_lte = self._params.get('cookedon_lte', None)
self._createdby = self._params.get('createdby', None)
self._makenow = self._params.get('makenow', None)
self._steps = self._params.get("steps", None)
self._units = self._params.get("units", None)
# TODO add created by
# TODO image exists
self._sort_order = self._params.get("sort_order", None)
self._internal = str2bool(self._params.get("internal", None))
self._random = str2bool(self._params.get("random", False))
self._new = str2bool(self._params.get("new", False))
self._num_recent = int(self._params.get("num_recent", 0))
self._include_children = str2bool(self._params.get("include_children", None))
self._timescooked = self._params.get("timescooked", None)
self._cookedon = self._params.get("cookedon", None)
self._createdon = self._params.get("createdon", None)
self._updatedon = self._params.get("updatedon", None)
self._viewedon = self._params.get("viewedon", None)
self._makenow = self._params.get("makenow", None)
self._never_used_food = str2bool(self._params.get("never_used_food", False))
# this supports hidden feature to find recipes missing X ingredients
if isinstance(self._makenow, bool) and self._makenow == True:
self._makenow = 0
@@ -116,7 +91,7 @@ class RecipeSearch():
except (ValueError, TypeError):
self._makenow = None
self._search_type = self._search_prefs.search or 'plain'
self._search_type = self._search_prefs.search or "plain"
if self._string:
if self._postgres:
self._unaccent_include = self._search_prefs.unaccent.values_list('field', flat=True)
@@ -134,11 +109,7 @@ class RecipeSearch():
if self._search_type not in ['websearch', 'raw'] and self._trigram_include:
self._trigram = True
self.search_query = SearchQuery(
self._string,
search_type=self._search_type,
config=self._language,
)
self.search_query = SearchQuery(self._string, search_type=self._search_type, config=self._language, )
self.search_rank = None
self.orderby = []
self._filters = None
@@ -147,26 +118,23 @@ class RecipeSearch():
def get_queryset(self, queryset):
self._queryset = queryset
self._queryset = self._queryset.prefetch_related('keywords')
self._build_sort_order()
self._recently_viewed(num_recent=self._num_recent)
self._cooked_on_filter()
self._created_on_filter()
self._updated_on_filter()
self._viewed_on_filter()
self._created_by_filter(created_by_user_id=self._createdby)
self._favorite_recipes()
self._cooked_on_filter(cooked_date=self._cookedon)
self._created_on_filter(created_date=self._createdon)
self._updated_on_filter(updated_date=self._updatedon)
self._viewed_on_filter(viewed_date=self._viewedon)
self._favorite_recipes(times_cooked=self._timescooked)
self._new_recipes()
self.keyword_filters(**self._keywords)
self.food_filters(**self._foods)
self.book_filters(**self._books)
self.rating_filter()
self.rating_filter(rating=self._rating)
self.internal_filter(internal=self._internal)
self.step_filters(steps=self._steps)
self.unit_filters(units=self._units)
self._makenow_filter(missing=self._makenow)
self._never_used_food_filter()
self.string_filters(string=self._string)
return self._queryset.filter(space=self._request.space).order_by(*self.orderby)
@@ -174,22 +142,22 @@ class RecipeSearch():
for x in args:
if x in self.orderby:
return True
elif '-' + x in self.orderby:
elif "-" + x in self.orderby:
return True
return False
def _build_sort_order(self):
if self._random:
self.orderby = ['?']
self.orderby = ["?"]
else:
order = []
# TODO add userpreference for default sort order and replace '-favorite'
default_order = ['name']
default_order = ["name"]
# recent and new_recipe are always first; they float a few recipes to the top
if self._num_recent:
order += ['-recent']
order += ["-recent"]
if self._new:
order += ['-new_recipe']
order += ["-new_recipe"]
# if a sort order is provided by user - use that order
if self._sort_order:
@@ -198,20 +166,18 @@ class RecipeSearch():
else:
order += self._sort_order
if not self._postgres or not self._string:
if 'score' in order:
order.remove('score')
if '-score' in order:
order.remove('-score')
if "score" in order:
order.remove("score")
if "-score" in order:
order.remove("-score")
# if no sort order provided prioritize text search, followed by the default search
elif self._postgres and self._string and (self._trigram or self._fulltext_include):
order += ['-score', *default_order]
order += ["-score", *default_order]
# otherwise sort by the remaining order_by attributes or favorite by default
else:
order += default_order
order[:] = [Lower('name').asc() if x ==
'name' else x for x in order]
order[:] = [Lower('name').desc() if x ==
'-name' else x for x in order]
order[:] = [Lower("name").asc() if x == "name" else x for x in order]
order[:] = [Lower("name").desc() if x == "-name" else x for x in order]
self.orderby = order
def string_filters(self, string=None):
@@ -246,104 +212,100 @@ class RecipeSearch():
self._queryset = self._queryset.annotate(score=F('rank') + F('simularity'))
else:
query_filter = Q()
for f in [x + '__unaccent__iexact' if x in self._unaccent_include else x + '__iexact' for x in SearchFields.objects.all().values_list('field', flat=True)]:
for f in [x + "__unaccent__iexact" if x in self._unaccent_include else x + "__iexact" for x in SearchFields.objects.all().values_list("field", flat=True)]:
query_filter |= Q(**{"%s" % f: self._string})
self._queryset = self._queryset.filter(query_filter).distinct()
def _cooked_on_filter(self):
if self._sort_includes('lastcooked') or self._cookedon_gte or self._cookedon_lte:
lessthan = self._sort_includes('-lastcooked') or self._cookedon_lte
def _cooked_on_filter(self, cooked_date=None):
if self._sort_includes('lastcooked') or cooked_date:
lessthan = self._sort_includes('-lastcooked') or '-' in (cooked_date or [])[:1]
if lessthan:
default = timezone.now() - timedelta(days=100000)
else:
default = timezone.now()
self._queryset = self._queryset.annotate(
lastcooked=Coalesce(Max(Case(When(cooklog__created_by=self._request.user, cooklog__space=self._request.space, then='cooklog__created_at'))), Value(default))
)
lastcooked=Coalesce(Max(Case(When(cooklog__created_by=self._request.user, cooklog__space=self._request.space, then='cooklog__created_at'))), Value(default)))
if cooked_date is None:
return
if self._cookedon_lte:
self._queryset = self._queryset.filter(lastcooked__date__lte=self._cookedon_lte).exclude(lastcooked=default)
elif self._cookedon_gte:
self._queryset = self._queryset.filter(lastcooked__date__gte=self._cookedon_gte).exclude(lastcooked=default)
cooked_date = date(*[int(x) for x in cooked_date.split('-') if x != ''])
if lessthan:
self._queryset = self._queryset.filter(lastcooked__date__lte=cooked_date).exclude(lastcooked=default)
else:
self._queryset = self._queryset.filter(lastcooked__date__gte=cooked_date).exclude(lastcooked=default)
def _created_on_filter(self, created_date=None):
if created_date is None:
return
lessthan = '-' in created_date[:1]
created_date = date(*[int(x) for x in created_date.split('-') if x != ''])
if lessthan:
self._queryset = self._queryset.filter(created_at__date__lte=created_date)
else:
self._queryset = self._queryset.filter(created_at__date__gte=created_date)
def _updated_on_filter(self, updated_date=None):
if updated_date is None:
return
lessthan = '-' in updated_date[:1]
updated_date = date(*[int(x) for x in updated_date.split('-') if x != ''])
if lessthan:
self._queryset = self._queryset.filter(updated_at__date__lte=updated_date)
else:
self._queryset = self._queryset.filter(updated_at__date__gte=updated_date)
def _viewed_on_filter(self, viewed_date=None):
if self._sort_includes('lastviewed') or self._viewedon_gte or self._viewedon_lte:
if self._sort_includes("lastviewed") or viewed_date:
longTimeAgo = timezone.now() - timedelta(days=100000)
self._queryset = self._queryset.annotate(
lastviewed=Coalesce(Max(Case(When(viewlog__created_by=self._request.user, viewlog__space=self._request.space, then='viewlog__created_at'))), Value(longTimeAgo))
)
if self._viewedon_lte:
self._queryset = self._queryset.filter(lastviewed__date__lte=self._viewedon_lte).exclude(lastviewed=longTimeAgo)
elif self._viewedon_gte:
self._queryset = self._queryset.filter(lastviewed__date__gte=self._viewedon_gte).exclude(lastviewed=longTimeAgo)
def _created_on_filter(self):
if self._createdon:
self._queryset = self._queryset.filter(created_at__date=self._createdon)
elif self._createdon_lte:
self._queryset = self._queryset.filter(created_at__date__lte=self._createdon_lte)
elif self._createdon_gte:
self._queryset = self._queryset.filter(created_at__date__gte=self._createdon_gte)
def _updated_on_filter(self):
if self._updatedon:
self._queryset = self._queryset.filter(updated_at__date__date=self._updatedon)
elif self._updatedon_lte:
self._queryset = self._queryset.filter(updated_at__date__lte=self._updatedon_lte)
elif self._updatedon_gte:
self._queryset = self._queryset.filter(updated_at__date__gte=self._updatedon_gte)
def _created_by_filter(self, created_by_user_id=None):
if created_by_user_id is None:
lastviewed=Coalesce(Max(Case(When(viewlog__created_by=self._request.user, viewlog__space=self._request.space, then='viewlog__created_at'))), Value(longTimeAgo)))
if viewed_date is None:
return
self._queryset = self._queryset.filter(created_by__id=created_by_user_id)
lessthan = '-' in viewed_date[:1]
viewed_date = date(*[int(x) for x in viewed_date.split('-') if x != ''])
if lessthan:
self._queryset = self._queryset.filter(lastviewed__date__lte=viewed_date).exclude(lastviewed=longTimeAgo)
else:
self._queryset = self._queryset.filter(lastviewed__date__gte=viewed_date).exclude(lastviewed=longTimeAgo)
def _new_recipes(self, new_days=7):
# TODO make new days a user-setting
if not self._new:
return
self._queryset = self._queryset.annotate(
new_recipe=Case(
When(created_at__gte=(timezone.now() - timedelta(days=new_days)), then=('pk')),
default=Value(0),
)
)
self._queryset = self._queryset.annotate(new_recipe=Case(When(created_at__gte=(timezone.now() - timedelta(days=new_days)), then=('pk')), default=Value(0), ))
def _recently_viewed(self, num_recent=None):
if not num_recent:
if self._sort_includes('lastviewed'):
self._queryset = self._queryset.annotate(lastviewed=Coalesce(
Max(Case(When(viewlog__created_by=self._request.user, viewlog__space=self._request.space, then='viewlog__pk'))), Value(0)))
if self._sort_includes("lastviewed"):
self._queryset = self._queryset.annotate(
lastviewed=Coalesce(Max(Case(When(viewlog__created_by=self._request.user, viewlog__space=self._request.space, then="viewlog__pk"))), Value(0)))
return
num_recent_recipes = (
ViewLog.objects.filter(created_by=self._request.user, space=self._request.space)
.values('recipe').annotate(recent=Max('created_at')).order_by('-recent')[:num_recent]
)
num_recent_recipes = (ViewLog.objects.filter(created_by=self._request.user,
space=self._request.space).values('recipe').annotate(recent=Max('created_at')).order_by('-recent')[:num_recent])
self._queryset = self._queryset.annotate(recent=Coalesce(Max(Case(When(pk__in=num_recent_recipes.values('recipe'), then='viewlog__pk'))), Value(0)))
def _favorite_recipes(self):
if self._sort_includes('favorite') or self._timescooked or self._timescooked_gte or self._timescooked_lte:
less_than = self._timescooked_lte and not self._sort_includes('-favorite')
def _favorite_recipes(self, times_cooked=None):
if self._sort_includes('favorite') or times_cooked:
less_than = '-' in (str(times_cooked) or []) and not self._sort_includes('-favorite')
if less_than:
default = 1000
else:
default = 0
favorite_recipes = (
CookLog.objects.filter(created_by=self._request.user, space=self._request.space, recipe=OuterRef('pk'))
.values('recipe')
.annotate(count=Count('pk', distinct=True))
.values('count')
)
favorite_recipes = (CookLog.objects.filter(created_by=self._request.user, space=self._request.space,
recipe=OuterRef('pk')).values('recipe').annotate(count=Count('pk', distinct=True)).values('count'))
self._queryset = self._queryset.annotate(favorite=Coalesce(Subquery(favorite_recipes), default))
if times_cooked is None:
return
if self._timescooked:
if times_cooked == "0":
self._queryset = self._queryset.filter(favorite=0)
elif self._timescooked_lte:
self._queryset = self._queryset.filter(favorite__lte=int(self._timescooked_lte)).exclude(favorite=0)
elif self._timescooked_gte:
self._queryset = self._queryset.filter(favorite__gte=int(self._timescooked_gte))
elif less_than:
self._queryset = self._queryset.filter(favorite__lte=int(times_cooked.replace('-', ''))).exclude(favorite=0)
else:
self._queryset = self._queryset.filter(favorite__gte=int(times_cooked))
def keyword_filters(self, **kwargs):
if all([kwargs[x] is None for x in kwargs]):
@@ -355,23 +317,23 @@ class RecipeSearch():
kwargs[kw_filter] = [kwargs[kw_filter]]
keywords = Keyword.objects.filter(pk__in=kwargs[kw_filter])
if 'or' in kw_filter:
if "or" in kw_filter:
if self._include_children:
f_or = Q(keywords__in=Keyword.include_descendants(keywords))
else:
f_or = Q(keywords__in=keywords)
if 'not' in kw_filter:
if "not" in kw_filter:
self._queryset = self._queryset.exclude(f_or)
else:
self._queryset = self._queryset.filter(f_or)
elif 'and' in kw_filter:
elif "and" in kw_filter:
recipes = Recipe.objects.all()
for kw in keywords:
if self._include_children:
f_and = Q(keywords__in=kw.get_descendants_and_self())
else:
f_and = Q(keywords=kw)
if 'not' in kw_filter:
if "not" in kw_filter:
recipes = recipes.filter(f_and)
else:
self._queryset = self._queryset.filter(f_and)
@@ -388,24 +350,24 @@ class RecipeSearch():
kwargs[fd_filter] = [kwargs[fd_filter]]
foods = Food.objects.filter(pk__in=kwargs[fd_filter])
if 'or' in fd_filter:
if "or" in fd_filter:
if self._include_children:
f_or = Q(steps__ingredients__food__in=Food.include_descendants(foods))
else:
f_or = Q(steps__ingredients__food__in=foods)
if 'not' in fd_filter:
if "not" in fd_filter:
self._queryset = self._queryset.exclude(f_or)
else:
self._queryset = self._queryset.filter(f_or)
elif 'and' in fd_filter:
elif "and" in fd_filter:
recipes = Recipe.objects.all()
for food in foods:
if self._include_children:
f_and = Q(steps__ingredients__food__in=food.get_descendants_and_self())
else:
f_and = Q(steps__ingredients__food=food)
if 'not' in fd_filter:
if "not" in fd_filter:
recipes = recipes.filter(f_and)
else:
self._queryset = self._queryset.filter(f_and)
@@ -421,16 +383,25 @@ class RecipeSearch():
units = [units]
self._queryset = self._queryset.filter(steps__ingredients__unit__in=units)
def rating_filter(self):
if self._rating or self._rating_lte or self._rating_gte or self._sort_includes('rating'):
self._queryset = self._queryset.annotate(rating=Round(Avg(Case(When(cooklog__created_by=self._request.user, then='cooklog__rating'), default=0))))
def rating_filter(self, rating=None):
if rating or self._sort_includes('rating'):
lessthan = '-' in (rating or [])
reverse = 'rating' in (self._sort_order or []) and '-rating' not in (self._sort_order or [])
if lessthan or reverse:
default = 100
else:
default = 0
# TODO make ratings a settings user-only vs all-users
self._queryset = self._queryset.annotate(rating=Round(Avg(Case(When(cooklog__created_by=self._request.user, then="cooklog__rating"), default=default))))
if rating is None:
return
if self._rating:
self._queryset = self._queryset.filter(rating=round(int(self._rating)))
elif self._rating_gte:
self._queryset = self._queryset.filter(rating__gte=int(self._rating_gte))
elif self._rating_lte:
self._queryset = self._queryset.filter(rating__gte=int(self._rating_lte)).exclude(rating=0)
if rating == "0":
self._queryset = self._queryset.filter(rating=0)
elif lessthan:
self._queryset = self._queryset.filter(rating__lte=int(rating[1:])).exclude(rating=0)
else:
self._queryset = self._queryset.filter(rating__gte=int(rating))
def internal_filter(self, internal=None):
if not internal:
@@ -446,13 +417,13 @@ class RecipeSearch():
if not isinstance(kwargs[bk_filter], list):
kwargs[bk_filter] = [kwargs[bk_filter]]
if 'or' in bk_filter:
if "or" in bk_filter:
f = Q(recipebookentry__book__id__in=kwargs[bk_filter])
if 'not' in bk_filter:
if "not" in bk_filter:
self._queryset = self._queryset.exclude(f)
else:
self._queryset = self._queryset.filter(f)
elif 'and' in bk_filter:
elif "and" in bk_filter:
recipes = Recipe.objects.all()
for book in kwargs[bk_filter]:
if 'not' in bk_filter:
@@ -525,62 +496,66 @@ class RecipeSearch():
trigram += TrigramSimilarity(f, self._string)
else:
trigram = TrigramSimilarity(f, self._string)
self._fuzzy_match = (
Recipe.objects.annotate(trigram=trigram)
.distinct()
.annotate(simularity=Max('trigram'))
.values('id', 'simularity')
.filter(simularity__gt=self._search_prefs.trigram_threshold)
)
self._fuzzy_match = (Recipe.objects.annotate(trigram=trigram).distinct().annotate(simularity=Max('trigram')).values('id', 'simularity').filter(
simularity__gt=self._search_prefs.trigram_threshold))
self._filters += [Q(pk__in=self._fuzzy_match.values('pk'))]
def _makenow_filter(self, missing=None):
if missing is None or (isinstance(missing, bool) and missing == False):
return
shopping_users = [*self._request.user.get_shopping_share(), self._request.user]
onhand_filter = Q(steps__ingredients__food__onhand_users__in=shopping_users) # food onhand
onhand_filter = (
Q(steps__ingredients__food__onhand_users__in=shopping_users) # food onhand
# or substitute food onhand
| Q(steps__ingredients__food__substitute__onhand_users__in=shopping_users)
| Q(steps__ingredients__food__in=self.__children_substitute_filter(shopping_users))
| Q(steps__ingredients__food__in=self.__sibling_substitute_filter(shopping_users))
)
makenow_recipes = Recipe.objects.annotate(
count_food=Count('steps__ingredients__food__pk', filter=Q(steps__ingredients__food__isnull=False), distinct=True),
count_onhand=Count('steps__ingredients__food__pk', filter=onhand_filter, distinct=True),
count_ignore_shopping=Count(
'steps__ingredients__food__pk', filter=Q(steps__ingredients__food__ignore_shopping=True, steps__ingredients__food__recipe__isnull=True), distinct=True
),
has_child_sub=Case(When(steps__ingredients__food__in=self.__children_substitute_filter(shopping_users), then=Value(1)), default=Value(0)),
has_sibling_sub=Case(When(steps__ingredients__food__in=self.__sibling_substitute_filter(shopping_users), then=Value(1)), default=Value(0))
).annotate(missingfood=F('count_food') - F('count_onhand') - F('count_ignore_shopping')).filter(missingfood__lte=missing)
# ignore substitutions when also using the never_used_food filter
if not self._never_used_food:
# or substitute food onhand
onhand_filter |= (Q(steps__ingredients__food__substitute__onhand_users__in=shopping_users)
| Q(steps__ingredients__food__in=self.__children_substitute_filter(shopping_users))
| Q(steps__ingredients__food__in=self.__sibling_substitute_filter(shopping_users)))
makenow_recipes = (Recipe.objects.annotate(count_food=Count("steps__ingredients__food__pk", filter=Q(steps__ingredients__food__isnull=False), distinct=True),
count_onhand=Count("steps__ingredients__food__pk", filter=onhand_filter, distinct=True),
count_ignore_shopping=Count("steps__ingredients__food__pk",
filter=Q(steps__ingredients__food__ignore_shopping=True,
steps__ingredients__food__recipe__isnull=True),
distinct=True),
has_child_sub=Case(When(steps__ingredients__food__in=self.__children_substitute_filter(shopping_users), then=Value(1)),
default=Value(0)),
has_sibling_sub=Case(When(steps__ingredients__food__in=self.__sibling_substitute_filter(shopping_users), then=Value(1)),
default=Value(0)),
).annotate(missingfood=F("count_food") - F("count_onhand") - F("count_ignore_shopping")).filter(missingfood=missing))
makenow_recipes = Recipe.objects.annotate(count_food=Count('steps__ingredients__food__pk', filter=Q(steps__ingredients__food__isnull=False), distinct=True),
count_onhand=Count('steps__ingredients__food__pk', filter=onhand_filter, distinct=True),
count_ignore_shopping=Count('steps__ingredients__food__pk',
filter=Q(steps__ingredients__food__ignore_shopping=True,
steps__ingredients__food__recipe__isnull=True),
distinct=True),
has_child_sub=Case(When(steps__ingredients__food__in=self.__children_substitute_filter(shopping_users), then=Value(1)),
default=Value(0)),
has_sibling_sub=Case(When(steps__ingredients__food__in=self.__sibling_substitute_filter(shopping_users), then=Value(1)),
default=Value(0))).annotate(missingfood=F('count_food') - F('count_onhand')
- F('count_ignore_shopping')).filter(missingfood__lte=missing)
self._queryset = self._queryset.distinct().filter(id__in=makenow_recipes.values('id'))
def _never_used_food_filter(self):
# filters recipes to include foods that have never been used
if not self._never_used_food:
return
self._queryset = self._queryset.filter(steps__ingredients__food__in=Food.objects.filter(~Q(ingredient__step__recipe__cooklog__isnull=False)).distinct())
@staticmethod
def __children_substitute_filter(shopping_users=None):
children_onhand_subquery = Food.objects.filter(path__startswith=OuterRef('path'), depth__gt=OuterRef('depth'), onhand_users__in=shopping_users)
return (
Food.objects.exclude( # list of foods that are onhand and children of: foods that are not onhand and are set to use children as substitutes
Q(onhand_users__in=shopping_users) | Q(ignore_shopping=True, recipe__isnull=True) | Q(substitute__onhand_users__in=shopping_users)
)
.exclude(depth=1, numchild=0)
.filter(substitute_children=True)
.annotate(child_onhand_count=Exists(children_onhand_subquery))
.filter(child_onhand_count=True)
)
return (Food.objects.exclude( # list of foods that are onhand and children of: foods that are not onhand and are set to use children as substitutes
Q(onhand_users__in=shopping_users) | Q(ignore_shopping=True, recipe__isnull=True)
| Q(substitute__onhand_users__in=shopping_users)).exclude(depth=1, numchild=0).filter(substitute_children=True).annotate(
child_onhand_count=Exists(children_onhand_subquery)).filter(child_onhand_count=True))
@staticmethod
def __sibling_substitute_filter(shopping_users=None):
sibling_onhand_subquery = Food.objects.filter(
path__startswith=Substr(OuterRef('path'), 1, Food.steplen * (OuterRef('depth') - 1)), depth=OuterRef('depth'), onhand_users__in=shopping_users
)
return (
Food.objects.exclude( # list of foods that are onhand and siblings of: foods that are not onhand and are set to use siblings as substitutes
Q(onhand_users__in=shopping_users) | Q(ignore_shopping=True, recipe__isnull=True) | Q(substitute__onhand_users__in=shopping_users)
)
.exclude(depth=1, numchild=0)
.filter(substitute_siblings=True)
.annotate(sibling_onhand=Exists(sibling_onhand_subquery))
.filter(sibling_onhand=True)
)
sibling_onhand_subquery = Food.objects.filter(path__startswith=Substr(OuterRef('path'), 1, Food.steplen * (OuterRef('depth') - 1)),
depth=OuterRef('depth'),
onhand_users__in=shopping_users)
return (Food.objects.exclude( # list of foods that are onhand and siblings of: foods that are not onhand and are set to use siblings as substitutes
Q(onhand_users__in=shopping_users) | Q(ignore_shopping=True, recipe__isnull=True)
| Q(substitute__onhand_users__in=shopping_users)).exclude(depth=1, numchild=0).filter(substitute_siblings=True).annotate(
sibling_onhand=Exists(sibling_onhand_subquery)).filter(sibling_onhand=True))

View File

@@ -106,14 +106,14 @@ def get_from_scraper(scrape, request):
# assign image
try:
recipe_json['image_url'] = parse_image(scrape.image()) or None
recipe_json['image'] = parse_image(scrape.image()) or None
except Exception:
recipe_json['image_url'] = None
if not recipe_json['image_url']:
recipe_json['image'] = None
if not recipe_json['image']:
try:
recipe_json['image_url'] = parse_image(scrape.schema.data.get('image')) or ''
recipe_json['image'] = parse_image(scrape.schema.data.get('image')) or ''
except Exception:
recipe_json['image_url'] = ''
recipe_json['image'] = ''
# assign keywords
try:
@@ -205,7 +205,6 @@ def get_from_scraper(scrape, request):
except Exception:
pass
recipe_json['properties'] = []
try:
recipe_json['properties'] = get_recipe_properties(request.space, scrape.schema.nutrients())
print(recipe_json['properties'])
@@ -228,13 +227,6 @@ def get_recipe_properties(space, property_data):
"property-proteins": "proteinContent",
"property-fats": "fatContent",
}
serving_size = 1
try:
serving_size = parse_servings(property_data['servingSize'])
except KeyError:
pass
recipe_properties = []
for pt in PropertyType.objects.filter(space=space, open_data_slug__in=list(properties.keys())).all():
for p in list(properties.keys()):
@@ -245,7 +237,7 @@ def get_recipe_properties(space, property_data):
'id': pt.id,
'name': pt.name,
},
'property_amount': parse_servings(property_data[properties[p]]) / serving_size,
'property_amount': parse_servings(property_data[properties[p]]) / parse_servings(property_data['servingSize']),
})
return recipe_properties
@@ -432,9 +424,9 @@ def parse_keywords(keyword_json, request):
if len(kw) != 0:
kw = automation_engine.apply_keyword_automation(kw)
if k := Keyword.objects.filter(name__iexact=kw, space=request.space).first():
keywords.append({'label': str(k), 'name': k.name, 'id': k.id, 'import_keyword': True})
keywords.append({'label': str(k), 'name': k.name, 'id': k.id})
else:
keywords.append({'label': kw, 'name': kw, 'import_keyword': False})
keywords.append({'label': kw, 'name': kw})
return keywords
@@ -491,11 +483,7 @@ def get_images_from_soup(soup, url):
u = u.split('?')[0]
filename = re.search(r'/([\w_-]+[.](jpg|jpeg|gif|png))$', u)
if filename:
if u.startswith('//'):
# urls from e.g. ottolenghi.co.uk start with //
u = 'https:' + u
if ('http' not in u) and url:
print(f'rewriting URL {u}')
if (('http' not in u) and (url)):
# sometimes an image source can be relative
# if it is provide the base url
u = '{}://{}{}'.format(prot, site, u)

View File

@@ -12,7 +12,7 @@ class ScopeMiddleware:
self.get_response = get_response
def __call__(self, request):
prefix = settings.SCRIPT_NAME or ''
prefix = settings.JS_REVERSE_SCRIPT_PREFIX or ''
# need to disable scopes for writing requests into userpref and enable for loading ?
if request.path.startswith(prefix + '/api/user-preference/'):

View File

@@ -153,9 +153,8 @@ class RecipeShoppingEditor():
return True
for sle in ShoppingListEntry.objects.filter(list_recipe=self._shopping_list_recipe):
if sle.ingredient: # TODO temporarily dont scale manual entries until ingredient_amount or some other base amount has been migrated to SLE
sle.amount = sle.ingredient.amount * Decimal(self._servings_factor)
sle.save()
sle.amount = sle.ingredient.amount * Decimal(self._servings_factor)
sle.save()
self._shopping_list_recipe.servings = self.servings
self._shopping_list_recipe.save()
return True

View File

@@ -70,7 +70,7 @@ def render_instructions(step): # TODO deduplicate markdown cleanup code
parsed_md = md.markdown(
instructions,
extensions=[
'markdown.extensions.fenced_code', 'markdown.extensions.sane_lists', 'markdown.extensions.nl2br', TableExtension(),
'markdown.extensions.fenced_code', TableExtension(),
UrlizeExtension(), MarkdownFormatExtension()
]
)

View File

@@ -60,15 +60,14 @@ class CookBookApp(Integration):
food=f, unit=u, amount=ingredient.get('amount', None), note=ingredient.get('note', None), original_text=ingredient.get('original_text', None), space=self.request.space,
))
try:
for url in images:
# import the first valid image which is not cookbookapp branding
if validate_import_url(url) and not url.startswith("https://media.cookbookmanager.com/brand/"):
if len(images) > 0:
try:
url = images[0]
if validate_import_url(url):
response = requests.get(url)
self.import_recipe_image(recipe, BytesIO(response.content))
break
except Exception as e:
print('failed to import image ', str(e))
except Exception as e:
print('failed to import image ', str(e))
recipe.save()
return recipe

View File

@@ -1,10 +1,10 @@
import imghdr
import json
import re
from io import BytesIO
from zipfile import ZipFile
import requests
from PIL import Image
from django.utils.translation import gettext as _
@@ -128,7 +128,7 @@ class RecetteTek(Integration):
url = file['originalPicture']
if validate_import_url(url):
response = requests.get(url)
if Image.open(BytesIO(response.content)).verify():
if imghdr.what(BytesIO(response.content)) is not None:
self.import_recipe_image(recipe, BytesIO(response.content), filetype=get_filetype(file['originalPicture']))
else:
raise Exception("Original image failed to download.")

View File

@@ -14,7 +14,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-01 15:04+0200\n"
"PO-Revision-Date: 2025-06-23 08:28+0000\n"
"PO-Revision-Date: 2025-01-29 13:44+0000\n"
"Last-Translator: Ángel <1024mb@users.noreply.translate.tandoor.dev>\n"
"Language-Team: Spanish <http://translate.tandoor.dev/projects/tandoor/"
"recipes-backend/es/>\n"
@@ -284,12 +284,14 @@ msgid "You have more users than allowed in your space."
msgstr "Tenés mas usuarios que los permitidos en tu espacio"
#: .\cookbook\helper\recipe_url_import.py:310
#, fuzzy
#| msgid "Use fractions"
msgid "reverse rotation"
msgstr "rotación inversa"
msgstr "Usar fracciones"
#: .\cookbook\helper\recipe_url_import.py:311
msgid "careful rotation"
msgstr "rotación cuidadosa"
msgstr ""
#: .\cookbook\helper\recipe_url_import.py:312
msgid "knead"
@@ -396,9 +398,8 @@ msgid "Section"
msgstr "Sección"
#: .\cookbook\management\commands\fix_duplicate_properties.py:15
#, fuzzy
msgid "Fixes foods with "
msgstr "Corrige alimentos con "
msgstr ""
#: .\cookbook\management\commands\rebuildindex.py:14
msgid "Rebuilds full text search index on Recipe"
@@ -435,14 +436,16 @@ msgid "Other"
msgstr "Otro"
#: .\cookbook\migrations\0190_auto_20230525_1506.py:17
#, fuzzy
#| msgid "Fats"
msgid "Fat"
msgstr "Grasa"
msgstr "Grasas"
#: .\cookbook\migrations\0190_auto_20230525_1506.py:17
#: .\cookbook\migrations\0190_auto_20230525_1506.py:18
#: .\cookbook\migrations\0190_auto_20230525_1506.py:19
msgid "g"
msgstr "gr."
msgstr ""
#: .\cookbook\migrations\0190_auto_20230525_1506.py:18
msgid "Carbohydrates"
@@ -465,8 +468,6 @@ msgid ""
"Maximum file storage for space in MB. 0 for unlimited, -1 to disable file "
"upload."
msgstr ""
"Almacenamiento máximo de archivos para el espacio en MB. 0 para ilimitado, -"
"1 para desactivar la carga de archivos."
#: .\cookbook\models.py:454 .\cookbook\templates\search.html:7
#: .\cookbook\templates\settings.html:18
@@ -497,16 +498,18 @@ msgid "Nutrition"
msgstr "Información Nutricional"
#: .\cookbook\models.py:918
#, fuzzy
#| msgid "Merge"
msgid "Allergen"
msgstr "Alérgeno"
msgstr "Combinar"
#: .\cookbook\models.py:919
msgid "Price"
msgstr "Precio"
msgstr ""
#: .\cookbook\models.py:919
msgid "Goal"
msgstr "Objetivo"
msgstr ""
#: .\cookbook\models.py:1408 .\cookbook\templates\search_info.html:28
msgid "Simple"
@@ -529,40 +532,54 @@ msgid "Food Alias"
msgstr "Alias de la Comida"
#: .\cookbook\models.py:1468
#, fuzzy
#| msgid "Units"
msgid "Unit Alias"
msgstr "Alias de unidad"
msgstr "Unidades"
#: .\cookbook\models.py:1469
#, fuzzy
#| msgid "Keywords"
msgid "Keyword Alias"
msgstr "Alias de palabra clave"
msgstr "Palabras clave"
#: .\cookbook\models.py:1470
#, fuzzy
#| msgid "Description"
msgid "Description Replace"
msgstr "Reemplazo de descripción"
msgstr "Descripción"
#: .\cookbook\models.py:1471
#, fuzzy
#| msgid "Instructions"
msgid "Instruction Replace"
msgstr "Reemplazo de instrucciones"
msgstr "Instrucciones"
#: .\cookbook\models.py:1472
#, fuzzy
#| msgid "New Unit"
msgid "Never Unit"
msgstr "Unidad prohibida"
msgstr "Nueva Unidad"
#: .\cookbook\models.py:1473
msgid "Transpose Words"
msgstr "Transponer palabras"
msgstr ""
#: .\cookbook\models.py:1474
#, fuzzy
#| msgid "Food Alias"
msgid "Food Replace"
msgstr "Reemplazo de alimento"
msgstr "Alias de la Comida"
#: .\cookbook\models.py:1475
#, fuzzy
#| msgid "Description"
msgid "Unit Replace"
msgstr "Reemplazo de unidad"
msgstr "Descripción"
#: .\cookbook\models.py:1476
msgid "Name Replace"
msgstr "Reemplazo de nombre"
msgstr ""
#: .\cookbook\models.py:1503 .\cookbook\views\delete.py:40
#: .\cookbook\views\edit.py:210 .\cookbook\views\new.py:39
@@ -570,8 +587,10 @@ msgid "Recipe"
msgstr "Receta"
#: .\cookbook\models.py:1504
#, fuzzy
#| msgid "Food"
msgid "Food"
msgstr "Alimento"
msgstr "Comida"
#: .\cookbook\models.py:1505 .\cookbook\templates\base.html:149
msgid "Keyword"
@@ -629,26 +648,22 @@ msgstr "Invitación para Tandoor Recipes"
#: .\cookbook\serializer.py:1426
msgid "Existing shopping list to update"
msgstr "Lista de compras existente para actualizar"
msgstr ""
#: .\cookbook\serializer.py:1428
msgid ""
"List of ingredient IDs from the recipe to add, if not provided all "
"ingredients will be added."
msgstr ""
"Lista de IDs de ingredientes de la receta para agregar; si no se "
"proporciona, se agregarán todos los ingredientes."
#: .\cookbook\serializer.py:1430
msgid ""
"Providing a list_recipe ID and servings of 0 will delete that shopping list."
msgstr ""
"Proporcionar un ID list_recipe y porciones igual a 0 eliminará esa lista de "
"compras."
#: .\cookbook\serializer.py:1439
msgid "Amount of food to add to the shopping list"
msgstr "Cantidad de alimento a agregar a la lista de compras"
msgstr ""
#: .\cookbook\serializer.py:1441
msgid "ID of unit to use for the shopping list"

View File

@@ -14,8 +14,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-01 15:04+0200\n"
"PO-Revision-Date: 2025-08-10 11:36+0000\n"
"Last-Translator: Enzo La Rafale <enzo.chaussivert@gmail.com>\n"
"PO-Revision-Date: 2025-02-16 14:58+0000\n"
"Last-Translator: Elvis Gosselin <elvis.gosselin@tutanota.com>\n"
"Language-Team: French <http://translate.tandoor.dev/projects/tandoor/"
"recipes-backend/fr/>\n"
"Language: fr\n"
@@ -405,7 +405,7 @@ msgstr "Rubrique"
#: .\cookbook\management\commands\fix_duplicate_properties.py:15
msgid "Fixes foods with "
msgstr "Corriger les aliments avec "
msgstr ""
#: .\cookbook\management\commands\rebuildindex.py:14
msgid "Rebuilds full text search index on Recipe"
@@ -442,6 +442,8 @@ msgid "Other"
msgstr "Autre"
#: .\cookbook\migrations\0190_auto_20230525_1506.py:17
#, fuzzy
#| msgid "Fats"
msgid "Fat"
msgstr "Matières grasses"
@@ -449,7 +451,7 @@ msgstr "Matières grasses"
#: .\cookbook\migrations\0190_auto_20230525_1506.py:18
#: .\cookbook\migrations\0190_auto_20230525_1506.py:19
msgid "g"
msgstr "g"
msgstr ""
#: .\cookbook\migrations\0190_auto_20230525_1506.py:18
msgid "Carbohydrates"
@@ -465,7 +467,7 @@ msgstr "Calories"
#: .\cookbook\migrations\0190_auto_20230525_1506.py:20
msgid "kcal"
msgstr "kcal"
msgstr ""
#: .\cookbook\models.py:325
msgid ""
@@ -552,24 +554,30 @@ msgid "Instruction Replace"
msgstr "Remplacer l'instruction"
#: .\cookbook\models.py:1472
#, fuzzy
#| msgid "New Unit"
msgid "Never Unit"
msgstr "Aucune unité"
msgstr "Nouvelle unité"
#: .\cookbook\models.py:1473
msgid "Transpose Words"
msgstr "Transposer les mots"
msgstr ""
#: .\cookbook\models.py:1474
#, fuzzy
#| msgid "Food Alias"
msgid "Food Replace"
msgstr "Aliment alternatif"
msgstr "Aliment équivalent"
#: .\cookbook\models.py:1475
#, fuzzy
#| msgid "Description Replace"
msgid "Unit Replace"
msgstr "Remplacer l'unité"
msgstr "Remplacer la Description"
#: .\cookbook\models.py:1476
msgid "Name Replace"
msgstr "Remplacer le nom"
msgstr ""
#: .\cookbook\models.py:1503 .\cookbook\views\delete.py:40
#: .\cookbook\views\edit.py:210 .\cookbook\views\new.py:39
@@ -1032,8 +1040,10 @@ msgid "Properties"
msgstr "Propriétés"
#: .\cookbook\templates\base.html:301 .\cookbook\views\lists.py:255
#, fuzzy
#| msgid "Account Connections"
msgid "Unit Conversions"
msgstr "Conversions d'unités"
msgstr "Comptes connectés"
#: .\cookbook\templates\base.html:318 .\cookbook\templates\index.html:47
msgid "Import Recipe"
@@ -1053,8 +1063,10 @@ msgid "Space Settings"
msgstr "Paramètres de groupe"
#: .\cookbook\templates\base.html:340
#, fuzzy
#| msgid "External Recipes"
msgid "External Connectors"
msgstr "Connecteurs externes"
msgstr "Recettes externes"
#: .\cookbook\templates\base.html:345 .\cookbook\templates\system.html:13
msgid "System"
@@ -1518,8 +1530,10 @@ msgid "Back"
msgstr "Retour"
#: .\cookbook\templates\property_editor.html:7
#, fuzzy
#| msgid "Ingredient Editor"
msgid "Property Editor"
msgstr "Éditeur de propriété"
msgstr "Éditeur dingrédients"
#: .\cookbook\templates\recipe_view.html:36
msgid "Comments"
@@ -1997,8 +2011,10 @@ msgid "Sign in using"
msgstr "Se connecter avec"
#: .\cookbook\templates\space_manage.html:7
#, fuzzy
#| msgid "Space Membership"
msgid "Space Management"
msgstr "Gestion de l'espace"
msgstr "Adhésion à l'espace"
#: .\cookbook\templates\space_manage.html:26
msgid "Space:"
@@ -2211,8 +2227,10 @@ msgid "Info"
msgstr "Info"
#: .\cookbook\templates\system.html:110 .\cookbook\templates\system.html:127
#, fuzzy
#| msgid "Use fractions"
msgid "Migrations"
msgstr "Migrations"
msgstr "Utiliser les fractions"
#: .\cookbook\templates\system.html:116
msgid ""
@@ -2247,8 +2265,10 @@ msgid "Hide"
msgstr "Cacher"
#: .\cookbook\templates\system.html:210
#, fuzzy
#| msgid "Show Log"
msgid "Show"
msgstr "Afficher"
msgstr "Afficher le journal"
#: .\cookbook\templates\url_import.html:8
msgid "URL Import"
@@ -2333,9 +2353,11 @@ msgstr ""
"MM-DD."
#: .\cookbook\views\api.py:744
#, fuzzy
#| msgid "ID of recipe a step is part of. For multiple repeat parameter."
msgid "Filter meal plans with MealType ID. For multiple repeat parameter."
msgstr ""
"Filtrer le planning des repas avec l'identifiant MealType. Pour plusieurs "
"Identifiant de la recette dont fait partie une étape. Pour plusieurs "
"paramètres de répétition."
#: .\cookbook\views\api.py:872
@@ -2438,27 +2460,18 @@ msgstr ""
#: .\cookbook\views\api.py:922
msgid "ID of book a recipe should be in. For multiple repeat parameter."
msgstr ""
"ID du livre dans lequel une recette doit se trouver. Pour plusieurs "
"paramètres de répétition."
#: .\cookbook\views\api.py:923
msgid "Book IDs, repeat for multiple. Return recipes with any of the books"
msgstr ""
"IDs de livre, répéter pour plusieurs livres. Renvoie les recettes dans "
"n'importe quel livre."
#: .\cookbook\views\api.py:924
msgid "Book IDs, repeat for multiple. Return recipes with all of the books."
msgstr ""
"IDs de livre, répéter pour plusieurs livres. Renvoie les recettes dans tous "
"les livre."
#: .\cookbook\views\api.py:925
#, fuzzy
msgid "Book IDs, repeat for multiple. Exclude recipes with any of the books."
msgstr ""
"Identifiants de livres : répéter pour plusieurs. Exclure les recettes de "
"l'un des livres."
#: .\cookbook\views\api.py:926
msgid "Book IDs, repeat for multiple. Exclude recipes with all of the books."

View File

@@ -11,7 +11,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-01 15:04+0200\n"
"PO-Revision-Date: 2025-07-21 09:43+0000\n"
"PO-Revision-Date: 2024-11-05 10:58+0000\n"
"Last-Translator: Aija Kozlovska <kozlovska.aija@gmail.com>\n"
"Language-Team: Latvian <http://translate.tandoor.dev/projects/tandoor/"
"recipes-backend/lv/>\n"
@@ -20,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
"X-Generator: Weblate 5.8.4\n"
"X-Generator: Weblate 5.6.2\n"
#: .\cookbook\forms.py:45
msgid ""
@@ -83,8 +83,8 @@ msgid ""
"Leave empty for dropbox and enter only base url for nextcloud (<code>/remote."
"php/webdav/</code> is added automatically)"
msgstr ""
"Atstājiet tukšu Dropbox un ievadiet tikai Nextcloud bāzes URL (<code> /remote"
".php/webdav/ </code> tiek pievienots automātiski)"
"Atstājiet tukšu Dropbox un ievadiet tikai Nextcloud bāzes URL (<kods> /"
"remote.php/webdav/ </code> tiek pievienots automātiski)"
#: .\cookbook\forms.py:188
msgid ""
@@ -147,65 +147,48 @@ msgid ""
"Determines how fuzzy a search is if it uses trigram similarity matching (e."
"g. low values mean more typos are ignored)."
msgstr ""
"Nosaka cik precīza ir meklēšana gadījumā, ja tiek izmantota trigram līdzība ("
"jo zemāka vērtība, jo vairāk rakstīšanas kļūdas tiek ignorētas)."
#: .\cookbook\forms.py:340
msgid ""
"Select type method of search. Click <a href=\"/docs/search/\">here</a> for "
"full description of choices."
msgstr ""
"Izvēlies meklēšanas veidu. Spied <a href=\"/docs/search/\">šeit</a>, lai "
"apskatītu visas iespējas."
#: .\cookbook\forms.py:341
msgid ""
"Use fuzzy matching on units, keywords and ingredients when editing and "
"importing recipes."
msgstr ""
"Izmanto aptuveno meklēšanu vienībām, atslēgas vārdiem un sastāvdaļām "
"importējot un labojot receptes."
#: .\cookbook\forms.py:342
msgid ""
"Fields to search ignoring accents. Selecting this option can improve or "
"degrade search quality depending on language"
msgstr ""
"Lauki, kurus meklējot ignorēt akcentus. Šī varianta izvēlēšanās var uzlabot "
"vai pasliktināt meklēšanas kvalitāti atkarībā no valodas"
#: .\cookbook\forms.py:343
msgid ""
"Fields to search for partial matches. (e.g. searching for 'Pie' will return "
"'pie' and 'piece' and 'soapie')"
msgstr ""
"Lauki, kuros meklēt aptuveno līdzību. (piem. meklējot vārdu 'Kūka' tiks "
"atrasts arī 'kūka' un 'ābolkūka')"
#: .\cookbook\forms.py:344
msgid ""
"Fields to search for beginning of word matches. (e.g. searching for 'sa' "
"will return 'salad' and 'sandwich')"
msgstr ""
"Lauki, kuros meklēt vārdu līdzības sākumu. (piem meklējot 'la' atradīt "
"'lapas' un 'laims')"
#: .\cookbook\forms.py:345
msgid ""
"Fields to 'fuzzy' search. (e.g. searching for 'recpie' will find 'recipe'.) "
"Note: this option will conflict with 'web' and 'raw' methods of search."
msgstr ""
"Lauki, kuriem izmantot aptuveno meklēšanu. (piem. meklējot 'recpte' tiks "
"atrasts 'recepte'.) Piezīme: šis variants konfliktēs ar 'web' un 'raw' "
"meklēšanas metodēm."
#: .\cookbook\forms.py:346
msgid ""
"Fields to full text search. Note: 'web', 'phrase', and 'raw' search methods "
"only function with fulltext fields."
msgstr ""
"Lauki priekš pilnās teksta meklēšanas. Piezīme: 'web', 'phrase' un 'raw' "
"meklēšanas metodes darbojās tikai ar pilno teksta meklēšanu."
#: .\cookbook\forms.py:350
#, fuzzy
@@ -215,11 +198,11 @@ msgstr "Meklēt"
#: .\cookbook\forms.py:350
msgid "Fuzzy Lookups"
msgstr "Aptuvenā meklēšana"
msgstr ""
#: .\cookbook\forms.py:350
msgid "Ignore Accent"
msgstr "Ignorēt akcentus"
msgstr ""
#: .\cookbook\forms.py:350
msgid "Partial Match"
@@ -762,8 +745,8 @@ msgid ""
" ."
msgstr ""
"Lūdzu apstipriniet, ka\n"
" <a href=\"mailto:%(email)s\">%(email)s</a> ir e-pasta adrese "
"lietotājam %(user_display)\n"
" <a href=\"mailto:%(email)s\">%(email)s</a> ir lietotāja "
"%(user_display) e-pasta adrese\n"
" ."
#: .\cookbook\templates\account\email_confirm.html:22
@@ -1348,7 +1331,7 @@ msgstr ""
#: .\cookbook\templates\markdown_info.html:57
#: .\cookbook\templates\markdown_info.html:73
msgid "or by leaving a blank line in between."
msgstr "vai atstājot tukšu rindu starp."
msgstr "vai atstājot tukšu rindu starp ."
#: .\cookbook\templates\markdown_info.html:59
#: .\cookbook\templates\markdown_info.html:74
@@ -1460,7 +1443,7 @@ msgstr "Nav Tiesību"
#: .\cookbook\templates\no_groups_info.html:17
msgid "You do not have any groups and therefor cannot use this application."
msgstr "Jūs neesat nevienā grupā un tādēļ nevarat izmantot šo lietotni."
msgstr "Jūs neesat nevienā grupā un tādēļ nevarat izmantot šo lietotni!"
#: .\cookbook\templates\no_groups_info.html:18
#: .\cookbook\templates\no_perm_info.html:15
@@ -1477,7 +1460,7 @@ msgid ""
"You do not have the required permissions to view this page or perform this "
"action."
msgstr ""
"Jums nav nepieciešamo atļauju, lai skatītu šo vietni vai veiktu šo darbību."
"Jums nav nepieciešamo atļauju, lai skatītu šo vietni vai veiktu šo darbību!"
#: .\cookbook\templates\offline.html:6
msgid "Offline"
@@ -1565,16 +1548,6 @@ msgid ""
"html#TEXTSEARCH-PARSING-QUERIES>Postgresql's website.</a>\n"
" "
msgstr ""
" \n"
" Pilnā teksta meklēšanas mēģinājums vienkāršot dotos vārdus, lai "
"tie sakristu ar tipiskajiem variantiem. Piemēram: 'griezt', 'griezšana', "
"'griezums' tiks vienkāršots uz 'griez'.\n"
" Lai kontrolētu meklētāja darbību ievadot vairākus meklējamos "
"vārdus, ir pieejamas vairākas zemāk aprakstītās metodes.\n"
" Pilno tehnisko informāciju par tām var apskatīt <a "
"href=https://www.postgresql.org/docs/current/textsearch-controls.html"
"#TEXTSEARCH-PARSING-QUERIES>Postgresql mājas lapā.</a>\n"
" "
#: .\cookbook\templates\search_info.html:29
msgid ""
@@ -2574,12 +2547,22 @@ msgid "Unable to determine PostgreSQL version."
msgstr ""
#: .\cookbook\views\views.py:317
#, fuzzy
#| msgid ""
#| "\n"
#| " This application is not running with a Postgres database "
#| "backend. This is ok but not recommended as some\n"
#| " features only work with postgres databases.\n"
#| " "
msgid ""
"This application is not running with a Postgres database backend. This is ok "
"but not recommended as some features only work with postgres databases."
msgstr ""
"Šī lietojumprogramma nedarbojas, izmantojot Postgres datubāzi. Tas ir labi, "
"bet nav ieteicams, jo dažas funkcijas darbojas tikai ar Postgres datu bāzēm."
"\n"
" Šī lietojumprogramma nedarbojas, izmantojot Postgres datubāzi. "
"Tas ir labi, bet nav ieteicams, jo dažas\n"
" funkcijas darbojas tikai ar Postgres datu bāzēm.\n"
" "
#: .\cookbook\views\views.py:360
#, fuzzy

View File

@@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-01 15:04+0200\n"
"PO-Revision-Date: 2025-07-31 19:14+0000\n"
"Last-Translator: Justin Straver <justin.straver@gmail.com>\n"
"PO-Revision-Date: 2025-02-16 14:58+0000\n"
"Last-Translator: Cots Partier <cots.pastier.34@icloud.com>\n"
"Language-Team: Dutch <http://translate.tandoor.dev/projects/tandoor/"
"recipes-backend/nl/>\n"
"Language: nl\n"
@@ -46,7 +46,7 @@ msgstr "Voorbereidingstijd in minuten"
#: .\cookbook\forms.py:62
msgid "Waiting time (cooking/baking) in minutes"
msgstr "Wachttijd in minuten (koken en bakken)"
msgstr "Wacht tijd in minuten (koken en bakken)"
#: .\cookbook\forms.py:63 .\cookbook\forms.py:222 .\cookbook\forms.py:246
msgid "Path"

File diff suppressed because it is too large Load Diff

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-01 15:04+0200\n"
"PO-Revision-Date: 2025-08-10 11:36+0000\n"
"Last-Translator: Elias Sjögreen <eliassjogreen1@gmail.com>\n"
"PO-Revision-Date: 2025-02-07 08:58+0000\n"
"Last-Translator: Mattias G <mattias.granlund@gmail.com>\n"
"Language-Team: Swedish <http://translate.tandoor.dev/projects/tandoor/"
"recipes-backend/sv/>\n"
"Language: sv\n"
@@ -641,8 +641,6 @@ msgstr "ID eller enhet att använda för inköpslistan"
#: .\cookbook\serializer.py:1443
msgid "When set to true will delete all food from active shopping lists."
msgstr ""
"Om det här alternativet är aktiverat kommer alla matvaror att raderas från "
"de aktiva inköpslistorna."
#: .\cookbook\tables.py:69 .\cookbook\tables.py:83
#: .\cookbook\templates\generic\delete_template.html:7
@@ -725,13 +723,10 @@ msgid ""
"You currently do not have any e-mail address set up. You should really add "
"an e-mail address so you can receive notifications, reset your password, etc."
msgstr ""
"Just nu har du inga e-post adresser konfigurerade. Du borde verkligen lägga "
"till en e-post adress så att du kan får notiser, återställa ditt lösenord, "
"mm."
#: .\cookbook\templates\account\email.html:64
msgid "Add E-mail Address"
msgstr "Lägg till en e-post adress"
msgstr ""
#: .\cookbook\templates\account\email.html:69
msgid "Add E-mail"
@@ -739,12 +734,12 @@ msgstr "Lägg till email"
#: .\cookbook\templates\account\email.html:79
msgid "Do you really want to remove the selected e-mail address?"
msgstr "Vill du verkligen ta bort den valda e-postadressen?"
msgstr ""
#: .\cookbook\templates\account\email_confirm.html:6
#: .\cookbook\templates\account\email_confirm.html:10
msgid "Confirm E-mail Address"
msgstr "Bekräfta e-postadress"
msgstr ""
#: .\cookbook\templates\account\email_confirm.html:16
#, python-format
@@ -754,10 +749,6 @@ msgid ""
"for user %(user_display)s\n"
" ."
msgstr ""
"Vänligen bekräfra att\n"
" <a href=\"mailto:%(email)s\">%(email)s</a> är e-postadressen för "
"användaren %(user_display)s\n"
" ."
#: .\cookbook\templates\account\email_confirm.html:22
#: .\cookbook\templates\generic\delete_template.html:72
@@ -771,9 +762,6 @@ msgid ""
" <a href=\"%(email_url)s\">issue a new e-mail confirmation "
"request</a>."
msgstr ""
"Denna e-post bekräftelselänk är utgången eller felaktig. Vänligen\n"
" <a href=\"%(email_url)s\">skapa en ny "
"e-postbekräftelsebegäran</a>."
#: .\cookbook\templates\account\login.html:8 .\cookbook\templates\base.html:388
#: .\cookbook\templates\openid\login.html:8
@@ -797,17 +785,19 @@ msgstr "Logga in"
#: .\cookbook\templates\account\password_reset_done.html:33
#: .\cookbook\templates\socialaccount\signup.html:8
#: .\cookbook\templates\socialaccount\signup.html:57
#, fuzzy
#| msgid "Sign In"
msgid "Sign Up"
msgstr "Registrera dig"
msgstr "Logga in"
#: .\cookbook\templates\account\login.html:38
msgid "Lost your password?"
msgstr "Glömt ditt lösenord?"
msgstr ""
#: .\cookbook\templates\account\login.html:39
#: .\cookbook\templates\account\password_reset.html:29
msgid "Reset My Password"
msgstr "Återställ mitt lösenord"
msgstr ""
#: .\cookbook\templates\account\login.html:50
msgid "Social Login"
@@ -834,8 +824,10 @@ msgstr "Är du säker på att du vill logga ut?"
#: .\cookbook\templates\account\password_reset_from_key.html:13
#: .\cookbook\templates\account\password_reset_from_key_done.html:7
#: .\cookbook\templates\account\password_reset_from_key_done.html:13
#, fuzzy
#| msgid "Changes saved!"
msgid "Change Password"
msgstr "Ändra lösenord"
msgstr "Ändringar sparade!"
#: .\cookbook\templates\account\password_change.html:12
#: .\cookbook\templates\account\password_set.html:12
@@ -858,20 +850,18 @@ msgid ""
"Forgotten your password? Enter your e-mail address below, and we'll send you "
"an e-mail allowing you to reset it."
msgstr ""
"Glömt ditt lösenord? Ange din e-postadress nedanför så skickar vi ett "
"återställningmail."
#: .\cookbook\templates\account\password_reset.html:32
#, fuzzy
#| msgid "Password reset is not implemented for the time being!"
msgid "Password reset is disabled on this instance."
msgstr "Återställning av lösenord är avaktiverat på denna instans."
msgstr "Återställning av lösenord har ännu inte lagts till!"
#: .\cookbook\templates\account\password_reset_done.html:25
msgid ""
"We have sent you an e-mail. Please contact us if you do not receive it "
"within a few minutes."
msgstr ""
"Vi har skickat ett e-postmeddelande till dig. Om du inte har fått det inom "
"några minuter, vänligen kontakta oss."
#: .\cookbook\templates\account\password_reset_from_key.html:13
#, fuzzy

View File

@@ -8,22 +8,22 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-01 15:04+0200\n"
"PO-Revision-Date: 2025-08-02 07:49+0000\n"
"Last-Translator: TC Kuo <tckuo7@gmail.com>\n"
"Language-Team: Chinese (Traditional Han script) <http://translate.tandoor."
"dev/projects/tandoor/recipes-backend/zh_Hant/>\n"
"PO-Revision-Date: 2024-11-04 10:29+0000\n"
"Last-Translator: Johnny Ip <ip.iohnny@gmail.com>\n"
"Language-Team: Chinese (Traditional) <http://translate.tandoor.dev/projects/"
"tandoor/recipes-backend/zh_Hant/>\n"
"Language: zh_Hant\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.8.4\n"
"X-Generator: Weblate 5.6.2\n"
#: .\cookbook\forms.py:45
msgid ""
"Both fields are optional. If none are given the username will be displayed "
"instead"
msgstr "這兩個欄位都是可選的。如果沒有輸入,將顯示用戶名"
msgstr "這兩個字段都是可選的。如果沒有輸入,將顯示用戶名"
#: .\cookbook\forms.py:62 .\cookbook\forms.py:246
msgid "Name"
@@ -31,7 +31,7 @@ msgstr "名字"
#: .\cookbook\forms.py:62 .\cookbook\forms.py:246 .\cookbook\views\lists.py:103
msgid "Keywords"
msgstr "關鍵"
msgstr "關鍵"
#: .\cookbook\forms.py:62
msgid "Preparation time in minutes"
@@ -51,13 +51,14 @@ msgstr "存儲ID"
#: .\cookbook\forms.py:93
msgid "Default"
msgstr "預設"
msgstr "默認"
#: .\cookbook\forms.py:121
msgid ""
"To prevent duplicates recipes with the same name as existing ones are "
"ignored. Check this box to import everything."
msgstr "為防止重複,忽略與現有同名的食譜。選中此框可導入所有內容(包括同名食譜)。"
msgstr ""
"為防止重復,忽略與現有同名的菜譜。選中此框可導入所有內容(包括同名菜譜)。"
#: .\cookbook\forms.py:143
msgid "Add your comment: "
@@ -240,7 +241,7 @@ msgstr "你沒有必要的權限來查看這個頁面!"
#: .\cookbook\helper\permission_helper.py:237
#: .\cookbook\helper\permission_helper.py:252
msgid "You cannot interact with this object as it is not owned by you!"
msgstr "你不能與此對象互,因為它不屬於你!"
msgstr "你不能與此對象互,因為它不屬於你!"
#: .\cookbook\helper\permission_helper.py:402
msgid "You have reached the maximum number of recipes for your space."
@@ -310,16 +311,16 @@ msgstr "在導入過程中發生了一個意外的錯誤。請確認你上傳的
#: .\cookbook\integration\integration.py:217
msgid "The following recipes were ignored because they already existed:"
msgstr "以下譜被忽略了,因為它們已經存在了:"
msgstr "以下譜被忽略了,因為它們已經存在了:"
#: .\cookbook\integration\integration.py:221
#, python-format
msgid "Imported %s recipes."
msgstr "導入了%s譜。"
msgstr "導入了%s譜。"
#: .\cookbook\integration\openeats.py:28
msgid "Recipe source:"
msgstr "譜來源:"
msgstr "譜來源:"
#: .\cookbook\integration\paprika.py:49
msgid "Notes"
@@ -327,7 +328,7 @@ msgstr "說明"
#: .\cookbook\integration\paprika.py:52
msgid "Nutritional Information"
msgstr "營養資訊"
msgstr "營養信息"
#: .\cookbook\integration\paprika.py:56
msgid "Source"
@@ -644,7 +645,7 @@ msgstr "電子郵件地址"
#: .\cookbook\templates\socialaccount\connections.html:10
#: .\cookbook\templates\user_settings.html:8
msgid "Settings"
msgstr "設"
msgstr "設"
#: .\cookbook\templates\account\email.html:13
msgid "Email"
@@ -1877,7 +1878,7 @@ msgstr "你可以被邀請加入現有空間或創建自己的空間。"
#: .\cookbook\templates\space_overview.html:53
msgid "Owner"
msgstr "有者"
msgstr "有者"
#: .\cookbook\templates\space_overview.html:57
msgid "Leave Space"

View File

@@ -1,34 +0,0 @@
# Generated by Django 4.2.22 on 2025-08-31 09:11
from django.db import migrations
from django_scopes import scopes_disabled
def migrate_comments(apps, schema_editor):
with scopes_disabled():
Comment = apps.get_model('cookbook', 'Comment')
CookLog = apps.get_model('cookbook', 'CookLog')
cook_logs = []
for c in Comment.objects.all():
cook_logs.append(CookLog(
recipe=c.recipe,
created_by=c.created_by,
created_at=c.created_at,
comment=c.text,
space=c.recipe.space,
))
CookLog.objects.bulk_create(cook_logs, unique_fields=('recipe', 'comment', 'created_at', 'created_by'))
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0222_alter_shoppinglistrecipe_created_by_and_more'),
]
operations = [
migrations.RunPython(migrate_comments),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 4.2.22 on 2025-07-13 19:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0222_alter_shoppinglistrecipe_created_by_and_more'),
]
operations = [
migrations.AddField(
model_name='userpreference',
name='ingredient_context',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='userpreference',
name='use_fractions',
field=models.BooleanField(default=True),
),
]

View File

@@ -126,7 +126,7 @@ class TreeModel(MP_Node):
return None
@property
def full_name(self) -> str:
def full_name(self):
"""
Returns a string representation of a tree node and it's ancestors,
e.g. 'Cuisine > Asian > Chinese > Catonese'.
@@ -191,7 +191,7 @@ class TreeModel(MP_Node):
return queryset.model.objects.filter(id__in=queryset.values_list('id')).exclude(descendants)
def include_ancestors(queryset=None):
def include_ancestors(queryset=None, filter=None):
"""
:param queryset: Model Queryset to add ancestors
:param filter: Filter (include) the ancestors nodes with the provided Q filter
@@ -487,6 +487,7 @@ class UserPreference(models.Model, PermissionModelMixin):
shopping_recent_days = models.PositiveIntegerField(default=7)
csv_delim = models.CharField(max_length=2, default=",")
csv_prefix = models.CharField(max_length=10, blank=True, )
ingredient_context = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
objects = ScopedManager(space='space')
@@ -767,6 +768,22 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
obj.inherit_fields.set(fields)
obj.save()
def get_substitutes(self, onhand=False, shopping_users=None):
# filters = ~Q(id=self.id)
filters = Q()
if self.substitute:
filters |= Q(id__in=self.substitute.values('id'))
if self.substitute_children:
filters |= Q(path__startswith=self.path, depth__gt=self.depth)
if self.substitute_siblings:
sibling_path = self.path[:Food.steplen * (self.depth - 1)]
filters |= Q(path__startswith=sibling_path, depth=self.depth)
qs = Food.objects.filter(filters).exclude(id=self.id)
if onhand:
qs = qs.filter(onhand_users__in=shopping_users)
return qs
@staticmethod
def reset_inheritance(space=None, food=None):
# resets inherited fields to the space defaults and updates all inherited fields to root object values
@@ -912,19 +929,12 @@ class PropertyType(models.Model, PermissionModelMixin, MergeModelMixin):
GOAL = 'GOAL'
OTHER = 'OTHER'
CHOICES = (
(NUTRITION, _('Nutrition')),
(ALLERGEN, _('Allergen')),
(PRICE, _('Price')),
(GOAL, _('Goal')),
(OTHER, _('Other')),
)
name = models.CharField(max_length=128)
unit = models.CharField(max_length=64, blank=True, null=True)
order = models.IntegerField(default=0)
description = models.CharField(max_length=512, blank=True, null=True)
category = models.CharField(max_length=64, choices=CHOICES, null=True, blank=True)
category = models.CharField(max_length=64, choices=((NUTRITION, _('Nutrition')), (ALLERGEN, _('Allergen')),
(PRICE, _('Price')), (GOAL, _('Goal')), (OTHER, _('Other'))), null=True, blank=True)
open_data_slug = models.CharField(max_length=128, null=True, blank=True, default=None)
fdc_id = models.IntegerField(null=True, default=None, blank=True)
@@ -1094,19 +1104,6 @@ class RecipeImport(models.Model, PermissionModelMixin):
def __str__(self):
return self.name
def convert_to_recipe(self, user):
recipe = Recipe(
name=self.name,
file_path=self.file_path,
storage=self.storage,
file_uid=self.file_uid,
created_by=user,
space=self.space
)
recipe.save()
self.delete()
return recipe
class RecipeBook(ExportModelOperationsMixin('book'), models.Model, PermissionModelMixin):
name = models.CharField(max_length=128)
@@ -1470,21 +1467,19 @@ class Automation(ExportModelOperationsMixin('automations'), models.Model, Permis
UNIT_REPLACE = 'UNIT_REPLACE'
NAME_REPLACE = 'NAME_REPLACE'
automation_types = (
(FOOD_ALIAS, _('Food Alias')),
(UNIT_ALIAS, _('Unit Alias')),
(KEYWORD_ALIAS, _('Keyword Alias')),
(DESCRIPTION_REPLACE, _('Description Replace')),
(INSTRUCTION_REPLACE, _('Instruction Replace')),
(NEVER_UNIT, _('Never Unit')),
(TRANSPOSE_WORDS, _('Transpose Words')),
(FOOD_REPLACE, _('Food Replace')),
(UNIT_REPLACE, _('Unit Replace')),
(NAME_REPLACE, _('Name Replace')),
)
type = models.CharField(max_length=128,
choices=automation_types)
choices=(
(FOOD_ALIAS, _('Food Alias')),
(UNIT_ALIAS, _('Unit Alias')),
(KEYWORD_ALIAS, _('Keyword Alias')),
(DESCRIPTION_REPLACE, _('Description Replace')),
(INSTRUCTION_REPLACE, _('Instruction Replace')),
(NEVER_UNIT, _('Never Unit')),
(TRANSPOSE_WORDS, _('Transpose Words')),
(FOOD_REPLACE, _('Food Replace')),
(UNIT_REPLACE, _('Unit Replace')),
(NAME_REPLACE, _('Name Replace')),
))
name = models.CharField(max_length=128, default='')
description = models.TextField(blank=True, null=True)

View File

@@ -31,7 +31,7 @@ class Dropbox(Provider):
except ValueError:
log_entry = SyncLog(status='ERROR', msg=str(r), sync=monitor)
log_entry.save()
return log_entry
return r
import_count = 0
# TODO check if has_more is set and import that as well
@@ -59,7 +59,7 @@ class Dropbox(Provider):
monitor.last_checked = datetime.now()
monitor.save()
return log_entry
return True
@staticmethod
def create_share_link(recipe):

View File

@@ -42,7 +42,7 @@ class Local(Provider):
monitor.last_checked = datetime.now()
monitor.save()
return log_entry
return True
@staticmethod
def get_file(recipe):

View File

@@ -66,7 +66,7 @@ class Nextcloud(Provider):
monitor.last_checked = datetime.now()
monitor.save()
return log_entry
return True
@staticmethod
def create_share_link(recipe):

69
cookbook/schemas.py Normal file
View File

@@ -0,0 +1,69 @@
from rest_framework.schemas.openapi import AutoSchema
from rest_framework.schemas.utils import is_list_view
class QueryParam(object):
def __init__(self, name, description=None, qtype='string', required=False):
self.name = name
self.description = description
self.qtype = qtype
self.required = required
def __str__(self):
return f'{self.name}, {self.qtype}, {self.description}'
class QueryParamAutoSchema(AutoSchema):
def get_path_parameters(self, path, method):
if not is_list_view(path, method, self.view):
return super().get_path_parameters(path, method)
parameters = super().get_path_parameters(path, method)
for q in self.view.query_params:
parameters.append({
"name": q.name, "in": "query", "required": q.required,
"description": q.description,
'schema': {'type': q.qtype, },
})
return parameters
class TreeSchema(AutoSchema):
def get_path_parameters(self, path, method):
if not is_list_view(path, method, self.view):
return super(TreeSchema, self).get_path_parameters(path, method)
api_name = path.split('/')[2]
parameters = super().get_path_parameters(path, method)
parameters.append({
"name": 'query', "in": "query", "required": False,
"description": 'Query string matched against {} name.'.format(api_name),
'schema': {'type': 'string', },
})
parameters.append({
"name": 'root', "in": "query", "required": False,
"description": 'Return first level children of {obj} with ID [int]. Integer 0 will return root {obj}s.'.format(
obj=api_name),
'schema': {'type': 'integer', },
})
parameters.append({
"name": 'tree', "in": "query", "required": False,
"description": 'Return all self and children of {} with ID [int].'.format(api_name),
'schema': {'type': 'integer', },
})
return parameters
class FilterSchema(AutoSchema):
def get_path_parameters(self, path, method):
if not is_list_view(path, method, self.view):
return super(FilterSchema, self).get_path_parameters(path, method)
api_name = path.split('/')[2]
parameters = super().get_path_parameters(path, method)
parameters.append({
"name": 'query', "in": "query", "required": False,
"description": 'Query string matched against {} name.'.format(api_name),
'schema': {'type': 'string', },
})
return parameters

File diff suppressed because it is too large Load Diff

View File

@@ -120,6 +120,37 @@ def update_food_inheritance(sender, instance=None, created=False, **kwargs):
child.save()
@receiver(post_save, sender=MealPlan)
def auto_add_shopping(sender, instance=None, created=False, weak=False, **kwargs):
print("MEAL_AUTO_ADD Signal trying to auto add to shopping")
if not instance:
print("MEAL_AUTO_ADD Instance is none")
return
try:
space = instance.get_space()
user = instance.get_owner()
with scope(space=space):
slr_exists = instance.shoppinglistrecipe_set.exists()
if not created and slr_exists:
for x in instance.shoppinglistrecipe_set.all():
# assuming that permissions checks for the MealPlan have happened upstream
if instance.servings != x.servings:
SLR = RecipeShoppingEditor(id=x.id, user=user, space=instance.space)
SLR.edit_servings(servings=instance.servings)
elif not user.userpreference.mealplan_autoadd_shopping or not instance.recipe:
print("MEAL_AUTO_ADD No recipe or no setting")
return
if created:
SLR = RecipeShoppingEditor(user=user, space=space)
SLR.create(mealplan=instance, servings=instance.servings)
print("MEAL_AUTO_ADD Created SLR")
except AttributeError:
pass
@receiver(post_save, sender=Unit)
def clear_unit_cache(sender, instance=None, created=False, **kwargs):
if instance:

View File

@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg48" inkscape:export-xdpi="48" inkscape:export-ydpi="48" sodipodi:docname="logo_color_shopping.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:serif="http://www.serif.com/" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 558.1 558.1"
style="enable-background:new 0 0 558.1 558.1;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:url(#ellipse2_00000062882008473870802360000001235346600214014370_);}
.st1{clip-path:url(#SVGID_00000040562990235419179500000014537515251997333940_);}
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#161616;}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFCB76;}
.st4{fill-rule:evenodd;clip-rule:evenodd;fill:#FF6F00;}
.st5{clip-path:url(#SVGID_00000026884998257896383920000012290328997039565247_);}
.st6{fill-rule:evenodd;clip-rule:evenodd;fill:#FFD100;}
.st7{fill:#161616;}
</style>
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview50" inkscape:current-layer="svg48" inkscape:cx="256" inkscape:cy="256" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="1377" inkscape:window-maximized="1" inkscape:window-width="2560" inkscape:window-x="2552" inkscape:window-y="-8" inkscape:zoom="2.0039062" objecttolerance="10" pagecolor="#ffffff" showgrid="false">
</sodipodi:namedview>
<g id="Kreis" transform="matrix(0.92371046,0,0,0.95776263,3.7134303,-54.329713)">
<linearGradient id="ellipse2_00000072976586691886204630000005673338158137684613_" gradientUnits="userSpaceOnUse" x1="-24.1585" y1="348.0664" x2="-23.1585" y2="348.0664" gradientTransform="matrix(2.147900e-06 0 0 -2.227081e-06 4347.1548 66.3621)">
<stop offset="0" style="stop-color:#272727"/>
<stop offset="1" style="stop-color:#6C6C6C"/>
</linearGradient>
<ellipse id="ellipse2" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#ellipse2_00000072976586691886204630000005673338158137684613_);" cx="298.1" cy="348.1" rx="302.1" ry="291.3"/>
<g>
<defs>
<circle id="SVGID_1_" cx="298.1" cy="348.1" r="279"/>
</defs>
<clipPath id="SVGID_00000080899089203538361760000014164288875061347472_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<g id="g18" style="clip-path:url(#SVGID_00000080899089203538361760000014164288875061347472_);">
<g id="Shadow" transform="matrix(1.10322,0,0,1.064,-5.58287,50.5786)">
<path id="path7" class="st2" d="M163.2,477.5l271.2,271.2L759.1,557L416.4,214.2L163.2,477.5z"/>
<g id="g11" transform="translate(-4.22105,0.775864)">
<path id="path9" class="st2" d="M223.4,188.6L545.8,511l121-106.1L326,64.1l-3.2,78.4L223.4,188.6z"/>
</g>
<g id="g15" transform="translate(-85.3876,27.8512)">
<path id="path13" class="st2" d="M328.5,154.7l322.4,322.4l3.1-71.6L313.3,64.7l-3.6,82.2L328.5,154.7z"/>
</g>
</g>
</g>
</g>
</g>
<g id="g23" transform="matrix(0.93750213,0,0,0.93750213,15.953517,15.99888)">
<path id="path21" class="st3" d="M280.6,238.7c35.1,0,65.8-14.8,85.3-30.1c19.7-15.6,48.3-12.5,64.2,6.9
c26.2,31.7,41.8,71.9,41.8,115.6c0,71.6-44.2,159.9-105.6,190.9c-26.4,13.3-53.8,19.6-85.6,19.6l0,0h-0.1h-0.1l0,0
c-31.8,0-59.2-6.3-85.6-19.6C133.5,491.1,89.3,402.7,89.3,331.2c0-43.7,15.7-83.9,41.8-115.6c15.9-19.4,44.5-22.5,64.2-6.9
C214.8,224,245.5,238.7,280.6,238.7L280.6,238.7z"/>
</g>
<g id="Flame-2" transform="matrix(0.61547875,0,0,0.56833279,-138.25728,-438.60298)" serif:id="Flame 2">
<path id="path25" class="st4" d="M636,823.4c-2.8-4-2.8-9.6-0.1-13.7c2.8-4.1,7.7-5.6,12.1-3.9c22.2,8.9,51.2,22.5,73.8,40.9
c46.9,38.3,59.7,63.9,70.2,90.3c12.4,31.2,14.2,63.5,11.6,86c-7.6,64.6-56,117.9-125,117.9c-69,0-123.9-52.8-125-117.9
c-0.7-39.2,12.1-70.5,26.1-92.8c3.5-5.6,10-7.8,15.8-5.6c5.8,2.3,9.5,8.6,8.8,15.3c-2,14.1-3.3,28.8-2.7,40.6
c2.2,39.8,25.9,50,50.2,49.8c25.9-0.2,52.1-22.2,42.7-78.4C686.3,902.9,656.8,853.5,636,823.4L636,823.4z"/>
<g>
<defs>
<path id="SVGID_00000067227953264718972400000007310393595166440114_" d="M636,823.4c-2.8-4-2.8-9.6-0.1-13.7
c2.8-4.1,7.7-5.6,12.1-3.9c22.2,8.9,51.2,22.5,73.8,40.9c46.9,38.3,59.7,63.9,70.2,90.3c12.4,31.2,14.2,63.5,11.6,86
c-7.6,64.6-56,117.9-125,117.9c-69,0-123.9-52.8-125-117.9c-0.7-39.2,12.1-70.5,26.1-92.8c3.5-5.6,10-7.8,15.8-5.6
c5.8,2.3,9.5,8.6,8.8,15.3c-2,14.1-3.3,28.8-2.7,40.6c2.2,39.8,25.9,50,50.2,49.8c25.9-0.2,52.1-22.2,42.7-78.4
C686.3,902.9,656.8,853.5,636,823.4L636,823.4z"/>
</defs>
<clipPath id="SVGID_00000178886517717031376290000002615817110574070691_">
<use xlink:href="#SVGID_00000067227953264718972400000007310393595166440114_" style="overflow:visible;"/>
</clipPath>
<g id="g34" style="clip-path:url(#SVGID_00000178886517717031376290000002615817110574070691_);">
<g id="g32" transform="matrix(1.28784,-0.270602,0.285942,1.59598,247.349,825.209)">
<path id="path30" class="st6" d="M279.8,36.7c28.5,13.5,59.3,44.8,67.8,85.1c14.1,67-25.3,85.6-59.1,84
c-54.2-2.6-72.4-45.5-36.2-97.1C274.8,76.8,253.9,24.5,279.8,36.7z"/>
</g>
</g>
</g>
</g>
<path class="st7" d="M245.7,280.1c6.2,0,11.1,5,11.1,11.1v11.1h44.5v-11.1c0-6.2,5-11.1,11.1-11.1s11.1,5,11.1,11.1v11.1h16.7
c9.2,0,16.7,7.5,16.7,16.7v16.7H201.2V319c0-9.2,7.5-16.7,16.7-16.7h16.7v-11.1C234.5,285,239.5,280.1,245.7,280.1z M201.2,346.8
h155.8v94.6c0,9.2-7.5,16.7-16.7,16.7H217.8c-9.2,0-16.7-7.5-16.7-16.7V346.8z M223.4,374.6v11.1c0,3.1,2.5,5.6,5.6,5.6h11.1
c3.1,0,5.6-2.5,5.6-5.6v-11.1c0-3.1-2.5-5.6-5.6-5.6H229C225.9,369.1,223.4,371.6,223.4,374.6z M267.9,374.6v11.1
c0,3.1,2.5,5.6,5.6,5.6h11.1c3.1,0,5.6-2.5,5.6-5.6v-11.1c0-3.1-2.5-5.6-5.6-5.6h-11.1C270.4,369.1,267.9,371.6,267.9,374.6z
M318,369.1c-3.1,0-5.6,2.5-5.6,5.6v11.1c0,3.1,2.5,5.6,5.6,5.6h11.1c3.1,0,5.6-2.5,5.6-5.6v-11.1c0-3.1-2.5-5.6-5.6-5.6H318z
M223.4,419.1v11.1c0,3.1,2.5,5.6,5.6,5.6h11.1c3.1,0,5.6-2.5,5.6-5.6v-11.1c0-3.1-2.5-5.6-5.6-5.6H229
C225.9,413.6,223.4,416.1,223.4,419.1z M273.5,413.6c-3.1,0-5.6,2.5-5.6,5.6v11.1c0,3.1,2.5,5.6,5.6,5.6h11.1c3.1,0,5.6-2.5,5.6-5.6
v-11.1c0-3.1-2.5-5.6-5.6-5.6H273.5z M312.4,419.1v11.1c0,3.1,2.5,5.6,5.6,5.6h11.1c3.1,0,5.6-2.5,5.6-5.6v-11.1
c0-3.1-2.5-5.6-5.6-5.6H318C314.9,413.6,312.4,416.1,312.4,419.1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg48" inkscape:export-xdpi="48" inkscape:export-ydpi="48" sodipodi:docname="logo_color_shopping.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:serif="http://www.serif.com/" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 558.1 558.1"
style="enable-background:new 0 0 558.1 558.1;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:url(#ellipse2_00000123406314579419878720000015292012387505797789_);}
.st1{clip-path:url(#SVGID_00000069378195777491616980000011609770225407185072_);}
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#161616;}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFCB76;}
.st4{fill-rule:evenodd;clip-rule:evenodd;fill:#FF6F00;}
.st5{clip-path:url(#SVGID_00000129168706913539839680000006972943119257724314_);}
.st6{fill-rule:evenodd;clip-rule:evenodd;fill:#FFD100;}
</style>
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview50" inkscape:current-layer="svg48" inkscape:cx="256" inkscape:cy="256" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="1377" inkscape:window-maximized="1" inkscape:window-width="2560" inkscape:window-x="2552" inkscape:window-y="-8" inkscape:zoom="2.0039062" objecttolerance="10" pagecolor="#ffffff" showgrid="false">
</sodipodi:namedview>
<g id="Kreis" transform="matrix(0.92371046,0,0,0.95776263,3.7134303,-54.329713)">
<linearGradient id="ellipse2_00000092432231847401152480000013557045245219773118_" gradientUnits="userSpaceOnUse" x1="-24.1585" y1="348.0664" x2="-23.1585" y2="348.0664" gradientTransform="matrix(2.147900e-06 0 0 -2.227081e-06 4347.1548 66.3621)">
<stop offset="0" style="stop-color:#272727"/>
<stop offset="1" style="stop-color:#6C6C6C"/>
</linearGradient>
<ellipse id="ellipse2" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#ellipse2_00000092432231847401152480000013557045245219773118_);" cx="298.1" cy="348.1" rx="302.1" ry="291.3"/>
<g>
<defs>
<circle id="SVGID_1_" cx="298.1" cy="348.1" r="279"/>
</defs>
<clipPath id="SVGID_00000078750348294658121660000005213362532985289101_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<g id="g18" style="clip-path:url(#SVGID_00000078750348294658121660000005213362532985289101_);">
<g id="Shadow" transform="matrix(1.10322,0,0,1.064,-5.58287,50.5786)">
<path id="path7" class="st2" d="M163.2,477.5l271.2,271.2L759.1,557L416.4,214.2L163.2,477.5z"/>
<g id="g11" transform="translate(-4.22105,0.775864)">
<path id="path9" class="st2" d="M223.4,188.6L545.8,511l121-106.1L326,64.1l-3.2,78.4L223.4,188.6z"/>
</g>
<g id="g15" transform="translate(-85.3876,27.8512)">
<path id="path13" class="st2" d="M328.5,154.7l322.4,322.4l3.1-71.6L313.3,64.7l-3.6,82.2L328.5,154.7z"/>
</g>
</g>
</g>
</g>
</g>
<g id="g23" transform="matrix(0.93750213,0,0,0.93750213,15.953517,15.99888)">
<path id="path21" class="st3" d="M280.6,238.7c35.1,0,65.8-14.8,85.3-30.1c19.7-15.6,48.3-12.5,64.2,6.9
c26.2,31.7,41.8,71.9,41.8,115.6c0,71.6-44.2,159.9-105.6,190.9c-26.4,13.3-53.8,19.6-85.6,19.6l0,0h-0.1h-0.1l0,0
c-31.8,0-59.2-6.3-85.6-19.6C133.5,491.1,89.3,402.7,89.3,331.2c0-43.7,15.7-83.9,41.8-115.6c15.9-19.4,44.5-22.5,64.2-6.9
C214.8,224,245.5,238.7,280.6,238.7L280.6,238.7z"/>
</g>
<g id="Flame-2" transform="matrix(0.61547875,0,0,0.56833279,-138.25728,-438.60298)" serif:id="Flame 2">
<path id="path25" class="st4" d="M636,823.4c-2.8-4-2.8-9.6-0.1-13.7c2.8-4.1,7.7-5.6,12.1-3.9c22.2,8.9,51.2,22.5,73.8,40.9
c46.9,38.3,59.7,63.9,70.2,90.3c12.4,31.2,14.2,63.5,11.6,86c-7.6,64.6-56,117.9-125,117.9c-69,0-123.9-52.8-125-117.9
c-0.7-39.2,12.1-70.5,26.1-92.8c3.5-5.6,10-7.8,15.8-5.6c5.8,2.3,9.5,8.6,8.8,15.3c-2,14.1-3.3,28.8-2.7,40.6
c2.2,39.8,25.9,50,50.2,49.8c25.9-0.2,52.1-22.2,42.7-78.4C686.3,902.9,656.8,853.5,636,823.4L636,823.4z"/>
<g>
<defs>
<path id="SVGID_00000170974775404888027640000005842834300324528060_" d="M636,823.4c-2.8-4-2.8-9.6-0.1-13.7
c2.8-4.1,7.7-5.6,12.1-3.9c22.2,8.9,51.2,22.5,73.8,40.9c46.9,38.3,59.7,63.9,70.2,90.3c12.4,31.2,14.2,63.5,11.6,86
c-7.6,64.6-56,117.9-125,117.9c-69,0-123.9-52.8-125-117.9c-0.7-39.2,12.1-70.5,26.1-92.8c3.5-5.6,10-7.8,15.8-5.6
c5.8,2.3,9.5,8.6,8.8,15.3c-2,14.1-3.3,28.8-2.7,40.6c2.2,39.8,25.9,50,50.2,49.8c25.9-0.2,52.1-22.2,42.7-78.4
C686.3,902.9,656.8,853.5,636,823.4L636,823.4z"/>
</defs>
<clipPath id="SVGID_00000137101924108689735560000002063526552501109413_">
<use xlink:href="#SVGID_00000170974775404888027640000005842834300324528060_" style="overflow:visible;"/>
</clipPath>
<g id="g34" style="clip-path:url(#SVGID_00000137101924108689735560000002063526552501109413_);">
<g id="g32" transform="matrix(1.28784,-0.270602,0.285942,1.59598,247.349,825.209)">
<path id="path30" class="st6" d="M279.8,36.7c28.5,13.5,59.3,44.8,67.8,85.1c14.1,67-25.3,85.6-59.1,84
c-54.2-2.6-72.4-45.5-36.2-97.1C274.8,76.8,253.9,24.5,279.8,36.7z"/>
</g>
</g>
</g>
</g>
<path id="path958" class="st2" d="M182.4,290.6c0-4.5,3.6-8.1,8.1-8.1h15.4c7.4,0,14,4.3,17.1,10.8h139.1c8.9,0,15.4,8.5,13.1,17.1
l-13.9,51.5c-2.9,10.6-12.5,18-23.5,18h-97.6l1.8,9.6c0.7,3.8,4.1,6.6,8,6.6h97.6c4.5,0,8.1,3.6,8.1,8.1s-3.6,8.1-8.1,8.1H250
c-11.7,0-21.8-8.3-23.9-19.8L208.6,301c-0.2-1.3-1.4-2.2-2.7-2.2h-15.4C186,298.8,182.4,295.1,182.4,290.6L182.4,290.6z
M225.7,439.5c0-9,7.3-16.3,16.2-16.3c9,0,16.3,7.3,16.3,16.2c0,0,0,0,0,0c0,9-7.3,16.3-16.2,16.3
C233,455.8,225.7,448.5,225.7,439.5C225.7,439.6,225.7,439.5,225.7,439.5z M339.4,423.3c9,0,16.2,7.3,16.3,16.2
c0,9-7.3,16.2-16.2,16.3c0,0,0,0,0,0c-9,0-16.2-7.3-16.3-16.2C323.2,430.6,330.4,423.3,339.4,423.3
C339.4,423.3,339.4,423.3,339.4,423.3z"/>
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,721 @@
/*!
* Select2 Bootstrap Theme v0.1.0-beta.10 (https://select2.github.io/select2-bootstrap-theme)
* Copyright 2015-2017 Florian Kissling and contributors (https://github.com/select2/select2-bootstrap-theme/graphs/contributors)
* Licensed under MIT (https://github.com/select2/select2-bootstrap-theme/blob/master/LICENSE)
*/
.select2-container--bootstrap {
display: block;
/*------------------------------------* #COMMON STYLES
\*------------------------------------*/
/**
* Search field in the Select2 dropdown.
*/
/**
* No outline for all search fields - in the dropdown
* and inline in multi Select2s.
*/
/**
* Adjust Select2's choices hover and selected styles to match
* Bootstrap 3's default dropdown styles.
*
* @see http://getbootstrap.com/components/#dropdowns
*/
/**
* Clear the selection.
*/
/**
* Address disabled Select2 styles.
*
* @see https://select2.github.io/examples.html#disabled
* @see http://getbootstrap.com/css/#forms-control-disabled
*/
/*------------------------------------* #DROPDOWN
\*------------------------------------*/
/**
* Dropdown border color and box-shadow.
*/
/**
* Limit the dropdown height.
*/
/*------------------------------------* #SINGLE SELECT2
\*------------------------------------*/
/*------------------------------------* #MULTIPLE SELECT2
\*------------------------------------*/
/**
* Address Bootstrap control sizing classes
*
* 1. Reset Bootstrap defaults.
* 2. Adjust the dropdown arrow button icon position.
*
* @see http://getbootstrap.com/css/#forms-control-sizes
*/
/* 1 */
/*------------------------------------* #RTL SUPPORT
\*------------------------------------*/
}
.select2-container--bootstrap .select2-selection {
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
color: #555555;
font-size: 14px;
outline: 0;
}
.select2-container--bootstrap .select2-selection.form-control {
border-radius: 4px;
}
.select2-container--bootstrap .select2-search--dropdown .select2-search__field {
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
color: #555555;
font-size: 14px;
}
.select2-container--bootstrap .select2-search__field {
outline: 0;
/* Firefox 18- */
/**
* Firefox 19+
*
* @see http://stackoverflow.com/questions/24236240/color-for-styled-placeholder-text-is-muted-in-firefox
*/
}
.select2-container--bootstrap .select2-search__field::-webkit-input-placeholder {
color: #999;
}
.select2-container--bootstrap .select2-search__field:-moz-placeholder {
color: #999;
}
.select2-container--bootstrap .select2-search__field::-moz-placeholder {
color: #999;
opacity: 1;
}
.select2-container--bootstrap .select2-search__field:-ms-input-placeholder {
color: #999;
}
.select2-container--bootstrap .select2-results__option {
padding: 6px 12px;
/**
* Disabled results.
*
* @see https://select2.github.io/examples.html#disabled-results
*/
/**
* Hover state.
*/
/**
* Selected state.
*/
}
.select2-container--bootstrap .select2-results__option[role=group] {
padding: 0;
}
.select2-container--bootstrap .select2-results__option[aria-disabled=true] {
color: #777777;
cursor: not-allowed;
}
.select2-container--bootstrap .select2-results__option[aria-selected=true] {
background-color: #f5f5f5;
color: #262626;
}
.select2-container--bootstrap .select2-results__option--highlighted[aria-selected] {
background-color: #337ab7;
color: #fff;
}
.select2-container--bootstrap .select2-results__option .select2-results__option {
padding: 6px 12px;
}
.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0;
}
.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option {
margin-left: -12px;
padding-left: 24px;
}
.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -24px;
padding-left: 36px;
}
.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -36px;
padding-left: 48px;
}
.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -48px;
padding-left: 60px;
}
.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -60px;
padding-left: 72px;
}
.select2-container--bootstrap .select2-results__group {
color: #777777;
display: block;
padding: 6px 12px;
font-size: 12px;
line-height: 1.42857143;
white-space: nowrap;
}
.select2-container--bootstrap.select2-container--focus .select2-selection, .select2-container--bootstrap.select2-container--open .select2-selection {
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
-o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
-webkit-transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;
transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;
border-color: #66afe9;
}
.select2-container--bootstrap.select2-container--open {
/**
* Make the dropdown arrow point up while the dropdown is visible.
*/
/**
* Handle border radii of the container when the dropdown is showing.
*/
}
.select2-container--bootstrap.select2-container--open .select2-selection .select2-selection__arrow b {
border-color: transparent transparent #999 transparent;
border-width: 0 4px 4px 4px;
}
.select2-container--bootstrap.select2-container--open.select2-container--below .select2-selection {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
border-bottom-color: transparent;
}
.select2-container--bootstrap.select2-container--open.select2-container--above .select2-selection {
border-top-right-radius: 0;
border-top-left-radius: 0;
border-top-color: transparent;
}
.select2-container--bootstrap .select2-selection__clear {
color: #999;
cursor: pointer;
float: right;
font-weight: bold;
margin-right: 10px;
}
.select2-container--bootstrap .select2-selection__clear:hover {
color: #333;
}
.select2-container--bootstrap.select2-container--disabled .select2-selection {
border-color: #ccc;
-webkit-box-shadow: none;
box-shadow: none;
}
.select2-container--bootstrap.select2-container--disabled .select2-selection,
.select2-container--bootstrap.select2-container--disabled .select2-search__field {
cursor: not-allowed;
}
.select2-container--bootstrap.select2-container--disabled .select2-selection,
.select2-container--bootstrap.select2-container--disabled .select2-selection--multiple .select2-selection__choice {
background-color: #eeeeee;
}
.select2-container--bootstrap.select2-container--disabled .select2-selection__clear,
.select2-container--bootstrap.select2-container--disabled .select2-selection--multiple .select2-selection__choice__remove {
display: none;
}
.select2-container--bootstrap .select2-dropdown {
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
border-color: #66afe9;
overflow-x: hidden;
margin-top: -1px;
}
.select2-container--bootstrap .select2-dropdown--above {
-webkit-box-shadow: 0px -6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0px -6px 12px rgba(0, 0, 0, 0.175);
margin-top: 1px;
}
.select2-container--bootstrap .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto;
}
.select2-container--bootstrap .select2-selection--single {
height: 34px;
line-height: 1.42857143;
padding: 6px 24px 6px 12px;
/**
* Adjust the single Select2's dropdown arrow button appearance.
*/
}
.select2-container--bootstrap .select2-selection--single .select2-selection__arrow {
position: absolute;
bottom: 0;
right: 12px;
top: 0;
width: 4px;
}
.select2-container--bootstrap .select2-selection--single .select2-selection__arrow b {
border-color: #999 transparent transparent transparent;
border-style: solid;
border-width: 4px 4px 0 4px;
height: 0;
left: 0;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0;
}
.select2-container--bootstrap .select2-selection--single .select2-selection__rendered {
color: #555555;
padding: 0;
}
.select2-container--bootstrap .select2-selection--single .select2-selection__placeholder {
color: #999;
}
.select2-container--bootstrap .select2-selection--multiple {
min-height: 34px;
padding: 0;
height: auto;
/**
* Make Multi Select2's choices match Bootstrap 3's default button styles.
*/
/**
* Minus 2px borders.
*/
/**
* Clear the selection.
*/
}
.select2-container--bootstrap .select2-selection--multiple .select2-selection__rendered {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: block;
line-height: 1.42857143;
list-style: none;
margin: 0;
overflow: hidden;
padding: 0;
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
}
.select2-container--bootstrap .select2-selection--multiple .select2-selection__placeholder {
color: #999;
float: left;
margin-top: 5px;
}
.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice {
color: #555555;
background: #fff;
border: 1px solid #ccc;
border-radius: 4px;
cursor: default;
float: left;
margin: 5px 0 0 6px;
padding: 0 6px;
}
.select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field {
background: transparent;
padding: 0 12px;
height: 32px;
line-height: 1.42857143;
margin-top: 0;
min-width: 5em;
}
.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice__remove {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 3px;
}
.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333;
}
.select2-container--bootstrap .select2-selection--multiple .select2-selection__clear {
margin-top: 6px;
}
.select2-container--bootstrap .select2-selection--single.input-sm,
.input-group-sm .select2-container--bootstrap .select2-selection--single,
.form-group-sm .select2-container--bootstrap .select2-selection--single {
border-radius: 3px;
font-size: 12px;
height: 30px;
line-height: 1.5;
padding: 5px 22px 5px 10px;
/* 2 */
}
.select2-container--bootstrap .select2-selection--single.input-sm .select2-selection__arrow b,
.input-group-sm .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b,
.form-group-sm .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b {
margin-left: -5px;
}
.select2-container--bootstrap .select2-selection--multiple.input-sm,
.input-group-sm .select2-container--bootstrap .select2-selection--multiple,
.form-group-sm .select2-container--bootstrap .select2-selection--multiple {
min-height: 30px;
border-radius: 3px;
}
.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-selection__choice,
.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice,
.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice {
font-size: 12px;
line-height: 1.5;
margin: 4px 0 0 5px;
padding: 0 5px;
}
.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-search--inline .select2-search__field,
.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field,
.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field {
padding: 0 10px;
font-size: 12px;
height: 28px;
line-height: 1.5;
}
.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-selection__clear,
.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear,
.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear {
margin-top: 5px;
}
.select2-container--bootstrap .select2-selection--single.input-lg,
.input-group-lg .select2-container--bootstrap .select2-selection--single,
.form-group-lg .select2-container--bootstrap .select2-selection--single {
border-radius: 6px;
font-size: 18px;
height: 46px;
line-height: 1.3333333;
padding: 10px 31px 10px 16px;
/* 1 */
}
.select2-container--bootstrap .select2-selection--single.input-lg .select2-selection__arrow,
.input-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow,
.form-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow {
width: 5px;
}
.select2-container--bootstrap .select2-selection--single.input-lg .select2-selection__arrow b,
.input-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b,
.form-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b {
border-width: 5px 5px 0 5px;
margin-left: -5px;
margin-left: -10px;
margin-top: -2.5px;
}
.select2-container--bootstrap .select2-selection--multiple.input-lg,
.input-group-lg .select2-container--bootstrap .select2-selection--multiple,
.form-group-lg .select2-container--bootstrap .select2-selection--multiple {
min-height: 46px;
border-radius: 6px;
}
.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-selection__choice,
.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice,
.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice {
font-size: 18px;
line-height: 1.3333333;
border-radius: 4px;
margin: 9px 0 0 8px;
padding: 0 10px;
}
.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-search--inline .select2-search__field,
.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field,
.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field {
padding: 0 16px;
font-size: 18px;
height: 44px;
line-height: 1.3333333;
}
.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-selection__clear,
.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear,
.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear {
margin-top: 10px;
}
.select2-container--bootstrap .select2-selection.input-lg.select2-container--open .select2-selection--single {
/**
* Make the dropdown arrow point up while the dropdown is visible.
*/
}
.select2-container--bootstrap .select2-selection.input-lg.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #999 transparent;
border-width: 0 5px 5px 5px;
}
.input-group-lg .select2-container--bootstrap .select2-selection.select2-container--open .select2-selection--single {
/**
* Make the dropdown arrow point up while the dropdown is visible.
*/
}
.input-group-lg .select2-container--bootstrap .select2-selection.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #999 transparent;
border-width: 0 5px 5px 5px;
}
.select2-container--bootstrap[dir="rtl"] {
/**
* Single Select2
*
* 1. Makes sure that .select2-selection__placeholder is positioned
* correctly.
*/
/**
* Multiple Select2
*/
}
.select2-container--bootstrap[dir="rtl"] .select2-selection--single {
padding-left: 24px;
padding-right: 12px;
}
.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__rendered {
padding-right: 0;
padding-left: 0;
text-align: right;
/* 1 */
}
.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left;
}
.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 12px;
right: auto;
}
.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__arrow b {
margin-left: 0;
}
.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice,
.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,
.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right;
}
.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 0;
margin-right: 6px;
}
.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto;
}
/*------------------------------------* #ADDITIONAL GOODIES
\*------------------------------------*/
/**
* Address Bootstrap's validation states
*
* If a Select2 widget parent has one of Bootstrap's validation state modifier
* classes, adjust Select2's border colors and focus states accordingly.
* You may apply said classes to the Select2 dropdown (body > .select2-container)
* via JavaScript match Bootstraps' to make its styles match.
*
* @see http://getbootstrap.com/css/#forms-control-validation
*/
.has-warning .select2-dropdown,
.has-warning .select2-selection {
border-color: #8a6d3b;
}
.has-warning .select2-container--focus .select2-selection,
.has-warning .select2-container--open .select2-selection {
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
border-color: #66512c;
}
.has-warning.select2-drop-active {
border-color: #66512c;
}
.has-warning.select2-drop-active.select2-drop.select2-drop-above {
border-top-color: #66512c;
}
.has-error .select2-dropdown,
.has-error .select2-selection {
border-color: #a94442;
}
.has-error .select2-container--focus .select2-selection,
.has-error .select2-container--open .select2-selection {
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
border-color: #843534;
}
.has-error.select2-drop-active {
border-color: #843534;
}
.has-error.select2-drop-active.select2-drop.select2-drop-above {
border-top-color: #843534;
}
.has-success .select2-dropdown,
.has-success .select2-selection {
border-color: #3c763d;
}
.has-success .select2-container--focus .select2-selection,
.has-success .select2-container--open .select2-selection {
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
border-color: #2b542c;
}
.has-success.select2-drop-active {
border-color: #2b542c;
}
.has-success.select2-drop-active.select2-drop.select2-drop-above {
border-top-color: #2b542c;
}
/**
* Select2 widgets in Bootstrap Input Groups
*
* @see http://getbootstrap.com/components/#input-groups
* @see https://github.com/twbs/bootstrap/blob/master/less/input-groups.less
*/
/**
* Reset rounded corners
*/
.input-group > .select2-hidden-accessible:first-child + .select2-container--bootstrap > .selection > .select2-selection,
.input-group > .select2-hidden-accessible:first-child + .select2-container--bootstrap > .selection > .select2-selection.form-control {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.input-group > .select2-hidden-accessible:not(:first-child) + .select2-container--bootstrap:not(:last-child) > .selection > .select2-selection,
.input-group > .select2-hidden-accessible:not(:first-child) + .select2-container--bootstrap:not(:last-child) > .selection > .select2-selection.form-control {
border-radius: 0;
}
.input-group > .select2-hidden-accessible:not(:first-child):not(:last-child) + .select2-container--bootstrap:last-child > .selection > .select2-selection,
.input-group > .select2-hidden-accessible:not(:first-child):not(:last-child) + .select2-container--bootstrap:last-child > .selection > .select2-selection.form-control {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
.input-group > .select2-container--bootstrap {
display: table;
table-layout: fixed;
position: relative;
z-index: 2;
width: 100%;
margin-bottom: 0;
/**
* Adjust z-index like Bootstrap does to show the focus-box-shadow
* above appended buttons in .input-group and .form-group.
*/
/**
* Adjust alignment of Bootstrap buttons in Bootstrap Input Groups to address
* Multi Select2's height which - depending on how many elements have been selected -
* may grow taller than its initial size.
*
* @see http://getbootstrap.com/components/#input-groups
*/
}
.input-group > .select2-container--bootstrap > .selection > .select2-selection.form-control {
float: none;
}
.input-group > .select2-container--bootstrap.select2-container--open, .input-group > .select2-container--bootstrap.select2-container--focus {
z-index: 3;
}
.input-group > .select2-container--bootstrap,
.input-group > .select2-container--bootstrap .input-group-btn,
.input-group > .select2-container--bootstrap .input-group-btn .btn {
vertical-align: top;
}
/**
* Temporary fix for https://github.com/select2/select2-bootstrap-theme/issues/9
*
* Provides `!important` for certain properties of the class applied to the
* original `<select>` element to hide it.
*
* @see https://github.com/select2/select2/pull/3301
* @see https://github.com/fk/select2/commit/31830c7b32cb3d8e1b12d5b434dee40a6e753ada
*/
.form-control.select2-hidden-accessible {
position: absolute !important;
width: 1px !important;
}
/**
* Display override for inline forms
*/
@media (min-width: 768px) {
.form-inline .select2-container--bootstrap {
display: inline-block;
}
}

1
cookbook/static/css/select2.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
$(document).ready(function () {
$('.multiselectwidget').select2();
});

View File

@@ -0,0 +1,3 @@
$(document).ready(function () {
$('.selectwidget').select2();
});

File diff suppressed because one or more lines are too long

View File

@@ -35,7 +35,7 @@
// process response
if (xhr.readyState == 4 && xhr.status == 201) {
// parse JSON data
window.open(redirect.concat('?bookmarklet_import=', JSON.parse(xhr.response).id) )
window.open(redirect.concat('?id=', JSON.parse(xhr.response).id) )
} else {
console.error('Error!');
}

1
cookbook/static/js/js.cookie.min.js vendored Normal file
View File

@@ -0,0 +1 @@
!function(e){var n;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var t=window.Cookies,o=window.Cookies=e();o.noConflict=function(){return window.Cookies=t,o}}}(function(){function f(){for(var e=0,n={};e<arguments.length;e++){var t=arguments[e];for(var o in t)n[o]=t[o]}return n}function a(e){return e.replace(/(%[0-9A-Z]{2})+/g,decodeURIComponent)}return function e(u){function c(){}function t(e,n,t){if("undefined"!=typeof document){"number"==typeof(t=f({path:"/"},c.defaults,t)).expires&&(t.expires=new Date(1*new Date+864e5*t.expires)),t.expires=t.expires?t.expires.toUTCString():"";try{var o=JSON.stringify(n);/^[\{\[]/.test(o)&&(n=o)}catch(e){}n=u.write?u.write(n,e):encodeURIComponent(String(n)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),e=encodeURIComponent(String(e)).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent).replace(/[\(\)]/g,escape);var r="";for(var i in t)t[i]&&(r+="; "+i,!0!==t[i]&&(r+="="+t[i].split(";")[0]));return document.cookie=e+"="+n+r}}function n(e,n){if("undefined"!=typeof document){for(var t={},o=document.cookie?document.cookie.split("; "):[],r=0;r<o.length;r++){var i=o[r].split("="),c=i.slice(1).join("=");n||'"'!==c.charAt(0)||(c=c.slice(1,-1));try{var f=a(i[0]);if(c=(u.read||u)(c,f)||a(c),n)try{c=JSON.parse(c)}catch(e){}if(t[f]=c,e===f)break}catch(e){}}return e?t[e]:t}}return c.set=t,c.get=function(e){return n(e,!1)},c.getJSON=function(e){return n(e,!0)},c.remove=function(e,n){t(e,"",f(n,{expires:-1}))},c.defaults={},c.withConverter=e,c}(function(){})});

View File

@@ -0,0 +1 @@
{"version":3,"sources":["js.cookie.js"],"names":["factory","registeredInModuleLoader","define","amd","exports","module","OldCookies","window","Cookies","api","noConflict","extend","i","result","arguments","length","attributes","key","decode","s","replace","decodeURIComponent","init","converter","set","value","document","path","defaults","expires","Date","toUTCString","JSON","stringify","test","e","write","encodeURIComponent","String","escape","stringifiedAttributes","attributeName","split","cookie","get","json","jar","cookies","parts","slice","join","charAt","name","read","parse","getJSON","remove","withConverter"],"mappings":"CAOE,SAAUA,GACX,IAAIC,EASJ,GARsB,mBAAXC,QAAyBA,OAAOC,MAC1CD,OAAOF,GACPC,GAA2B,GAEL,iBAAZG,UACVC,OAAOD,QAAUJ,IACjBC,GAA2B,IAEvBA,EAA0B,CAC9B,IAAIK,EAAaC,OAAOC,QACpBC,EAAMF,OAAOC,QAAUR,IAC3BS,EAAIC,WAAa,WAEhB,OADAH,OAAOC,QAAUF,EACVG,IAfT,CAkBC,WACD,SAASE,IAGR,IAFA,IAAIC,EAAI,EACJC,EAAS,GACND,EAAIE,UAAUC,OAAQH,IAAK,CACjC,IAAII,EAAaF,UAAWF,GAC5B,IAAK,IAAIK,KAAOD,EACfH,EAAOI,GAAOD,EAAWC,GAG3B,OAAOJ,EAGR,SAASK,EAAQC,GAChB,OAAOA,EAAEC,QAAQ,mBAAoBC,oBA0HtC,OAvHA,SAASC,EAAMC,GACd,SAASd,KAET,SAASe,EAAKP,EAAKQ,EAAOT,GACzB,GAAwB,oBAAbU,SAAX,CAQkC,iBAJlCV,EAAaL,EAAO,CACnBgB,KAAM,KACJlB,EAAImB,SAAUZ,IAEKa,UACrBb,EAAWa,QAAU,IAAIC,KAAkB,EAAb,IAAIA,KAAkC,MAArBd,EAAWa,UAI3Db,EAAWa,QAAUb,EAAWa,QAAUb,EAAWa,QAAQE,cAAgB,GAE7E,IACC,IAAIlB,EAASmB,KAAKC,UAAUR,GACxB,UAAUS,KAAKrB,KAClBY,EAAQZ,GAER,MAAOsB,IAETV,EAAQF,EAAUa,MACjBb,EAAUa,MAAMX,EAAOR,GACvBoB,mBAAmBC,OAAOb,IACxBL,QAAQ,4DAA6DC,oBAExEJ,EAAMoB,mBAAmBC,OAAOrB,IAC9BG,QAAQ,2BAA4BC,oBACpCD,QAAQ,UAAWmB,QAErB,IAAIC,EAAwB,GAC5B,IAAK,IAAIC,KAAiBzB,EACpBA,EAAWyB,KAGhBD,GAAyB,KAAOC,GACE,IAA9BzB,EAAWyB,KAWfD,GAAyB,IAAMxB,EAAWyB,GAAeC,MAAM,KAAK,KAGrE,OAAQhB,SAASiB,OAAS1B,EAAM,IAAMQ,EAAQe,GAG/C,SAASI,EAAK3B,EAAK4B,GAClB,GAAwB,oBAAbnB,SAAX,CAUA,IANA,IAAIoB,EAAM,GAGNC,EAAUrB,SAASiB,OAASjB,SAASiB,OAAOD,MAAM,MAAQ,GAC1D9B,EAAI,EAEDA,EAAImC,EAAQhC,OAAQH,IAAK,CAC/B,IAAIoC,EAAQD,EAAQnC,GAAG8B,MAAM,KACzBC,EAASK,EAAMC,MAAM,GAAGC,KAAK,KAE5BL,GAA6B,MAArBF,EAAOQ,OAAO,KAC1BR,EAASA,EAAOM,MAAM,GAAI,IAG3B,IACC,IAAIG,EAAOlC,EAAO8B,EAAM,IAIxB,GAHAL,GAAUpB,EAAU8B,MAAQ9B,GAAWoB,EAAQS,IAC9ClC,EAAOyB,GAEJE,EACH,IACCF,EAASX,KAAKsB,MAAMX,GACnB,MAAOR,IAKV,GAFAW,EAAIM,GAAQT,EAER1B,IAAQmC,EACX,MAEA,MAAOjB,KAGV,OAAOlB,EAAM6B,EAAI7B,GAAO6B,GAoBzB,OAjBArC,EAAIe,IAAMA,EACVf,EAAImC,IAAM,SAAU3B,GACnB,OAAO2B,EAAI3B,GAAK,IAEjBR,EAAI8C,QAAU,SAAUtC,GACvB,OAAO2B,EAAI3B,GAAK,IAEjBR,EAAI+C,OAAS,SAAUvC,EAAKD,GAC3BQ,EAAIP,EAAK,GAAIN,EAAOK,EAAY,CAC/Ba,SAAU,MAIZpB,EAAImB,SAAW,GAEfnB,EAAIgD,cAAgBnC,EAEbb,EAGDa,CAAK"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
cookbook/static/js/select2.min.js vendored Normal file

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More