Compare commits

..

15 Commits

Author SHA1 Message Date
45f8072679 feat: render the dummy test in json 2025-12-18 09:31:57 +01:00
984438729e docs: update readme 2025-12-18 07:28:59 +01:00
1e8bfc2ac0 build: update cpan.snapshot 2025-12-18 07:28:46 +01:00
1148a65355 build: add Mojo::Redis2 as a requirement 2025-12-18 07:28:41 +01:00
acb1f63bae feat: add a dummy set/get in the main route to try redis 2025-12-18 07:28:24 +01:00
6565be735d feat: add basic db logic 2025-12-18 07:27:55 +01:00
1de83a858e docs: update roadmap 2025-12-17 16:54:38 +01:00
7d7360fc16 feat: first version of installation script 2025-12-17 16:54:07 +01:00
8d6f2df942 docs: carton handles deps 2025-12-17 16:53:59 +01:00
34f400b421 docs: wording again 2025-12-17 14:43:10 +01:00
f98b67292b docs: fix wording 2025-12-17 14:29:33 +01:00
a00d409aba docs: get rid of Makefile.PL 2025-12-17 14:28:53 +01:00
f84c9dcbb4 feat: add basic skeleton app 2025-12-17 14:15:27 +01:00
5596014f8d build: add cpanfile.snapshot 2025-12-17 14:15:18 +01:00
912e8a35ab build: add cpanfile 2025-12-17 14:15:13 +01:00
7 changed files with 1030 additions and 14 deletions

View File

@@ -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

12
bin/urupam Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Urupam::App;
my $app = Urupam::App->new();
$app->start();

3
cpanfile Normal file
View File

@@ -0,0 +1,3 @@
requires 'Mojolicious', '>= 9.0';
requires 'Moose';
requires 'Mojo::Redis2';

857
cpanfile.snapshot Normal file
View File

