root/trunk/htdocs/stats.bml @ 919

Revision 919, 8.0 KB (checked in by bradfitz, 11 years ago)

promos? hah. old-skool. bye. that was from before we ever had a business model.

  • 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
51 $ret .= "(=H1 Users H1=)\n";
52 $ret .= "(=P How many users, and how many of those are active? <UL>";
53 $ret .= "<LI><B>Total users: </B> $total\n";
54 $ret .= "<LI><B>Users that have ever updated: </B> $usedever\n";
55 $ret .= "<LI><B>Users updating in last 30 days: </B> $used30\n";
56 $ret .= "<LI><B>Users updating in last 7 days: </B> $used7\n";
57 $ret .= "<LI><B>Users updating in past 24 hours: </B> $usedlastday\n";
58 $ret .= "</UL> P=)\n";
59
60 $ret .= "(=H1 Gender H1=)\n";
61 $ret .= "(=P Are males or females more likely to maintain journals? <UL>";
62 {
63     my $male = $stat{'gender'}->{'M'}+0;
64     my $female = $stat{'gender'}->{'F'}+0;
65     my $tot = $male+$female;
66     $tot ||= 1;
67     $ret .= "<LI><B>Male: </B> $male (" . sprintf("%0.1f", $male*100/($tot||1)) . "%)";
68     $ret .= "<LI><B>Female: </B> $female (" . sprintf("%0.1f", $female*100/($tot||1)) . "%)";
69 }
70 $ret .= "<LI><B>Unspecified: </B> " . ($stat{'gender'}->{'U'}+0);
71 $ret .= "</UL> P=)\n";
72
73 $ret .= "(=H1 Account Types H1=)\n";
74 $ret .= "(=P What type of <a href=\"/support/faqbrowse.bml?faqid=38\">account</a> do people have? <ul>";
75 {
76     # FIXME: ljcom specific, make into a hook.
77     my %acct_name = ("paid" => "Paid Account",
78                      "off" => "Free Account",
79                      "early" => "Early Adopter",
80                      "on" => "Permanent Account");
81     foreach my $act (qw(off early paid on)) {
82         my $num = $stat{'account'}->{$act}+0;
83         $ret .= "<LI><B>$acct_name{$act}: </B> $num (" . sprintf("%0.1f", $num*100/($stat{'userinfo'}->{'total'}||1)) . "%)";   
84     }
85 }
86 $ret .= "</ul> P=)\n";
87
88 unless ($LJ::DISABLED{'stats-newsadv'}) {
89     $ret .= "(=H1 Receiving News/Advertising H1=)\n";
90     $ret .= "(=P This information says how many users of the ones with validated email addresses subscribe to the LiveJournal news that we send out. <ul>";
91     $ret .= "<li><b>Users getting LiveJournal news: </b> $allow_getljnews</li>\n";
92     $ret .= "</ul> P=)\n";
93 }
94
95 unless ($LJ::DISABLED{'stats-recentupdates'})
96 {
97     $ret .= "(=H1 Recent Updates H1=)\n";
98     $ret .= "(=P The following are the 10 most recently updated journals: <ul>";
99     $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");
100     $sth->execute;
101     while (my ($iuser, $iname, $itime) = $sth->fetchrow_array) {
102         $ret .= "<li><a href='/users/$iuser/'>(=_EH $iname _EH=)</a>, $itime</li>\n";
103     }
104     $ret .= "</ul> P=)\n";
105 }
106
107 unless ($LJ::DISABLED{'stats-newjournals'})
108 {
109     $ret .= "(=H1 New Journals H1=)\n";
110     $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>";
111     $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");
112     $sth->execute;
113     while (my ($iuser, $iname, $itime) = $sth->fetchrow_array) {
114         $ret .= "<li><a href='/users/$iuser/'>(=_EH $iname _EH=)</a>, $itime</li>\n";
115     }
116     $ret .= "</ul> P=)\n";
117 }
118
119 $ret .= "(=H1 Demographics H1=)\n";
120 $ret .= "(=P The following are the 15 most popular countries LiveJournal is used in: <UL>";
121 foreach my $key (sort { $stat{'country'}->{$b} <=> $stat{'country'}->{$a} } keys %{$stat{'country'}})
122 {
123     $ret .= "<LI><B>$key</B> - $stat{'country'}->{$key}\n";
124 }
125 $ret .= "</UL>\n";
126 $ret .= "The following are the 15 most popular U.S. states LiveJournal is used in: <UL>";
127 foreach my $key (sort { $stat{'state'}->{$b} <=> $stat{'state'}->{$a} } keys %{$stat{'state'}})
128 {
129     $ret .= "<LI><B>$key</B> - $stat{'state'}->{$key}\n";
130 }
131 $ret .= "</UL> P=)\n";
132
133 # ages
134 $ret .= "(=H1 Age Distribution H1=)(=P The following shows the age distribution of LiveJournal users: P=)\n";
135
136 my %age = ();
137 my $maxage = 1;
138 foreach my $key (keys %{$stat{'age'}}) {
139     $age{$key} = $stat{'age'}->{$key};
140     if ($stat{'age'}->{$key} > $maxage) { $maxage = $stat{'age'}->{$key}; }
141 }
142 $ret .= "<P><TABLE>\n";
143 my $lastage = 0;
144 foreach my $age (grep { $_ >= 13  && $_ <= 55 } sort { $a <=> $b } sort keys %age)
145 {
146     $width = int(400 * $age{$age}/$maxage);
147     $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";
148     $lastage = $_;
149 }
150 $ret .= "</TABLE>\n";
151
152
153 # clients
154 $ret .= "(=H1 Client Usage H1=)(=P How people update their journals (over the last 30 days): P=)\n";
155 $ret .= "<P><TABLE CELLPADDING=3>\n";
156
157 ### sum up clients over different versions
158 foreach my $c (keys %{$stat{'client'}}) {
159     next unless ($c =~ /^(.+?)\//);
160     $stat{'clientname'}->{$1} += $stat{'client'}->{$c};
161 }
162 foreach my $cn (sort { $stat{'clientname'}->{$b} <=> $stat{'clientname'}->{$a} } keys %{$stat{'clientname'}})
163 {
164     $ret .= "<TR VALIGN=TOP><TD><FONT SIZE=+1><B>$stat{'clientname'}->{$cn}</B></FONT></TD><TD><B>$cn</B><BR>\n";
165     $ret .= "<FONT SIZE=-1>\n";
166     foreach my $c (sort grep { /^\Q$cn\E\// } keys %{$stat{'client'}}) {
167         my $count = $stat{'client'}->{$c};
168         $c =~ s/^\Q$cn\E\///;
169         $ret .= "$c ($count), ";
170     }
171     chop $ret; chop $ret;  # remove trailing ", "
172     $ret .= "</FONT>\n";
173     $ret .= "</TD></TR>\n";
174 }
175 $ret .= "</TABLE>\n";
176
177 ### graphs!
178
179 $ret .= "(=H1 Pretty Graphs! H1=)(=P These are the most fun, aren't they? P=)";
180 
181 $ret .= "(=H2 Journal entries -- last 60 days H2=)(=P How often do people post over the last 60 days? P=)";
182 $ret .= "<P><CENTER><IMG SRC=\"stats/postsbyday.png\" WIDTH=520 HEIGHT=350></CENTER>";
183
184 $ret .= "(=H2 Journal entries -- by week, ever H2=)(=P What's the week-to-week trend? P=)";
185 $ret .= "<P><CENTER><IMG SRC=\"stats/postsbyweek.png\" WIDTH=520 HEIGHT=350></CENTER>";
186
187 $ret .= "(=H2 New accounts -- last 60 days H2=)(=P How fast are we growing? P=)";
188 $ret .= "<P><CENTER><IMG SRC=\"stats/newbyday.png\" WIDTH=520 HEIGHT=350></CENTER>";
189
190 return $ret;
191
192_CODE=)
193
194<=BODY
195PAGE=)(=_C <LJDEP>
196link: htdocs/stats/, htdocs/support/faqbrowse.bml
197img: htdocs/img/bluedot.gif, htdocs/stats/postsbyday.png, htdocs/stats/postsbyweek.png, htdocs/stats/newbyday.png
198</LJDEP> _C=)
Note: See TracBrowser for help on using the browser.