Modul:Person

Aus Steel Beasts Wiki
Version vom 3. September 2023, 08:02 Uhr von Dr.Thodt (Diskussion | Beiträge) (1 Version importiert)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

Die Dokumentation für dieses Modul kann unter Modul:Person/Doku erstellt werden

local Person = {}

local metatable = {}
local methodtable = {}

metatable.__index = methodtable

--- Needed Extensions
local infobox = require( 'Module:InfoboxNeue' )
local common = require( 'Module:Common' )

--- Characters to trim
local toTrim = "\t\r\n\f %(%)%?"

--- Pattern for matching (Date - Date / text)
local pattern = "%([%d]+[%s]?[%-]?[%s]?[%d%-%w]*%)"

--- Local Functions
--- Add Entry / Exit dates to a container table
--- @param dateToSplit string
--- @param data table
---
--- @return table
local function addDates( dateToSplit, data )
    if dateToSplit ~= nil and type( dateToSplit ) == 'string' then
        local split = mw.text.split( dateToSplit, '-', true )

        if split[ 1 ] ~= nil then
            data[ 'Eintritt' ] = mw.text.trim( split[ 1 ], toTrim )
        end

        if split[ 2 ] ~= nil then
            data[ 'Austritt' ] = mw.text.trim( split[ 2 ], toTrim )
        end
    end

    return data
end


--- Entry / Exit dates to text line in the form of (ENTRY - EXIT)
---
--- @param dates table
--- @return string
function Person.datesToTextLine( dates )
    local line = ''

    if dates[ 'Eintritt' ] ~= nil or dates[ 'Austritt' ] ~= nil then
        line = line .. ' ('

        if dates[ 'Eintritt' ] ~= nil then
            line = line .. dates[ 'Eintritt' ]
        end

        if dates[ 'Austritt' ] ~= nil then
            if dates[ 'Eintritt' ] ~= nil then
                line = line .. ' - '
            end

            line = line .. dates[ 'Austritt' ]
        end

        line = line .. ')'
    end

    return line
end

-- Parsed data as text
-- Returns table where each entry is one text line
function Person.parsedLinesToText( parsedData, mainKey )
    local texts = {}

    for _, occupation in pairs( parsedData ) do
        if occupation[ mainKey ] ~= nil then
            table.insert( texts, occupation[ mainKey ] .. Person.datesToTextLine( occupation ) )
        end
    end

    return texts
end

-- Remove Entry / Exit indexes if value is non numeric
function Person.removeNonNumberDates( data )
    if data[ 'Eintritt' ] ~= nil and tonumber( data[ 'Eintritt' ], 10 ) == nil then
        data[ 'Eintritt' ] = nil
    end

    if data[ 'Austritt' ] ~= nil and tonumber( data[ 'Austritt' ], 10 ) == nil then
        data[ 'Austritt' ] = nil
    end

    return data
end

--
function methodtable.parseArgLines( self, argPrefix, mainKey )
    if self.cache[ argPrefix ] ~= nil then
        return self.cache[ argPrefix ]
    end

    local parsed = {}
    local extractedArgs = common.extractDataFromPrefix( argPrefix, self.args, '%d' )

    for _, argLine in pairs( extractedArgs ) do
        local data = {}

        if argLine ~= nil and argLine ~= '' then
            local matchedDate = mw.ustring.match( argLine, pattern )

            if matchedDate ~= nil then
                argLine = mw.ustring.gsub( argLine, pattern, '' )
            end

            data[ mainKey ] = mw.text.trim( argLine )

            data = addDates( matchedDate, data )

            table.insert( parsed, data )
        end
    end

    self.cache[ argPrefix ] = parsed

    return parsed
end

-- Save properties into the smw store
function methodtable.setSemanticProperties( self )
    if self.smwData[ 'Todesdatum' ] and mw.ustring.lower( self.smwData[ 'Todesdatum' ] ) == 'unbekannt' then
        self.smwData[ 'Todesdatum' ] = nil;
    end

    if self.smwData[ 'Geburtsdatum' ] and mw.ustring.lower( self.smwData[ 'Geburtsdatum' ] ) == 'unbekannt' then
        self.smwData[ 'Geburtsdatum' ] = nil;
    end

    local result = mw.smw.set( self.smwData )

    common.checkSmwResult( result )
end


-- Save Occupation and affiliations as subobjects
function methodtable.setSubobjects( self )
    for _, occupationObject in pairs( self:parseArgLines( 'occupation', 'Beruf' ) ) do
        occupationObject = Person.removeNonNumberDates( occupationObject )

        common.checkSmwResult( mw.smw.subobject( occupationObject ) )
    end

    for _, affiliationObjects in pairs( self:parseArgLines( 'affiliation', 'Zugehörigkeit' ) ) do
        affiliationObjects = Person.removeNonNumberDates( affiliationObjects )

        common.checkSmwResult( mw.smw.subobject( affiliationObjects ) )
    end

    for _, employerObjects in pairs( self:parseArgLines( 'employer', 'Arbeitgeber' ) ) do
        employerObjects = Person.removeNonNumberDates( employerObjects )

        common.checkSmwResult( mw.smw.subobject( employerObjects ) )
    end
end

-- Creates the main title
function methodtable.getTitle( self )
    local title = ''

    if self.smwData[ 'Titel' ] ~= nil then
        title = self.smwData[ 'Titel' ] .. ' ' .. mw.title.getCurrentTitle().subpageText
    else
        title = mw.title.getCurrentTitle().subpageText
    end

    return title
end

