GureWork > espacios de Coworking topalekuak :)
Template:@carlescm > PagesMonitor

PagesMonitor
PagesMonitorEdit

    Tabla de contenidos
    No hay encabezados
    /* 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    10-March-2010          Added a loading icon on ajax action.
            1.04    19-March-2010          Mindtouch guys changed an JS api call, Deki.Api -> Mindtouch.Deki , Grrr
            1.05    24-March-2010          Change some CSS copied from neilwPagesMonitor               
            1.05a                          @himikel some changes
     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.
        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 ??  '',
        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);
        //@himikel mod 2011-01-19: solve issue with pages not reached because has internalization chars
        if (p.date==nil)
          continue;    
        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 ]; }
        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: web.html( (hobj.views!=obj.views ? "<span class='plusCount'>".."+"..(obj.views-hobj.views).."</span>" :"")..(hobj.views?obj.views:"")),
            cmts: web.html((hobj.cmts!=obj.cmts? "<span class='plusCount'>".."+"..(obj.cmts-hobj.cmts).."</span>" :"")..(hobj.cmts?obj.cmts:"")),
            atts: web.html((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 ? ( <div class='mp_avatar'>web.html(cache_avatars[last.author.name])</div> 
                                       <div class='mp_avatar_text'>obj.lastcomment;
                                       collapseItem(<div> 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:    ( <div class='mp_avatar'>web.html(cache_avatars[p.author.name])</div>
                           <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'>
    //@himikel mod 2010-10-04: If user is anonymous don't show the update button
    if (!user.anonymous)
    {
      <input id='button_pm_update_history' type='button' value='Update History' />
    }
    if (#data_history>0) {
      <span id='pages_monitor_updated' class='mp_last_updated'>" "..TXTS[lg].txt_last_updated.." "..data_history[0].fecha</span>
      <span id="pages_monitor_loading" style="display:none;margin:auto;width:40px;height:40px;background-repeat: no-repeat; align: left; background-image:url('/skins/common/icons/anim-wait-circle.gif');">&nbsp;;&nbsp;;&nbsp;;</span>
     }
    
    TSTable {
        options: { id: 'ts_pages_monitor', zebra:true, width:'100%', pager: false },
        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)", initial:1 },
            { 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"> "
    
    //@himikel #add 2010-07-11: To avoid authentication dialog for anonymous users
    var useranony='"..user.anonymous.."';
    //alert('Anonymous? '+useranony);
    
     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() {
            $('#pages_monitor_updated').hide();
            $('#pages_monitor_loading').show();
    
            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;
            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')) ..
    
    Powered by MindTouch Core (Expired)