File size: 6,873 Bytes
e678200
4ae2054
 
b7ec643
e678200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
from flask import Flask, render_template, request, jsonify
from google import genai
from google.genai import types
import google.generativeai as genai
from PIL import Image
import io
import fitz
import markdown2
import re
import matplotlib.pyplot as plt
import base64
import json
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from dotenv import load_dotenv
import os

load_dotenv()  # This will load variables from a .env file in your project directory
gemini_api_key = os.getenv("GEMINI_API_KEY")
if not gemini_api_key:
    raise ValueError("GEMINI_API_KEY not set in environment variables.")
genai.configure(api_key=gemini_api_key)

app = Flask(__name__)
app.secret_key = "supersecretkey"


def process_file(file):
    """Process file into an appropriate format for Gemini."""
    if file.content_type == 'application/pdf':
        try:
            pdf_bytes = file.read()
            pdf_document = fitz.open(stream=pdf_bytes, filetype="pdf")
            first_page = pdf_document[0]
            pix = first_page.get_pixmap()
            img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
            return img, file.filename
        except Exception as e:
            raise Exception(f"Error processing PDF {file.filename}: {str(e)}")
    else:
        try:
            image_bytes = file.read()
            image = Image.open(io.BytesIO(image_bytes))
            return image, file.filename
        except Exception as e:
            raise Exception(f"Error processing image {file.filename}: {str(e)}")


def format_markdown(text):
    lines = [line.strip() for line in text.split('\n')]
    formatted_lines = []
    for i, line in enumerate(lines):
        if line.startswith('#'):
            if i > 0:
                formatted_lines.append('')
            formatted_lines.append(line)
            formatted_lines.append('')
        elif line:
            formatted_lines.append(line)
    text = '\n'.join(formatted_lines)
    text = re.sub(r'(?m)^(\s*)-', r'\1•', text)
    text = re.sub(r'\n(•[^\n]+)(?:\n(?!•)|\Z)', r'\n\1\n', text)
    return text




@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "POST":
        if "files" not in request.files:
            return jsonify({"error": "No files uploaded"})
        files = request.files.getlist("files")
        if not files or files[0].filename == "":
            return jsonify({"error": "No files selected"})
        
        # Retrieve the selected language from the form
        language = request.form.get("language", "English")
        
        try:
            processed_files = []
            for file in files:
                processed_content, filename = process_file(file)
                processed_files.append((processed_content, filename))
            filenames = [f[1] for f in processed_files]
            files_list = "\n".join([f"- {fname}" for fname in filenames])
            content_parts = []
            for img, _ in processed_files:
                content_parts.append(img)
            # Updated prompt: include the language instruction and refined content details
            content_parts.append(f"""
Please analyze all {len(files)} soil reports and generate a comprehensive soil analysis report in markdown format, entirely in {language}.
dont reveal yourself as llm or ai model make the report as proffessional as possible and dont refer like i me sorry and all that in response.
Ensure **exactly** five sections, each labeled as an H2 heading in Markdown, like this (in {language}):
## Overview Provide a detailed snapshot of the soil's overall health in plain language.
## Soil Composition Explain the proportions of sand, silt, and clay, and describe how these affect water retention, drainage, and fertility.
## Nutrient Levels Present an in-depth analysis of key nutrients (e.g. Nitrogen, Phosphorus, Potassium) and include recommendations.
## pH Balance & Moisture Content Describe the soil’s pH level and moisture content, and explain how they influence crop performance.    
## Recommendations & Actionable Steps Provide clear, practical advice to improve soil quality (such as lime application, fertilizer usage, and adding organic matter) with this  aslo provide  which crops should we should  cultivate with  season and  weather condition that will help me to  improve my soil  condition and let me develop  more and  also which crops should  i avoid  with this  can you also  recommend me  any home remedies  or natural remedies  that will help me to improve my soil  condition  also  recommend me what  agriculture  practices whill help me to  maintain my soil condition   in terms of the  future of 5 to 10 years.
Reports being analyzed:
{files_list}

Ensure that every section is clearly labeled and formatted so that the output is easy to understand and visually appealing."""
)

            model = genai.GenerativeModel("gemini-1.5-flash")
            response = model.generate_content(content_parts)

            if response and response.text:
                summary = response.text.strip()
                if summary.lower().startswith("please provide"):
                    return jsonify({"error": "Could not analyze the documents"})

                # Extract nutrient data from the analysis if available
                nutrient_data = None
                if "NUTRIENT_DATA:" in summary:
                    try:
                        parts = summary.split("NUTRIENT_DATA:")
                        summary = parts[0].strip()
                        # Assume the nutrient JSON is on the first line after the marker
                        nutrient_json_str = parts[1].strip().split("\n")[0]
                        nutrient_data = json.loads(nutrient_json_str)
                    except Exception as e:
                        nutrient_data = None

                final_output = f"""
# 🌱 Soil Report Analysis

{summary}

---
                """
                fixed_output = format_markdown(final_output)
                html_output = markdown2.markdown(
                    fixed_output,
                    extras=[
                        'tables',
                        'fenced-code-blocks',
                        'break-on-newline',
                        'cuddled-lists',
                        'code-friendly'
                    ]
                )

                return jsonify({
                    "summary": fixed_output,
                    "html_summary": html_output,
                })
            else:
                return jsonify({"error": "No analysis could be generated"})
        except Exception as e:
            return jsonify({"error": f"Error processing files: {str(e)}"})
    return render_template("index.html")

if __name__ == "__main__":
    port = int(os.environ.get("PORT", 7860))
    app.run(host='0.0.0.0', port=port)