Actions

Module

Module:VideoGallery

From Dune Awakening DB

Documentation for this module may be created at Module:VideoGallery/doc

-- Module:VideoGallery
-- Lua module for rendering video gallery sections

local p = {}

-- Helper function to escape quotes
local function escapeQuotes(str)
    if not str then return '' end
    return str:gsub('"', '"'):gsub("'", ''')
end

-- Helper function to format duration
local function formatDuration(seconds)
    if not seconds or seconds == 0 then return '' end
    local minutes = math.floor(seconds / 60)
    local secs = seconds % 60
    return string.format("%d:%02d", minutes, secs)
end

-- Render videos for a specific category
function p.renderCategoryVideos(frame)
    local category = frame.args.category or 'Featured'
    local html = ''
    
    -- Get unique purposes for this category
    local purposes = mw.ext.externalData.getExternalData{
        source = 'externaldb',
        from = 'data_videos',
        data = 'purpose=purpose',
        where = "primary_tag='" .. category .. "' AND visibility='public' AND purpose IS NOT NULL",
        group_by = 'purpose',
        order_by = 'purpose'
    }
    
    -- Loop through each purpose and create a section
    if purposes and purposes.purpose then
        for i, purpose in ipairs(purposes.purpose) do
            html = html .. '<div class="video-section">\n'
            html = html .. '  <div class="video-section-header">\n'
            html = html .. '    <h3 class="section-title">' .. purpose .. '</h3>\n'
            html = html .. '  </div>\n'
            html = html .. '  <div class="video-grid">\n'
            
            -- Get videos for this purpose
            local videos = mw.ext.externalData.getExternalData{
                source = 'externaldb',
                from = 'data_videos',
                data = 'video_id=video_id,youtube_id=youtube_id,title=title,channel_title=channel_title,channel_id=channel_id,author=author,published_at=published_at,duration_sec=duration_sec,purpose=purpose,primary_tag=primary_tag,secondary_tag=secondary_tag,description=description,video_notes=video_notes,video_internal_link=video_internal_link',
                where = "primary_tag='" .. category .. "' AND purpose='" .. purpose .. "' AND visibility='public'",
                order_by = 'published_at DESC'
            }
            
            -- Render each video card
            if videos and videos.video_id then
                for j, video_id in ipairs(videos.video_id) do
                    local duration = formatDuration(tonumber(videos.duration_sec[j] or 0))
                    
                    html = html .. '    <div class="video-card" '
                    html = html .. 'data-video-id="' .. video_id .. '" '
                    html = html .. 'data-youtube-id="' .. (videos.youtube_id[j] or '') .. '" '
                    html = html .. 'data-title="' .. escapeQuotes(videos.title[j] or '') .. '" '
                    html = html .. 'data-channel="' .. escapeQuotes(videos.channel_title[j] or '') .. '" '
                    html = html .. 'data-channel-id="' .. (videos.channel_id[j] or '') .. '" '
                    html = html .. 'data-author="' .. escapeQuotes(videos.author[j] or '') .. '" '
                    html = html .. 'data-published="' .. (videos.published_at[j] or '') .. '" '
                    html = html .. 'data-duration="' .. (videos.duration_sec[j] or '') .. '" '
                    html = html .. 'data-purpose="' .. escapeQuotes(videos.purpose[j] or '') .. '" '
                    html = html .. 'data-primary-tag="' .. (videos.primary_tag[j] or '') .. '" '
                    html = html .. 'data-secondary-tag="' .. (videos.secondary_tag[j] or '') .. '" '
                    html = html .. 'data-description="' .. escapeQuotes(videos.description[j] or '') .. '" '
                    html = html .. 'data-notes="' .. escapeQuotes(videos.video_notes[j] or '') .. '" '
                    html = html .. 'data-internal-link="' .. escapeQuotes(videos.video_internal_link[j] or '') .. '">\n'
                    
                    html = html .. '      <div class="video-thumbnail" style="background-image: url(\'https://img.youtube.com/vi/' .. (videos.youtube_id[j] or '') .. '/mqdefault.jpg\');">\n'
                    if duration ~= '' then
                        html = html .. '        <span class="video-duration">' .. duration .. '</span>\n'
                    end
                    html = html .. '      </div>\n'
                    html = html .. '      <div class="video-info">\n'
                    html = html .. '        <div class="video-title">' .. (videos.title[j] or '') .. '</div>\n'
                    html = html .. '        <div class="video-channel">' .. (videos.channel_title[j] or '') .. '</div>\n'
                    html = html .. '      </div>\n'
                    html = html .. '    </div>\n'
                end
            end
            
            html = html .. '  </div>\n'
            html = html .. '</div>\n'
        end
    end
    
    return html
end

-- Render featured videos (shows videos from all categories)
function p.renderFeaturedVideos(frame)
    local html = ''
    
    -- Get unique purposes from all categories
    local purposes = mw.ext.externalData.getExternalData{
        source = 'externaldb',
        from = 'data_videos',
        data = 'purpose=purpose',
        where = "visibility='public' AND purpose IS NOT NULL",
        group_by = 'purpose',
        order_by = 'purpose',
        limit = 10  -- Limit featured to first 10 purposes
    }
    
    -- Loop through each purpose and create a section
    if purposes and purposes.purpose then
        for i, purpose in ipairs(purposes.purpose) do
            html = html .. '<div class="video-section">\n'
            html = html .. '  <div class="video-section-header">\n'
            html = html .. '    <h3 class="section-title">' .. purpose .. '</h3>\n'
            html = html .. '  </div>\n'
            html = html .. '  <div class="video-grid">\n'
            
            -- Get videos for this purpose
            local videos = mw.ext.externalData.getExternalData{
                source = 'externaldb',
                from = 'data_videos',
                data = 'video_id=video_id,youtube_id=youtube_id,title=title,channel_title=channel_title,channel_id=channel_id,author=author,published_at=published_at,duration_sec=duration_sec,purpose=purpose,primary_tag=primary_tag,secondary_tag=secondary_tag,description=description,video_notes=video_notes,video_internal_link=video_internal_link',
                where = "purpose='" .. purpose .. "' AND visibility='public'",
                order_by = 'published_at DESC',
                limit = 4  -- Limit to 4 videos per purpose in featured
            }
            
            -- Render each video card
            if videos and videos.video_id then
                for j, video_id in ipairs(videos.video_id) do
                    local duration = formatDuration(tonumber(videos.duration_sec[j] or 0))
                    
                    html = html .. '    <div class="video-card" '
                    html = html .. 'data-video-id="' .. video_id .. '" '
                    html = html .. 'data-youtube-id="' .. (videos.youtube_id[j] or '') .. '" '
                    html = html .. 'data-title="' .. escapeQuotes(videos.title[j] or '') .. '" '
                    html = html .. 'data-channel="' .. escapeQuotes(videos.channel_title[j] or '') .. '" '
                    html = html .. 'data-channel-id="' .. (videos.channel_id[j] or '') .. '" '
                    html = html .. 'data-author="' .. escapeQuotes(videos.author[j] or '') .. '" '
                    html = html .. 'data-published="' .. (videos.published_at[j] or '') .. '" '
                    html = html .. 'data-duration="' .. (videos.duration_sec[j] or '') .. '" '
                    html = html .. 'data-purpose="' .. escapeQuotes(videos.purpose[j] or '') .. '" '
                    html = html .. 'data-primary-tag="' .. (videos.primary_tag[j] or '') .. '" '
                    html = html .. 'data-secondary-tag="' .. (videos.secondary_tag[j] or '') .. '" '
                    html = html .. 'data-description="' .. escapeQuotes(videos.description[j] or '') .. '" '
                    html = html .. 'data-notes="' .. escapeQuotes(videos.video_notes[j] or '') .. '" '
                    html = html .. 'data-internal-link="' .. escapeQuotes(videos.video_internal_link[j] or '') .. '">\n'
                    
                    html = html .. '      <div class="video-thumbnail" style="background-image: url(\'https://img.youtube.com/vi/' .. (videos.youtube_id[j] or '') .. '/mqdefault.jpg\');">\n'
                    if duration ~= '' then
                        html = html .. '        <span class="video-duration">' .. duration .. '</span>\n'
                    end
                    html = html .. '      </div>\n'
                    html = html .. '      <div class="video-info">\n'
                    html = html .. '        <div class="video-title">' .. (videos.title[j] or '') .. '</div>\n'
                    html = html .. '        <div class="video-channel">' .. (videos.channel_title[j] or '') .. '</div>\n'
                    html = html .. '      </div>\n'
                    html = html .. '    </div>\n'
                end
            end
            
            html = html .. '  </div>\n'
            html = html .. '</div>\n'
        end
    end
    
    return html
end

return p