Merge branch '0.7.x' of git@gitorious.org:laconica/dev into 0.7.x

This commit is contained in:
Zach Copley 2009-03-04 16:21:37 -08:00
commit 77e4fad9fa
21 changed files with 250 additions and 111 deletions

View File

@ -99,3 +99,7 @@ StartPublicGroupNav: Showing the public group nav menu
EndPublicGroupNav: At the end of the public group nav menu EndPublicGroupNav: At the end of the public group nav menu
- $action: the current action - $action: the current action
RouterInitialized: After the router instance has been initialized
- $m: the Net_URL_Mapper that has just been set up

93
README
View File

@ -236,21 +236,28 @@ especially if you've previously installed PHP/MySQL packages.
configure virtual hosts on your web server, you can try setting up configure virtual hosts on your web server, you can try setting up
"http://micro.example.net/" or the like. "http://micro.example.net/" or the like.
3. You should also take this moment to make your avatar subdirectory 3. Make your target directory writeable by the Web server.
chmod a+w /var/www/mublog/
On some systems, this will probably work:
chgrp www-data /var/www/mublog/
chmod g+w /var/www/mublog/
If your Web server runs as another user besides "www-data", try
that user's default group instead. As a last resort, you can create
a new group like "mublog" and add the Web server's user to the group.
4. You should also take this moment to make your avatar subdirectory
writeable by the Web server. An insecure way to do this is: writeable by the Web server. An insecure way to do this is:
chmod a+w /var/www/mublog/avatar chmod a+w /var/www/mublog/avatar
On some systems, this will probably work: You can also make the avatar directory writeable by the Web server
group, as noted above.
chgrp www-data /var/www/mublog/avatar 5. Create a database to hold your microblog data. Something like this
chmod g+w /var/www/mublog/avatar
If your Web server runs as another user besides "www-data", try
that user's default group instead. As a last resort, you can create
a new group like "avatar" and add the Web server's user to the group.
4. Create a database to hold your microblog data. Something like this
should work: should work:
mysqladmin -u "username" --password="password" create laconica mysqladmin -u "username" --password="password" create laconica
@ -263,63 +270,55 @@ especially if you've previously installed PHP/MySQL packages.
a tool like PHPAdmin to create a database. Check your hosting a tool like PHPAdmin to create a database. Check your hosting
service's documentation for how to create a new MySQL database.) service's documentation for how to create a new MySQL database.)
5. Run the laconica.sql SQL script in the db subdirectory to create
the database tables in the database. A typical system would work
like this:
mysql -u "username" --password="password" laconica < /var/www/mublog/db/laconica.sql
You may want to test by logging into the database and checking that
the tables were created. Here's an example:
SHOW TABLES;
6. Create a new database account that Laconica will use to access the 6. Create a new database account that Laconica will use to access the
database. If you have shell access, this will probably work from the database. If you have shell access, this will probably work from the
MySQL shell: MySQL shell:
GRANT SELECT,INSERT,DELETE,UPDATE on laconica.* GRANT ALL on laconica.*
TO 'lacuser'@'localhost' TO 'lacuser'@'localhost'
IDENTIFIED BY 'lacpassword'; IDENTIFIED BY 'lacpassword';
You should change 'lacuser' and 'lacpassword' to your preferred new You should change 'lacuser' and 'lacpassword' to your preferred new
username and password. You may want to test logging in as this new username and password. You may want to test logging in to MySQL as
user and testing that you can SELECT from some of the tables in the this new user.
DB (use SHOW TABLES to see which ones are there).
7. Copy the config.php.sample in the Laconica directory to config.php. 7. In a browser, navigate to the Laconica install script; something like:
8. Edit config.php to set the basic configuration for your system. http://yourserver.example.com/mublog/install.php
(See descriptions below for basic config options.) Note that there
are lots of options and if you try to do them all at once, you will
have a hard time making sure what's working and what's not. So,
stick with the basics at first. In particular, customizing the
'site' and 'db' settings will almost definitely be needed.
9. At this point, you should be able to navigate in a browser to your Enter the database connection information and your site name. The
microblog's main directory and see the "Public Timeline", which install program will configure your site and install the initial,
will be empty. If not, magic has happened! You can now register a almost-empty database.
new user, post some notices, edit your profile, etc. However, you
may want to wait to do that stuff if you think you can set up 8. You should now be able to navigate to your microblog's main directory
"fancy URLs" (see below), since some URLs are stored in the database. and see the "Public Timeline", which will be empty. If not, magic
has happened! You can now register a new user, post some notices,
edit your profile, etc. However, you may want to wait to do that stuff
if you think you can set up "fancy URLs" (see below), since some
URLs are stored in the database.
Fancy URLs Fancy URLs
---------- ----------
By default, Laconica will have big long sloppy URLs that are hard for By default, Laconica will use URLs that include the main PHP program's
people to remember or use. For example, a user's home profile might be name in them. For example, a user's home profile might be
found at: found at:
http://example.org/mublog/index.php?action=showstream&nickname=fred http://example.org/mublog/index.php/mublog/fred
On certain systems that don't support this kind of syntax, they'll
look like this:
http://example.org/mublog/index.php?p=mublog/fred
It's possible to configure the software so it looks like this instead: It's possible to configure the software so it looks like this instead:
http://example.org/mublog/fred http://example.org/mublog/fred
These "fancy URLs" are more readable and memorable for users. To use These "fancy URLs" are more readable and memorable for users. To use
fancy URLs, you must either have Apache 2.2.x with .htaccess enabled fancy URLs, you must either have Apache 2.x with .htaccess enabled and
and mod_redirect enabled, -OR- know how to configure "url redirection" mod_redirect enabled, -OR- know how to configure "url redirection" in
in your server. your server.
1. Copy the htaccess.sample file to .htaccess in your Laconica 1. Copy the htaccess.sample file to .htaccess in your Laconica
directory. Note: if you have control of your server's httpd.conf or directory. Note: if you have control of your server's httpd.conf or
@ -344,10 +343,6 @@ like:
If you changed your HTTP server configuration, you may need to restart If you changed your HTTP server configuration, you may need to restart
the server first. the server first.
If you have problems with the .htaccess file on versions of Apache
earlier than 2.2.x, try changing the regular expressions in the
htaccess.sample file that use "\w" to just use ".".
Sphinx Sphinx
------ ------
@ -644,7 +639,7 @@ to these resources.
Themes Themes
------ ------
There are two themes shipped with this version of Laconica: "stoica", There are two themes shipped with this version of Laconica: "identica",
which is what the Identi.ca site uses, and "default", which is a good which is what the Identi.ca site uses, and "default", which is a good
basis for other sites. basis for other sites.

