Skip to the content.

PPR

Personal Project Requierments

  1. function
  2. call to function
  3. list
  4. list in use

Function (with sequencing, selection, and itteration)

@search_api.route("/increment_tag", methods=["POST"])
@token_required()
def increment_tag():
    data = request.get_json()
    if not data or "name" not in data:
        return jsonify({"error": "Invalid data"}), 400

    current_user = g.current_user  
    item_name = data["name"]

    item = next((item for item in items if item["name"].lower() == item_name.lower()), None)
    if item:

        for tag in item["tags"]:
            item["tags"][tag] += 1

        try:
            search_entry = SearchHistory(
                user=current_user.uid,
                name=item["name"],  
                tags=item["tags"],  
                query=None 
            )
            db.session.add(search_entry)
            db.session.commit()

            append_to_json(search_entry.read())
        except IntegrityError as e:
            db.session.rollback()
            return jsonify({"error": f"Failed to log item selection: {str(e)}"}), 500

        return jsonify({
            "message": f"Tags for '{item_name}' updated successfully!",
            "tags": item["tags"]
        }), 200

    return jsonify({"error": "Item not found!"}), 404

Sequencing –> checks if name of item you searched exsists in the lift of items, checks logged in/connected user

selection –> If item dosent exsist return with an error “Item not found”, If item exsists proceed with itteration

Iteration –> Generates connected items when you type in searchbar, adds tags to items when item is clicked in search bar

Call To Function

async function searchItems() {
    const input = document.getElementById('searchInput').value.trim().toLowerCase();
    const resultsDiv = document.getElementById('results');
    resultsDiv.innerHTML = ''; 

    if (input) {
      try {
        const response = await fetch(`${pythonURI}/api/search?q=${encodeURIComponent(input)}`, {
          ...fetchOptions,
          method: 'GET',
          headers: { 'Content-Type': 'application/json' }
        });

        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const items = await response.json();
        if (items.length > 0) {
          items.forEach(item => {
            const resultDiv = document.createElement('div');
            resultDiv.className = 'result';
            resultDiv.textContent = item.name;
            resultDiv.onclick = async () => {
              await incrementTags(item.name);
              window.location.href = item.link;
            };
            resultsDiv.appendChild(resultDiv);
          });
        } else {
          resultsDiv.textContent = 'No results found.';
        }
      } catch (error) {
        console.error('Error fetching search results:', error);
        resultsDiv.textContent = 'An error occurred while searching. Please try again.';
      }
    }
  }

Explination

  • Call to function (above this code cell) when user inputs (clicks on item in searchbar)
  • Remove old results from previous inputs (with resultsDiv.innerHTML = ‘’; )
  • Fetch from api (to get item data)
  • Display item/item link or error depending on input

List

DEFINING THE LIST

items = [
    {"name": "Teddy Bear", "link": "/holiday_frontend/holiday/toys", "tags": {"all": 1, "teddy": 0, "bear": 0, "toys": 0}},
    {"name": "Lego Set", "link": "/holiday_frontend/holiday/toys", "tags": {"all": 1, "lego": 0, "set": 0, "toys": 0}},
    {"name": "Remote Control Car", "link": "/holiday_frontend/holiday/toys", "tags": {"all": 1, "remote": 0, "control": 0, "car": 0, "toys": 0}},
]

Snipit of code from defined list that I am pulling data from

ADDING DATA TO LIST/STORING DATA

@search_api.route("/increment_tag", methods=["POST"])
@token_required()
def increment_tag():
    data = request.get_json()
    if not data or "name" not in data:
        return jsonify({"error": "Invalid data"}), 400

    current_user = g.current_user  
    item_name = data["name"]

    item = next((item for item in items if item["name"].lower() == item_name.lower()), None)
    if item:
        for tag in item["tags"]:
            item["tags"][tag] += 1  

        try:
            search_entry = SearchHistory(
                user=current_user.uid,
                name=item["name"],  
                tags=item["tags"],  
            )
            db.session.add(search_entry)
            db.session.commit()

            append_to_json(search_entry.read())  
        except IntegrityError as e:
            db.session.rollback()
            return jsonify({"error": f"Failed to log item selection: {str(e)}"}), 500

        return jsonify({
            "message": f"Tags for '{item_name}' updated successfully!",
            "tags": item["tags"]
        }), 200

    return jsonify({"error": "Item not found!"}), 404