@@ -0,0 +1,857 @@
# carton snapshot format: version 1.0
DISTRIBUTIONS
Class-Load-0.25
pathname: E/ET/ETHER/Class-Load-0.25.tar.gz
provides:
Class::Load 0.25
Class::Load::PP 0.25
requirements:
Carp 0
Data::OptList 0.110
Exporter 0
ExtUtils::MakeMaker 0
Module::Implementation 0.04
Module::Runtime 0.012
Package::Stash 0.14
Scalar::Util 0
Try::Tiny 0
base 0
perl 5.006
strict 0
warnings 0
Class-Load-XS-0.10
pathname: E/ET/ETHER/Class-Load-XS-0.10.tar.gz
provides:
Class::Load::XS 0.10
requirements:
Class::Load 0.20
ExtUtils::MakeMaker 0
XSLoader 0
perl 5.006
strict 0
warnings 0
Data-OptList-0.114
pathname: R/RJ/RJBS/Data-OptList-0.114.tar.gz
provides:
Data::OptList 0.114
requirements:
ExtUtils::MakeMaker 6.78
List::Util 0
Params::Util 0
Sub::Install 0.921
perl 5.012
strict 0
warnings 0
Devel-GlobalDestruction-0.14
pathname: H/HA/HAARG/Devel-GlobalDestruction-0.14.tar.gz
provides:
Devel::GlobalDestruction 0.14
requirements:
ExtUtils::MakeMaker 0
Sub::Exporter::Progressive 0.001011
perl 5.006
Devel-OverloadInfo-0.008
pathname: I/IL/ILMARI/Devel-OverloadInfo-0.008.tar.gz
provides:
Devel::OverloadInfo 0.008
requirements:
B 0
Exporter 5.57
ExtUtils::MakeMaker 0
MRO::Compat 0
Package::Stash 0.14
Scalar::Util 0
Sub::Util 1.40
Text::ParseWords 0
overload 0
perl 5.006
strict 0
warnings 0
Devel-StackTrace-2.05
pathname: D/DR/DROLSKY/Devel-StackTrace-2.05.tar.gz
provides:
Devel::StackTrace 2.05
Devel::StackTrace::Frame 2.05
requirements:
ExtUtils::MakeMaker 0
File::Spec 0
Scalar::Util 0
overload 0
perl 5.006
strict 0
warnings 0
Dist-CheckConflicts-0.11
pathname: D/DO/DOY/Dist-CheckConflicts-0.11.tar.gz
provides:
Dist::CheckConflicts 0.11
requirements:
Carp 0
Exporter 0
ExtUtils::MakeMaker 6.30
Module::Runtime 0.009
base 0
strict 0
warnings 0
Eval-Closure-0.14
pathname: D/DO/DOY/Eval-Closure-0.14.tar.gz
provides:
Eval::Closure 0.14
requirements:
Carp 0
Exporter 0
ExtUtils::MakeMaker 0
Scalar::Util 0
constant 0
overload 0
strict 0
warnings 0
MRO-Compat-0.15
pathname: H/HA/HAARG/MRO-Compat-0.15.tar.gz
provides:
MRO::Compat 0.15
requirements:
ExtUtils::MakeMaker 0
perl 5.006
Module-Implementation-0.09
pathname: D/DR/DROLSKY/Module-Implementation-0.09.tar.gz
provides:
Module::Implementation 0.09
requirements:
Carp 0
ExtUtils::MakeMaker 0
Module::Runtime 0.012
Try::Tiny 0
strict 0
warnings 0
Module-Runtime-0.018
pathname: H/HA/HAARG/Module-Runtime-0.018.tar.gz
provides:
Module::Runtime 0.018
requirements:
ExtUtils::MakeMaker 0
perl 5.006000
Module-Runtime-Conflicts-0.003
pathname: E/ET/ETHER/Module-Runtime-Conflicts-0.003.tar.gz
provides:
Module::Runtime::Conflicts 0.003
requirements:
Dist::CheckConflicts 0
ExtUtils::MakeMaker 0
Module::Runtime 0
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:
Mojo undef
Mojo::Asset undef
Mojo::Asset::File undef
Mojo::Asset::Memory undef
Mojo::Base undef
Mojo::BaseUtil undef
Mojo::ByteStream undef
Mojo::Cache undef
Mojo::Collection undef
Mojo::Content undef
Mojo::Content::MultiPart undef
Mojo::Content::Single undef
Mojo::Cookie undef
Mojo::Cookie::Request undef
Mojo::Cookie::Response undef
Mojo::DOM undef
Mojo::DOM::CSS undef
Mojo::DOM::HTML undef
Mojo::Date undef
Mojo::DynamicMethods undef
Mojo::EventEmitter undef
Mojo::Exception undef
Mojo::File undef
Mojo::Headers undef
Mojo::HelloWorld undef
Mojo::Home undef
Mojo::IOLoop undef
Mojo::IOLoop::Client undef
Mojo::IOLoop::Server undef
Mojo::IOLoop::Stream undef
Mojo::IOLoop::Subprocess undef
Mojo::IOLoop::TLS undef
Mojo::JSON undef
Mojo::JSON::Pointer undef
Mojo::Loader undef
Mojo::Log undef
Mojo::Message undef
Mojo::Message::Request undef
Mojo::Message::Response undef
Mojo::Parameters undef
Mojo::Path undef
Mojo::Promise undef
Mojo::Reactor undef
Mojo::Reactor::EV undef
Mojo::Reactor::Poll undef
Mojo::SSE undef
Mojo::Server undef
Mojo::Server::CGI undef
Mojo::Server::Daemon undef
Mojo::Server::Hypnotoad undef
Mojo::Server::Morbo undef
Mojo::Server::Morbo::Backend undef
Mojo::Server::Morbo::Backend::Poll undef
Mojo::Server::PSGI undef
Mojo::Server::Prefork undef
Mojo::Template undef
Mojo::Transaction undef
Mojo::Transaction::HTTP undef
Mojo::Transaction::WebSocket undef
Mojo::URL undef
Mojo::Upload undef
Mojo::UserAgent undef
Mojo::UserAgent::CookieJar undef
Mojo::UserAgent::Proxy undef
Mojo::UserAgent::Server undef
Mojo::UserAgent::Transactor undef
Mojo::Util undef
Mojo::WebSocket undef
Mojolicious 9.42
Mojolicious::Command undef
Mojolicious::Command::Author::cpanify undef
Mojolicious::Command::Author::generate undef
Mojolicious::Command::Author::generate::app undef
Mojolicious::Command::Author::generate::dockerfile undef
Mojolicious::Command::Author::generate::lite_app undef
Mojolicious::Command::Author::generate::makefile undef
Mojolicious::Command::Author::generate::plugin undef
Mojolicious::Command::Author::inflate undef
Mojolicious::Command::cgi undef
Mojolicious::Command::daemon undef
Mojolicious::Command::eval undef
Mojolicious::Command::get undef
Mojolicious::Command::prefork undef
Mojolicious::Command::psgi undef
Mojolicious::Command::routes undef
Mojolicious::Command::version undef
Mojolicious::Commands undef
Mojolicious::Controller undef
Mojolicious::Lite undef
Mojolicious::Plugin undef
Mojolicious::Plugin::Config undef
Mojolicious::Plugin::DefaultHelpers undef
Mojolicious::Plugin::EPLRenderer undef
Mojolicious::Plugin::EPRenderer undef
Mojolicious::Plugin::HeaderCondition undef
Mojolicious::Plugin::JSONConfig undef
Mojolicious::Plugin::Mount undef
Mojolicious::Plugin::NotYAMLConfig undef
Mojolicious::Plugin::TagHelpers undef
Mojolicious::Plugins undef
Mojolicious::Renderer undef
Mojolicious::Routes undef
Mojolicious::Routes::Match undef
Mojolicious::Routes::Pattern undef
Mojolicious::Routes::Route undef
Mojolicious::Sessions undef
Mojolicious::Static undef
Mojolicious::Types undef
Mojolicious::Validator undef
Mojolicious::Validator::Validation undef
Test::Mojo undef
ojo undef
requirements:
ExtUtils::MakeMaker 0
IO::Socket::IP 0.37
Sub::Util 1.41
perl 5.016
Moose-2.4000
pathname: E/ET/ETHER/Moose-2.4000.tar.gz
provides:
Class::MOP 2.4000
Class::MOP::Attribute 2.4000
Class::MOP::Class 2.4000
Class::MOP::Class::Immutable::Trait 2.4000
Class::MOP::Deprecated 2.4000
Class::MOP::Instance 2.4000
Class::MOP::Method 2.4000
Class::MOP::Method::Accessor 2.4000
Class::MOP::Method::Constructor 2.4000
Class::MOP::Method::Generated 2.4000
Class::MOP::Method::Inlined 2.4000
Class::MOP::Method::Meta 2.4000
Class::MOP::Method::Wrapped 2.4000
Class::MOP::MiniTrait 2.4000
Class::MOP::Mixin 2.4000
Class::MOP::Mixin::AttributeCore 2.4000
Class::MOP::Mixin::HasAttributes 2.4000
Class::MOP::Mixin::HasMethods 2.4000
Class::MOP::Mixin::HasOverloads 2.4000
Class::MOP::Module 2.4000
Class::MOP::Object 2.4000
Class::MOP::Overload 2.4000
Class::MOP::Package 2.4000
Moose 2.4000
Moose::Cookbook 2.4000
Moose::Cookbook::Basics::BankAccount_MethodModifiersAndSubclassing 2.4000
Moose::Cookbook::Basics::BinaryTree_AttributeFeatures 2.4000
Moose::Cookbook::Basics::BinaryTree_BuilderAndLazyBuild 2.4000
Moose::Cookbook::Basics::Company_Subtypes 2.4000
Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent 2.4000
Moose::Cookbook::Basics::Document_AugmentAndInner 2.4000
Moose::Cookbook::Basics::Genome_OverloadingSubtypesAndCoercion 2.4000
Moose::Cookbook::Basics::HTTP_SubtypesAndCoercion 2.4000
Moose::Cookbook::Basics::Immutable 2.4000
Moose::Cookbook::Basics::Person_BUILDARGSAndBUILD 2.4000
Moose::Cookbook::Basics::Point_AttributesAndSubclassing 2.4000
Moose::Cookbook::Extending::Debugging_BaseClassRole 2.4000
Moose::Cookbook::Extending::ExtensionOverview 2.4000
Moose::Cookbook::Extending::Mooseish_MooseSugar 2.4000
Moose::Cookbook::Legacy::Debugging_BaseClassReplacement 2.4000
Moose::Cookbook::Legacy::Labeled_AttributeMetaclass 2.4000
Moose::Cookbook::Legacy::Table_ClassMetaclass 2.4000
Moose::Cookbook::Meta::GlobRef_InstanceMetaclass 2.4000
Moose::Cookbook::Meta::Labeled_AttributeTrait 2.4000
Moose::Cookbook::Meta::PrivateOrPublic_MethodMetaclass 2.4000
Moose::Cookbook::Meta::Table_MetaclassTrait 2.4000
Moose::Cookbook::Meta::WhyMeta 2.4000
Moose::Cookbook::Roles::ApplicationToInstance 2.4000
Moose::Cookbook::Roles::Comparable_CodeReuse 2.4000
Moose::Cookbook::Roles::Restartable_AdvancedComposition 2.4000
Moose::Cookbook::Snack::Keywords 2.4000
Moose::Cookbook::Snack::Types 2.4000
Moose::Cookbook::Style 2.4000
Moose::Deprecated 2.4000
Moose::Exception 2.4000
Moose::Exception::AccessorMustReadWrite 2.4000
Moose::Exception::AddParameterizableTypeTakesParameterizableType 2.4000
Moose::Exception::AddRoleTakesAMooseMetaRoleInstance 2.4000
Moose::Exception::AddRoleToARoleTakesAMooseMetaRole 2.4000
Moose::Exception::ApplyTakesABlessedInstance 2.4000
Moose::Exception::AttachToClassNeedsAClassMOPClassInstanceOrASubclass 2.4000
Moose::Exception::AttributeConflictInRoles 2.4000
Moose::Exception::AttributeConflictInSummation 2.4000
Moose::Exception::AttributeExtensionIsNotSupportedInRoles 2.4000
Moose::Exception::AttributeIsRequired 2.4000
Moose::Exception::AttributeMustBeAnClassMOPMixinAttributeCoreOrSubclass 2.4000
Moose::Exception::AttributeNamesDoNotMatch 2.4000
Moose::Exception::AttributeValueIsNotAnObject 2.4000
Moose::Exception::AttributeValueIsNotDefined 2.4000
Moose::Exception::AutoDeRefNeedsArrayRefOrHashRef 2.4000
Moose::Exception::BadOptionFormat 2.4000
Moose::Exception::BothBuilderAndDefaultAreNotAllowed 2.4000
Moose::Exception::BuilderDoesNotExist 2.4000
Moose::Exception::BuilderMethodNotSupportedForAttribute 2.4000
Moose::Exception::BuilderMethodNotSupportedForInlineAttribute 2.4000
Moose::Exception::BuilderMustBeAMethodName 2.4000
Moose::Exception::CallingMethodOnAnImmutableInstance 2.4000
Moose::Exception::CallingReadOnlyMethodOnAnImmutableInstance 2.4000
Moose::Exception::CanExtendOnlyClasses 2.4000
Moose::Exception::CanOnlyConsumeRole 2.4000
Moose::Exception::CanOnlyWrapBlessedCode 2.4000
Moose::Exception::CanReblessOnlyIntoASubclass 2.4000
Moose::Exception::CanReblessOnlyIntoASuperclass 2.4000
Moose::Exception::CannotAddAdditionalTypeCoercionsToUnion 2.4000
Moose::Exception::CannotAddAsAnAttributeToARole 2.4000
Moose::Exception::CannotApplyBaseClassRolesToRole 2.4000
Moose::Exception::CannotAssignValueToReadOnlyAccessor 2.4000
Moose::Exception::CannotAugmentIfLocalMethodPresent 2.4000
Moose::Exception::CannotAugmentNoSuperMethod 2.4000
Moose::Exception::CannotAutoDerefWithoutIsa 2.4000
Moose::Exception::CannotAutoDereferenceTypeConstraint 2.4000
Moose::Exception::CannotCalculateNativeType 2.4000
Moose::Exception::CannotCallAnAbstractBaseMethod 2.4000
Moose::Exception::CannotCallAnAbstractMethod 2.4000
Moose::Exception::CannotCoerceAWeakRef 2.4000
Moose::Exception::CannotCoerceAttributeWhichHasNoCoercion 2.4000
Moose::Exception::CannotCreateHigherOrderTypeWithoutATypeParameter 2.4000
Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresent 2.4000
Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresentInClass 2.4000
Moose::Exception::CannotDelegateLocalMethodIsPresent 2.4000
Moose::Exception::CannotDelegateWithoutIsa 2.4000
Moose::Exception::CannotFindDelegateMetaclass 2.4000
Moose::Exception::CannotFindType 2.4000
Moose::Exception::CannotFindTypeGivenToMatchOnType 2.4000
Moose::Exception::CannotFixMetaclassCompatibility 2.4000
Moose::Exception::CannotGenerateInlineConstraint 2.4000
Moose::Exception::CannotInitializeMooseMetaRoleComposite 2.4000
Moose::Exception::CannotInlineTypeConstraintCheck 2.4000
Moose::Exception::CannotLocatePackageInINC 2.4000
Moose::Exception::CannotMakeMetaclassCompatible 2.4000
Moose::Exception::CannotOverrideALocalMethod 2.4000
Moose::Exception::CannotOverrideBodyOfMetaMethods 2.4000
Moose::Exception::CannotOverrideLocalMethodIsPresent 2.4000
Moose::Exception::CannotOverrideNoSuperMethod 2.4000
Moose::Exception::CannotRegisterUnnamedTypeConstraint 2.4000
Moose::Exception::CannotUseLazyBuildAndDefaultSimultaneously 2.4000
Moose::Exception::CircularReferenceInAlso 2.4000
Moose::Exception::ClassDoesNotHaveInitMeta 2.4000
Moose::Exception::ClassDoesTheExcludedRole 2.4000
Moose::Exception::ClassNamesDoNotMatch 2.4000
Moose::Exception::CloneObjectExpectsAnInstanceOfMetaclass 2.4000
Moose::Exception::CodeBlockMustBeACodeRef 2.4000
Moose::Exception::CoercingWithoutCoercions 2.4000
Moose::Exception::CoercionAlreadyExists 2.4000
Moose::Exception::CoercionNeedsTypeConstraint 2.4000
Moose::Exception::ConflictDetectedInCheckRoleExclusions 2.4000
Moose::Exception::ConflictDetectedInCheckRoleExclusionsInToClass 2.4000
Moose::Exception::ConstructClassInstanceTakesPackageName 2.4000
Moose::Exception::CouldNotCreateMethod 2.4000
Moose::Exception::CouldNotCreateWriter 2.4000
Moose::Exception::CouldNotEvalConstructor 2.4000
Moose::Exception::CouldNotEvalDestructor 2.4000
Moose::Exception::CouldNotFindTypeConstraintToCoerceFrom 2.4000
Moose::Exception::CouldNotGenerateInlineAttributeMethod 2.4000
Moose::Exception::CouldNotLocateTypeConstraintForUnion 2.4000
Moose::Exception::CouldNotParseType 2.4000
Moose::Exception::CreateMOPClassTakesArrayRefOfAttributes 2.4000
Moose::Exception::CreateMOPClassTakesArrayRefOfSuperclasses 2.4000
Moose::Exception::CreateMOPClassTakesHashRefOfMethods 2.4000
Moose::Exception::CreateTakesArrayRefOfRoles 2.4000
Moose::Exception::CreateTakesHashRefOfAttributes 2.4000
Moose::Exception::CreateTakesHashRefOfMethods 2.4000
Moose::Exception::DefaultToMatchOnTypeMustBeCodeRef 2.4000
Moose::Exception::DelegationToAClassWhichIsNotLoaded 2.4000
Moose::Exception::DelegationToARoleWhichIsNotLoaded 2.4000
Moose::Exception::DelegationToATypeWhichIsNotAClass 2.4000
Moose::Exception::DoesRequiresRoleName 2.4000
Moose::Exception::EnumCalledWithAnArrayRefAndAdditionalArgs 2.4000
Moose::Exception::EnumValuesMustBeString 2.4000
Moose::Exception::ExtendsMissingArgs 2.4000
Moose::Exception::HandlesMustBeAHashRef 2.4000
Moose::Exception::IllegalInheritedOptions 2.4000
Moose::Exception::IllegalMethodTypeToAddMethodModifier 2.4000
Moose::Exception::IncompatibleMetaclassOfSuperclass 2.4000
Moose::Exception::InitMetaRequiresClass 2.4000
Moose::Exception::InitializeTakesUnBlessedPackageName 2.4000
Moose::Exception::InstanceBlessedIntoWrongClass 2.4000
Moose::Exception::InstanceMustBeABlessedReference 2.4000
Moose::Exception::InvalidArgPassedToMooseUtilMetaRole 2.4000
Moose::Exception::InvalidArgumentToMethod 2.4000
Moose::Exception::InvalidArgumentsToTraitAliases 2.4000
Moose::Exception::InvalidBaseTypeGivenToCreateParameterizedTypeConstraint 2.4000
Moose::Exception::InvalidHandleValue 2.4000
Moose::Exception::InvalidHasProvidedInARole 2.4000
Moose::Exception::InvalidNameForType 2.4000
Moose::Exception::InvalidOverloadOperator 2.4000
Moose::Exception::InvalidRoleApplication 2.4000
Moose::Exception::InvalidTypeConstraint 2.4000
Moose::Exception::InvalidTypeGivenToCreateParameterizedTypeConstraint 2.4000
Moose::Exception::InvalidValueForIs 2.4000
Moose::Exception::IsaDoesNotDoTheRole 2.4000
Moose::Exception::IsaLacksDoesMethod 2.4000
Moose::Exception::LazyAttributeNeedsADefault 2.4000
Moose::Exception::Legacy 2.4000
Moose::Exception::MOPAttributeNewNeedsAttributeName 2.4000
Moose::Exception::MatchActionMustBeACodeRef 2.4000
Moose::Exception::MessageParameterMustBeCodeRef 2.4000
Moose::Exception::MetaclassIsAClassNotASubclassOfGivenMetaclass 2.4000
Moose::Exception::MetaclassIsARoleNotASubclassOfGivenMetaclass 2.4000
Moose::Exception::MetaclassIsNotASubclassOfGivenMetaclass 2.4000
Moose::Exception::MetaclassMustBeASubclassOfMooseMetaClass 2.4000
Moose::Exception::MetaclassMustBeASubclassOfMooseMetaRole 2.4000
Moose::Exception::MetaclassMustBeDerivedFromClassMOPClass 2.4000
Moose::Exception::MetaclassNotLoaded 2.4000
Moose::Exception::MetaclassTypeIncompatible 2.4000
Moose::Exception::MethodExpectedAMetaclassObject 2.4000
Moose::Exception::MethodExpectsFewerArgs 2.4000
Moose::Exception::MethodExpectsMoreArgs 2.4000
Moose::Exception::MethodModifierNeedsMethodName 2.4000
Moose::Exception::MethodNameConflictInRoles 2.4000
Moose::Exception::MethodNameNotFoundInInheritanceHierarchy 2.4000
Moose::Exception::MethodNameNotGiven 2.4000
Moose::Exception::MustDefineAMethodName 2.4000
Moose::Exception::MustDefineAnAttributeName 2.4000
Moose::Exception::MustDefineAnOverloadOperator 2.4000
Moose::Exception::MustHaveAtLeastOneValueToEnumerate 2.4000
Moose::Exception::MustPassAHashOfOptions 2.4000
Moose::Exception::MustPassAMooseMetaRoleInstanceOrSubclass 2.4000
Moose::Exception::MustPassAPackageNameOrAnExistingClassMOPPackageInstance 2.4000
Moose::Exception::MustPassEvenNumberOfArguments 2.4000
Moose::Exception::MustPassEvenNumberOfAttributeOptions 2.4000
Moose::Exception::MustProvideANameForTheAttribute 2.4000
Moose::Exception::MustSpecifyAtleastOneMethod 2.4000
Moose::Exception::MustSpecifyAtleastOneRole 2.4000
Moose::Exception::MustSpecifyAtleastOneRoleToApplicant 2.4000
Moose::Exception::MustSupplyAClassMOPAttributeInstance 2.4000
Moose::Exception::MustSupplyADelegateToMethod 2.4000
Moose::Exception::MustSupplyAMetaclass 2.4000
Moose::Exception::MustSupplyAMooseMetaAttributeInstance 2.4000
Moose::Exception::MustSupplyAnAccessorTypeToConstructWith 2.4000
Moose::Exception::MustSupplyAnAttributeToConstructWith 2.4000
Moose::Exception::MustSupplyArrayRefAsCurriedArguments 2.4000
Moose::Exception::MustSupplyPackageNameAndName 2.4000
Moose::Exception::NeedsTypeConstraintUnionForTypeCoercionUnion 2.4000
Moose::Exception::NeitherAttributeNorAttributeNameIsGiven 2.4000
Moose::Exception::NeitherClassNorClassNameIsGiven 2.4000
Moose::Exception::NeitherRoleNorRoleNameIsGiven 2.4000
Moose::Exception::NeitherTypeNorTypeNameIsGiven 2.4000
Moose::Exception::NoAttributeFoundInSuperClass 2.4000
Moose::Exception::NoBodyToInitializeInAnAbstractBaseClass 2.4000
Moose::Exception::NoCasesMatched 2.4000
Moose::Exception::NoConstraintCheckForTypeConstraint 2.4000
Moose::Exception::NoDestructorClassSpecified 2.4000
Moose::Exception::NoImmutableTraitSpecifiedForClass 2.4000
Moose::Exception::NoParentGivenToSubtype 2.4000
Moose::Exception::OnlyInstancesCanBeCloned 2.4000
Moose::Exception::OperatorIsRequired 2.4000
Moose::Exception::OverloadConflictInSummation 2.4000
Moose::Exception::OverloadRequiresAMetaClass 2.4000
Moose::Exception::OverloadRequiresAMetaMethod 2.4000
Moose::Exception::OverloadRequiresAMetaOverload 2.4000
Moose::Exception::OverloadRequiresAMethodNameOrCoderef 2.4000
Moose::Exception::OverloadRequiresAnOperator 2.4000
Moose::Exception::OverloadRequiresNamesForCoderef 2.4000
Moose::Exception::OverrideConflictInComposition 2.4000
Moose::Exception::OverrideConflictInSummation 2.4000
Moose::Exception::PackageDoesNotUseMooseExporter 2.4000
Moose::Exception::PackageNameAndNameParamsNotGivenToWrap 2.4000
Moose::Exception::PackagesAndModulesAreNotCachable 2.4000
Moose::Exception::ParameterIsNotSubtypeOfParent 2.4000
Moose::Exception::ReferencesAreNotAllowedAsDefault 2.4000
Moose::Exception::RequiredAttributeLacksInitialization 2.4000
Moose::Exception::RequiredAttributeNeedsADefault 2.4000
Moose::Exception::RequiredMethodsImportedByClass 2.4000
Moose::Exception::RequiredMethodsNotImplementedByClass 2.4000
Moose::Exception::Role::Attribute 2.4000
Moose::Exception::Role::AttributeName 2.4000
Moose::Exception::Role::Class 2.4000
Moose::Exception::Role::EitherAttributeOrAttributeName 2.4000
Moose::Exception::Role::Instance 2.4000
Moose::Exception::Role::InstanceClass 2.4000
Moose::Exception::Role::InvalidAttributeOptions 2.4000
Moose::Exception::Role::Method 2.4000
Moose::Exception::Role::ParamsHash 2.4000
Moose::Exception::Role::Role 2.4000
Moose::Exception::Role::RoleForCreate 2.4000
Moose::Exception::Role::RoleForCreateMOPClass 2.4000
Moose::Exception::Role::TypeConstraint 2.4000
Moose::Exception::RoleDoesTheExcludedRole 2.4000
Moose::Exception::RoleExclusionConflict 2.4000
Moose::Exception::RoleNameRequired 2.4000
Moose::Exception::RoleNameRequiredForMooseMetaRole 2.4000
Moose::Exception::RolesDoNotSupportAugment 2.4000
Moose::Exception::RolesDoNotSupportExtends 2.4000
Moose::Exception::RolesDoNotSupportInner 2.4000
Moose::Exception::RolesDoNotSupportRegexReferencesForMethodModifiers 2.4000
Moose::Exception::RolesInCreateTakesAnArrayRef 2.4000
Moose::Exception::RolesListMustBeInstancesOfMooseMetaRole 2.4000
Moose::Exception::SingleParamsToNewMustBeHashRef 2.4000
Moose::Exception::TriggerMustBeACodeRef 2.4000
Moose::Exception::TypeConstraintCannotBeUsedForAParameterizableType 2.4000
Moose::Exception::TypeConstraintIsAlreadyCreated 2.4000
Moose::Exception::TypeParameterMustBeMooseMetaType 2.4000
Moose::Exception::UnableToCanonicalizeHandles 2.4000
Moose::Exception::UnableToCanonicalizeNonRolePackage 2.4000
Moose::Exception::UnableToRecognizeDelegateMetaclass 2.4000
Moose::Exception::UndefinedHashKeysPassedToMethod 2.4000
Moose::Exception::UnionCalledWithAnArrayRefAndAdditionalArgs 2.4000
Moose::Exception::UnionTakesAtleastTwoTypeNames 2.4000
Moose::Exception::ValidationFailedForInlineTypeConstraint 2.4000
Moose::Exception::ValidationFailedForTypeConstraint 2.4000
Moose::Exception::WrapTakesACodeRefToBless 2.4000
Moose::Exception::WrongTypeConstraintGiven 2.4000
Moose::Exporter 2.4000
Moose::Intro 2.4000
Moose::Manual 2.4000
Moose::Manual::Attributes 2.4000
Moose::Manual::BestPractices 2.4000
Moose::Manual::Classes 2.4000
Moose::Manual::Concepts 2.4000
Moose::Manual::Construction 2.4000
Moose::Manual::Contributing 2.4000
Moose::Manual::Delegation 2.4000
Moose::Manual::Delta 2.4000
Moose::Manual::Exceptions 2.4000
Moose::Manual::Exceptions::Manifest 2.4000
Moose::Manual::FAQ 2.4000
Moose::Manual::MOP 2.4000
Moose::Manual::MethodModifiers 2.4000
Moose::Manual::MooseX 2.4000
Moose::Manual::Resources 2.4000
Moose::Manual::Roles 2.4000
Moose::Manual::Support 2.4000
Moose::Manual::Types 2.4000
Moose::Manual::Unsweetened 2.4000
Moose::Meta::Attribute 2.4000
Moose::Meta::Attribute::Native 2.4000
Moose::Meta::Attribute::Native::Trait 2.4000
Moose::Meta::Attribute::Native::Trait::Array 2.4000
Moose::Meta::Attribute::Native::Trait::Bool 2.4000
Moose::Meta::Attribute::Native::Trait::Code 2.4000
Moose::Meta::Attribute::Native::Trait::Counter 2.4000
Moose::Meta::Attribute::Native::Trait::Hash 2.4000
Moose::Meta::Attribute::Native::Trait::Number 2.4000
Moose::Meta::Attribute::Native::Trait::String 2.4000
Moose::Meta::Class 2.4000
Moose::Meta::Class::Immutable::Trait 2.4000
Moose::Meta::Instance 2.4000
Moose::Meta::Method 2.4000
Moose::Meta::Method::Accessor 2.4000
Moose::Meta::Method::Accessor::Native 2.4000
Moose::Meta::Method::Accessor::Native::Array 2.4000
Moose::Meta::Method::Accessor::Native::Array::Writer 2.4000
Moose::Meta::Method::Accessor::Native::Array::accessor 2.4000
Moose::Meta::Method::Accessor::Native::Array::clear 2.4000
Moose::Meta::Method::Accessor::Native::Array::count 2.4000
Moose::Meta::Method::Accessor::Native::Array::delete 2.4000
Moose::Meta::Method::Accessor::Native::Array::elements 2.4000
Moose::Meta::Method::Accessor::Native::Array::first 2.4000
Moose::Meta::Method::Accessor::Native::Array::first_index 2.4000
Moose::Meta::Method::Accessor::Native::Array::get 2.4000
Moose::Meta::Method::Accessor::Native::Array::grep 2.4000
Moose::Meta::Method::Accessor::Native::Array::insert 2.4000
Moose::Meta::Method::Accessor::Native::Array::is_empty 2.4000
Moose::Meta::Method::Accessor::Native::Array::join 2.4000
Moose::Meta::Method::Accessor::Native::Array::map 2.4000
Moose::Meta::Method::Accessor::Native::Array::natatime 2.4000
Moose::Meta::Method::Accessor::Native::Array::pop 2.4000
Moose::Meta::Method::Accessor::Native::Array::push 2.4000
Moose::Meta::Method::Accessor::Native::Array::reduce 2.4000
Moose::Meta::Method::Accessor::Native::Array::set 2.4000
Moose::Meta::Method::Accessor::Native::Array::shallow_clone 2.4000
Moose::Meta::Method::Accessor::Native::Array::shift 2.4000
Moose::Meta::Method::Accessor::Native::Array::shuffle 2.4000
Moose::Meta::Method::Accessor::Native::Array::sort 2.4000
Moose::Meta::Method::Accessor::Native::Array::sort_in_place 2.4000
Moose::Meta::Method::Accessor::Native::Array::splice 2.4000
Moose::Meta::Method::Accessor::Native::Array::uniq 2.4000
Moose::Meta::Method::Accessor::Native::Array::unshift 2.4000
Moose::Meta::Method::Accessor::Native::Bool::not 2.4000
Moose::Meta::Method::Accessor::Native::Bool::set 2.4000
Moose::Meta::Method::Accessor::Native::Bool::toggle 2.4000
Moose::Meta::Method::Accessor::Native::Bool::unset 2.4000
Moose::Meta::Method::Accessor::Native::Code::execute 2.4000
Moose::Meta::Method::Accessor::Native::Code::execute_method 2.4000
Moose::Meta::Method::Accessor::Native::Collection 2.4000
Moose::Meta::Method::Accessor::Native::Counter::Writer 2.4000
Moose::Meta::Method::Accessor::Native::Counter::dec 2.4000
Moose::Meta::Method::Accessor::Native::Counter::inc 2.4000
Moose::Meta::Method::Accessor::Native::Counter::reset 2.4000
Moose::Meta::Method::Accessor::Native::Counter::set 2.4000
Moose::Meta::Method::Accessor::Native::Hash 2.4000
Moose::Meta::Method::Accessor::Native::Hash::Writer 2.4000
Moose::Meta::Method::Accessor::Native::Hash::accessor 2.4000
Moose::Meta::Method::Accessor::Native::Hash::clear 2.4000
Moose::Meta::Method::Accessor::Native::Hash::count 2.4000
Moose::Meta::Method::Accessor::Native::Hash::defined 2.4000
Moose::Meta::Method::Accessor::Native::Hash::delete 2.4000
Moose::Meta::Method::Accessor::Native::Hash::elements 2.4000
Moose::Meta::Method::Accessor::Native::Hash::exists 2.4000
Moose::Meta::Method::Accessor::Native::Hash::get 2.4000
Moose::Meta::Method::Accessor::Native::Hash::is_empty 2.4000
Moose::Meta::Method::Accessor::Native::Hash::keys 2.4000
Moose::Meta::Method::Accessor::Native::Hash::kv 2.4000
Moose::Meta::Method::Accessor::Native::Hash::set 2.4000
Moose::Meta::Method::Accessor::Native::Hash::shallow_clone 2.4000
Moose::Meta::Method::Accessor::Native::Hash::values 2.4000
Moose::Meta::Method::Accessor::Native::Number::abs 2.4000
Moose::Meta::Method::Accessor::Native::Number::add 2.4000
Moose::Meta::Method::Accessor::Native::Number::div 2.4000
Moose::Meta::Method::Accessor::Native::Number::mod 2.4000
Moose::Meta::Method::Accessor::Native::Number::mul 2.4000
Moose::Meta::Method::Accessor::Native::Number::set 2.4000
Moose::Meta::Method::Accessor::Native::Number::sub 2.4000
Moose::Meta::Method::Accessor::Native::Reader 2.4000
Moose::Meta::Method::Accessor::Native::String::append 2.4000
Moose::Meta::Method::Accessor::Native::String::chomp 2.4000
Moose::Meta::Method::Accessor::Native::String::chop 2.4000
Moose::Meta::Method::Accessor::Native::String::clear 2.4000
Moose::Meta::Method::Accessor::Native::String::inc 2.4000
Moose::Meta::Method::Accessor::Native::String::length 2.4000
Moose::Meta::Method::Accessor::Native::String::match 2.4000
Moose::Meta::Method::Accessor::Native::String::prepend 2.4000
Moose::Meta::Method::Accessor::Native::String::replace 2.4000
Moose::Meta::Method::Accessor::Native::String::substr 2.4000
Moose::Meta::Method::Accessor::Native::Writer 2.4000
Moose::Meta::Method::Augmented 2.4000
Moose::Meta::Method::Constructor 2.4000
Moose::Meta::Method::Delegation 2.4000
Moose::Meta::Method::Destructor 2.4000
Moose::Meta::Method::Meta 2.4000
Moose::Meta::Method::Overridden 2.4000
Moose::Meta::Mixin::AttributeCore 2.4000
Moose::Meta::Object::Trait 2.4000
Moose::Meta::Role 2.4000
Moose::Meta::Role::Application 2.4000
Moose::Meta::Role::Application::RoleSummation 2.4000
Moose::Meta::Role::Application::ToClass 2.4000
Moose::Meta::Role::Application::ToInstance 2.4000
Moose::Meta::Role::Application::ToRole 2.4000
Moose::Meta::Role::Attribute 2.4000
Moose::Meta::Role::Composite 2.4000
Moose::Meta::Role::Method 2.4000
Moose::Meta::Role::Method::Conflicting 2.4000
Moose::Meta::Role::Method::Required 2.4000
Moose::Meta::TypeCoercion 2.4000
Moose::Meta::TypeCoercion::Union 2.4000
Moose::Meta::TypeConstraint 2.4000
Moose::Meta::TypeConstraint::Class 2.4000
Moose::Meta::TypeConstraint::DuckType 2.4000
Moose::Meta::TypeConstraint::Enum 2.4000
Moose::Meta::TypeConstraint::Parameterizable 2.4000
Moose::Meta::TypeConstraint::Parameterized 2.4000
Moose::Meta::TypeConstraint::Registry 2.4000
Moose::Meta::TypeConstraint::Role 2.4000
Moose::Meta::TypeConstraint::Union 2.4000
Moose::Object 2.4000
Moose::Role 2.4000
Moose::Spec::Role 2.4000
Moose::Unsweetened 2.4000
Moose::Util 2.4000
Moose::Util::MetaRole 2.4000
Moose::Util::TypeConstraints 2.4000
Moose::Util::TypeConstraints::Builtins 2.4000
Test::Moose 2.4000
metaclass 2.4000
oose 2.4000
requirements:
Carp 1.22
Class::Load 0.09
Class::Load::XS 0.01
Data::OptList 0.107
Devel::GlobalDestruction 0
Devel::OverloadInfo 0.005
Devel::StackTrace 2.03
Dist::CheckConflicts 0.02
Eval::Closure 0.04
ExtUtils::MakeMaker 0
List::Util 1.56
MRO::Compat 0.05
Module::Runtime 0.014
Module::Runtime::Conflicts 0.002
Package::DeprecationManager 0.11
Package::Stash 0.32
Package::Stash::XS 0.24
Params::Util 1.00
Scalar::Util 1.19
Sub::Exporter 0.980
Sub::Util 1.40
Try::Tiny 0.17
parent 0.223
strict 1.03
warnings 1.03
Package-DeprecationManager-0.18
pathname: D/DR/DROLSKY/Package-DeprecationManager-0.18.tar.gz
provides:
Package::DeprecationManager 0.18
requirements:
Carp 0
ExtUtils::MakeMaker 0
List::Util 1.33
Package::Stash 0
Params::Util 0
Sub::Install 0
Sub::Util 0
strict 0
warnings 0
Package-Stash-0.40
pathname: E/ET/ETHER/Package-Stash-0.40.tar.gz
provides:
Package::Stash 0.40
Package::Stash::PP 0.40
requirements:
B 0
Carp 0
Dist::CheckConflicts 0.02
ExtUtils::MakeMaker 0
Getopt::Long 0
Module::Implementation 0.06
Package::Stash::XS 0.26
Scalar::Util 0
Symbol 0
Text::ParseWords 0
constant 0
perl 5.008001
strict 0
warnings 0
Package-Stash-XS-0.30
pathname: E/ET/ETHER/Package-Stash-XS-0.30.tar.gz
provides:
Package::Stash::XS 0.30
requirements:
ExtUtils::MakeMaker 0
XSLoader 0
perl 5.008001
strict 0
warnings 0
Params-Util-1.102
pathname: R/RE/REHSACK/Params-Util-1.102.tar.gz
provides:
Params::Util 1.102
Params::Util::PP 1.102
requirements:
Carp 0
ExtUtils::MakeMaker 0
File::Basename 0
File::Copy 0
File::Path 0
File::Spec 0
IPC::Cmd 0
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:
Sub::Exporter 0.991
Sub::Exporter::Util 0.991
requirements:
Carp 0
Data::OptList 0.100
ExtUtils::MakeMaker 6.78
Params::Util 0.14
Sub::Install 0.92
perl 5.012
strict 0
warnings 0
Sub-Exporter-Progressive-0.001013
pathname: F/FR/FREW/Sub-Exporter-Progressive-0.001013.tar.gz
provides:
Sub::Exporter::Progressive 0.001013
requirements:
ExtUtils::MakeMaker 0
Sub-Install-0.929
pathname: R/RJ/RJBS/Sub-Install-0.929.tar.gz
provides:
Sub::Install 0.929
requirements:
B 0
Carp 0
ExtUtils::MakeMaker 6.78
Scalar::Util 0
perl 5.008000
strict 0
warnings 0
Try-Tiny-0.32
pathname: E/ET/ETHER/Try-Tiny-0.32.tar.gz
provides:
Try::Tiny 0.32
requirements:
Carp 0
Exporter 5.57
ExtUtils::MakeMaker 0
constant 0
perl 5.006
strict 0
warnings 0

50
lib/Urupam/App.pm Normal file
View File

@@ -0,0 +1,50 @@
package Urupam::App;
use Mojo::Base 'Mojolicious';
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;
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
View 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
View 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