activities.tcl

Displays active users in a community

Location:
/packages/xotcl-request-monitor/www/activities.tcl
Author:
Gustaf Neumann
CVS ID:
$id$

Related Files

[ hide source ] | [ make this the default ]

File Contents

ad_page_contract {
  Displays active users in a community
  
  @author Gustaf Neumann 

  @cvs-id $id$
} -query {
  {hours:integer 1}
  {users:word "authorized"}
  {type:word "sessions"}
  {user:token ""}
  {community_id:integer ""}
} -properties {
  title:onevalue
  context:onevalue
}

set title "Activities"
set context [list $title]

if {![::parameter::get_from_package_key \
         -package_key "xotcl-request-monitor" \
         -parameter "do_track_activity" \
         -default "off"]} {
  ad_return_forbidden "Permission Denied" "<blockquote><p>Activity tracking is not activated</blockquote>"
  ad_script_abort
}

set swa [acs_user::site_wide_admin_p]
if {!$swa} {
  ad_return_forbidden "Permission Denied" "<blockquote><p>You don't have permissions to view this page</blockquote>"
  ad_script_abort
}

set dimensional {
  {
    hours "Interval:" 1 {
      {1     "One Hour"}
      {24    "One Day"}
      {168   "One Week"}
      {1176  "One Month"} 
    }
  } {
    type "Type:" sessions {
      {sessions "Sessions"}
      {time "Time"}
    }
  } {
    users "Users:" authorized {
      {authorized "Authorized"}
      {anonymous "Anonymous"}
    }
  }
}


set dimensional_html [ad_dimensional $dimensional]

#set type sessions

proc __community_label {community_id} {
  if {[info commands ::dotlrn_community::get_community_name] ne ""} {
    set community_name [::dotlrn_community::get_community_name $community_id]
  } else {
    set community_name ""
  }
  if {$community_name eq ""} {
    set community_name [::xo::db::sql::apm_package name -package_id $community_id]
  }
  return $community_name
}

set sql_days "$hours hours"
set filter_html ""
set user_clause true

#
# When either "user" or "community_id" are given ...
#
if {$users eq "authorized"} {

  set user_clause "user_id > -1"
  if {$user ne ""} {
    append user_clause " and user_id = :user"
    acs_user::get -user_id $user -array user_info
    set user_label "$user_info(first_names) $user_info(last_name)"
    set no_filter_url [export_vars -base activities [list type users community_id {hours 1}]]
    append filter_html [subst {
      <li>Activities of $user_info(first_names) $user_info(last_name)
      (stop <a href="[ns_quotehtml $no_filter_url]">filtering</a>)</li>
    }]
  }
} else {
  set user_clause "user_id = -1"
}

if {$community_id ne ""} {
  append user_clause " and community_id = :community_id"
  set community_label [__community_label $community_id]
  set no_filter_url [export_vars -base activities [list type users user {hours 1}]]
  append filter_html [subst {
      <li>Activities in $community_label
    (stop <a href="[ns_quotehtml $no_filter_url]">filtering</a>)</li>
  }]
}

