diff --git a/lib/SeMeet/Controller/Records.pm b/lib/SeMeet/Controller/Records.pm new file mode 100644 index 0000000000000000000000000000000000000000..018a722a9b7bee5283f820e62f07287392208905 --- /dev/null +++ b/lib/SeMeet/Controller/Records.pm @@ -0,0 +1,51 @@ +package SeMeet::Controller::Records; +use Mojo::Base 'Mojolicious::Controller', -signatures; + +use constant FILENAME_REGEX => qr/(.+)_(\d{4})\-(\d{2})\-(\d{2})\-(\d{2})\-(\d{2})\-(\d{2})\.mp4/; + +sub create($c) { + $c->openapi->valid_input or return; + my $args = $c->req->json; + + # datum meetu + if ($args->{file} !~ FILENAME_REGEX) { + return $c->error(400, 'INVALID FILENAME'); + } + my $recorded = "$2-$3-$4 $5:$6:$7"; + + # Duplicita id + my $exists = $c->schema->resultset('Record')->count({ + deleted => undef, + uuid => $args->{uuid}, + }); + return $c->error(400, 'DUPLICTE UUID') if $exists; + + # meet + my $meet_uuid = $args->{meeting_url}; + $meet_uuid =~ s/.+\///; + my $meet = $c->schema->resultset('Meet')->search({ + uuid => $meet_uuid + })->first; + + return $c->error(400, 'MEET NOT FOUND') if ! $meet; + + my $guard = $c->schema->txn_scope_guard; + + $meet->add_to_records({ + uuid => $args->{uuid}, + file => $args->{file}, + recorded => $recorded, + }); + + $guard->commit; + +# $c->trace(\'Record %s create meet "%s" with id %d', +# $c->stash->{user}->username, +# $meet->name, +# $meet->id, +# ); + + $c->render( status => 204, text => '' ); +} + +1; diff --git a/lib/SeMeet/Schema/Result/Meet.pm b/lib/SeMeet/Schema/Result/Meet.pm index 3a0c1516c6c4fe37e3df82484444434b77b143c7..f105a0fb1eecd29daef017353bb92b0df61365bb 100644 --- a/lib/SeMeet/Schema/Result/Meet.pm +++ b/lib/SeMeet/Schema/Result/Meet.pm @@ -70,6 +70,11 @@ __PACKAGE__->has_many( { 'foreign.meet_id' => 'self.id', }, ); +__PACKAGE__->has_many( + records => 'SeMeet::Schema::Result::Record', + { 'foreign.meet_id' => 'self.id', }, +); + __PACKAGE__->inflate_column('properties', { inflate => sub { from_json(shift); }, deflate => sub { to_json(shift); }, diff --git a/lib/SeMeet/Schema/Result/Record.pm b/lib/SeMeet/Schema/Result/Record.pm new file mode 100644 index 0000000000000000000000000000000000000000..a2445ecaaeff78b99e84b70a16446d62069bb407 --- /dev/null +++ b/lib/SeMeet/Schema/Result/Record.pm @@ -0,0 +1,37 @@ +package SeMeet::Schema::Result::Record; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +our $VERSION = 1; + +__PACKAGE__->table('records'); + +__PACKAGE__->add_columns( + id => { + data_type => 'integer', + is_auto_increment => 1, + is_nullable => 0, + sequence => 'uid_seq' + }, + qw( + uuid + meet_id + deleted + recorded + decription + file + ), +); + +__PACKAGE__->set_primary_key('id'); + +__PACKAGE__->add_unique_constraint( + 'uuid' => [qw(uuid)] +); + + +1; + diff --git a/openapi.yaml b/openapi.yaml index 04533ad772dc3f8ad4bbf9e19d9428638c9521e2..86fa95cfc50d12a00fed1ca239502af4aa8b60a1 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -505,3 +505,36 @@ paths: application/json: schema: $ref: '#/components/schemas/Invite' + /records: + post: + x-mojo-to: records#create + tags: + - records + summary: "NovĂ˝ zaznam" + operationId: addRecord + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + uuid: + type: string + description: "Record UUID" + example: "504e4a84-864c-417b-91a9-fc65bb7e15d9" + file: + type: string + description: "Record file" + example: "3ab57b30-7e11-4031-9ef9-429d2054a92e_2024-12-05-21-22-45.mp4" + meeting_url: + type: string + description: "Meeting URL" + example: "https://meet.pirati.cz/3ab57b30-7e11-4031-9ef9-429d2054a92f" + required: + - uuid + - file + - meeting_url + responses: + 204: + description: Record created diff --git a/sql/migrations.sql b/sql/migrations.sql index 8c93ae9168fe92260b0d0ba152bf211c998b00d3..4c7ff82cf56b17f45875a599e5f237587f8b5263 100644 --- a/sql/migrations.sql +++ b/sql/migrations.sql @@ -106,3 +106,17 @@ create table "invites" ( foreign key ("meet_id") references "meets" ("id") on update cascade on delete cascade, foreign key ("user_id") references "users" ("id") on update cascade on delete cascade ); + +-- 10 up +create table "records" ( + "id" integer not null default nextval('uid_seq'), + "uuid" uuid not null, -- unique string + "meet_id" integer not null, + "deleted" timestamp(0), + "recorded" timestamp(0), + "description" text, + "file" text, + primary key("id"), + unique("uuid"), + foreign key ("meet_id") references "meets" ("id") on update cascade on delete restrict +);