-- Adds the main category
function methodtable.setMainCategory( self )
    table.insert( self.categories, '[[Category:Persönlichkeit]]' )
end

-- Extracts args and sets up the module
function methodtable.init( self, frame )
    self.args = require( 'Module:Arguments' ).getArgs( frame )

    self.smwData[ 'Titel' ] = self.args[ 'title' ] or self.args[ 'Titel' ];
    self.smwData[ 'Volk' ] = self.args[ 'species' ] or self.args[ 'Spezies' ];
    self.smwData[ 'foaf:name' ] = self.args[ 'name' ] or self.args[ 'Name' ];
    self.smwData[ 'Geschlecht' ] = self.args[ 'gender' ] or self.args[ 'Geschlecht' ];
    self.smwData[ 'Geburtsdatum' ] = self.args[ 'born' ] or self.args[ 'Geburtsdatum' ];
    self.smwData[ 'Todesdatum' ] = self.args[ 'died' ] or self.args[ 'Todesdatum' ];
    self.smwData[ 'foaf:knows' ] = common.extractDataFromPrefix( 'related', self.args );

    self:setSemanticProperties()
    self:setMainCategory()

    self.entity = require( 'Module:SystemEntity' ):new( 'Person' )
    -- Try unset
    self.args[ 'Habitabel' ] = nil
    self.entity:addManual( self.args )

    if self.args[ 'Starmap Code' ] ~= nil then
		local dataSuccess, _ = pcall( self.entity.getCelestialObjectData, self.entity, self.args[ 'Starmap Code' ] )
		local parentSuccess, _ = pcall( self.entity.getParentObjectData, self.entity )

		if not dataSuccess or not parentSuccess then
			return '<p class="hatnote">Daten werden im semantic Wiki aktualisiert, dies kann mehrere Minuten dauern.</p>'
		end
    end
end

-- Public functions
--
function Person.infoBox( frame )
    local instance = Person:new()
    instance:init( frame )

    local box = infobox:new( {
        removeEmpty = true,
        emptyString = '-'
    } )

    local titleImage = common.getImage( {
        instance.args[ 'image' ]
    } )

    if titleImage == false then
        table.insert( instance.categories, '[[Category:Persönlichkeit mit fehlendem Bild]]' )
    end

    box:renderImage( titleImage )
    box:renderHeader( {
    	title = instance:getTitle(),
    	subtitle = instance.entity:getSystemHeader()
    } )

	local section = {
		box:renderItem( 'Titel', instance.smwData[ 'Titel' ] or '-' ),
		box:renderItem( 'Name', instance.smwData[ 'foaf:name' ] or '-' ),
		box:renderItem( 'Geschlecht', instance.smwData[ 'Geschlecht' ] or '-' ),
		box:renderItem( 'Geboren', instance.smwData[ 'Geburtsdatum' ] or '-' ),
		box:renderItem( 'Gestorben', instance.smwData[ 'Todesdatum' ] or '-' ),
		box:renderItem( 'Spezies', instance.smwData[ 'Volk' ] or '-' ),
	}

    local employerText = Person.parsedLinesToText( instance:parseArgLines( 'employer', 'Arbeitgeber' ), 'Arbeitgeber' );
    local affiliationText = Person.parsedLinesToText( instance:parseArgLines( 'affiliation', 'Zugehörigkeit' ), 'Zugehörigkeit' );
    local occupationText = Person.parsedLinesToText( instance:parseArgLines( 'occupation', 'Beruf' ), 'Beruf' );

    local persons = {}
    for _, person in pairs( instance.smwData[ 'foaf:knows' ] ) do
        table.insert( persons, '[[' .. person .. ']]' )
    end

    if #employerText > 0 then
        table.insert( section, box:renderItem( 'Arbeitgeber', table.concat( employerText, '<br>' ) ) )
    end

    if #affiliationText > 0 then
    	table.insert( section, box:renderItem( 'Zugehörigkeit', table.concat( affiliationText, '<br>' ) ) )
    end

	box:renderSection( {
		col = 2,
		content = section
	} )

	section = {}
	
    if #occupationText > 0 then
    	table.insert( section, box:renderItem( {
    		label = 'Beruf', 
    		data = table.concat( occupationText, '<br>' ),
    		row = true,
			spacebetween = true
		} ) )
    end

    if #persons > 0 then
    	table.insert( section, box:renderItem( {
    		label = 'Familie / Bekannte', 
    		data = table.concat( persons, '<br>' ),
    		row = true,
			spacebetween = true
		} ) )
    end

	if #section > 0 then
		box:renderSection( {
			content = section
		} )
	end

    instance:setSubobjects()

    if instance.smwData[ 'Todesdatum' ] ~= nil then
        table.insert( instance.categories, '[[Category:Verstorbene Persönlichkeit]]' )
    end

    if instance.smwData[ 'Volk' ] ~= nil then
        table.insert( instance.categories, '[[Category:' .. instance.smwData[ 'Volk' ] .. ']]' )
    end

    return tostring( box ) .. tostring( table.concat( instance.categories, '' ) )
end


--- New Instance
function Person.new( self )
    local instance = {
        args = {},
        smwData = {
            [ 'Titel' ] = nil,
            [ 'Volk' ] = nil,
            [ 'foaf:name' ] = nil,
            [ 'Geschlecht' ] = nil,
            [ 'foaf:knows' ] = {},
            [ 'Geburtsdatum' ] = nil,
            [ 'Todesdatum' ] = nil,
        },

        categories = {},

        -- Parsed data cache
        cache = {},

        entity = {},
    }

    setmetatable( instance, metatable )

    return instance
end

return Person