Update app.py
Browse files
app.py
CHANGED
@@ -508,12 +508,7 @@ def format_question(q: Dict) -> str:
|
|
508 |
try:
|
509 |
# Extract and validate basic question data
|
510 |
title = q.get('title', 'Untitled')
|
511 |
-
source = q.get('source', '').lower()
|
512 |
-
|
513 |
-
# Log available fields for debugging
|
514 |
-
logger.info(f"Question fields: {list(q.keys())}")
|
515 |
-
if 'created_utc_ts' in q:
|
516 |
-
logger.info(f"Raw created_utc_ts value: {q['created_utc_ts']}")
|
517 |
|
518 |
# Format metadata section based on source
|
519 |
metadata_html = ""
|
@@ -523,19 +518,18 @@ def format_question(q: Dict) -> str:
|
|
523 |
if 'author' in q or 'created_utc_ts' in q:
|
524 |
author = q.get('author', 'Unknown author')
|
525 |
created_date = format_neo4j_datetime(q.get('created_utc_ts'))
|
526 |
-
logger.info(f"Question {title}: author={author}, date={created_date}")
|
527 |
upvotes = q.get('upvotes', 0)
|
528 |
num_comments = q.get('num_comments', 0)
|
529 |
|
530 |
metadata_html = f"""
|
531 |
-
<div class="question-meta" style="font-size: 0.9em;
|
532 |
-
<span style="color: #
|
533 |
{' asked' if source == 'stack_exchange' else ' posted'} on
|
534 |
-
<span style="color: #
|
535 |
<div class="stats" style="margin-top: 5px;">
|
536 |
-
<span title="Upvotes"><span style="color: #
|
537 |
-
<span style="margin-left: 15px;" title="Comments"><span style="color: #
|
538 |
-
|
539 |
</div>
|
540 |
"""
|
541 |
|
@@ -544,7 +538,7 @@ def format_question(q: Dict) -> str:
|
|
544 |
body = q.get('body', '')
|
545 |
if body:
|
546 |
content_html = f"""
|
547 |
-
<div class="question-content" style="margin-top: 20px; font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; color: #
|
548 |
{process_body(body, title)}
|
549 |
</div>
|
550 |
"""
|
@@ -553,12 +547,11 @@ def format_question(q: Dict) -> str:
|
|
553 |
correct_answer = q.get('correct_answer', '')
|
554 |
incorrect_answers = q.get('incorrect_answers', [])
|
555 |
|
556 |
-
# Create answer options HTML
|
557 |
answers = [correct_answer] + incorrect_answers if incorrect_answers else [correct_answer]
|
558 |
answers_html = "".join([
|
559 |
f"""
|
560 |
-
<div class="answer-option" style="margin: 8px 0; padding: 10px; background:
|
561 |
-
<span style="color:
|
562 |
{answer}
|
563 |
</span>
|
564 |
</div>
|
@@ -568,7 +561,7 @@ def format_question(q: Dict) -> str:
|
|
568 |
|
569 |
content_html = f"""
|
570 |
<div class="answers-container" style="margin-top: 15px;">
|
571 |
-
<div style="color: #
|
572 |
{answers_html}
|
573 |
</div>
|
574 |
"""
|
@@ -577,56 +570,53 @@ def format_question(q: Dict) -> str:
|
|
577 |
correct_answer = q.get('correct_answer', '')
|
578 |
if correct_answer:
|
579 |
content_html = f"""
|
580 |
-
<div class="answer" style="margin-top: 15px; padding: 15px; background:
|
581 |
-
<div style="color: #
|
582 |
-
<div style="color: #
|
583 |
</div>
|
584 |
"""
|
585 |
|
586 |
elif source == "reddit":
|
587 |
-
# Add subreddit to metadata if available
|
588 |
if 'subreddit' in q:
|
589 |
subreddit = q.get('subreddit', '')
|
590 |
metadata_html = metadata_html.replace(
|
591 |
'posted on',
|
592 |
-
f'posted in <span style="color: #
|
593 |
)
|
594 |
|
595 |
-
# If no specific content is set, try to use any available content fields
|
596 |
if not content_html:
|
597 |
if 'body' in q:
|
598 |
content_html = f"""
|
599 |
-
<div class="question-content" style="margin-top: 20px; font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; color: #
|
600 |
{process_body(q['body'], title)}
|
601 |
</div>
|
602 |
"""
|
603 |
elif 'correct_answer' in q:
|
604 |
content_html = f"""
|
605 |
-
<div class="answer" style="margin-top: 15px; padding: 15px; background:
|
606 |
-
<div style="color: #
|
607 |
-
<div style="color: #
|
608 |
</div>
|
609 |
"""
|
610 |
|
611 |
# Get source-specific icon and color
|
612 |
source_icon = {
|
613 |
-
'stack_exchange': 'β‘',
|
614 |
-
'reddit': 'πΈ',
|
615 |
-
'wikipedia': 'π',
|
616 |
-
'trivia': 'π―',
|
617 |
-
}.get(source, 'β')
|
618 |
|
619 |
source_color = {
|
620 |
-
'stack_exchange': '#
|
621 |
-
'reddit': '#
|
622 |
-
'wikipedia': '#
|
623 |
-
'trivia': '#
|
624 |
-
}.get(source, '#
|
625 |
|
626 |
-
# Create the source badge with icon
|
627 |
source_display = source.title() if source else "Unknown"
|
628 |
source_badge = f"""
|
629 |
-
<div class="source-badge" style="display: inline-flex; align-items: center; padding: 4px 8px; background:
|
630 |
<span style="margin-right: 6px; font-size: 1.1em;">{source_icon}</span>
|
631 |
<span style="color: {source_color}; font-size: 0.9em; font-weight: 500;">{source_display}</span>
|
632 |
</div>
|
@@ -643,11 +633,9 @@ def format_question(q: Dict) -> str:
|
|
643 |
'type': type_
|
644 |
})
|
645 |
|
646 |
-
# Format interests by type
|
647 |
keywords = [i['name'] for i in interests_with_types if i['type'] == 'keyword']
|
648 |
topics = [i['name'] for i in interests_with_types if i['type'] == 'topic']
|
649 |
|
650 |
-
# Create interests display string
|
651 |
interests_display = []
|
652 |
if keywords:
|
653 |
interests_display.append(f"Keywords: {format_interest_list(set(keywords), max_items=3)}")
|
@@ -655,30 +643,29 @@ def format_question(q: Dict) -> str:
|
|
655 |
interests_display.append(f"Topics: {format_interest_list(set(topics), max_items=3)}")
|
656 |
interests_str = " | ".join(interests_display) if interests_display else "No common interests found"
|
657 |
|
658 |
-
# Calculate relevance score display
|
659 |
relevance_score = q.get('relevance_score', 0)
|
660 |
score_display = f"""
|
661 |
-
<div class="relevance-score" style="display: inline-block; padding: 4px 8px; background:
|
662 |
-
<span style="color: #
|
663 |
</div>
|
664 |
""" if relevance_score > 0 else ""
|
665 |
|
666 |
# Create the question card HTML
|
667 |
question_html = f"""
|
668 |
-
<div class="question-card" style="background:
|
669 |
-
<div class="question-header" style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px;">
|
670 |
<div style="flex: 1; display: flex; align-items: center;">
|
671 |
{source_badge}
|
672 |
-
<h3 style="color: #
|
673 |
</div>
|
674 |
{score_display}
|
675 |
</div>
|
676 |
|
677 |
{metadata_html}
|
678 |
|
679 |
-
<div class="interests-bar" style="margin: 15px 0; padding: 10px; background:
|
680 |
-
<div style="color: #
|
681 |
-
<div style="color: #
|
682 |
</div>
|
683 |
|
684 |
{content_html}
|
@@ -690,8 +677,8 @@ def format_question(q: Dict) -> str:
|
|
690 |
except Exception as e:
|
691 |
logger.error(f"Error formatting question: {str(e)}")
|
692 |
return f"""
|
693 |
-
<div style="background:
|
694 |
-
<div style="color: #
|
695 |
</div>
|
696 |
"""
|
697 |
|
|
|
508 |
try:
|
509 |
# Extract and validate basic question data
|
510 |
title = q.get('title', 'Untitled')
|
511 |
+
source = q.get('source', '').lower()
|
|
|
|
|
|
|
|
|
|
|
512 |
|
513 |
# Format metadata section based on source
|
514 |
metadata_html = ""
|
|
|
518 |
if 'author' in q or 'created_utc_ts' in q:
|
519 |
author = q.get('author', 'Unknown author')
|
520 |
created_date = format_neo4j_datetime(q.get('created_utc_ts'))
|
|
|
521 |
upvotes = q.get('upvotes', 0)
|
522 |
num_comments = q.get('num_comments', 0)
|
523 |
|
524 |
metadata_html = f"""
|
525 |
+
<div class="question-meta" style="font-size: 0.9em; margin-bottom: 15px;">
|
526 |
+
<span style="color: #219ebc; font-weight: 500;">{author}</span>
|
527 |
{' asked' if source == 'stack_exchange' else ' posted'} on
|
528 |
+
<span style="color: #333333;">{created_date}</span>
|
529 |
<div class="stats" style="margin-top: 5px;">
|
530 |
+
<span title="Upvotes"><span style="color: #219ebc;">β²</span> {upvotes}</span>
|
531 |
+
<span style="margin-left: 15px;" title="Comments"><span style="color: #219ebc;">π¬</span> {num_comments}</span>
|
532 |
+
</div>
|
533 |
</div>
|
534 |
"""
|
535 |
|
|
|
538 |
body = q.get('body', '')
|
539 |
if body:
|
540 |
content_html = f"""
|
541 |
+
<div class="question-content" style="margin-top: 20px; font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; color: #333333; line-height: 1.6;">
|
542 |
{process_body(body, title)}
|
543 |
</div>
|
544 |
"""
|
|
|
547 |
correct_answer = q.get('correct_answer', '')
|
548 |
incorrect_answers = q.get('incorrect_answers', [])
|
549 |
|
|
|
550 |
answers = [correct_answer] + incorrect_answers if incorrect_answers else [correct_answer]
|
551 |
answers_html = "".join([
|
552 |
f"""
|
553 |
+
<div class="answer-option" style="margin: 8px 0; padding: 10px; background: #f9fafc; border-radius: 6px; border: 1px solid #8ecae6; border-left: 3px solid {'#219ebc' if answer == correct_answer else '#8ecae6'};">
|
554 |
+
<span style="color: #333333;">
|
555 |
{answer}
|
556 |
</span>
|
557 |
</div>
|
|
|
561 |
|
562 |
content_html = f"""
|
563 |
<div class="answers-container" style="margin-top: 15px;">
|
564 |
+
<div style="color: #333333; margin-bottom: 10px;">Answer options:</div>
|
565 |
{answers_html}
|
566 |
</div>
|
567 |
"""
|
|
|
570 |
correct_answer = q.get('correct_answer', '')
|
571 |
if correct_answer:
|
572 |
content_html = f"""
|
573 |
+
<div class="answer" style="margin-top: 15px; padding: 15px; background: #f9fafc; border-radius: 6px; border: 1px solid #8ecae6;">
|
574 |
+
<div style="color: #333333; margin-bottom: 10px;">Answer:</div>
|
575 |
+
<div style="color: #333333;">{correct_answer}</div>
|
576 |
</div>
|
577 |
"""
|
578 |
|
579 |
elif source == "reddit":
|
|
|
580 |
if 'subreddit' in q:
|
581 |
subreddit = q.get('subreddit', '')
|
582 |
metadata_html = metadata_html.replace(
|
583 |
'posted on',
|
584 |
+
f'posted in <span style="color: #219ebc; font-weight: 500;">r/{subreddit}</span> on'
|
585 |
)
|
586 |
|
|
|
587 |
if not content_html:
|
588 |
if 'body' in q:
|
589 |
content_html = f"""
|
590 |
+
<div class="question-content" style="margin-top: 20px; font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; color: #333333; line-height: 1.6;">
|
591 |
{process_body(q['body'], title)}
|
592 |
</div>
|
593 |
"""
|
594 |
elif 'correct_answer' in q:
|
595 |
content_html = f"""
|
596 |
+
<div class="answer" style="margin-top: 15px; padding: 15px; background: #f9fafc; border-radius: 6px; border: 1px solid #8ecae6;">
|
597 |
+
<div style="color: #333333; margin-bottom: 10px;">Answer:</div>
|
598 |
+
<div style="color: #333333;">{q['correct_answer']}</div>
|
599 |
</div>
|
600 |
"""
|
601 |
|
602 |
# Get source-specific icon and color
|
603 |
source_icon = {
|
604 |
+
'stack_exchange': 'β‘',
|
605 |
+
'reddit': 'πΈ',
|
606 |
+
'wikipedia': 'π',
|
607 |
+
'trivia': 'π―',
|
608 |
+
}.get(source, 'β')
|
609 |
|
610 |
source_color = {
|
611 |
+
'stack_exchange': '#219ebc',
|
612 |
+
'reddit': '#fb8500',
|
613 |
+
'wikipedia': '#4caf50',
|
614 |
+
'trivia': '#ffb703',
|
615 |
+
}.get(source, '#219ebc')
|
616 |
|
|
|
617 |
source_display = source.title() if source else "Unknown"
|
618 |
source_badge = f"""
|
619 |
+
<div class="source-badge" style="display: inline-flex; align-items: center; padding: 4px 8px; background: #f9fafc; border-radius: 4px; margin-right: 10px; border: 1px solid {source_color};">
|
620 |
<span style="margin-right: 6px; font-size: 1.1em;">{source_icon}</span>
|
621 |
<span style="color: {source_color}; font-size: 0.9em; font-weight: 500;">{source_display}</span>
|
622 |
</div>
|
|
|
633 |
'type': type_
|
634 |
})
|
635 |
|
|
|
636 |
keywords = [i['name'] for i in interests_with_types if i['type'] == 'keyword']
|
637 |
topics = [i['name'] for i in interests_with_types if i['type'] == 'topic']
|
638 |
|
|
|
639 |
interests_display = []
|
640 |
if keywords:
|
641 |
interests_display.append(f"Keywords: {format_interest_list(set(keywords), max_items=3)}")
|
|
|
643 |
interests_display.append(f"Topics: {format_interest_list(set(topics), max_items=3)}")
|
644 |
interests_str = " | ".join(interests_display) if interests_display else "No common interests found"
|
645 |
|
|
|
646 |
relevance_score = q.get('relevance_score', 0)
|
647 |
score_display = f"""
|
648 |
+
<div class="relevance-score" style="display: inline-block; padding: 4px 8px; background: #f9fafc; border-radius: 4px; margin-left: 10px; border: 1px solid #8ecae6;">
|
649 |
+
<span style="color: #219ebc; font-size: 0.9em;">Relevance: {relevance_score:.2f}</span>
|
650 |
</div>
|
651 |
""" if relevance_score > 0 else ""
|
652 |
|
653 |
# Create the question card HTML
|
654 |
question_html = f"""
|
655 |
+
<div class="question-card" style="background: #ffffff; padding: 20px; border-radius: 8px; margin: 15px 0; border: 1px solid #219ebc; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);">
|
656 |
+
<div class="question-header" style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px; border-bottom: 1px solid #8ecae6; padding-bottom: 10px;">
|
657 |
<div style="flex: 1; display: flex; align-items: center;">
|
658 |
{source_badge}
|
659 |
+
<h3 style="color: #023047; margin: 0; font-size: 1.4em; display: inline;">{title}</h3>
|
660 |
</div>
|
661 |
{score_display}
|
662 |
</div>
|
663 |
|
664 |
{metadata_html}
|
665 |
|
666 |
+
<div class="interests-bar" style="margin: 15px 0; padding: 10px; background: #f9fafc; border-radius: 6px; border: 1px solid #8ecae6; border-left: 3px solid #219ebc;">
|
667 |
+
<div style="color: #333333; font-size: 0.9em;">Common Interests:</div>
|
668 |
+
<div style="color: #219ebc; font-weight: 500; margin-top: 5px;">{interests_str}</div>
|
669 |
</div>
|
670 |
|
671 |
{content_html}
|
|
|
677 |
except Exception as e:
|
678 |
logger.error(f"Error formatting question: {str(e)}")
|
679 |
return f"""
|
680 |
+
<div style="background: #fee2e2; padding: 15px; border-radius: 8px; margin: 10px 0; border: 1px solid #dc2626;">
|
681 |
+
<div style="color: #dc2626;">Error displaying question: {str(e)}</div>
|
682 |
</div>
|
683 |
"""
|
684 |
|