if {$type eq "sessions"} {

  ##################################################################
  #
  # Session Statistics
  #
  ##################################################################
  
  TableWidget create t1 \
      -columns {
        AnchorField user -label User
        AnchorField pa -label "Peer Address"
        AnchorField community_id -label "Community"
        Field start_time -label "Start Time" 
        Field end_time -label "End Time"
        Field duration -label "Duration"
        Field clicks -label "Clicks" -html {align right}
      }

  set items [::xo::db::Object instantiate_objects -sql [subst {
    select
       user_id, peer_address as pa, community_id,
       extract(EPOCH from (start_time)) as start_time,
       extract(EPOCH from (end_time)) as end_time,
       extract(EPOCH from (end_time-start_time)) as duration,
       clicks
    from request_monitor_community_activities
    where start_time > (now() - :sql_days::interval)
    and   $user_clause
    order by start_time desc
  }] -initialize false]

  foreach {key data} [throttle do Users array get user_in_community] {
    if {$users eq "authorized"} {
      if {[string match *.* $key]
          || ($user ne "" && $key ne $user)
          || ($community_id ne "" && $community_id ne [dict get $data community_id]) } {
        continue
      }
    }
    set o [::xotcl::Object new]
    $o set user_id [expr {[string match *.* $key] ? -1 : $key}]
    $o set pa ""
    catch {$o set pa [throttle do Users set pa($key)]}
    $o set community_id [dict get $data community_id]
    $o set start_time [dict get $data community_start]
    $o set end_time {}
    $o set duration [expr {[clock seconds] - [dict get $data community_start]}]
    $o set clicks [dict get $data community_clicks]

    $items add $o
  }

  $items
  
  foreach t [$items children] {
    set user_id [$t set user_id]
    set pa [$t set pa]
    
    if {$user_id > -1} {
      acs_user::get -user_id $user_id -array user_info
      set user_label "$user_info(first_names) $user_info(last_name)"
      set user_link [export_vars -base activities [list [list user $user_id] community_id type users hours]]
    } else {
      set user_label $pa
      set user_link ""
    }

    set nice_duration [::xowiki::utility pretty_age -timestamp [expr {[clock seconds]-[$t set duration]}]]
    regsub -all "( ago|vor )"  $nice_duration "" nice_duration


    set end_time [$t set end_time]
    if {$end_time ne ""} {
      set end_time [clock format [expr {int($end_time)}] -format "%Y-%m-%d %H:%M"]
    }

    t1 add \
        -user         $user_label \
        -pa           $pa  -pa.href [export_vars -base ip-info [list [list ip $pa]]] \
        -community_id [__community_label [$t set community_id]] \
        -community_id.href [export_vars -base activities [list user [list community_id [$t set community_id]] type users hours]] \
        -start_time   [clock format [expr {int([$t set start_time])}] -format "%Y-%m-%d %H:%M"] \
        -end_time     $end_time \
        -duration     $nice_duration \
        -clicks       [$t set clicks]

    if {$user_link ne ""} {
      [::template::t1 last_child] set user.href $user_link
    }

  }
  
  set order desc
  t1 orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] start_time
  
} else {

  ##################################################################
  #
  # Time Statistics
  #
  ##################################################################
  
  TableWidget create t1 \
      -columns {
        AnchorField user -label User
        AnchorField community_id -label "Community"
        Field nice_duration -label "Duration"
        Field duration -label "Seconds" -html {align right}
        Field clicks -label "Clicks" -html {align right}
      }
  
  set time_fraction_query [subst {
    select user_id, pa, community_id, start_time, end_time, on_day,
      round(clicks*fraction) as clicks,
      round(full_duration*fraction) as duration from (
        select
            user_id, peer_address as pa, community_id, clicks, start_time, end_time,
            date_trunc('day',start_time) as on_day,
            extract(EPOCH from (end_time-start_time)) as full_duration,
            1 as fraction
          from request_monitor_community_activities
          where date_trunc('day',start_time) = date_trunc('day',end_time) 
        union
        select
            user_id, peer_address as pa, community_id, clicks, start_time, end_time,
            date_trunc('day',start_time) as on_day,
            extract(EPOCH from (end_time-start_time)) as full_duration,
            extract(EPOCH from ((date_trunc('day',start_time) + interval '1 day') - start_time)) /
            extract(EPOCH from (end_time-start_time)) as fraction
          from request_monitor_community_activities
          where date_trunc('day',start_time) < date_trunc('day',end_time)
        union
        select
            user_id, peer_address as pa, community_id, clicks, start_time, end_time,
            date_trunc('day',end_time) as on_day,
            extract(EPOCH from (end_time-start_time)) as full_duration,
            1 - extract(EPOCH from ((date_trunc('day',start_time) + interval '1 day') - start_time))/
            extract(EPOCH from (end_time-start_time)) as fraction
          from request_monitor_community_activities
          where date_trunc('day',start_time) < date_trunc('day',end_time)
      ) frac where $user_clause and start_time > (now() - :sql_days::interval)
  }]

  set user_field [expr {$users eq "authorized" ? "user_id" : "pa"}]

  set items [::xo::db::Object instantiate_objects -sql [subst {
    select $user_field, community_id, sum(clicks) as clicks, sum(duration) as duration
    from ($time_fraction_query) as time_fractions
    group by 1, 2
  }] -initialize false]

  #
  # For the time being, ignore open sessions
  #
  
  foreach t [$items children] {
    if {$users eq "authorized"} {
      set user_id [$t set user_id]
      if {$user_id > -1} {
        acs_user::get -user_id $user_id -array user_info
        set user_label "$user_info(first_names) $user_info(last_name)"
        set user_link [export_vars -base activities [list [list user $user_id] community_id type users hours]]
      } else {
        set user_label "Unknown"
        set user_link ""
      }
    } else {
      set user_label [$t set pa]
      set user_link ""
    }
    set duration [$t set duration]

    set nice_duration [::xowiki::utility pretty_age -timestamp [expr {[clock seconds] - $duration}]]
    regsub -all "( ago|vor )"  $nice_duration "" nice_duration

    t1 add \
        -user         $user_label \
        -user.href    $user_link \
        -community_id [__community_label [$t set community_id]] \
        -community_id.href [export_vars -base activities [list user [list community_id [$t set community_id]] type users hours]] \
        -duration     $duration \
        -nice_duration $nice_duration \
        -clicks       [$t set clicks]
  }
  
  set order desc
  t1 orderby -order [expr {$order eq "asc" ? "increasing" : "decreasing"}] duration
}
set t1 [t1 asHTML]


# Local variables:
#    mode: tcl
#    tcl-indent-level: 2
#    indent-tabs-mode: nil
# End: