added own PmWiki recipes
This commit is contained in:
394
cookbook/behavior_recall.php
Normal file
394
cookbook/behavior_recall.php
Normal file
@@ -0,0 +1,394 @@
|
||||
<?php if (!defined('PmWiki')) exit();
|
||||
/*
|
||||
inspired by PageFeed by Daniel Roesler (diafygi)
|
||||
conversation array imported from it
|
||||
*/
|
||||
|
||||
## Recipe version information
|
||||
$RecipeInfo['BehaviorRecall']['Version'] = '2011-01-02';
|
||||
|
||||
## Add action for pagefeed
|
||||
SDV($HandleActions['recall'], 'BehaviorRecall');
|
||||
|
||||
function addDate_BehaviorRecall($date,$day)//add days
|
||||
{
|
||||
$sum = strtotime(date("Y-m-d", strtotime("$date")) . " +$day days");
|
||||
$dateTo=date('Y-m-d',$sum);
|
||||
return $dateTo;
|
||||
}
|
||||
function convertDate_BehaviorRecall($date) {
|
||||
return preg_replace("/(\d+)\/(\d+)\/(\d+)/",'$3-$2-$1',$date);
|
||||
}
|
||||
|
||||
## Create feed from page history
|
||||
function BehaviorRecall($pagename, $auth = 'read') {
|
||||
global $FarmD, $WikiTitle, $ScriptUrl;
|
||||
$feedfile = $FarmD."/pub/recallfeed.xml"; #change to a pattern when support arguments
|
||||
|
||||
// PATTERNS
|
||||
// TODO
|
||||
// * transform to math functions
|
||||
// * add some randomness
|
||||
// * add a bunded random recall
|
||||
$exponential_pattern = array(1,10,30,60,120,350,700,1500,3000,7000,15000,30000,100000); //exp
|
||||
// $datestorecall = array(1,10,30,60..,61,62..,80..);
|
||||
$monthly_pattern = array(1,30,60,90,120,150,180,210,240,270,300); //mod30
|
||||
$weekly_pattern = array(1,7,14,21,28,35,43,50,57,64,71,78,85,93,100,101,107,114,121,128,135,143,150,157,164,171,178,185,193,100); //mod7
|
||||
$daily_pattern = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30); //mod1
|
||||
$datestorecall = $exponential_pattern;
|
||||
$varname='recall';
|
||||
|
||||
$pages = ListPages();
|
||||
# open $feed as read
|
||||
if (!file_exists($feedfile))
|
||||
if (!touch($feedfile))
|
||||
print "Creation of the feed file fails, check write permissions for pmWiki and $feedfile.";
|
||||
|
||||
$feed_oldcontent = file_get_contents($feedfile);
|
||||
|
||||
$feed_newcontent = '';
|
||||
|
||||
# 2 loops can be probably optimized since they are ordered by date
|
||||
foreach ($pages as $page) {
|
||||
$recall = PageTextVar($page,$varname);
|
||||
if ( isset($recall) ) {
|
||||
$params = explode(" ",$recall);
|
||||
$patternrecall = $params[1];
|
||||
$daterecall = $params[0];
|
||||
switch($patternrecall){
|
||||
case "daily": $datestorecall = $daily_pattern; break;
|
||||
case "weekly": $datestorecall = $weekly_pattern; break;
|
||||
case "monthly": $datestorecall = $monthly_pattern; break;
|
||||
case "exponentially": $datestorecall = $exponential_pattern; break;
|
||||
}
|
||||
foreach ($datestorecall as $day) {
|
||||
# print $page . " ";
|
||||
$checkdate = addDate_BehaviorRecall(convertDate_BehaviorRecall($daterecall),$day);
|
||||
# print $daterecall . " + " . $day . " (" . $checkdate . ") == " . date("d/m/Y");
|
||||
if ($checkdate==convertDate_BehaviorRecall(date("d/m/Y")))
|
||||
{
|
||||
# print " recall time";
|
||||
# generate GUID
|
||||
$item_GUID = $page.'_'.$checkdate;
|
||||
# if not present in file using a regex on the GUID
|
||||
if (preg_match("/$item_GUID/",$feed_oldcontent) == 0)
|
||||
{
|
||||
|
||||
# generate date
|
||||
$feed_newitemdate = date(DATE_RSS, time());
|
||||
# transform line to XML format
|
||||
$cleaned_page_name = str_replace(".","/",$page);
|
||||
global $FmtV;
|
||||
$pagecontent = FmtPageName($FmtV, $page);
|
||||
$feed_newitem = " <item>
|
||||
<title>Day $day recall for page $page started at $daterecall</title>
|
||||
<link>$ScriptUrl/$cleaned_page_name#BehaviorRecallDay$day</link>
|
||||
<description>This is to improve behaviors you decided yourself were valuable. Also don't forget to improve those instructions to be more and more efficient!$pagecontent</description>
|
||||
<guid>$item_GUID</guid>
|
||||
<pubDate>$feed_newitemdate</pubDate>
|
||||
</item>";
|
||||
# appending the item
|
||||
$feed_newcontent .= $feed_newitem;
|
||||
}
|
||||
break; #we can't have 2 days at the same time
|
||||
}
|
||||
# print "<br/>";
|
||||
} # check if the next recall day is today
|
||||
} # check if the next page is tagged
|
||||
}
|
||||
# feed should be properly updated
|
||||
|
||||
$feed_newdate = date(DATE_RSS, time());
|
||||
|
||||
$feed_header = "<?xml version=\"1.0\"?>
|
||||
<rss version=\"2.0\">
|
||||
<channel>
|
||||
<title>BehaviorRecall feed for $WikiTitle .</title>
|
||||
<link>$ScriptUrl</link>
|
||||
<description>Receive links as reminded to periodic behaviors you want to transform to habits.</description>
|
||||
<lastBuildDate>$feed_newdate</lastBuildDate>";
|
||||
|
||||
$feed_footer = "
|
||||
</channel>
|
||||
</rss>";
|
||||
|
||||
|
||||
# print header
|
||||
print $feed_header;
|
||||
|
||||
# print items
|
||||
print $feed_oldcontent;
|
||||
# $feed_newcontent = str_replace(array_keys($EntitiesTable), array_values($EntitiesTable), $feed_newcontent);
|
||||
print $feed_newcontent;
|
||||
|
||||
# print footer
|
||||
print $feed_footer;
|
||||
|
||||
$write_result = file_put_contents($feedfile,$feed_oldcontent.$feed_newcontent);
|
||||
if (!$write_result)
|
||||
if (strlen($feed_oldcontent.$feed_newcontent)>0)
|
||||
print "Creation of the feed file fails, check write permissions for pmWiki and $feedfile.";
|
||||
else
|
||||
print "No item to generate, did you correctly tag your pages?";
|
||||
}
|
||||
|
||||
## Since most feeds don't understand html character entities, we
|
||||
## convert the common ones to their numeric form here.
|
||||
## Taken from /scripts/feeds.php
|
||||
SDVA($EntitiesTable, array(
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"
|
||||
' ' => ' ',
|
||||
'¡' => '¡',
|
||||
'¢' => '¢',
|
||||
'£' => '£',
|
||||
'¤' => '¤',
|
||||
'¥' => '¥',
|
||||
'¦' => '¦',
|
||||
'§' => '§',
|
||||
'¨' => '¨',
|
||||
'©' => '©',
|
||||
'ª' => 'ª',
|
||||
'«' => '«',
|
||||
'¬' => '¬',
|
||||
'­' => '­',
|
||||
'®' => '®',
|
||||
'¯' => '¯',
|
||||
'°' => '°',
|
||||
'±' => '±',
|
||||
'²' => '²',
|
||||
'³' => '³',
|
||||
'´' => '´',
|
||||
'µ' => 'µ',
|
||||
'¶' => '¶',
|
||||
'·' => '·',
|
||||
'¸' => '¸',
|
||||
'¹' => '¹',
|
||||
'º' => 'º',
|
||||
'»' => '»',
|
||||
'¼' => '¼',
|
||||
'½' => '½',
|
||||
'¾' => '¾',
|
||||
'¿' => '¿',
|
||||
'À' => 'À',
|
||||
'Á' => 'Á',
|
||||
'Â' => 'Â',
|
||||
'Ã' => 'Ã',
|
||||
'Ä' => 'Ä',
|
||||
'Å' => 'Å',
|
||||
'Æ' => 'Æ',
|
||||
'Ç' => 'Ç',
|
||||
'È' => 'È',
|
||||
'É' => 'É',
|
||||
'Ê' => 'Ê',
|
||||
'Ë' => 'Ë',
|
||||
'Ì' => 'Ì',
|
||||
'Í' => 'Í',
|
||||
'Î' => 'Î',
|
||||
'Ï' => 'Ï',
|
||||
'Ð' => 'Ð',
|
||||
'Ñ' => 'Ñ',
|
||||
'Ò' => 'Ò',
|
||||
'Ó' => 'Ó',
|
||||
'Ô' => 'Ô',
|
||||
'Õ' => 'Õ',
|
||||
'Ö' => 'Ö',
|
||||
'×' => '×',
|
||||
'Ø' => 'Ø',
|
||||
'Ù' => 'Ù',
|
||||
'Ú' => 'Ú',
|
||||
'Û' => 'Û',
|
||||
'Ü' => 'Ü',
|
||||
'Ý' => 'Ý',
|
||||
'Þ' => 'Þ',
|
||||
'ß' => 'ß',
|
||||
'à' => 'à',
|
||||
'á' => 'á',
|
||||
'â' => 'â',
|
||||
'ã' => 'ã',
|
||||
'ä' => 'ä',
|
||||
'å' => 'å',
|
||||
'æ' => 'æ',
|
||||
'ç' => 'ç',
|
||||
'è' => 'è',
|
||||
'é' => 'é',
|
||||
'ê' => 'ê',
|
||||
'ë' => 'ë',
|
||||
'ì' => 'ì',
|
||||
'í' => 'í',
|
||||
'î' => 'î',
|
||||
'ï' => 'ï',
|
||||
'ð' => 'ð',
|
||||
'ñ' => 'ñ',
|
||||
'ò' => 'ò',
|
||||
'ó' => 'ó',
|
||||
'ô' => 'ô',
|
||||
'õ' => 'õ',
|
||||
'ö' => 'ö',
|
||||
'÷' => '÷',
|
||||
'ø' => 'ø',
|
||||
'ù' => 'ù',
|
||||
'ú' => 'ú',
|
||||
'û' => 'û',
|
||||
'ü' => 'ü',
|
||||
'ý' => 'ý',
|
||||
'þ' => 'þ',
|
||||
'ÿ' => 'ÿ',
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
|
||||
'"' => '"',
|
||||
#'&' => '&#38;',
|
||||
#'<' => '&#60;',
|
||||
#'>' => '>',
|
||||
''' => ''',
|
||||
'Œ' => 'Œ',
|
||||
'œ' => 'œ',
|
||||
'Š' => 'Š',
|
||||
'š' => 'š',
|
||||
'Ÿ' => 'Ÿ',
|
||||
'ˆ' => 'ˆ',
|
||||
'˜' => '˜',
|
||||
' ' => ' ',
|
||||
' ' => ' ',
|
||||
' ' => ' ',
|
||||
'‌' => '‌',
|
||||
'‍' => '‍',
|
||||
'‎' => '‎',
|
||||
'‏' => '‏',
|
||||
'–' => '–',
|
||||
'—' => '—',
|
||||
'‘' => '‘',
|
||||
'’' => '’',
|
||||
'‚' => '‚',
|
||||
'“' => '“',
|
||||
'”' => '”',
|
||||
'„' => '„',
|
||||
'†' => '†',
|
||||
'‡' => '‡',
|
||||
'‰' => '‰',
|
||||
'‹' => '‹',
|
||||
'›' => '›',
|
||||
'€' => '€',
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
|
||||
'ƒ' => 'ƒ',
|
||||
'Α' => 'Α',
|
||||
'Β' => 'Β',
|
||||
'Γ' => 'Γ',
|
||||
'Δ' => 'Δ',
|
||||
'Ε' => 'Ε',
|
||||
'Ζ' => 'Ζ',
|
||||
'Η' => 'Η',
|
||||
'Θ' => 'Θ',
|
||||
'Ι' => 'Ι',
|
||||
'Κ' => 'Κ',
|
||||
'Λ' => 'Λ',
|
||||
'Μ' => 'Μ',
|
||||
'Ν' => 'Ν',
|
||||
'Ξ' => 'Ξ',
|
||||
'Ο' => 'Ο',
|
||||
'Π' => 'Π',
|
||||
'Ρ' => 'Ρ',
|
||||
'Σ' => 'Σ',
|
||||
'Τ' => 'Τ',
|
||||
'Υ' => 'Υ',
|
||||
'Φ' => 'Φ',
|
||||
'Χ' => 'Χ',
|
||||
'Ψ' => 'Ψ',
|
||||
'Ω' => 'Ω',
|
||||
'α' => 'α',
|
||||
'β' => 'β',
|
||||
'γ' => 'γ',
|
||||
'δ' => 'δ',
|
||||
'ε' => 'ε',
|
||||
'ζ' => 'ζ',
|
||||
'η' => 'η',
|
||||
'θ' => 'θ',
|
||||
'ι' => 'ι',
|
||||
'κ' => 'κ',
|
||||
'λ' => 'λ',
|
||||
'μ' => 'μ',
|
||||
'ν' => 'ν',
|
||||
'ξ' => 'ξ',
|
||||
'ο' => 'ο',
|
||||
'π' => 'π',
|
||||
'ρ' => 'ρ',
|
||||
'ς' => 'ς',
|
||||
'σ' => 'σ',
|
||||
'τ' => 'τ',
|
||||
'υ' => 'υ',
|
||||
'φ' => 'φ',
|
||||
'χ' => 'χ',
|
||||
'ψ' => 'ψ',
|
||||
'ω' => 'ω',
|
||||
'ϑ' => 'ϑ',
|
||||
'ϒ' => 'ϒ',
|
||||
'ϖ' => 'ϖ',
|
||||
'•' => '•',
|
||||
'…' => '…',
|
||||
'′' => '′',
|
||||
'″' => '″',
|
||||
'‾' => '‾',
|
||||
'⁄' => '⁄',
|
||||
'℘' => '℘',
|
||||
'ℑ' => 'ℑ',
|
||||
'ℜ' => 'ℜ',
|
||||
'™' => '™',
|
||||
'ℵ' => 'ℵ',
|
||||
'←' => '←',
|
||||
'↑' => '↑',
|
||||
'→' => '→',
|
||||
'↓' => '↓',
|
||||
'↔' => '↔',
|
||||
'↵' => '↵',
|
||||
'⇐' => '⇐',
|
||||
'⇑' => '⇑',
|
||||
'⇒' => '⇒',
|
||||
'⇓' => '⇓',
|
||||
'⇔' => '⇔',
|
||||
'∀' => '∀',
|
||||
'∂' => '∂',
|
||||
'∃' => '∃',
|
||||
'∅' => '∅',
|
||||
'∇' => '∇',
|
||||
'∈' => '∈',
|
||||
'∉' => '∉',
|
||||
'∋' => '∋',
|
||||
'∏' => '∏',
|
||||
'∑' => '∑',
|
||||
'−' => '−',
|
||||
'∗' => '∗',
|
||||
'√' => '√',
|
||||
'∝' => '∝',
|
||||
'∞' => '∞',
|
||||
'∠' => '∠',
|
||||
'∧' => '∧',
|
||||
'∨' => '∨',
|
||||
'∩' => '∩',
|
||||
'∪' => '∪',
|
||||
'∫' => '∫',
|
||||
'∴' => '∴',
|
||||
'∼' => '∼',
|
||||
'≅' => '≅',
|
||||
'≈' => '≈',
|
||||
'≠' => '≠',
|
||||
'≡' => '≡',
|
||||
'≤' => '≤',
|
||||
'≥' => '≥',
|
||||
'⊂' => '⊂',
|
||||
'⊃' => '⊃',
|
||||
'⊄' => '⊄',
|
||||
'⊆' => '⊆',
|
||||
'⊇' => '⊇',
|
||||
'⊕' => '⊕',
|
||||
'⊗' => '⊗',
|
||||
'⊥' => '⊥',
|
||||
'⋅' => '⋅',
|
||||
'⌈' => '⌈',
|
||||
'⌉' => '⌉',
|
||||
'⌊' => '⌊',
|
||||
'⌋' => '⌋',
|
||||
'⟨' => '〈',
|
||||
'⟩' => '〉',
|
||||
'◊' => '◊',
|
||||
'♠' => '♠',
|
||||
'♣' => '♣',
|
||||
'♥' => '♥',
|
||||
'♦' => '♦'));
|
||||
75
cookbook/coeditions.php
Normal file
75
cookbook/coeditions.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
# return coeditions for a wholewiki
|
||||
|
||||
function Coeditions($groupname){
|
||||
|
||||
global $ScriptUrl, $PubDir, $FarmD;
|
||||
$cache_time = 0; # set to 0 to disable cache, practical for testing
|
||||
$cache_time = 3600;
|
||||
$cachefile = "/pub/coedits.txt";
|
||||
$timewindow = 360; # in seconds
|
||||
$pagelist = ListPages("/$groupname\./e");
|
||||
// consider removing structural pages (headers, PmWiki, Site, ...)
|
||||
// mostly case by default since those remains into wikilib.d unless modified
|
||||
|
||||
//unset($pagelist[array_search("$groupname.Template",$pagelist)]);
|
||||
|
||||
# cache since its costly
|
||||
if (!file_exists($FarmD.$cachefile)){
|
||||
if (!touch($FarmD.$cachefile))
|
||||
print "Creation of the cache file fails, check write permissions for pmWiki and $cachefile.";
|
||||
# if cache exist
|
||||
} else {
|
||||
# cache has been generated recently
|
||||
if (( (time() - filemtime($FarmD.$cachefile)) < $cache_time ) && $groupname == "")
|
||||
#return it
|
||||
return unserialize(file_get_contents($FarmD.$cachefile));
|
||||
}
|
||||
|
||||
foreach ($pagelist as $pagename){
|
||||
$page = ReadPage($pagename);
|
||||
if (!$page) return;
|
||||
krsort($page); reset($page);
|
||||
|
||||
foreach($page as $k=>$v) {
|
||||
if (!preg_match("/^diff:(\d+):(\d+):?([^:]*)/",$k,$match)) continue;
|
||||
$diff = intval($match[1]);
|
||||
$edits[] = array ("diff" => $diff, "name" => $pagename);
|
||||
$diffs[] = $diff;
|
||||
$names[] = $pagename;
|
||||
#automatic index since there might multiple edits with the same diff
|
||||
}
|
||||
}
|
||||
# numeric sort $edits by ascending diff (either regenerate or discard index)
|
||||
array_multisort($diffs,SORT_ASC,SORT_NUMERIC,$names);
|
||||
//var_dump($diffs,$names);
|
||||
$numberofedits = count($diffs);
|
||||
for ($j=0;$j<$numberofedits;$j++){
|
||||
if (($diffs[$j+1]-$diffs[$j])<$timewindow){
|
||||
$target = $names[$j];
|
||||
$dest = $names[$j+1];
|
||||
$coedits["$target"]["$dest"]++ ;
|
||||
# dirty since it's a string, not a proper table but will do for tests
|
||||
}
|
||||
}
|
||||
foreach ($coedits as &$ce){
|
||||
arsort($ce,SORT_NUMERIC);
|
||||
//$scoedits[] = $ce;
|
||||
}
|
||||
//var_dump($coedits);
|
||||
|
||||
# should highlight the highest coedition that is not self
|
||||
# also remove under a certain threshold, e.g. 1 or rather a sigma of the distribution
|
||||
# most result are... from the same page
|
||||
# it could thus be noted then filtered
|
||||
# also the timewindow gives only short-term result
|
||||
# a second processing could check over long-term editions between pages
|
||||
|
||||
#write cache
|
||||
if ($groupname == "")
|
||||
$write_result = file_put_contents($FarmD.$cachefile,serialize($coedits));
|
||||
return $coedits;
|
||||
}
|
||||
|
||||
?>
|
||||
162
cookbook/groupkeypages.php
Normal file
162
cookbook/groupkeypages.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
# return the "key pages" of a group
|
||||
# todo
|
||||
# http://phpir.com/pagerank-in-php
|
||||
# http://faculty.ucr.edu/~hanneman/nettext/C10_Centrality.html#Betweenness
|
||||
# check if isset() really is necessary, seems it was avoided in Coeditions
|
||||
|
||||
function GroupKeyPages($groupname,$selectionmechanism=""){
|
||||
$pages = ListPages("/$groupname\./e");
|
||||
|
||||
//note that this could be replaced by proper ListPages call
|
||||
$pages = CleanPageList($pages,$groupname);
|
||||
|
||||
$b = GenerateNetworkFromList($pages);
|
||||
//var_dump($b);
|
||||
|
||||
switch ($selectionmechanism) {
|
||||
case "NetworkLeverageCentrality":
|
||||
$keypages = $selectionmechanism($b,0.05); # value threshold
|
||||
break;
|
||||
case "NetworkOutgoingIncoming":
|
||||
$keypages = $selectionmechanism($b,4,5); # outgoing and incoming degree threshold
|
||||
break;
|
||||
default:
|
||||
$keypages = NetworkDegree($b,8); # degree threshold
|
||||
}
|
||||
return array_unique($keypages);
|
||||
}
|
||||
|
||||
|
||||
function GenerateNetworkFromList($pagelist){
|
||||
foreach ($pagelist as $page) {
|
||||
$content = ReadPage($page,$since=0);
|
||||
$links = $content["targets"];
|
||||
$links_array = explode(",",$links);
|
||||
foreach ($links_array as $link) {
|
||||
if (($linkindex = array_search($link,$pagelist)) !== false ){
|
||||
if (isset($b["$page"]["outgoing"]))
|
||||
$b["$page"]["outgoing"]++;
|
||||
else
|
||||
{ $b["$page"]["outgoing"] = 1; $b["$page"]["name"]=$page; }
|
||||
if (isset( $b["$link"]["incoming"]))
|
||||
$b["$link"]["incoming"]++;
|
||||
else
|
||||
{ $b["$link"]["incoming"] = 1; $b["$link"]["name"]=$link; }
|
||||
if (isset($b["$page"]["degree"]))
|
||||
$b["$page"]["degree"]++;
|
||||
else
|
||||
{ $b["$page"]["degree"] = 1; $b["$page"]["name"]=$page; }
|
||||
if (isset($b["$link"]["degree"]))
|
||||
$b["$link"]["degree"]++;
|
||||
else
|
||||
{ $b["$link"]["degree"] = 1; $b["$link"]["name"]=$link; }
|
||||
$b["$page"]["neighboors"][] = $link;
|
||||
$b["$link"]["neighboors"][] = $page;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $b;
|
||||
}
|
||||
|
||||
function CleanPageList($pagelist,$groupname){
|
||||
// rather arbitrary, not necessarily a good choice
|
||||
unset($pagelist[array_search("$groupname.$groupname",$pagelist)]);
|
||||
unset($pagelist[array_search("$groupname.Template",$pagelist)]);
|
||||
unset($pagelist[array_search("$groupname.GroupHeader",$pagelist)]);
|
||||
unset($pagelist[array_search("$groupname.GroupFooter",$pagelist)]);
|
||||
return $pagelist;
|
||||
}
|
||||
|
||||
function NetworkOutgoingIncoming($b,$IncomingThreshold=0,$OutgoingThreshold=0){
|
||||
$keypages = array(); //done to avoid returning notthing if the theshold is too high
|
||||
foreach ($b as $bs){
|
||||
if (isset($bs["incoming"]))
|
||||
if ($bs["incoming"] > $IncomingThreshold )
|
||||
$keypages[] = $bs["name"];
|
||||
if (isset($bs["outgoing"]))
|
||||
if ($bs["outgoing"] > $OutgoingThreshold )
|
||||
$keypages[] = $bs["name"];
|
||||
}
|
||||
return $keypages;
|
||||
}
|
||||
|
||||
function NetworkDegree($b, $DegreeThreshold=0){
|
||||
$keypages = array(); //done to avoid returning notthing if the theshold is too high
|
||||
foreach ($b as $bs){
|
||||
if (isset($bs["degree"]))
|
||||
if ($bs["degree"] > $DegreeThreshold )
|
||||
$keypages[] = $bs["name"];
|
||||
}
|
||||
return $keypages;
|
||||
}
|
||||
|
||||
function NetworkLeverageCentrality($b,$Threshold=0){
|
||||
$keypages = array(); //done to avoid returning notthing if the theshold is too high
|
||||
foreach ($b as $bs){
|
||||
if (isset($bs["neighboors"])){
|
||||
$bs["leveragecentrality"] = 0;
|
||||
$sum = 0; $avg=0;
|
||||
foreach($bs["neighboors"] as $neighboor){
|
||||
$sum += ($bs["degree"] - $b["$neighboor"]["degree"]) / ($bs["degree"] + $b["$neighboor"]["degree"]);
|
||||
$avg += $b["$neighboor"]["degree"];
|
||||
}
|
||||
if ($bs["degree"] > 0){
|
||||
$avg = $avg / $bs["degree"];
|
||||
if ($avg > 0){
|
||||
$bs["leveragecentrality"] = ($sum/$avg) / $bs["degree"];
|
||||
}
|
||||
}
|
||||
if ($bs["leveragecentrality"] > $Threshold )
|
||||
$keypages[] = $bs["name"];
|
||||
}
|
||||
}
|
||||
return $keypages;
|
||||
}
|
||||
|
||||
function GroupDegreeDistribution($groupname){
|
||||
$pages = ListPages("/$groupname\./e");
|
||||
|
||||
//note that this could be replaced by proper ListPages call
|
||||
$pages = CleanPageList($pages,$groupname);
|
||||
|
||||
$b = GenerateNetworkFromList($pages);
|
||||
|
||||
$distribution = array_fill(1,10,0);
|
||||
// has no effect
|
||||
|
||||
foreach ($b as $node){
|
||||
$degree = $node["degree"];
|
||||
if (isset($distribution[$degree]))
|
||||
$distribution[$degree]++;
|
||||
else
|
||||
$distribution[$degree]=1;
|
||||
$sumdeg += $node["degree"];
|
||||
$sumin += $node["incoming"];
|
||||
$sumout += $node["outgoing"];
|
||||
}
|
||||
$avgdeg = $sumdeg / count($b);
|
||||
$avgin = $sumin / count($b);
|
||||
$avgout = $sumout / count($b);
|
||||
|
||||
/*
|
||||
print "avgdeg = $avgdeg; ";
|
||||
print "avgin = $avgin; ";
|
||||
print "avgout = $avgout; ";
|
||||
strangely equal, probably a mistake there
|
||||
*/
|
||||
ksort($distribution);
|
||||
|
||||
/* fails to get the proper last key
|
||||
end($distribution);
|
||||
$last_key = key($distribution);
|
||||
print $last_key;
|
||||
for ($i=1;i<$last_key;$i++)
|
||||
if (!(isset($distribution[$i])))
|
||||
$distribution[$i]=0;
|
||||
*/
|
||||
return array_unique($distribution);
|
||||
}
|
||||
|
||||
?>
|
||||
50
cookbook/groupstats.php
Normal file
50
cookbook/groupstats.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
# give a visual representation of pages and group
|
||||
#
|
||||
# action for the whole wiki (equivalent to group="") done through AllPages fake group
|
||||
# add the GroupKeyPages function as a parameter
|
||||
|
||||
$RecipeInfo['GroupStats']['Version'] = '2011-08-06';
|
||||
|
||||
$HandleActions['GroupStats'] = 'GroupStats'; # if url contains action=myaction call HandleMyAction timely
|
||||
$HandleAuth['GroupStats'] = 'read'; # authorization level $auth for HandleMyAction
|
||||
|
||||
function GroupStats($pagename, $auth){
|
||||
list($group,$page) = explode(".",$pagename);
|
||||
$distmax = 15;
|
||||
if ($group == "AllPages"){
|
||||
// equivalent to getting ALL pages
|
||||
$group = "";
|
||||
$distmax = 50;
|
||||
}
|
||||
$dist= GroupDegreeDistribution($group);
|
||||
for($i=1;$i<$distmax;$i++){
|
||||
if (isset($dist[$i]))
|
||||
$distribution .= $dist[$i].",";
|
||||
else
|
||||
$distribution .= "0,";
|
||||
}
|
||||
$max = max($dist);
|
||||
$upperbound = $dist[($distmax/5)];
|
||||
$img = "http://sparklines.bitworking.info/spark.cgi?type=impulse"
|
||||
."&d=$distribution&height=100"
|
||||
."&limits=0,$max"
|
||||
."&upper=$upperbound&above-color=red&below-color=gray&width=15&.png";
|
||||
$selectingalgo = "NetworkDegree";
|
||||
# can also be NetworkOutgoingIncoming or NetworkLeverageCentrality or NetworkDegree
|
||||
# threshold are set later on
|
||||
$keypages = var_export(GroupKeyPages($group, $selectingalgo),true);
|
||||
$coeditions = var_export(Coeditions($group),true);
|
||||
# could be improvied by coloring
|
||||
# link to self
|
||||
# links that do not exist explicitely
|
||||
print "<h1>Group statistics for $group</h1>"
|
||||
."<hr/><h2>Degree distribution</h2>(from d(1) to d(max), d()=0 excluded, max(d())=2, avg(d())~=4):</br>"
|
||||
.$distribution."<br><img src=\"$img\" /><br>"
|
||||
."<hr/><h2><a name=\"Key pages\"></a>Keypages using $selectingalgo</h2><pre>".$keypages."</pre>"
|
||||
."<hr/><h2><a name=\"Coeditions\"></a>Coedition</h2><pre>".$coeditions."</pre>";
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
386
cookbook/memorization.php
Normal file
386
cookbook/memorization.php
Normal file
@@ -0,0 +1,386 @@
|
||||
<?php if (!defined('PmWiki')) exit();
|
||||
/*
|
||||
inspired by PageFeed by Daniel Roesler (diafygi)
|
||||
conversation array imported from it
|
||||
*/
|
||||
|
||||
## Recipe version information
|
||||
$RecipeInfo['Memorization']['Version'] = '2010-04-02';
|
||||
|
||||
## Add action for pagefeed
|
||||
SDV($HandleActions['memorization'], 'Memorization');
|
||||
|
||||
# from http://www.pmwiki.org/wiki/PmWiki/Functions
|
||||
function FeedText($pagename, &$page, $tag) {
|
||||
$text = RetrieveAuthSection("ReadingNotes.GroupHeader","");
|
||||
$content = MarkupToHTML($pagename, $text);
|
||||
$text = RetrieveAuthSection($pagename, '##Chapter2');
|
||||
$content .= MarkupToHTML($pagename, $text);
|
||||
return "<$tag><![CDATA[$content]]></$tag>";
|
||||
}
|
||||
|
||||
function addDate($date,$day)//add days
|
||||
{
|
||||
$sum = strtotime(date("Y-m-d", strtotime("$date")) . " +$day days");
|
||||
$dateTo=date('Y-m-d',$sum);
|
||||
return $dateTo;
|
||||
}
|
||||
function convertdate($date) {
|
||||
return preg_replace("/(\d+)\/(\d+)\/(\d+)/",'$3-$2-$1',$date);
|
||||
}
|
||||
|
||||
## Create feed from page history
|
||||
function Memorization($pagename, $auth = 'read') {
|
||||
global $FarmD, $WikiTitle, $ScriptUrl;
|
||||
$feedfile = $FarmD."/pub/memorizationfeed.xml"; #change to a pattern when support arguments
|
||||
$datestorecall = array(1,10,30,60,120,350,700,1500,3000,7000,15000,30000,100000);
|
||||
// $datestorecall = array(1,10,30,60..,61,62..,80..);
|
||||
$varname='startrecall';
|
||||
|
||||
$pages = ListPages();
|
||||
# open $feed as read
|
||||
if (!file_exists($feedfile))
|
||||
if (!touch($feedfile))
|
||||
print "Creation of the feed file fails, check write permissions for pmWiki and $feedfile.";
|
||||
|
||||
$feed_oldcontent = file_get_contents($feedfile);
|
||||
|
||||
$feed_newcontent = '';
|
||||
|
||||
# 2 loops can be probably optimized since they are ordered by date
|
||||
foreach ($pages as $page) {
|
||||
$daterecall = PageTextVar($page,$varname);
|
||||
if ( isset($daterecall) ) {
|
||||
foreach ($datestorecall as $day) {
|
||||
# print $page . " ";
|
||||
$checkdate = addDate(convertdate($daterecall),$day);
|
||||
# print $daterecall . " + " . $day . " (" . $checkdate . ") == " . date("d/m/Y");
|
||||
if ($checkdate==convertdate(date("d/m/Y")))
|
||||
{
|
||||
# print " recall time";
|
||||
# generate GUID
|
||||
$item_GUID = $page.'_'.$checkdate;
|
||||
# if not present in file using a regex on the GUID
|
||||
if (preg_match("/$item_GUID/",$feed_oldcontent) == 0)
|
||||
{
|
||||
|
||||
# generate date
|
||||
$feed_newitemdate = date(DATE_RSS, time());
|
||||
# transform line to XML format
|
||||
$cleaned_page_name = str_replace(".","/",$page);
|
||||
// function FeedText($pagename, &$page, $tag) {
|
||||
//"manually" add the cover by simulating the GroupHeadre (read page ISBN + if exist display image)
|
||||
$feed_newitem = " <item>
|
||||
<title>Day $day recall for page $page started at $daterecall</title>
|
||||
<link>$ScriptUrl/$cleaned_page_name#MemorizationDay$day</link>"
|
||||
.FeedText($page,$page,"description").
|
||||
"<guid>$item_GUID</guid>
|
||||
<pubDate>$feed_newitemdate</pubDate>
|
||||
</item>";
|
||||
# bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
|
||||
# appending the item
|
||||
$feed_newcontent .= $feed_newitem;
|
||||
}
|
||||
break; #we can't have 2 days at the same time
|
||||
}
|
||||
# print "<br/>";
|
||||
} # check if the next recall day is today
|
||||
} # check if the next page is tagged
|
||||
}
|
||||
# feed should be properly updated
|
||||
|
||||
$feed_newdate = date(DATE_RSS, time());
|
||||
|
||||
$feed_header = "<?xml version=\"1.0\"?>
|
||||
<rss version=\"2.0\">
|
||||
<channel>
|
||||
<title>Memorization feed for $WikiTitle .</title>
|
||||
<link>$ScriptUrl</link>
|
||||
<description>Receive links to the page you tagged in order to have optimal memorization.</description>
|
||||
<generator>Generated by http://fabien.benetou.fr/Wiki/MemoryRecipe for PmWiki</generator>
|
||||
<lastBuildDate>$feed_newdate</lastBuildDate>";
|
||||
|
||||
$feed_footer = "
|
||||
</channel>
|
||||
</rss>";
|
||||
|
||||
|
||||
# print header
|
||||
print $feed_header;
|
||||
|
||||
# print items
|
||||
print $feed_oldcontent;
|
||||
# $feed_newcontent = str_replace(array_keys($EntitiesTable), array_values($EntitiesTable), $feed_newcontent);
|
||||
print $feed_newcontent;
|
||||
|
||||
# print footer
|
||||
print $feed_footer;
|
||||
|
||||
$write_result = file_put_contents($feedfile,$feed_oldcontent.$feed_newcontent);
|
||||
if (!$write_result)
|
||||
if (strlen($feed_oldcontent.$feed_newcontent)>0)
|
||||
print "Creation of the feed file fails, check write permissions for pmWiki and $feedfile.";
|
||||
else
|
||||
print "No item to generate, did you correctly tag your pages?";
|
||||
}
|
||||
|
||||
## Since most feeds don't understand html character entities, we
|
||||
## convert the common ones to their numeric form here.
|
||||
## Taken from /scripts/feeds.php
|
||||
SDVA($EntitiesTable, array(
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"
|
||||
' ' => ' ',
|
||||
'¡' => '¡',
|
||||
'¢' => '¢',
|
||||
'£' => '£',
|
||||
'¤' => '¤',
|
||||
'¥' => '¥',
|
||||
'¦' => '¦',
|
||||
'§' => '§',
|
||||
'¨' => '¨',
|
||||
'©' => '©',
|
||||
'ª' => 'ª',
|
||||
'«' => '«',
|
||||
'¬' => '¬',
|
||||
'­' => '­',
|
||||
'®' => '®',
|
||||
'¯' => '¯',
|
||||
'°' => '°',
|
||||
'±' => '±',
|
||||
'²' => '²',
|
||||
'³' => '³',
|
||||
'´' => '´',
|
||||
'µ' => 'µ',
|
||||
'¶' => '¶',
|
||||
'·' => '·',
|
||||
'¸' => '¸',
|
||||
'¹' => '¹',
|
||||
'º' => 'º',
|
||||
'»' => '»',
|
||||
'¼' => '¼',
|
||||
'½' => '½',
|
||||
'¾' => '¾',
|
||||
'¿' => '¿',
|
||||
'À' => 'À',
|
||||
'Á' => 'Á',
|
||||
'Â' => 'Â',
|
||||
'Ã' => 'Ã',
|
||||
'Ä' => 'Ä',
|
||||
'Å' => 'Å',
|
||||
'Æ' => 'Æ',
|
||||
'Ç' => 'Ç',
|
||||
'È' => 'È',
|
||||
'É' => 'É',
|
||||
'Ê' => 'Ê',
|
||||
'Ë' => 'Ë',
|
||||
'Ì' => 'Ì',
|
||||
'Í' => 'Í',
|
||||
'Î' => 'Î',
|
||||
'Ï' => 'Ï',
|
||||
'Ð' => 'Ð',
|
||||
'Ñ' => 'Ñ',
|
||||
'Ò' => 'Ò',
|
||||
'Ó' => 'Ó',
|
||||
'Ô' => 'Ô',
|
||||
'Õ' => 'Õ',
|
||||
'Ö' => 'Ö',
|
||||
'×' => '×',
|
||||
'Ø' => 'Ø',
|
||||
'Ù' => 'Ù',
|
||||
'Ú' => 'Ú',
|
||||
'Û' => 'Û',
|
||||
'Ü' => 'Ü',
|
||||
'Ý' => 'Ý',
|
||||
'Þ' => 'Þ',
|
||||
'ß' => 'ß',
|
||||
'à' => 'à',
|
||||
'á' => 'á',
|
||||
'â' => 'â',
|
||||
'ã' => 'ã',
|
||||
'ä' => 'ä',
|
||||
'å' => 'å',
|
||||
'æ' => 'æ',
|
||||
'ç' => 'ç',
|
||||
'è' => 'è',
|
||||
'é' => 'é',
|
||||
'ê' => 'ê',
|
||||
'ë' => 'ë',
|
||||
'ì' => 'ì',
|
||||
'í' => 'í',
|
||||
'î' => 'î',
|
||||
'ï' => 'ï',
|
||||
'ð' => 'ð',
|
||||
'ñ' => 'ñ',
|
||||
'ò' => 'ò',
|
||||
'ó' => 'ó',
|
||||
'ô' => 'ô',
|
||||
'õ' => 'õ',
|
||||
'ö' => 'ö',
|
||||
'÷' => '÷',
|
||||
'ø' => 'ø',
|
||||
'ù' => 'ù',
|
||||
'ú' => 'ú',
|
||||
'û' => 'û',
|
||||
'ü' => 'ü',
|
||||
'ý' => 'ý',
|
||||
'þ' => 'þ',
|
||||
'ÿ' => 'ÿ',
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
|
||||
'"' => '"',
|
||||
#'&' => '&#38;',
|
||||
#'<' => '&#60;',
|
||||
#'>' => '>',
|
||||
''' => ''',
|
||||
'Œ' => 'Œ',
|
||||
'œ' => 'œ',
|
||||
'Š' => 'Š',
|
||||
'š' => 'š',
|
||||
'Ÿ' => 'Ÿ',
|
||||
'ˆ' => 'ˆ',
|
||||
'˜' => '˜',
|
||||
' ' => ' ',
|
||||
' ' => ' ',
|
||||
' ' => ' ',
|
||||
'‌' => '‌',
|
||||
'‍' => '‍',
|
||||
'‎' => '‎',
|
||||
'‏' => '‏',
|
||||
'–' => '–',
|
||||
'—' => '—',
|
||||
'‘' => '‘',
|
||||
'’' => '’',
|
||||
'‚' => '‚',
|
||||
'“' => '“',
|
||||
'”' => '”',
|
||||
'„' => '„',
|
||||
'†' => '†',
|
||||
'‡' => '‡',
|
||||
'‰' => '‰',
|
||||
'‹' => '‹',
|
||||
'›' => '›',
|
||||
'€' => '€',
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
|
||||
'ƒ' => 'ƒ',
|
||||
'Α' => 'Α',
|
||||
'Β' => 'Β',
|
||||
'Γ' => 'Γ',
|
||||
'Δ' => 'Δ',
|
||||
'Ε' => 'Ε',
|
||||
'Ζ' => 'Ζ',
|
||||
'Η' => 'Η',
|
||||
'Θ' => 'Θ',
|
||||
'Ι' => 'Ι',
|
||||
'Κ' => 'Κ',
|
||||
'Λ' => 'Λ',
|
||||
'Μ' => 'Μ',
|
||||
'Ν' => 'Ν',
|
||||
'Ξ' => 'Ξ',
|
||||
'Ο' => 'Ο',
|
||||
'Π' => 'Π',
|
||||
'Ρ' => 'Ρ',
|
||||
'Σ' => 'Σ',
|
||||
'Τ' => 'Τ',
|
||||
'Υ' => 'Υ',
|
||||
'Φ' => 'Φ',
|
||||
'Χ' => 'Χ',
|
||||
'Ψ' => 'Ψ',
|
||||
'Ω' => 'Ω',
|
||||
'α' => 'α',
|
||||
'β' => 'β',
|
||||
'γ' => 'γ',
|
||||
'δ' => 'δ',
|
||||
'ε' => 'ε',
|
||||
'ζ' => 'ζ',
|
||||
'η' => 'η',
|
||||
'θ' => 'θ',
|
||||
'ι' => 'ι',
|
||||
'κ' => 'κ',
|
||||
'λ' => 'λ',
|
||||
'μ' => 'μ',
|
||||
'ν' => 'ν',
|
||||
'ξ' => 'ξ',
|
||||
'ο' => 'ο',
|
||||
'π' => 'π',
|
||||
'ρ' => 'ρ',
|
||||
'ς' => 'ς',
|
||||
'σ' => 'σ',
|
||||
'τ' => 'τ',
|
||||
'υ' => 'υ',
|
||||
'φ' => 'φ',
|
||||
'χ' => 'χ',
|
||||
'ψ' => 'ψ',
|
||||
'ω' => 'ω',
|
||||
'ϑ' => 'ϑ',
|
||||
'ϒ' => 'ϒ',
|
||||
'ϖ' => 'ϖ',
|
||||
'•' => '•',
|
||||
'…' => '…',
|
||||
'′' => '′',
|
||||
'″' => '″',
|
||||
'‾' => '‾',
|
||||
'⁄' => '⁄',
|
||||
'℘' => '℘',
|
||||
'ℑ' => 'ℑ',
|
||||
'ℜ' => 'ℜ',
|
||||
'™' => '™',
|
||||
'ℵ' => 'ℵ',
|
||||
'←' => '←',
|
||||
'↑' => '↑',
|
||||
'→' => '→',
|
||||
'↓' => '↓',
|
||||
'↔' => '↔',
|
||||
'↵' => '↵',
|
||||
'⇐' => '⇐',
|
||||
'⇑' => '⇑',
|
||||
'⇒' => '⇒',
|
||||
'⇓' => '⇓',
|
||||
'⇔' => '⇔',
|
||||
'∀' => '∀',
|
||||
'∂' => '∂',
|
||||
'∃' => '∃',
|
||||
'∅' => '∅',
|
||||
'∇' => '∇',
|
||||
'∈' => '∈',
|
||||
'∉' => '∉',
|
||||
'∋' => '∋',
|
||||
'∏' => '∏',
|
||||
'∑' => '∑',
|
||||
'−' => '−',
|
||||
'∗' => '∗',
|
||||
'√' => '√',
|
||||
'∝' => '∝',
|
||||
'∞' => '∞',
|
||||
'∠' => '∠',
|
||||
'∧' => '∧',
|
||||
'∨' => '∨',
|
||||
'∩' => '∩',
|
||||
'∪' => '∪',
|
||||
'∫' => '∫',
|
||||
'∴' => '∴',
|
||||
'∼' => '∼',
|
||||
'≅' => '≅',
|
||||
'≈' => '≈',
|
||||
'≠' => '≠',
|
||||
'≡' => '≡',
|
||||
'≤' => '≤',
|
||||
'≥' => '≥',
|
||||
'⊂' => '⊂',
|
||||
'⊃' => '⊃',
|
||||
'⊄' => '⊄',
|
||||
'⊆' => '⊆',
|
||||
'⊇' => '⊇',
|
||||
'⊕' => '⊕',
|
||||
'⊗' => '⊗',
|
||||
'⊥' => '⊥',
|
||||
'⋅' => '⋅',
|
||||
'⌈' => '⌈',
|
||||
'⌉' => '⌉',
|
||||
'⌊' => '⌊',
|
||||
'⌋' => '⌋',
|
||||
'⟨' => '〈',
|
||||
'⟩' => '〉',
|
||||
'◊' => '◊',
|
||||
'♠' => '♠',
|
||||
'♣' => '♣',
|
||||
'♥' => '♥',
|
||||
'♦' => '♦'));
|
||||
218
cookbook/pim_functions.php
Normal file
218
cookbook/pim_functions.php
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
// PIM functions (for PmWiki)
|
||||
// consider adding other related scripts here too (e.g. MemoryRecipe, Recalls, GroupStats, Coeditions, ...)
|
||||
// http://fabien.benetou.fr/pub/graphformatexporter.php.txt
|
||||
// http://fabien.benetou.fr/pub/memorization.php.txt
|
||||
// note that the order is important though
|
||||
// e.g. currently MemoryRecipe is loaded after thus can't be called here
|
||||
// add to http://fabien.benetou.fr/repository/
|
||||
// it would be particularly useful to refactor each properly
|
||||
// especially since they share variables (e.g. first edit) but also some have better function
|
||||
// e.g. caching in Coeditions
|
||||
// change ProcessingJS generation by first producing JSON
|
||||
// via http://www.php.net/manual/en/function.json-encode.php
|
||||
// cf http://fabien.benetou.fr/Tools/Processing and http://fabien.benetou.fr/Tools/JavaScript
|
||||
// this might be even faster on most computers since JS engines are improving
|
||||
|
||||
//handle implicit linking
|
||||
/*
|
||||
cf http://fabien.benetou.fr/MemoryRecalls/ImprovingPIM#ImplicitLinking
|
||||
*/
|
||||
function ImplicitLinking(){
|
||||
return "list of pages generated on the fly";
|
||||
}
|
||||
//$AutoCreate['/\\.GroupStats$/'] = array( 'ctime' => $Now, 'text' => ImplicitLinking());
|
||||
//$AutoCreate['/^Categora\\./'] = array('ctime' => $Now);
|
||||
//doesn't work, AutoCreate present in pmwiki.php and example too
|
||||
// category works though
|
||||
// TODO try making it global $AutoCreate;
|
||||
|
||||
//display working status
|
||||
// see http://fabien.benetou.fr/Tools/Greasemonkey#VirtualBlinders
|
||||
Markup("currenttask", "directives", "/\(:currenttask:\)/", GetCurrentTask());
|
||||
function GetCurrentTask(){
|
||||
$currenttask = trim(file_get_contents("/home/utopiah/web/benetou.fr/fabien/pub/currenttask"));
|
||||
if ($currenttask == "")
|
||||
return "(either available or asleep, Im usually on CET)";
|
||||
return "[[CognitiveEnvironments/".$currenttask."]]";
|
||||
}
|
||||
|
||||
Markup("timetable", "fulltext", "/\(:timetable:\)/",
|
||||
"\n||border=1\n||!Time ||!Action ||\n"
|
||||
.preg_replace("/.* (\d+) (\d+).* \/(.*)/","||$1:$2||$3||",file_get_contents("/home/utopiah/.irssi/cron.save"))
|
||||
."");
|
||||
|
||||
//load a dedicated edition page for the admin (shouldn't be hard coded but I dont use Auth)
|
||||
//global $GLOBALS;
|
||||
if ($GLOBALS['action'] == 'edit' && ( $GLOBALS['Author'] == 'Fabien' || $GLOBALS['Author'] == 'Utopiah' ) )
|
||||
{
|
||||
//TODO fails since moved in cookbook directory, thus added back there
|
||||
global $SkinDir,$pagename;
|
||||
LoadPageTemplate($pagename, "$SkinDir/edit.tmpl");
|
||||
}
|
||||
|
||||
//display editions through an horizontal line
|
||||
/*
|
||||
fomally done via GnuPlot, cf http://fabien.benetou.fr/Wiki/Visualization#timeline
|
||||
http://www.scholarpedia.org/article/Spike-response_model is probably too complicated for the small resolution
|
||||
yet provide interesting non-linear properties
|
||||
|
||||
*/
|
||||
function DisplayVisualEdits($pagename){
|
||||
global $ScriptUrl, $PubDir, $FarmD;
|
||||
|
||||
$processingpath = '/pub/libraries/processing.js';
|
||||
$processingfile = "/pub/visualization/edits_per_page/$pagename.pjs";
|
||||
$processinglib = "<script src=\"$processingpath\" type=\"text/javascript\"></script>";
|
||||
$first_edit = 1212192000;
|
||||
$now = time();
|
||||
// draw the timeline from the first edit to now()
|
||||
// get the list of edits of the current page
|
||||
// "get inspired" by PrintDiff() in scripts/pagerev.php
|
||||
$canvaswidth = 600-2*10;
|
||||
$canvasheight = 10;
|
||||
$block_width = 4;
|
||||
$block_height = 8;
|
||||
$page = ReadPage($pagename);
|
||||
if (!$page) return;
|
||||
krsort($page); reset($page);
|
||||
// newest first
|
||||
// for each edit
|
||||
$canvas = "
|
||||
void setup()
|
||||
{
|
||||
size($canvaswidth, $canvasheight);
|
||||
PFont font;
|
||||
font = loadFont(\"FFScala-Bold-12.vlw\");
|
||||
textFont(font);
|
||||
}
|
||||
void mouseMoved() {
|
||||
checkButtons();
|
||||
}
|
||||
|
||||
void mouseDragged() {
|
||||
checkButtons();
|
||||
}
|
||||
void draw()
|
||||
{
|
||||
background(251);
|
||||
fill(0,0,255,20);
|
||||
noStroke();
|
||||
";
|
||||
$mousePressed = "void mousePressed() {";
|
||||
$destination_link = "$ScriptUrl/".strtr($pagename,".","/")."?action=diff#diff";
|
||||
$mousePressed .= "\t\tif (lastHovered>0) { link(\"$destination_link\"+lastHovered); }\n";
|
||||
$checkButtons = "void checkButtons() {";
|
||||
print $processinglib.'<canvas data-src="'.$processingfile.'" width="'.$canvaswidth.'" height="'.$canvasheight.'"></canvas>';
|
||||
// set to false to de-activate cache (practical for tests)
|
||||
$newest_diff = true;
|
||||
//$newest_diff = false;
|
||||
//$first_diff = true;
|
||||
foreach($page as $k=>$v) {
|
||||
if (!preg_match("/^diff:(\d+):(\d+):?([^:]*)/",$k,$match)) continue;
|
||||
|
||||
$diff = $match[1];
|
||||
|
||||
$diffclass = $match[3];
|
||||
if ($diffclass=='minor')
|
||||
{ $canvas .= "\t\tfill(0,255,0,20);\n"; }
|
||||
else
|
||||
{ $canvas .= "\t\tfill(0,0,255,20);\n"; }
|
||||
//if ($first_diff)
|
||||
// { $canvas .= "\t\tfill(255,0,0,20);\n"; $first_diff = false;}
|
||||
|
||||
$buttonname = "over".$diff."Button";
|
||||
//$bools .= "boolean $buttonname = false;\n";
|
||||
if (file_exists($FarmD.$processingfile) && $newest_diff)
|
||||
if ( filemtime($FarmD.$processingfile) > $diff)
|
||||
return;
|
||||
$newest_diff = false;
|
||||
// add a sightly transparent tick rectangle with its Unix timestamp link to the diff page
|
||||
// the mouse over a certain edit should change its color
|
||||
// see http://processingjs.org/learning/basic/embeddedlinks
|
||||
// or clicablerects.js via Pomax on :mozilla2/#processing.js (14/05/2011 ~11pm)
|
||||
$x = round ( ($canvaswidth - $block_width) * ( (($now - $first_edit)-($now-$diff)) / ($now - $first_edit)));
|
||||
$y = 1;
|
||||
$checkButtons .= "\t\tif ( mouseX > $x && mouseX < $x+$block_width) lastHovered = $diff; \n";
|
||||
// if (mouseY > $y && mouseY < $y+$block_height) not really required
|
||||
// others should be set to false else one always jump to the olded diff mouved over
|
||||
$canvas .= "\t\trect($x,$y,$block_width,$block_height);\n";
|
||||
}
|
||||
$canvas .= "\t\tstroke(0,155);\n";
|
||||
$canvas .= "\t\tfill(0,0,255,80);\n";
|
||||
$canvas .= "\t\ttext(\"Edits:\",2,10 );\n";
|
||||
$canvas .= "\t\tfill(0,0,255,40);\n";
|
||||
for ($year=2009;$year<2012;$year++){ //each year until now
|
||||
$unixyear = mktime(0,0,0,1,1,$year);
|
||||
$x = round ( ($canvaswidth - $block_width) * ( (($now - $first_edit)-($now-$unixyear)) / ($now - $first_edit)));
|
||||
$y = 0;
|
||||
$canvas .= "line($x,$y,$x,$y+$block_height+2); text(\"$year\",$x+2,$y+10 );\n";
|
||||
}
|
||||
$canvas = $bools . $canvas ."}" . $mousePressed ."}" .$checkButtons . "}";
|
||||
|
||||
// load ProcessinJS
|
||||
|
||||
$write_result = file_put_contents($FarmD.$processingfile,$canvas);
|
||||
|
||||
// print resulting canvas
|
||||
|
||||
$older_gnuplot_version = "<div><center><img src=\"/pub/visualization/edits_per_page/{$pagename}.png\" alt=\"/pub/visualization/edits_per_page/{$pagename}.png\"/></br>(<a href=\"$ScriptUrl/Wiki/Visualization#timeline\">visualization details</a>).</center></div><hr />";
|
||||
}
|
||||
|
||||
|
||||
//display images with transparancy invertionnaly proportional to last time of update
|
||||
// http://fabien.benetou.fr/MemoryRecalls/ImprovingPIM#VisualDecayOfInformation
|
||||
function DisplayDecay($pagename){
|
||||
|
||||
/*
|
||||
consider
|
||||
adding threshold
|
||||
not keeping it linear (e.g. log)
|
||||
but still constantly inscreasing between 0 and 1
|
||||
use a factor when matches (e.g. regex changing $impeding_factor or $first_edit)
|
||||
regex would match groupname (e.g. "Person." with fast decay) or pagename or both (e.g. "Math" with slow decay)
|
||||
yellowish background, looking like old paper
|
||||
...rest got deleted by a dumb rm...
|
||||
*/
|
||||
global $ScriptUrl;
|
||||
$first_edit = 1212192000;
|
||||
$now = time();
|
||||
//load page
|
||||
$page = ReadPage($pagename);
|
||||
if (!$page) return;
|
||||
|
||||
$last_edit = $page["time"];
|
||||
//get last edit
|
||||
|
||||
$destination_link = "$ScriptUrl/".strtr($pagename,".","/")."?action=edit";
|
||||
|
||||
//use the previous equation adding 1 - ()
|
||||
$opacity = round ( 1 - ( (($now - $first_edit)-($now-$last_edit)) / ($now - $first_edit)) , 2 );
|
||||
|
||||
$opacitymsg = "opacity=$opacity";
|
||||
if ($opacity > 0.8)
|
||||
$opacitymsg = "<font color=\"red\">".$opacitymsg."</font>";
|
||||
|
||||
//if user if admin
|
||||
if ( $GLOBALS['Author'] == 'Fabien' || $GLOBALS['Author'] == 'Utopiah' ) {
|
||||
//for 1 to a multiplier of value
|
||||
for ($i=0;$i<$opacity*10;$i++){
|
||||
// display another visual problem with a link back to improvingwiki#visualdecay
|
||||
print "<div style=\"opacity:$opacity;position:absolute;top:".rand(60,800)."px;left:".rand(100,500)."px;\"><a href=\"$destination_link\">"
|
||||
.decbin(rand(0,10000))."</a></div>";
|
||||
}
|
||||
// add a good practice msg
|
||||
print "<div style=\"opacity:$opacity;position:absolute;top:10px;left:450px;width:300px;background-color:gray;\">
|
||||
$opacitymsg edits should be done to check if
|
||||
the informamtion presented is still relevant,
|
||||
links are working,
|
||||
opinion expressed still correct, etc.
|
||||
</div>";
|
||||
}
|
||||
|
||||
|
||||
//print img with opacity + warning message
|
||||
|
||||
print "<div style=\"opacity:$opacity;\"><a name=\"Decay\"></a>If you can read this text ($opacitymsg) if means the page has not been edited for a long time. Consequently the information it holds might be deprecated or no longer represent the opinion of this author.</div>";
|
||||
|
||||
}
|
||||
109
cookbook/wikibrainmapping.php
Normal file
109
cookbook/wikibrainmapping.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
## give a visual representation of pages and group
|
||||
$RecipeInfo['WikiBrainMapping']['Version'] = '2011-05-15';
|
||||
Markup('WikiBrainMapping', 'directives', '/\\(:WikiBrainMapping:\\)/e', Keep(WikiBrainMapping()));
|
||||
|
||||
function WikiBrainMapping(){
|
||||
$sourcepagename = $_SERVER["REQUEST_URI"];
|
||||
// apply changes done to graphprocessing.php to insure proper URI format
|
||||
$sourcepagename = preg_replace("/(.*)\?.*/","$1",$sourcepagename);
|
||||
$sourcename = preg_replace("/.*[\.\/](.*)/","$1",$sourcepagename);
|
||||
$sourcegroup = preg_replace("/\/(.*)[\/\.].*/","$1",$sourcepagename);
|
||||
if ($sourcegroup == "/"){
|
||||
$sourcegroup = "Main";
|
||||
# consider instead filling the pages array with
|
||||
## groups names
|
||||
## "neighboors" wikis from InterWiki page
|
||||
# list page, remove pagenames, sort|uniq ... then what? maybe whole different process
|
||||
}
|
||||
|
||||
global $FarmD, $WikiTitle, $ScriptUrl;
|
||||
$processingpath = '/pub/libraries/processing.js';
|
||||
$processingfile = "/pub/visualization/wikibrainmapping.pjs";
|
||||
$processinglib = "<script src=\"$processingpath\" type=\"text/javascript\"></script>";
|
||||
|
||||
# eventually modify to use a dedicated folder
|
||||
# generate a file per page
|
||||
if (!file_exists($FarmD.$processingfile))
|
||||
if (!touch($FarmD.$processingfile))
|
||||
print "Creation of the processing file fails, check write permissions for pmWiki and $processingfile.";
|
||||
|
||||
# cached version (to comment during tests)
|
||||
#if ( (time() - filemtime($FarmD.$processingfile)) < 3600 ) return $processinglib.'<canvas data-src="'.$processingfile.'" width="'.$canvaswidth.'" height="'.$canvasheight.'"></canvas>';
|
||||
|
||||
$canvaswidth=500;
|
||||
$canvasheight=300;
|
||||
|
||||
$groupname = $sourcegroup;
|
||||
$pages = ListPages("/$groupname\./e");
|
||||
$pages = MatchPageNames($pages,array('-*.*RecentChanges,-*.GroupFooter,-*.GroupHeader'));
|
||||
$pagesnum = count($pages);
|
||||
$processingsetupcode = "
|
||||
PShape s;
|
||||
void setup(){
|
||||
frameRate(15);
|
||||
size($canvaswidth,$canvasheight);
|
||||
strokeWeight(2);
|
||||
|
||||
PFont font;
|
||||
font = loadFont(\"FFScala-32.vlw\");
|
||||
textFont(font);
|
||||
|
||||
sright = loadShape(\"/pub/illustrations/flat_brain_right.svg\");
|
||||
sleft = loadShape(\"/pub/illustrations/flat_brain_left.svg\");
|
||||
smooth();
|
||||
";
|
||||
$processingdrawcode .= "
|
||||
void draw(){
|
||||
background(255);
|
||||
";
|
||||
|
||||
$processingdrawcode .= "shape(sright,300, 400);";
|
||||
$processingdrawcode .= "shape(sleft,200, 400);";
|
||||
$processingdrawcode .= "fill(0,0,255,255);\n";
|
||||
$processingdrawcode .= "text(\"flattened left hemisphere\",300,10);\n;";
|
||||
$processingdrawcode .= "text(\"flattened right hemisphere\",100,10);\n;";
|
||||
|
||||
$target_area["x"] = 150;
|
||||
$target_area["y"] = 100;
|
||||
$target_area["width"] = 50;
|
||||
$target_area["height"] = 60;
|
||||
|
||||
//replace with actual list of pages
|
||||
for ($pagen=0;$pagen<10;$pagen++){
|
||||
$x = rand($target_area["x"],$target_area["x"]+$target_area["width"]);
|
||||
$y = rand($target_area["y"],$target_area["y"]+$target_area["height"]);
|
||||
//draw cercle in the area
|
||||
$radius = 3;
|
||||
$processingdrawcode .= "fill(255,0,0,100);ellipse($x,$y,$radius,$radius);\n";
|
||||
//draw diagonal line of edits
|
||||
$linelength=10;
|
||||
$processingdrawcode .= "strokeWeight(1); line($x,$y,$x+$linelength,$y-$linelength);\n";
|
||||
//replace with actual list of edits
|
||||
$maxdiff = rand(0,10);
|
||||
for ($diff=0;$diff<$maxdiff;$diff++){
|
||||
//draw points on the line of edits with smaller stroke weight
|
||||
$diff_pos = rand(0,$linelength);
|
||||
$processingdrawcode .= "strokeWeight(2); point($x+$diff_pos,$y-$diff_pos);\n";
|
||||
}
|
||||
}
|
||||
$processingdrawcode .= "fill(255,0,0,255);\n";
|
||||
$processingdrawcode .= "text(\"Note that currently points are randomly generated\\nand randomly positionned on a designated area.\\nNo mapping has been done between function and position.\\nGyri and sulci are also not represented.\",10,200);\n;";
|
||||
$processingsetupcode .= " }";
|
||||
$processingdrawcode .= " }";
|
||||
|
||||
$result = $processinglib.'<canvas data-src="'.$processingfile.'" width="'.$canvaswidth.'" height="'.$canvasheight.'"></canvas>';
|
||||
|
||||
$write_result = file_put_contents($FarmD.$processingfile,$processingsetupcode.$processingdrawcode);
|
||||
if (!$write_result)
|
||||
if (strlen($processingcode)>0)
|
||||
print "Creation of the feed file fails, check write permissions for pmWiki and $processingfile.";
|
||||
else
|
||||
print "No code to generate, did you correctly generate your Processing code?";
|
||||
|
||||
// ----------------------- return the processed result -----------------------
|
||||
return $result;
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user