Compare commits
12 Commits
f84c9dcbb4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 45f8072679 | |||
| 984438729e | |||
| 1e8bfc2ac0 | |||
| 1148a65355 | |||
| acb1f63bae | |||
| 6565be735d | |||
| 1de83a858e | |||
| 7d7360fc16 | |||
| 8d6f2df942 | |||
| 34f400b421 | |||
| f98b67292b | |||
| a00d409aba |
24
README.md
24
README.md
@@ -1,15 +1,17 @@
|
||||
# urupam
|
||||
|
||||
`urupam` is a small URL shortener written in Perl with Mojolicious, using Redis for storage.
|
||||
`urupam` is a lightweight URL shortener built with Perl and Mojolicious, and backed by Redis.
|
||||
|
||||
## Requirements
|
||||
## Basic requirements
|
||||
|
||||
- Perl 5.42.0
|
||||
- Mojolicious 9.42
|
||||
- Carton (handles perl deps)
|
||||
- Redis
|
||||
|
||||
## Roadmap
|
||||
|
||||
- [ ] connect to redis
|
||||
- [x] create installation script
|
||||
- [x] connect to redis + setter and getter operations
|
||||
- [ ] create dummy API endpoints
|
||||
- [ ] decide how to handle short url generation
|
||||
- [ ] avoid collisions in short urls
|
||||
@@ -17,7 +19,6 @@
|
||||
- [ ] validate URLs and handle errors
|
||||
- [ ] create a simple and clean UI
|
||||
- [ ] manage/delete short urls
|
||||
- [ ] create `Makefile.PL`
|
||||
- [ ] create systemd service
|
||||
- [ ] create `Dockerfile`
|
||||
- [ ] create `docker-compose.yml`
|
||||
@@ -25,8 +26,6 @@
|
||||
|
||||
## How to run
|
||||
|
||||
### Dev
|
||||
|
||||
To run the application in development, you'll first need a Redis server. The easiest way is to start a local Redis instance using Docker:
|
||||
|
||||
```sh
|
||||
@@ -47,18 +46,15 @@ carton exec morbo bin/urupam
|
||||
|
||||
Open [http://127.0.0.1:3000](http://127.0.0.1:3000) in your browser.
|
||||
|
||||
### Install
|
||||
## Installation
|
||||
|
||||
Use the provided `Makefile.pl`:
|
||||
Run the installation script:
|
||||
|
||||
```sh
|
||||
perl Makefile.PL
|
||||
make
|
||||
make test
|
||||
sudo make install
|
||||
scripts/install.sh
|
||||
```
|
||||
|
||||
Activate/enable the systemd service:
|
||||
Enable and start the systemd service:
|
||||
|
||||
```sh
|
||||
sudo systemctl enable --now urupam
|
||||
|
||||
1
cpanfile
1
cpanfile
@@ -1,2 +1,3 @@
|
||||
requires 'Mojolicious', '>= 9.0';
|
||||
requires 'Moose';
|
||||
requires 'Mojo::Redis2';
|
||||
|
||||
@@ -141,6 +141,20 @@ DISTRIBUTIONS
|
||||
perl 5.006
|
||||
strict 0
|
||||
warnings 0
|
||||
Mojo-Redis2-0.32
|
||||
pathname: D/DB/DBOOK/Mojo-Redis2-0.32.tar.gz
|
||||
provides:
|
||||
Mojo::Redis2 0.32
|
||||
Mojo::Redis2::Backend undef
|
||||
Mojo::Redis2::Bulk undef
|
||||
Mojo::Redis2::Client undef
|
||||
Mojo::Redis2::Cursor undef
|
||||
Mojo::Redis2::Server undef
|
||||
Mojo::Redis2::Transaction 0.01
|
||||
requirements:
|
||||
ExtUtils::MakeMaker 0
|
||||
Mojolicious 7.50
|
||||
Protocol::Redis 1.0
|
||||
Mojolicious-9.42
|
||||
pathname: S/SR/SRI/Mojolicious-9.42.tar.gz
|
||||
provides:
|
||||
@@ -787,6 +801,16 @@ DISTRIBUTIONS
|
||||
Scalar::Util 1.18
|
||||
XSLoader 0.22
|
||||
parent 0
|
||||
Protocol-Redis-1.0021
|
||||
pathname: U/UN/UNDEF/Protocol-Redis-1.0021.tar.gz
|
||||
provides:
|
||||
Protocol::Redis 1.0021
|
||||
Protocol::Redis::Test undef
|
||||
requirements:
|
||||
Carp 0
|
||||
ExtUtils::MakeMaker 0
|
||||
Test::More 0.94
|
||||
perl 5.008001
|
||||
Sub-Exporter-0.991
|
||||
pathname: R/RJ/RJBS/Sub-Exporter-0.991.tar.gz
|
||||
provides:
|
||||
|
||||
@@ -1,19 +1,50 @@
|
||||
package Urupam::App;
|
||||
|
||||
use Mojo::Base 'Mojolicious';
|
||||
use Moose;
|
||||
use Urupam::DB;
|
||||
|
||||
sub startup {
|
||||
my $self = shift;
|
||||
|
||||
$self->helper(
|
||||
db => sub {
|
||||
my $c = shift;
|
||||
$c->stash->{db} ||= Urupam::DB->new;
|
||||
}
|
||||
);
|
||||
|
||||
my $r = $self->routes;
|
||||
$r->get('/')->to(
|
||||
cb => sub {
|
||||
my $c = shift;
|
||||
$c->render( text => 'Hello from urupam!' );
|
||||
my $tx = $c->render_later->tx;
|
||||
my $db = $c->db;
|
||||
|
||||
$db->set( 'test_key' => '123soleil' )->then(
|
||||
sub {
|
||||
$c->app->log->info('Value set: test_key => 123soleil');
|
||||
return $db->get('test_key');
|
||||
}
|
||||
)->then(
|
||||
sub {
|
||||
my $value = shift;
|
||||
$c->app->log->info("Value retrieved: $value");
|
||||
$c->render( json => { status => 'ok', value => $value } );
|
||||
undef $tx;
|
||||
}
|
||||
)->catch(
|
||||
sub {
|
||||
my $err = shift;
|
||||
$c->app->log->error("DB error: $err");
|
||||
$c->render(
|
||||
json => { status => 'error', message => "$err" },
|
||||
status => 500
|
||||
);
|
||||
undef $tx;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
36
lib/Urupam/DB.pm
Normal file
36
lib/Urupam/DB.pm
Normal file
@@ -0,0 +1,36 @@
|
||||
package Urupam::DB;
|
||||
|
||||
use Mojo::Base -base;
|
||||
use Mojo::Promise;
|
||||
use Mojo::Redis2;
|
||||
|
||||
has redis => sub {
|
||||
Mojo::Redis2->new( url => $ENV{REDIS_URL} || 'redis://localhost:6379' );
|
||||
};
|
||||
|
||||
sub get {
|
||||
my ( $self, $key ) = @_;
|
||||
my $promise = Mojo::Promise->new;
|
||||
$self->redis->get(
|
||||
$key => sub {
|
||||
my ( $redis, $err, $value ) = @_;
|
||||
$err ? $promise->reject($err) : $promise->resolve($value);
|
||||
}
|
||||
);
|
||||
return $promise;
|
||||
}
|
||||
|
||||
sub set {
|
||||
my ( $self, $key, $value ) = @_;
|
||||
my $promise = Mojo::Promise->new;
|
||||
$self->redis->set(
|
||||
$key => $value,
|
||||
sub {
|
||||
my ( $redis, $err, $result ) = @_;
|
||||
$err ? $promise->reject($err) : $promise->resolve($result);
|
||||
}
|
||||
);
|
||||
return $promise;
|
||||
}
|
||||
|
||||
1;
|
||||
62
scripts/install.sh
Normal file
62
scripts/install.sh
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
# simple helper to deploy urupam
|
||||
|
||||
# fail-fast
|
||||
set -euo pipefail
|
||||
|
||||
# get root or get out
|
||||
if [[ $(id -u) != 0 ]]; then
|
||||
echo "Please use sudo or run as root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check carton
|
||||
if ! command -v carton &>/dev/null; then
|
||||
echo "carton not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check redis
|
||||
if ! ss -ltn | grep -q ":6379"; then
|
||||
echo "Redis isn't running, check README."
|
||||
fi
|
||||
|
||||
# create urupam user
|
||||
groupadd urupam
|
||||
useradd -s /bin/bash -g urupam -d /opt/urupam urupam
|
||||
|
||||
# deploy code
|
||||
cp -r bin lib cpan* /opt/urupam
|
||||
chown -R urupam:urupam /opt/urupam
|
||||
|
||||
# install dependencies
|
||||
su - urupam -c "cd /opt/urupam && carton install ."
|
||||
|
||||
# create systemd service
|
||||
cat >>/etc/systemd/system/urupam.service <<EOF
|
||||
[Unit]
|
||||
Description=Urupam
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=urupam
|
||||
Group=urupam
|
||||
WorkingDirectory=/opt/urupam
|
||||
ExecStart=carton exec -- bin/urupam
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
|
||||
# install documentation
|
||||
mkdir -p /usr/share/doc/urupam
|
||||
cp README.md LICENSE /usr/share/doc/urupam
|
||||
|
||||
# enable and start service
|
||||
systemctl enable --now urupam
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user