Benutzer:Simon04/Spielwiese/Modul:Denkmalliste Österreich Tabellenzeile

--

--[[
  Modul für Vorlage:Denkmalliste_Österreich_Tabellenzeile
  Referenzen:
  - https://de.wikipedia.org/w/index.php?title=Vorlage:Denkmalliste_%C3%96sterreich_Tabellenzeile&oldid=167492395
  - https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual
  - https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua
]]

local config = {
  Bearbeitungsdatum = '2019-01-23',
}

local WLink = require('Module:WLink').WLink()
local AdressenSort = require('Module:AdressenSort')
local FormatDate = require('Modul:Vorlage:FormatDate')

local function _withoutEmptyFields(t)
  local new = {}
  for k, v in pairs(t) do
    if #v > 0 then
      new[k] = v
    end
  end
  return new
end

local function _createMetadataSpan()
  return mw.html.create('span'):addClass('metadata')
end

-- 1st return value is args[argKey] or the specified wikidata value
-- 2nd return value is a metadata html element
local function _argumentOr(args, argKey, wikidata)
  local argument = argKey and args[argKey]
  local meta = _createMetadataSpan()
  if not argument and not wikidata then
    return nil, meta
  elseif args._wikidata and not wikidata then
    return argument, meta:addClass('error'):wikitext('∉WD'):attr('title', string.format('Kein Wert für %s in Wikidata!', argKey))
  elseif not wikidata then
    return argument, meta
  elseif not argument then
    return wikidata, meta:addClass('success'):wikitext('WD'):attr('title', string.format('Wert für %s von Wikidata', argKey))
  elseif argument == wikidata then
    return argument, meta:addClass('success'):wikitext('≡'):attr('title', string.format('%s in Vorlage stimmt mit Wert in Wikidata überein', argKey))
  else
    return argument, meta:addClass('error'):wikitext('≠'):attr('title', string.format('Wikidata hat anderen Wert für %s: %s', argKey, wikidata))
  end
end

-- 1st return value is args[argKey] or the Wikidata property
-- 2nd return value is a metadata html element
local function _argumentOrWikidata(args, argKey, wikidataProperty)
  local statement = args._wikidata and args._wikidata:getBestStatements(wikidataProperty)
  local wikidata = nil
  if statement and statement[1] then
    wikidata = statement[1].mainsnak.datavalue.value
    wikidata = wikidata.text or wikidata -- for type=monolingualtext (P6375)
  end
  return _argumentOr(args, argKey, wikidata)
end

local function _argumentOrWikidataCoordinates(args)
  local P625 = args._wikidata and args._wikidata:getBestStatements('P625') -- geographische Koordinaten
  local lat1 = tonumber(args['Breitengrad'])
  local lon1 = tonumber(args['Längengrad'])
  local lat2 = P625 and P625[1] and P625[1].mainsnak and P625[1].mainsnak.datavalue.value.latitude
  local lon2 = P625 and P625[1] and P625[1].mainsnak and P625[1].mainsnak.datavalue.value.longitude
  if not lat1 or not lat2 then
    local lat, checkLat = _argumentOr(args, 'Breitengrad', lat2)
    local lon, checkLon = _argumentOr(args, 'Längengrad', lon2)
    return lat, lon, checkLat
  else
    -- calculate distance, see https://commons.wikimedia.org/wiki/Module:Coordinates
    local dLat = math.rad(lat1 - lat2)
    local dLon = math.rad(lon1 - lon2)
    local distance = math.pow(math.sin(dLat / 2), 2) + math.pow(math.sin(dLon / 2), 2) * math.cos(math.rad(lat1)) * math.cos(math.rad(lat2))
    distance = 2 * math.atan2(math.sqrt(distance), math.sqrt(1 - distance)) -- angular distance in radians
    distance = math.floor(6371000 * distance + 0.5) -- radians to meters conversion
    if distance > 5 then
      return lat1, lon1, _createMetadataSpan():addClass('error'):wikitext(string.format('Δ = %i m', distance))
    else
      return lat1, lon1, _createMetadataSpan():addClass('success'):wikitext('≡')
    end
  end
