Skill: ricanwarfare/slickdeals (version 1.1.0)

--- name: slickdeals description: Search Slickdeals.net for deals, coupons, and promo codes. Use when the user asks for deals, discounts, price comparisons, or to find cheap games, electronics, or other products. license: Apache-2.0 --- # Slickdeals Skill Search Slickdeals.net for the best deals, coupons, promo codes, and discounts across electronics, games, home goods, and more. ## Capabilities - Search for deals by product name, category, or keyword - Get frontpage deals (top trending deals) - Filter by store, category, or price range - Check deal expiration status - Find coupon codes and promo codes ## Usage ### Search for Deals ``` Use the skill to search Slickdeals for specific products or categories. ``` **Examples:** - "Find deals on PS5 games" - "Search for Nintendo Switch deals" - "Any deals on air fryers?" - "Find GTA Trilogy deals under $30" - "Show me frontpage deals" - "Find laptop deals on Slickdeals" ### Search URL Format The search URL pattern is: ``` https://slickdeals.net/newsearch.php?q={QUERY}&searcharea=deals&searchin=first ``` For category browsing: ``` https://slickdeals.net/computer-deals/ https://slickdeals.net/electronics-deals/ https://slickdeals.net/video-game-deals/ https://slickdeals.net/home-deals/ ``` ## Implementation ### Step 1: Search Slickdeals Use `ollama_web_fetch` to retrieve search results: ``` https://slickdeals.net/newsearch.php?q=URL_ENCODED_QUERY&searcharea=deals&searchin=first ``` ### Step 2: Verify Each Deal is Active **CRITICAL: Before presenting any deal, you MUST verify it is currently active.** For each search result: 1. Fetch the individual deal page using `ollama_web_fetch` 2. Check for expiration indicators: - "expired" or "deal has expired" text on the page - "currently unavailable" or "out of stock" on the retailer page - Deal posted date older than 30 days (likely expired) 3. Only include deals confirmed as active in your output 4. If no deals are active, say so explicitly — do NOT show expired deals ### Step 3: Parse Active Deals Extract from confirmed-active deals: - Deal title - Current price vs original price - Discount percentage - Store name - Deal score (thumbs up/down) - Direct link to deal - Any coupon codes required ### Step 4: Format Output Present only **active** deals in a clean table format: | Deal | Price | Discount | Store | Score | Link | |------|-------|----------|-------|-------|------| | Title | $XX ($YY) | 50% off | Amazon | +15 | [URL] | If no active deals are found, respond: > No active deals found for [query]. The most recent deals have expired. I'll keep an eye out — want me to set up a deal alert? ## Categories - `video-game-deals` - Video games, consoles, accessories - `computer-deals` - Laptops, desktops, components - `electronics-deals` - TVs, phones, audio - `home-deals` - Appliances, furniture - `clothing-deals` - Fashion, apparel - `travel-deals` - Hotels, flights, vacation packages ## Rules 1. **ACTIVE DEALS ONLY**: Never show expired deals. If the deal page says "expired" or the retailer shows "unavailable", exclude it entirely 2. **Verify before presenting**: Fetch each deal page to confirm it's still live 3. **Be honest about availability**: If nothing is active, say so — don't pad results with stale deals 4. **Deal score**: Higher thumbs up = better verified deal 5. **Comments**: Read comments for coupon codes or price match tips 6. **Store filter**: Results often include Amazon, Best Buy, Walmart, Newegg, etc. 7. **Post date awareness**: Deals older than ~30 days are very likely expired — prioritize recent deals ## Limitations - Slickdeals is a community-driven site; deals may expire quickly - Some deals require store-specific coupons or subscriptions (Amazon Prime, etc.) - Regional availability may vary ## Example Queries | User Request | Search Query | |--------------|--------------| | "Find PS5 deals" | `PS5` | | "Cheap GTA Trilogy" | `GTA Trilogy` | | "Nintendo Switch games under $30" | `Nintendo Switch games` | | "Laptop deals" | `laptop` | | "Air fryer deals" | `air fryer` | | "Frontpage deals" | Browse `https://slickdeals.net/` | ## Notes - **MANDATORY**: Verify every deal is active before showing it. Expired deals waste the user's time - If most/all results are expired, try a broader search or check current retailer prices via web search - Include the store name and any coupon codes required - Mention if the deal requires membership (Prime, etc.) - When Slickdeals search returns no active deals, supplement with current retail pricing from Amazon/Best Buy/etc.

path: slickdeals.py
content: #!/usr/bin/env python3
"""
Slickdeals Deal Search - Search Slickdeals.net for deals, coupons, and promo codes.
"""

import argparse
import json
import re
import urllib.parse
import urllib.request
import urllib.error
from html.parser import HTMLParser
from dataclasses import dataclass
from typing import List, Optional


@dataclass
class Deal:
    title: str
    price: str
    original_price: Optional[str]
    discount: Optional[str]
    store: str
    score: str
    comments: int
    expired: bool
    url: str


