Vrushali commited on
Commit
5329974
·
2 Parent(s): e6bde5b 5f901fb

Merge branch 'main' of https://github.com/gamingflexer/Catalog-Digitization

Browse files
.github/workflows/file_size_check.yml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Check file size
2
+ on:
3
+ pull_request:
4
+ branches: [main]
5
+
6
+ # to run this workflow manually from the Actions tab
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ sync-to-hub:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Check large files
14
+ uses: ActionsDesk/[email protected]
15
+ with:
16
+ filesizelimit: 10485760 # this is 10MB so we can sync to HF Spaces
.github/workflows/main.yml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync to Hugging Face hub
2
+ on:
3
+ push:
4
+ branches: [main]
5
+
6
+ # to run this workflow manually from the Actions tab
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ sync-to-hub:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ with:
15
+ fetch-depth: 0
16
+ - name: Add remote
17
+ env:
18
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
19
+ run: git remote add space https://asach:[email protected]/spaces/asach/Catalog-Digitization
20
+ - name: Push to hub
21
+ env:
22
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
23
+ run: git push --force https://asach:[email protected]/spaces/asach/Catalog-Digitization main
.gitignore CHANGED
@@ -173,3 +173,4 @@ src/app/api/migrations/0005_alter_database_barcode_alter_database_brand_and_more
173
  src/app/api/migrations/0006_alter_product_barcode_alter_product_brand_and_more.py
174
  src/app/api/migrations/0007_alter_product_price.py