end

local function _addHiddenSpan(node)
  return node:tag('span'):css('display', 'none')
end

local function TabellenzelleFoto(args)
  local td = mw.html.create('td')
  td:addClass('col-Foto')
  if args.Bilderwunsch then
    td:addClass('DenkmallisteBW')
  end
  td:attr('data-sort-value', args.Foto and 'ja' or '')
  if args.Foto then
    td:tag('div'):addClass('Foto-300px'):wikitext(string.format('[[Datei:%s|300x300px|%s]]', args.Foto, args.Fotobeschreibung or args.Name))
    td:node(args._checkFoto)
  elseif args.Fotobeschreibung then
    td:wikitext(args.Fotobeschreibung)
  end
  if (args.Bilderwunsch or not args.Foto or args.Foto == 'Baustelledenkmal.svg') and args.Breitengrad and mw.title.getCurrentTitle().namespace == 0 then
    td:wikitext(mw.getCurrentFrame():expandTemplate({title = 'Bilderwunsch/encode', args = {
      Ort = args.Artikel or mw.title.getCurrentTitle().text,
      Name = args.Name or '',
      KoordLat = args['Breitengrad'] or '',
      KoordLon = args['Längengrad'] or ''
    }}))
  end
  return td
end

local function TabellenzelleIcons(args)
  local td = mw.html.create('td')
  td:addClass('col-Icons')
  td:addClass('noprint')
  if args.Commonscat then
    td:wikitext(string.format('[[Datei:Commons-logo.svg|x16px|alt=|link=commons:Category:%s|Weitere Bilder auf Wikimedia Commons]]', args.Commonscat))
    td:node(args._checkCommonscat)
    td:tag('br')
  end
  local uploadUrl = 'https://commons.wikimedia.org/wiki/Special:UploadWizard?' .. mw.uri.buildQueryString({
    campaign = 'wlm-at',
    id = args.ObjektID,
    descriptionlang = 'de',
    description = args.Name,
    captionlang = 'de',
    caption = args.NameAdresseKatastralgemeinde,
    categories = args.Commonscat or mw.getCurrentFrame():callParserFunction({name = '#property', args = {'P373'}}) or ''
  })
  td:wikitext(string.format('[[Datei:Camera-photo_Upload.svg|x16px|alt=Datei hochladen|eigenes Werk hochladen|link=%s]]', uploadUrl))
  if args._wikidata then
    td:tag('br')
    td:tag('span'):addClass('metadata'):wikitext(string.format('[[Datei:Wikidata-logo.svg|x16px|alt=|link=wikidata:%s|%s]]', args['WD-Item'], args._wikidata:getLabel()))
  end
  return td
end

local function AnzeigeName(args)
  local span = mw.html.create('span')
  if args['Anzeige-Name'] and string.find(args['Anzeige-Name'], ']]') then
    span:wikitext(args['Anzeige-Name'])
  elseif args.Artikel then
    span:wikitext(string.format('[[%s|%s]]', args.Artikel, args['Anzeige-Name'] or args.Name))
    span:node(args._checkArtikel)
  elseif args['Anzeige-Name'] then
    span:wikitext(args['Anzeige-Name'])
    span:node(args._checkAnzeigeName)
  else
    local checkName
    span:wikitext(args.Name)
    span:node(args._checkName)
  end
  return span
end