class SlickdealsParser(HTMLParser):
    """Parse Slickdeals search results."""
    
    def __init__(self):
        super().__init__()
        self.deals: List[Deal] = []
        self.current_deal = None
        self.in_deal = False
        self.current_field = None
        
    def handle_starttag(self, tag, attrs):
        attrs_dict = dict(attrs)
        
        # Deal container
        if 'class' in attrs_dict and 'dealRow' in attrs_dict.get('class', ''):
            self.in_deal = True
            self.current_deal = {
                'title': '',
                'price': '',
                'original_price': None,
                'discount': None,
                'store': '',
                'score': '0',
                'comments': 0,
                'expired': False,
                'url': ''
            }
    
    def handle_endtag(self, tag):
        if tag == 'div' and self.in_deal:
            self.in_deal = False
            if self.current_deal and self.current_deal.get('title'):
                self.deals.append(Deal(**self.current_deal))
            self.current_deal = None
    
    def handle_data(self, data):
        if self.in_deal and self.current_deal:
            data = data.strip()
            if data and 'expired' in data.lower():
                self.current_deal['expired'] = True


def search_deals(query: str, limit: int = 10) -> List[Deal]:
    """Search Slickdeals for deals matching query."""
    
    encoded_query = urllib.parse.quote(query)
    url = f"https://slickdeals.net/newsearch.php?q={encoded_query}&searcharea=deals&searchin=first"
    
    try:
        req = urllib.request.Request(
            url,
            headers={
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            }
        )
        with urllib.request.urlopen(req, timeout=30) as response:
            html = response.read().decode('utf-8', errors='ignore')
    except urllib.error.URLError as e:
        print(f"Error fetching deals: {e}")
        return []
    
    # Simple regex-based extraction (more reliable than HTML parsing for this site)
    deals = []
    
    # Find deal titles and prices
    title_pattern = r'Found by[^>]*>.*?</a>\s*\$?([\d,.]+)?\s*(\$[\d,.]+)?\s*(\d+% off)?'
    
    # Look for deal blocks
    deal_blocks = re.findall(
        r'<div[^>]*class="[^"]*dealRow[^"]*"[^>]*>(.*?)</div>',
        html,
        re.DOTALL | re.IGNORECASE
    )
    
    # Alternative: parse from the text content
    lines = html.split('\n')
    current_title = None
    current_price = None
    current_store = None
    expired = False
    
    for i, line in enumerate(lines):
        line = line.strip()
        
        # Check for expiration
        if 'expired' in line.lower():
            expired = True
        
        # Check for deal title (Found by pattern)
        if 'Found by' in line:
            # Extract title from nearby content
            title_match = re.search(r'([^<]+)(?:<[^>]+>)*\s*\$?[\d,.]+', line)
            if title_match:
                current_title = title_match.group(1).strip()
        
        # Check for price
        price_match = re.search(r'\$?([\d,.]+)\s*(\$[\d,.]+)?\s*(\d+% off)?', line)
        if price_match and current_title:
            current_price = price_match.group(0)
        
        # Check for store
        store_match = re.search(r'(Amazon|Best Buy|Walmart|Newegg|Target|Steam|Epic|GameStop|Nintendo|PlayStation|Xbox)', line, re.I)
        if store_match:
            current_store = store_match.group(1)
    
    # Use a simpler approach: parse visible deals from the HTML
    # Look for patterns like: "Title $XX $YY 50% off Store"
    
    deal_pattern = re.compile(
        r'([^<>\n]{10,100}?)\s*\$?([\d,.]+)\s*(?:\$[\d,.]+)?\s*(\d+% off)?\s*(Amazon|Best Buy|Walmart|Newegg|Target|Steam|Epic|GameStop|Nintendo|PlayStation|Xbox)?',
        re.IGNORECASE
    )
    
    # Extract deals from the raw text
    visible_text = re.sub(r'<script[^>]*>.*?</script>', '', html, flags=re.DOTALL)
    visible_text = re.sub(r'<style[^>]*>.*?</style>', '', visible_text, flags=re.DOTALL)
    visible_text = re.sub(r'<[^>]+>', ' ', visible_text)
    
    # Find deals with price patterns
    lines = visible_text.split('\n')
    for line in lines:
        line = ' '.join(line.split())  # Normalize whitespace
        if '$' in line and len(line) > 20 and len(line) < 500:
            # Check if it looks like a deal
            if any(store in line for store in ['Amazon', 'Best Buy', 'Walmart', 'Newegg', 'Target', 'Steam']):
                deals.append(line)
                if len(deals) >= limit:
                    break
    
    return deals[:limit]


def format_deals(deals: List, output_format: str = 'text') -> str:
    """Format deals for output."""
    
    if output_format == 'json':
        return json.dumps(deals, indent=2)
    
    if not deals:
        return "No deals found."
    
    output = []
    output.append("| Deal | Price | Store |")
    output.append("|------|-------|-------|")
    
    for deal in deals[:10]:
        if isinstance(deal, str):
            output.append(f"| {deal[:80]}... | - | - |" if len(deal) > 80 else f"| {deal} | - | - |")
        else:
            output.append(f"| {deal.title[:50]} | {deal.price} | {deal.store} |")
    
    return '\n'.join(output)


def main():
    parser = argparse.ArgumentParser(
        description='Search Slickdeals for deals'
    )
    parser.add_argument('query', help='Search query')
    parser.add_argument('-l', '--limit', type=int, default=10, help='Max results')
    parser.add_argument('-j', '--json', action='store_true', help='JSON output')
    parser.add_argument('-c', '--category', help='Category filter (video-games, electronics, etc.)')
    
    args = parser.parse_args()
    
    deals = search_deals(args.query, args.limit)
    output = format_deals(deals, 'json' if args.json else 'text')
    print(output)


if __name__ == '__main__':
    main()

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)