<commit_before>package MediaWords::Controller::Api::V2::Topics;

use Modern::Perl "2015";
use MediaWords::CommonLibs;

use strict;
use warnings;
use base 'Catalyst::Controller';

use HTTP::Status qw(:constants);
use Readonly;

use Moose;
use namespace::autoclean;

use MediaWords::TM::Mine;

BEGIN
{
    extends 'MediaWords::Controller::Api::V2::MC_Controller_REST';
    use MediaWords::DBI::Auth::Roles;
}

__PACKAGE__->config(
    action => {
        list          => { Does => [ qw( ~PublicApiKeyAuthenticated ~Throttled ~Logged ) ] },
        single        => { Does => [ qw( ~PublicApiKeyAuthenticated ~Throttled ~Logged ) ] },
        create        => { Does => [ qw( ~PublicApiKeyAuthenticated ~Throttled ~Logged ) ] },
        update        => { Does => [ qw( ~TopicsWriteAuthenticated ~Throttled ~Logged ) ] },
        spider        => { Does => [ qw( ~TopicsWriteAuthenticated ~Throttled ~Logged ) ] },
        spider_status => { Does => [ qw( ~PublicApiKeyAuthenticated ~Throttled ~Logged ) ] },
    }
);

Readonly::Scalar my $TOPICS_EDIT_FIELDS => [
    qw/name solr_seed_query description max_iterations start_date end_date is_public ch_monitor_id twitter_topics_id max_stories is_logogram/
];

Readonly::Scalar my $JOB_STATE_FIELD_LIST =>
  "job_states_id, ( args->>'topics_id' )::int topics_id, state, message, last_updated";

sub apibase : Chained('/') : PathPart('api/v2/topics') : CaptureArgs(1)
{
    my ( $self, $c, $topics_id ) = @_;

    $c->stash->{ topics_id } = $topics_id;
}

sub _get_topics_list($$$)    # sql clause for fields to query from job_states for api publication
{
    my ( $db, $params, $auth_users_id ) = @_;

    my $name      = $params->{ name } || '';
    my $topics_id = $params->{ topics_id };
    my $public    = $params->{ public };

    my $limit  = $params->{ limit };
    my $offset = $params->{ offset };

    my $id_clause = '';
    if ( $topics_id )
    {
        $id_clause = 't.topics_id = ' . int( $topics_id ) . ' and ';
    }

    my $public_clause = '';
    if ( defined( $public ) )
    {
        $public_clause = $public ? "t.is_public and" : "not t.is_public and";
    }

    my $topics = $db->query(
        <<END,
select t.topics_id, t.name, t.pattern, t.solr_seed_query, t.solr_seed_query_run,
        t.description, t.max_iterations, t.state,
        t.message, t.is_public, t.ch_monitor_id, t.twitter_topics_id, t.start_date, t.end_date,
        min( p.auth_users_id ) auth_users_id, min( p.user_permission ) user_permission,
        t.job_queue, t.max_stories, t.is_logogram
    from topics t
        join topics_with_user_permission p using ( topics_id )
        left join snapshots snap on ( t.topics_id = snap.topics_id )
    where
        $id_clause
        $public_clause
        p.auth_users_id= \$1 and
        t.name ilike \$2 and
        p.user_permission <> 'none'
    group by t.topics_id
    order by t.state = 'completed', t.state,  max( coalesce( snap.snapshot_date, '2000-01-01'::date ) ) desc
    limit \$3 offset \$4
END
        $auth_users_id, '%' . $name . '%', $limit, $offset
    )->hashes;

    $topics = $db->attach_child_query( $topics, <<SQL, 'media', 'topics_id' );
select m.media_id, m.name, tmm.topics_id
    from media m join topics_media_map tmm using ( media_id )
SQL

    $topics = $db->attach_child_query( $topics, <<SQL, 'media_tags', 'topics_id' );
select t.tags_id, t.tag, t.label, t.description, tmtm.topics_id
    from tags t join topics_media_tags_map tmtm using ( tags_id )
SQL

    return $topics;
}

sub list : Local : ActionClass('MC_REST')
{

}

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

    MediaWords::DBI::ApiLinks::process_and_stash_link( $c );

    my $db = $c->dbis;

    my $auth_users_id = $c->stash->{ api_auth }->id();

    my $topics = _get_topics_list( $db, $c->req->params, $auth_users_id );

    my $entity = { topics => $topics };

    MediaWords::DBI::ApiLinks::add_links_to_entity( $c, $entity, 'topics' );

    $self->status_ok( $c, entity => $entity );
}
<commit_msg>include owners list in topics/list results<commit_after>package MediaWords::Controller::Api::V2::Topics;

use Modern::Perl "2015";
use MediaWords::CommonLibs;

use strict;
use warnings;
use base 'Catalyst::Controller';

use HTTP::Status qw(:constants);
use Readonly;

