Skip to content
Snippets Groups Projects
Verified Commit dc38b3d1 authored by Andrej Ramašeuski's avatar Andrej Ramašeuski
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Pipeline #1755 passed
**
!lib
!script
!cpanfile
!iapi.yaml
!iapi.conf
_work
docker-compose.yaml
image: docker:19.03.1
variables:
DOCKER_TLS_CERTDIR: "/certs"
IMAGE_TAG: $CI_REGISTRY_IMAGE
IMAGE_VER: 0.1.0
services:
- docker:19.03.1-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
script:
- docker build -t $IMAGE_TAG:$IMAGE_VER .
- docker tag $IMAGE_TAG:$IMAGE_VER $IMAGE_TAG:latest
- docker push $IMAGE_TAG:$IMAGE_VER
- docker push $IMAGE_TAG:latest
FROM node:buster
#FROM node:buster-slim
RUN apt-get update && apt-get install -y \
wget \
cpanminus \
build-essential \
libdbd-pg-perl \
libdbi-perl \
libdbix-class-perl \
libmodule-build-tiny-perl \
libnet-ssleay-perl \
libtest-deep-perl \
libyaml-dev
RUN cpanm \
Mojolicious \
Mojo::Pg \
Mojo::JWT \
Mojolicious::Plugin::OpenAPI
ADD . /opt/cf
WORKDIR /opt/cf
USER nobody
EXPOSE 3000
CMD /opt/cf/script/cf daemon
{
secrets => ['04283d549647774b17d10e1d75bcf16c2969673d']
}
package CF;
use Mojo::Base 'Mojolicious';
use Mojo::Pg;
use CF::Schema;
# This method will run once at server start
sub startup {
my $self = shift;
$self->plugin('CF::Helpers::Core');
my $cfg = $self->plugin('Config' => { file => 'cf.conf'} );
# Konfigurace z ENV ma prednost
KEY:
foreach my $key ( keys %ENV ) {
if ( $key =~ /^CFG_(.+)/i ) {
$cfg->{lc($1)} = $ENV{$key};
}
}
# migrace schematu
my $pg = Mojo::Pg->new
->dsn($cfg->{db_dsn})
->username($cfg->{db_username})
->password($cfg->{db_password})
;
$pg->migrations->from_file($self->home . '/sql/migrations.sql');
$pg->migrations->migrate();
$self->helper( pg => sub { return $pg; } );
# DB Schema
my $schema = CF::Schema->connect({
dsn => $cfg->{db_dsn},
user => $cfg->{db_username},
password => $cfg->{db_password}
});
$self->helper( schema => sub { return $schema; } );
$self->plugin("OpenAPI" => {
url => $self->home . '/openapi.yaml',
schema => 'v3',
plugins => [qw(+SpecRenderer +Cors +Security)],
render_specification => 1,
render_specification_for_paths => 1,
default_response_codes => [400, 404, 500, 501],
});
$self->defaults(
openapi_cors_allowed_origins => ['*']
);
# Router
my $r = $self->routes;
$r->get('/')->to(cb => sub { shift->redirect_to('/api.html');});
}
1;
package CF::Controller::Program;
use Mojo::Base 'Mojolicious::Controller';
sub entries {
my $c = shift->openapi->valid_input or return;
my $entries = $c->schema->resultset('ProgramEntry')->search(
{ is_approved => 't' },
{ order_by => 'number' },
);
my @entries = ();
ENTRY:
while ( my $entry = $entries->next ) {
push @entries, $c->spec_filter( {
$entry->get_columns,
expectedStartAt => $c->format_timestamp( $entry->start, '%H:%M' ),
expectedFinishAt => $c->format_timestamp( $entry->finish, '%H:%M' ),
}, 'ProgramScheduleEntry');
}
$c->render(openapi => \@entries );
}
1;
package CF::Helpers::Core;
use base 'Mojolicious::Plugin';
use feature 'signatures';
no warnings qw{ experimental::signatures } ;
sub register ($class, $self, $conf) {
$self->helper( spec_filter => sub {
my $c = shift;
my $data = shift;
my $class = shift;
if (my $def =$c->openapi->spec("/components/schemas/$class")) {
my $filtered = {};
KEY:
foreach my $key ( keys %{ $def->{properties} } ) {
my $value = $data->{$key};
my $nullable = 0;
my $types = $def->{properties}{$key}{type};
if ( ref $types eq 'ARRAY' ) {
TYPE:
foreach my $type ( @{ $types } ) {
$nullable = 1, last if $type eq 'null';
}
}
$filtered->{$key} = $value;
}
$data = $filtered;
}
return $data;
});
$self->helper( format_timestamp => sub($c, $timestamp, $format) {
return $timestamp;
});
}
1;
package CF::Schema;
use strict;
use warnings;
use base 'DBIx::Class::Schema';
our $VERSION = 1;
__PACKAGE__->load_namespaces;
1;
package CF::Schema::Result::ProgramEntry;
use strict;
use warnings;
use base 'DBIx::Class::Core';
our $VERSION = 1;
__PACKAGE__->table('program');
__PACKAGE__->add_columns(
id => {
data_type => 'integer',
is_auto_increment => 1,
is_nullable => 0,
sequence => 'uid_seq'
},
qw(
number
start
finish
is_approved
is_live
title
proposer
description
),
);
__PACKAGE__->set_primary_key('id');
1;
package CF::Schema::Result::User;
use strict;
use warnings;
use base 'DBIx::Class::Core';
our $VERSION = 1;
__PACKAGE__->table('users');
__PACKAGE__->add_columns(
id => {
data_type => 'integer',
is_auto_increment => 1,
is_nullable => 0,
sequence => 'uid_seq'
},
qw(
uuid
username
name
main_group_name
),
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->add_unique_constraint(
'uuid' => [qw(uuid)]
);
1;
openapi: 3.0.3
info:
version: 0.1.0
title: CF Online
description: CF Online
license:
name: Artistic License 2.0
url: https://www.perlfoundation.org/artistic-license-20.html
contact:
name: Andrej Ramašeuski
email: andrej.ramaseuski@pirati.cz
url: https://pardubicky.pirati.cz/lide/andrej-ramaseuski/
servers:
- url: http://127.0.0.1:3000/api
description: Developement server
- url: https://cf2021.pirati.cz/api
description: Production server
components:
schemas:
ProgramScheduleEntry:
type: object
properties:
id:
type: integer
readOnly: true
number:
type: string
nullable: true
is_live:
type: boolean
title:
type: string
proposer:
type: string
nullable: true
description:
type: string
nullable: true
expectedStartAt:
type: string
expectedFinishAt:
type: string
nullable: true
securitySchemes:
Bearer:
name: Authorization
in: header
type: apiKey
paths:
/program:
get:
tags:
- program
summary: "Program zasedani"
operationId: getProgram
responses:
200:
description: Program zasedani
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ProgramScheduleEntry'
x-mojo-to: program#entries
#!/usr/bin/env perl
use strict;
use warnings;
use Mojo::File qw(curfile);
use lib curfile->dirname->sibling('lib')->to_string;
use Mojolicious::Commands;
# Start command line interface for application
Mojolicious::Commands->start_app('CF');
-- 1 up
create sequence "uid_seq" start 100000;
create table "program" (
"id" integer not null default nextval('uid_seq'),
"number" text,
"start" timestamp,
"finish" timestamp,
"is_approved" bool not null default 'false',
"is_live" bool not null default 'false',
"title" text not null,
"proposer" text,
"description" text,
primary key("id")
);
create table "users" (
"id" integer not null default nextval('uid_seq'),
"uuid" varchar(36) not null,
"username" text,
"name" text,
"main_group_name" text,
primary key("id"),
unique("uuid")
);
use Mojo::Base -strict;
use Test::More;
use Test::Mojo;
my $t = Test::Mojo->new('CF');
$t->get_ok('/')->status_is(200)->content_like(qr/Mojolicious/i);
done_testing();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment