Skip to content

Commit

Permalink
Merge branch 'beta' into production
Browse files Browse the repository at this point in the history
* beta:
  Translated using Weblate (Chinese (Simplified Han script))
  Translated using Weblate (Italian)
  Update translation files
  MBS-13917: Add new properties to avoid crashes (#3481)
  Update POT files using the production database
  Merge pull request #3472 from reosarevok/MBS-13929
  Merge pull request #3477 from reosarevok/MBS-13939
  Merge pull request #3478 from reosarevok/MBS-13938
  Merge pull request #3473 from reosarevok/MBS-13930
  Add ordering to `_find_authors_or_other_artists` roles
  Use proper query variable bindings in `Data::Edit::find_by_collection`
  MBS-13914: Validate vote arguments for voter edit search (#3464)
  MBS-13763: Add past year stats to the editors statistic page (#3465)
  MBS-13928: Use jaxsta.com instead of jaxsta.io (#3471)
  add --no-same-owner option to tar (#3456)
  MBS-13925: Instrument name erroneously displayed in link type autocomplete (#3467)
  Avoid spreading `key` props in `useTable` hook (#3476)
  Translated using Weblate (Chinese (Simplified Han script))
  Translated using Weblate (Chinese (Simplified Han script))
  Translated using Weblate (Russian)
  Translated using Weblate (Chinese (Simplified Han script))
  Translated using Weblate (Polish)
  Translated using Weblate (Italian)
  More direct `get_authorship_relationship_gids` implementation
  Rename "misc_artists" to "other_artists"
  MBS-8328: Split the role filter for artist works
  MBS-13917: Rename work "writers" to "authors"
  Get authorship rel gids from the DB
  Rename "composition" to "authorship"
  Add test for loading different subsets of work artists
  Drop unneeded work artist credit test SQL
  MBS-8328: Add the non-writer artists back as own column
  MBS-8328: Limit work writers to writing rels
  MBS-11916: Report for recordings marked both karaoke and instrumental (#2504)
  Merge pull request #3468 from derat/feat_error
  MBS-13920 (II): Detect feat. artists in titles when seeding (#3469)
  Use `qq` to avoid escaping "
  MBS-6502: Surround catno search with quotes
  MBS-13922: Add URL cleanup and validation for Naver Vibe (#3463)
  Move most filter find_by to right Data file
  MBS-8500: Add "not by me" filter for collection edit lists
  MBS-13597: Add release filter to label index pages
  Avoid warning when selected_artist_credit_id is missing
  • Loading branch information
reosarevok committed Feb 24, 2025
2 parents 01c6cc0 + 335064a commit 5522cf8
Show file tree
Hide file tree
Showing 258 changed files with 17,127 additions and 6,672 deletions.
4 changes: 2 additions & 2 deletions admin/MBImport.pl
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ sub usage
for (@tar_to_extract)
{
my ($tar, $dir, $decompress) = @$_;
print localtime() . " : tar -C $dir $decompress -xvf $tar\n";
system "tar -C $dir $decompress -xvf $tar";
print localtime() . " : tar -C $dir $decompress --no-same-owner -xvf $tar\n";
system "tar -C $dir $decompress --no-same-owner -xvf $tar";
exit($CHILD_ERROR >> 8) if $CHILD_ERROR;
}

Expand Down
10 changes: 5 additions & 5 deletions flow-typed/npm/react-table_v7.x.x.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,29 @@ declare module 'react-table' {

declare export type ColumnInstance = {
+cellProps?: {[attribute: string]: string},
+getCellProps: (props?: {...}) => {...},
+getHeaderProps: (props?: {...}) => {...},
+getCellProps: (props?: {...}) => {+key: string, ...},
+getHeaderProps: (props?: {...}) => {+key: string, ...},
// Not actually part of react-table but our own expansion of it
+headerProps?: {[attribute: string]: string},
+render: (type: 'Header' | string, props?: {...}) => React.Node,
};

declare export type HeaderGroup = $ReadOnly<{
...$ReadOnly<ColumnInstance>,
+getHeaderGroupProps: (props?: {...}) => {...},
+getHeaderGroupProps: (props?: {...}) => {+key: string, ...},
+headers: $ReadOnlyArray<ColumnInstance>,
}>;

declare export type Cell<+V> = {
+column: ColumnInstance,
+getCellProps: (props?: {...}) => {...},
+getCellProps: (props?: {...}) => {+key: string, ...},
+render: (type: 'Cell' | string, userProps?: {...}) => React.Node,
+value: V,
};

declare export type Row<+D> = {
+cells: $ReadOnlyArray<Cell<mixed>>,
+getRowProps: (props?: {...}) => {...},
+getRowProps: (props?: {...}) => {+key: string, ...},
+index: number,
+original: D,
};
Expand Down
2 changes: 2 additions & 0 deletions lib/MusicBrainz/Server/Constants.pm
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ our @EXPORT_OK = (
$AREA_TYPE_COUNTRY $AREA_TYPE_CITY
$ARTIST_TYPE_PERSON $ARTIST_TYPE_GROUP
$INSTRUMENT_ROOT_ID $VOCAL_ROOT_ID
$WORK_AUTHORSHIP_ROOT_ID
$REQUIRED_VOTES $OPEN_EDIT_DURATION
$MINIMUM_RESPONSE_PERIOD $MINIMUM_VOTING_PERIOD
$LIMIT_FOR_EDIT_LISTING
Expand Down Expand Up @@ -391,6 +392,7 @@ Readonly our $COVERART_BACK_TYPE => 2;

Readonly our $INSTRUMENT_ROOT_ID => 14;
Readonly our $VOCAL_ROOT_ID => 3;
Readonly our $WORK_AUTHORSHIP_ROOT_ID => 170;

Readonly our $AREA_TYPE_COUNTRY => 1;
Readonly our $AREA_TYPE_CITY => 3;
Expand Down
11 changes: 11 additions & 0 deletions lib/MusicBrainz/Server/Controller/Ajax.pm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use MusicBrainz::Server::FilterUtils qw(
create_artist_releases_form
create_artist_recordings_form
create_artist_works_form
create_label_releases_form
);

sub filter_artist_events_form : Local {
Expand Down Expand Up @@ -64,4 +65,14 @@ sub filter_artist_works_form : Local {
$c->res->content_type('application/json; charset=utf-8');
}

sub filter_label_releases_form : Local {
my ($self, $c) = @_;

my $label_id = $c->req->query_params->{label_id};
my $form = create_label_releases_form($c, $label_id);

$c->res->body(encode_json($form->TO_JSON));
$c->res->content_type('application/json; charset=utf-8');
}

1;
36 changes: 1 addition & 35 deletions lib/MusicBrainz/Server/Controller/Artist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ with 'MusicBrainz::Server::Controller::Role::Annotation';
with 'MusicBrainz::Server::Controller::Role::Alias';
with 'MusicBrainz::Server::Controller::Role::Details';
with 'MusicBrainz::Server::Controller::Role::EditListing';
with 'MusicBrainz::Server::Controller::Role::Filter';
with 'MusicBrainz::Server::Controller::Role::IPI';
with 'MusicBrainz::Server::Controller::Role::ISNI';
with 'MusicBrainz::Server::Controller::Role::Rating';
Expand Down Expand Up @@ -891,41 +892,6 @@ sub edit_credit : Chained('credit') PathPart('edit') Edit {
);
}

=head2 process_filter
Utility function for dynamically loading the filter form.
=cut

sub process_filter
{
my ($self, $c, $create_form) = @_;

my %filter;
unless (exists $c->req->params->{'filter.cancel'}) {
my $cookie = $c->req->cookies->{filter};
my $has_filter_params = grep { /^filter\./ } keys %{ $c->req->params };
if ($has_filter_params || ($cookie && defined($cookie->value) && $cookie->value eq '1')) {
my $filter_form = $create_form->();
if ($c->form_submitted_and_valid($filter_form)) {
for my $name ($filter_form->filter_field_names) {
my $value = $filter_form->field($name)->value;
if ($value) {
$filter{$name} = $value;
}

}
$c->res->cookies->{filter} = { value => '1', path => '/' };
}
}
}
else {
$c->res->cookies->{filter} = { value => '', path => '/' };
}

return \%filter;
}

=head1 COPYRIGHT AND LICENSE
Copyright (C) 2008 MetaBrainz Foundation
Expand Down
7 changes: 6 additions & 1 deletion lib/MusicBrainz/Server/Controller/Collection.pm
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,15 @@ sub _list_edits {

$self->collection_collaborator($c) if !$collection->public;

my $hide_own = 0;
if (($c->req->query_params->{hide_own} // '') eq '1') {
$hide_own = 1;
}

my $status = $show_open_only ? $STATUS_OPEN : undef;
my $edits = $self->_load_paged($c, sub {
my ($limit, $offset) = @_;
$c->model('Edit')->find_by_collection($collection->id, $limit, $offset, $status);
$c->model('Edit')->find_by_collection($collection->id, $limit, $offset, $status, $hide_own, $c->user->id);
});

$c->stash(edits => $edits); # stash early in case an ISE occurs while loading the edits
Expand Down
3 changes: 2 additions & 1 deletion lib/MusicBrainz/Server/Controller/ISWC.pm
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ sub show : Chained('load') PathPart('')
my $iswcs = $c->stash->{iswcs};
my @works = sort_by { $_->name } $c->model('Work')->load(@$iswcs);
$c->model('WorkType')->load(@works);
$c->model('Work')->load_writers(@works);
$c->model('Work')->load_authors(@works);
$c->model('Work')->load_other_artists(@works);
$c->model('Work')->load_recording_artists(@works);
$c->model('Language')->load_for_works(@works);
$c->stash(
Expand Down
19 changes: 17 additions & 2 deletions lib/MusicBrainz/Server/Controller/Label.pm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ with 'MusicBrainz::Server::Controller::Role::Alias';
with 'MusicBrainz::Server::Controller::Role::Cleanup';
with 'MusicBrainz::Server::Controller::Role::Details';
with 'MusicBrainz::Server::Controller::Role::EditListing';
with 'MusicBrainz::Server::Controller::Role::Filter';
with 'MusicBrainz::Server::Controller::Role::IPI';
with 'MusicBrainz::Server::Controller::Role::ISNI';
with 'MusicBrainz::Server::Controller::Role::Rating';
Expand All @@ -52,8 +53,14 @@ use MusicBrainz::Server::Constants qw(
);
use MusicBrainz::Server::ControllerUtils::JSON qw( serialize_pager );
use Data::Page;
use MusicBrainz::Server::Data::Utils qw( is_special_label );
use MusicBrainz::Server::Data::Utils qw(
boolean_to_json
is_special_label
);
use MusicBrainz::Server::Entity::Util::JSON qw( to_json_array to_json_object );
use MusicBrainz::Server::FilterUtils qw(
create_label_releases_form
);
use MusicBrainz::Server::Translation qw( l );
use HTTP::Status qw( :constants );
use List::AllUtils qw( any );
Expand Down Expand Up @@ -124,8 +131,13 @@ sub show : PathPart('') Chained('load')

my $label = $c->stash->{label};

my %filter = %{ $self->process_filter($c, sub {
return create_label_releases_form($c, $label->id);
}) };
my $has_filter = %filter ? 1 : 0;

my $releases = $self->_load_paged($c, sub {
$c->model('Release')->find_by_label($label->id, shift, shift);
$c->model('Release')->find_by_label($label->id, shift, shift, filter => \%filter);
});

$c->model('ArtistCredit')->load(@$releases);
Expand Down Expand Up @@ -156,6 +168,9 @@ sub show : PathPart('') Chained('load')
}

my %props = (
ajaxFilterFormUrl => '' . $c->uri_for_action('/ajax/filter_label_releases_form', { label_id => $label->id }),
filterForm => to_json_object($c->stash->{filter_form}),
hasFilter => boolean_to_json($has_filter),
label => $label->TO_JSON,
numberOfRevisions => $c->stash->{number_of_revisions},
pager => serialize_pager($c->stash->{pager}),
Expand Down
25 changes: 24 additions & 1 deletion lib/MusicBrainz/Server/Controller/OtherLookup.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,29 @@ extends 'MusicBrainz::Server::Controller';

use MusicBrainz::Server::Entity::Util::JSON qw( to_json_array );

sub build_term {
my ($self, $value) = @_;

# We want to turn the given value into a valid Lucene term so
# the search server understands it properly.
# As such, we quote it to make it a Lucene phrase,
# except if it is a regular expression or the user already entered
# a Lucene phrase (i.e. the value is already in quotes).
# See https://lucene.apache.org/core/7_7_2/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Terms
my $is_regex = $value =~ /^\/.*\/$/;
my $is_quoted = $value =~ /^".*"$/;

# We escape any quotes inside the actual value so that they are
# still searched for when we turn it into a phrase.
my $escaped_value = $value =~ s/"/\\"/gr;

my $term = ($is_regex || $is_quoted)
? $value
: qq("$escaped_value");

return $term;
}

sub lookup_handler {
my ($name, $code) = @_;

Expand Down Expand Up @@ -43,7 +66,7 @@ lookup_handler 'catno' => sub {

$c->response->redirect(
$c->uri_for_action('/search/search', {
query => 'catno:' . $cat_no,
query => 'catno:' . $self->build_term($cat_no),
type => 'release',
advanced => '1',
}));
Expand Down
51 changes: 51 additions & 0 deletions lib/MusicBrainz/Server/Controller/Role/Filter.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package MusicBrainz::Server::Controller::Role::Filter;
use Moose::Role;
use namespace::autoclean;

=head2 process_filter
Utility function for dynamically loading the filter form.
=cut

sub process_filter
{
my ($self, $c, $create_form) = @_;

my %filter;
unless (exists $c->req->params->{'filter.cancel'}) {
my $cookie = $c->req->cookies->{filter};
my $has_filter_params = grep { /^filter\./ } keys %{ $c->req->params };
if ($has_filter_params || ($cookie && defined($cookie->value) && $cookie->value eq '1')) {
my $filter_form = $create_form->();
if ($c->form_submitted_and_valid($filter_form)) {
for my $name ($filter_form->filter_field_names) {
my $value = $filter_form->field($name)->value;
if ($value) {
$filter{$name} = $value;
}

}
$c->res->cookies->{filter} = { value => '1', path => '/' };
}
}
}
else {
$c->res->cookies->{filter} = { value => '', path => '/' };
}

return \%filter;
}

no Moose::Role;
1;

=head1 COPYRIGHT AND LICENSE
Copyright (C) 2025 MetaBrainz Foundation
This file is part of MusicBrainz, the open internet music database,
and is licensed under the GPL version 2, or (at your option) any
later version: http://www.gnu.org/licenses/gpl-2.0.txt
=cut
3 changes: 2 additions & 1 deletion lib/MusicBrainz/Server/Controller/Search.pm
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ sub direct : Private
$c->model('ISRC')->load_for_recordings(map { $_->entity } @$results);
}
elsif ($type eq 'work') {
$c->model('Work')->load_writers(@entities);
$c->model('Work')->load_authors(@entities);
$c->model('Work')->load_other_artists(@entities);
$c->model('Work')->load_recording_artists(@entities);
$c->model('ISWC')->load_for_works(@entities);
$c->model('Language')->load_for_works(@entities);
Expand Down
16 changes: 14 additions & 2 deletions lib/MusicBrainz/Server/Controller/Statistics.pm
Original file line number Diff line number Diff line change
Expand Up @@ -354,18 +354,28 @@ sub editors : Path('editors') {
my $top_recently_active_editors =
_editor_data_points($stats, 'editor.top_recently_active.rank',
'count.edit.top_recently_active.rank');
my $top_yearly_active_editors =
_editor_data_points($stats, 'editor.top_yearly_active.rank',
'count.edit.top_yearly_active.rank');
my $top_active_editors =
_editor_data_points($stats, 'editor.top_active.rank',
'count.edit.top_active.rank');
my $top_recently_active_voters =
_editor_data_points($stats, 'editor.top_recently_active_voters.rank',
'count.vote.top_recently_active_voters.rank');
my $top_yearly_active_voters =
_editor_data_points($stats, 'editor.top_yearly_active_voters.rank',
'count.vote.top_yearly_active_voters.rank');
my $top_active_voters =
_editor_data_points($stats, 'editor.top_active_voters.rank',
'count.vote.top_active_voters.rank');

my @data_points = ( @$top_recently_active_editors, @$top_active_editors,
@$top_recently_active_voters, @$top_active_voters );
my @data_points = ( @$top_recently_active_editors,
@$top_yearly_active_editors,
@$top_active_editors,
@$top_recently_active_voters,
@$top_yearly_active_voters,
@$top_active_voters );

my $editors = $c->model('Editor')->get_by_ids(map { $_->{editor_id} } @data_points);
for my $data_point (@data_points) {
Expand All @@ -375,8 +385,10 @@ sub editors : Path('editors') {
my %props = (
dateCollected => $stats->{date_collected},
topRecentlyActiveEditors => $top_recently_active_editors,
topYearlyEditors => $top_yearly_active_editors,
topEditors => $top_active_editors,
topRecentlyActiveVoters => $top_recently_active_voters,
topYearlyVoters => $top_yearly_active_voters,
topVoters => $top_active_voters,
);

Expand Down
5 changes: 3 additions & 2 deletions lib/MusicBrainz/Server/Controller/Work.pm
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ sub show : PathPart('') Chained('load')
my ($self, $c) = @_;

my $stash = $c->stash;
$c->model('Work')->load_writers($stash->{work});
$c->model('Work')->load_authors($stash->{work});

my $pager = defined $stash->{pager}
? serialize_pager($stash->{pager})
Expand Down Expand Up @@ -177,7 +177,8 @@ sub _merge_load_entities
$c->model('Work')->load_aliases(@works);
$c->model('Work')->load_meta(@works);
$c->model('WorkType')->load(@works);
$c->model('Work')->load_writers(@works);
$c->model('Work')->load_authors(@works);
$c->model('Work')->load_other_artists(@works);
$c->model('Work')->load_recording_artists(@works);
$c->model('WorkAttribute')->load_for_works(@works);
$c->model('Language')->load_for_works(@works);
Expand Down
Loading

0 comments on commit 5522cf8

Please sign in to comment.