use Moose;
use namespace::autoclean;

use MediaWords::TM::Mine;

BEGIN
{
    extends 'MediaWords::Controller::Api::V2::MC_Controller_REST';
    use MediaWords::DBI::Auth::Roles;
}

__PACKAGE__->config(
    action => {
        list          => { Does => [ qw( ~PublicApiKeyAuthenticated ~Throttled ~Logged ) ] },
        single        => { Does => [ qw( ~PublicApiKeyAuthenticated ~Throttled ~Logged ) ] },
        create        => { Does => [ qw( ~PublicApiKeyAuthenticated ~Throttled ~Logged ) ] },
        update        => { Does => [ qw( ~TopicsWriteAuthenticated ~Throttled ~Logged ) ] },
        spider        => { Does => [ qw( ~TopicsWriteAuthenticated ~Throttled ~Logged ) ] },
        spider_status => { Does => [ qw( ~PublicApiKeyAuthenticated ~Throttled ~Logged ) ] },
    }
);

Readonly::Scalar my $TOPICS_EDIT_FIELDS => [
    qw/name solr_seed_query description max_iterations start_date end_date is_public ch_monitor_id twitter_topics_id max_stories is_logogram/
];

Readonly::Scalar my $JOB_STATE_FIELD_LIST =>
  "job_states_id, ( args->>'topics_id' )::int topics_id, state, message, last_updated";

sub apibase : Chained('/') : PathPart('api/v2/topics') : CaptureArgs(1)
{
    my ( $self, $c, $topics_id ) = @_;

    $c->stash->{ topics_id } = $topics_id;
}

sub _get_topics_list($$$)    # sql clause for fields to query from job_states for api publication
{
    my ( $db, $params, $auth_users_id ) = @_;

    my $name      = $params->{ name } || '';
    my $topics_id = $params->{ topics_id };
    my $public    = $params->{ public };

    my $limit  = $params->{ limit };
    my $offset = $params->{ offset };

    my $id_clause = '';
    if ( $topics_id )
    {
        $id_clause = 't.topics_id = ' . int( $topics_id ) . ' and ';
    }

    my $public_clause = '';
    if ( defined( $public ) )
    {
        $public_clause = $public ? "t.is_public and" : "not t.is_public and";
    }

    my $topics = $db->query(
        <<END,

select t.topics_id, t.name, t.pattern, t.solr_seed_query, t.solr_seed_query_run,
        t.description, t.max_iterations, t.state,
        t.message, t.is_public, t.ch_monitor_id, t.twitter_topics_id, t.start_date, t.end_date,
        min( p.auth_users_id ) auth_users_id, min( p.user_permission ) user_permission,
        t.job_queue, t.max_stories, t.is_logogram
    from topics t
        join topics_with_user_permission p using ( topics_id )
        left join snapshots snap on ( t.topics_id = snap.topics_id )
    where
        $id_clause
        $public_clause
        p.auth_users_id= \$1 and
        t.name ilike \$2 and
        p.user_permission <> 'none'
    group by t.topics_id
    order by t.state = 'completed', t.state,  max( coalesce( snap.snapshot_date, '2000-01-01'::date ) ) desc
    limit \$3 offset \$4
END
        $auth_users_id, '%' . $name . '%', $limit, $offset
    )->hashes;

    $topics = $db->attach_child_query( $topics, <<SQL, 'media', 'topics_id' );
select m.media_id, m.name, tmm.topics_id
    from media m join topics_media_map tmm using ( media_id )
SQL

    $topics = $db->attach_child_query( $topics, <<SQL, 'media_tags', 'topics_id' );
select t.tags_id, t.tag, t.label, t.description, tmtm.topics_id
    from tags t join topics_media_tags_map tmtm using ( tags_id )
SQL

    $topics = $db->attach_child_query( $topics, <<SQL, 'owners', 'topics_id' );
select tp.topics_id, au.auth_users_id, au.email, au.full_name
    from topic_permissions tp
        join auth_users au using ( auth_users_id )
    where
        tp.permission = 'admin'
SQL

    return $topics;
}

sub list : Local : ActionClass('MC_REST')
{

}

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

    MediaWords::DBI::ApiLinks::process_and_stash_link( $c );

    my $db = $c->dbis;

    my $auth_users_id = $c->stash->{ api_auth }->id();

    my $topics = _get_topics_list( $db, $c->req->params, $auth_users_id );

    my $entity = { topics => $topics };

    MediaWords::DBI::ApiLinks::add_links_to_entity( $c, $entity, 'topics' );

    $self->status_ok( $c, entity => $entity );
}

{'fraction_non_alphanumeric': 0.1487463837994214, 'fraction_numerical': 0.0048216007714561235, 'mean_word_length': 3.1672526368658964, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 82, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4769496', 'n_tokens_mistral': 3123, 'n_tokens_neox': 3053, 'n_words': 666}