File size: 8,694 Bytes
64a54ba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
import requests
import pandas as pd
from PIL import Image
import os
import subprocess
from bs4 import BeautifulSoup
import urllib.parse

def web_search(query: str, api_key: str = None) -> str:
    """
    Perform web search using SerpAPI if available, otherwise fallback to DuckDuckGo scraping.
    """
    if api_key and api_key != "your-serpapi-key-here":
        return _serpapi_search(query, api_key)
    else:
        return _duckduckgo_search(query)

def _serpapi_search(query: str, api_key: str) -> str:
    """Search using SerpAPI."""
    try:
        url = f"https://serpapi.com/search"
        params = {
            "q": query,
            "api_key": api_key,
            "engine": "google"
        }
        response = requests.get(url, params=params, timeout=10)
        response.raise_for_status()
        
        results = response.json()
        organic_results = results.get("organic_results", [])
        
        if organic_results:
            # Get top 3 results
            search_summary = []
            for i, result in enumerate(organic_results[:3]):
                title = result.get("title", "")
                snippet = result.get("snippet", "")
                if title and snippet:
                    search_summary.append(f"{i+1}. {title}: {snippet}")
            
            return "\n".join(search_summary) if search_summary else "No useful results found"
        else:
            return "No search results found"
            
    except requests.RequestException as e:
        print(f"SerpAPI search error: {e}")
        return "Search failed"

def _duckduckgo_search(query: str) -> str:
    """Fallback web search using DuckDuckGo scraping."""
    try:
        # DuckDuckGo instant answer API
        url = "https://api.duckduckgo.com/"
        params = {
            "q": query,
            "format": "json",
            "no_html": "1",
            "skip_disambig": "1"
        }
        
        response = requests.get(url, params=params, timeout=10)
        response.raise_for_status()
        
        data = response.json()
        
        # Try to get instant answer
        abstract = data.get("Abstract", "")
        if abstract:
            return f"Summary: {abstract}"
        
        # Try related topics
        related_topics = data.get("RelatedTopics", [])
        if related_topics:
            summaries = []
            for topic in related_topics[:3]:
                if isinstance(topic, dict) and "Text" in topic:
                    summaries.append(topic["Text"])
            if summaries:
                return "Related information:\n" + "\n".join(summaries)
        
        # Fallback to web scraping (simplified)
        return _simple_web_scrape(query)
        
    except Exception as e:
        print(f"DuckDuckGo search error: {e}")
        return "Search failed"

def _simple_web_scrape(query: str) -> str:
    """Simple web scraping fallback."""
    try:
        # Use a simple search approach
        search_url = f"https://html.duckduckgo.com/html/?q={urllib.parse.quote(query)}"
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        }
        
        response = requests.get(search_url, headers=headers, timeout=10)
        if response.status_code == 200:
            soup = BeautifulSoup(response.content, 'html.parser')
            # Try to extract some basic information
            results = soup.find_all('a', class_='result__snippet')[:3]
            if results:
                snippets = [r.get_text().strip() for r in results if r.get_text().strip()]
                return "\n".join(snippets[:3]) if snippets else "Limited search results available"
        
        return "Basic web search completed - limited results"
        
    except Exception as e:
        print(f"Web scraping error: {e}")
        return "Web search unavailable"

def read_file(file_name: str) -> str:
    """
    Read and process different file types (text, CSV, images).
    """
    if not file_name or not os.path.exists(file_name):
        return "File not found"
    
    try:
        file_extension = os.path.splitext(file_name)[1].lower()
        
        if file_extension == ".csv":
            return _read_csv_file(file_name)
        elif file_extension in [".png", ".jpg", ".jpeg", ".gif", ".bmp"]:
            return _read_image_file(file_name)
        elif file_extension in [".txt", ".md", ".py", ".js", ".html", ".json"]:
            return _read_text_file(file_name)
        else:
            # Try to read as text file
            return _read_text_file(file_name)
            
    except Exception as e:
        return f"Error reading file: {str(e)}"

def _read_text_file(file_name: str) -> str:
    """Read a text file."""
    try:
        with open(file_name, "r", encoding="utf-8") as f:
            content = f.read()
        return content[:5000]  # Limit to first 5000 characters
    except UnicodeDecodeError:
        # Try with different encoding
        try:
            with open(file_name, "r", encoding="latin-1") as f:
                content = f.read()
            return content[:5000]
        except Exception as e:
            return f"Text file reading error: {str(e)}"

def _read_csv_file(file_name: str) -> str:
    """Read and summarize a CSV file."""
    try:
        df = pd.read_csv(file_name)
        
        # Create a summary
        summary = []
        summary.append(f"CSV file shape: {df.shape[0]} rows, {df.shape[1]} columns")
        summary.append(f"Columns: {', '.join(df.columns.tolist())}")
        
        # Show first few rows
        summary.append("\nFirst 5 rows:")
        summary.append(df.head().to_string())
        
        # Show basic statistics for numeric columns
        numeric_columns = df.select_dtypes(include=['number']).columns
        if len(numeric_columns) > 0:
            summary.append(f"\nNumeric column statistics:")
            summary.append(df[numeric_columns].describe().to_string())
        
        return "\n".join(summary)
        
    except Exception as e:
        return f"CSV reading error: {str(e)}"

def _read_image_file(file_name: str) -> str:
    """Read and analyze an image file."""
    try:
        # Try OCR first
        try:
            import pytesseract
            img = Image.open(file_name)
            
            # Get image info
            info = f"Image: {img.size[0]}x{img.size[1]} pixels, mode: {img.mode}"
            
            # Try OCR
            text = pytesseract.image_to_string(img).strip()
            if text:
                return f"{info}\n\nExtracted text:\n{text}"
            else:
                return f"{info}\n\nNo text detected in image."
                
        except ImportError:
            # OCR not available, just return image info
            img = Image.open(file_name)
            return f"Image: {img.size[0]}x{img.size[1]} pixels, mode: {img.mode}\n(OCR not available - install pytesseract for text extraction)"
            
    except Exception as e:
        return f"Image reading error: {str(e)}"

def execute_code(code: str, timeout: int = 10) -> str:
    """
    Execute Python code safely with timeout.
    """
    try:
        # Basic security check - prevent dangerous operations
        dangerous_keywords = ["import os", "import subprocess", "__import__", "exec", "eval", "open("]
        if any(keyword in code.lower() for keyword in dangerous_keywords):
            return "Code execution blocked: potentially unsafe operations detected"
        
        result = subprocess.run(
            ["python3", "-c", code],
            capture_output=True,
            text=True,
            timeout=timeout,
            cwd="/tmp"  # Run in safe directory
        )
        
        if result.returncode == 0:
            return result.stdout.strip() if result.stdout else "Code executed successfully (no output)"
        else:
            return f"Code execution error: {result.stderr.strip()}"
            
    except subprocess.TimeoutExpired:
        return "Code execution timeout"
    except Exception as e:
        return f"Code execution error: {str(e)}"

def calculate_simple_math(expression: str) -> str:
    """
    Safely evaluate simple mathematical expressions.
    """
    try:
        # Only allow basic math characters
        allowed_chars = set("0123456789+-*/.() ")
        if not all(c in allowed_chars for c in expression):
            return "Invalid mathematical expression"
        
        # Use eval safely for basic math
        result = eval(expression)
        return str(result)
        
    except Exception as e:
        return f"Math calculation error: {str(e)}"