Документация Документация

Для шаблона авторских прав, в частности Шаблон:АП.

Модуль:Copyright terms of countries.json — настройки юридических условий по странам.

local p = {}

local r = {t = {}, c ={}}
function r:add(s) table.insert(self.t, s) end
function r:add_category(s) table.insert(self.c, '[[Категория:'..s..']]') end
function r:result() return table.concat(self.t) .. table.concat(self.c)  end

-- инициализация базовых параметров
local util = require("Module:Util")
local terms_of_countries = util.get_json('Модуль:Copyright_terms_of_countries.json')  -- параметры авторских прав по странам
-- local countries_with_cases = util.get_json('MediaWiki:Отексте/Документ/countries_with_cases.json')  -- страны с падежами
-- local countries_words = {['россия']='России', ['белоруссия']='Белоруссии', ['узбекистан']='Узбекистане', ['украина']='Украине', ['финляндия']='Финляндии'}
local d = {}
local function init_values(frame)
	local pargs = frame:getParent().args
	local country =  mw.ustring.lower(is(pargs['СТРАНА']) or "Россия")
	country_terms = get_entity_from_table_by_name(terms_of_countries, country)
	d = {
		country_terms = country_terms,
		country = country_terms['aliases'][1] or country,     -- страна; за основное название страны принимаем 1-е значение в списке aliases
		year_death = tonumber(pargs['ГОД']),                  -- год смерти
		is_year_death_approximate = (pargs[1] == '?'),        -- дата смерти препдоположительна
		years_base_term =  nil,  -- лет, базовый срок действия АП после смерти автора
		is_war_participant = p.is_war_participant(pargs),     -- участник/работник ВОВ
		year_reability = tonumber(pargs['ГОДРЕАБИЛИТАЦИИ']),  -- год реабилитаци
		year_to_PD = nil,                        -- год когда произведения перейдут в ОД в стране-источнике, высчитывается
		is_uraa_free = nil,                      -- свободно ли произведение по URAA (true/false), принятому в 1996 году. В России это значит перешло ли в ОД к 1993 году
		wikilivres_ru = is(pargs['ВИКИЛИВРУ']),  -- страница автора на Викикливр.ру
	}
	-- mw.logObject(d, "d")
	local year_death = p.year_death_from_template_or_wikidata(pargs)  -- замещаем указанный в шаблоне год смерти годом из Викиданных, ставим категорию если они отличаются

	-- для России меняем базовый срок в зависимости от ВОВ и реабилитации
	local years_for_war_participant = p.number_of_years_for_war_participant(d)
	if d.country == 'Россия' and d.year_death and d.year_death <= 1917 then
		d.is_uraa_free = true
	end
	if d.year_death or d.year_reability then
		-- years_as_base_term = d.country_terms["years_as_base_term"]
		-- mw.logObject(d.country_terms, "d.country_terms")
		if d.country_terms['from_year'] then
			year_term = d.country_terms['until_year'] - d.country_terms['until_term_years'] - 1  -- 1942 для России
			if (d.year_death or d.year_reability) <= year_term and not d.is_war_participant and not d.year_reability then
				-- умер до 1993: применяется срок 50 лет pma, URAA не применяется
				d.years_base_term = d.country_terms['until_term_years']
				d.is_uraa_free = true
			else 
				d.years_base_term = d.country_terms['from_term_years']
			end
		else 
			d.years_base_term = d.country_terms['years_as_base_term']
		end
	end
	
	if not d.year_death and d.year_reability then
		r:add_category('Авторы с не указаным годом смерти, но с указаным годом реабилитации')
	end	
	
	local year_from_reability_or_death = p.latest_year_from_reability_or_death(d)
	
	if not year_from_reability_or_death then return end
	d.year_to_PD = year_from_reability_or_death + years_for_war_participant + d.years_base_term + 1  -- Расчёт года перехода в ОД, с 1 января следующего года
	end	

function p.year70pma(frame)
	init_values(frame)
	return d.year_to_PD
end	

