241 lines
7.7 KiB
Python
Executable File
241 lines
7.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Phone Refurb CLI - Gestion du stock de téléphones
|
|
Usage: ./phone-cli <command> [args]
|
|
"""
|
|
|
|
import sqlite3
|
|
import sys
|
|
import os
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
DB_PATH = Path(__file__).parent / "phones.db"
|
|
|
|
def get_conn():
|
|
return sqlite3.connect(DB_PATH)
|
|
|
|
def cmd_add(brand, model, model_code, imei=None, serial=None, status="stock", notes=None):
|
|
"""Ajouter un téléphone"""
|
|
conn = get_conn()
|
|
c = conn.cursor()
|
|
c.execute("""
|
|
INSERT INTO phones (brand, model, model_code, imei, serial, status, notes)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
""", (brand, model, model_code, imei, serial, status, notes))
|
|
conn.commit()
|
|
print(f"✅ Téléphone ajouté (ID: {c.lastrowid})")
|
|
conn.close()
|
|
|
|
def cmd_list(status=None):
|
|
"""Lister les téléphones"""
|
|
conn = get_conn()
|
|
c = conn.cursor()
|
|
if status:
|
|
c.execute("SELECT * FROM phone_summary WHERE status = ?", (status,))
|
|
else:
|
|
c.execute("SELECT * FROM phone_summary")
|
|
rows = c.fetchall()
|
|
conn.close()
|
|
|
|
if not rows:
|
|
print("Aucun téléphone trouvé")
|
|
return
|
|
|
|
print(f"{'ID':<4} {'Marque':<10} {'Modèle':<20} {'Code':<15} {'Statut':<10} {'OS':<10} {'Root':<5}")
|
|
print("-" * 80)
|
|
for r in rows:
|
|
print(f"{r[0]:<4} {r[1]:<10} {r[2]:<20} {r[3] or '':<15} {r[4]:<10} {r[5] or '':<10} {'✓' if r[7] else '✗':<5}")
|
|
|
|
def cmd_info(phone_id):
|
|
"""Détails d'un téléphone"""
|
|
conn = get_conn()
|
|
c = conn.cursor()
|
|
|
|
# Infos de base
|
|
c.execute("SELECT * FROM phones WHERE id = ?", (phone_id,))
|
|
phone = c.fetchone()
|
|
if not phone:
|
|
print(f"❌ Téléphone {phone_id} non trouvé")
|
|
conn.close()
|
|
return
|
|
|
|
print(f"\n📱 {phone[1]} {phone[2]} ({phone[3]})")
|
|
print(f" IMEI: {phone[4] or 'N/A'}")
|
|
print(f" Serial: {phone[5] or 'N/A'}")
|
|
print(f" Statut: {phone[6]}")
|
|
print(f" Notes: {phone[7] or 'Aucune'}")
|
|
|
|
# Specs
|
|
c.execute("SELECT * FROM phone_specs WHERE phone_id = ?", (phone_id,))
|
|
specs = c.fetchone()
|
|
if specs:
|
|
print(f"\n🔧 Specs:")
|
|
print(f" CPU: {specs[2] or 'N/A'}")
|
|
print(f" RAM: {specs[4]} Mo" if specs[4] else "")
|
|
print(f" Stockage: {specs[5]} Go" if specs[5] else "")
|
|
print(f" Écran: {specs[6] or 'N/A'}")
|
|
print(f" Batterie: {specs[8]} mAh" if specs[8] else "")
|
|
|
|
# Software
|
|
c.execute("SELECT * FROM software_state WHERE phone_id = ? ORDER BY date_recorded DESC LIMIT 1", (phone_id,))
|
|
sw = c.fetchone()
|
|
if sw:
|
|
print(f"\n💾 Logiciel:")
|
|
print(f" OS: {sw[2]} {sw[3] or ''}")
|
|
print(f" SDK: {sw[4] or 'N/A'}")
|
|
print(f" Kernel: {sw[5] or 'N/A'}")
|
|
print(f" Bootloader: {'🔒 Verrouillé' if sw[6] else '🔓 Déverrouillé'}")
|
|
print(f" Root: {'✓' if sw[7] else '✗'}")
|
|
print(f" Recovery: {sw[8] or 'Stock'}")
|
|
|
|
# Actions
|
|
c.execute("SELECT action_type, action_date, status, notes FROM actions WHERE phone_id = ? ORDER BY action_date DESC LIMIT 10", (phone_id,))
|
|
actions = c.fetchall()
|
|
if actions:
|
|
print(f"\n📋 Actions récentes:")
|
|
for a in actions:
|
|
status_icon = "✅" if a[2] == "success" else "⚠️" if a[2] == "partial" else "❌"
|
|
print(f" {status_icon} {a[0]} ({a[1][:10]})")
|
|
if a[3]:
|
|
print(f" {a[3][:50]}")
|
|
|
|
conn.close()
|
|
|
|
def cmd_action(phone_id, action_type, status="success", notes=None, rom_id=None):
|
|
"""Ajouter une action"""
|
|
conn = get_conn()
|
|
c = conn.cursor()
|
|
c.execute("""
|
|
INSERT INTO actions (phone_id, action_type, status, notes, rom_id)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
""", (phone_id, action_type, status, notes, rom_id))
|
|
conn.commit()
|
|
|
|
# Update phone timestamp
|
|
c.execute("UPDATE phones SET updated_at = CURRENT_TIMESTAMP WHERE id = ?", (phone_id,))
|
|
conn.commit()
|
|
|
|
print(f"✅ Action '{action_type}' ajoutée")
|
|
conn.close()
|
|
|
|
def cmd_update_status(phone_id, status):
|
|
"""Changer le statut d'un téléphone"""
|
|
conn = get_conn()
|
|
c = conn.cursor()
|
|
c.execute("UPDATE phones SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?", (status, phone_id))
|
|
conn.commit()
|
|
print(f"✅ Statut mis à jour: {status}")
|
|
conn.close()
|
|
|
|
def cmd_roms(device_code=None):
|
|
"""Lister les ROMs disponibles"""
|
|
conn = get_conn()
|
|
c = conn.cursor()
|
|
if device_code:
|
|
c.execute("SELECT id, name, version, android_version, file_size_mb FROM roms WHERE device_code = ?", (device_code,))
|
|
else:
|
|
c.execute("SELECT id, name, version, android_version, device_code, file_size_mb FROM roms")
|
|
rows = c.fetchall()
|
|
conn.close()
|
|
|
|
print(f"{'ID':<4} {'ROM':<20} {'Version':<25} {'Android':<10} {'Device':<15} {'Size':<10}")
|
|
print("-" * 90)
|
|
for r in rows:
|
|
if device_code:
|
|
print(f"{r[0]:<4} {r[1]:<20} {r[2] or '':<25} {r[3] or '':<10} {r[4]}M")
|
|
else:
|
|
print(f"{r[0]:<4} {r[1]:<20} {r[2] or '':<25} {r[3] or '':<10} {r[4]:<15} {r[5]}M")
|
|
|
|
def cmd_search(query):
|
|
"""Rechercher un téléphone"""
|
|
conn = get_conn()
|
|
c = conn.cursor()
|
|
c.execute("""
|
|
SELECT * FROM phone_summary
|
|
WHERE brand LIKE ? OR model LIKE ? OR model_code LIKE ? OR status LIKE ?
|
|
""", (f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%"))
|
|
rows = c.fetchall()
|
|
conn.close()
|
|
|
|
if not rows:
|
|
print("Aucun résultat")
|
|
return
|
|
|
|
print(f"{'ID':<4} {'Marque':<10} {'Modèle':<20} {'Code':<15} {'Statut':<10}")
|
|
print("-" * 60)
|
|
for r in rows:
|
|
print(f"{r[0]:<4} {r[1]:<10} {r[2]:<20} {r[3] or '':<15} {r[4]:<10}")
|
|
|
|
def print_help():
|
|
print("""
|
|
Phone Refurb CLI - Gestion du stock de téléphones
|
|
|
|
Usage: ./phone-cli <command> [args]
|
|
|
|
Commands:
|
|
add <brand> <model> <model_code> [imei] [serial] [status] [notes]
|
|
Ajouter un nouveau téléphone
|
|
|
|
list [status]
|
|
Lister les téléphones (filtrer par statut: stock, paused, sold, etc.)
|
|
|
|
info <phone_id>
|
|
Détails complets d'un téléphone
|
|
|
|
action <phone_id> <action_type> [status] [notes]
|
|
Ajouter une action (status: success, partial, failed)
|
|
|
|
status <phone_id> <status>
|
|
Changer le statut d'un téléphone
|
|
|
|
roms [device_code]
|
|
Lister les ROMs disponibles
|
|
|
|
search <query>
|
|
Rechercher un téléphone
|
|
|
|
Examples:
|
|
./phone-cli add Samsung "Galaxy S7" SM-G930F
|
|
./phone-cli list stock
|
|
./phone-cli info 1
|
|
./phone-cli action 1 flash_rom success "LineageOS 18.1 installée"
|
|
./phone-cli status 1 ready
|
|
./phone-cli roms j5xnlte
|
|
./phone-cli search samsung
|
|
""")
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print_help()
|
|
return
|
|
|
|
cmd = sys.argv[1]
|
|
|
|
try:
|
|
if cmd == "add":
|
|
args = sys.argv[2:]
|
|
cmd_add(*args[:7] if len(args) >= 3 else (print("Usage: add <brand> <model> <model_code>"), sys.exit(1)))
|
|
elif cmd == "list":
|
|
cmd_list(sys.argv[2] if len(sys.argv) > 2 else None)
|
|
elif cmd == "info":
|
|
cmd_info(int(sys.argv[2]))
|
|
elif cmd == "action":
|
|
args = sys.argv[2:]
|
|
cmd_action(int(args[0]), args[1], args[2] if len(args) > 2 else "success", args[3] if len(args) > 3 else None)
|
|
elif cmd == "status":
|
|
cmd_update_status(int(sys.argv[2]), sys.argv[3])
|
|
elif cmd == "roms":
|
|
cmd_roms(sys.argv[2] if len(sys.argv) > 2 else None)
|
|
elif cmd == "search":
|
|
cmd_search(sys.argv[2])
|
|
elif cmd in ["help", "-h", "--help"]:
|
|
print_help()
|
|
else:
|
|
print(f"Commande inconnue: {cmd}")
|
|
print_help()
|
|
except Exception as e:
|
|
print(f"❌ Erreur: {e}")
|
|
|
|
if __name__ == "__main__":
|
|
main() |