Template:neilwPagesMonitor

    Table of contents
    No headers
    // EXPERIMENTAL CUSTOMIZED VERSION OF CARLES.COLL'S TEMPLATE
    
    /* PagesMonitor
        Monitors the changes on pages, it saves the state per user.
    
        get the idea from http://developer.mindtouch.com/index.php?title=User:Neilw/Monitoring by neilw
        created by carles.coll, 2009
    
        Version history:
            1.00    28-October-2009        First published version
            1.01    07-november-2009       - Susbtitute the Last edit resume, for a link to Difference
                                              between las review and actual version.
                                           - Change the behaviour, all uses AJAX calls, no page reloads.
                                           - Show how many changes on (views, comments, attachments)
            1.02    06-March-2010          A change on language behaviour on 9.12 release -> Better language behaviour.
            1.03    22-March-2010          Update to new MindTouch.Deki naming
                                           Test new CollapseItem functionality
    
     Usage:  PagesMonitor(favorites:bool?, paths:list of str?, search_criteria:str?, language:str?)
        favorites:  (optional) default -> true; It includes all the Whatch List pages.
        paths:   (optional) default -> []; List of paths to add, they get recursive automatically.
        search_criteria:      (optional) default -> ''; Search criteria for pages to monitor.
        avatars: (optional) default->true; show avatars for comments and edits
        language:                 (optional) default -> 
                                                        1rst -> Page language
                                                        2nd  -> Site language
                                                        3rd  -> 'en-us'
    
    */
    
    dekiapi();
    
    // + PARAMETERS
    var par = { 
        favorites: __request.args.favorites?? args.favorites ??  true,
        paths: __request.args.paths?? args.paths ??  [],
        search_criteria: __request.args.search_criteria ?? args.search_criteria ??  '',
        avatars: $avatars ?? true,
        collapse: $collapse ?? false,
        language: __request.args.language ?? args.language ?? ( wiki.language ? wiki.language() : (page.language .. site.languge .. 'en-us') ),
        ajax_action: String.tolower( __request.args.ajax_action ?? args.ajax_action ?? 'load')   
       };
    
    if ((par.ajax_action=='load') || (par.ajax_action=='reload_pagesmonitor')) {
    
    
    // + CONSTANTS
    
    // -- START LANGUAGE STRINGS
    var LANGUAGE_ES = {
        title_recursive: web.html("<span class='recursive' title='Incluir subpáginas'>&nbsp;</span>"),
        title_page: "Página",
        title_cmts: web.html("<span class='comment' title='Número comentarios'>&nbsp;</span>"),
        title_lst_cmt: "Ult. Com.",
        title_lst_edit: "Ult. Edición",
        title_views: web.html("<span class='views' title='Número Visitas'>&nbsp;</span>"),    
        title_atts: web.html("<span class='attach' title='Número Adjuntos'>&nbsp;</span>"),
        title_types: "T",
    
        txt_last_updated: "Fecha última actualización:",
    
        error_no_data_page: "ERROR: no puedo encontrar la pagina con los datos históricos.",
        error_updating_history: "ERROR: actualizando el histórico ",
        error_creating_history: "ERROR: creando el histórico ",
        error_reading_history: "ERROR: leyendo el histórico "
    
        };
    var LANGUAGE_EN = {
        title_recursive: web.html("<span class='recursive' title='Include subpages'>&nbsp;</span>"),
        title_page: "Page",
        title_cmts: web.html("<span class='comment' title='Comments number'>&nbsp;</span>"),
        title_lst_cmt: "Last comment",
        title_lst_edit: "Last edit",
        title_views: web.html("<span class='views' title='Viewcount'>&nbsp;</span>"),    
        title_atts: web.html("<span class='attach' title='Attachments number'>&nbsp;</span>"),
        title_types: "T",
    
        txt_last_updated: "Last updated on:",
    
        error_no_data_page: "ERROR: can't find page with data store",
        error_updating_history: "ERROR: updating history ",
        error_creating_history: "ERROR: creating history ",
        error_reading_history: "ERROR: reding history "
    
        };
    
    var TXTS = { 'es-es': LANGUAGE_ES, 'en-us': LANGUAGE_EN,  'en': LANGUAGE_EN };
    var lg = par.language;
    // -- END LANGUAGE STRINGS
    
    var OBJ_BLANK = {
            page: '' ,
            views: 0,
            cmts: 0,
            lastcomment: '',
            lastedit:    '',
            revision: 1
          };
    var STYLE_DIFF_VALUE = 'background-color: #AAFFAA';
    var HISTORY_STORE = 'monitoring_history_'..user.name;
    var RECURSIVE_STORE = 'monitoring_recursive_'..user.name;
    var ICONOS = '/skins/fiesta/icon_grid_dropdown.png';
    var NO_AVATAR = '/@api/deki/files/4913/=NoAvatar.jpg';
    var DATE_FORMAT = 'dd/MM/yyyy hh:mm';
    
    // + VARS
    /*var path = $3 ?? $path;
    var p = (path == nil ? page : wiki.getpage(path));*/
    var p = page;
    var p_api = null;
    if (p == nil) { <p>TXTS[lg].error_no_data_page;</p>;}
       else { let p_api = p.api; }
    
    var cache_avatars = {};
    var avatar,source,n,a;
    
    var favorites = [];
    
    // + LET'S CODE
    // -- Let's search for the notifications
    // -- !!! We can't do it for the moment, they are stored on a file, and it's
    // -- !!! innaccesible from DekiScript, let's wait for a ne Deki Wiki release...
    
    // -- Let's search for the watchlist
    if (par.favorites) {
       let favorites ..= [ { path: xml.text(fname), type: "<span class='favoritos' title='favoritos'>&nbsp;</span>", recusive: 0 } foreach var fname in 
                        wiki.api(site.api.."/users/"..user.id.."/favorites")['//path'] ]; 
      }
    
    // -- Let's search for the search criteria
    if (par.search_criteria!='') {
       var sres = wiki.getsearch(par.search_criteria, 10000, 'title');
       foreach(var gs in sres) {
         let favorites ..= [ { path: gs.path, 
                type: "<span class='search' title='busqueda'>&nbsp;</span>", 
                recursive: 0} ]; 
        }
     }
    
    // -- Let's add each path
    if (par.paths!=[]) {
      foreach(var p in par.paths) { 
        let favorites ..= [ { path: p, 
            type: "<span class='recursive' title='ruta'>&nbsp;</span>",
            recursive: 3} ]; 
       }
     }
    
    // -- Let's eliminate de duplicity
    let k = List.GroupBy(favorites,"$.path");
    let favorites = [];
    foreach(var group in map.keys(k)) {
      var types = "";
      var rec = 0;
      foreach(var val in k[group]) {
            let types ..= val.type;
            if (val.recursive>rec) { let rec = val.recursive;}
        }
      let favorites ..= [ { 'path': group, 'types': types, 'recursive': rec} ];
     }
      
    var recursive = json.parse(page.properties[RECURSIVE_STORE].text ?? "") ??[];
    
    var pages = [];
    var npages = 0;
    
    foreach(var fv in favorites) {
      let npages += 1;
      var p = wiki.getpage(fv.path);
      var r = 0;
      if ((list.contains(recursive,""..p.id))||(fv.recursive>0)) {
         var tree = wiki.tree(fv.path);
         let npages +=#xml.list(tree, ".//li"); 
         let r = 1;
        }
      let pages ..= [ {'path': fv.path, 'recursive': (fv.recursive>0?fv.recursive:r), 'types': fv.types} ];
     }
    
    
    var data_history = json.parse(page.properties[HISTORY_STORE].text ?? "") ??[];
    
    var data = [];
    var data_save = [ { id: 'special', fecha: (date.now) } ];
    
    var dummy = Num.Series(0,npages);
    
    foreach(var dummy_k in dummy) {
        if (__index==#pages) { break; }
        var act = pages[__index];
        var path = act.path;
        var p = wiki.getpage(path);
        var num_cmts = #p.comments;
        var num_atts = #p.files;
        var last = num_cmts ? p.comments[num_cmts - 1] : nil;
        var hobj = List.Select(data_history,"$.id=='"..p.id.."'");
        if (#hobj) { let hobj = hobj[0]; }
          else { let hobj = OBJ_BLANK; }
    
        if (act.recursive>0) {
          foreach(var k in p.subpages) {
             let pages ..= [ { 'path': k.path, 'recursive': 2, 'types': "<span class='recursive' title='Subpágina'>&nbsp;</span>" } ];
            }
         }
        var obj = {
            id: p.id ,
            page: p.path ,
            path: p.path ,
            views: p.viewcount,
            cmts: num_cmts,
            atts: num_atts,
            lastcomment: (num_cmts ? ( date.format(last.date,DATE_FORMAT).." by "..last.author.name; ) : ""),
            lastedit:    ( date.format(p.date, DATE_FORMAT).." by "..p.author.name ),
            revision: (#p.revisions)
          };
        let data_save ..= [ obj ];
    
         // -- Let Search for the avatar and save it to the cache.
        var users = [ p.author ];
        var un ='';
        if (num_cmts) { let users ..= [ last.author ]; }
        if (par.avatars) {
            foreach ( var uns in users ) {
                let un = uns.name;
                if (!Map.Contains(cache_avatars,un)) {
                    let source=wiki.getpage('/User:' .. un).files;
                    let avatar=NO_AVATAR;
                    foreach (var f in source) {
                       let n=f.name;
                       let a=f.api;
                       if (String.tolower(n) == 'avatar.jpg') { let avatar=f.api; }
                    }
                }
                if (avatar==NO_AVATAR) { let avatar = uns.gravatar; }
                let cache_avatars ..= {(un): ("<img src='"..avatar.."' width='30px' valing='top' style='vertical-align: text-top' />") };
             }
         }
    
        let obj ..= { 
            views: ((hobj.views!=obj.views ? <span class="plusCount"> "+"..(obj.views-hobj.views) </span> :"");(hobj.views?obj.views:"")),
            cmts: ((hobj.cmts!=obj.cmts? <span class="plusCount"> "+"..(obj.cmts-hobj.cmts) </span> :"");(hobj.cmts?obj.cmts:"")),
            atts: ((hobj.atts!=obj.atts? <span class="plusCount"> "+"..(obj.atts-hobj.atts) </span> :"");(hobj.atts?obj.atts:"")),
            recursive: (act.recursive<2?
                            web.html("<input type='checkbox' name='recursive' class='pm_cb_recursive' value='"..obj.id.."' "..(act.recursive>0 ? "checked=1" : nil).." />"):
                            (act.recursive==3?web.html("<span class='recursive' title='Se incluyen subpaginas'>&nbsp;</span>"):"")),
            types: web.html(act.types),
            page_style: (hobj.page!=obj.page?STYLE_DIFF_VALUE:''),
            views_style: (hobj.views!=obj.views?STYLE_DIFF_VALUE:''),
            cmts_style: (hobj.cmts!=obj.cmts?STYLE_DIFF_VALUE:''),
            atts_style: (hobj.atts!=obj.atts?STYLE_DIFF_VALUE:''),
            lastcomment_style: (hobj.lastcomment!=obj.lastcomment?(last.author.name !=user.name?STYLE_DIFF_VALUE:''):''),
            lastedit_style: (hobj.lastedit!=obj.lastedit?(p.author.name!=user.name?STYLE_DIFF_VALUE:''):''),
    
            lastcomment: (num_cmts ? ( par.avatars ? <div class='mp_avatar'>web.html(cache_avatars[last.author.name])</div> : nil;
                                       <div class='mp_avatar_text'> if (par.collapse) collapseItem("comment"..dummy_k, _,_, "slide"); obj.lastcomment;
                                       <div id=("comment" .. dummy_k) style=(par.collapse? "display:none" : "")> last.text </div> </div> ) : ""),
    	        page: (web.link(p.uri, p.title);
                    <br /><span style="font-size: 10px; font-color: #eeeeee; font-style: italic">(obj.path)</span>;),
            lastedit:    ( par.avatars ? <div class='mp_avatar'>web.html(cache_avatars[p.author.name])</div> : nil;
                           <div class='mp_avatar_text'>obj.lastedit;' ';
                            if (hobj.revision!=#p.revisions) { <a href=(uri.build(p.uri,nil,{action:'diff',revision: (hobj.revision??1),diff: (#p.revisions)})) target='_blank'>'Diff'</a> }
                            </div> )
    
           };
        let data ..= [ obj ];
    }
    
    let data = list.sort(data,'path');
    
    // + DYNAMIC HTML CONTENT
    <div id='monitor_pages'>
    <form id='form_page_monitor'>
    <input id='button_pm_update_history' type="button" value="Update History" />
    if (#data_history>0) {
      <span class='mp_last_updated'>" "..TXTS[lg].txt_last_updated.." "..data_history[0].fecha</span>
     }
    
    TSTable {
        options: { id: 'ts_pages_monitor', zebra:true },
        columns: [
            { title:TXTS[lg].title_recursive,key: "recursive", width:"5%"},
            { title:TXTS[lg].title_page,    key: "page", width:"35%" , style:"($.page_style)" },
            { title:TXTS[lg].title_views,   key: "views", width:"8%", style:"($.views_style)" },
    //        { title:TXTS[lg].title_atts,    key: "atts", width:"8%", style:"($.atts_style)" },
            { title:TXTS[lg].title_cmts,    key: "cmts", width:"8%", style:"($.cmts_style)" },
            { title:TXTS[lg].title_lst_cmt, key:"lastcomment", width:"20%", style:"($.lastcomment_style)" },
            { title:TXTS[lg].title_lst_edit,key:"lastedit", width:"20%", style:"($.lastedit_style)" },
            { title:TXTS[lg].title_types,   key:"types" }
    
          ],
        data: data
    };
    </form>
    
    <span id='pg_data_save' style='display: none' data=(json.emit(data_save))></span>
    
    </div>
    
    if (par.ajax_action=='load') {
    
    <script type="text/javascript"> "
    
     function pagemonitorWireControls(){
        Deki.$('.pm_cb_recursive').bind('click', function() {
            var $this = Deki.$(this);
            var prop = 'urn:custom.mindtouch.com#'  + '"..RECURSIVE_STORE.."';
            MindTouch.Deki.ReadPageProperty('"..p_api.."', prop, function(result) {
                var data = YAHOO.lang.JSON.parse(result.value || '[]');
                if ($this.attr('checked'))
                    {  data.push($this.attr('value')); }
                    else {  
                            var i; 
                            var trobat=-1;
                            for(i=0;i<data.length;i++) {
                                if (data[i]==$this.attr('value')) { trobat=i; }
                               } 
                            if (trobat!=-1) { data.splice(trobat,1); }
                         }
                if(result.etag)
                    MindTouch.Deki.UpdatePageProperty(result.href,  YAHOO.lang.JSON.stringify(data), result.etag,
                        function() { 
                                      MindTouch.Deki.Reload($('#monitor_pages'),{ajax_action: 'reload_pagesmonitor'}, function() {  pagemonitorWireControlsReload(); });
                                    },
                        function(result) { alert('"..TXTS[lg].error_updating_history.." (status: ' +
                result.status + ' - ' + result.text + ')'); }
                    );
                else
                    MindTouch.Deki.CreatePageProperty('"..p_api.."', prop,  YAHOO.lang.JSON.stringify(data),
                        function() { 
                                    MindTouch.Deki.Reload($('#monitor_pages'),{ajax_action: 'reload_pagesmonitor'}, function() {  pagemonitorWireControlsReload(); });
                                    },
                        function(result) { alert('"..TXTS[lg].error_creating_history.." (status: ' +
                result.status + ' - ' + result.text + ')'); }
                    );
            },
            function(result) { alert('"..TXTS[lg].error_reading_history.." (status: ' +
                result.status + ' - ' + result.text + ')'); }
            );
        });
    
        Deki.$('#button_pm_update_history').bind('click', function() {
            var prop = 'urn:custom.mindtouch.com#'  + '"..HISTORY_STORE.."';
            MindTouch.Deki.ReadPageProperty('"..p_api.."', prop, function(result) {
                var data = Deki.$('#pg_data_save').attr('data');
                if(result.etag)
                    MindTouch.Deki.UpdatePageProperty(result.href, data, result.etag,
                        function() { 
                             MindTouch.Deki.Reload($('#monitor_pages'),{ajax_action: 'reload_pagesmonitor'}, function() { 
                                 pagemonitorWireControlsReload();
                                });
                            },
                        function(result) { alert('"..TXTS[lg].error_updating_history.." (status: ' +
                result.status + ' - ' + result.text + ')'); }
                    );
                else
                    MindTouch.Deki.CreatePageProperty('"..p_api.."', prop, data,
                        function() { 
                             MindTouch.Deki.Reload($('#monitor_pages'),{ajax_action: 'reload_pagesmonitor'}, function() {  pagemonitorWireControlsReload(); });
                            },
                        function(result) { alert('"..TXTS[lg].error_creating_history.." (status: ' +
                result.status + ' - ' + result.text + ')'); }
                    );
            },
            function(result) { alert('"..TXTS[lg].error_reading_history.." (status: ' +
                result.status + ' - ' + result.text + ')'); }
            );
    
         });
    
      }
    
     function pagemonitorWireControlsReload() {
        tstableApply($, false,false,null,'ts_pages_monitor',{},[],['zebra'],[],false);
        pagemonitorWireControls();
      }
    
     Deki.$(document).ready(function(){ 
            pagemonitorWireControls(); 
       });
     
    " </script> 
    
     // + CSS DEFINITION
    <style type="text/css">"
     #monitor_pages span.mp_last_updated {
         font-size:12px;
         font-style: italic;
        }
    
     #monitor_pages span.favoritos {
            width: 28px;
            height: 28px;
            float: left;
    	background-image: url("..ICONOS..");
    	background-position: left -420px;
    	background-repeat:no-repeat;
     }
    
     #monitor_pages span.search {
            width: 28px;
            height: 28px;
            float: left;
    	background-image: url("..ICONOS..");
    	background-position: left -60px;
    	background-repeat:no-repeat;
     }
    
     #monitor_pages span.recursive {
            width: 28px;
            height: 28px;
            float: left;
    	background-image: url("..ICONOS..");
    	background-position: left -180px;
    	background-repeat:no-repeat;
     }
    
     #monitor_pages span.views {
            width: 28px;
            height: 28px;
            float: left;
    	background-image: url("..ICONOS..");
    	background-position: left -120px;
    	background-repeat:no-repeat;
     }
    
     #monitor_pages span.attach {
            width: 28px;
            height: 28px;
            float: left;
    	background-image: url("..ICONOS..");
    	background-position: left -300px;
    	background-repeat:no-repeat;
     }
    
     #monitor_pages span.comment {
            width: 28px;
            height: 28px;
            float: left;
    	background-image: url("..ICONOS..");
    	background-position: left -510px;
    	background-repeat:no-repeat;
     }
    
     #monitor_pages div.mp_avatar {
            margin: 0px; 
            padding: 0px; 
            float: left; 
            width: 25%;
        }
    
     #monitor_pages div.mp_avatar_text {
            margin: 0px; 
            padding: 0px; 
            font-size: 10px;";
    if (par.avatars) "
            float: right; 
            width: 70%;
    ";
    "    }
    
      #monitor_pages .plusCount {
          padding:2px;
          background-color: black;
          color:white;
          margin-right: 5px;
      }
    
    "</style>
     } // if (par.ajax_action=='load')...
    
    }  // -- if ((par.ajax_action=='load') || (par.ajax_action=='reload_pagesmonitor')) ..
    Tag page
    You must login to post a comment.

    Copyright © 2011 MindTouch, Inc. Powered by