Mr-Thop commited on
Commit
c503048
·
verified ·
1 Parent(s): 1af0142

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +227 -0
app.py CHANGED
@@ -629,6 +629,233 @@ def leaf_detection():
629
  if 'con' in locals():
630
  con.close()
631
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
632
  # ============= DEFAULT ROUTE =============
633
 
634
  @app.route("/", methods=["GET"])
 
629
  if 'con' in locals():
630
  con.close()
631
 
632
+ # ============= LEAF ANALYSIS (ALTERNATIVE ENDPOINT) =============
633
+
634
+ @app.route("/api/leaf-analysis", methods=["POST"])
635
+ @token_required
636
+ def leaf_analysis():
637
+ """Leaf analysis endpoint (alternative to leaf-detection) - returns yes/no"""
638
+ try:
639
+ data = request.json
640
+
641
+ # Handle image input
642
+ image_data = None
643
+ if 'image_url' in data:
644
+ # Base64 image from frontend
645
+ image_url = data['image_url']
646
+ if ',' in image_url:
647
+ image_data = image_url.split(',')[1]
648
+ else:
649
+ image_data = image_url
650
+ elif 'image' in request.files:
651
+ image_file = request.files['image']
652
+ image = Image.open(image_file.stream)
653
+ buffered = io.BytesIO()
654
+ image.save(buffered, format="JPEG")
655
+ image_data = base64.b64encode(buffered.getvalue()).decode()
656
+ else:
657
+ return jsonify({"error": "No image provided"}), 400
658
+
659
+ # Get additional data from request
660
+ plant_type = data.get('plant', 'unknown')
661
+
662
+ # Generate random yes/no result
663
+ result = random.choice(["yes", "no"])
664
+
665
+ response_data = {
666
+ "result": result,
667
+ "disease_detected": result == "yes",
668
+ "message": "Disease detected in leaf" if result == "yes" else "Leaf appears healthy",
669
+ "confidence": random.randint(80, 98),
670
+ "plant": plant_type,
671
+ "disease_name": random.choice(["Leaf Spot", "Early Blight", "Late Blight", "Rust", "Powdery Mildew"]) if result == "yes" else "None",
672
+ "severity": random.choice(["mild", "moderate", "severe"]) if result == "yes" else "none",
673
+ "treatments": [
674
+ "Apply fungicide spray",
675
+ "Remove affected leaves",
676
+ "Improve air circulation",
677
+ "Reduce watering frequency"
678
+ ] if result == "yes" else ["Continue regular care", "Monitor plant health"],
679
+ "prevention": [
680
+ "Regular plant inspection",
681
+ "Proper spacing between plants",
682
+ "Avoid overhead watering",
683
+ "Good garden hygiene"
684
+ ]
685
+ }
686
+
687
+ # Save to database
688
+ try:
689
+ con = conn()
690
+ cur = con.cursor()
691
+ cur.execute("""
692
+ INSERT INTO leaf_analysis (user_id, image_data, plant_type, result,
693
+ disease_detected, analysis_data, created_at)
694
+ VALUES (%s, %s, %s, %s, %s, %s, %s)
695
+ """, (request.user["user_id"], image_data, plant_type, result,
696
+ result == "yes", json.dumps(response_data), datetime.datetime.now()))
697
+ con.commit()
698
+ except Exception as db_error:
699
+ print(f"Database error in leaf analysis: {db_error}")
700
+ # Continue without saving to database
701
+
702
+ return jsonify(response_data), 200
703
+
704
+ except Exception as e:
705
+ print(f"Leaf analysis error: {e}")
706
+ return jsonify({"error": "Failed to analyze leaf image"}), 500
707
+ finally:
708
+ if 'cur' in locals():
709
+ cur.close()
710
+ if 'con' in locals():
711
+ con.close()
712
+
713
+ @app.route("/api/leaf-analysis/history", methods=["GET"])
714
+ @token_required
715
+ def get_leaf_analysis_history():
716
+ """Get user's leaf analysis history"""
717
+ try:
718
+ con = conn()
719
+ cur = con.cursor(dictionary=True)
720
+ cur.execute("""
721
+ SELECT id, plant_type, result, disease_detected, analysis_data, created_at
722
+ FROM leaf_analysis
723
+ WHERE user_id = %s
724
+ ORDER BY created_at DESC
725
+ LIMIT 20
726
+ """, (request.user["user_id"],))
727
+
728
+ history = cur.fetchall()
729
+
730
+ # Parse JSON analysis results
731
+ for item in history:
732
+ if item['analysis_data']:
733
+ item['analysis_data'] = json.loads(item['analysis_data'])
734
+
735
+ return jsonify({"history": history}), 200
736
+
737
+ except Exception as e:
738
+ print(f"Leaf analysis history error: {e}")
739
+ return jsonify({"history": []}), 200
740
+ finally:
741
+ if 'cur' in locals():
742
+ cur.close()
743
+ if 'con' in locals():
744
+ con.close()
745
+
746
+ # ============= SOIL ANALYSIS (IMAGE + YES/NO) =============
747
+
748
+ @app.route("/api/soil-analysis", methods=["POST"])
749
+ @token_required
750
+ def soil_analysis():
751
+ """Soil analysis with image input - returns yes/no for soil quality"""
752
+ try:
753
+ # Handle image input
754
+ image_data = None
755
+ if 'image' in request.files:
756
+ image_file = request.files['image']
757
+ image = Image.open(image_file.stream)
758
+ buffered = io.BytesIO()
759
+ image.save(buffered, format="JPEG")
760
+ image_data = base64.b64encode(buffered.getvalue()).decode()
761
+ elif request.json and 'image_base64' in request.json:
762
+ image_data = request.json['image_base64']
763
+ if ',' in image_data:
764
+ image_data = image_data.split(',')[1]
765
+ else:
766
+ return jsonify({"error": "No image provided"}), 400
767
+
768
+ # Generate random yes/no result for soil quality
769
+ result = random.choice(["yes", "no"])
770
+
771
+ response_data = {
772
+ "result": result,
773
+ "soil_quality": "good" if result == "yes" else "poor",
774
+ "message": "Soil appears healthy and fertile" if result == "yes" else "Soil needs improvement",
775
+ "confidence": random.randint(75, 95),
776
+ "soil_type": random.choice(["Loamy", "Clay", "Sandy", "Silty"]),
777
+ "ph_level": round(random.uniform(5.5, 8.0), 1),
778
+ "nutrients": {
779
+ "nitrogen": random.choice(["low", "medium", "high"]),
780
+ "phosphorus": random.choice(["low", "medium", "high"]),
781
+ "potassium": random.choice(["low", "medium", "high"])
782
+ },
783
+ "recommendations": [
784
+ "Add organic compost",
785
+ "Test pH levels regularly",
786
+ "Consider crop rotation"
787
+ ] if result == "yes" else [
788
+ "Add organic matter",
789
+ "Improve drainage",
790
+ "Test for nutrient deficiencies",
791
+ "Consider soil amendments"
792
+ ],
793
+ "suitable_crops": [
794
+ "Tomatoes", "Wheat", "Corn", "Beans"
795
+ ] if result == "yes" else [
796
+ "Cover crops", "Legumes for nitrogen fixing"
797
+ ]
798
+ }
799
+
800
+ # Save to database
801
+ try:
802
+ con = conn()
803
+ cur = con.cursor()
804
+ cur.execute("""
805
+ INSERT INTO soil_analysis (user_id, image_data, result, soil_quality,
806
+ analysis_data, created_at)
807
+ VALUES (%s, %s, %s, %s, %s, %s)
808
+ """, (request.user["user_id"], image_data, result, response_data["soil_quality"],
809
+ json.dumps(response_data), datetime.datetime.now()))
810
+ con.commit()
811
+ except Exception as db_error:
812
+ print(f"Database error in soil analysis: {db_error}")
813
+ # Continue without saving to database
814
+
815
+ return jsonify(response_data), 200
816
+
817
+ except Exception as e:
818
+ print(f"Soil analysis error: {e}")
819
+ return jsonify({"error": "Failed to analyze soil image"}), 500
820
+ finally:
821
+ if 'cur' in locals():
822
+ cur.close()
823
+ if 'con' in locals():
824
+ con.close()
825
+
826
+ @app.route("/api/soil-analysis/history", methods=["GET"])
827
+ @token_required
828
+ def get_soil_analysis_history():
829
+ """Get user's soil analysis history"""
830
+ try:
831
+ con = conn()
832
+ cur = con.cursor(dictionary=True)
833
+ cur.execute("""
834
+ SELECT id, result, soil_quality, analysis_data, created_at
835
+ FROM soil_analysis
836
+ WHERE user_id = %s
837
+ ORDER BY created_at DESC
838
+ LIMIT 20
839
+ """, (request.user["user_id"],))
840
+
841
+ history = cur.fetchall()
842
+
843
+ # Parse JSON analysis results
844
+ for item in history:
845
+ if item['analysis_data']:
846
+ item['analysis_data'] = json.loads(item['analysis_data'])
847
+
848
+ return jsonify({"history": history}), 200
849
+
850
+ except Exception as e:
851
+ print(f"Soil history error: {e}")
852
+ return jsonify({"history": []}), 200
853
+ finally:
854
+ if 'cur' in locals():
855
+ cur.close()
856
+ if 'con' in locals():
857
+ con.close()
858
+
859
  # ============= DEFAULT ROUTE =============
860
 
861
  @app.route("/", methods=["GET"])