<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://digida.mgpu.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3ADatasetAggregator</id>
	<title>Модуль:DatasetAggregator - История изменений</title>
	<link rel="self" type="application/atom+xml" href="http://digida.mgpu.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3ADatasetAggregator"/>
	<link rel="alternate" type="text/html" href="http://digida.mgpu.ru/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:DatasetAggregator&amp;action=history"/>
	<updated>2026-09-28T05:57:42Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>http://digida.mgpu.ru/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:DatasetAggregator&amp;diff=46208&amp;oldid=prev</id>
		<title>Patarakin: Новая страница: «local p = {}  local function trim(s)     if type(s) ~= &#039;string&#039; then         return s     end     return mw.text.trim(s) end  local function getArgs(frame)     local args = {}     for k, v in pairs(frame.args) do         if v ~= nil and v ~= &#039;&#039; then             args[k] = trim(v)         end     end     return args end  local function getData(url)     if not mw.ext or not mw.ext.externalData or not mw.ext.externalData.getExternalData then         return nil,...»</title>
		<link rel="alternate" type="text/html" href="http://digida.mgpu.ru/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:DatasetAggregator&amp;diff=46208&amp;oldid=prev"/>
		<updated>2026-04-14T10:15:14Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «local p = {}  local function trim(s)     if type(s) ~= &amp;#039;string&amp;#039; then         return s     end     return mw.text.trim(s) end  local function getArgs(frame)     local args = {}     for k, v in pairs(frame.args) do         if v ~= nil and v ~= &amp;#039;&amp;#039; then             args[k] = trim(v)         end     end     return args end  local function getData(url)     if not mw.ext or not mw.ext.externalData or not mw.ext.externalData.getExternalData then         return nil,...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local function trim(s)&lt;br /&gt;
    if type(s) ~= &amp;#039;string&amp;#039; then&lt;br /&gt;
        return s&lt;br /&gt;
    end&lt;br /&gt;
    return mw.text.trim(s)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getArgs(frame)&lt;br /&gt;
    local args = {}&lt;br /&gt;
    for k, v in pairs(frame.args) do&lt;br /&gt;
        if v ~= nil and v ~= &amp;#039;&amp;#039; then&lt;br /&gt;
            args[k] = trim(v)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getData(url)&lt;br /&gt;
    if not mw.ext or not mw.ext.externalData or not mw.ext.externalData.getExternalData then&lt;br /&gt;
        return nil, { &amp;#039;Ошибка: Extension:External Data недоступен&amp;#039; }&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local data, errors = mw.ext.externalData.getExternalData{&lt;br /&gt;
        source = url,&lt;br /&gt;
        format = &amp;#039;csv with header&amp;#039;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if not data then&lt;br /&gt;
        return nil, errors or { &amp;#039;Ошибка: данные не загружены&amp;#039; }&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return data, nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function countRows(data)&lt;br /&gt;
    return #data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function countDistinct(data, field)&lt;br /&gt;
    local seen = {}&lt;br /&gt;
    local n = 0&lt;br /&gt;
&lt;br /&gt;
    for _, row in ipairs(data) do&lt;br /&gt;
        local value = row[field]&lt;br /&gt;
        if value ~= nil and value ~= &amp;#039;&amp;#039; and not seen[value] then&lt;br /&gt;
            seen[value] = true&lt;br /&gt;
            n = n + 1&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return n&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function countByValue(data, field, expected)&lt;br /&gt;
    local n = 0&lt;br /&gt;
    for _, row in ipairs(data) do&lt;br /&gt;
        if tostring(row[field] or &amp;#039;&amp;#039;) == tostring(expected) then&lt;br /&gt;
            n = n + 1&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return n&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function buildSummaryTable(data)&lt;br /&gt;
    local rows = countRows(data)&lt;br /&gt;
    local authors = countDistinct(data, &amp;#039;author_name&amp;#039;)&lt;br /&gt;
    local objects = countDistinct(data, &amp;#039;object_id&amp;#039;)&lt;br /&gt;
    local pages = countDistinct(data, &amp;#039;page_title&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    local out = &amp;#039;{| class=&amp;quot;wikitable&amp;quot;\n&amp;#039;&lt;br /&gt;
    out = out .. &amp;#039;! Метрика !! Значение\n&amp;#039;&lt;br /&gt;
    out = out .. &amp;#039;|-\n| Строк в CSV || &amp;#039; .. rows .. &amp;#039;\n&amp;#039;&lt;br /&gt;
    out = out .. &amp;#039;|-\n| Уникальных авторов || &amp;#039; .. authors .. &amp;#039;\n&amp;#039;&lt;br /&gt;
    out = out .. &amp;#039;|-\n| Уникальных объектов || &amp;#039; .. objects .. &amp;#039;\n&amp;#039;&lt;br /&gt;
    out = out .. &amp;#039;|-\n| Уникальных страниц || &amp;#039; .. pages .. &amp;#039;\n&amp;#039;&lt;br /&gt;
    out = out .. &amp;#039;|}&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    return out&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.rows(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local data, errors = getData(args.url)&lt;br /&gt;
    if not data then&lt;br /&gt;
        return &amp;#039;Ошибка: &amp;#039; .. table.concat(errors, &amp;#039;; &amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
    return &amp;#039;Строк в CSV: &amp;#039; .. countRows(data)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.authors(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local data, errors = getData(args.url)&lt;br /&gt;
    if not data then&lt;br /&gt;
        return &amp;#039;Ошибка: &amp;#039; .. table.concat(errors, &amp;#039;; &amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
    return &amp;#039;Уникальных авторов: &amp;#039; .. countDistinct(data, &amp;#039;author_name&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.objects(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local data, errors = getData(args.url)&lt;br /&gt;
    if not data then&lt;br /&gt;
        return &amp;#039;Ошибка: &amp;#039; .. table.concat(errors, &amp;#039;; &amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
    return &amp;#039;Уникальных объектов: &amp;#039; .. countDistinct(data, &amp;#039;object_id&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.commits(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local data, errors = getData(args.url)&lt;br /&gt;
    if not data then&lt;br /&gt;
        return &amp;#039;Ошибка: &amp;#039; .. table.concat(errors, &amp;#039;; &amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local commitType = args.type or &amp;#039;wiki_minor_edit&amp;#039;&lt;br /&gt;
    return &amp;#039;Правок типа &amp;quot;&amp;#039; .. commitType .. &amp;#039;&amp;quot;: &amp;#039; .. countByValue(data, &amp;#039;commit_type&amp;#039;, commitType)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.summary(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local data, errors = getData(args.url)&lt;br /&gt;
    if not data then&lt;br /&gt;
        return &amp;#039;Ошибка: &amp;#039; .. table.concat(errors, &amp;#039;; &amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
    return buildSummaryTable(data)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local mode = args.mode or &amp;#039;summary&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    if not args.url or args.url == &amp;#039;&amp;#039; then&lt;br /&gt;
        return &amp;#039;Ошибка: укажите параметр url&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if mode == &amp;#039;rows&amp;#039; then&lt;br /&gt;
        return p.rows(frame)&lt;br /&gt;
    elseif mode == &amp;#039;authors&amp;#039; then&lt;br /&gt;
        return p.authors(frame)&lt;br /&gt;
    elseif mode == &amp;#039;objects&amp;#039; then&lt;br /&gt;
        return p.objects(frame)&lt;br /&gt;
    elseif mode == &amp;#039;commits&amp;#039; then&lt;br /&gt;
        return p.commits(frame)&lt;br /&gt;
    elseif mode == &amp;#039;summary&amp;#039; then&lt;br /&gt;
        return p.summary(frame)&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;#039;Ошибка: неизвестный режим. Допустимо: rows, authors, objects, commits, summary&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Patarakin</name></author>
	</entry>
</feed>