File size: 2,562 Bytes
91073d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import re
from datetime import datetime
from flask import url_for
from slugify import slugify

def format_datetime(dt):
    """Format datetime for display"""
    if not dt:
        return ""
    
    now = datetime.utcnow()
    diff = now - dt
    
    if diff.days == 0:
        # Today
        if diff.seconds < 60:
            return "Just now"
        if diff.seconds < 3600:
            minutes = diff.seconds // 60
            return f"{minutes} minute{'s' if minutes != 1 else ''} ago"
        else:
            hours = diff.seconds // 3600
            return f"{hours} hour{'s' if hours != 1 else ''} ago"
    elif diff.days == 1:
        return "Yesterday"
    elif diff.days < 7:
        return f"{diff.days} days ago"
    else:
        return dt.strftime("%b %d, %Y")

def get_username_for_mention(text):
    """Extract username from a @mention"""
    pattern = r'@([a-zA-Z0-9_]+)'
    matches = re.findall(pattern, text)
    return matches

def make_url_slug(text):
    """Create a URL-friendly slug from text"""
    return slugify(text)

def truncate_text(text, length=100):
    """Truncate text to specified length and add ellipsis if needed"""
    if len(text) <= length:
        return text
    return text[:length].rsplit(' ', 1)[0] + '...'

def get_avatar_url(avatar_filename):
    """Get the URL for user avatar"""
    if not avatar_filename or avatar_filename == 'default.png':
        return url_for('static', filename='uploads/avatars/default.png')
    return url_for('static', filename=f'uploads/avatars/{avatar_filename}')

def parse_bbcode(text):
    """Convert basic BBCode to HTML (simple implementation)"""
    # Bold
    text = re.sub(r'\[b\](.*?)\[/b\]', r'<strong>\1</strong>', text)
    # Italic
    text = re.sub(r'\[i\](.*?)\[/i\]', r'<em>\1</em>', text)
    # Underline
    text = re.sub(r'\[u\](.*?)\[/u\]', r'<u>\1</u>', text)
    # URLs
    text = re.sub(r'\[url=(.*?)\](.*?)\[/url\]', r'<a href="\1" target="_blank">\2</a>', text)
    text = re.sub(r'\[url\](.*?)\[/url\]', r'<a href="\1" target="_blank">\1</a>', text)
    # Images
    text = re.sub(r'\[img\](.*?)\[/img\]', r'<img src="\1" alt="User posted image" class="img-fluid">', text)
    # Code blocks
    text = re.sub(r'\[code\](.*?)\[/code\]', r'<pre><code>\1</code></pre>', text, flags=re.DOTALL)
    # Quotes
    text = re.sub(r'\[quote\](.*?)\[/quote\]', r'<blockquote>\1</blockquote>', text, flags=re.DOTALL)
    text = re.sub(r'\[quote=(.*?)\](.*?)\[/quote\]', r'<blockquote>\2<footer>\1</footer></blockquote>', text, flags=re.DOTALL)
    
    return text