root/trunk/htdocs/stats.bml @ 857

Revision 857, 8.2 KB (checked in by bradfitz, 11 years ago)

untabify

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1(=PAGE
2TITLE=>Statistics
3BODY<=
4
5(=H1 (=SITENAME=) Statistics H1=)
6(=P
7The following statistics may be interesting for some of you.  Note that for speed, most of this page is only updated every 24 hours.  However, certain parts are live.  Raw data can be picked up <A HREF="stats/">here</A>.
8P=)
9(=HR=)
10
11(=_CODE
12
13 my $ret = "";
14
15 my $dbs = LJ::get_dbs();
16 my $dbh = $dbs->{'dbh'};
17 my $dbr = $dbs->{'reader'};
18
19 $now = time();
20 %stat = ();
21
22 $sth = $dbr->prepare("SELECT statcat, statkey, statval FROM stats WHERE statcat IN ('userinfo', 'client', 'age', 'gender', 'account')");
23 $sth->execute;
24 while ($_ = $sth->fetchrow_hashref) {
25     $stat{$_->{'statcat'}}->{$_->{'statkey'}} = $_->{'statval'};
26 }
27
28 unless (%stat) {
29     return "(=H1 Sorry... H1=)(=P No statistics are available.  If you're the administrator for this site, run <b>ljmaint.pl genstats</b>, or ideally, put it in cron to run nightly. P=)";
30 }
31
32 $sth = $dbr->prepare("SELECT c.item, s.statval FROM stats s, codes c WHERE c.type='country' AND s.statcat='country' AND s.statkey=c.code ORDER BY s.statval DESC LIMIT 15");
33 $sth->execute;
34 while ($_ = $sth->fetchrow_hashref) {
35     $stat{'country'}->{$_->{'item'}} = $_->{'statval'};
36 }
37
38 $sth = $dbr->prepare("SELECT c.item, s.statval FROM stats s, codes c WHERE c.type='state' AND s.statcat='stateus' AND s.statkey=c.code ORDER BY s.statval DESC LIMIT 15");
39 $sth->execute;
40 while ($_ = $sth->fetchrow_hashref) {
41     $stat{'state'}->{$_->{'item'}} = $_->{'statval'};
42 }
43
44 $total = $stat{'userinfo'}->{'total'}+0;
45 $usedever = $stat{'userinfo'}->{'updated'}+0;
46 $used30 = $stat{'userinfo'}->{'updated_last30'}+0;
47 $used7 = $stat{'userinfo'}->{'updated_last7'}+0;
48 $usedlastday = $stat{'userinfo'}->{'updated_last1'}+0;
49 $allow_getljnews = $stat{'userinfo'}->{'allow_getljnews'}+0;
50 $allow_getpromos = $stat{'userinfo'}->{'allow_getpromos'}+0;
51
52 $ret .= "(=H1 Users H1=)\n";
53 $ret .= "(=P How many users, and how many of those are active? <UL>";
54 $ret .= "<LI><B>Total users: </B> $total\n";
55 $ret .= "<LI><B>Users that have ever updated: </B> $usedever\n";
56 $ret .= "<LI><B>Users updating in last 30 days: </B> $used30\n";
57 $ret .= "<LI><B>Users updating in last 7 days: </B> $used7\n";
58 $ret .= "<LI><B>Users updating in past 24 hours: </B> $usedlastday\n";
59 $ret .= "</UL> P=)\n";
60
61 $ret .= "(=H1 Gender H1=)\n";
62 $ret .= "(=P Are males or females more likely to maintain journals? <UL>";
63 {
64     my $male = $stat{'gender'}->{'M'}+0;
65     my $female = $stat{'gender'}->{'F'}+0;
66     my $tot = $male+$female;
67     $tot ||= 1;
68     $ret .= "<LI><B>Male: </B> $male (" . sprintf("%0.1f", $male*100/($tot||1)) . "%)";
69     $ret .= "<LI><B>Female: </B> $female (" . sprintf("%0.1f", $female*100/($tot||1)) . "%)";
70 }
71 $ret .= "<LI><B>Unspecified: </B> " . ($stat{'gender'}->{'U'}+0);
72 $ret .= "</UL> P=)\n";
73
74 $ret .= "(=H1 Account Types H1=)\n";
75 $ret .= "(=P What type of <a href=\"/support/faqbrowse.bml?faqid=38\">account</a> do people have? <ul>";
76 {
77     # FIXME: ljcom specific, make into a hook.
78     my %acct_name = ("paid" => "Paid Account",
79                      "off" => "Free Account",
80                      "early" => "Early Adopter",
81                      "on" => "Permanent Account");
82     foreach my $act (qw(off early paid on)) {
83         my $num = $stat{'account'}->{$act}+0;
84         $ret .= "<LI><B>$acct_name{$act}: </B> $num (" . sprintf("%0.1f", $num*100/($stat{'userinfo'}->{'total'}||1)) . "%)";   
85     }
86 }
87 $ret .= "</ul> P=)\n";
88
89 unless ($LJ::DISABLED{'stats-newsadv'}) {
90     $ret .= "(=H1 Receiving News/Advertising H1=)\n";
91     $ret .= "(=P This information says how many users of the ones with validated email addresses subscribe to the LiveJournal news that we send out, and how many people say they wouldn't mind getting advertisement/promotions sent to them by email. <UL>";
92     $ret .= "<LI><B>Users getting LiveJournal news: </B> $allow_getljnews\n";
93     $ret .= "<LI><B>Users getting promotions by mail: </B> $allow_getpromos\n";
94     $ret .= "</UL> P=)\n";
95 }
96
97 unless ($LJ::DISABLED{'stats-recentupdates'})
98 {
99     $ret .= "(=H1 Recent Updates H1=)\n";
100     $ret .= "(=P The following are the 10 most recently updated journals: <ul>";
101     $sth = $dbr->prepare("SELECT u.user, u.name, uu.timeupdate FROM user u, userusage uu WHERE u.userid=uu.userid AND uu.timeupdate > DATE_SUB(NOW(), INTERVAL 30 DAY) ORDER BY uu.timeupdate DESC LIMIT 10");
102     $sth->execute;
103     while (my ($iuser, $iname, $itime) = $sth->fetchrow_array) {
104         $ret .= "<li><a href='/users/$iuser/'>(=_EH $iname _EH=)</a>, $itime</li>\n";
105     }
106     $ret .= "</ul> P=)\n";
107 }
108
109 unless ($LJ::DISABLED{'stats-newjournals'})
110 {
111     $ret .= "(=H1 New Journals H1=)\n";
112     $ret .= "(=P The following are the 10 most recently created journals.  It's very likely these users haven't modified their journals much, and probably haven't wrote much in them yet either... <ul>";
113     $sth = $dbr->prepare("SELECT u.user, u.name, uu.timeupdate FROM user u, userusage uu WHERE u.userid=uu.userid AND uu.timeupdate IS NOT NULL ORDER BY uu.timecreate DESC LIMIT 10");
114     $sth->execute;
115     while (my ($iuser, $iname, $itime) = $sth->fetchrow_array) {
116         $ret .= "<li><a href='/users/$iuser/'>(=_EH $iname _EH=)</a>, $itime</li>\n";
117     }
118     $ret .= "</ul> P=)\n";
119 }
120
121 $ret .= "(=H1 Demographics H1=)\n";
122 $ret .= "(=P The following are the 15 most popular countries LiveJournal is used in: <UL>";
123 foreach my $key (sort { $stat{'country'}->{$b} <=> $stat{'country'}->{$a} } keys %{$stat{'country'}})
124 {
125     $ret .= "<LI><B>$key</B> - $stat{'country'}->{$key}\n";
126 }
127 $ret .= "</UL>\n";
128 $ret .= "The following are the 15 most popular U.S. states LiveJournal is used in: <UL>";
129 foreach my $key (sort { $stat{'state'}->{$b} <=> $stat{'state'}->{$a} } keys %{$stat{'state'}})
130 {
131     $ret .= "<LI><B>$key</B> - $stat{'state'}->{$key}\n";
132 }
133 $ret .= "</UL> P=)\n";
134
135 # ages
136 $ret .= "(=H1 Age Distribution H1=)(=P The following shows the age distribution of LiveJournal users: P=)\n";
137
138 my %age = ();
139 my $maxage = 1;
140 foreach my $key (keys %{$stat{'age'}}) {
141     $age{$key} = $stat{'age'}->{$key};
142     if ($stat{'age'}->{$key} > $maxage) { $maxage = $stat{'age'}->{$key}; }
143 }
144 $ret .= "<P><TABLE>\n";
145 my $lastage = 0;
146 foreach my $age (grep { $_ >= 13  && $_ <= 55 } sort { $a <=> $b } sort keys %age)
147 {
148     $width = int(400 * $age{$age}/$maxage);
149     $ret .= "<TR><TD ALIGN=RIGHT><B>$age</B></TD><TD>$age{$age}</TD><TD><IMG SRC=\"/img/bluedot.gif\" HEIGHT=10 WIDTH=$width></TD></TR>\n";
150     $lastage = $_;
151 }
152 $ret .= "</TABLE>\n";
153
154
155 # clients
156 $ret .= "(=H1 Client Usage H1=)(=P How people update their journals (over the last 30 days): P=)\n";
157 $ret .= "<P><TABLE CELLPADDING=3>\n";
158
159 ### sum up clients over different versions
160 foreach my $c (keys %{$stat{'client'}}) {
161     next unless ($c =~ /^(.+?)\//);
162     $stat{'clientname'}->{$1} += $stat{'client'}->{$c};
163 }
164 foreach my $cn (sort { $stat{'clientname'}->{$b} <=> $stat{'clientname'}->{$a} } keys %{$stat{'clientname'}})
165 {
166     $ret .= "<TR VALIGN=TOP><TD><FONT SIZE=+1><B>$stat{'clientname'}->{$cn}</B></FONT></TD><TD><B>$cn</B><BR>\n";
167     $ret .= "<FONT SIZE=-1>\n";
168     foreach my $c (sort grep { /^\Q$cn\E\// } keys %{$stat{'client'}}) {
169         my $count = $stat{'client'}->{$c};
170         $c =~ s/^\Q$cn\E\///;
171         $ret .= "$c ($count), ";
172     }
173     chop $ret; chop $ret;  # remove trailing ", "
174     $ret .= "</FONT>\n";
175     $ret .= "</TD></TR>\n";
176 }
177 $ret .= "</TABLE>\n";
178
179 ### graphs!
180
181 $ret .= "(=H1 Pretty Graphs! H1=)(=P These are the most fun, aren't they? P=)";
182 
183 $ret .= "(=H2 Journal entries -- last 60 days H2=)(=P How often do people post over the last 60 days? P=)";
184 $ret .= "<P><CENTER><IMG SRC=\"stats/postsbyday.png\" WIDTH=520 HEIGHT=350></CENTER>";
185
186 $ret .= "(=H2 Journal entries -- by week, ever H2=)(=P What's the week-to-week trend? P=)";
187 $ret .= "<P><CENTER><IMG SRC=\"stats/postsbyweek.png\" WIDTH=520 HEIGHT=350></CENTER>";
188
189 $ret .= "(=H2 New accounts -- last 60 days H2=)(=P How fast are we growing? P=)";
190 $ret .= "<P><CENTER><IMG SRC=\"stats/newbyday.png\" WIDTH=520 HEIGHT=350></CENTER>";
191
192 return $ret;
193
194_CODE=)
195
196<=BODY
197PAGE=)(=_C <LJDEP>
198link: htdocs/stats/, htdocs/support/faqbrowse.bml
199img: htdocs/img/bluedot.gif, htdocs/stats/postsbyday.png, htdocs/stats/postsbyweek.png, htdocs/stats/newbyday.png
200</LJDEP> _C=)
Note: See TracBrowser for help on using the browser.