2525 LookupData ,
2626 MetaInfo ,
2727 MissingLanguageError ,
28+ MissingLookup ,
2829 MissingStructureError ,
2930 SiteVisit ,
3031)
@@ -63,6 +64,16 @@ def store_lookup_info(request, visit, language1, version1, language2, version2,
6364 info .save ()
6465
6566
67+ def store_missing_info (visit , item_type , item_value , language_context = None ):
68+ info = MissingLookup (
69+ item_type = item_type ,
70+ item_value = item_value ,
71+ language_context = language_context ,
72+ site_visit = visit
73+ )
74+ info .save ()
75+
76+
6677@require_http_methods (['GET' ])
6778def index (request ):
6879 """
@@ -239,6 +250,34 @@ def statistics(request):
239250 'date_time' : item .date_time
240251 })
241252
253+ # Missing items statistics
254+ missing_items_counts = MissingLookup .objects .values ('item_type' , 'item_value' , 'language_context' ) \
255+ .annotate (count = Count ('id' )).order_by ('-count' )[:15 ]
256+
257+ missing_items = []
258+ for item in missing_items_counts :
259+ label = item ['item_value' ]
260+ if item ['item_type' ] == 'language' :
261+ label = f"Language: { item ['item_value' ]} "
262+ elif item ['item_type' ] == 'structure' :
263+ try :
264+ lang_name = meta_info .language_name (item ['language_context' ])
265+ except (KeyError , MissingLanguageError ):
266+ lang_name = item ['language_context' ]
267+ label = f"Structure: { item ['item_value' ]} (for { lang_name } )"
268+ elif item ['item_type' ] == 'concept' :
269+ try :
270+ lang_name = meta_info .language_name (item ['language_context' ])
271+ except (KeyError , MissingLanguageError ):
272+ lang_name = item ['language_context' ]
273+ label = f"Concept: { item ['item_value' ]} (missing in { lang_name } )"
274+
275+ missing_items .append ({
276+ 'label' : label ,
277+ 'count' : item ['count' ],
278+ 'type' : item ['item_type' ]
279+ })
280+
242281 import json
243282 context = {
244283 'title' : 'Statistics' ,
@@ -247,6 +286,7 @@ def statistics(request):
247286 'popular_comparisons' : popular_comparisons ,
248287 'popular_concept_langs' : popular_concept_langs ,
249288 'recent_lookups' : recent_lookups ,
289+ 'missing_items' : missing_items ,
250290 'total_visits' : total_visits ,
251291 'total_lookups' : total_lookups ,
252292 'unique_comparisons_count' : unique_comparisons_count ,
@@ -300,6 +340,12 @@ def concepts(request):
300340 try :
301341 languages = meta_info .load_languages (language_strings , meta_structure )
302342 except MissingStructureError as missing_structure :
343+ store_missing_info (
344+ visit ,
345+ 'structure' ,
346+ missing_structure .structure .key ,
347+ missing_structure .language_key
348+ )
303349 return HttpResponseNotFound (render (
304350 request ,
305351 "error_missing_structure.html" ,
@@ -317,6 +363,7 @@ def concepts(request):
317363 }
318364 ))
319365 except MissingLanguageError as missing_language :
366+ store_missing_info (visit , 'language' , missing_language .key )
320367 errors .append (f"The language \" { missing_language .key } \" isn't valid. \
321368 Double-check your URL and try again." )
322369
@@ -338,7 +385,7 @@ def concepts(request):
338385
339386 for (category_key , category ) in meta_structure .categories .items ():
340387 concept_keys = list (category .keys ())
341- concepts_list = [concepts_data (key , name , languages , lexers ) for (key , name ) in category .items ()]
388+ concepts_list = [concepts_data (key , name , languages , lexers , visit ) for (key , name ) in category .items ()]
342389
343390 category_entry = {
344391 "key" : category_key ,
@@ -503,19 +550,25 @@ def format_comment_for_display(concept_key, lang):
503550 return lang .concept_comment (concept_key )
504551
505552
506- def concepts_data (key , name , languages , lexers = None ):
553+ def concepts_data (key , name , languages , lexers = None , visit = None ):
507554 """
508555 Generates the comparision object of a single concept
509556
510557 :param key: key of the concept
511558 :param name: name of the concept
512559 :param languages: list of languages to compare / get a reference for
513560 :param lexers: optional list of pre-fetched lexers corresponding to languages
561+ :param visit: optional SiteVisit for logging missing items
514562 :return: string with code with applied HTML formatting
515563 """
516564 data = []
517565 for i , lang in enumerate (languages ):
518566 lexer = lexers [i ] if lexers else None
567+
568+ # Log if concept is not implemented
569+ if visit and not lang .concept_implemented (key ):
570+ store_missing_info (visit , 'concept' , key , lang .key )
571+
519572 data .append ({
520573 "code" : format_code_for_display (key , lang , lexer ),
521574 "comment" : format_comment_for_display (key , lang )
@@ -584,9 +637,16 @@ def api_reference(request, structure_key, lang, version):
584637 try :
585638 response = lang_obj .load_filled_concepts (structure_key , version )
586639 except Exception as e :
640+ # Determine if it's a language or structure issue
641+ # If Language(lang, "") failed to find versions, it might be a language issue
642+ if not lang_obj .versions ():
643+ store_missing_info (visit , 'language' , lang )
644+ else :
645+ store_missing_info (visit , 'structure' , structure_key , lang )
587646 return error_handler_404_not_found (request , e )
588647
589648 if response is False :
649+ store_missing_info (visit , 'structure' , structure_key , lang )
590650 return HttpResponseNotFound ()
591651
592652 store_lookup_info (
@@ -615,9 +675,15 @@ def api_compare(request, structure_key, lang1, version1, lang2, version2):
615675 """
616676 visit = store_url_info (request )
617677
618- response = Language (lang1 , "" ).load_comparison (structure_key , lang2 , version2 , version1 )
678+ try :
679+ response = Language (lang1 , "" ).load_comparison (structure_key , lang2 , version2 , version1 )
680+ except Exception :
681+ # Simple logging for now
682+ store_missing_info (visit , 'structure' , structure_key , f"{ lang1 } /{ lang2 } " )
683+ return HttpResponseNotFound ()
619684
620685 if response is False :
686+ store_missing_info (visit , 'structure' , structure_key , f"{ lang1 } /{ lang2 } " )
621687 return HttpResponseNotFound ()
622688
623689 store_lookup_info (
0 commit comments