local function TabellenzelleDenkmal(args)
  local td = mw.html.create('td')
  td:addClass('col-Denkmal')
  td:attr('data-sort-value', WLink.getPlain((args['Anzeige-Name'] or '') .. args.Name))
  td:node(AnzeigeName(args))
  if args.ObjektID then
    td:tag('br')
    local url = string.format('[//tools.wmflabs.org/denkmalliste/?action=EinzelID&ID=%s %s]', args.ObjektID, args.ObjektID)
    td:tag('small'):wikitext('ObjektID: ' .. url)
    td:node(args._checkObjektID)
  end
  -- denkmalgeschützt seit, bis
  local sinceSource = args['denkmalgeschützt seit Quelle'] or ''
  local untilSource = args['denkmalgeschützt bis Quelle'] or (args['denkmalgeschützt bis'] and mw.getCurrentFrame():extensionTag('ref', mw.getCurrentFrame():expandTemplate({title = 'BDA DenkmallisteRef', args = {
    args['Region-ISO'],
    Jahr = string.format('%4s', args['denkmalgeschützt bis'] or '')
  }})))
  if args['denkmalgeschützt seit'] and args ['denkmalgeschützt bis'] then
    td:tag('br')
    td:tag('span'):wikitext(string.format('von %s%s bis %s%s', args['denkmalgeschützt seit'], sinceSource, args['denkmalgeschützt bis'], untilSource))
  elseif args['denkmalgeschützt seit'] then
    td:tag('br')
    td:tag('span'):wikitext(string.format('seit %s%s', args['denkmalgeschützt seit'], sinceSource))
  elseif args['denkmalgeschützt bis'] then
    td:tag('br')
    td:tag('span'):wikitext(string.format('bis %s%s', args['denkmalgeschützt bis'], untilSource))
  end
  return td
end

local function CoordinateSimple(args)
  local name = args.NameAdresseKatastralgemeinde
  local lat = args['Breitengrad']
  local lon = args['Längengrad']
  local region = args['Region-ISO']
  local type = args['KOORDINATE_TYP'] or 'landmark'
  -- https://www.mediawiki.org/wiki/Extension:GeoData
  mw.getCurrentFrame():callParserFunction({name = '#coordinates', args = {
    lat,
    lon,
    name = name,
    region = region,
    type = type
  }})
  -- essence of https://de.wikipedia.org/wiki/Vorlage:CoordinateSimple
  local geohack = '//tools.wmflabs.org/geohack/geohack.php?' .. mw.uri.buildQueryString({
    language = 'de',
    pagename = mw.title.getCurrentTitle().text,
    params = string.format('%s_N_%s_E_region:%s_type:%s', lat, lon, region, type),
    title = name
  })
  return mw.html.create('span'):addClass('plainlinks-print'):attr('title', 'Koordinate'):wikitext(string.format('[%s Standort]', geohack))
end

