Файловый менеджер - Редактировать - /var/www/html/RealTimeUsers.zip
Ðазад
PK ! �][ [ RealTimeUsers_body.phpnu �[��� <?php /** * SpecialPage for RealTimeUsers extension * Show info and realtime users' number * Called with "/getNumber" param returns the number of RT users * @ingroup Extensions * @author Josef Martiňák * @license MIT */ class RealTimeUsers extends SpecialPage { function __construct() { parent::__construct( 'RealTimeUsers' ); } function execute($param) { $this->setHeaders(); $out = $this->getOutput(); $config = $out->getConfig(); if($param == 'getNumber') { // Output raw number of RT users $out->disable(); header( 'Content-type: application/text; charset=utf-8' ); $rtusers = []; $done = false; $started = false; try { $handle = @fopen(__DIR__ . "/data/wiki.log", "r"); while (($buffer = fgets($handle, 4096)) !== false) { if(preg_match("/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})[^\[]*\[([^ ]*)/", $buffer, $m)) { //188.75.128.28 - - [02/Jan/2020:00:01:02 +0100] $date = DateTime::createFromFormat('d/M/Y:H:i:s', $m[2]); $now = new DateTime(); //$now = new DateTime("2020-01-07 14:00:00"); // pro testování $diff = $now->getTimestamp() - $date->getTimestamp(); if($diff<300) { // found hits from last 5 minutes array_push($rtusers, $m[1]); $started = true; } elseif($started) { $done = true; break; } } } fclose($handle); if(!$started) $done = true; // no recent hit in log, stop searching // check older logs if necessary if(!$done) { for($i=0;$i<5;$i++) { $started = false; if($bz = @bzopen(__DIR__ . "/data/wiki.log." . (string)$i . ".bz2", "r")) { while (!feof($bz)) { $buffer = bzread($bz); if(preg_match("/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})[^\[]*\[([^ ]*)/", $buffer, $m)) { $date = DateTime::createFromFormat('d/M/Y:H:i:s', $m[2]); $now = new DateTime(); //$now = new DateTime("2020-01-07 14:00:00"); // pro testování $diff = $now->getTimestamp() - $date->getTimestamp(); if($diff<300) { // found hits from last 5 minutes array_push($rtusers, $m[1]); $started = true; } elseif($started) { $done = true; break; } } } bzclose($bz); if(!$started) $done = true; // no recent hit in log, stop searching } if($done) break; } } } catch(Exception $e) { echo 'err'; } $unique = array_unique($rtusers); echo sizeof($unique); exit; } // Display info $out->addHTML( "<p>" . $this->msg( 'realtimeusers-desc' )->text() . "</p>" ); $out->addHTML( "<p>" . $this->msg( 'realtimeusers-manual' )->text() . "</p>" ); // prepare data $data = RealTimeUsersHooks::getChartData('today'); $points1 = []; foreach($data as $point) { $point[1] = preg_replace("/[0-9]{4}-[0-9]{2}-[0-9]{2} /", '', $point[1]); array_push($points1, "{\"x\":\"$point[1]\",\"y\":$point[0]}"); } $data = RealTimeUsersHooks::getChartData('yesterday'); $points2 = []; foreach($data as $point) { $point[1] = preg_replace("/[0-9]{4}-[0-9]{2}-[0-9]{2} /", '', $point[1]); array_push($points2, "{\"x\":\"$point[1]\",\"y\":$point[0]}"); } $out->addHTML("<div id='rtContainer'><div id='rtUsers'>" . $this->msg( 'realtimeusers-boxtext' )->text() . "</div>"); $out->addHTML("<canvas id='rtuChart' width='400' height='300' data-refresh='" . $config->get("refreshInterval") . "' data-chart1='[" . implode(',', $points1) . "]' data-chart2='[" . implode(',', $points2) . "]'></canvas></div>"); $out->addModules('ext.RealTimeUsers'); } }PK ! �P�� � cron/saveRecentRealTimeUsers.pynu �[��� # Save recent number of realtime users to "data/chart.csv" # Call https://www.wikiskripta.eu/w/Special:RealTimeUsers/getNumber and save result to "data/chart.csv" # Run in cron, choose interval from [5,10,15,20,30,60] # @ingroup Extensions # @author Josef Martiňák # @license MIT import requests import os from datetime import datetime dir_path = os.path.dirname(os.path.realpath(__file__)) response = requests.get("https://www.wikiskripta.eu/index.php?title=Special:RealTimeUsers/getNumber", timeout = 15) rtNumber = response.content.decode("utf-8") # get current datetime now = datetime.now() dt_string = now.strftime("%Y-%m-%d %H:%M") # save value to file, allow max lines 192 (4 days when checking once a 30 min) with open(dir_path + '/../data/chart.csv', 'r') as f: chLines = f.readlines() if len(chLines)>191: with open(dir_path + '/../data/chart.csv', 'w') as fin: for i in range(192-len(chLines),1+len(chLines)): f.write(chLines[i]) f.write(rtNumber + ';' + dt_string + '\n') # recent value else: with open(dir_path + '/../data/chart.csv', 'a') as f: f.write(rtNumber + ';' + dt_string + '\n') # recent valuePK ! �V]� � README.mdnu �[��� # RealTimeUsers Mediawiki extension. ## Description * Extension gathers and displays info about wiki's real time users. Information is taken from server access log. * Active users are those who have sent a hit within the last five minutes. * Adding tag <realtimeusers mode=""></realtimeusers> * mode="number": numer of RT users refreshing in given interval (default 30s) * mode="chart": chart of RT users' snapshots in given intervals (default 30min) * mode="combo": box with complete available information (default choice) * It works on main page only ## Installation * Make sure you have MediaWiki 1.29+ installed. * Download and place the extension to your _/extensions/_ folder. * Set variables in _extension.json_. * Create symlinks to logfiles (with correct rights) * `ln -s /var/log/..../????.access.log data/wiki.log`. * `ln -s /var/log/..../????.access.log.0.bz2 data/wiki.log.0.bz2`. * `ln -s /var/log/..../????.access.log.1.bz2 data/wiki.log.1.bz2`. * `ln -s /var/log/..../????.access.log.2.bz2 data/wiki.log.2.bz2`. * `ln -s /var/log/..../????.access.log.3.bz2 data/wiki.log.3.bz2`. * `ln -s /var/log/..../????.access.log.4.bz2 data/wiki.log.4.bz2`. * Set Cron job _cron/saveRecentRealTimeUsers.py_ at every 30th minute `*/30 * * * *`. * Add the following code to your LocalSettings.php: `wfLoadExtension( 'RealTimeUsers' )`; * _cron/saveRecentRealTimeUsers.py_ shouldn't be accessible from web. ## Internationalization This extension is available in English and Czech language. For other languages, just edit files in /i18n/ folder. ## Authors and license * [Josef Martiňák](https://www.wikiskripta.eu/w/User:Josmart) * MIT License, Copyright (c) 2020 First Faculty of Medicine, Charles University PK ! ,y��� � extension.jsonnu �[��� { "name": "RealTimeUsers", "version": "1.0", "author": "[https://www.wikiskripta.eu/w/User:Josmart Josef Martiňák]", "url": "https://bitbucket.org/wikiskripta/realtimeusers", "descriptionmsg": "realtimeusers-desc", "license-name": "MIT", "type": "parserhook", "status": "stable", "requires": { "MediaWiki": ">= 1.29.0" }, "SpecialPages": { "RealTimeUsers": "RealTimeUsers" }, "MessagesDirs": { "RealTimeUsers": [ "i18n" ] }, "AutoloadClasses": { "RealTimeUsersHooks": "RealTimeUsersHooks.php", "RealTimeUsers": "RealTimeUsers_body.php" }, "ResourceModules": { "ext.RealTimeUsers": { "styles": [ "Chart.min.css", "ext.RealTimeUsers.css" ], "scripts": [ "moment.min.js", "moment.locale.cs.js", "Chart.min.js", "ext.RealTimeUsers.js" ], "messages": [ "realtimeusers-boxtext", "realtimeusers-yesterday", "realtimeusers-today", "realtimeusers-title", "realtimeusers-xAxis", "realtimeusers-yAxis" ] } }, "ResourceFileModulePaths": { "localBasePath": "resources", "remoteExtPath": "RealTimeUsers/resources" }, "Hooks": { "ParserFirstCallInit": "RealTimeUsersHooks::registerParserHook", "BeforePageDisplay": "RealTimeUsersHooks::showChart" }, "config": { "refreshInterval": { "value": 10, "description": "Refreshing interval in seconds of RT users number displayed on a webpage." } }, "manifest_version": 2 } PK ! w=�!� � .git/info/excludenu �[��� # git ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~ PK ! �;{%� � .git/logs/HEADnu �[��� 0000000000000000000000000000000000000000 051441c5db197d0ee0b0c42f94cb75a001778cf4 root <root@wiki.mekcity.com> 1737632679 -0800 clone: from https://bitbucket.org/wikiskripta/realtimeusers.git PK ! �;{%� � "