View File

@ -169,8 +169,14 @@ class FavoritedAction extends Action
function showContent() function showContent()
{ {
if (common_config('db', 'type') == 'pgsql') {
$weightexpr='sum(exp(-extract(epoch from (now() - fave.modified)) / %s))';
} else {
$weightexpr='sum(exp(-(now() - fave.modified) / %s))';
}
$qry = 'SELECT notice.*, '. $qry = 'SELECT notice.*, '.
'sum(exp(-(now() - fave.modified) / %s)) as weight ' . $weightexpr . ' as weight ' .
'FROM notice JOIN fave ON notice.id = fave.notice_id ' . 'FROM notice JOIN fave ON notice.id = fave.notice_id ' .
'GROUP BY fave.notice_id ' . 'GROUP BY fave.notice_id ' .
'ORDER BY weight DESC'; 'ORDER BY weight DESC';

View File

@ -1,8 +1,5 @@
insert into foreign_service insert into foreign_service
(id, name, description, created) (id, name, description, created)
values values
('1','Twitter', 'Twitter Micro-blogging service', now()); ('1','Twitter', 'Twitter Micro-blogging service', now()),
insert into foreign_service
(id, name, description, created)
values
('2','Facebook', 'Facebook', now()); ('2','Facebook', 'Facebook', now());

View File

@ -8,7 +8,7 @@ create table profile (
homepage varchar(255) /* comment 'identifying URL' */, homepage varchar(255) /* comment 'identifying URL' */,
bio varchar(140) /* comment 'descriptive biography' */, bio varchar(140) /* comment 'descriptive biography' */,
location varchar(255) /* comment 'physical location' */, location varchar(255) /* comment 'physical location' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
textsearch tsvector textsearch tsvector
@ -23,7 +23,7 @@ create table avatar (
mediatype varchar(32) not null /* comment 'file type' */, mediatype varchar(32) not null /* comment 'file type' */,
filename varchar(255) null /* comment 'local filename, if local' */, filename varchar(255) null /* comment 'local filename, if local' */,
url varchar(255) unique /* comment 'avatar location' */, url varchar(255) unique /* comment 'avatar location' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
primary key(profile_id, width, height) primary key(profile_id, width, height)
@ -34,7 +34,7 @@ create table sms_carrier (
id serial primary key /* comment 'primary key for SMS carrier' */, id serial primary key /* comment 'primary key for SMS carrier' */,
name varchar(64) unique /* comment 'name of the carrier' */, name varchar(64) unique /* comment 'name of the carrier' */,
email_pattern varchar(255) not null /* comment 'sprintf pattern for making an email address from a phone number' */, email_pattern varchar(255) not null /* comment 'sprintf pattern for making an email address from a phone number' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified ' */ modified timestamp /* comment 'date this record was modified ' */
); );
@ -69,7 +69,7 @@ create table "user" (
autosubscribe integer default 0 /* comment 'automatically subscribe to users who subscribe to us' */, autosubscribe integer default 0 /* comment 'automatically subscribe to users who subscribe to us' */,
urlshorteningservice varchar(50) default 'ur1.ca' /* comment 'service to use for auto-shortening URLs' */, urlshorteningservice varchar(50) default 'ur1.ca' /* comment 'service to use for auto-shortening URLs' */,
inboxed integer default 0 /* comment 'has an inbox been created for this user?' */, inboxed integer default 0 /* comment 'has an inbox been created for this user?' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */ modified timestamp /* comment 'date this record was modified' */
); );
@ -82,7 +82,7 @@ create table remote_profile (
uri varchar(255) unique /* comment 'universally unique identifier, usually a tag URI' */, uri varchar(255) unique /* comment 'universally unique identifier, usually a tag URI' */,
postnoticeurl varchar(255) /* comment 'URL we use for posting notices' */, postnoticeurl varchar(255) /* comment 'URL we use for posting notices' */,
updateprofileurl varchar(255) /* comment 'URL we use for updates to this profile' */, updateprofileurl varchar(255) /* comment 'URL we use for updates to this profile' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */ modified timestamp /* comment 'date this record was modified' */
); );
@ -93,7 +93,7 @@ create table subscription (
sms integer default 1 /* comment 'deliver sms messages' */, sms integer default 1 /* comment 'deliver sms messages' */,
token varchar(255) /* comment 'authorization token' */, token varchar(255) /* comment 'authorization token' */,
secret varchar(255) /* comment 'token secret' */, secret varchar(255) /* comment 'token secret' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
primary key (subscriber, subscribed) primary key (subscriber, subscribed)
@ -109,7 +109,7 @@ create table notice (
content varchar(140) /* comment 'update content' */, content varchar(140) /* comment 'update content' */,
rendered text /* comment 'HTML version of the content' */, rendered text /* comment 'HTML version of the content' */,
url varchar(255) /* comment 'URL of any attachment (image, video, bookmark, whatever)' */, url varchar(255) /* comment 'URL of any attachment (image, video, bookmark, whatever)' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
reply_to integer /* comment 'notice replied to (usually a guess)' */ references notice (id) , reply_to integer /* comment 'notice replied to (usually a guess)' */ references notice (id) ,
is_local integer default 0 /* comment 'notice was generated by a user' */, is_local integer default 0 /* comment 'notice was generated by a user' */,
@ -124,7 +124,7 @@ create table notice_source (
code varchar(32) primary key not null /* comment 'source code' */, code varchar(32) primary key not null /* comment 'source code' */,
name varchar(255) not null /* comment 'name of the source' */, name varchar(255) not null /* comment 'name of the source' */,
url varchar(255) not null /* comment 'url to link to' */, url varchar(255) not null /* comment 'url to link to' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */ modified timestamp /* comment 'date this record was modified' */
); );
@ -132,7 +132,7 @@ create table reply (
notice_id integer not null /* comment 'notice that is the reply' */ references notice (id) , notice_id integer not null /* comment 'notice that is the reply' */ references notice (id) ,
profile_id integer not null /* comment 'profile replied to' */ references profile (id) , profile_id integer not null /* comment 'profile replied to' */ references profile (id) ,
modified timestamp not null default 'now' /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
replied_id integer /* comment 'notice replied to (not used, see notice.reply_to)' */, replied_id integer /* comment 'notice replied to (not used, see notice.reply_to)' */,
primary key (notice_id, profile_id) primary key (notice_id, profile_id)
@ -146,7 +146,7 @@ create table fave (
notice_id integer not null /* comment 'notice that is the favorite' */ references notice (id), notice_id integer not null /* comment 'notice that is the favorite' */ references notice (id),
user_id integer not null /* comment 'user who likes this notice' */ references "user" (id) , user_id integer not null /* comment 'user who likes this notice' */ references "user" (id) ,
modified timestamp not null /* comment 'date this record was modified' */, modified timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was modified' */,
primary key (notice_id, user_id) primary key (notice_id, user_id)
); );
@ -160,7 +160,7 @@ create table consumer (
consumer_key varchar(255) primary key /* comment 'unique identifier, root URL' */, consumer_key varchar(255) primary key /* comment 'unique identifier, root URL' */,
seed char(32) not null /* comment 'seed for new tokens by this consumer' */, seed char(32) not null /* comment 'seed for new tokens by this consumer' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */ modified timestamp /* comment 'date this record was modified' */
); );
@ -171,7 +171,7 @@ create table token (
type integer not null default 0 /* comment 'request or access' */, type integer not null default 0 /* comment 'request or access' */,
state integer default 0 /* comment 'for requests; 0 = initial, 1 = authorized, 2 = used' */, state integer default 0 /* comment 'for requests; 0 = initial, 1 = authorized, 2 = used' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
primary key (consumer_key, tok) primary key (consumer_key, tok)
@ -183,7 +183,7 @@ create table nonce (
nonce char(32) not null /* comment 'nonce' */, nonce char(32) not null /* comment 'nonce' */,
ts timestamp not null /* comment 'timestamp sent' */, ts timestamp not null /* comment 'timestamp sent' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
primary key (consumer_key, tok, nonce), primary key (consumer_key, tok, nonce),
@ -196,7 +196,7 @@ create table user_openid (
canonical varchar(255) primary key /* comment 'Canonical true URL' */, canonical varchar(255) primary key /* comment 'Canonical true URL' */,
display varchar(255) not null unique /* comment 'URL for viewing, may be different from canonical' */, display varchar(255) not null unique /* comment 'URL for viewing, may be different from canonical' */,
user_id integer not null /* comment 'user owning this URL' */ references "user" (id) , user_id integer not null /* comment 'user owning this URL' */ references "user" (id) ,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */ modified timestamp /* comment 'date this record was modified' */
); );
@ -242,7 +242,7 @@ create table queue_item (
notice_id integer not null /* comment 'notice queued' */ references notice (id) , notice_id integer not null /* comment 'notice queued' */ references notice (id) ,
transport varchar(8) not null /* comment 'queue for what? "email", "jabber", "sms", "irc", ...' */, transport varchar(8) not null /* comment 'queue for what? "email", "jabber", "sms", "irc", ...' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
claimed timestamp /* comment 'date this item was claimed' */, claimed timestamp /* comment 'date this item was claimed' */,
primary key (notice_id, transport) primary key (notice_id, transport)
@ -254,7 +254,7 @@ create index queue_item_created_idx on queue_item using btree(created);
create table notice_tag ( create table notice_tag (
tag varchar( 64 ) not null /* comment 'hash tag associated with this notice' */, tag varchar( 64 ) not null /* comment 'hash tag associated with this notice' */,
notice_id integer not null /* comment 'notice tagged' */ references notice (id) , notice_id integer not null /* comment 'notice tagged' */ references notice (id) ,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
primary key (tag, notice_id) primary key (tag, notice_id)
); );
@ -266,7 +266,7 @@ create table foreign_service (
id int not null primary key /* comment 'numeric key for service' */, id int not null primary key /* comment 'numeric key for service' */,
name varchar(32) not null unique /* comment 'name of the service' */, name varchar(32) not null unique /* comment 'name of the service' */,
description varchar(255) /* comment 'description' */, description varchar(255) /* comment 'description' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */ modified timestamp /* comment 'date this record was modified' */
); );
@ -275,7 +275,7 @@ create table foreign_user (
service int not null /* comment 'foreign key to service' */ references foreign_service(id) , service int not null /* comment 'foreign key to service' */ references foreign_service(id) ,
uri varchar(255) not null unique /* comment 'identifying URI' */, uri varchar(255) not null unique /* comment 'identifying URI' */,
nickname varchar(255) /* comment 'nickname on foreign service' */, nickname varchar(255) /* comment 'nickname on foreign service' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
primary key (id, service) primary key (id, service)
@ -289,8 +289,8 @@ create table foreign_link (
noticesync int not null default 1 /* comment 'notice synchronisation, bit 1 = sync outgoing, bit 2 = sync incoming, bit 3 = filter local replies' */, noticesync int not null default 1 /* comment 'notice synchronisation, bit 1 = sync outgoing, bit 2 = sync incoming, bit 3 = filter local replies' */,
friendsync int not null default 2 /* comment 'friend synchronisation, bit 1 = sync outgoing, bit 2 = sync incoming */, friendsync int not null default 2 /* comment 'friend synchronisation, bit 1 = sync outgoing, bit 2 = sync incoming */,
profilesync int not null default 1 /* comment 'profile synchronization, bit 1 = sync outgoing, bit 2 = sync incoming' */, profilesync int not null default 1 /* comment 'profile synchronization, bit 1 = sync outgoing, bit 2 = sync incoming' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp not null /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
primary key (user_id,foreign_id,service) primary key (user_id,foreign_id,service)
); );
@ -300,7 +300,7 @@ create table foreign_subscription (
service int not null /* comment 'service where relationship happens' */ references foreign_service(id) , service int not null /* comment 'service where relationship happens' */ references foreign_service(id) ,
subscriber int not null /* comment 'subscriber on foreign service' */ , subscriber int not null /* comment 'subscriber on foreign service' */ ,
subscribed int not null /* comment 'subscribed user' */ , subscribed int not null /* comment 'subscribed user' */ ,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
primary key (service, subscriber, subscribed) primary key (service, subscriber, subscribed)
); );
@ -312,7 +312,7 @@ create table invitation (
user_id int not null /* comment 'who sent the invitation' */ references "user" (id), user_id int not null /* comment 'who sent the invitation' */ references "user" (id),
address varchar(255) not null /* comment 'invitation sent to' */, address varchar(255) not null /* comment 'invitation sent to' */,
address_type varchar(8) not null /* comment 'address type ("email", "jabber", "sms") '*/, address_type varchar(8) not null /* comment 'address type ("email", "jabber", "sms") '*/,
created timestamp not null /* comment 'date this record was created' */ created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */
); );
create index invitation_address_idx on invitation using btree(address,address_type); create index invitation_address_idx on invitation using btree(address,address_type);
@ -327,7 +327,7 @@ create table message (
content varchar(140) /* comment 'message content' */, content varchar(140) /* comment 'message content' */,
rendered text /* comment 'HTML version of the content' */, rendered text /* comment 'HTML version of the content' */,
url varchar(255) /* comment 'URL of any attachment (image, video, bookmark, whatever)' */, url varchar(255) /* comment 'URL of any attachment (image, video, bookmark, whatever)' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
source varchar(32) /* comment 'source of comment, like "web", "im", or "clientname"' */ source varchar(32) /* comment 'source of comment, like "web", "im", or "clientname"' */
@ -340,7 +340,7 @@ create table notice_inbox (
user_id integer not null /* comment 'user receiving the message' */ references "user" (id), user_id integer not null /* comment 'user receiving the message' */ references "user" (id),
notice_id integer not null /* comment 'notice received' */ references notice (id), notice_id integer not null /* comment 'notice received' */ references notice (id),
created timestamp not null /* comment 'date the notice was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date the notice was created' */,
source integer default 1 /* comment 'reason it is in the inbox; 1=subscription' */, source integer default 1 /* comment 'reason it is in the inbox; 1=subscription' */,
primary key (user_id, notice_id) primary key (user_id, notice_id)
@ -383,7 +383,7 @@ create table user_group (
stream_logo varchar(255) /* comment 'stream-sized logo' */, stream_logo varchar(255) /* comment 'stream-sized logo' */,
mini_logo varchar(255) /* comment 'mini logo' */, mini_logo varchar(255) /* comment 'mini logo' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */ modified timestamp /* comment 'date this record was modified' */
); );
@ -395,7 +395,7 @@ create table group_member (
profile_id integer not null /* comment 'foreign key to profile table' */ references profile (id), profile_id integer not null /* comment 'foreign key to profile table' */ references profile (id),
is_admin integer default 0 /* comment 'is this user an admin?' */, is_admin integer default 0 /* comment 'is this user an admin?' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */, modified timestamp /* comment 'date this record was modified' */,
primary key (group_id, profile_id) primary key (group_id, profile_id)
@ -406,7 +406,7 @@ create table related_group (
group_id integer not null /* comment 'foreign key to user_group' */ references user_group (id) , group_id integer not null /* comment 'foreign key to user_group' */ references user_group (id) ,
related_group_id integer not null /* comment 'foreign key to user_group' */ references user_group (id), related_group_id integer not null /* comment 'foreign key to user_group' */ references user_group (id),
created timestamp not null /* comment 'date this record was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
primary key (group_id, related_group_id) primary key (group_id, related_group_id)
@ -415,7 +415,7 @@ create table related_group (
create table group_inbox ( create table group_inbox (
group_id integer not null /* comment 'group receiving the message' references user_group (id) */, group_id integer not null /* comment 'group receiving the message' references user_group (id) */,
notice_id integer not null /* comment 'notice received' references notice (id) */, notice_id integer not null /* comment 'notice received' references notice (id) */,
created timestamp not null /* comment 'date the notice was created' */, created timestamp not null default CURRENT_TIMESTAMP /* comment 'date the notice was created' */,
primary key (group_id, notice_id) primary key (group_id, notice_id)
); );

46
db/notice_source.sql Normal file
View File

@ -0,0 +1,46 @@
INSERT INTO notice_source
(code, name, url, created)
VALUES
('Do','Gnome Do','http://do.davebsd.com/wiki/index.php?title=Microblog_Plugin', now()),
('Facebook','Facebook','http://apps.facebook.com/identica/', now()),
('Gwibber','Gwibber','http://launchpad.net/gwibber', now()),
('HelloTxt','HelloTxt','http://hellotxt.com/', now()),
('IdentiFox','IdentiFox','http://www.bitbucket.org/uncryptic/identifox/', now()),
('LaTwit','LaTwit','http://latwit.mac65.com/', now()),
('Nambu','Nambu','http://www.nambu.com/', now()),
('Pikchur','Pikchur','http://www.pikchur.com/', now()),
('Ping.fm','Ping.fm','http://ping.fm/', now()),
('Twidge','Twidge','http://software.complete.org/twidge', now()),
('Updating.Me','Updating.Me','http://updating.me/', now()),
('betwittered','BeTwittered','http://www.32hours.com/betwitteredinfo/', now()),
('bti','bti','http://gregkh.github.com/bti/', now()),
('deskbar','Deskbar-Applet','http://www.gnome.org/projects/deskbar-applet/', now()),
('identicatools','Laconica Tools','http://bitbucketlabs.net/laconica-tools/', now()),
('identichat','identichat','http://identichat.prosody.im/', now()),
('identitwitch','IdentiTwitch','http://richfish.org/identitwitch/', now()),
('mbpidgin','mbpidgin','http://code.google.com/p/microblog-purple/', now()),
('moconica','Moconica','http://moconica.com/', now()),
('pocketwit','PockeTwit','http://code.google.com/p/pocketwit/', now()),
('posty','Posty','http://spreadingfunkyness.com/posty/', now()),
('royalewithcheese','Royale With Cheese','http://p.hellyeah.org/', now()),
('rssdent','rssdent','http://github.com/zcopley/rssdent/tree/master', now()),
('rygh.no','rygh.no','http://rygh.no/', now()),
('ryghsms','ryghsms','http://sms.rygh.no/', now()),
('smob','SMOB','http://smob.sioc-project.org/', now()),
('spaz','Spaz','http://funkatron.com/spaz', now()),
('tarpipe','tarpipe','http://tarpipe.com/', now()),
('tjunar','Tjunar','http://nederflash.nl/boek/titels/tjunar-air', now()),
('tr.im','tr.im','http://tr.im/', now()),
('tweenky','Tweenky','http://beta.tweenky.com/', now()),
('twhirl','Twhirl','http://www.twhirl.org/', now()),
('twibble','twibble','http://www.twibble.de/', now()),
('twidge','Twidge','http://software.complete.org/twidge', now()),
('twidroid','twidroid','http://www.twidroid.com/', now()),
('twittelator','Twittelator','http://www.stone.com/iPhone/Twittelator/', now()),
('twitterfeed','twitterfeed','http://twitterfeed.com/', now()),
('twitterphoto','TwitterPhoto','http://richfish.org/twitterphoto/', now()),
('twitterpm','Net::Twitter','http://search.cpan.org/dist/Net-Twitter/', now()),
('twittertools','Twitter Tools','http://wordpress.org/extend/plugins/twitter-tools/', now()),
('twitux','Twitux','http://live.gnome.org/DanielMorales/Twitux', now()),
('twitvim','TwitVim','http://vim.sourceforge.net/scripts/script.php?script_id=2204', now()),
('urfastr','urfastr','http://urfastr.net/', now());

View File

@ -65,6 +65,14 @@ function main()
{ {
global $user, $action; global $user, $action;
if (!_have_config()) {
$msg = sprintf(_("No configuration file found. Try running ".
"the installation program first."));
$sac = new ServerErrorAction($msg);
$sac->showPage();
return;
}
// For database errors // For database errors
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'handleError'); PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'handleError');

View File

@ -130,6 +130,36 @@ function handlePost()
$password = $_POST['password']; $password = $_POST['password'];
$sitename = $_POST['sitename']; $sitename = $_POST['sitename'];
if (empty($host)) {
updateStatus("No hostname specified.", true);
showForm();
return;
}
if (empty($database)) {
updateStatus("No database specified.", true);
showForm();
return;
}
if (empty($username)) {
updateStatus("No username specified.", true);
showForm();
return;
}
if (empty($password)) {
updateStatus("No password specified.", true);
showForm();
return;
}
if (empty($sitename)) {
updateStatus("No sitename specified.", true);
showForm();
return;
}
updateStatus("Starting installation..."); updateStatus("Starting installation...");
updateStatus("Checking database..."); updateStatus("Checking database...");
$conn = mysql_connect($host, $username, $password); $conn = mysql_connect($host, $username, $password);
@ -152,6 +182,18 @@ function handlePost()
showForm(); showForm();
return; return;
} }
foreach (array('sms_carrier' => 'SMS carrier',
'notice_source' => 'notice source',
'foreign_services' => 'foreign service')
as $scr => $name) {
updateStatus(sprintf("Adding %s data to database...", $name));
$res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn);
if ($res === false) {
updateStatus(sprintf("Can't run %d script.", $name), true);
showForm();
return;
}
}
updateStatus("Writing config file..."); updateStatus("Writing config file...");
$sqlUrl = "mysqli://$username:$password@$host/$database"; $sqlUrl = "mysqli://$username:$password@$host/$database";
$res = writeConf($sitename, $sqlUrl); $res = writeConf($sitename, $sqlUrl);

