/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2010, Tomasz Sowa * All rights reserved. * */ #include #include "core/log.h" #include "core/request.h" #include "core/config.h" #include "core/db.h" #include "stats.h" #include "templates.h" #include "data.h" extern "C" void Init(PluginInfo &); const char plugin_name[] = "stats"; namespace Stats { // when the statistics start time_t stats_start; // statistics for all pages StatsGlobal stat_global; // statistics for one item // std::map stats_tab; // when to save the config (how many requests should have gone) // (for safety: power failure etc) // default: 1000 // you can set: stats_req_save_freq in the config file to overwrite it // 0 - turn it off int req_save_freq = 1000; int req_current = 0; // helper long ItemId() { long item_id; if( request.is_item ) item_id = request.item.id; else item_id = request.dir_table.back()->id; return item_id; } void CheckSaving() { req_current += 1; if( req_save_freq != 0 && req_current >= req_save_freq ) { SaveStats(); req_current = 0; } } bool BrowserHas(const char * name) { const char * is = strstr(request.env_http_user_agent, name); return is != 0; } bool IsGoogle() { return BrowserHas("Googlebot") && BrowserHas("www.google.com"); } bool IsYahoo() { return BrowserHas("Yahoo!") && BrowserHas("yahoo.com"); } void UpdateStats(Stats & item_stats) { stat_global.all += 1; item_stats.all += 1; if( IsGoogle() ) { stat_global.google += 1; item_stats.google += 1; } if( IsYahoo() ) { stat_global.yahoo += 1; item_stats.yahoo += 1; } } void ContentMake(PluginInfo & info) { StatsData * d = 0; long id = ItemId(); if( info.plugin_data_base ) d = reinterpret_cast(info.plugin_data_base); // this simply prevents F5 (refresh) from a webbrowser if( d && d->last_visited != -1 && d->last_visited == id ) return; if( d ) d->last_visited = id; UpdateStats(stats_tab[id]); if( d && !d->calculated ) { stat_global.unique += 1; d->calculated = true; } CheckSaving(); } void SessionCreated(PluginInfo & info) { StatsData * d = new StatsData(); request.session->plugin_data.Assign(d); log << log3 << "created stats plugin data" << ", plugin id: " << info.plugin_id << ", pointer: " << d << logend; } void RemoveSession(PluginInfo & info) { log << log1 << "deleting stats plugin data" << ", plugin id: " << info.plugin_id << ", pointer: " << info.plugin_data_base << logend; delete info.plugin_data_base; } void ReadConfig() { stats_file = config.Text("stats_file"); req_save_freq = config.Int("stats_req_save_freq", req_save_freq); if( stats_file.empty() ) log << log1 << "you should set stats_file in your config to keep statistics between restarting winix" << logend; else log << log2 << "stats_file: " << stats_file << logend; stats_start = time(0); // it will be overwritten if the config file exists ReadStats(); } void Close() { SaveStats(); } void RemoveItem(long id) { std::map::iterator i = stats_tab.find(id); if( i == stats_tab.end() ) return; stats_tab.erase(i); log << log3 << "Stats: removed stats for item.id: " << id << logend; } void RemoveFile(PluginInfo & info) { RemoveItem(info.l1); } void RemoveDir(PluginInfo & info) { Db::ItemQuery query; std::vector items; size_t i; query.SetAll(false, false); query.WhereParentId(info.l1); db.GetItems(items, query); // removing childs for(i=0 ; i