feat: Tandoor integration — settings, test connection, import, duplicate detection
Add TandoorClient (app/tandoor.py) with full recipe creation, image upload, and duplicate detection via the Tandoor REST API. Settings page now has separate Mealie and Tandoor sections. Import page shows both send buttons based on which services are configured. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+67
-12
@@ -2,9 +2,10 @@
|
||||
{% block title %}Beállítások — Recept Importáló{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<h2>Mealie kapcsolat</h2>
|
||||
<form method="POST" action="/settings">
|
||||
<form method="POST" action="/settings">
|
||||
<div class="card">
|
||||
<h2>Mealie kapcsolat</h2>
|
||||
|
||||
<label for="mealie_url">Mealie URL</label>
|
||||
<input type="url" id="mealie_url" name="mealie_url"
|
||||
value="{{ cfg.mealie_url }}"
|
||||
@@ -20,26 +21,56 @@
|
||||
</p>
|
||||
|
||||
<div class="flex">
|
||||
<button type="submit" class="btn btn-primary">Mentés</button>
|
||||
<button type="button" class="btn btn-secondary" id="testBtn" onclick="testConnection()">
|
||||
<button type="button" class="btn btn-secondary" id="testMealieBtn" onclick="testMealie()">
|
||||
Kapcsolat tesztelése
|
||||
</button>
|
||||
<span id="testResult"></span>
|
||||
<span id="testMealieResult"></span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Tandoor kapcsolat</h2>
|
||||
|
||||
<label for="tandoor_url">Tandoor URL</label>
|
||||
<input type="url" id="tandoor_url" name="tandoor_url"
|
||||
value="{{ cfg.tandoor_url }}"
|
||||
placeholder="https://recipes.example.com">
|
||||
|
||||
<label for="tandoor_api_key">API kulcs</label>
|
||||
<input type="password" id="tandoor_api_key" name="tandoor_api_key"
|
||||
value="{{ cfg.tandoor_api_key }}"
|
||||
placeholder="Tandoor API token">
|
||||
<p class="text-dim mb-2" style="font-size:0.85rem;">
|
||||
Az API kulcsot a Tandoor-ban itt hozhatod létre:
|
||||
<em>Settings → API Browser → Auth Token</em>
|
||||
</p>
|
||||
|
||||
<div class="flex">
|
||||
<button type="button" class="btn btn-secondary" id="testTandoorBtn" onclick="testTandoor()">
|
||||
Kapcsolat tesztelése
|
||||
</button>
|
||||
<span id="testTandoorResult"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<button type="submit" class="btn btn-primary">Mentés</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
async function testConnection() {
|
||||
const btn = document.getElementById('testBtn');
|
||||
const result = document.getElementById('testResult');
|
||||
async function testMealie() {
|
||||
const btn = document.getElementById('testMealieBtn');
|
||||
const result = document.getElementById('testMealieResult');
|
||||
btn.disabled = true;
|
||||
result.innerHTML = '<span class="spinner"></span>';
|
||||
|
||||
try {
|
||||
const form = new FormData(document.querySelector('form'));
|
||||
const form = new FormData();
|
||||
form.append('mealie_url', document.getElementById('mealie_url').value);
|
||||
form.append('mealie_api_key', document.getElementById('mealie_api_key').value);
|
||||
const resp = await fetch('/settings/test', { method: 'POST', body: form });
|
||||
const data = await resp.json();
|
||||
if (data.ok) {
|
||||
@@ -53,5 +84,29 @@ async function testConnection() {
|
||||
}
|
||||
btn.disabled = false;
|
||||
}
|
||||
|
||||
async function testTandoor() {
|
||||
const btn = document.getElementById('testTandoorBtn');
|
||||
const result = document.getElementById('testTandoorResult');
|
||||
btn.disabled = true;
|
||||
result.innerHTML = '<span class="spinner"></span>';
|
||||
|
||||
try {
|
||||
const form = new FormData();
|
||||
form.append('tandoor_url', document.getElementById('tandoor_url').value);
|
||||
form.append('tandoor_api_key', document.getElementById('tandoor_api_key').value);
|
||||
const resp = await fetch('/settings/test-tandoor', { method: 'POST', body: form });
|
||||
const data = await resp.json();
|
||||
if (data.ok) {
|
||||
const v = data.data.version || '?';
|
||||
result.innerHTML = '<span class="text-success">✓ Kapcsolódva (Tandoor v' + v + ')</span>';
|
||||
} else {
|
||||
result.innerHTML = '<span class="text-danger">✗ ' + data.error + '</span>';
|
||||
}
|
||||
} catch (e) {
|
||||
result.innerHTML = '<span class="text-danger">✗ Hálózati hiba</span>';
|
||||
}
|
||||
btn.disabled = false;
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user