View File

@ -976,17 +976,17 @@ class Action extends HTMLOutputter // lawsuit
} }
if ($have_before) { if ($have_before) {
$pargs = array('page' => $page-1); $pargs = array('page' => $page-1);
$newargs = $args ? array_merge($args, $pargs) : $pargs;
$this->elementStart('li', array('class' => 'nav_prev')); $this->elementStart('li', array('class' => 'nav_prev'));
$this->element('a', array('href' => common_local_url($action, $newargs), 'rel' => 'prev'), $this->element('a', array('href' => common_local_url($action, $args, $pargs),
'rel' => 'prev'),
_('After')); _('After'));
$this->elementEnd('li'); $this->elementEnd('li');
} }
if ($have_after) { if ($have_after) {
$pargs = array('page' => $page+1); $pargs = array('page' => $page+1);
$newargs = $args ? array_merge($args, $pargs) : $pargs;
$this->elementStart('li', array('class' => 'nav_next')); $this->elementStart('li', array('class' => 'nav_next'));
$this->element('a', array('href' => common_local_url($action, $newargs), 'rel' => 'next'), $this->element('a', array('href' => common_local_url($action, $args, $pargs),
'rel' => 'next'),
_('Before')); _('Before'));
$this->elementEnd('li'); $this->elementEnd('li');
} }