175
  src/app/media/images/*
 
 
173
  src/app/api/migrations/0006_alter_product_barcode_alter_product_brand_and_more.py
174
  src/app/api/migrations/0007_alter_product_price.py
175
  src/app/media/images/*
176
+ src/app/api/module/image.ipynb
Dockerfile ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ARG OPENAI_API_KEY
2
+ ARG SEVER_IP
3
+
4
+ FROM python:3.9
5
+
6
+ WORKDIR /code
7
+
8
+ COPY ./requirements.txt /code/requirements.txt
9
+
10
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
11
+
12
+ # Set up a new user named "user" with user ID 1000
13
+ RUN useradd -m -u 1000 user
14
+
15
+ # Switch to the "user" user
16
+ USER user
17
+
18
+ # Set home to the user's home directory
19
+ ENV HOME=/home/user \
20
+ PATH=/home/user/.local/bin:$PATH \
21
+ OPENAI_API_KEY=$OPENAI_API_KEY \
22
+ SEVER_IP=$SEVER_IP
23
+
24
+
25
+ # Set the working directory to the user's home directory
26
+ WORKDIR $HOME/app
27
+
28
+ # Copy the current directory contents into the container at $HOME/app setting the owner to the user
29
+ COPY --chown=user . $HOME/app
30
+
31
+ ENV GRADIO_SERVER_NAME=0.0.0.0
32
+
33
+ EXPOSE 7860
34
+
35
+ CMD ["python", "src/app2.py"]
README.md CHANGED
@@ -1,3 +1,12 @@
 
 
 
 
 
 
 
 
 
1
  # Catalog Digitization - BUILD FOR BHARAT Hackathon 2024
2
 
3
  ## Introduction
@@ -34,4 +43,4 @@ python manage.py runserver
34
  - **Django**: Backend framework for managing data operations and interfaces.
35
  - **Tesseract OCR & Easy OCR & AZURE OCR**: Extracts text from images for digitization.
36
  - **LLAMA 7B & GPT 3.5**: Large language model for processing text and voice inputs.
37
- - **Speech Recognition**: Converts voice inputs to text for digitization.
 
1
+ ---
2
+ title: Catalog Digitization
3
+ emoji: 🚀
4
+ colorFrom: pink
5
+ colorTo: pink
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: true
9
+ ---
10
  # Catalog Digitization - BUILD FOR BHARAT Hackathon 2024
11
 
12
  ## Introduction
 
43
  - **Django**: Backend framework for managing data operations and interfaces.
44
  - **Tesseract OCR & Easy OCR & AZURE OCR**: Extracts text from images for digitization.
45
  - **LLAMA 7B & GPT 3.5**: Large language model for processing text and voice inputs.
46
+ - **Speech Recognition**: Converts voice inputs to text for digitization.
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ pandas
src/app/api/serializers.py CHANGED
@@ -1,7 +1,12 @@
1
  from rest_framework import serializers
2
- from .models import Product
3
 
4
  class ProductSerializer(serializers.ModelSerializer):
5
  class Meta:
6
  model = Product
7
  fields = '__all__'
 
 
 
 
 
 
1
  from rest_framework import serializers
2
+ from .models import Product,Database
3
 
4
  class ProductSerializer(serializers.ModelSerializer):
5
  class Meta:
6
  model = Product
7
  fields = '__all__'
8
+
9
+ class DatabaseSerializer(serializers.ModelSerializer):
10
+ class Meta:
11
+ model = Database
12
+ fields = '__all__'
src/app/api/templates/catalouge.html CHANGED
@@ -30,7 +30,7 @@
30
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
31
  <div class="container">
32
  <a class="navbar-brand" href="{% url 'index' %}" style="font-weight: bold;">HomePage</a>
33
- <a class="navbar-brand" href="http://34.122.223.224:9003/" style="font-weight: bold;">Database</a>
34
  <a href="{% url 'add_product_by_image' %}" class="btn btn-primary ml-1" style="padding: 0.5rem 1rem; font-size: 1rem;">Add a Product by Image</a>
35
  </div>
36
  </nav>
@@ -58,8 +58,9 @@
58
  <p class="card-text">Description: {{ product.parent_category }}</p>
59
  <p class="card-text">Brand: {{ product.brand }}</p>
60
  <div class="d-flex justify-content-between align-items-center">
61
- <a href="{% url 'product_detail' product.id %}" class="btn btn-primary btn-sm mb-2">View Details</a>
62
  <a href="{% url 'voice_product_detail' product.id %}" class="btn btn-secondary btn-sm mb-2">Voice Edit</a>
 
63
  </div>
64
  </div>
65
  </div>
 
30
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
31
  <div class="container">
32
  <a class="navbar-brand" href="{% url 'index' %}" style="font-weight: bold;">HomePage</a>
33
+ <a href="http://34.122.223.224:9003/" class="btn btn-secondary ml-1" target="_blank" style="font-weight: bold;">Database</a>
34
  <a href="{% url 'add_product_by_image' %}" class="btn btn-primary ml-1" style="padding: 0.5rem 1rem; font-size: 1rem;">Add a Product by Image</a>
35
  </div>
36
  </nav>
 
58
  <p class="card-text">Description: {{ product.parent_category }}</p>
59
  <p class="card-text">Brand: {{ product.brand }}</p>
60
  <div class="d-flex justify-content-between align-items-center">
61
+ <a href="{% url 'product_detail' product.id %}" class="btn btn-primary btn-sm mb-2">View</a>
62
  <a href="{% url 'voice_product_detail' product.id %}" class="btn btn-secondary btn-sm mb-2">Voice Edit</a>
63
+ <a href="{% url 'delete_product_api' product.id %}" class="btn btn-danger btn-sm mb-2">Delete</a>
64
  </div>
65
  </div>
66
  </div>
src/app/api/templates/edit_product.html CHANGED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Edit Product</title>
7
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
8
+ </head>
9
+ <body>
10
+ <header>
11
+ <nav class="navbar navbar-expand-lg navbar-light bg-light">
12
+ <div class="container">
13
+ <a class="navbar-brand" href="{% url 'index' %}">Catalogue</a>
14
+ </div>
15
+ </nav>
16
+ </header>
17
+ <div class="container mt-5">
18
+ <h1 class="text-center">Edit Product</h1>
19
+ <form method="post">
20
+ {% csrf_token %}
21
+ <div class="form-group">
22
+ <label for="barcode">Barcode:</label>
23
+ <input type="text" class="form-control" id="barcode" name="barcode" value="{{ product.barcode }}">
24
+ </div>
25
+ <div class="form-group">
26
+ <label for="brand">Brand:</label>
27
+ <input type="text" class="form-control" id="brand" name="brand" value="{{ product.brand }}">
28
+ </div>
29
+ <div class="form-group">
30
+ <label for="sub_brand">Sub Brand:</label>
31
+ <input type="text" class="form-control" id="sub_brand" name="sub_brand" value="{{ product.sub_brand }}">
32
+ </div>
33
+ <div class="form-group">
34
+ <label for="manufacturer">Manufacturer:</label>
35
+ <input type="text" class="form-control" id="manufacturer" name="manufacturer" value="{{ product.manufacturer }}">
36
+ </div>
37
+ <!-- Add similar form fields for other attributes -->
38
+ <div class="text-center">
39
+ <button type="submit" class="btn btn-primary">Save</button>
40
+ </div>
41
+ </form>
42
+ </div>
43
+ </body>
44
+ </html>
src/app/api/urls.py CHANGED
@@ -1,6 +1,6 @@
1
  from django.urls import path
2
  from . import views
3
- from .views import ProductAPIView
4
 
5
  urlpatterns = [
6
  path('', views.catalouge_page, name='index'),
@@ -9,4 +9,10 @@ urlpatterns = [
9
  path('product/<int:product_id>/edit/', views.edit_product, name='edit_product'),
10
  path('upload/', views.upload_image_and_audio, name='add_product_by_image'),
11
  path('api/products/', ProductAPIView.as_view(), name='product_api'),
 
 
 
 
 
 
12
  ]
 
1
  from django.urls import path
2
  from . import views
3
+ from .views import ProductAPIView,SearchProducts,TotalNumberOfProducts,ProductDetailsById,UpdateProduct
4
 
5
  urlpatterns = [
6
  path('', views.catalouge_page, name='index'),
 
9
  path('product/<int:product_id>/edit/', views.edit_product, name='edit_product'),
10
  path('upload/', views.upload_image_and_audio, name='add_product_by_image'),
11
  path('api/products/', ProductAPIView.as_view(), name='product_api'),
12
+ path('api/delete_product/<int:product_id>/', views.delete_product_api, name='delete_product_api'),
13
+
14
+ path('api/search_products/', SearchProducts.as_view(), name='search_products'),
15
+ path('api/total_number_of_products/', TotalNumberOfProducts.as_view(), name='total_number_of_products'),
16
+ path('api/product_details/<int:pk>/', ProductDetailsById.as_view(), name='product_details_by_id'),
17
+ path('api/update_product/<int:pk>/', UpdateProduct.as_view(), name='update_product'),
18
  ]
src/app/api/views.py CHANGED
@@ -6,12 +6,14 @@ from django.shortcuts import render, get_object_or_404
6
  from rest_framework.views import APIView
7
  from rest_framework.response import Response
8
  from rest_framework import status
9
- from .models import Product
10
- from .serializers import ProductSerializer
11
  from django.http import JsonResponse
12
  import os
13
  from config import BASE_PATH
14
  from api.module.product_description import get_details
 
 
15
 
16
  def catalouge_page(request):
17
  # Fetch all products from the database
@@ -41,13 +43,11 @@ def edit_product(request, product_id):
41
 
42
  if request.method == 'POST':
43
  # Update the product fields with the submitted data
 
44
  product.barcode = request.POST.get('barcode')
45
  product.brand = request.POST.get('brand')
46
  product.sub_brand = request.POST.get('sub_brand')
47
  product.manufacturer = request.POST.get('manufacturer')
48
- # Update other fields similarly
49
-
50
- # Save the updated product
51
  product.save()
52
 
53
  # Redirect to the product page after saving
@@ -130,4 +130,46 @@ def edit_voice_product(request,product_id):
130
  else:
131
  return JsonResponse({'error': 'No voice file submitted.'}, status=400)
132
  else:
133
- return render(request, 'edit_voice_product.html')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  from rest_framework.views import APIView
7
  from rest_framework.response import Response
8
  from rest_framework import status
9
+ from .models import Product,Database
10
+ from .serializers import ProductSerializer,DatabaseSerializer
11
  from django.http import JsonResponse
12
  import os
13
  from config import BASE_PATH
14
  from api.module.product_description import get_details
15
+ from django.views.decorators.http import require_http_methods
16
+ from django.db.models import Q
17
 
18
  def catalouge_page(request):
19
  # Fetch all products from the database
 
43
 
44
  if request.method == 'POST':
45
  # Update the product fields with the submitted data
46
+ product = Product.objects.get(pk=product_id)
47
  product.barcode = request.POST.get('barcode')
48
  product.brand = request.POST.get('brand')
49
  product.sub_brand = request.POST.get('sub_brand')
50
  product.manufacturer = request.POST.get('manufacturer')
 
 
 
51
  product.save()
52
 
53
  # Redirect to the product page after saving
 
130
  else:
131
  return JsonResponse({'error': 'No voice file submitted.'}, status=400)
132
  else:
133
+ return render(request, 'edit_voice_product.html')
134
+
135
+ def delete_product_api(request, product_id):
136
+ try:
137
+ product = Product.objects.get(pk=product_id)
138
+ product.delete()
139
+ return HttpResponseRedirect(reverse('index'))
140
+ except Product.DoesNotExist:
141
+ return JsonResponse({'error': 'Product not found.'}, status=404)
142
+
143
+ class SearchProducts(APIView):
144
+ def get(self, request):
145
+ name = request.query_params.get('name', '')
146
+ products = Database.objects.filter(Q(product_name__icontains=name) & Q(description__icontains=name))
147
+ db_serializer = DatabaseSerializer(products, many=True)
148
+ return Response(db_serializer.data)
149
+
150
+ class TotalNumberOfProducts(APIView):
151
+ def get(self, request):
152
+ count = Database.objects.count()
153
+ return Response({"total_number_of_products": count})
154
+
155
+ class ProductDetailsById(APIView):
156
+ def get(self, request, pk):
157
+ try:
158
+ product = Product.objects.get(pk=pk)
159
+ product_serializer = ProductSerializer(product)
160
+ return Response(product_serializer.data)
161
+ except Product.DoesNotExist:
162
+ return Response({"error": "Product not found"}, status=404)
163
+
164
+ class UpdateProduct(APIView):
165
+ def put(self, request, pk):
166
+ try:
167
+ product = Product.objects.get(pk=pk)
168
+ serializer = ProductSerializer(product, data=request.data)
169
+ print(serializer.is_valid(), serializer.errors)
170
+ if serializer.is_valid():
171
+ serializer.save()
172
+ return Response(serializer.data)
173
+ return Response(serializer.errors, status=400)
174
+ except Product.DoesNotExist:
175
+ return Response({"error": "Product not found"}, status=404)
src/app2.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import os
4
+ import requests
5
+
6
+ OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
7
+ SEVER_IP = os.environ.get("SEVER_IP")
8
+
9
+ def get_total_number_of_products():
10
+ response = requests.get(f'{SEVER_IP}/api/total_number_of_products/')
11
+ if response.status_code == 200:
12
+ return response.json()['total_number_of_products']
13
+ else:
14
+ return "Error fetching total number of products"
15
+
16
+ def search_products(product_name):
17
+ response = requests.get(f'{SEVER_IP}/api/search_products/', params={'name': product_name})
18
+ if response.status_code == 200:
19
+ return pd.DataFrame(response.json())
20
+ else:
21
+ return pd.DataFrame([]) # Return an empty DataFrame in case of an error
22
+
23
+ def get_product_details_by_id(product_id):
24
+ response = requests.get(f'{SEVER_IP}/api/product_details/{product_id}/')
25
+ if response.status_code == 200:
26
+ return response.json() # Returns the product details as a dictionary
27
+ else:
28
+ return {"error": f"Product with ID {product_id} not found or error occurred."}
29
+
30
+ def sample_fun(voice_input, prodcut_id):
31
+ print(prodcut_id)
32
+ return
33
+
34
+ with gr.Blocks(theme=gr.themes.Default(primary_hue=gr.themes.colors.red, secondary_hue=gr.themes.colors.pink)) as demo:
35
+
36
+ with gr.Tab("Add Your Image"):
37
+ voice_input = gr.Audio(label="Upload Audio")
38
+ prodcut_id = gr.Textbox(label="Enter Product ID")
39
+ with gr.Row():
40
+ submit_button_tab_1 = gr.Button("Start")
41
+
42
+ with gr.Tab("Search Catalog"):
43
+ with gr.Row():
44
+ total_no_of_products = gr.Textbox(value=str(get_total_number_of_products()),label="Total Products")
45
+ with gr.Row():
46
+ embbed_text_search = gr.Textbox(label="Enter Product Name")
47
+ submit_button_tab_4 = gr.Button("Start")
48
+ dataframe_output_tab_4 = gr.Dataframe(headers=['id', 'barcode', 'brand', 'sub_brand', 'manufactured_by', 'product_name',
49
+ 'weight', 'variant', 'net_content', 'price', 'parent_category',
50
+ 'child_category', 'sub_child_category', 'images_paths', 'description',
51
+ 'quantity', 'promotion_on_the_pack', 'type_of_packaging', 'mrp'])
52
+
53
+
54
+
55
+ submit_button_tab_1.click(fn=sample_fun,inputs=[voice_input,prodcut_id])
56
+ submit_button_tab_4.click(fn=search_products,inputs=[embbed_text_search] ,outputs= dataframe_output_tab_4)
57
+
58
+ demo.launch()