OSDN Git Service

Model::LegacyDB: add 'getCurrentStatic' method
authorhylom <hylom@users.sourceforge.jp>
Mon, 24 Oct 2016 18:15:45 +0000 (03:15 +0900)
committerhylom <hylom@users.sourceforge.jp>
Mon, 24 Oct 2016 18:15:45 +0000 (03:15 +0900)
src/newslash_web/lib/Newslash/Model/LegacyDB.pm

index cb21230..bb819ec 100644 (file)
@@ -4,6 +4,432 @@ use Newslash::Model::Base -base;
 ## WORNING:
 ## This is legacy from slash. deprecated, and you can use only backword-compatible.
 
+#========================================================================
+
+=head2 dbAvailable([TOKEN])
+
+Returns TRUE if (as usual) the DB(s) are available for reading and
+writing.  Returns FALSE if the DB(s) are not available and should not
+be accessed.  If a TOKEN is named, return FALSE if either the DB(s)
+required for that purpose are down or all DBs are down.  If no TOKEN is
+named, return FALSE only if all DBs are down.
+
+Whether or not the DBs are down is determined only by whether files exist
+at /usr/local/slash/dboff or /usr/local/slash/dboff_TOKEN.  For best
+results, admins will want to write their own db-angel scripts that detect
+DBs having gone down and create one or more of those files.
+
+=over 4
+
+=item Parameters
+
+=over 4
+
+=item TOKEN
+
+Name of the resource specifically being asked about, or the
+empty string.
+
+=back
+
+=item Return value
+
+0 or 1.
+
+=back
+
+=cut
+
+sub dbAvailable {
+    return 1;
+}
+
+#========================================================================
+
+=head2 getCurrentStatic([MEMBER])
+
+Returns the current static variables (or variable).
+
+Slash's original implement was depended to Apache and memcached,
+but this implement uses redis for cache.
+
+And in this implement, this function is method.
+
+=over 4
+
+=item Parameters
+
+=over 4
+
+=item MEMBER
+
+A member from the static record to be returned.
+
+=back
+
+=item Return value
+
+A hash reference with the static information is returned unless MEMBER is passed. If
+MEMBER is passed in then only its value will be returned.
+
+=back
+
+=cut
+
+sub getCurrentStatic {
+    my ($self, $value, $force_secure) = @_;
+    my $kvs = $self->connect_kvs;
+    my $kvs_key = "slash_static";
+    my $constants;
+
+    if ($kvs->exists($kvs_key)) {
+        $constants = $kvs->hgetall($kvs_key);
+    }
+    else {
+        $constants = $self->getSlashConf(0, 0);
+        $kvs->hmset($kvs_key, $constants);
+    }
+
+    return defined $value ? $constants->{$value} : $constants;
+}
+
+########################################################
+sub _getSlashConf_rawvars {
+       my($self, $secure, $skipcache) = @_;
+       $secure = $secure ? 1 : 0;
+#      my $vu = $self->{virtual_user};
+#      return undef unless $vu;
+#      my $mcd = $self->getMCD({ no_getcurrentstatic => 1 });
+#      my $mcdkey= "x:vars$secure";
+#      my $got_from_memcached = 0;
+       my $vars_hr;
+#      if ($mcd && !$skipcache) {
+#              if ($vars_hr = $mcd->get($mcdkey)) {
+#                      $got_from_memcached = 1;
+#              }
+#      }
+       $vars_hr ||= $self->sqlSelectAllKeyValue('name, value', 'vars');
+#      if ($mcd && !$got_from_memcached) {
+#              # Cache this for about 3 minutes.   should be a var.
+#              my $expire_time = 180;
+#              $mcd->set($mcdkey, $vars_hr, $expire_time);
+#      }
+       return $vars_hr;
+}
+
+########################################################
+# Now, the idea is to not cache here, since we actually
+# cache elsewhere (namely in %Slash::Apache::constants) - Brian
+# I'm caching this in memcached now though. - Jamie
+sub getSlashConf {
+       my($self, $secure, $skipcache) = @_;
+
+       # Get the raw vars data (possibly from a memcached cache).
+
+       my $vars_hr = $self->_getSlashConf_rawvars($secure, $skipcache);
+       return if !defined $vars_hr;
+       my %conf = %$vars_hr;
+
+       # Now start adding and tweaking the data for various reasons:
+       # convenience, fixing bad data, etc.
+
+       # This allows you to do stuff like constant.plugin.Zoo in a template
+       # and know that the plugin is installed -Brian
+       my $plugindata = $self->sqlSelectColArrayref('value', 'site_info',
+               "name='plugin'");
+       for my $plugin (@$plugindata) {
+               $conf{plugin}{$plugin} = 1;
+       }
+       my $tagboxdata = $self->sqlSelectColArrayref('value', 'site_info',
+               "name='tagbox'");
+       for my $tagbox (@$tagboxdata) {
+               $conf{tagbox}{$tagbox} = 1;
+       }
+
+       # This really should be a separate piece of data returned by
+       # getReasons() the same way getTopicTree() works.  It's only part
+       # of $constants for historical, er, reasons.
+       if ($conf{m1}) {
+               $conf{reasons} = $self->sqlSelectAllHashref(
+                       "id", "*", "modreasons"
+               );
+               $conf{reasons_base} = $self->sqlSelectAllHashref(
+                       "id", "*", "modreasons", "m2able = 1 OR val = 0"
+               );
+               $conf{reasons_plused} = $self->sqlSelectAllHashref(
+                       "id", "*", "modreasons", "m2able = 1 OR val <= 0"
+               );
+               $conf{reasons_minused} = $self->sqlSelectAllHashref(
+                       "id", "*", "modreasons", "m2able = 1 OR val >= 0"
+               );
+               foreach my $d (split(/,/, $conf{modreasons_select_disabled} || '')) {
+                       $conf{reasons}{int($d)}{select_disabled} = 1;
+                       $conf{reasons_base}{int($d)}{select_disabled} = 1;
+                       $conf{reasons_plused}{int($d)}{select_disabled} = 1;
+                       $conf{reasons_minused}{int($d)}{select_disabled} = 1;
+               }
+       }
+
+       $conf{rootdir}          ||= "//$conf{basedomain}";
+       $conf{real_rootdir}     ||= $conf{rootdir};  # for when rootdir changes
+       $conf{real_section}     ||= $conf{section};  # for when section changes
+       $conf{absolutedir}      ||= "http://$conf{basedomain}";
+       $conf{imagedir}         ||= "$conf{rootdir}/images";
+               # If absolutedir_secure is not defined, it defaults to the
+               # same as absolutedir.  Same for imagedir_secure.
+       $conf{absolutedir_secure} ||= $conf{absolutedir};
+       $conf{imagedir_secure}  ||= $conf{imagedir};
+       $conf{css_extension}      = 'css';
+#      if (defined &Slash::Apache::ConnectionIsSSL && Slash::Apache::ConnectionIsSSL())
+       if ($secure) {
+               # On Secure HTTP connections, force absolutedir/imagedir to
+               # be the secure versions.
+               $conf{imagedir} = $conf{imagedir_secure};
+               $conf{absolutedir} = $conf{absolutedir_secure};
+               $conf{css_extension} = 'ssl.css';
+       }
+       $conf{cssdir}           ||= $conf{css_use_imagedir} ? $conf{imagedir} : $conf{rootdir};
+       $conf{rdfimg}           ||= "$conf{imagedir}/topics/topicslash.gif";
+       $conf{adminmail_mod}    ||= $conf{adminmail};
+       $conf{adminmail_post}   ||= $conf{adminmail};
+       $conf{adminmail_ban}    ||= $conf{adminmail};
+       $conf{basedir}          ||= "$conf{datadir}/public_html";
+       $conf{index_handler}    ||= 'index.pl';
+       $conf{cookiepath}       ||= URI->new($conf{rootdir})->path . '/';
+       $conf{maxkarma}           =  999 unless defined $conf{maxkarma};
+       $conf{minkarma}           = -999 unless defined $conf{minkarma};
+       $conf{expiry_exponent}    = 1 unless defined $conf{expiry_exponent};
+       $conf{panic}            ||= 0;
+       $conf{textarea_rows}    ||= 10;
+       $conf{textarea_cols}    ||= 50;
+       $conf{allow_deletions}  ||= 1;
+       $conf{authors_unlimited}  = 100 if !defined $conf{authors_unlimited}
+               || $conf{authors_unlimited} == 1;
+               # m2_consensus must be odd
+       $conf{m2_consensus}       = 2*int(($conf{m2_consensus} || 5)/2) + 1
+               if !$conf{m2_consensus}
+                  || ($conf{m2_consensus}-1)/2 != int(($conf{m2_consensus}-1)/2);
+       $conf{nick_chars}       ||= q{ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_.+!*'(),-};
+       $conf{nick_maxlen}      ||= 20;
+       $conf{cookie_location}  ||= 'classbid';
+       $conf{login_temp_minutes} ||= 10;
+       # For all fields that it is safe to default to -1 if their
+       # values are not present...
+       for (qw[min_expiry_days max_expiry_days min_expiry_comm max_expiry_comm]) {
+               $conf{$_}       = -1 unless exists $conf{$_};
+       }
+
+       # no trailing newlines on directory variables
+       # possibly should rethink this for basedir,
+       # since some OSes don't use /, and if we use File::Spec
+       # everywhere this won't matter, but still should be do
+       # it for the others, since they are URL paths
+       # -- pudge
+       for (qw[rootdir absolutedir imagedir imagedir_secure basedir]) {
+               $conf{$_} =~ s|/+$||;
+       }
+
+       my $fixup = sub {
+               return [ ] if !$_[0];
+               [
+                       map {(
+                               s/^\s+//,
+                               s/\s+$//,
+                               $_
+                       )[-1]}
+                       split /\|/, $_[0]
+               ];
+       };
+       my $fixup_hash = sub {
+               my $ar = $fixup->(@_);
+               my $hr = { };
+               return $hr if !$ar;
+               for my $str (@$ar) {
+                       my($k, $v) = split(/=/, $str);
+                       $v = 1 if !defined($v);
+                       $v = [ split ",", $v ] if $v =~ /,/;
+                       $hr->{$k} = $v;
+               }
+               $hr;
+       };
+
+       my %conf_fixup_arrays = (
+               # var name                      # default array value
+               # --------                      # -------------------
+               anonymous_coward_uids =>        [ $conf{anonymous_coward_uid} ],
+                                               # See <http://www.iana.org/assignments/uri-schemes>
+               approved_url_schemes =>         [qw( ftp http gopher mailto news nntp telnet wais https )],
+               approvedtags =>                 [qw( b i p br a ol ul li dl dt dd em strong tt blockquote div ecode quote)],
+               approvedtags_break =>           [qw(     p br   ol ul li dl dt dd              blockquote div             img hr )],
+               # all known tags, plus table, pre, and slash; this can be overridden
+               # in vars, but since we make this all known tags by default ...
+               # easier to just keep it in here
+               approvedtags_admin =>           [qw( b i p br a ol ul li dl dt dd em strong tt blockquote div ecode
+                                                    img hr big small sub sup span
+                                                    dfn code samp kbd var cite address ins del
+                                                    h1 h2 h3 h4 h5 h6
+                                                    table thead tbody tfoot tr th td pre
+                                                    slash
+                                               )],
+               charrefs_bad_entity =>          [qw( zwnj zwj lrm rlm )],
+               charrefs_bad_numeric =>         [qw( 8204 8205 8206 8207 8236 8237 8238 )],
+               charrefs_good_entity =>         [qw( amp lt gt euro pound yen rsquo lsquo rdquo ldquo ndash mdash )],
+               charrefs_good_numeric =>        [ ],
+               cur_performance_stat_ops =>     [ ],
+               firehose_story_ignore_skids =>  [ ],
+               fixhrefs =>                     [ ],
+               hc_possible_fonts =>            [ ],
+               lonetags =>                     [ ],
+               m2_sliding_consensus =>         [ ],
+               op_exclude_from_countdaily =>   [qw( rss )],
+               op_extras_countdaily =>         [ ],
+               mod_stats_reports =>            [ $conf{adminmail_mod} ],
+               stats_reports =>                [ $conf{adminmail} ],
+               stats_metrics_reports =>        [ $conf{adminmail} ],
+               stats_sfnet_groupids =>         [ 4421 ],
+               submit_categories =>            [ ],
+               skins_recenttopics =>           [ ],
+               subnet_karma_post_limit_range => [ ],
+               search_ignore_skids =>          [ ],
+       );
+       my %conf_fixup_hashes = (
+               # var name                      # default hash of keys/values
+               # --------                      # --------------------
+               ad_messaging_sections =>        { },
+               comments_perday_bykarma =>      {  -1 => 2,             25 => 25,       99999 => 50          },
+               karma_adj =>                    { -10 => 'Terrible',    -1 => 'Bad',        0 => 'Neutral',
+                                                  12 => 'Positive',    25 => 'Good',   99999 => 'Excellent' },
+               mod_up_points_needed =>         { },
+                                               #          m2_f_t m2_u_t  m1_t m1_k
+               m2_consequences =>              { 0.00 => [qw( -5    +2   -100 -1   )],
+                                                 0.15 => [qw( -2    +1    -40 -1   )],
+                                                 0.30 => [qw( -0.5  +0.5  -20  0   )],
+                                                 0.35 => [qw(  0     0    -10  0   )],
+                                                 0.49 => [qw(  0     0     -4  0   )],
+                                                 0.60 => [qw(  0     0     +1  0   )],
+                                                 0.70 => [qw(  0     0     +2  0   )],
+                                                 0.80 => [qw( +0.01 -1     +3  0   )],
+                                                 0.90 => [qw( +0.02 -2     +4  0   )],
+                                                 1.00 => [qw( +0.05 -5     +5 +0.5 )], },
+               m2_consequences_repeats =>      { 3 => -4, 5 => -12, 10 => -100 },
+               # 40=0|30=Mainpage|20=0|10=Sectional|0=0
+               topic_popup_weights     =>      { 40 => 0, 30 => 'Mainpage', 20 => 0, 10 => 'Sectional', 0 => 0 },
+       );
+       for my $key (keys %conf_fixup_arrays) {
+               if (defined($conf{$key})) {
+                       $conf{$key} = $fixup->($conf{$key});
+               } else {
+                       $conf{$key} = $conf_fixup_arrays{$key};
+               }
+       }
+       for my $key (keys %conf_fixup_hashes) {
+               if (defined($conf{$key})) {
+                       $conf{$key} = $fixup_hash->($conf{$key});
+               } else {
+                       $conf{$key} = $conf_fixup_hashes{$key};
+               }
+       }
+
+       for my $var (qw(email_domains_invalid submit_domains_invalid)) {
+               if ($conf{$var}) {
+                       my $regex = sprintf('[^\w-](?:%s)$',
+                               join '|', map quotemeta, split ' ', $conf{$var});
+                       $conf{$var} = qr{$regex};
+               }
+       }
+
+       if ($conf{comment_nonstartwordchars}) {
+               # Expand this into a complete regex.  We catch not only
+               # these chars in their raw form, but also all HTML entities
+               # (because Windows/MSIE refuses to break before any word
+               # that starts with either the chars, or their entities).
+               # Build the regex with qr// and match entities for
+               # optimal speed.
+               my $src = $conf{comment_nonstartwordchars};
+               my @chars = ( );
+               my @entities = ( );
+               for my $i (0..length($src)-1) {
+                       my $c = substr($src, $i, 1);
+                       push @chars, "\Q$c";
+                       push @entities, ord($c);
+                       push @entities, sprintf("x%x", ord($c));
+               }
+               my $dotchar =
+                       '(?:'
+                               . '[' . join("", @chars) . ']'
+                               . '|&#(?:' . join("|", @entities) . ');'
+                       . ')';
+               my $regex = '(\s+)' . "((?:<[^>]+>)*$dotchar+)" . '(\S)';
+               $conf{comment_nonstartwordchars_regex} = qr{$regex}i;
+       }
+
+       for my $regex (qw(
+               accesslog_imageregex
+               x_forwarded_for_trust_regex
+               lowbandwidth_bids_regex
+       )) {
+               next if !$conf{$regex} || $conf{$regex} eq 'NONE';
+               $conf{$regex} = qr{$conf{$regex}};
+       }
+
+       # anchor
+       for my $regex (qw(
+               feed_types
+       )) {
+               next if !$conf{$regex};
+               $conf{$regex} = qr{^(?:$conf{$regex})$};
+       }
+
+
+       for my $var (qw(approvedtags approvedtags_break lonetags)) {
+               $conf{$var} = [ map lc, @{$conf{$var}} ];
+       }
+
+       for my $attrname (qw(approvedtags_attr approvedtags_attr_admin)) {
+               if ($conf{$attrname}) {
+                       my $approvedtags_attr = $conf{$attrname};
+                       $conf{$attrname} = {};
+                       my @tags = split /\s+/, $approvedtags_attr;
+                       foreach my $tag (@tags){
+                               my($tagname, $attr_info) = $tag =~ /([^:]*)(?:\:(.*))?$/;
+                               my @attrs = split ',', ($attr_info || '');
+                               my $ord = 1;
+                               foreach my $attr (@attrs){
+                                       my($at, $extra) = split /_/, $attr;
+                                       $extra ||= '';
+                                       $at = lc $at;
+                                       $tagname = lc $tagname;
+                                       $conf{$attrname}{$tagname}{$at}{ord} = $ord;
+                                       $conf{$attrname}{$tagname}{$at}{req} = 1 if $extra =~ /R/;
+                                       $conf{$attrname}{$tagname}{$at}{req} = 2 if $extra =~ /N/; # "necessary"
+                                       $conf{$attrname}{$tagname}{$at}{url} = 1 if $extra =~ /U/;
+                                       $ord++;
+                               }
+                       }
+               }
+       }
+       if ($conf{approvedtags_attr} && $conf{approvedtags_attr_admin}) {
+               for (keys %{$conf{approvedtags_attr}}) {
+                       # only add to _admin if not already in it
+                       $conf{approvedtags_attr_admin}{$_} ||= $conf{approvedtags_attr}{$_};
+               }
+       }
+
+       # We only need to do this on startup.  This var isn't really used;
+       # see the code comment in getObject().
+       $conf{classes} = $self->getClasses();
+
+       if ($conf{utf8}) {
+               foreach my $k (keys %conf) {
+                       next if ref($conf{$k}) ne 'SCALAR' || Encode::is_utf8($conf{$k});
+                       Encode::_utf8_on($conf{$k});
+               }
+       }
+
+       return \%conf;
+}
+
+
 sub sqlConnect {
     my ($self, $restart) = @_;
     if ($restart) {
@@ -185,5 +611,4 @@ sub sqlGetCharColumnLength {
 }
 } # end closure
 
-
 1;