WallpaperMachine
당신이 사랑하는 배경화면, 맥에서 새롭게 만나보세요
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Site de suivi budget et workflow de montage pour le projet PC Full White d'AntoniMan31.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Site de suivi du budget et du montage du PC Full White d'AntoniMan31, consultable depuis un téléphone. En ligne : https://antoniman31.github.io/pc-full-white/
HTML, CSS et JS sans framework · Python (relevé des prix) · GitHub Actions et Pages.
data/prices.json est la seule source de vérité : prix, statuts, checklists, historique. Rien n'est codé en dur dans la page.main.revendeurs ──► relevé (Actions, 1er et 15) ──► PR « prix » ──┐
├─► fusion ──► data/prices.json ──► GitHub Pages ──► site
navigateur ──► « Envoyer » ──► PR site-changes/… ────────────┘
(achats, prix saisis) (data/changes.json)
Navigation. Barre du bas sous 600 px ; dès 600 px, barre latérale avec icônes, sous-onglets avec icônes et texte 10 % plus grand. Les sous-onglets se parcourent aussi au swipe.
Thèmes. Réglages ou icône en haut de page. En Auto, le thème suit le système. L'impression repasse toujours en clair.
Fraîcheur d'un prix. Une alerte ambre « à vérifier » apparaît si le prix a plus de 7 jours ou repose sur une seule boutique (IKEA, seul vendeur de ses produits, est exclu de cette règle).
Envoyer ses changements. Achats, prix saisis, produits modifiés, articles ajoutés ou supprimés :
site-changes/…, y écrit data/changes.json et ouvre la PR. Un envoi suivant met à jour la même PR tant qu'elle est ouverte..github/workflows/site-changes.yml applique changes.json à prices.json (scripts/apply_changes.py), contrôle la cohérence et commit le résultat. Il remet aussi à jour les PR site-changes/… ouvertes quand main change.Lancer un relevé. La carte « Relevé des prix » de Réglages propose « Relevé complet » (ouvre une PR de prix) et « Essai » (n'écrit rien, rapport dans le résumé du job). Chaque lancement demande une confirmation : un relevé consomme des recherches SerpApi. La page suit l'avancement toutes les 15 secondes et affiche le lien de la PR. La fusion reste manuelle.
Checklist de montage. Chaque case est enregistrée dans le localStorage de l'appareil : pas de compte, pas de synchronisation entre téléphone et PC.
Le 1er et le 15 de chaque mois à 7 h UTC, ou à la main (Actions → Relevé des prix → Run workflow). Le script ouvre une PR, en brouillon si le contrôle de cohérence échoue.
| Règle | Valeur |
|---|---|
| Prix retenu | l'offre valide la moins chère |
| Offre valide | le nom de la fiche contient les mots attendus et aucun mot interdit (scraper/sources.json) |
| Écarté comme absurde | prix sous 70 % de la médiane, ou hors de 0,5 à 2 fois le prix actuel |
| Écrit seulement si | au moins 2 sites concordent (1 pour IKEA) et la variation reste sous 30 % |
| Sinon | le prix est proposé dans la description de la PR |
| Articles achetés | figés ; sans source : listés « sans source » dans le rapport |
Respect des sites. Données structurées uniquement (JSON-LD, microdata, Open Graph, via extruct), jamais « le premier montant de la page ». Identifiant pc-full-white-price-check, robots.txt respecté, une requête toutes les 3 s par site. Un site qui bloque est signalé, pas contourné.
Liens d'achat. Chaque article garde dans prices.json (offers) les fiches qui ont servi : revendeur, adresse, prix, date. Une fiche momentanément injoignable garde son lien 60 jours.
Google Shopping et Amazon (SerpApi). Pour les articles que les fiches directes ne confirment pas (Cdiscount, Darty et Fnac interdisent les robots, Materiel.net refuse GitHub, Amazon n'a pas d'API ouverte). Forfait gratuit de 250 recherches par mois ; au plus 40 par passage (25 Shopping, 15 Amazon, Amazon en dernier recours). Une offre vue il y a moins de 14 jours reste valable si le vendeur ne ressort pas aujourd'hui (« mémorisée » dans le rapport). Les produits de référence génériques (auto: false) ne sont jamais écrits sans ton accord. Activation : secret de dépôt SERPAPI_KEY (Settings → Secrets and variables → Actions). Sans lui, le complément est désactivé sans rien casser.
Modes manuels (champ mode) :
| Mode | Effet |
|---|---|
releve | relevé complet, écrit les prix, ouvre une PR (mode des passages automatiques) |
essai | idem sans rien écrire ; rapport dans le résumé du job |
decouverte | cherche des fiches par nom chez chaque revendeur, ouvre une PR sur sources.json |
essai-decouverte | idem sans PR |
sonde | teste des adresses collées dans le champ adresses |
Ajouter une source. Dans scraper/sources.json, ajoute {"retailer": "ldlc", "url": "https://…"} à sources de l'article. Pour vérifier qu'une adresse est lisible, utilise d'abord sonde. En local : pip install -r scraper/requirements.txt, puis python3 scraper/update_prices.py --dry-run (ou --probe URL).
pc-full-white/
├── data/
│ ├── prices.json # source de vérité
│ └── changes.json # changements envoyés depuis le site
├── site/
│ ├── index.html # page unique, sprite d'icônes, politique de sécurité
│ ├── style.css # design system Full White (Material 3)
│ ├── app.js # génère tout depuis prices.json
│ └── fonts/ # polices auto-hébergées
├── scraper/ # relevé : update_prices.py, sources.json, retailers.json,
│ └── tests/ # extract / fetch / aggregate / recompute / shopping / discover / changes
├── scripts/
│ ├── check_prices.py # recalcule les totaux, refuse un JSON incohérent
│ ├── apply_changes.py # applique changes.json à prices.json
│ └── stamp_assets.py # numéros de version des fichiers + empreinte de la politique de sécurité
├── tests/ # Playwright (13 fichiers) ; unit/ : logique pure, sans navigateur
├── docs/ # archive : anciens PDFs (Sauvegarde, LITE, Workflow)
├── .github/workflows/
│ ├── checks.yml # données, tests du scraper, tests de logique, accessibilité
│ ├── update-prices.yml # relevé le 1er et le 15 + modes manuels
│ └── site-changes.yml # applique et rafraîchit les PR site-changes/…
├── SPEC.md # spécification accessibilité / Material 3
├── TODO.md # points ouverts
└── index.html # redirection vers site/
python3 -m http.server 8000 # puis http://localhost:8000/site/
Le serveur sert la racine du dépôt, pas site/ : app.js lit ../data/prices.json. C'est aussi ainsi que GitHub Pages sert le projet.
python3 scripts/check_prices.py data/prices.json # cohérence des données (CI)
node --check site/app.js # syntaxe (CI)
node --test tests/unit/logique.mjs # logique du budget, < 1 s (CI)
python3 -m unittest discover -s scraper/tests # scraper, sans réseau (CI)
python3 scripts/stamp_assets.py # après toute modif de app.js, style.css ou du script du <head>
npm ci && npx playwright install chromium # la première fois
npx playwright test # ~390 tests, environ 4 minutes
| Tests | Nombre | Rôle |
|---|---|---|
scraper/tests (Python) | 142 | extraction, concordance, recalcul des totaux, changements, Shopping |
tests/unit (Node) | 9 | nettoyage des changements locaux, calcul du budget |
tests/*.spec.mjs (Playwright, bureau et mobile) | ~390 | accessibilité (axe, clair et sombre), clavier, cohérence visuelle, envoi, relevé, fraîcheur, politique de sécurité |
Conventions.
stamp_assets.py écrit ?v=<empreinte> sur style.css et app.js, et l'empreinte du script du <head> dans la politique de sécurité. La CI échoue si tu l'oublies.light-dark() ; les données gardent des emojis (prices.json), traduits en pictogrammes par EMOJI_ICON dans app.js.// >>> logique pure et // <<< fin logique pure dans app.js.<meta>) : scripts du site uniquement, connexions limitées au site et à api.github.com. Aucune requête vers un tiers : polices auto-hébergées. frame-ancestors n'est pas prise en charge dans une balise meta, donc l'affichage dans une iframe n'est pas bloqué.main : protège-la (PR obligatoire) pour que le token ne puisse rien y pousser directement.main, dossier / (root) : index.html à la racine redirige vers site/.Pictogrammes : Material Symbols (Google, style « outlined », licence Apache 2.0), extraits de @material-symbols/svg-400 et intégrés au sprite de site/index.html.
AntoniMan31, dev Android et web amateur, Toulouse.