Move OS and Platform guessing regexps into DB and allow to edit them

hinted-selects
Vitaliy Filippov 2014-07-25 14:44:48 +04:00
parent 689fc81b45
commit 620531c4b9
10 changed files with 158 additions and 274 deletions

View File

@ -65,8 +65,23 @@ use constant ISOLATION_LEVEL => 'REPEATABLE READ';
use constant ENUM_DEFAULTS => {
bug_severity => [qw(blocker critical major normal minor trivial enhancement)],
priority => [qw(Highest High Normal Low Lowest)],
op_sys => [qw(All Windows Mac OS Linux Other)],
rep_platform => [qw(All PC Macintosh Other)],
op_sys => [
{ value => 'All', ua_regex => '' },
{ value => 'Windows', ua_regex => '\(.*(Windows|Win.*9[8x].*4\.9|Win(?:dows |)(M[Ee]|98|95|16)|Win(?:dows[ -]|)NT|WinMosaic).*\)' },
{ value => 'MacOS', ua_regex => '\(.*(Mac OS (X|9|8)|Darwin|PowerPC|PPC|68k).*\)' },
{ value => 'Android', ua_regex => '\(.*Android.*\)' },
{ value => 'iOS', ua_regex => '\(.*(iPod|iPad|iPhone).*\)' },
{ value => 'Linux', ua_regex => '\(.*Linux.*\)' },
{ value => 'BSD', ua_regex => '\(.*BSD.*\)' },
{ value => 'Other', ua_regex => '\(.*(Solaris|SunOS|IRIX|OSF|BeOS|AIX|OS/2|QNX|VMS|HP-?UX|Amiga).*\)' },
],
rep_platform => [
{ value => 'All', ua_regex => '' },
{ value => 'PC', ua_regex => '\(.*([ix0-9]86 (?:on |\()x86_64|amd64|x86_64|IA64|Intel|[ix0-9]86|Win(?:dows |)[39M]|Win(?:dows |)16|WOW64|Win64|WinMosaic|Win(?:dows[ -])NT).*\)|\(Win.*\)' },
{ value => 'ARM', ua_regex => '\(.*(iPod|iPad|iPhone|ARM|Android|Windows CE).*\)' },
{ value => 'PowerPC', ua_regex => '\(.*(PowerPC|68K|680[x0]0|AIX|Macintosh|Mac OS [89]).*\)' },
{ value => 'Other', ua_regex => '\(.*(sparc|sun4|AXP|IRIX|MIPS|9000|OSF|HP-?UX|SunOS|Solaris).*\)|\(.*[ _]Alpha.\D|\(.*[ _]Alpha\)|Amiga' },
],
bug_status => [qw(UNCONFIRMED NEW ASSIGNED REOPENED RESOLVED VERIFIED CLOSED)],
resolution => [qw(FIXED INVALID WONTFIX DUPLICATE WORKSFORME MOVED)],
};
@ -465,8 +480,7 @@ sub bz_check_regexp
eval { $self->do("SELECT " . $self->sql_regexp($self->quote("a"), $pattern, 1)) };
$@ && ThrowUserError('illegal_regexp',
{ value => $pattern, dberror => $self->errstr });
$@ && ThrowUserError('illegal_regexp', { value => $pattern, dberror => $self->errstr });
}
#####################################################################
@ -479,7 +493,7 @@ sub bz_setup_database {
# If we haven't ever stored a serialized schema,
# set up the bz_schema table and store it.
$self->_bz_init_schema_storage();
my @desired_tables = $self->_bz_schema->get_table_list();
foreach my $table_name (@desired_tables) {
@ -487,17 +501,30 @@ sub bz_setup_database {
}
}
# This really just exists to get overridden in Bugzilla::DB::Mysql.
sub bz_enum_initial_values {
return ENUM_DEFAULTS;
}
sub bz_populate_enum_tables {
sub bz_populate_enum_tables
{
my ($self) = @_;
my $enum_values = $self->bz_enum_initial_values();
while (my ($table, $values) = each %$enum_values) {
$self->_bz_populate_enum_table($table, $values);
my $enum_values = ENUM_DEFAULTS();
while (my ($table, $values) = each %$enum_values)
{
# Check if there are any table entries
my ($table_size) = $self->selectrow_array("SELECT COUNT(*) FROM $table");
# If the table is empty...
if (!$table_size)
{
print "Populating '$table' table:\n";
$values = [ map { { value => $_ } } @$values ] if !ref $values->[0];
my $sortorder = 0;
$_->{sortkey} = $sortorder += 100 for @$values;
my @keys = keys %{$values->[0]};
$self->do(
"INSERT INTO $table (".join(', ', @keys).") VALUES ".
join(', ', ("(".join(', ', ('?') x @keys).")") x @$values),
undef, map { @$_{@keys} } @$values
);
}
}
}
@ -1361,30 +1388,6 @@ sub _bz_store_real_schema {
$sth->execute();
}
# For bz_populate_enum_tables
sub _bz_populate_enum_table {
my ($self, $table, $valuelist) = @_;
my $sql_table = $self->quote_identifier($table);
# Check if there are any table entries
my $table_size = $self->selectrow_array("SELECT COUNT(*) FROM $sql_table");
# If the table is empty...
if (!$table_size) {
my $insert = $self->prepare(
"INSERT INTO $sql_table (value,sortkey) VALUES (?,?)");
print "Inserting values into the '$table' table:\n";
my $sortorder = 0;
my $maxlen = max(map(length($_), @$valuelist)) + 2;
foreach my $value (@$valuelist) {
$sortorder += 100;
printf "%-${maxlen}s sortkey: $sortorder\n", "'$value'";
$insert->execute($value, $sortorder);
}
}
}
# This is used before adding a foreign key to a column, to make sure
# that the database won't fail adding the key.
sub _check_references {

View File

@ -912,39 +912,6 @@ sub bz_db_is_utf8 {
return $db_collation->[1] =~ /utf8/ ? 1 : 0;
}
sub bz_enum_initial_values {
my ($self) = @_;
my %enum_values = %{$self->ENUM_DEFAULTS};
# Get a complete description of the 'bugs' table; with DBD::MySQL
# there isn't a column-by-column way of doing this. Could use
# $dbh->column_info, but it would go slower and we would have to
# use the undocumented mysql_type_name accessor to get the type
# of each row.
my $sth = $self->prepare("DESCRIBE bugs");
$sth->execute();
# Look for the particular columns we are interested in.
while (my ($thiscol, $thistype) = $sth->fetchrow_array()) {
if (defined $enum_values{$thiscol}) {
# this is a column of interest.
my @value_list;
if ($thistype and ($thistype =~ /^enum\(/)) {
# it has an enum type; get the set of values.
while ($thistype =~ /'([^']*)'(.*)/) {
push(@value_list, $1);
$thistype = $2;
}
}
if (@value_list) {
# record the enum values found.
$enum_values{$thiscol} = \@value_list;
}
}
}
return \%enum_values;
}
#####################################################################
# MySQL-specific Database-Reading Methods
#####################################################################

View File

@ -675,7 +675,10 @@ use constant ABSTRACT_SCHEMA => {
},
rep_platform => {
FIELDS => dclone(FIELD_TABLE_SCHEMA->{FIELDS}),
FIELDS => [
@{ dclone(FIELD_TABLE_SCHEMA->{FIELDS}) },
ua_regex => {TYPE => 'VARCHAR(255)'},
],
INDEXES => [
rep_platform_value_idx => {FIELDS => ['value'], TYPE => 'UNIQUE'},
rep_platform_sortkey_idx => ['sortkey', 'value'],
@ -683,7 +686,10 @@ use constant ABSTRACT_SCHEMA => {
},
op_sys => {
FIELDS => dclone(FIELD_TABLE_SCHEMA->{FIELDS}),
FIELDS => [
@{ dclone(FIELD_TABLE_SCHEMA->{FIELDS}) },
ua_regex => {TYPE => 'VARCHAR(255)'},
],
INDEXES => [
op_sys_value_idx => {FIELDS => ['value'], TYPE => 'UNIQUE'},
op_sys_sortkey_idx => ['sortkey', 'value'],

View File

@ -54,6 +54,8 @@ use constant CLASS_MAP => {
version => 'Bugzilla::Version',
target_milestone => 'Bugzilla::Milestone',
classification => 'Bugzilla::Classification',
op_sys => 'Bugzilla::OS',
rep_platform => 'Bugzilla::Platform',
};
use constant DEFAULT_MAP => { reverse %{ Bugzilla::Config::BugFields::DEFAULTNAMES() } };

View File

@ -796,8 +796,8 @@ WHERE description LIKE\'%[CC:%\'');
}
# Add is_assigned and is_confirmed columns to bug_status table
$dbh->bz_add_column('bug_status', is_assigned => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
$dbh->bz_add_column('bug_status', is_confirmed => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
$dbh->bz_add_column('bug_status', 'is_assigned');
$dbh->bz_add_column('bug_status', 'is_confirmed');
$dbh->do('UPDATE bug_status SET is_assigned=0 WHERE NOT value=?', undef, 'ASSIGNED');
$dbh->do('UPDATE bug_status SET is_confirmed=0 WHERE value=?', undef, 'UNCONFIRMED');
@ -849,6 +849,21 @@ WHERE description LIKE\'%[CC:%\'');
# Revert 4.4 quips.quip varchar(512) change
$dbh->bz_alter_column('quips', 'quip', { TYPE => 'MEDIUMTEXT', NOTNULL => 1 });
# Add ua_regex field to op_sys and rep_platform
if (!$dbh->bz_column_info('op_sys', 'ua_regex'))
{
$dbh->bz_add_column('op_sys', 'ua_regex');
$dbh->bz_add_column('rep_platform', 'ua_regex');
for (@{Bugzilla::DB->ENUM_DEFAULTS->{op_sys}})
{
$dbh->do('UPDATE op_sys SET ua_regex=? WHERE value=?', undef, $_->{ua_regex}, $_->{value});
}
for (@{Bugzilla::DB->ENUM_DEFAULTS->{rep_platform}})
{
$dbh->do('UPDATE rep_platform SET ua_regex=? WHERE value=?', undef, $_->{ua_regex}, $_->{value});
}
}
################################################################
# New --TABLE-- changes should go *** A B O V E *** this point #
################################################################
@ -4192,7 +4207,8 @@ sub _set_varchar_255
$abs = { @{$abs->{FIELDS} || []} };
for my $f (keys %$abs)
{
if (lc $abs->{$f}->{TYPE} eq 'varchar(255)' &&
if ($r->{$f} &&
lc $abs->{$f}->{TYPE} eq 'varchar(255)' &&
lc $r->{$f}->{TYPE} ne 'varchar(255)')
{
$started ||= (print "-- Raising length limit for all VARCHARs to 255 --\n");

28
Bugzilla/OS.pm Normal file
View File

@ -0,0 +1,28 @@
#!/usr/bin/perl
# Value of 'operating system' field
# License: Dual-license GPL 3.0+ or MPL 1.1+
# Contributor(s): Vitaliy Filippov <vitalif@mail.ru>
package Bugzilla::OS;
use strict;
use base qw(Bugzilla::Field::Choice);
use constant DB_TABLE => 'op_sys';
use constant FIELD_NAME => 'op_sys';
use constant DB_COLUMNS => (Bugzilla::Field::Choice->DB_COLUMNS, 'ua_regex');
use constant UPDATE_COLUMNS => (Bugzilla::Field::Choice->UPDATE_COLUMNS, 'ua_regex');
sub ua_regex
{
return $_[0]->{ua_regex};
}
sub set_ua_regex
{
return $_[0]->set('ua_regex', $_[1]);
}
1;
__END__

28
Bugzilla/Platform.pm Normal file
View File

@ -0,0 +1,28 @@
#!/usr/bin/perl
# Value of 'platform' field
# License: Dual-license GPL 3.0+ or MPL 1.1+
# Contributor(s): Vitaliy Filippov <vitalif@mail.ru>
package Bugzilla::Platform;
use strict;
use base qw(Bugzilla::Field::Choice);
use constant DB_TABLE => 'rep_platform';
use constant FIELD_NAME => 'rep_platform';
use constant DB_COLUMNS => (Bugzilla::Field::Choice->DB_COLUMNS, 'ua_regex');
use constant UPDATE_COLUMNS => (Bugzilla::Field::Choice->UPDATE_COLUMNS, 'ua_regex');
sub ua_regex
{
return $_[0]->{ua_regex};
}
sub set_ua_regex
{
return $_[0]->set('ua_regex', $_[1]);
}
1;
__END__

View File

@ -144,8 +144,10 @@ Bugzilla::DB::bz_create_database() if $lc_hash->{'db_check'};
# now get a handle to the database:
my $dbh = Bugzilla->dbh;
# Create the tables, and do any database-specific schema changes.
$dbh->bz_setup_database();
# Populate the tables that hold the values for the <select> fields.
$dbh->bz_populate_enum_tables();

View File

@ -181,208 +181,31 @@ else
# to enter a bug against this product.
$user->can_enter_product($product ? $product->name : $product_name, THROW_ERROR);
# Takes the name of a field and a list of possible values for that
# field. Returns the first value in the list that is actually a
# valid value for that field.
# The field should be named after its DB table.
# Returns undef if none of the platforms match.
sub pick_valid_field_value (@)
sub pick_by_ua
{
my ($field, @values) = @_;
my $dbh = Bugzilla->dbh;
foreach my $value (@values)
my ($ARGS, $field) = @_;
return $ARGS->{$field} if $ARGS->{$field};
$field = Bugzilla->get_field($field);
if (my $id = $field->default_value)
{
return $value if $dbh->selectrow_array("SELECT 1 FROM $field WHERE value = ?", undef, $value);
my ($v) = grep { $_->id == $id } @{ $field->legal_values };
return $v->name if $v;
}
else
{
my $ua = $ENV{HTTP_USER_AGENT};
for my $v (@{ $field->legal_values })
{
my $re = $v->ua_regex;
if ($re && $ua =~ /$re/i)
{
return $v->name;
}
}
}
return undef;
}
# FIXME Regexps for platform and operating system should be stored in the database,
# probably in a property of Platform/OpSys objects.
sub pickplatform
{
my ($ARGS) = @_;
return $ARGS->{rep_platform} if $ARGS->{rep_platform};
my @platform;
if (Bugzilla->params->{defaultplatform})
{
@platform = Bugzilla->params->{defaultplatform};
}
else
{
# If @platform is a list, this function will return the first
# item in the list that is a valid platform choice. If
# no choice is valid, we return "Other".
for ($ENV{HTTP_USER_AGENT})
{
# PowerPC
/\(.*PowerPC.*\)/i && do {push @platform, ("PowerPC", "Macintosh");};
# AMD64, Intel x86_64
/\(.*amd64.*\)/ && do {push @platform, ("AMD64", "x86_64", "PC");};
/\(.*x86_64.*\)/ && do {push @platform, ("AMD64", "x86_64", "PC");};
# Intel Itanium
/\(.*IA64.*\)/ && do {push @platform, "IA64";};
# Intel x86
/\(.*Intel.*\)/ && do {push @platform, ("IA32", "x86", "PC");};
/\(.*[ix0-9]86.*\)/ && do {push @platform, ("IA32", "x86", "PC");};
# Versions of Windows that only run on Intel x86
/\(.*Win(?:dows |)[39M].*\)/ && do {push @platform, ("IA32", "x86", "PC");};
/\(.*Win(?:dows |)16.*\)/ && do {push @platform, ("IA32", "x86", "PC");};
# Sparc
/\(.*sparc.*\)/ && do {push @platform, ("Sparc", "Sun");};
/\(.*sun4.*\)/ && do {push @platform, ("Sparc", "Sun");};
# Alpha
/\(.*AXP.*\)/i && do {push @platform, ("Alpha", "DEC");};
/\(.*[ _]Alpha.\D/i && do {push @platform, ("Alpha", "DEC");};
/\(.*[ _]Alpha\)/i && do {push @platform, ("Alpha", "DEC");};
# MIPS
/\(.*IRIX.*\)/i && do {push @platform, ("MIPS", "SGI");};
/\(.*MIPS.*\)/i && do {push @platform, ("MIPS", "SGI");};
# 68k
/\(.*68K.*\)/ && do {push @platform, ("68k", "Macintosh");};
/\(.*680[x0]0.*\)/ && do {push @platform, ("68k", "Macintosh");};
# HP
/\(.*9000.*\)/ && do {push @platform, ("PA-RISC", "HP");};
# ARM
/\(.*ARM.*\)/ && do {push @platform, ("ARM", "PocketPC");};
# PocketPC intentionally before PowerPC
/\(.*Windows CE.*PPC.*\)/ && do {push @platform, ("ARM", "PocketPC");};
# PowerPC
/\(.*PPC.*\)/ && do {push @platform, ("PowerPC", "Macintosh");};
/\(.*AIX.*\)/ && do {push @platform, ("PowerPC", "Macintosh");};
# Stereotypical and broken
/\(.*Windows CE.*\)/ && do {push @platform, ("ARM", "PocketPC");};
/\(.*Macintosh.*\)/ && do {push @platform, ("68k", "Macintosh");};
/\(.*Mac OS [89].*\)/ && do {push @platform, ("68k", "Macintosh");};
/\(.*Win64.*\)/ && do {push @platform, "IA64";};
/\(Win.*\)/ && do {push @platform, ("IA32", "x86", "PC");};
/\(.*Win(?:dows[ -])NT.*\)/ && do {push @platform, ("IA32", "x86", "PC");};
/\(.*OSF.*\)/ && do {push @platform, ("Alpha", "DEC");};
/\(.*HP-?UX.*\)/i && do {push @platform, ("PA-RISC", "HP");};
/\(.*IRIX.*\)/i && do {push @platform, ("MIPS", "SGI");};
/\(.*(SunOS|Solaris).*\)/ && do {push @platform, ("Sparc", "Sun");};
# Braindead old browsers who didn't follow convention:
/Amiga/ && do {push @platform, ("68k", "Macintosh");};
/WinMosaic/ && do {push @platform, ("IA32", "x86", "PC");};
}
}
return pick_valid_field_value('rep_platform', @platform) || "Other";
}
sub pickos
{
my ($ARGS) = @_;
return $ARGS->{op_sys} if $ARGS->{op_sys};
my @os = ();
if (Bugzilla->params->{defaultopsys})
{
@os = Bugzilla->params->{defaultopsys};
}
else
{
# This function will return the first
# item in @os that is a valid platform choice. If
# no choice is valid, we return "Other".
for ($ENV{HTTP_USER_AGENT})
{
/\(.*IRIX.*\)/ && do {push @os, "IRIX";};
/\(.*OSF.*\)/ && do {push @os, "OSF/1";};
/\(.*Linux.*\)/ && do {push @os, "Linux";};
/\(.*Solaris.*\)/ && do {push @os, "Solaris";};
/\(.*SunOS.*\)/ && do {
/\(.*SunOS 5.11.*\)/ && do {push @os, ("OpenSolaris", "Opensolaris", "Solaris 11");};
/\(.*SunOS 5.10.*\)/ && do {push @os, "Solaris 10";};
/\(.*SunOS 5.9.*\)/ && do {push @os, "Solaris 9";};
/\(.*SunOS 5.8.*\)/ && do {push @os, "Solaris 8";};
/\(.*SunOS 5.7.*\)/ && do {push @os, "Solaris 7";};
/\(.*SunOS 5.6.*\)/ && do {push @os, "Solaris 6";};
/\(.*SunOS 5.5.*\)/ && do {push @os, "Solaris 5";};
/\(.*SunOS 5.*\)/ && do {push @os, "Solaris";};
/\(.*SunOS.*sun4u.*\)/ && do {push @os, "Solaris";};
/\(.*SunOS.*i86pc.*\)/ && do {push @os, "Solaris";};
/\(.*SunOS.*\)/ && do {push @os, "SunOS";};
};
/\(.*HP-?UX.*\)/ && do {push @os, "HP-UX";};
/\(.*BSD.*\)/ && do {
/\(.*BSD\/(?:OS|386).*\)/ && do {push @os, "BSDI";};
/\(.*FreeBSD.*\)/ && do {push @os, "FreeBSD";};
/\(.*OpenBSD.*\)/ && do {push @os, "OpenBSD";};
/\(.*NetBSD.*\)/ && do {push @os, "NetBSD";};
};
/\(.*BeOS.*\)/ && do {push @os, "BeOS";};
/\(.*AIX.*\)/ && do {push @os, "AIX";};
/\(.*OS\/2.*\)/ && do {push @os, "OS/2";};
/\(.*QNX.*\)/ && do {push @os, "Neutrino";};
/\(.*VMS.*\)/ && do {push @os, "OpenVMS";};
/\(.*Win.*\)/ && do {
/\(.*Windows XP.*\)/ && do {push @os, "Windows XP";};
/\(.*Windows NT 6\.1.*\)/ && do {push @os, "Windows 7";};
/\(.*Windows NT 6\.0.*\)/ && do {push @os, "Windows Vista";};
/\(.*Windows NT 5\.2.*\)/ && do {push @os, "Windows Server 2003";};
/\(.*Windows NT 5\.1.*\)/ && do {push @os, "Windows XP";};
/\(.*Windows 2000.*\)/ && do {push @os, "Windows 2000";};
/\(.*Windows NT 5.*\)/ && do {push @os, "Windows 2000";};
/\(.*Win.*9[8x].*4\.9.*\)/ && do {push @os, "Windows ME";};
/\(.*Win(?:dows |)M[Ee].*\)/ && do {push @os, "Windows ME";};
/\(.*Win(?:dows |)98.*\)/ && do {push @os, "Windows 98";};
/\(.*Win(?:dows |)95.*\)/ && do {push @os, "Windows 95";};
/\(.*Win(?:dows |)16.*\)/ && do {push @os, "Windows 3.1";};
/\(.*Win(?:dows[ -]|)NT.*\)/ && do {push @os, "Windows NT";};
/\(.*Windows.*NT.*\)/ && do {push @os, "Windows NT";};
};
/\(.*Mac OS X.*\)/ && do {
/\(.*Mac OS X (?:|Mach-O |\()10.6.*\)/ && do {push @os, "Mac OS X 10.6";};
/\(.*Mac OS X (?:|Mach-O |\()10.5.*\)/ && do {push @os, "Mac OS X 10.5";};
/\(.*Mac OS X (?:|Mach-O |\()10.4.*\)/ && do {push @os, "Mac OS X 10.4";};
/\(.*Mac OS X (?:|Mach-O |\()10.3.*\)/ && do {push @os, "Mac OS X 10.3";};
/\(.*Mac OS X (?:|Mach-O |\()10.2.*\)/ && do {push @os, "Mac OS X 10.2";};
/\(.*Mac OS X (?:|Mach-O |\()10.1.*\)/ && do {push @os, "Mac OS X 10.1";};
# Unfortunately, OS X 10.4 was the first to support Intel. This is
# fallback support because some browsers refused to include the OS
# Version.
/\(.*Intel.*Mac OS X.*\)/ && do {push @os, "Mac OS X 10.4";};
# OS X 10.3 is the most likely default version of PowerPC Macs
# OS X 10.0 is more for configurations which didn't setup 10.x versions
/\(.*Mac OS X.*\)/ && do {push @os, ("Mac OS X 10.3", "Mac OS X 10.0", "Mac OS X");};
};
/\(.*32bit.*\)/ && do {push @os, "Windows 95";};
/\(.*16bit.*\)/ && do {push @os, "Windows 3.1";};
/\(.*Mac OS \d.*\)/ && do {
/\(.*Mac OS 9.*\)/ && do {push @os, ("Mac System 9.x", "Mac System 9.0");};
/\(.*Mac OS 8\.6.*\)/ && do {push @os, ("Mac System 8.6", "Mac System 8.5");};
/\(.*Mac OS 8\.5.*\)/ && do {push @os, "Mac System 8.5";};
/\(.*Mac OS 8\.1.*\)/ && do {push @os, ("Mac System 8.1", "Mac System 8.0");};
/\(.*Mac OS 8\.0.*\)/ && do {push @os, "Mac System 8.0";};
/\(.*Mac OS 8[^.].*\)/ && do {push @os, "Mac System 8.0";};
/\(.*Mac OS 8.*\)/ && do {push @os, "Mac System 8.6";};
};
/\(.*Darwin.*\)/ && do {push @os, ("Mac OS X 10.0", "Mac OS X");};
# Silly
/\(.*Mac.*\)/ && do {
/\(.*Mac.*PowerPC.*\)/ && do {push @os, "Mac System 9.x";};
/\(.*Mac.*PPC.*\)/ && do {push @os, "Mac System 9.x";};
/\(.*Mac.*68k.*\)/ && do {push @os, "Mac System 8.0";};
};
# Evil
/Amiga/i && do {push @os, "Other";};
/WinMosaic/ && do {push @os, "Windows 95";};
/\(.*PowerPC.*\)/ && do {push @os, "Mac System 9.x";};
/\(.*PPC.*\)/ && do {push @os, "Mac System 9.x";};
/\(.*68K.*\)/ && do {push @os, "Mac System 8.0";};
}
}
push(@os, "Windows") if grep(/^Windows /, @os);
push(@os, "Mac OS") if grep(/^Mac /, @os);
return pick_valid_field_value('op_sys', @os) || "Other";
}
sub components_json
{
my ($product) = @_;
@ -573,8 +396,8 @@ else
$default{component_} = $ARGS->{component};
$default{priority} = $ARGS->{priority} || Bugzilla->params->{defaultpriority};
$default{bug_severity} = $ARGS->{bug_severity} || Bugzilla->params->{defaultseverity};
$default{rep_platform} = pickplatform($ARGS) if Bugzilla->params->{useplatform};
$default{op_sys} = pickos($ARGS) if Bugzilla->params->{useopsys};
$default{rep_platform} = pick_by_ua($ARGS, 'rep_platform') if Bugzilla->params->{useplatform};
$default{op_sys} = pick_by_ua($ARGS, 'op_sys') if Bugzilla->params->{useopsys};
$default{alias} = $ARGS->{alias};
$default{short_desc} = $ARGS->{short_desc};

View File

@ -59,6 +59,15 @@
[%+ 'checked="checked"' IF value.is_confirmed %] />
</td>
</tr>
[% ELSIF field.name == "op_sys" || field.name == "rep_platform" %]
<tr>
<th valign="top" align="left">
<label for="ua_regex">User Agent Regexp:</label>
</th>
<td>
<input id="ua_regex" name="ua_regex" size="100" value="[% value.ua_regex | html %]" />
</td>
</tr>
[% END %]
<tr>
<th align="left"><label for="isactive">Enabled for [% terms.bugs %]:</label></th>