@@ -25,39 +25,27 @@ def get_geo_data(ip):
2525def load_data_from_mongodb (app ):
2626 """Load data from MongoDB into pandas DataFrame"""
2727 try :
28- # Get all records from the visits collection
2928 cursor = app .data_collection .find ({})
3029 data = list (cursor )
31-
32- # Convert to DataFrame
3330 df = pd .DataFrame (data )
34-
35- # Update geo data for records with missing coordinates
3631 for index , row in df .iterrows ():
3732 if not row .get ('geo' ) or row .get ('geoAccuracy' ) == '—' or row .get ('geoAccuracy' ) == '' :
3833 ip = row .get ('ip' )
3934 if ip :
4035 geo_data = get_geo_data (ip )
4136 if geo_data :
4237 df .at [index , 'geo' ] = geo_data
43-
4438 return df
4539 except Exception as e :
4640 print (f"Error loading data from MongoDB: { str (e )} " )
4741 return pd .DataFrame ()
4842
49- def create_map_visualization (df , output_pattern ):
43+ def create_map_visualization (df , output_pattern , num ):
5044 """Create a map visualization of visitor locations"""
5145 try :
52- # Create a map centered at a default location
5346 m = folium .Map (location = [0 , 0 ], zoom_start = 2 )
54-
55- # Add a marker cluster
5647 marker_cluster = MarkerCluster ().add_to (m )
57-
58- # Count occurrences of each location
5948 location_counts = {}
60-
6149 for _ , row in df .iterrows ():
6250 geo = row .get ('geo' )
6351 if geo and ',' in geo :
@@ -67,8 +55,6 @@ def create_map_visualization(df, output_pattern):
6755 location_counts [location_key ] = location_counts .get (location_key , 0 ) + 1
6856 except ValueError :
6957 continue
70-
71- # Add markers for each location
7258 for loc_key , count in location_counts .items ():
7359 try :
7460 lat , lon = map (float , loc_key .split (',' ))
@@ -80,70 +66,54 @@ def create_map_visualization(df, output_pattern):
8066 ).add_to (marker_cluster )
8167 except ValueError :
8268 continue
83-
84- # Save the map
85- map_file = output_pattern .format (3 )
69+ map_file = output_pattern .format (num )
8670 m .save (map_file )
87-
8871 return True
8972 except Exception as e :
9073 print (f"Error creating map visualization: { str (e )} " )
9174 return False
9275
93- def create_language_chart (df , output_pattern ):
76+ def create_language_chart (df , output_pattern , num ):
9477 """Create a bar chart of visitor languages"""
9578 try :
96- # Get unique visitors by IP
9779 unique_df = df .drop_duplicates (subset = ['ip' ])
98-
99- # Count languages
10080 language_counts = unique_df ['language' ].value_counts ()
101-
10281 plt .figure (figsize = (12 , 6 ))
10382 language_counts .plot (kind = 'bar' )
10483 plt .title ('Languages of Unique Visitors' )
10584 plt .xlabel ('Language' )
10685 plt .ylabel ('Count' )
10786 plt .tight_layout ()
108- plt .savefig (output_pattern .format (4 ))
87+ plt .savefig (output_pattern .format (num ))
10988 plt .close ()
110-
11189 return True
11290 except Exception as e :
11391 print (f"Error creating language chart: { str (e )} " )
11492 return False
11593
116- def create_screen_resolution_chart (df , output_pattern ):
94+ def create_screen_resolution_chart (df , output_pattern , num ):
11795 """Create a bar chart of screen resolutions"""
11896 try :
119- # Get unique visitors by IP
12097 unique_df = df .drop_duplicates (subset = ['ip' ])
121-
122- # Count screen resolutions
123- screen_counts = unique_df ['screen' ].value_counts ().head (10 ) # Top 10 resolutions
124-
98+ screen_counts = unique_df ['screen' ].value_counts ().head (10 )
12599 plt .figure (figsize = (12 , 6 ))
126100 screen_counts .plot (kind = 'bar' )
127101 plt .title ('Screen Resolutions of Unique Visitors (Top 10)' )
128102 plt .xlabel ('Resolution' )
129103 plt .ylabel ('Count' )
130104 plt .xticks (rotation = 45 )
131105 plt .tight_layout ()
132- plt .savefig (output_pattern .format (5 ))
106+ plt .savefig (output_pattern .format (num ))
133107 plt .close ()
134-
135108 return True
136109 except Exception as e :
137110 print (f"Error creating screen resolution chart: { str (e )} " )
138111 return False
139112
140- def create_os_visualization (df , output_pattern ):
113+ def create_os_visualization (df , output_pattern , num ):
141114 """Create visualization of operating systems"""
142115 try :
143- # Get unique visitors by IP
144116 unique_df = df .drop_duplicates (subset = ['ip' ])
145-
146- # Define OS categories and their patterns
147117 os_categories = {
148118 'Windows' : ['Win32' , 'Win64' , 'Win16' , 'WinCE' , 'Windows' ],
149119 'Mac' : ['MacIntel' , 'MacPPC' , 'Mac68K' , 'Mac' , 'macOS' ],
@@ -152,198 +122,111 @@ def create_os_visualization(df, output_pattern):
152122 'Android' : ['Android' ],
153123 'Other' : ['SunOS' , 'HP-UX' ]
154124 }
155-
156- # Categorize platforms
157125 def categorize_os (platform ):
158126 for category , patterns in os_categories .items ():
159127 if any (pattern in platform for pattern in patterns ):
160128 return category
161129 return 'Other'
162-
163130 unique_df ['os_category' ] = unique_df ['platform' ].apply (categorize_os )
164131 os_counts = unique_df ['os_category' ].value_counts ()
165-
166- # Create figure with OS icons
167132 fig , ax = plt .subplots (figsize = (14 , 8 ))
168-
169- # Define positions for each OS category
170133 categories = list (os_categories .keys ())
171134 positions = np .arange (len (categories ))
172-
173- # Create bars
174135 bars = ax .bar (positions , [os_counts .get (cat , 0 ) for cat in categories ])
175-
176- # Add percentages and counts
177136 total = os_counts .sum ()
178137 for i , bar in enumerate (bars ):
179138 count = os_counts .get (categories [i ], 0 )
180139 percentage = (count / total ) * 100 if total > 0 else 0
181140 ax .text (bar .get_x () + bar .get_width ()/ 2 , bar .get_height () + 5 ,
182141 f"{ percentage :.1f} %\n ({ count } )" ,
183142 ha = 'center' , va = 'bottom' )
184-
185143 ax .set_xticks (positions )
186144 ax .set_xticklabels (categories )
187145 ax .set_title ('Operating Systems of Unique Visitors' )
188146 ax .set_ylabel ('Count' )
189-
190147 plt .tight_layout ()
191- plt .savefig (output_pattern .format (6 ))
148+ plt .savefig (output_pattern .format (num ))
192149 plt .close ()
193-
194150 return True
195151 except Exception as e :
196152 print (f"Error creating OS visualization: { str (e )} " )
197153 return False
198154
199- def create_browser_visualization (df , output_pattern ):
155+ def create_browser_visualization (df , output_pattern , num ):
200156 """Create visualization of browsers"""
201157 try :
202- # Get unique visitors by IP
203158 unique_df = df .drop_duplicates (subset = ['ip' ])
204-
205- # Count browsers
206159 browser_counts = unique_df ['browserName' ].value_counts ()
207-
208- # Create figure
209160 fig , ax = plt .subplots (figsize = (14 , 8 ))
210-
211- # Create bars
212161 positions = np .arange (len (browser_counts ))
213162 bars = ax .bar (positions , browser_counts .values )
214-
215- # Add percentages and counts
216163 total = browser_counts .sum ()
217164 for i , bar in enumerate (bars ):
218165 count = browser_counts .values [i ]
219166 percentage = (count / total ) * 100
220167 ax .text (bar .get_x () + bar .get_width ()/ 2 , bar .get_height () + 5 ,
221168 f"{ percentage :.1f} %\n ({ count } )" ,
222169 ha = 'center' , va = 'bottom' )
223-
224170 ax .set_xticks (positions )
225171 ax .set_xticklabels (browser_counts .index )
226172 ax .set_title ('Browsers of Unique Visitors' )
227173 ax .set_ylabel ('Count' )
228-
229174 plt .tight_layout ()
230- plt .savefig (output_pattern .format (7 ))
175+ plt .savefig (output_pattern .format (num ))
231176 plt .close ()
232-
233177 return True
234178 except Exception as e :
235179 print (f"Error creating browser visualization: { str (e )} " )
236180 return False
237181
238- def create_media_devices_table (df , output_pattern ):
182+ def create_media_devices_table (df , output_pattern , num ):
239183 """Create table of media devices access"""
240184 try :
241- # Get unique visitors by IP
242185 unique_df = df .drop_duplicates (subset = ['ip' ])
243-
244- # Extract media device information
245186 media_data = {
246187 'Device' : ['Speakers' , 'Microphones' , 'Webcams' ],
247188 'Count' : [0 , 0 , 0 ],
248189 'Percentage' : [0 , 0 , 0 ]
249190 }
250-
251191 total_visitors = len (unique_df )
252-
253192 if 'multimediaDevices' in unique_df .columns :
254- # Count devices
255193 speakers_count = unique_df ['multimediaDevices' ].apply (
256194 lambda x : x .get ('speakers' , 0 ) > 0 if isinstance (x , dict ) else False
257195 ).sum ()
258-
259196 micros_count = unique_df ['multimediaDevices' ].apply (
260197 lambda x : x .get ('micros' , 0 ) > 0 if isinstance (x , dict ) else False
261198 ).sum ()
262-
263199 webcams_count = unique_df ['multimediaDevices' ].apply (
264200 lambda x : x .get ('webcams' , 0 ) > 0 if isinstance (x , dict ) else False
265201 ).sum ()
266-
267- # Update data
268202 media_data ['Count' ] = [speakers_count , micros_count , webcams_count ]
269203 media_data ['Percentage' ] = [
270204 (speakers_count / total_visitors ) * 100 if total_visitors > 0 else 0 ,
271205 (micros_count / total_visitors ) * 100 if total_visitors > 0 else 0 ,
272206 (webcams_count / total_visitors ) * 100 if total_visitors > 0 else 0
273207 ]
274-
275- # Create table
276208 fig , ax = plt .subplots (figsize = (10 , 6 ))
277209 ax .axis ('tight' )
278210 ax .axis ('off' )
279-
280- # Format percentage values
281211 formatted_percentages = [f"{ p :.1f} %" for p in media_data ['Percentage' ]]
282-
283212 table_data = [
284213 media_data ['Device' ],
285214 media_data ['Count' ],
286215 formatted_percentages
287216 ]
288-
289217 table = ax .table (
290218 cellText = list (zip (* table_data )),
291219 colLabels = ['Device' , 'Count' , 'Percentage' ],
292220 loc = 'center' ,
293221 cellLoc = 'center'
294222 )
295-
296223 table .auto_set_font_size (False )
297224 table .set_fontsize (12 )
298225 table .scale (1.2 , 1.5 )
299-
300226 plt .title ('Media Devices Access' )
301- plt .savefig (output_pattern .format (8 ))
227+ plt .savefig (output_pattern .format (num ))
302228 plt .close ()
303-
304229 return True
305230 except Exception as e :
306231 print (f"Error creating media devices table: { str (e )} " )
307- return False
308-
309- def generate_statistics_images (stats_data , output_pattern ):
310- """Generate visualization images from statistics data"""
311- try :
312- # Basic period statistics visualizations
313- periods = list (stats_data ['periodStats' ].keys ())
314- totals = [v ['total' ] for v in stats_data ['periodStats' ].values ()]
315- uniques = [v ['unique' ] for v in stats_data ['periodStats' ].values ()]
316-
317- plt .figure (figsize = (10 , 6 ))
318- plt .bar (periods , totals , label = 'Total Visits' )
319- plt .bar (periods , uniques , label = 'Unique Visitors' )
320- plt .title ('Visitors Statistics' )
321- plt .legend ()
322- plt .savefig (output_pattern .format (1 ))
323- plt .close ()
324-
325- # Pie chart for period distribution
326- plt .figure (figsize = (8 , 8 ))
327- plt .pie (totals , labels = periods , autopct = '%1.1f%%' )
328- plt .title ('Visits Distribution' )
329- plt .savefig (output_pattern .format (2 ))
330- plt .close ()
331-
332- # Get app from current context if available
333- from flask import current_app
334- app = current_app ._get_current_object ()
335-
336- # Load data from MongoDB
337- df = load_data_from_mongodb (app )
338-
339- if not df .empty :
340- # Create additional visualizations
341- create_map_visualization (df , output_pattern )
342- create_language_chart (df , output_pattern )
343- create_screen_resolution_chart (df , output_pattern )
344- create_os_visualization (df , output_pattern )
345- create_browser_visualization (df , output_pattern )
346- create_media_devices_table (df , output_pattern )
347-
348- except Exception as e :
349- print (f"Error generating images: { str (e )} " )
232+ return False
0 commit comments