FANDOM


------------------------------------------------------------
-- 생일 알리미 | Birthday Alarm
--
-- @Author(s): User:Cafeinlove
-- @License: MIT License
------------------------------------------------------------
 
local p = {}
 
local data = mw.loadData('Module:BirthdayAlarm/Data')
local birthData, _birthData = data.calendar, {} -- 생일 데이터
local showLength = data.showlength -- 생일을 보여줄 기간
local now, nowMonth, nowDay, nowIndex
 
--- processData() : 생일 데이터를 액세스하기 편리도록 재정리
local function processData()
	local monNum, dayNum
 
    -- parseNum() : 문자열에서 숫자를 추출
	local function parseNum(str)
		local nStr = string.match(str, '(%d+)')
		if not nStr then
			return false
		else
			return tonumber(nStr)
		end
    end
 
	-- 3d 테이블 `birthData` => 2d 테이블 `_birthData`
	for month, monthVal in pairs(birthData) do
		monNum = parseNum(month)
 
		for day, dayVal in pairs(monthVal) do
			dayNum = parseNum(day)
 
			table.insert(_birthData, {
			    index = p.getDayIndex(monNum, dayNum),
			    value = dayVal
			})
		end
    end
 
    -- _birthData 테이블을 날짜순 정렬
    table.sort(_birthData, function(a, b)
        return a.index < b.index
    end)
end
 
-- setList() : 생일 목록을 생성
local function setList()
	local ul
	local curIndex = nowIndex
 
	ul = mw.html.create('ul')
		:attr('id', 'birthdayList')
		:addClass('birthday-list')
 
    -- setListItem() : 생일 목록의 각 항목 생성
	local function setListItem(ul, dayIndex)
	    local className, wText, day, repDay, daysGap
		local chars
		local charTbl = {}
		local charExists = false
		local isToday = dayIndex == nowIndex
 
	    for i = 1, #_birthData do
	        if (_birthData[i].index == dayIndex) then
	            charExists = true
	            chars = _birthData[i].value
        		break
	        end
        end
 
        if isToday == false and charExists == false then return end
 
	    day = p.getDayStr(dayIndex)
	    repDay = p.getRepDate(dayIndex)
 
	    if isToday == false then
	        className = 'birthday-list__item'
	        daysGap = dayIndex - nowIndex
	        wText = (daysGap == 1 and '내일' or (daysGap == 2 and '모레' or daysGap .. '일 뒤'))
	    else
	        className = 'birthday-list__item active'
	        wText = '오늘'
	    end
 
		wText = wText .. ', <b>' ..repDay..'</b>' .. '<sup>(' ..day..')</sup>' .. '은<br>'
 
		if chars then
    		for _, v in pairs(chars) do
    		    table.insert(charTbl,
    		        '<span class="birthday-list__char">[[파일:'
    			    ..v.. '_도트.gif]][[' ..v.. ']]</span>'
    			)
    		end
		    wText = wText .. table.concat(charTbl, ', ') .. '의 생일입니다.'
 
		    if isToday then
		        wText = wText .. ' 축하합니다!'
		    end
		else
		    wText = wText .. '생일을 맞은 캐릭터가 없습니다.'
		end
 
		ul:tag('li')
			:addClass(className)
			:wikitext(wText)
	end
 
	-- 보여줄 일수가 지정되지 않았거나 규격에 맞지 않으면 30일로 설정
	if (not showLength) or (showLength < 1) or (showLength > 365) then
	    showLength = 30
	end
 
	-- 보여줄 일수 안에 존재하는 생일 목록을 추가
	for i = 1, showLength do
	    setListItem(ul, curIndex)
 
	    if (curIndex - 365) < 0 then
            curIndex = curIndex + 1
	    else
	        curIndex = curIndex - 364
	    end
    end
 
    return ul
end
 
--- p.getDayIndex() : 입력된 월, 일의 대응하는 날짜 인덱스값을 반환
-- 윤년은 계산되지 않음. 2월 29일은 3월 1일과 같이 60을 반환.
function p.getDayIndex(month, day)
	local monthLength = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
	local index = 0
 
	index = index + day
	if month > 1 then
		for i = 1, month-1 do
			index = index + monthLength[i]
		end
	end
 
	return index
end
 
--- p.getDayStr() : 입력된 날짜 인덱스값에 대응하는 월, 일을 반환
-- 윤년은 계산되지 않음
function p.getDayStr(index)
	local monthLength = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
	local tbl = {}
	local month = 1
 
    for i = 1, #monthLength do
	    if (index - monthLength[i] > 0) then
	        index = index - monthLength[i]
	        month = i + 1
	    end
    end
 
    tbl[1] = month .. '월'
    tbl[2] = index .. '일'
 
	return table.concat(tbl, ' ')
end
 
--- p.getRepDate() : 날짜 인덱스값으로 혁명력 날짜를 구함
function p.getRepDate(dayIndex)
	local rMonths = {
		{'눈의 달', 30},
		{'비의 달', 30},
		{'바람의 달', 30},
		{'새싹의 달', 30},
		{'꽃의 달', 30},
		{'목초의 달', 30},
		{'수확의 달', 30},
		{'열의 달', 30},
		{'열매의 달', 30},
		{'축제', 5},
		{'포도의 달', 30},
		{'안개의 달', 30},
		{'서리의 달', 30}
	}
	local index = dayIndex
	local i = 1
	local repDate = {}
 
    -- 눈의 달 12일부터 시작
    index = index + 11
 
    -- 달력을 넘겨 현재 날짜까지 이동
	while(index - rMonths[i][2] > 0) do
		index = index - rMonths[i][2]
 
		if i < #rMonths then
		    i = i + 1
	    else
	        i = 1
	    end
	end
 
    -- 알맞은 날짜 이름을 골라 반환
	repDate[1] = rMonths[i][1]
	repDate[2] = index .. '일'
 
	return table.concat(repDate, ' ')
end
 
function p.main(frame)
    local output
 
	-- 현재 월, 일을 파악해 변수에 저장
	now = os.date('*t', os.time()+32400) -- GMT+9
	nowMonth, nowDay = now.month, now.day
	nowIndex = p.getDayIndex(nowMonth, nowDay)
 
	-- 데이터를 재정렬
	processData()
 
	-- 출력을 구축
    output = setList()
 
	return output:done()
end
 
return p
Community content is available under CC-BY-SA unless otherwise noted.