Files
depenses_trello/app.py

259 lines
8.1 KiB
Python

#!/usr/bin/env python3
from flask import Flask, request, jsonify, redirect
import json
import os
import requests
app = Flask(__name__)
CONFIG_FILE = '/home/h3r7/depenses_trello/config.json'
def load_config():
with open(CONFIG_FILE, 'r') as f:
return json.load(f)
def save_config(data):
with open(CONFIG_FILE, 'w') as f:
json.dump(data, f, indent=2)
def parse_date(d):
if not d: return ""
if "/" in d:
parts = d.split("/")
if len(parts) == 3:
return f"{parts[2]}-{parts[1]}-{parts[0]}"
return d
@app.route('/')
def index():
with open('/home/h3r7/depenses_trello/templates/index.html', 'r') as f:
return f.read()
# API Config
@app.route('/api/config')
def get_config():
return jsonify(load_config())
# Add depense
@app.route('/api/add', methods=['POST'])
def add_depense():
config = load_config()
data = {
'id': len(config.get('depenses', [])) + 1,
'prenom': request.form.get('prenom'),
'date': parse_date(request.form.get('date', '')),
'libelle': request.form.get('libelle'),
'montant': float(request.form.get('montant', 0)),
'status': 'En attente'
}
if 'depenses' not in config:
config['depenses'] = []
config['depenses'].append(data)
save_config(config)
return redirect('/?page=saisie')
# Get depenses
@app.route('/api/depenses')
def get_depenses():
config = load_config()
return jsonify(config.get('depenses', []))
# Delete depense
@app.route('/api/del/<int:id>')
def delete_depense(id):
config = load_config()
config['depenses'] = [d for d in config.get('depenses', []) if d.get('id') != id]
save_config(config)
return redirect('/?page=saisie')
# Clear all
@app.route('/api/clear', methods=['POST'])
def clear_depenses():
config = load_config()
config['depenses'] = []
save_config(config)
return jsonify({'success': True})
# Generate text for ONE expense
@app.route('/api/generate_one/<int:id>', methods=['GET'])
def generate_one(id):
config = load_config()
d = None
for exp in config.get('depenses', []):
if exp.get('id') == id:
d = exp
break
if not d:
return jsonify({'text': ''})
template = config.get('format', '{prenom} - {date} - {libelle} - {montant}')
line = template
ddate = d.get('date', '') or ''
if ddate:
ddate = '/'.join(ddate.split('-')[::-1])
line = line.replace('{prenom}', d.get('prenom', ''))
line = line.replace('{date}', ddate)
line = line.replace('{libelle}', d.get('libelle', ''))
line = line.replace('{montant}', str(d.get('montant', 0)))
return jsonify({'text': line})
# Send to Trello - ONE card per pending expense
@app.route('/api/trello/send_one/<int:id>', methods=['POST'])
def send_one(id):
config = load_config()
t = config.get('trello', {})
if not t.get('api_key') or not t.get('token') or not t.get('list_id'):
return jsonify({'error': 'Config Trello manquante'}), 400
# Find the expense
d = None
for exp in config.get('depenses', []):
if exp.get('id') == id:
d = exp
break
if not d:
return jsonify({'error': 'Dépense non trouvée'}), 404
# Skip if already sent
if d.get('status') == 'Envoyé ✅':
return jsonify({'error': 'Déjà envoyé'}), 400
# Generate text
template = config.get('format', '{prenom} - {date} - {libelle} - {montant}')
line = template
ddate = d.get('date', '') or ''
if ddate:
ddate = '/'.join(ddate.split('-')[::-1])
line = line.replace('{prenom}', d.get('prenom', ''))
line = line.replace('{date}', ddate)
line = line.replace('{libelle}', d.get('libelle', ''))
line = line.replace('{montant}', str(d.get('montant', 0)))
# Send to Trello
url = 'https://api.trello.com/1/cards'
params = {
'key': t.get('api_key'),
'token': t.get('token'),
'idList': t.get('list_id'),
'name': line,
'desc': line
}
try:
r = requests.post(url, params=params)
if r.status_code == 200:
# Mark as sent
for exp in config.get('depenses', []):
if exp.get('id') == id:
exp['status'] = 'Envoyé ✅'
save_config(config)
return jsonify({'success': True})
return jsonify({'error': r.text}), r.status_code
except Exception as e:
return jsonify({'error': str(e)}), 500
# Legacy - send all (for compatibility)
@app.route('/api/trello/send', methods=['POST'])
def send_trello():
config = load_config()
t = config.get('trello', {})
if not t.get('api_key') or not t.get('token') or not t.get('list_id'):
return jsonify({'error': 'Config Trello manquante'}), 400
# Send only pending expenses
sent_count = 0
for d in config.get('depenses', []):
if d.get('status') == 'En attente':
# Generate text
template = config.get('format', '{prenom} - {date} - {libelle} - {montant}')
line = template
ddate = d.get('date', '') or ''
if ddate:
ddate = '/'.join(ddate.split('-')[::-1])
line = line.replace('{prenom}', d.get('prenom', ''))
line = line.replace('{date}', ddate)
line = line.replace('{libelle}', d.get('libelle', ''))
line = line.replace('{montant}', str(d.get('montant', 0)))
# Send to Trello
url = 'https://api.trello.com/1/cards'
params = {
'key': t.get('api_key'),
'token': t.get('token'),
'idList': t.get('list_id'),
'name': line,
'desc': line
}
try:
r = requests.post(url, params=params)
if r.status_code == 200:
d['status'] = 'Envoyé ✅'
sent_count += 1
except:
pass
save_config(config)
return jsonify({'success': True, 'sent': sent_count})
# Generate text (all)
@app.route('/api/generate', methods=['POST'])
def generate_text():
config = load_config()
data = request.json
template = config.get('format', '{prenom} - {date} - {libelle} - {montant}')
lines = []
for d in data.get('depenses', []):
line = template
ddate = d.get('date', '') or ''
if ddate:
ddate = '/'.join(ddate.split('-')[::-1])
line = line.replace('{prenom}', d.get('prenom', ''))
line = line.replace('{date}', ddate)
line = line.replace('{libelle}', d.get('libelle', ''))
line = line.replace('{montant}', str(d.get('montant', 0)))
lines.append(line)
return jsonify({'text': '\n'.join(lines)})
# Add prenom
@app.route('/api/prenom/add', methods=['POST'])
def add_prenom():
config = load_config()
prenom = request.form.get('prenom', '').strip()
if prenom and prenom not in config.get('prenoms', []):
if 'prenoms' not in config:
config['prenoms'] = []
config['prenoms'].append(prenom)
save_config(config)
return redirect('/?page=config')
# Del prenom
@app.route('/api/prenom/del/<int:idx>')
def del_prenom(idx):
config = load_config()
if 0 <= idx < len(config.get('prenoms', [])):
config['prenoms'].pop(idx)
save_config(config)
return redirect('/?page=config')
# Save format
@app.route('/api/format', methods=['POST'])
def save_format():
config = load_config()
config['format'] = request.form.get('format', '{prenom} - {date} - {libelle} - {montant}')
save_config(config)
return redirect('/?page=config')
# Save trello config
@app.route('/api/trello/save', methods=['POST'])
def save_trello():
config = load_config()
config['trello'] = {
'api_key': request.form.get('api_key', ''),
'token': request.form.get('token', ''),
'list_id': request.form.get('list_id', '')
}
save_config(config)
return redirect('/?page=config')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8769, debug=False)