Welcome to PriceBuddy
Relevant source files
The following files were used as context for generating this wiki page:
PriceBuddy is an open-source, self-hostable web application that enables users to compare prices of products from various online retailers. Users can add products by providing a URL, and the application will automatically track the price, extract product information, and visualize its price history. It is designed to be flexible, allowing users to add almost any store that has a product page.
The application is built using the Laravel framework for the backend and Filament for the administrative interface. It is designed to be deployed easily using Docker. Key functionalities include managing stores and products, daily price fetching, notifications for price changes, and integration with SearXNG for product discovery.
Sources: README.md:3-7, README.md:53-54
Key Features
The primary features of PriceBuddy are summarized below.
| Feature | Description |
|---|---|
| Store Management | Create and manage stores. The system is designed to fetch products from almost any store with a product page. |
| Product Management | Create and manage products. Each product can have multiple URLs, and prices are fetched daily from these URLs. |
| Price History Visualization | Visualise product price history with charts. |
| Flexible Data Extraction | Extract product information using CSS selectors, regular expressions, or JSONPath. |
| SPA Support | Supports scraping single-page applications (SPA) or JavaScript-rendered sites via an integration with a SeleniumBase Scrapper. |
| Product Tagging | Organize products using tags. |
| Multi-User Support | Each user has their own set of products. |
| Notifications | Receive notifications via the app, email, or Pushover/Gotify when a product's price changes to match user preferences. |
| SearXNG Integration | Search for products and add URLs directly from within the app using SearXNG. |
| Dockerized Setup | Simple setup via Docker Compose for easy installation. |
Sources: README.md:11-26
System Architecture
Technology Stack
PriceBuddy is built on a modern PHP stack, containerized for portability and ease of deployment.
- Backend Framework: Laravel
- Admin Panel: Filament
- Development Environment: Lando
- Containerization: Docker & Docker Compose
Sources: README.md:53-57, docker/php.dockerfile
Component Overview
The application is composed of a main Laravel application, a database, and an external scraper service. A cron job is responsible for orchestrating background tasks like price fetching.
This diagram illustrates the high-level interaction between the main components of the PriceBuddy system.
Sources: README.md:22, README.md:49, config/price_buddy.php:14
Core Data Model
The data model revolves around the Product, which is associated with multiple Urls. Each Url belongs to a Store and has many Price entries over time.
This ER diagram shows the relationships between the main entities in the database.
Sources: app/Models/Product.php:73-120
Product Model
The Product model is the central entity. It stores information about a product being tracked, including its price history and user-specific settings.
| Property / Method | Type | Description |
|---|---|---|
title | ?string | The full title of the product. |
image | ?string | The primary image URL for the product. |
price_cache | array | A JSON array caching recent price history and metadata for quick access. |
current_price | float | The latest known lowest price for the product across all its URLs. |
notify_price | ?float | The price threshold at or below which a notification should be sent. |
notify_percent | ?float | The percentage drop from the initial price that should trigger a notification. |
favourite | bool | A boolean flag to mark a product as a favorite. |
urls() | HasMany | Relationship to the Url models associated with this product. |
prices() | HasManyThrough | Relationship to all Price entries through its Urls. |
stores() | HasManyThrough | Relationship to all Stores through its Urls. |
tags() | MorphToMany | Relationship to Tag models. |
updatePrices() | bool | Triggers a price update for all associated URLs and returns true if all were successful. |
updatePriceCache() | void | Rebuilds and updates the price_cache JSON attribute. |
getPriceHistory() | Collection | Retrieves and groups the price history for the product from the database. |
trend() | Attribute | A calculated attribute that determines the price trend (up, down, stable). |
Sources: app/Models/Product.php
Price Scraping and Processing
Scraping Flow
Price fetching is a core background process. It is initiated by a cron job that calls a Laravel command. This command then iterates through products and their associated URLs, sending requests to an external scraper service to fetch the latest price.
This sequence diagram shows the process of updating a product's price.
Scraping Strategies
PriceBuddy can automatically create store configurations by attempting various data extraction strategies defined in config/price_buddy.php. When a new URL is added for a product, these strategies are used to find the product's title, price, and image.
| Field | Strategy Type | Value Examples |
|---|---|---|
| title | selector | meta[property="og:title"]|content, title, h1 |
| price | selector | meta[property="product:price:amount"]|content, .price, [itemProp="price"]|content |
| price | regex | ~\"price\"\:\s?\"(.*?)\"~, ~\$(\d+(\.\d{2})?)~ |
| image | selector | meta[property="og:image"]|content |
| image | regex | ~\"hiRes\":\"(.+?)\"~ (for Amazon) |
The system also includes pre-defined strategies for specific stores.
Sources: config/price_buddy.php:20-69, database/seeders/Stores/australia.php
Price Caching
To improve performance and provide historical data for trend analysis, each Product model stores a price_cache. This is a JSON column that holds a collection of recent prices, trends, and metadata for each associated URL. The buildPriceCache() method on the Product model is responsible for generating this data from the prices table.
The getPriceCacheAggregate() method allows for quick calculation of avg, min, and max prices from this cache without querying the database directly.
Sources: app/Models/Product.php:330-349, app/Models/Product.php:355-368
Installation and Setup
Docker
The recommended installation method is via Docker Compose. The repository provides a docker-compose.yml file. The setup involves running touch .env && docker compose up -d. The application will be available at http://localhost:8080 with default credentials.
The docker/php.dockerfile defines the application's runtime environment, including the PHP version, required extensions, and setup of cron and supervisor for background tasks.
Sources: README.md:41-45, docker/php.dockerfile
Cron Jobs
The Docker container includes a cron job that handles background tasks like fetching prices and sending notifications. The cron is configured in docker/php/schedule-cron to run the Laravel scheduler every minute.
Sources: README.md:49-51, docker/php.dockerfile:21
Configuration
Key application settings are defined in config/price_buddy.php and can be overridden using environment variables in the .env file.
| Configuration Key | Environment Variable | Description |
|---|---|---|
help_url | HELP_URL | The URL for the help link displayed in the sidebar. |
chunk_size | N/A | The number of products to scrape in a single batch job. |
scraper_api_url | SCRAPER_BASE_URL | The base URL for the external scraper service. |
auto_create_store_strategies | N/A | Defines the methods used to automatically extract data for new stores. |
Sources: config/price_buddy.php
Product API
PriceBuddy exposes a RESTful API for managing products. Authentication is handled via Sanctum tokens. The tests in tests/Feature/Api/ProductApiTest.php demonstrate the expected behavior and structure of the API.
| Endpoint | Method | Description |
|---|---|---|
/api/products | GET | Lists all products for the authenticated user. Supports filtering and sorting. |
/api/products | POST | Creates a new product. Requires a title and url. |
/api/products/{id} | GET | Shows a single product belonging to the authenticated user. |
/api/products/{id} | PUT | Updates a product belonging to the authenticated user. |
/api/products/{id} | DELETE | Deletes a product belonging to the authenticated user. |
The API supports including related data like tags and user via an include query parameter.
Sources: tests/Feature/Api/ProductApiTest.php
License
The project is licensed under a modified GPL-3.0 license. It allows for non-commercial use, modification, and distribution. However, it explicitly prohibits commercial use, such as selling access to a hosted solution or distributing the software for profit.
Sources: LICENSE.md
Conclusion
PriceBuddy is a comprehensive, self-hostable price tracking application with a flexible architecture. Its reliance on an external scraper service and configurable extraction strategies allows it to adapt to a wide range of e-commerce sites. The provision of a Docker-based setup simplifies installation, and the REST API enables integration with other services or custom frontends.