local function TabellenzelleStandort(args)
  local td = mw.html.create('td')
  td:addClass('col-Standort')
  local Adresse
  if args['Anzeige-Adresse'] and args['Anzeige-Adresse'] == 'keine' then
    Adresse = ''
  elseif args['Anzeige-Adresse'] then
    Adresse = args['Anzeige-Adresse']
  elseif args.Adresse then
    Adresse = args.Adresse
  else
    Adresse = ''
  end
  td:attr('data-sort-value', string.format('%s-%s', args.Katastralgemeinde or '', AdressenSort.convert({args = {Adresse}})))
  td:tag('span'):css('white-space', #Adresse > 35 and 'normal' or 'nowrap'):wikitext(Adresse)
  td:node(args._checkAdresse)
  td:tag('br')
  if args['Keine Koordinate'] then
    td:wikitext('Standort siehe Beschreibung')
  elseif tonumber(args['Breitengrad']) and tonumber(args['Längengrad']) then
    td:node(CoordinateSimple(args))
    td:node(args._checkCoordinates)
  else
    td:wikitext(mw.getCurrentFrame():expandTemplate({title = 'Coordinate', args = {
      text = 'Standort',
      simple = string.find(args['Breitengrad'], '/') and 'n' or 'y',
      NS = args['Breitengrad'],
      EW = args['Längengrad'],
      type = args['KOORDINATE_TYP'] or 'landmark',
      dim = args['Dim'],
      name = WLink.getPlain(string.format('%s%s%s', args.Name, args.Adresse and (', ' .. args.Adresse) or '', args.Katastralgemeinde and (', ' .. args.Katastralgemeinde) or '')),
      region = args['Region-ISO']
    }}))
    td:node(args._checkCoordinates)
  end
  td:tag('br')
  td:tag('small'):wikitext('KG: ' .. (args['Anzeige-KG'] or args.Katastralgemeinde))
  if not args.Breitengrad then
    td:tag('br')
    td:tag('small'):wikitext('GstNr.: ' .. args['Grundstücksnummer'])
  end
return td
end

local function TabellenzelleBeschreibung(args)
  local td = mw.html.create('td')
  td:addClass('col-Beschreibung')
  if args.Beschreibung then
    td:wikitext(args.Beschreibung)
  elseif args.Artikel then
    td:wikitext(mw.getCurrentFrame():expandTemplate{title = 'Hauptartikel', args = {args.Artikel}})
    -- `exists` is expensive, see https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Expensive_properties
    --if not mw.title.new(args.Artikel).exists then
    --  td:node(_hiddenSpan():wikitext('[[Vorlage:Denkmalliste Österreich/Wartung/Hauptartikel ohne Beschreibung|f1]]')
    --end
  end
  if args.Anmerkung then
    td:tag('br')
    td:tag('small'):wikitext('Anmerkung: ' .. args.Anmerkung)
  end
  if args.Beschreibung and args.Beschreibung == mw.getCurrentFrame():expandTemplate{title = 'Hauptartikel', args = {args.Artikel}} then
    _addHiddenSpan(td):wikitext('[[Vorlage:Denkmalliste Österreich/Wartung/nur Hauptartikel|f1]]')
  end
  return td
end

local function TabellenzelleMetadaten(args)
  local td = mw.html.create('td')
  td:addClass('col-Metadaten')
  td:addClass('nomobile')
  td:addClass('metadata')
  local dl = td:tag('dl')
  if args.ObjektID then
    dl:tag('dt'):wikitext('ObjektID:')
    dl:tag('dd'):wikitext(string.format("[//tools.wmflabs.org/krdbot/cgi-bin/Denkmalgrep.pl?%s %s]", mw.uri.buildQueryString({page = ';' .. args.ObjektID .. ';'}), args.ObjektID))
  else
    dl:tag('dt'):addClass('error'):wikitext('ObjektID:')
    dl:tag('dd'):addClass('error'):wikitext('fehlt!')
    if mw.title.getCurrentTitle().namespace == 0 and args['denkmalgeschützt bis'] then
      _addHiddenSpan(td):wikitext('[[Kategorie:Wikipedia:Denkmalliste Österreich ObjektID fehlt (ehemaliges Denkmal)]]')
    elseif mw.title.getCurrentTitle().namespace == 0 then
      _addHiddenSpan(td):wikitext('[[Kategorie:Wikipedia:Denkmalliste Österreich ObjektID fehlt]]')
    end
  end
  local Status = {
    ['Bescheid'] = 'Bescheid',
    ['§2a'] = '§ 2a',
    ['§ 2a'] = '§ 2a'
  }
  if Status[args.Status] then
    dl:tag('dt'):wikitext('Status:')
    dl:tag('dd'):wikitext(Status[args.Status])
  else
    dl:tag('dt'):addClass('error'):wikitext('Status:')
    dl:tag('dd'):addClass('error'):wikitext(args.Status)
  end
  if args.Bearbeitungsdatum and args.Bearbeitungsdatum == config.Bearbeitungsdatum then
    dl:tag('dt'):wikitext('Stand der BDA-Liste:')
    dl:tag('dd'):wikitext(args.Bearbeitungsdatum)
  elseif not args['denkmalgeschützt bis'] then
    dl:tag('dt'):addClass('error'):wikitext('Stand der BDA-Liste:')
    dl:tag('dd'):addClass('error'):wikitext(args.Bearbeitungsdatum or '')
    _addHiddenSpan(td):wikitext('[[Vorlage:Denkmalliste Österreich/Wartung/ObjekteNeedingManualUpdate|f6]]')
  end
  dl:tag('dt'):wikitext('Name:')
  dl:tag('dd'):wikitext(args.Name)
  if args.Breitengrad and args['Grundstücksnummer'] then
    dl:tag('dt'):wikitext('GstNr:')
    dl:tag('dd'):wikitext(args['Grundstücksnummer'])
  end
  if args.Einlagezahl then
    dl:tag('dt'):wikitext('EZ:')
    dl:tag('dd'):wikitext(args.Einlagezahl)
  end
  if args.Commonscat then
    td:tag('small'):wikitext(string.format('[[:commons:category:%s|%s]]', args.Commonscat, args.Commonscat))
  end
  if args.Datenfehler then
    _addHiddenSpan(td):wikitext('[[Vorlage:Denkmalliste Österreich/Wartung/Datenfehler|f2]]')
  end
  if args.Anmerkung then
    _addHiddenSpan(td):wikitext('[[Vorlage:Denkmalliste Österreich/Wartung/Anmerkung|f3]]')
  end
  if args['denkmalgeschützt seit'] and args['denkmalgeschützt seit'] == '2016' and not args.Breitengrad then
    _addHiddenSpan(td):wikitext('[[Vorlage:Denkmalliste Österreich/Wartung/neuOhneGeo|f4]]')
  elseif args.Foto and not args.Breitengrad then
    _addHiddenSpan(td):wikitext('[[Vorlage:Denkmalliste Österreich/Wartung/FotoOhneGeo|f5]]')
  end
  return td
end

local p = {}

p.Tabellenzeile = function(frame)
  local args = frame.args
  if not args or not args.ObjektID then
    args = mw.getCurrentFrame():getParent().args
  end
  args = _withoutEmptyFields(args)
  -- fetch Wikidata, _check* is a metadata info whether specified value and Wikidata value match
  args._wikidata = args['WD-Item'] and mw.wikibase.getEntity(args['WD-Item'])
  args.Adresse, args._checkAdresse = _argumentOrWikidata(args, 'Adresse', 'P6375')
  args.Artikel, args._checkArtikel = _argumentOr(args, 'Artikel', args._wikidata and args._wikidata:getSitelink())
  args.Commonscat, args._checkCommonscat = _argumentOrWikidata(args, 'Commonscat', 'P373')
  args.Foto, args._checkFoto = _argumentOrWikidata(args, 'Foto', 'P18')
  args.Name, args._checkName = _argumentOr(args, 'Name', args._wikidata and args._wikidata:getLabel())
  args.ObjektID, args._checkObjektID = _argumentOrWikidata(args, 'ObjektID', 'P2951')
  args['Breitengrad'], args['Längengrad'], args._checkCoordinates = _argumentOrWikidataCoordinates(args)
  if args['Anzeige-Name'] then
    args['Anzeige-Name'], args._checkAnzeigeName = _argumentOr(args, 'Anzeige-Name', args._wikidata and args._wikidata:getLabel())
  end
  args.NameAdresseKatastralgemeinde = WLink.getPlain(string.format('%s%s%s',
    args['Anzeige-Name'] or args.Name,
    args.Adresse and (', ' .. args.Adresse) or '',
    args.Katastralgemeinde and (', ' .. args.Katastralgemeinde) or '')
  )
  -- create tr
  local tr = mw.html.create('tr')
  if args.ObjektID then
    tr:attr('id', 'objektid-' .. args.ObjektID)
    tr:addClass('vcard')
  end
  if args.Datenfehler then
    tr:addClass('BDAerror')
  end
  -- create td
  tr:node(TabellenzelleFoto(args))
  tr:node(TabellenzelleIcons(args))
  tr:node(TabellenzelleDenkmal(args))
  tr:node(TabellenzelleStandort(args))
  tr:node(TabellenzelleBeschreibung(args))
  tr:node(TabellenzelleMetadaten(args))
  return tostring(tr)
end

return p

--