where im ading the data into the list by updating the tags and grabbing assosiated item name and user

[
    {
        "id": 2,
        "user": "nora",
        "name": "Gourmet Cheese Set",
        "tags": {
            "all": 2,
            "gourmet": 1,
            "cheese": 1,
            "set": 1,
            "food": 1
        }
    }
]

Where the data is stores into JSON file with updated tags

Api endpoint to grab data from defined list and and create JSON file/database with added tags (when items are clicked on)

where im adding data to

  1. SearchHistory SQLite database
  2. JSON file with saved tags

List In Use

import os
import json
import logging
from flask import request, jsonify, Blueprint, g
from sqlalchemy.exc import IntegrityError
from model.search import SearchHistory, db
from api.jwt_authorize import token_required

JSON_FILE_PATH = os.path.join(os.path.dirname(__file__), "../searchHistory.json")

def append_to_json(data):
    try:
        if os.path.exists(JSON_FILE_PATH):
            with open(JSON_FILE_PATH, "r") as json_file:
                existing_data = json.load(json_file)  
        else:
            existing_data = []

        existing_entry = next((entry for entry in existing_data if entry["name"] == data["name"]), None)

        if existing_entry:
            existing_entry["tags"] = data["tags"]
        else:
            existing_data.append(data)

        with open(JSON_FILE_PATH, "w") as json_file:
            json.dump(existing_data, json_file, indent=4)

    except Exception as e:
        logging.error(f"Error saving data to JSON file: {e}")

search_api = Blueprint("search_api", __name__, url_prefix="/api/search")

@search_api.route("/increment_tag", methods=["POST"])
@token_required()
def increment_tag():
    data = request.get_json()
    if not data or "name" not in data:
        return jsonify({"error": "Invalid data"}), 400

    current_user = g.current_user  
    item_name = data["name"]

    search_entry = SearchHistory.query.filter_by(name=item_name, user=current_user.uid).first()

    if search_entry:
        for tag in search_entry.tags:
            search_entry.tags[tag] += 1
    else:
        item = next((item for item in items if item["name"].lower() == item_name.lower()), None)
        if not item:
            return jsonify({"error": "Item not found!"}), 404

        for tag in item["tags"]:
            item["tags"][tag] += 1

        search_entry = SearchHistory(
            user=current_user.uid,
            name=item["name"],
            tags=item["tags"],
            query=None
        )
        db.session.add(search_entry)

    try:
        db.session.commit()
    except IntegrityError:
        db.session.rollback()
        return jsonify({"error": "Failed to update tags in database"}), 500

    append_to_json(search_entry.read())

    return jsonify({
        "message": f"Tags for '{item_name}' updated successfully!",
        "tags": search_entry.tags
    }), 200

class SearchHistory(db.Model):
    __tablename__ = 'search_history'

    id = db.Column(db.Integer, primary_key=True)
    user = db.Column(db.String(255), nullable=False)
    name = db.Column(db.String(255), nullable=False)  
    query = db.Column(db.String(255), nullable=True)  
    tags = db.Column(db.JSON, nullable=False)  

    def __init__(self, user, name=None, query=None, tags=None):
        self.user = user
        self.name = name
        self.query = query
        self.tags = tags

    def read(self):
        return {
            "id": self.id,
            "user": self.user,
            "name": self.name,
            "query": self.query,
            "tags": self.tags,
        }

    def update(self, data):
        for key, value in data.items():
            if hasattr(self, key) and key != 'id':
                setattr(self, key, value)
        try:
            db.session.commit()
        except IntegrityError:
            db.session.rollback()

Explination

  1. retrives data from JSON (list) request
  2. checks if item exsists in the database
  3. updates tags to alread exisiting items OR adds item and tags if not already exsisting
  4. add finalized items into JSON file and SQLite database