View File

@ -91,4 +91,9 @@ class ClientErrorAction extends ErrorAction
$this->showPage(); $this->showPage();
} }
function title()
{
return $this->status[$this->code];
}
} }

View File

@ -188,6 +188,12 @@ foreach ($_config_files as $_config_file) {
} }
} }
function _have_config()
{
global $_have_a_config;
return $_have_a_config;
}
// XXX: Throw a conniption if database not installed // XXX: Throw a conniption if database not installed
// Fixup for laconica.ini // Fixup for laconica.ini

View File

@ -45,7 +45,7 @@ class GroupsByMembersSection extends GroupSection
{ {
function getGroups() function getGroups()
{ {
$qry = 'SELECT user_group.*, count(*) as value ' . $qry = 'SELECT user_group.id, count(*) as value ' .
'FROM user_group JOIN group_member '. 'FROM user_group JOIN group_member '.
'ON user_group.id = group_member.group_id ' . 'ON user_group.id = group_member.group_id ' .
'GROUP BY user_group.id ' . 'GROUP BY user_group.id ' .

View File

@ -45,7 +45,7 @@ class GroupsByPostsSection extends GroupSection
{ {
function getGroups() function getGroups()
{ {
$qry = 'SELECT user_group.*, count(*) as value ' . $qry = 'SELECT user_group.id, count(*) as value ' .
'FROM user_group JOIN group_inbox '. 'FROM user_group JOIN group_inbox '.
'ON user_group.id = group_inbox.group_id ' . 'ON user_group.id = group_inbox.group_id ' .
'GROUP BY user_group.id ' . 'GROUP BY user_group.id ' .

View File

@ -58,8 +58,14 @@ class GroupTagCloudSection extends TagCloudSection
function getTags() function getTags()
{ {
if (common_config('db', 'type') == 'pgsql') {
$weightexpr='sum(exp(-extract(epoch from (now() - notice_tag.created)) / %s))';
} else {
$weightexpr='sum(exp(-(now() - notice_tag.created) / %s))';
}
$qry = 'SELECT notice_tag.tag, '. $qry = 'SELECT notice_tag.tag, '.
'sum(exp(-(now() - notice_tag.created)/%s)) as weight ' . $weightexpr . ' as weight ' .
'FROM notice_tag JOIN notice ' . 'FROM notice_tag JOIN notice ' .
'ON notice_tag.notice_id = notice.id ' . 'ON notice_tag.notice_id = notice.id ' .
'JOIN group_inbox on group_inbox.notice_id = notice.id ' . 'JOIN group_inbox on group_inbox.notice_id = notice.id ' .

View File

@ -58,8 +58,14 @@ class PersonalTagCloudSection extends TagCloudSection
function getTags() function getTags()
{ {
if (common_config('db', 'type') == 'pgsql') {
$weightexpr='sum(exp(-extract(epoch from (now() - notice_tag.created)) / %s))';
} else {
$weightexpr='sum(exp(-(now() - notice_tag.created) / %s))';
}
$qry = 'SELECT notice_tag.tag, '. $qry = 'SELECT notice_tag.tag, '.
'sum(exp(-(now() - notice_tag.created)/%s)) as weight ' . $weightexpr . ' as weight ' .
'FROM notice_tag JOIN notice ' . 'FROM notice_tag JOIN notice ' .
'ON notice_tag.notice_id = notice.id ' . 'ON notice_tag.notice_id = notice.id ' .
'WHERE notice.profile_id = %d ' . 'WHERE notice.profile_id = %d ' .

View File

@ -48,10 +48,16 @@ class PopularNoticeSection extends NoticeSection
{ {
function getNotices() function getNotices()
{ {
$qry = 'SELECT notice.*, '. if (common_config('db', 'type') == 'pgsql') {
'sum(exp(-(now() - fave.modified) / %s)) as weight ' . $weightexpr='sum(exp(-extract(epoch from (now() - fave.modified)) / %s))';
} else {
$weightexpr='sum(exp(-(now() - fave.modified) / %s))';
}
$qry = 'SELECT notice.id, '.
$weightexpr . ' as weight ' .
'FROM notice JOIN fave ON notice.id = fave.notice_id ' . 'FROM notice JOIN fave ON notice.id = fave.notice_id ' .
'GROUP BY fave.notice_id ' . 'GROUP BY notice.id ' .
'ORDER BY weight DESC'; 'ORDER BY weight DESC';
$offset = 0; $offset = 0;

View File

@ -394,6 +394,8 @@ class Router
array('action' => 'showstream'), array('action' => 'showstream'),
array('nickname' => '[a-zA-Z0-9]{1,64}')); array('nickname' => '[a-zA-Z0-9]{1,64}'));
Event::handle('RouterInitialized', array($m));
return $m; return $m;
} }

View File

@ -89,4 +89,8 @@ class ServerErrorAction extends ErrorAction
$this->showPage(); $this->showPage();
} }
function title()
{
return $this->status[$this->code];
}
} }

View File

@ -81,7 +81,7 @@ function common_language()
// If there is a user logged in and they've set a language preference // If there is a user logged in and they've set a language preference
// then return that one... // then return that one...
if (common_logged_in()) { if (_have_config() && common_logged_in()) {
$user = common_current_user(); $user = common_current_user();
$user_language = $user->language; $user_language = $user->language;
if ($user_language) if ($user_language)
@ -315,6 +315,10 @@ function common_current_user()
{ {
global $_cur; global $_cur;
if (!_have_config()) {
return null;
}
if ($_cur === false) { if ($_cur === false) {
if (isset($_REQUEST[session_name()]) || (isset($_SESSION['userid']) && $_SESSION['userid'])) { if (isset($_REQUEST[session_name()]) || (isset($_SESSION['userid']) && $_SESSION['userid'])) {

View File

@ -0,0 +1 @@
BE9KrPPSJAPljm0ykS59yJQmWBFY9RPVJFhZsiF_5Wcf_tkGwf4FP2Ncjs7qGfHFCb2pv.eDr5y0zhKrF4s3ugs89DbLaA.hrbRJwglsNym5TDwDycrGw3TvjfCVmHBx4VzOZ2QzUyXBIs0T30paT6PYQfARKBdMkieKbbQ1tfl.f.ul35_kcpoXZt_lTDWFDaia2RM41uDLHJyVbCcRkqfHCLabgNeOq_MGFXGA6DjnKQx7TNyQe.2N6IyVd1quVapHn6jUOsWNkahehPMHtO72yvPpugS0UHCKBqcd.UCcbIhmtzLnKoBQAH2AJqUrmfg1XRwqFvTo6y9Z5XmDQK2hRnv97InV5he1AMIqNUotAcIrYjq5Tn42whYsznnMYhMY44UqZGoJI_ZwsSvnH6Je.AhKU3hBW9Tsmggpxgnhx_o2vhyNw2QAgPJng0FKxaevCmPnFtLntwluhxLbiTo2IiIotP4VjIVKs76hHzAsmXYuvS01OU.XB43Gmcw5yP9OUIoh5fEA1ANxOb.ba8aVxu2FdvedbOECgO6gvr.kYilrdxwwnVbHwVP6esrOiYE32dRs0_tWdgfvJfyloLjj_M5stZLEBcVfoUSQHsxX6jW5jrs4BTEHhKrxlOzdBt8f8T2E6eA9x2h7B8zK4eRtC2NBrcj1jzYCVWUT7IdbN05NZBjGYvxtmX1KRW91QwdFXgytfOINFkDk0scNCGGt4OYDzKLJ7sRBy0iKhHNfTC3noUhWf1372uXQ_yiWDWB7cTfxF9meAU3TWrTS7DjGTkwLvCVUJ43QyCxBQd1jWU6sp_VvytDeHx7cqrkNsa3JRN9dht3POqq_mVL0c5MX_XRpV8O.tPSGmfUPUrR5qnV8Z739D6PGWkOQzfzTTv6vGkf4jj1xyDEfUqr767_yL7gHeI2VlbdD2ammzwEhRK9f8ME8FbrZTTgX1OD0.v1cFULt1lew.rtCOtKf4F2MBbi90edst.TpOoUh_TvFkgKf0zgteNo2JjzrmCO.uviLCM2weGksARL70mdU6W9N932YWr6E8HbUc02S8ifSnbMpiUTHwNzMErsg7BSyRVJngGLDreBkBEIjXkNoApJR7kMPMaYVwtvjU.8wLmyFLZ.PHqqcrADTr7R50hL3UKj1mLsL19gQL3cP9J7_zJJM4Q1GDj2dPWBLhJMosUVhW8XBFPhW0aEdmgqhpsAJ_qv52xfjBeEPyPmKHu1p.1G2QEmOqFm_swbVAPHnra5zd8x4OOlHGFeL3qPLW9_LXN46chs6cOpUdYaWRzT2YuOUHHE8RDV9Mev22p7WjrbgC8hY3wK55Cpw_fCekaHcJX2jU3FPl09httjI1i5yGU04yD5MpOQF5EadbSlfjDEg8H.GoOFZcyKKDnqj_8SYdrXWq4aTqAnWgvBPh.bznvmevDgEpH.9gtzLcao4Dzmk.K0PnRgvkzyaN5IGk60TiD4Fk0u3f4bqKaPCOIKCTajbNGIasyND0J5ROtAa_IlXljCpzeEYPhSASSFV6fWmlqHFiGa2cKlLNr157MAUVQg52dJRRyid1YDcHK8ZuMc4BX8QA0olb2CDbUHKxxwv0zbIsgUTL8gvKIAPwBfF0cPfV9v6Phs1rPFXnysxdnunXnr6r6ZCN00rZeA7XbH68f.UjW0.ERGvB72kMnB8fBhfEgD22Y0ZFkwxI00UVAm5yiwkjYx86EdCpkMLBVDR1kWictX04pFLzxZK8iRflPBy74Nx2SFO19qJFnQmKEV2IN2wlrH6z14902LEI2Vuh_dVxNphr1k5mJ9x2VNGmvol.vvHmaLCufHIrOMRkAFMxeP37Mnzyk6NpxAQbdV0KwC.YTfoK9Y5knYAherlh7x8NqELX6XqutF2Lm11dikoK8Yu8u3Rkhoaef00PISV0LOb0E.D1LRjFFGzUCt5Ezcq68Tt0rFNEF1gm5Xl9Rygln_67F0KMgacpKTJ2PBIqcteyRZoRohFBRUTLkKn784KacSBsWFkogD5n7blv943wWeZFvUcKsFyYZny1WLvGEQX01kbjyaDCLDxiEQWSvlDuD.2wOra0JO5.Bo2PpPK5tbNexZDVx3k1yb48ev2UC4J4IlD6oK1KYe46Y.7NX9kDYCcdRiQOVnLJ4PSbPhDW0hcE2SNtxmFdpAf2xQOiekXY35lkuNxvebVhKuoFWxUgQmFEfreJQsC5qf_dunxGquD6u3SXnLbTg8aNWZqtR74dr3s7C5kwBK6eBGwJfkAx8Z2JKwLr5QHdISfa0wLl7aIejz5Mg_tfeATLIwW8SiIQdJiZ992Bx1k_50XQVeHOdyEc8J1Tjnkrji_ZY9PFn3AZc94wXD8erpANuJIbDIdLUp1idqF_TDtmqSK2qQgz26IkewcZnSIQnm98qxkHf9DAIbE6_GUP0ZeWqLQrn0CdhejhOPsKsovcDI7zBHMQABquMeBh9YC1.QCO9br6YmYEAV30n5IsZgl5PRiRDjkhXv8VaE.fnRNndSy7BX6kmxSmDWQfY0FvbUBWBQm7tfU3Mrk2Ojm4ALIYUZnJxl.5xj6VvD.2ZX3ug_1zo7mAiAYG_F939DMccfgCVFUcdtbF9Q9YFeC2bVMfgX5gA75nBCu5R8KopeWfTjdqZBtJoT6HxFmCSLQqIdjrxD7X2RapCI0QoDsp9xyzRZJ5NF5ygVBJqtNn2lAwFENasqFvGRSb35B.sjTQoHW5WBoBjFy5tNF1vWYJENfKRjWn5Pr0FvFdQfBKqeiWrLtStAnGrd49frviyK5VtYa.eSuRyX32SGb7.Pxo0Hf0bhER4uvPBktf3ec5UjL_xRI3eQ__F7tRiGu2tRYIUYcUkhLKAGYoDx2_gdMOXcow5W3KwtuVNtZ4UMRmuB3ccyBUzDTRWNLFISq56JXU46_v7ANub44kTLDfGuJExu.0NaOuW6isndAIYslJlcCs6NJ6j_6Ag55G.UhQFfzDKVOEt.L

View File

@ -0,0 +1 @@
bzN6aQzSJBM8jb6JDpNRvtfEMpxOC6r2ffo5VJf0ah_Q3kXs8gwvDzGy0KGHkwDDijfnJAwhb.BIcFihUZVWe.vAy2xZZN8XUMxHwc16HwCsgDyOC9sH5WzOV0dvJcVZ.9ipAgI7RuXsAvZdJv90N89iOh1WmD6QwWyzyvnu.FjQDrQH1DlGwFs3ZNzY5lsd5uYhtJ3puBXrzSmGcR68_7OEw4QzAV9SyPSHSskXF56cpH8pUey8WiQieM4X_uuKsMjQfWEUdqNb6teXDplvPDRqHwP5rC6X1_oHBiocfgWiBfUfKOXE1g5J.JtqXYIBee8ROyx3sVIc7V2I0eotZCCiCJ1k74ru2OGC9UhX__ZESGrp9b0JZGZFO6w97IL1Y3BTgVXNox8L3FcFjl11s7YcYBhc_3e3WbJA4pZzczPzd0ouZiCjUcBCZXNu6fnM6XerBbsVj584ZbPdjQ6A5TcrED8dTcFdgfMWlMu7bHsE7e0QIJYmc2g5NWeur2ovAOPVxhELrvnJ6X6Z.06vAmwdJcl4hyYRVqA.9QynHlH2dezXS5y0eKXFUzg.tHNqZboEGutLL316mZQYvwZwATZFc8iO3EuiNV3MWbiCrLX.n3nbXp82A4v7Bv.PVJoeOTmiPmq8vuxts8nUEPf7gA3j6.DmlDvfZQNx9.WNmNFps0B08hzDMvKX98.ft9.GJlftPCYCk2qHRtWm3tjB2R9O6mF6XYvOLUK7aQ4rz5oCxHwmrF.n56G07MS5GS1pjV3ByUO88PI1i_rPbim_Up0jIO5q7PqXudyFE.nG0Dc8yaExZk7PryBfSHk2yMQVXcBjy3XQBVmrIwPwKs.YUFC1qLSThfA8UNckik2xuDZKvf29xpGvHlMbH67UV5HhY5CTeqlgvapRThmfrexqaBTTPPqR.Sy3Pvr9vHX.0UC6kNCTlxW3CExrx9EipRKUvRVClNLEG6M9hm5MQkdfgmd2Dmj5DmjcrZkWOqnNfLn_mtYdoD3nK4zCk.NZwXTFlx5FVr5bOzyncalNdb77qLEH9E9R8d2KUA4Axljx29kycILhZCvy3Qz22Vz_M72lVFKQAFnGlERRS7NLu2rB00e.MNeH9aB01uj.y9UHpfjTAwOJSFEBf7yKRCkVzqFpGAQo7txlC3NRgSyI3kQtW0WeWiNzghBv8c_5iXWkXqFyRfVZUCw2qqow3BF6SDtkhXAr8d.JrprGdG67U66ZD3JB10OLmmAaDiiCr81eVOkrsz3ONdigZOlP7RrYtodAORnheCZ10SAYbaru0sKmsJx4sB41QKn79dieWs5oihI5Rr3jUzPjfYgav5jeEfUYz5qHTtmps4vVJjt9s4zueRiT8AYzg.Xv.wdC1dvBr_kpGxwrkMEZJ0QfZkH.TDWBSWyxeG9gtuKd1gy9CGQTXlLvonJWHwK9gwWZwRKIanV4gnMfWz4pvhGixzEaiRU6g9giKYHpVKe.w0cwPfSDIhbBYqrlvuxkSTXfuFNyTpHM0Mgc6PMNnH6GooeLVK3IO2M8dRdDbL7EHykIJWe85pm5BxSqFTcWXn1nGuVWQV.F.J1XYJj1KheT725MVRlrE3sH.MgY6m4hKCUXT7mIgJ6xsfAQ8dWn7V1fCpqoIYub55iw_dg8yfZ7Yfgwj9bqN81lvTWQzBMLKYpG6pOh37JsTikpXa9kTSJfbJm0_GYZv_Bu10D1WqiO0UCvJXrlqkl5F610fkXkhwRXvmIQL2Mv_R71zSKqMr1g5RmnNifUv43jpXoOWmOKscg59pv8eOyb2JG26BtyVS2XOTDw6pHpHKuksqRKt62i1z83uv_ve5rO0zIKeMnWGlvXKHn8ld3fqGyJvqZ7wqYpnV_LTE3p73XCLEeniClXyk5Q_Icu1PgakYh3GIz8RVBjbjgrZIsvvkEp0Kgeo6oFY0wnboIwDlaUVHIue1nPkuAIsVk9i_IJWeqoRV0eO0wUGWgQ5.HT9RzcKdFVe2kl84RKuQkvoibiCfGlfTXpOfLOZtwsfl2TuNgZtP5oG1Wfsgi6g2a1N8B2WHYN8kZuG8pMnc4NQDIoO8BDnz89lDt7Y9JCslIM3O2Y25EGsylNKamKPJZr.ZSvvTVJG5sxftLxvF8vc8h5_pJD9Akj.84CjqQyfsnzFqc_.EqBaRVSy35wHHrdWTBsvjcobtSed8wXs.5En6HdubdATcgthozHWMEMsUdA29XkenPic2cR.8bQ5VdGZ2_YkJIXrxgt_XoEFFB8tgy061cghyL2fc2fHMQm4KBEc1vjkZjwRo9adWbg9dzAl782AwKC.C72bw--