-- Шаблон:АП
function p.template(frame)
	init_values(frame)
	mw.logObject(d, "d")
	local year_death, year_reability, year_to_PD = d.year_death, d.year_reability, d.year_to_PD
	local CURRENTYEAR = tonumber(os.date( '%Y' ))
	local year_by_uraa = CURRENTYEAR - 95 - 1
	local NSMAIN; if mw.title.getCurrentTitle().namespace == 0 then NSMAIN = 0 end
	local s = {}  -- текст шаблона АП
	
	-- если год не указан
	if not year_death and not year_reability then
		r:add(frame:expandTemplate{ title = 'license', args = {image='Red copyright.svg', cssclass='authorpage',
			text = "Публикация произведений этого автора в Викитеке возможна только с его согласия.",
			note = "См. также [[w:Википедия:Получение разрешений|Википедия:Получение разрешений]]."}})
		if NSMAIN then r:add_category("Авторы, публикация произведений которых возможна только с их согласия") end
	
	-- умер до 1917 года
	elseif not year_reability and year_death <= 1917 then
		-- Сомнительно, для иностранных авторов, поскольку у них могут быть нюансы в законах. А обычно параметр страны в {{АП}} не указывают. 
		-- Сомнителен и для России, поскольку не учитывается, что автор мог умереть после 1917 и:
		--   быть реабилитирован (царская семья реабилитирована в 2020-х, их записи под охраной АП?). 
		--   его записи впервые опубликованы в течении 70 лет после смерти, а значит охраняются с даты публикации ещё 70 лет.
		r:add(frame:expandTemplate{ title = 'PD-author-old-100', -- "ОД в тех странах, где срок охраны авторского права равен жизни автора плюс 100 лет и менее."
			args = {cssclass='authorpage'} -- {set_from_module_copyright='true'}  -- [[special:diff/3871262]] → [[Категория:Включения шаблона PD-author-old]]
		})
	
	elseif year_to_PD <= CURRENTYEAR then
		-- local s_country_first_upper = mw.language.getContentLanguage():ucfirst(mw.ustring.lower(d.country))
			
		local a_string
		if d.country == 'Россия' then 
			if d.is_uraa_free then  -- if d.years_base_term < 70 then
				a_string = "Ориентировочно, произведения этого автора, обнародованные при его жизни, [[Справка:Общественное достояние|находятся]] в&nbsp;'''[[w:Общественное достояние|общественном достоянии]]''' в стране-источнике. " ..
				    -- "Поскольку, страной автора предполагается Россия и автор умер более чем за ".. d.years_base_term .." лет до 1 января 1993 года ([[Федеральный закон от 18.12.2006 № 231-ФЗ#Статья 6|ст. 6 Федерального закона № 231-ФЗ]]). " ..
				    "Некоторые произведения могут иметь иной статус охраны авторского права в зависимости от ситуации и юрисдикции."
			else
				a_string = "Ориентировочно, произведения этого автора, обнародованные при его жизни, [[Справка:Общественное достояние|находятся]] в&nbsp;'''[[w:Общественное достояние|общественном достоянии]]''' в стране-источнике. " ..
				    -- "Поскольку, страной автора предполагается Россия и автор умер более чем за ".. d.years_base_term .." лет до 1 января 1993 года ([[Федеральный закон от 18.12.2006 № 231-ФЗ#Статья 6|ст. 6 Федерального закона № 231-ФЗ]]). " ..
				    "Некоторые произведения могут иметь иной статус охраны авторского права в зависимости от ситуации и юрисдикции."
			end
		-- else
		-- 	a_string = "Ориентировочно, произведения этого автора, обнародованные при его жизни, [[Справка:Общественное достояние|находятся]] в&nbsp;'''[[w:Общественное достояние|общественном достоянии]]''' в стране-источнике. " ..
		-- 	    ", поскольку автор умер более чем за ".. d.years_base_term .." лет до 1 января 1993 года (и к её произведениям может применяться национальный закон, аналогичный российскому [[Федеральный закон от 18.12.2006 № 231-ФЗ#Статья 6|ст. 6 Федерального закона № 231-ФЗ]]). " ..
		-- 	    "Лицензии на отдельные произведения могут отличаться в зависимости от ситуации и юрисдикции."
		-- end
		else
			a_string = "Ориентировочно, произведения этого автора, обнародованные при его жизни, [[Справка:Общественное достояние|находятся]] в&nbsp;'''[[w:Общественное достояние|общественном достоянии]]''' в стране-источнике. " ..
			    -- "Поскольку, страной автора является не Россия и автор умер более чем за ".. d.years_base_term .." лет назад. " ..
			    "Некоторые произведения могут иметь иной статус охраны авторского права в зависимости от ситуации и юрисдикции."
			-- Дополнительную фразу про другие страны нет смысла упоминать, поскольку законы в разных странах разные, могут меняться, издательства сами знают. Здесь не юридическая консультация.
			--  "Это может распространятся на большинство стран [[w:Бернская конвенция об охране литературных и художественных произведений|Бернской конвенции]]."
		end
		table.insert(s, a_string)
		if year_reability or year_death > 1942 then 
			table.insert(s, "Произведения, обнародованные после ".. year_by_uraa .." года, могут оставаться под защитой авторских прав в США, в юрисдикции которых расположены сервера Викитеки." )
		end
		table.insert(s, "Переводы и позднейшие редакции произведений этого автора могут являться объектами авторских прав соответствующих лиц согласно [[Гражданский кодекс РФ/Глава 70#Статья 1260|статье 1260 ГК РФ]].")
		r:add(frame:expandTemplate{ title = 'license', args = {image='PD-icon.svg', text = table.concat(s, '\n\n'), cssclass='authorpage' }})
	
	else
		table.insert(s, [=[В&nbsp;соответствии&nbsp;со&nbsp;[[Гражданский кодекс РФ/Глава 70#Статья 1281. Срок действия исключительного права на произведение|статьёй&nbsp;1281 ГК&nbsp;РФ]] произведения этого автора, впервые опубликованные (или обнародованные) после 7 ноября 1917 года (по новому стилю) на территории [[w:Российская Федерация|Российской Федерации]] или стран, правопреемником которых является Российская Федерация ([[w:СССР|СССР]], [[w:РСФСР|РСФСР]], [[w:Советская Россия (государство)|Советская Россия]]), перейдут в&nbsp;[[Викитека:Общественное достояние|общественное достояние]] '''1&nbsp;января ]=] ..year_to_PD.. "&nbsp;года'''." .. p.prolongation_note() .. p.wikilivres_note() )
		
		-- table.insert(s, "Срок действия исключительного права на произведение определяется по законодательству страны где оно было впервые обнародовано." )
		
		table.insert(s, "Произведения могут оставаться под защитой авторских прав в США, в юрисдикции которых расположены сервера Викитеки." )
		
		r:add(frame:expandTemplate{ title = 'license', args = {image='Red copyright.svg', text = table.concat(s, '\n\n'), cssclass='authorpage'}})
		
		-- категоризация для отслеживания нарушений [[ВТ:Не каталог авторов]]
		if NSMAIN then 
			r:add_category('Авторы, срок исключительных прав на произведения которых ещё не истёк')
			local years_before_free = year_to_PD - CURRENTYEAR
			if years_before_free >= 50 then r:add_category('Авторы, срок исключительных прав на произведения которых истекает позднее чем через 50 лет')
			elseif years_before_free >= 40 then r:add_category('Авторы, срок исключительных прав на произведения которых истекает позднее чем через 40 лет')
			elseif years_before_free >= 30 then r:add_category('Авторы, срок исключительных прав на произведения которых истекает позднее чем через 30 лет')
			elseif years_before_free >= 20 then r:add_category('Авторы, срок исключительных прав на произведения которых истекает позднее чем через 20 лет')
			elseif years_before_free >= 10 then r:add_category('Авторы, срок исключительных прав на произведения которых истекает позднее чем через 10 лет')
			end
		end
	
	end
	if is_year_death_approximate then
		r:add("\n<small>'''Примечание.''' Год смерти этого автора точно не известен и оценён как '''"..year_death.."'''.</small>")
	end	
	return r:result()
end

function p.wikilivres_note()
	Wikilivres_ru = d.Wikilivres_ru
	local w = {t = {}}
	function w:add(s) table.insert(self.t, s) end
	function w:add_category(s) table.insert(self.t, '[[Категория:'..s..']]') end
	function w:result() return table.concat(self.t) end

	if Wikilivres_ru then
		w:add('<br><small>')
		if Wikilivres_ru == 'Нужно перенести' then
			w:add('Произведения этого автора должны быть удалены из Викитеки, поэтому их нужно срочно перенести на&nbsp;сайт [[wikilivresru:|Wikilivres.ru]].')
			w:add_category('Авторы, чьи произведения нужно срочно перенести на сайт Wikilivres.ru')
		else
			w:add('Содержание данной страницы временно перенесено на&nbsp;сайт [[wikilivresru:'..Wikilivres_ru..'|Wikilivres.ru]]')
			w:add_category('Авторы, чьи произведения были перенесены на сайт Wikilivres.ru')
		end
		w:add('</small>')
	end
	return w:result()
end


function p.prolongation_note()
	local s = ''
	if d.year_reability or d.is_war_participant then 
		g = {}
		if d.year_reability then table.insert(g, 'был реабилитирован в ' .. d.year_reability .. ' году') end 
		if d.is_war_participant then table.insert(g, 'участвовал или работал в <abbr title="Великая Отечественная война">ВОВ</abbr>') end 
		s = ' Срок охраны АП продлён, поскольку автор ' .. table.concat(g, ' и ') .. '. '
	end
	return s
end

-- берёт год смерти из ВД
function p.get_year_death_wd(entity)
	local year_death_wd
	for _, s in pairs( entity:getBestStatements( 'P570' ) ) do
		if s.mainsnak.datavalue and s.mainsnak.datavalue.value.time then 
			local d = s.mainsnak.datavalue.value.time 
			return tonumber(mw.ustring.match( d, "(%-?%d+)%-%d+%-%d+T"))
		end	
	end
end

-- Если год смерти в шаблоне отличается от года в ВД, заменяет годом ВД. Добавляет категории.
-- Возвращает год смерти
function p.year_death_from_template_or_wikidata(pargs)
	local year_death_tpl = tonumber(pargs['ГОД'])
	local entity = mw.wikibase.getEntity()
	if entity then 
		local year_death_wd = p.get_year_death_wd(entity)  -- из ВД
		if year_death_tpl and year_death_wd then 
			if year_death_tpl ~= year_death_wd then 
				year_death = year_death_wd
				r:add_category('Викиданные:Год смерти отличается от указанного в шаблоне АП')
			end
		elseif year_death_wd then
			year_death = year_death_wd
			r:add_category('Викиданные:Год смерти не указан в шаблоне АП и взят из Викиданных')
		end
	end
	return year_death
end

-- Участник/работник ВОВ?
function p.is_war_participant(pargs)
	local war_status = pargs['ВОВ'] and mw.ustring.lower(pargs['ВОВ'])
	if war_status == 'участник' or war_status == 'работник' then 
		return true
	end
end

-- Возвращает '4' года для участников/работников ВОВ, иначе '0'. Для формулы расчёта.
function p.number_of_years_for_war_participant(d)
	local years_for_war_participant = 0; if d.country == 'Россия' and d.is_war_participant then years_for_war_participant = 4 end
	return years_for_war_participant
end

-- Возвращает год реабилитации или год смерти, какой позже
function p.latest_year_from_reability_or_death(d)
	local year
	local year_reability = d.year_reability
	local year_death = d.year_death
	if year_reability and year_death then 
		year = math.max(d.year_reability, d.year_death) 
	else 
		year = tonumber(d.year_reability) or tonumber(d.year_death) 
	end
	return year
end
	
-- Используется для итерации по значениям в таблицах по падежам (см. выше json)
-- Аргументы: таблица, название
function get_entity_from_table_by_name ( tbl, name )
	local name = mw.ustring.lower(name)
	for i, a in ipairs(tbl['list']) do 
		if a['aliases'] then
			for i, v in ipairs(a['aliases']) do 
				if mw.ustring.lower(v) == name then
					return a
				end
			end
		end
	end	
end

-- падеж страны
function get_country_case(country)
	return countries_words[mw.ustring.lower(country)]
end

-- проверка переменной, возврат её или nil если пустая
function is(var)
	if (var == '' or var == nil) then return nil  else return var end
end

return p