Module:GetRootVerses/Data

From Bodhicitta

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

-- Module:GetRootVerses/Data
-- Optimized data retrieval with minimal queries

local p = {}

-- Frequently used functions
local smw = mw.smw
local externalData = mw.ext.externalData
local uri_encode = mw.uri.encode

-- Configuration
local AUDIO_CATEGORIES = {
    tibetan = 'BCA Tibetan Chanted Verses',
    sanskrit = 'BCA Sanskrit Chanted Verses'
}

-- Get ALL verse data for a verse number in a SINGLE query
-- This replaces multiple individual calls
function p.getAllVerseData(verse)
    local query = table.concat({
        '[[Category:Translation Memories]]',
        '[[RootTextVerseNumPadmaK::' .. verse .. ']]',
        '[[SegmentFormat::Root]]',
        '|?#-=Page',
        '|?TransMemID',
        '|?TransMemNum',
        '|?SegmentSource',
        '|?SourceTranslit',
        '|?SegmentTranslation',
        '|?SegmentOrder',
        '|?RootTextChapVerseNum',
        '|?RootTextChapterNum',
        '|?RootTextVerseNum',
        '|?Flag',
        '|?Spanish',
        '|?SourceVersionLabel',
        '|?TranslationWikiPage#',
        '|?SourceWikiPage#',
        '|?ShortTitle',
        '|?RootSourceTransMem',
        '|?TranslationPublishedYear',
        '|?DuplicateRootTranslation',
        '|?SourceSortOrder',
        '|sort=SegmentOrder',
        '|order=asc',
        '|limit=1000',
        '|valuesep=;'
    })
    
    local results = smw.ask(query)
    if not results then
        return {}
    end
    
    -- Organize by TransMemID
    local organized = {
        bySource = {},
        rootSources = {},
        translations = {}
    }
    
    for _, item in ipairs(results) do
        local tmid = item.TransMemID
        
        -- Initialize array for this source
        if not organized.bySource[tmid] then
            organized.bySource[tmid] = {
                segments = {},
                metadata = {
                    TransMemID = tmid,
                    TransMemNum = item.TransMemNum,
                    SourceVersionLabel = item.SourceVersionLabel,
                    TranslationWikiPage = item.TranslationWikiPage,
                    SourceWikiPage = item.SourceWikiPage,
                    ShortTitle = item.ShortTitle,
                    RootSourceTransMem = item.RootSourceTransMem,
                    TranslationPublishedYear = item.TranslationPublishedYear,
                    SourceSortOrder = item.SourceSortOrder
                }
            }
        end
        
        -- Add segment
        organized.bySource[tmid].segments[#organized.bySource[tmid].segments + 1] = item
        
        -- Track root sources
        if item.RootSourceTransMem == tmid then
            organized.rootSources[tmid] = organized.bySource[tmid].metadata
        end
        
        -- Track translations (non-root sources)
        if item.RootSourceTransMem and item.RootSourceTransMem ~= tmid then
            if not organized.translations[item.RootSourceTransMem] then
                organized.translations[item.RootSourceTransMem] = {}
            end
            organized.translations[item.RootSourceTransMem][tmid] = organized.bySource[tmid]
        end


        -- Special case: Spanish translation within root source 001
        if tmid == '001-Tsadra-BCA-Root-Padmakara' and item.Spanish and item.Spanish ~= '' then
            if not organized.translations[tmid] then
                organized.translations[tmid] = {}
            end
            -- Create a virtual translation entry for Spanish
            if not organized.translations[tmid]['001-Spanish'] then
                organized.translations[tmid]['001-Spanish'] = {
                    segments = {},
                    metadata = {
                        TransMemID = '001-Spanish',
                        TransMemNum = '001-SP',
                        SourceVersionLabel = 'Spanish',
                        TranslationWikiPage = 'Books/La Práctica del Bodisatva',
                        ShortTitle = 'Padmakara Spain 2008',
                        RootSourceTransMem = tmid,
                        TranslationPublishedYear = '2008'
                    }
                }
            end
            -- Add segment with Spanish text
            organized.translations[tmid]['001-Spanish'].segments[#organized.translations[tmid]['001-Spanish'].segments + 1] = {
                Page = item.Page,
                SegmentTranslation = item.Spanish,
                Spanish = item.Spanish,
                SegmentOrder = item.SegmentOrder
            }
        end

    end
    
    return organized
end

-- Get audio track for a verse
function p.getAudioTrack(chapter, verse, language, transMemNum)
    local category = AUDIO_CATEGORIES[language]
    if not category then
        return nil
    end

    -- Special case: For TransMemNum 001, if chapter is 9 and verse > 20, increase verse by 1
    local adjustedVerse = verse
    if transMemNum == '009' and tostring(chapter) == '9' and tonumber(verse) > 20 then
        adjustedVerse = tostring(tonumber(verse) + 1)
    end

    local queryPart = table.concat({
        '[[Category:' .. category .. ']]',
        '[[ChapterNumber::' .. chapter .. ']]',
        '[[VerseNumber::' .. adjustedVerse .. ']]'
    })

    local encodedQuery = uri_encode(queryPart)
    local queryUrl = 'https://commons.tsadra.org/index.php?title=Special%3AAsk&q=' ..
                     encodedQuery ..
                     '&p%5Bmainlabel%5D=Track&p%5Blink%5D=none&p%5Bformat%5D=csv'

    local trkData = externalData.getExternalData{
        url = queryUrl,
        data = {Track = 'Track'},
        format = 'CSV with header'
    }

    return trkData and trkData.Track or nil
end

-- Process verse segments for display
function p.processVerseSegments(segments)
    if not segments or #segments == 0 then
        return nil
    end
    
    local processed = {
        segments = segments,
        flags = {},
        chapterNum = nil,
        verseNums = {}
    }
    
    for _, segment in ipairs(segments) do
        if segment.Flag then
            processed.flags[#processed.flags + 1] = segment.Flag
        end
        
        if segment.RootTextChapterNum and not processed.chapterNum then
            processed.chapterNum = segment.RootTextChapterNum
        end
        
        if segment.RootTextVerseNum then
            local verseNum = segment.RootTextVerseNum
            if type(verseNum) == 'table' then
                for _, v in ipairs(verseNum) do
                    processed.verseNums[v] = true
                end
            else
                processed.verseNums[verseNum] = true
            end
        end
    end
    
    return processed
end

-- Process translations for display
function p.processTranslations(translationsData)
    if not translationsData then
        return {}
    end
    
    local result = {}
    
    for tmid, data in pairs(translationsData) do
        local segments = data.segments
        local metadata = data.metadata
        
        if segments and #segments > 0 then
            local content = {}
            local year = metadata.TranslationPublishedYear or '9999'
            
            -- Check for duplicates
            local isDuplicate = false
            for _, seg in ipairs(segments) do
                if tostring(seg.DuplicateRootTranslation) == 'true' then
                    isDuplicate = true
                    break
                end
            end
            
            if not isDuplicate then
                for _, seg in ipairs(segments) do
                    if seg.Spanish then
                        content[#content + 1] = seg.Spanish
                        year = '2008'
                        metadata.TranslationWikiPage = 'Books/La Práctica del Bodisatva'
                        metadata.ShortTitle = 'Padmakara Spain 2008'
                    elseif seg.SegmentTranslation then
                        content[#content + 1] = seg.SegmentTranslation
                    end
                end
                
                if #content > 0 then
                    result[#result + 1] = {
                        id = tmid,
                        content = content,
                        source = metadata.TranslationWikiPage,
                        shortTitle = metadata.ShortTitle,
                        year = year,
                        page = segments[1].Page
                    }
                end
            end
        end
    end
    
    -- Sort by year
    table.sort(result, function(a, b) return a.year < b.year end)
    return result
end

return p