Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit c6d4bd09c2c358c5ae320b2e8f546bc816b33e0e 0 parents
@reneeb authored
Showing with 3,020 additions and 0 deletions.
  1. +34 −0 admin.cgi
  2. +18 −0 analyzer_test.pl
  3. +13 −0 conf/base.yml
  4. +11 −0 conf/daemon.yml
  5. +12 −0 conf/logging.conf
  6. +23 −0 conf/perlcriticrc
  7. +15 −0 conf/perltidyrc
  8. +28 −0 create_schema.pl
  9. +16 −0 dist.ini
  10. +66 −0 get_modules.pl
  11. +47 −0 lib/OPR/DAO/AccessMatrix.pm
  12. +31 −0 lib/OPR/DAO/Author.pm
  13. +29 −0 lib/OPR/DAO/Base.pm
  14. +44 −0 lib/OPR/DAO/Package.pm
  15. +7 −0 lib/OPR/DB/Schema.pm
  16. +19 −0 lib/OPR/DB/Schema/Result/Session.pm
  17. +22 −0 lib/OPR/DB/Schema/Result/opr_comments.pm
  18. +22 −0 lib/OPR/DB/Schema/Result/opr_component.pm
  19. +26 −0 lib/OPR/DB/Schema/Result/opr_functions.pm
  20. +24 −0 lib/OPR/DB/Schema/Result/opr_group.pm
  21. +24 −0 lib/OPR/DB/Schema/Result/opr_group_functions.pm
  22. +24 −0 lib/OPR/DB/Schema/Result/opr_group_user.pm
  23. +25 −0 lib/OPR/DB/Schema/Result/opr_job_queue.pm
  24. +21 −0 lib/OPR/DB/Schema/Result/opr_job_type.pm
  25. +23 −0 lib/OPR/DB/Schema/Result/opr_oq_entity.pm
  26. +27 −0 lib/OPR/DB/Schema/Result/opr_oq_result.pm
  27. +40 −0 lib/OPR/DB/Schema/Result/opr_package.pm
  28. +25 −0 lib/OPR/DB/Schema/Result/opr_package_author.pm
  29. +24 −0 lib/OPR/DB/Schema/Result/opr_package_dependencies.pm
  30. +32 −0 lib/OPR/DB/Schema/Result/opr_user.pm
  31. +44 −0 lib/OTRS/OPR/App/Attributes.pm
  32. +29 −0 lib/OTRS/OPR/DAO/Base.pm
  33. +11 −0 lib/OTRS/OPR/DAO/User.pm
  34. +55 −0 lib/OTRS/OPR/DB/Helper/Comment.pm
  35. +56 −0 lib/OTRS/OPR/DB/Helper/Job.pm
  36. +55 −0 lib/OTRS/OPR/DB/Helper/Package.pm
  37. +46 −0 lib/OTRS/OPR/DB/Helper/User.pm
  38. +7 −0 lib/OTRS/OPR/DB/Schema.pm
  39. +19 −0 lib/OTRS/OPR/DB/Schema/Result/Session.pm
  40. +25 −0 lib/OTRS/OPR/DB/Schema/Result/opr_comments.pm
  41. +22 −0 lib/OTRS/OPR/DB/Schema/Result/opr_component.pm
  42. +26 −0 lib/OTRS/OPR/DB/Schema/Result/opr_functions.pm
  43. +24 −0 lib/OTRS/OPR/DB/Schema/Result/opr_group.pm
  44. +24 −0 lib/OTRS/OPR/DB/Schema/Result/opr_group_functions.pm
  45. +24 −0 lib/OTRS/OPR/DB/Schema/Result/opr_group_user.pm
  46. +25 −0 lib/OTRS/OPR/DB/Schema/Result/opr_job_queue.pm
  47. +21 −0 lib/OTRS/OPR/DB/Schema/Result/opr_job_type.pm
  48. +23 −0 lib/OTRS/OPR/DB/Schema/Result/opr_oq_entity.pm
  49. +27 −0 lib/OTRS/OPR/DB/Schema/Result/opr_oq_result.pm
  50. +41 −0 lib/OTRS/OPR/DB/Schema/Result/opr_package.pm
  51. +25 −0 lib/OTRS/OPR/DB/Schema/Result/opr_package_author.pm
  52. +24 −0 lib/OTRS/OPR/DB/Schema/Result/opr_package_dependencies.pm
  53. +32 −0 lib/OTRS/OPR/DB/Schema/Result/opr_user.pm
  54. +183 −0 lib/OTRS/OPR/Daemon.pm
  55. +280 −0 lib/OTRS/OPR/Daemon/Job.pm
  56. +34 −0 lib/OTRS/OPR/Exporter/Aliased.pm
  57. +83 −0 lib/OTRS/OPR/Web/Admin.pm
  58. +35 −0 lib/OTRS/OPR/Web/Admin/Author.pm
  59. +35 −0 lib/OTRS/OPR/Web/Admin/Misc.pm
  60. +237 −0 lib/OTRS/OPR/Web/Admin/Package.pm
  61. +35 −0 lib/OTRS/OPR/Web/Admin/System.pm
  62. +185 −0 lib/OTRS/OPR/Web/App.pm
  63. +53 −0 lib/OTRS/OPR/Web/App/Config.pm
  64. +39 −0 lib/OTRS/OPR/Web/App/Prerun.pm
  65. +105 −0 lib/OTRS/OPR/Web/App/Session.pm
  66. +52 −0 lib/OTRS/OPR/Web/App/View.pm
  67. +186 −0 lib/OTRS/OPR/Web/Utils.pm
  68. +10 −0 run_daemon.pl
  69. +6 −0 templates/admin_login.tmpl
  70. +5 −0 templates/main.tmpl
34 admin.cgi
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use lib qw(./lib ../perllib);
+use CGI::Application::Dispatch;
+
+CGI::Application::Dispatch->dispatch(
+ prefix => 'OTRS::OPR::Web',
+ table => [
+ '' => {
+ app => 'Admin',
+ rm => 'login',
+ },
+ 'misc/:run?/:id?' => {
+ app => 'Admin::Misc',
+ },
+ 'package/:run/:package/:id?' => {
+ app => 'Admin::Package',
+ },
+ 'package/:run?/:id?' => {
+ app => 'Admin::Package',
+ },
+ 'system/:run?/:id?' => {
+ app => 'Admin::System',
+ },
+ 'user/:run?/:id?' => {
+ app => 'Admin::User',
+ },
+ ':rm' => {
+ app => 'Admin',
+ },
+ ],
+);
18 analyzer_test.pl
@@ -0,0 +1,18 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use lib qw(lib);
+
+use OPR::Backend::OPMAnalyzer;
+
+use Data::Dumper;
+
+my $file = 'C:\Users\Entwicklung\WIDSpecialEdition-0.0.1.opm';
+my $config = 'D:\SVNRepo\PerlServices\software\OPR\Sources\conf\base.yml';
+my $analyzer = OPR::Backend::OPMAnalyzer->new(
+ configfile => $config,
+);
+my $results = $analyzer->analyze( $file );
+
+print Dumper $results;
13 conf/base.yml
@@ -0,0 +1,13 @@
+---
+paths:
+ base: D:\SVNRepo\PerlServices\software\OPR\Sources\
+ templates: templates\
+templates:
+ base: main.tmpl
+utils:
+ perltidy:
+ config: D:\SVNRepo\PerlServices\software\OPR\Sources\conf\perltidyrc
+ perlcritic:
+ config: D:\SVNRepo\PerlServices\software\OPR\Sources\conf\perlcriticrc
+general:
+ perl_version: 5.008001
11 conf/daemon.yml
@@ -0,0 +1,11 @@
+---
+db:
+ user: opr
+ host: localhost
+ name: opr
+ passwd: opr_db
+ type: mysql
+analyzer:
+ max_time: 86400
+fork:
+ max: 3
12 conf/logging.conf
@@ -0,0 +1,12 @@
+log4perl.logger = TRACE, Rotator
+log4perl.appender.Rotator = Log::Dispatch::FileRotate
+log4perl.appender.Rotator.name = file1
+log4perl.appender.Rotator.min_level = debug
+log4perl.appender.Rotator.filename = D:/temp/opr.daemon.log
+log4perl.appender.Rotator.mode = append
+log4perl.appender.Rotator.max = 30
+log4perl.appender.Rotator.TZ = CET
+log4perl.appender.Rotator.DatePattern = yyyy-MM-dd
+log4perl.appender.Rotator.layout = PatternLayout
+log4perl.appender.Rotator.layout.cspec.N = sub { return $$ }
+log4perl.appender.Rotator.layout.ConversionPattern = [%d][%N][%p] %m%n
23 conf/perlcriticrc
@@ -0,0 +1,23 @@
+[TestingAndDebugging::RequireUseStrict]
+severity = 5
+set_themes = opr
+
+[TestingAndDebugging::RequireUseWarnings]
+severity = 5
+set_themes = opr
+
+[CodeLayout::ProhibitHardTabs]
+severity = 5
+set_themes = opr
+
+[CodeLayout::ProhibitParensWithBuiltins]
+severity = 5
+set_themes = opr
+
+[ControlStructures::ProhibitUnlessBlocks]
+severity = 5
+set_themes = opr
+
+[Documentation::PodSpelling]
+severity = 5
+set_themes = opr
15 conf/perltidyrc
@@ -0,0 +1,15 @@
+-l=100 # max line length = 100
+-i=4 # indentation is 4 spaces
+-ci=4 # continuation indentation
+-vt=0 # block brace vertical tightness
+-vtc=0 # do not place the closing token at the end of the list
+-cti=0 # for closing tokens use indentation defined by next lower level
+-pt=1 # add parens padding when there is more than one token
+-bt=1 # add brace padding when there is more than one token
+-sbt=1 # add square bracket padding when there is more than one token
+-bbt=1 # add block brace padding when there is more than one token
+-nsfs # no loop semicolon spaces
+-nolq # do not outdent long quotes
+-bbao
+-nola
+-ndnl # do not delete old newlines
28 create_schema.pl
@@ -0,0 +1,28 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use FabForce::DBDesigner4;
+use FabForce::DBDesigner4::DBIC;
+
+my $file = 'D:\SVNRepo\PerlServices\software\OPR\docs\er_modell.xml';
+my $sql = 'D:\SVNRepo\PerlServices\software\OPR\docs\er_modell.sql';
+
+my $dbic = FabForce::DBDesigner4::DBIC->new();
+$dbic->namespace( 'OTRS::OPR::DB' );
+$dbic->output_path( 'D:\SVNRepo\PerlServices\software\OPR\Sources\lib\\' );
+$dbic->schema_name( 'Schema' );
+$dbic->create_schema( $file );
+
+my $designer = FabForce::DBDesigner4->new();
+$designer->parsefile(xml => $file);
+$designer->writeSQL( $sql ,
+ {
+ type => 'mysql',
+ drop_tables => 1,
+ sql_options => {
+ engine => 'InnoDB',
+ charset => 'utf8',
+ },
+ }
+);
16 dist.ini
@@ -0,0 +1,16 @@
+File::Basename
+File::Spec
+File::Temp
+HTML::Lint
+MIME::Base64
+Module::CoreList
+Moose
+Path::Class
+Perl::Critic
+Perl::Tidy
+PPI
+Software::License
+Text::Diff
+Try::Tiny
+XML::LibXML
+YAML::Tiny
66 get_modules.pl
@@ -0,0 +1,66 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Archive::Tar;
+use File::Spec;
+use File::Temp;
+use Net::FTP;
+use Data::Dumper;
+
+my $ftp_host = 'ftp.otrs.org';
+my $local_dir = File::Temp::tempdir();
+my @dirs = qw(pub otrs);
+
+my $ftp = Net::FTP->new( $ftp_host, Debug => 1 );
+$ftp->login();
+
+for my $dir ( @dirs ) {
+ $ftp->cwd( $dir );
+}
+
+my @files = $ftp->ls;
+my @tar_gz = grep{ m{ \.tar\.gz \z }xms }@files;
+my @no_beta = grep{ !m{ -beta }xms }@tar_gz;
+
+my %hash;
+
+FILE:
+for my $file ( @no_beta ) {
+ my ($major,$minor) = $file =~ m{ \A otrs - (\d+) \. (\d+) \. }xms;
+
+ next FILE if !(defined $major and defined $minor);
+
+ next FILE if $major < 2;
+ next FILE if $major == 2 and $minor < 3;
+
+ my $local_path = File::Spec->catfile( $local_dir, $file );
+
+ $ftp->binary;
+ $ftp->get( $file, $local_path );
+
+ my $tar = Archive::Tar->new( $local_path, 1 );
+ my @files_in_archive = $tar->list_files;
+ my @modules = grep{ m{ \.pm \z }xms }@files_in_archive;
+
+ MODULE:
+ for my $module ( @modules ) {
+ next MODULE if $module =~ m{/scripts/};
+
+ my ($otrs,$modfile) = $module =~ m{ \A otrs-(\d+\.\d+\.\d+)/(.*) }xms;
+ my $is_cpan = $modfile =~ m{cpan-lib}xms;
+
+ my $key = $is_cpan ? 'cpan' : 'core';
+
+ (my $modulename = $modfile) =~ s{/}{::}g;
+ $modulename =~ s{\.pm}{}g;
+ $modulename =~ s{Kernel::cpan-lib::}{}g if $is_cpan;
+
+ $hash{$otrs}->{$key}->{$modulename} = 1;
+ }
+}
+
+if ( open my $fh, '>', 'corelist' ) {
+ print $fh Dumper \%hash;
+}
47 lib/OPR/DAO/AccessMatrix.pm
@@ -0,0 +1,47 @@
+package OPR::DAO::AccessMatrix;
+
+use Moose;
+
+extends 'OPR::DAO::Base';
+
+has userid => ();
+has matrix => ();
+
+sub has_access {
+ my ($self,$func,$perm) = @_;
+
+ my $matrix = $self->matrix;
+ return if !$matrix;
+
+ return if !exists $matrix->{$func};
+}
+
+sub set_permission {
+ my ($self,$func,$perm) = @_;
+
+ $perm ||= 0;
+
+ return if !$func;
+}
+
+sub init {
+ my ($self) = @_;
+
+ return if !$self->userid;
+
+ # try to get precompiled matrix from db
+
+ # if it does not exist, init with empty hash
+
+ # try to compile matrix from db
+}
+
+sub save {
+ my ($self) = @_;
+
+ # save matrix in db
+}
+
+no Moose;
+
+1;
31 lib/OPR/DAO/Author.pm
@@ -0,0 +1,31 @@
+package OPR::DAO::Author;
+
+use Moose;
+
+use Scalar::Util;
+
+extends 'OPR::DAO::Base';
+
+has _create_package_objects => ();
+
+has username => ();
+has userid => ();
+has packages => ();
+has email => ();
+has website => ();
+has active => ();
+
+sub init {
+ my ( $self, $id ) = @_;
+
+ return if !$id;
+ return if !looks_like_number( $id );
+
+ my $author = $self->_schema->();
+
+ $self->_after_init;
+}
+
+no Moose;
+
+1;
29 lib/OPR/DAO/Base.pm
@@ -0,0 +1,29 @@
+package OPR::DAO::Base;
+
+use Moose;
+
+has _schema => ();
+
+sub _after_init {
+ my ($self) = @_;
+
+ # get all attributes of object and save initial value
+ # this is used to find out, if the object should be saved on destruction
+
+}
+
+sub _has_changed {
+}
+
+sub _save {
+}
+
+after 'new' => sub {
+ my ($self) = @_;
+
+ $self->init if $self->can( 'init' );
+};
+
+no Moose;
+
+1;
44 lib/OPR/DAO/Package.pm
@@ -0,0 +1,44 @@
+package OPR::DAO::Package;
+
+use Moose;
+
+extends 'OPR::DAO::Base';
+
+has _create_author_object => ( is => 'ro', isa => 'Bool' );
+
+has package_id => ( is => 'rw', isa => 'Int' );
+has name => ( is => 'rw', isa => 'Str' );
+has framework => ( is => 'rw', isa => 'VersionString' );
+has vendor => ( is => 'rw', isa => 'Str' );
+has comments => ( is => 'rw', isa => 'ArrayRef[HashRef]' );
+has version => ( is => 'rw', isa => 'VersionString' );
+has path => ( is => 'rw', isa => 'Str' );
+has is_in_index => ( is => 'rw', isa => 'Bool' );
+has website => ( is => 'rw', isa => 'Url' );
+has bugtracker => ( is => 'rw', isa => 'Url' );
+has upload_time => ( is => 'rw', isa => 'Int' );
+has virtual_path => ( is => 'rw', isa => 'Str' );
+has description => ( is => 'rw', isa => 'Str' );
+has documentation => ( is => 'rw', isa => 'Str' );
+
+has oq_results => (
+);
+
+has dependencies => (
+);
+
+has author => (
+);
+
+has co_maintainer => (
+);
+
+sub init {
+ my ($self) = @_;
+
+ $self->_after_init;
+}
+
+no Moose;
+
+1;
7 lib/OPR/DB/Schema.pm
@@ -0,0 +1,7 @@
+package OPR::DB::Schema;
+
+use base qw/DBIx::Class::Schema/;
+
+__PACKAGE__->load_namespaces;
+
+1;
19 lib/OPR/DB/Schema/Result/Session.pm
@@ -0,0 +1,19 @@
+package OPR::DB::Schema::Result::Session;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'Session' );
+__PACKAGE__->add_columns( qw/
+ SessionID
+ Start
+ Expire
+/);
+__PACKAGE__->set_primary_key( qw/ SessionID / );
+
+
+
+
+1;
22 lib/OPR/DB/Schema/Result/opr_comments.pm
@@ -0,0 +1,22 @@
+package OPR::DB::Schema::Result::opr_comments;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_comments' );
+__PACKAGE__->add_columns( qw/
+ comment_id
+ username
+ packagename
+ packageversion
+ comments
+ rating
+/);
+__PACKAGE__->set_primary_key( qw/ comment_id / );
+
+
+
+
+1;
22 lib/OPR/DB/Schema/Result/opr_component.pm
@@ -0,0 +1,22 @@
+package OPR::DB::Schema::Result::opr_component;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_component' );
+__PACKAGE__->add_columns( qw/
+ component_id
+ component_name
+ component_label
+/);
+__PACKAGE__->set_primary_key( qw/ component_id / );
+
+
+__PACKAGE__->has_many( opr_functions => 'OPR::DB::Schema::Result::opr_functions',
+ { 'foreign.component_id' => 'self.component_id' });
+
+
+
+1;
26 lib/OPR/DB/Schema/Result/opr_functions.pm
@@ -0,0 +1,26 @@
+package OPR::DB::Schema::Result::opr_functions;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_functions' );
+__PACKAGE__->add_columns( qw/
+ function_id
+ component_id
+ function_name
+ function_label
+/);
+__PACKAGE__->set_primary_key( qw/ function_id / );
+
+
+__PACKAGE__->has_many( opr_group_functions => 'OPR::DB::Schema::Result::opr_group_functions',
+ { 'foreign.function_id' => 'self.function_id' });
+
+
+__PACKAGE__->belongs_to(opr_component => 'OPR::DB::Schema::Result::opr_component',
+ { 'foreign.component_id' => 'self.component_id' });
+
+
+1;
24 lib/OPR/DB/Schema/Result/opr_group.pm
@@ -0,0 +1,24 @@
+package OPR::DB::Schema::Result::opr_group;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_group' );
+__PACKAGE__->add_columns( qw/
+ group_id
+ group_name
+/);
+__PACKAGE__->set_primary_key( qw/ group_id / );
+
+
+__PACKAGE__->has_many( opr_group_functions => 'OPR::DB::Schema::Result::opr_group_functions',
+ { 'foreign.group_id' => 'self.group_id' });
+
+__PACKAGE__->has_many( opr_group_user => 'OPR::DB::Schema::Result::opr_group_user',
+ { 'foreign.group_id' => 'self.group_id' });
+
+
+
+1;
24 lib/OPR/DB/Schema/Result/opr_group_functions.pm
@@ -0,0 +1,24 @@
+package OPR::DB::Schema::Result::opr_group_functions;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_group_functions' );
+__PACKAGE__->add_columns( qw/
+ group_id
+ function_id
+/);
+__PACKAGE__->set_primary_key( qw/ group_id function_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_functions => 'OPR::DB::Schema::Result::opr_functions',
+ { 'foreign.function_id' => 'self.function_id' });
+
+__PACKAGE__->belongs_to(opr_group => 'OPR::DB::Schema::Result::opr_group',
+ { 'foreign.group_id' => 'self.group_id' });
+
+
+1;
24 lib/OPR/DB/Schema/Result/opr_group_user.pm
@@ -0,0 +1,24 @@
+package OPR::DB::Schema::Result::opr_group_user;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_group_user' );
+__PACKAGE__->add_columns( qw/
+ group_id
+ user_id
+/);
+__PACKAGE__->set_primary_key( qw/ group_id user_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_user => 'OPR::DB::Schema::Result::opr_user',
+ { 'foreign.user_id' => 'self.user_id' });
+
+__PACKAGE__->belongs_to(opr_group => 'OPR::DB::Schema::Result::opr_group',
+ { 'foreign.group_id' => 'self.group_id' });
+
+
+1;
25 lib/OPR/DB/Schema/Result/opr_job_queue.pm
@@ -0,0 +1,25 @@
+package OPR::DB::Schema::Result::opr_job_queue;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_job_queue' );
+__PACKAGE__->add_columns( qw/
+ job_id
+ type_id
+ package_id
+ created
+ job_state
+ changed
+/);
+__PACKAGE__->set_primary_key( qw/ job_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_job_type => 'OPR::DB::Schema::Result::opr_job_type',
+ { 'foreign.type_id' => 'self.type_id' });
+
+
+1;
21 lib/OPR/DB/Schema/Result/opr_job_type.pm
@@ -0,0 +1,21 @@
+package OPR::DB::Schema::Result::opr_job_type;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_job_type' );
+__PACKAGE__->add_columns( qw/
+ type_id
+ type_label
+/);
+__PACKAGE__->set_primary_key( qw/ type_id / );
+
+
+__PACKAGE__->has_many( opr_job_queue => 'OPR::DB::Schema::Result::opr_job_queue',
+ { 'foreign.type_id' => 'self.type_id' });
+
+
+
+1;
23 lib/OPR/DB/Schema/Result/opr_oq_entity.pm
@@ -0,0 +1,23 @@
+package OPR::DB::Schema::Result::opr_oq_entity;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_oq_entity' );
+__PACKAGE__->add_columns( qw/
+ oq_id
+ oq_label
+ priority
+ module
+/);
+__PACKAGE__->set_primary_key( qw/ oq_id / );
+
+
+__PACKAGE__->has_many( opr_oq_result => 'OPR::DB::Schema::Result::opr_oq_result',
+ { 'foreign.oq_id' => 'self.oq_id' });
+
+
+
+1;
27 lib/OPR/DB/Schema/Result/opr_oq_result.pm
@@ -0,0 +1,27 @@
+package OPR::DB::Schema::Result::opr_oq_result;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_oq_result' );
+__PACKAGE__->add_columns( qw/
+ result_id
+ oq_id
+ package_id
+ oq_result
+ filename
+/);
+__PACKAGE__->set_primary_key( qw/ result_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_oq_entity => 'OPR::DB::Schema::Result::opr_oq_entity',
+ { 'foreign.oq_id' => 'self.oq_id' });
+
+__PACKAGE__->belongs_to(opr_package => 'OPR::DB::Schema::Result::opr_package',
+ { 'foreign.package_id' => 'self.package_id' });
+
+
+1;
40 lib/OPR/DB/Schema/Result/opr_package.pm
@@ -0,0 +1,40 @@
+package OPR::DB::Schema::Result::opr_package;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_package' );
+__PACKAGE__->add_columns( qw/
+ package_id
+ uploaded_by
+ package_name
+ description
+ version
+ framework
+ path
+ is_in_index
+ website
+ bugtracker
+ upload_time
+ virtual_path
+/);
+__PACKAGE__->set_primary_key( qw/ package_id / );
+
+
+__PACKAGE__->has_many( opr_package_author => 'OPR::DB::Schema::Result::opr_package_author',
+ { 'foreign.package_id' => 'self.package_id' });
+
+__PACKAGE__->has_many( opr_oq_result => 'OPR::DB::Schema::Result::opr_oq_result',
+ { 'foreign.package_id' => 'self.package_id' });
+
+__PACKAGE__->has_many( opr_package_dependencies => 'OPR::DB::Schema::Result::opr_package_dependencies',
+ { 'foreign.package_id' => 'self.package_id' });
+
+
+__PACKAGE__->belongs_to(opr_user => 'OPR::DB::Schema::Result::opr_user',
+ { 'foreign.user_id' => 'self.uploaded_by' });
+
+
+1;
25 lib/OPR/DB/Schema/Result/opr_package_author.pm
@@ -0,0 +1,25 @@
+package OPR::DB::Schema::Result::opr_package_author;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_package_author' );
+__PACKAGE__->add_columns( qw/
+ user_id
+ package_id
+ is_main_author
+/);
+__PACKAGE__->set_primary_key( qw/ user_id package_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_user => 'OPR::DB::Schema::Result::opr_user',
+ { 'foreign.user_id' => 'self.user_id' });
+
+__PACKAGE__->belongs_to(opr_package => 'OPR::DB::Schema::Result::opr_package',
+ { 'foreign.package_id' => 'self.package_id' });
+
+
+1;
24 lib/OPR/DB/Schema/Result/opr_package_dependencies.pm
@@ -0,0 +1,24 @@
+package OPR::DB::Schema::Result::opr_package_dependencies;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_package_dependencies' );
+__PACKAGE__->add_columns( qw/
+ dependency_id
+ package_id
+ dependency
+ dependency_type
+ dependency_version
+/);
+__PACKAGE__->set_primary_key( qw/ dependency_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_package => 'OPR::DB::Schema::Result::opr_package',
+ { 'foreign.package_id' => 'self.package_id' });
+
+
+1;
32 lib/OPR/DB/Schema/Result/opr_user.pm
@@ -0,0 +1,32 @@
+package OPR::DB::Schema::Result::opr_user;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_user' );
+__PACKAGE__->add_columns( qw/
+ user_id
+ user_name
+ user_password
+ session_id
+ website
+ mail
+ active
+/);
+__PACKAGE__->set_primary_key( qw/ user_id / );
+
+
+__PACKAGE__->has_many( opr_package_author => 'OPR::DB::Schema::Result::opr_package_author',
+ { 'foreign.user_id' => 'self.user_id' });
+
+__PACKAGE__->has_many( opr_group_user => 'OPR::DB::Schema::Result::opr_group_user',
+ { 'foreign.user_id' => 'self.user_id' });
+
+__PACKAGE__->has_many( opr_package => 'OPR::DB::Schema::Result::opr_package',
+ { 'foreign.uploaded_by' => 'self.user_id' });
+
+
+
+1;
44 lib/OTRS/OPR/App/Attributes.pm
@@ -0,0 +1,44 @@
+package OTRS::OPR::App::Attributes;
+
+use strict;
+use warnings;
+use Attribute::Handlers;
+use Data::Dumper;
+
+sub Permission : ATTR(CODE) {
+ my ($pkg,$sym,$code,$attrname,$params) = @_;
+
+ my $name = *{$sym}{NAME};
+
+ no warnings 'redefine';
+
+ *{$sym} = sub {
+ my ($self) = @_;
+ unless( $self->user->permission( $params->[0] ) ) {
+ $self->logger->info(
+ $self->user->user_name .
+ ' has no sufficient permission for ' .
+ $params->[0]
+ );
+ $self->no_permission(1);
+ return;
+ }
+ $code->(@_);
+ };
+}
+
+sub Json : ATTR(CODE) {
+ my ($pkg,$sym,$code) = @_;
+
+ my $name = *{$sym}{NAME};
+
+ no warnings 'redefine';
+
+ *{$sym} = sub {
+ $_[0]->json_method(1);
+ print "ATTR <<json>>";
+ $code->(@_);
+ };
+}
+
+1;
29 lib/OTRS/OPR/DAO/Base.pm
@@ -0,0 +1,29 @@
+package OTRS::OPR::DAO::Base;
+
+use Moose;
+
+has _schema => ( is => 'rw' );
+
+sub _after_init {
+ my ($self) = @_;
+
+ # get all attributes of object and save initial value
+ # this is used to find out, if the object should be saved on destruction
+
+}
+
+sub _has_changed {
+}
+
+sub _save {
+}
+
+after 'new' => sub {
+ my ($self) = @_;
+
+ $self->init if $self->can( 'init' );
+};
+
+no Moose;
+
+1;
11 lib/OTRS/OPR/DAO/User.pm
@@ -0,0 +1,11 @@
+package OTRS::OPR::DAO::User;
+
+use Moose;
+
+extends 'OTRS::OPR::DAO::Base';
+
+has session_id => ( is => 'rw' );
+
+no Moose;
+
+1;
55 lib/OTRS/OPR/DB/Helper/Comment.pm
@@ -0,0 +1,55 @@
+package OTRS::OPR::DB::Helper::Comment;
+
+use base 'OTRS::OPR::Exporter::Aliased';
+
+use OTRS::OPR::Web::App::Utils qw(time_to_date);
+
+our @EXPORT_OK = qw(
+ page
+);
+
+sub page {
+ my ($self,$page,$search_term,$params) = @_;
+
+ my $rows = $self->config->get( 'rows.search' );
+
+ my $resultset = $self->table( 'opr_comments' )->search(
+ {},
+ {
+ page => $page,
+ rows => $rows,
+ order_by => 'comment_id',
+ },
+ );
+
+ my @comments = $resultset->all;
+ my $pages = $resultset->pager->last_page;
+
+ my @comments_for_template;
+ for my $comment ( @comments ) {
+
+ # show just a short excerpt of the text if it is too long
+ my $text = $comment->comments;
+ $text = substr( $text, 0, 57 ) . '...' if $params{short} and 60 < length $text;
+
+ # show just a short excerpt of the headline if it is too long
+ my $head = $comment->headline;
+ $head = substr( $head, 0, 17 ) . '...' if $params{short} and 20 < length $head;
+
+ # create the infos for the template
+ push @comments_for_template, {
+ TEXT => $text,
+ ID => $comment->comment_id,
+ HEAD => $head,
+ RATING => $comment->rating,
+ USER => $comment->username,
+ DATE => $self->time_to_date( $comment->published ),
+ PACKAGE => $comment->packagename,
+ VERSION => $comment->packageversion,
+ };
+ }
+
+ return ( \@comments_for_template, $pages );
+}
+
+1;
56 lib/OTRS/OPR/DB/Helper/Job.pm
@@ -0,0 +1,56 @@
+package OTRS::OPR::DB::Helper::Job;
+
+use base 'OTRS::OPR::Exporter::Aliased';
+
+our @EXPORT_OK = qw(
+ create_job
+ find_job
+);
+
+sub create_job {
+ my ($self,$params) = @_;
+
+ return if !($params{id} and $params{type});
+
+ my ($type) = $self->table( 'opr_job_type' )->search({
+ type_label => $params{type},
+ })->all;
+
+ return if !$type;
+
+ my ($existing_job) = $self->table( 'opr_job_queue' )->search({
+ type_id => $type->type_id,
+ package_id => $params{id},
+ });
+
+ return if $existing_job;
+
+ my $job = $self->table( 'opr_job_queue' )->create({
+ type_id => $type->type_id,
+ package_id => $params{id},
+ created => time,
+ });
+
+ return $job->job_id;
+}
+
+sub find_job {
+ my ($self,$params) = @_;
+
+ return if !($params{id} and $params{type});
+
+ my ($type) = $self->table( 'opr_job_type' )->search({
+ type_label => $params{type},
+ })->all;
+
+ return if !$type;
+
+ my ($existing_job) = $self->table( 'opr_job_queue' )->search({
+ type_id => $type->type_id,
+ package_id => $params{id},
+ });
+
+ return $existing_job;
+}
+
+1;
55 lib/OTRS/OPR/DB/Helper/Package.pm
@@ -0,0 +1,55 @@
+package OTRS::OPR::DB::Helper::Package;
+
+use parent 'OTRS::OPR::Exporter::Aliased';
+
+use OTRS::OPR::Web::App::Utils qw(time_to_date);
+
+our @EXPORT_OK = qw(
+ page
+);
+
+sub page {
+ my ($self,$page,$search_term,$params) = @_;
+
+ my $rows = $self->config->get( 'rows.search' );
+
+ my $resultset = $self->table( 'opr_package' )->search(
+ {
+ # is_in_index => 1,
+ # group by name
+ },
+ {
+ page => $page,
+ rows => $rows,
+ order_by => 'package_id',
+ },
+ );
+
+ my @packages = $resultset->all;
+ my $pages = $resultset->pager->last_page;
+
+ my @packages_for_template;
+ for my $package ( @packages ) {
+
+ # show just a short excerpt of the text if it is too long
+ my $text = $package->package_name;
+ $text = substr( $text, 0, 37 ) . '...' if $params{short} and 40 < length $text;
+
+ # show just a short excerpt of the description if it is too long
+ my $desc = $package->description;
+ $desc = substr( $desc, 0, 57 ) . '...' if $params{short} and 60 < length $desc;
+
+ # create the infos for the template
+ push @comments_for_template, {
+ NAME => $text,
+ VERSION => $package->version,
+ DESCRIPTION => $desc,
+ AUTHOR => $package->uploaded_by->user_name,
+ DATE => $self->time_to_date( $package->upload_time ),
+ };
+ }
+
+ return ( \@packages_for_template, $pages );
+}
+
+1;
46 lib/OTRS/OPR/DB/Helper/User.pm
@@ -0,0 +1,46 @@
+package OTRS::OPR::DB::Helper::User;
+
+use base 'OTRS::OPR::Exporter::Aliased';
+
+our @EXPORT_OK = qw(
+ check_credentials
+ list
+);
+
+sub check_credentials {
+ my ($self,$params) = @_;
+
+ my $logger = $self->logger;
+
+ return if !($params{user} and $params{password});
+
+ my $password = crypt $params{password}, $self->config->get( 'password.salt' );
+
+ my ($user) = $self->table( 'opr_user' )->search({
+ user_name => $params{user},
+ user_password => $password,
+ })->all;
+
+ if ( !$user ) {
+ $logger->info( "Login for $params{user} not successful" );
+ return;
+ }
+
+ $logger->debug( "Login $params{user} successful" );
+
+ my $session = $self->session;
+ $session->session->force_new;
+
+ my $session_id = $session->session_id;
+ $user->session_id( $session_id );
+ $user->update;
+
+ $logger->trace( "Session ID for $params{user}: $session_id" );
+
+ return 1;
+}
+
+sub list {
+}
+
+1;
7 lib/OTRS/OPR/DB/Schema.pm
@@ -0,0 +1,7 @@
+package OTRS::OPR::DB::Schema;
+
+use base qw/DBIx::Class::Schema/;
+
+__PACKAGE__->load_namespaces;
+
+1;
19 lib/OTRS/OPR/DB/Schema/Result/Session.pm
@@ -0,0 +1,19 @@
+package OTRS::OPR::DB::Schema::Result::Session;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'Session' );
+__PACKAGE__->add_columns( qw/
+ SessionID
+ Start
+ Expire
+/);
+__PACKAGE__->set_primary_key( qw/ SessionID / );
+
+
+
+
+1;
25 lib/OTRS/OPR/DB/Schema/Result/opr_comments.pm
@@ -0,0 +1,25 @@
+package OTRS::OPR::DB::Schema::Result::opr_comments;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_comments' );
+__PACKAGE__->add_columns( qw/
+ comment_id
+ username
+ packagename
+ packageversion
+ comments
+ rating
+ deletion_flag
+ headline
+ published
+/);
+__PACKAGE__->set_primary_key( qw/ comment_id / );
+
+
+
+
+1;
22 lib/OTRS/OPR/DB/Schema/Result/opr_component.pm
@@ -0,0 +1,22 @@
+package OTRS::OPR::DB::Schema::Result::opr_component;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_component' );
+__PACKAGE__->add_columns( qw/
+ component_id
+ component_name
+ component_label
+/);
+__PACKAGE__->set_primary_key( qw/ component_id / );
+
+
+__PACKAGE__->has_many( opr_functions => 'OTRS::OPR::DB::Schema::Result::opr_functions',
+ { 'foreign.component_id' => 'self.component_id' });
+
+
+
+1;
26 lib/OTRS/OPR/DB/Schema/Result/opr_functions.pm
@@ -0,0 +1,26 @@
+package OTRS::OPR::DB::Schema::Result::opr_functions;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_functions' );
+__PACKAGE__->add_columns( qw/
+ function_id
+ component_id
+ function_name
+ function_label
+/);
+__PACKAGE__->set_primary_key( qw/ function_id / );
+
+
+__PACKAGE__->has_many( opr_group_functions => 'OTRS::OPR::DB::Schema::Result::opr_group_functions',
+ { 'foreign.function_id' => 'self.function_id' });
+
+
+__PACKAGE__->belongs_to(opr_component => 'OTRS::OPR::DB::Schema::Result::opr_component',
+ { 'foreign.component_id' => 'self.component_id' });
+
+
+1;
24 lib/OTRS/OPR/DB/Schema/Result/opr_group.pm
@@ -0,0 +1,24 @@
+package OTRS::OPR::DB::Schema::Result::opr_group;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_group' );
+__PACKAGE__->add_columns( qw/
+ group_id
+ group_name
+/);
+__PACKAGE__->set_primary_key( qw/ group_id / );
+
+
+__PACKAGE__->has_many( opr_group_functions => 'OTRS::OPR::DB::Schema::Result::opr_group_functions',
+ { 'foreign.group_id' => 'self.group_id' });
+
+__PACKAGE__->has_many( opr_group_user => 'OTRS::OPR::DB::Schema::Result::opr_group_user',
+ { 'foreign.group_id' => 'self.group_id' });
+
+
+
+1;
24 lib/OTRS/OPR/DB/Schema/Result/opr_group_functions.pm
@@ -0,0 +1,24 @@
+package OTRS::OPR::DB::Schema::Result::opr_group_functions;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_group_functions' );
+__PACKAGE__->add_columns( qw/
+ group_id
+ function_id
+/);
+__PACKAGE__->set_primary_key( qw/ group_id function_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_functions => 'OTRS::OPR::DB::Schema::Result::opr_functions',
+ { 'foreign.function_id' => 'self.function_id' });
+
+__PACKAGE__->belongs_to(opr_group => 'OTRS::OPR::DB::Schema::Result::opr_group',
+ { 'foreign.group_id' => 'self.group_id' });
+
+
+1;
24 lib/OTRS/OPR/DB/Schema/Result/opr_group_user.pm
@@ -0,0 +1,24 @@
+package OTRS::OPR::DB::Schema::Result::opr_group_user;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_group_user' );
+__PACKAGE__->add_columns( qw/
+ group_id
+ user_id
+/);
+__PACKAGE__->set_primary_key( qw/ group_id user_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_user => 'OTRS::OPR::DB::Schema::Result::opr_user',
+ { 'foreign.user_id' => 'self.user_id' });
+
+__PACKAGE__->belongs_to(opr_group => 'OTRS::OPR::DB::Schema::Result::opr_group',
+ { 'foreign.group_id' => 'self.group_id' });
+
+
+1;
25 lib/OTRS/OPR/DB/Schema/Result/opr_job_queue.pm
@@ -0,0 +1,25 @@
+package OTRS::OPR::DB::Schema::Result::opr_job_queue;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_job_queue' );
+__PACKAGE__->add_columns( qw/
+ job_id
+ type_id
+ package_id
+ created
+ job_state
+ changed
+/);
+__PACKAGE__->set_primary_key( qw/ job_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_job_type => 'OTRS::OPR::DB::Schema::Result::opr_job_type',
+ { 'foreign.type_id' => 'self.type_id' });
+
+
+1;
21 lib/OTRS/OPR/DB/Schema/Result/opr_job_type.pm
@@ -0,0 +1,21 @@
+package OTRS::OPR::DB::Schema::Result::opr_job_type;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_job_type' );
+__PACKAGE__->add_columns( qw/
+ type_id
+ type_label
+/);
+__PACKAGE__->set_primary_key( qw/ type_id / );
+
+
+__PACKAGE__->has_many( opr_job_queue => 'OTRS::OPR::DB::Schema::Result::opr_job_queue',
+ { 'foreign.type_id' => 'self.type_id' });
+
+
+
+1;
23 lib/OTRS/OPR/DB/Schema/Result/opr_oq_entity.pm
@@ -0,0 +1,23 @@
+package OTRS::OPR::DB::Schema::Result::opr_oq_entity;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_oq_entity' );
+__PACKAGE__->add_columns( qw/
+ oq_id
+ oq_label
+ priority
+ module
+/);
+__PACKAGE__->set_primary_key( qw/ oq_id / );
+
+
+__PACKAGE__->has_many( opr_oq_result => 'OTRS::OPR::DB::Schema::Result::opr_oq_result',
+ { 'foreign.oq_id' => 'self.oq_id' });
+
+
+
+1;
27 lib/OTRS/OPR/DB/Schema/Result/opr_oq_result.pm
@@ -0,0 +1,27 @@
+package OTRS::OPR::DB::Schema::Result::opr_oq_result;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_oq_result' );
+__PACKAGE__->add_columns( qw/
+ result_id
+ oq_id
+ package_id
+ oq_result
+ filename
+/);
+__PACKAGE__->set_primary_key( qw/ result_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_oq_entity => 'OTRS::OPR::DB::Schema::Result::opr_oq_entity',
+ { 'foreign.oq_id' => 'self.oq_id' });
+
+__PACKAGE__->belongs_to(opr_package => 'OTRS::OPR::DB::Schema::Result::opr_package',
+ { 'foreign.package_id' => 'self.package_id' });
+
+
+1;
41 lib/OTRS/OPR/DB/Schema/Result/opr_package.pm
@@ -0,0 +1,41 @@
+package OTRS::OPR::DB::Schema::Result::opr_package;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_package' );
+__PACKAGE__->add_columns( qw/
+ package_id
+ uploaded_by
+ package_name
+ description
+ version
+ framework
+ path
+ is_in_index
+ website
+ bugtracker
+ upload_time
+ virtual_path
+ deletion_flag
+/);
+__PACKAGE__->set_primary_key( qw/ package_id / );
+
+
+__PACKAGE__->has_many( opr_package_author => 'OTRS::OPR::DB::Schema::Result::opr_package_author',
+ { 'foreign.package_id' => 'self.package_id' });
+
+__PACKAGE__->has_many( opr_oq_result => 'OTRS::OPR::DB::Schema::Result::opr_oq_result',
+ { 'foreign.package_id' => 'self.package_id' });
+
+__PACKAGE__->has_many( opr_package_dependencies => 'OTRS::OPR::DB::Schema::Result::opr_package_dependencies',
+ { 'foreign.package_id' => 'self.package_id' });
+
+
+__PACKAGE__->belongs_to(opr_user => 'OTRS::OPR::DB::Schema::Result::opr_user',
+ { 'foreign.user_id' => 'self.uploaded_by' });
+
+
+1;
25 lib/OTRS/OPR/DB/Schema/Result/opr_package_author.pm
@@ -0,0 +1,25 @@
+package OTRS::OPR::DB::Schema::Result::opr_package_author;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_package_author' );
+__PACKAGE__->add_columns( qw/
+ user_id
+ package_id
+ is_main_author
+/);
+__PACKAGE__->set_primary_key( qw/ user_id package_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_user => 'OTRS::OPR::DB::Schema::Result::opr_user',
+ { 'foreign.user_id' => 'self.user_id' });
+
+__PACKAGE__->belongs_to(opr_package => 'OTRS::OPR::DB::Schema::Result::opr_package',
+ { 'foreign.package_id' => 'self.package_id' });
+
+
+1;
24 lib/OTRS/OPR/DB/Schema/Result/opr_package_dependencies.pm
@@ -0,0 +1,24 @@
+package OTRS::OPR::DB::Schema::Result::opr_package_dependencies;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_package_dependencies' );
+__PACKAGE__->add_columns( qw/
+ dependency_id
+ package_id
+ dependency
+ dependency_type
+ dependency_version
+/);
+__PACKAGE__->set_primary_key( qw/ dependency_id / );
+
+
+
+__PACKAGE__->belongs_to(opr_package => 'OTRS::OPR::DB::Schema::Result::opr_package',
+ { 'foreign.package_id' => 'self.package_id' });
+
+
+1;
32 lib/OTRS/OPR/DB/Schema/Result/opr_user.pm
@@ -0,0 +1,32 @@
+package OTRS::OPR::DB::Schema::Result::opr_user;
+
+use strict;
+use warnings;
+use base qw(DBIx::Class);
+
+__PACKAGE__->load_components( qw/PK::Auto Core/ );
+__PACKAGE__->table( 'opr_user' );
+__PACKAGE__->add_columns( qw/
+ user_id
+ user_name
+ user_password
+ session_id
+ website
+ mail
+ active
+/);
+__PACKAGE__->set_primary_key( qw/ user_id / );
+
+
+__PACKAGE__->has_many( opr_package_author => 'OTRS::OPR::DB::Schema::Result::opr_package_author',
+ { 'foreign.user_id' => 'self.user_id' });
+
+__PACKAGE__->has_many( opr_group_user => 'OTRS::OPR::DB::Schema::Result::opr_group_user',
+ { 'foreign.user_id' => 'self.user_id' });
+
+__PACKAGE__->has_many( opr_package => 'OTRS::OPR::DB::Schema::Result::opr_package',
+ { 'foreign.uploaded_by' => 'self.user_id' });
+
+
+
+1;
183 lib/OTRS/OPR/Daemon.pm
@@ -0,0 +1,183 @@
+package OTRS::OPR::Daemon;
+
+use strict;
+use warnings;
+
+use Log::Log4perl;
+use Parallel::ForkManager;
+use Path::Class;
+
+use OTRS::OPR::Daemon::Job;
+use OTRS::OPM::Analyzer;
+use OTRS::OPM::Analyzer::Utils::Config;
+use OTRS::OPR::DB::Schema;
+
+sub new {
+ my ( $class, %args ) = @_;
+
+ my $self = bless {}, $class;
+
+ # set config directory
+ $self->_conf_dir( $args{config} );
+
+ # initialize logging
+ $self->_init_logging;
+
+ # initialize db connection
+ $self->_init_db;
+
+ return $self;
+}
+
+sub run {
+ my ($self) = @_;
+
+ # get logger
+ my $logger = Log::Log4perl->get_logger;
+
+ # set all jobs with state 'running' to 'stalled' if they were started long time ago
+ my @running_jobs = $self->table( 'opr_job_queue' )->search({
+ job_state => [qw/running/],
+ });
+
+ my $max_time = $self->config->get( 'analyzer.max_time' );
+ for my $job ( @running_jobs ) {
+ if ( time - $job->changed > $max_time ) {
+ $job->job_state( 'stalled' );
+ $logger->info( 'set state of job ' . $job->job_id . ' to "stalled"' );
+ }
+ }
+
+ # get 'open' and 'stalled' jobs
+ my @jobs_to_run = $self->table( 'opr_job_queue' )->search({
+ job_state => [qw(open stalled)],
+ });
+
+ $logger->info( 'found ' . @jobs_to_run . ' jobs to run!' );
+
+ my $local_config = $self->_analyzer_conf->stringify;
+
+ # set state to 'running' this is done so early to avoid race conditions
+ my @job_info;
+
+ for my $job ( @jobs_to_run ) {
+ push @job_info, {
+ old_state => $job->job_state,
+ job_id => $job->job_id,
+ analyzer_config => $local_config,
+ config => $self->config,
+ };
+
+ $job->job_state( 'running' );
+ $job->changed( time );
+ $job->update;
+
+ $logger->trace( 'set job state (job id=' . $job->job_id . ') to running' );
+ }
+
+ # init fork manager
+ my $max_processes = $self->config->get( 'fork.max' );
+ my $fork_manager = Parallel::ForkManager->new( $max_processes );
+ $logger->trace( 'init fork manager with max ' . $max_processes . ' processes' );
+
+ $self->{__schema__}->storage->disconnect;
+
+ for my $tmpjob ( @job_info ) {
+
+ # do the fork
+ $fork_manager->start and next;
+
+ # create job and run it
+ my $job = OTRS::OPR::Daemon::Job->new(
+ %{$tmpjob},
+ );
+ $job->run if $job;
+
+ # exit the forked process
+ $fork_manager->finish;
+ }
+
+ $fork_manager->wait_all_children;
+}
+
+sub config {
+ my ($self) = @_;
+
+ if ( !$self->{__config__} ) {
+ $self->_init_config;
+ }
+
+ return $self->{__config__};
+}
+
+sub table {
+ my ( $self, $name ) = @_;
+
+ return $self->{__schema__}->resultset( $name );
+}
+
+sub _conf_dir {
+ my ($self,$value) = @_;
+
+ if ( $value ) {
+ $self->{__config_dir__} = Path::Class::Dir->new( $value );
+ }
+
+ return $self->{__config_dir__};
+}
+
+sub _analyzer_conf {
+ my ($self) = @_;
+
+ unless ( $self->{__analyzer_config__} ) {
+ $self->{__analyzer_config__} = Path::Class::File->new(
+ $conf_dir,
+ 'base.yml',
+ );
+ }
+
+ return $self->{__analyzer_config__};
+}
+
+sub _init_db {
+ my ( $self ) = @_;
+
+ my $config = $self->config;
+ my $user = $config->get( 'db.user' );
+ my $passwd = $config->get( 'db.passwd' );
+ my $host = $config->get( 'db.host' );
+ my $db = $config->get( 'db.name' );
+ my $type = $config->get( 'db.type' );
+
+ $self->{__schema__} = OTRS::OPR::DB::Schema->connect(
+ "DBI:$type:$db:$host",
+ $user,
+ $passwd,
+ );
+}
+
+sub _init_config {
+ my ($self) = @_;
+
+ my $config_file = Path::Class::File->new(
+ $self->_conf_dir,
+ 'daemon.yml',
+ );
+
+ $self->{__config__} = OTRS::OPM::Analyzer::Utils::Config->new(
+ "$config_file",
+ );
+}
+
+sub _init_logging {
+ my ($self) = @_;
+
+ my $logging_conf = Path::Class::File->new(
+ $self->_conf_dir,
+ 'logging.conf',
+ );
+
+ Log::Log4perl->init( "$logging_conf" );
+}
+
+1;
280 lib/OTRS/OPR/Daemon/Job.pm
@@ -0,0 +1,280 @@
+package OTRS::OPR::Daemon::Job;
+
+use strict;
+use warnings;
+
+use Data::Dumper;
+use Log::Log4perl;
+
+use OTRS::OPM::Analyzer;
+use OTRS::OPR::DB::Schema;
+
+sub new {
+ my ( $class, %args ) = @_;
+
+ my $self = bless {}, $class;
+
+ for my $needed ( qw(job_id old_state analyzer_config config) ) {
+ return if !$args{$needed};
+ }
+
+ # set some basic attributes
+ $self->job_id( $args{job_id} );
+ $self->old_state( $args{old_state} );
+ $self->analyzer_config( $args{analyzer_config} );
+ $self->config( $args{config} );
+
+ # initialize db connection
+ $self->_init_db;
+
+ return $self;
+}
+
+sub analyzer_config {
+ my ( $self, $config ) = @_;
+
+ $self->{__analyzer_config__} = $config if @_ == 2;
+ return $self->{__analyzer_config__};
+}
+
+sub run {
+ my ($self) = @_;
+
+ # get logger
+ my $logger = Log::Log4perl->get_logger;
+
+ my ($job) = $self->table( 'opr_job_queue' )->find( $self->job_id );
+ $logger->trace( 'forked for job ' . $job->job_id );
+
+ # run job
+ my $result;
+ my $job_type = $job->opr_job_type->type_label;
+
+ if ( $job_type eq 'analyze' ) {
+ $result = $self->analyze_package( $job );
+ }
+ elsif ( $job_type eq 'delete' ) {
+ $result = $self->delete_package( $job );
+ }
+ elsif ( $job_type eq 'comment' ) {
+ $result = $self->delete_comment( $job );
+ }
+ else {
+ $logger->warn( "unknown job type: " . $job_type );
+ }
+
+ # delete job from queue if successful
+ if ( $result ) {
+ $job->delete;
+ $logger->info( 'deleted job ' . $job->job_id );
+ }
+}
+
+sub analyze_package {
+ my ( $self, $job ) = @_;
+
+ # if job state was 'stalled', delete possibly existing info about the package
+ if ( $self->old_state eq 'stalled' ) {
+ $self->table( 'opr_oq_result' )->search({
+ package_id => $job->package_id,
+ })->delete;
+ }
+
+ # get the package object that belongs to the job
+ my $package = $self->table( 'opr_package' )->find( $job->package_id );
+ return if !$package;
+
+ # analyse package
+ my $analyzer = OTRS::OPM::Analyzer->new(
+ configfile => $self->analyzer_config,
+ );
+
+ my $result = $analyzer->analyze( $package->path );
+ return if !$result;
+
+ # save basic data of file
+ $self->_save_basic_info( $package, $analyzer->opm );
+
+ # save analysis data in db
+ # double check that there is no data about that package in the database
+ $self->_save_analysis_data( $package, $result );
+
+ # remove job from queue
+}
+
+sub _save_basic_info {
+ my ( $self, $package, $opm ) = @_;
+
+ my $logger = Log::Log4perl->get_logger;
+
+ my $name = $opm->name;
+
+ for my $attr ( qw/description framework version/ ) {
+ if ( $package->can( $attr ) && $opm->can( $attr ) ) {
+ $package->$attr( $opm->$attr() );
+ $logger->trace( "set $attr for $name" );
+ }
+ }
+
+ $package->website( $opm->url );
+ $logger->trace( "set website for $name" );
+
+ $package->package_name( $name );
+ $logger->trace( "set packagename for $name" );
+
+ # save the updates
+ $package->update;
+
+ # delete dependencies that already exist for the given package
+ $self->table( 'opr_package_dependencies' )->search({
+ package_id => $package->package_id,
+ })->delete;
+
+ # save dependencies
+ for my $dep ( $opm->dependencies ) {
+ my $dep_row = $self->table( 'opr_package_dependencies' )->create({
+ package_id => $package->package_id,
+ dependency => $dep->{name},
+ dependency_type => lc( $dep->{type} ),
+ dependency_version => $dep->{version},
+ })->update;
+
+ $logger->trace( 'added dependency ' . $dep->{name} . ' for package ' . $name );
+ }
+}
+
+sub _save_analysis_data {
+ my ( $self, $package, $results ) = @_;
+
+ my $logger = Log::Log4perl->get_logger;
+ $logger->info( 'save analysis results' );
+
+ $logger->trace( Dumper $results );
+
+ if ( !$results || ref $results ne 'HASH' ) {
+ $logger->warn( 'no results found' );
+ }
+
+ my $package_id = $package->package_id;
+
+ # delete old oq results for the package
+ $self->table( 'opr_oq_result' )->search({
+ package_id => $package_id,
+ })->delete;
+
+
+ my @entities = $self->table( 'opr_oq_entity' )->all;
+ my %entity_map = map { $_->module => $_->oq_id }@entities;
+
+ MODULE:
+ for my $module ( keys %{$results} ) {
+ my $oq_id = $entity_map{$module};
+ if ( !$oq_id ) {
+ $logger->warn( "did not found an ID for OQ module $module" );
+ next MODULE;
+ }
+
+ if ( !ref $results->{$module} ) {
+ $self->table( 'opr_oq_result' )->create({
+ package_id => $package_id,
+ oq_id => $oq_id,
+ oq_result => $results->{$module},
+ })->update;
+
+ $logger->info( "set oq result for module $module and package $package_id" );
+ next MODULE;
+ }
+
+ for my $file ( keys %{ $results->{$module} } ) {
+ my $text = $results->{$module}->{$file};
+ $self->table( 'opr_oq_result' )->create({
+ package_id => $package_id,
+ oq_id => $oq_id,
+ oq_result => $text,
+ filename => $file,
+ })->update;
+
+ $logger->info( "set oq result for module $module and package $package_id" );
+ }
+ }
+}
+
+sub delete_package {
+ my ( $self, $job ) = @_;
+
+ # get package that belongs to the job
+ my ($package) = $self->table( 'opr_package' )->search(
+ package_id => $job->package_id,
+ );
+
+ my $logger = Log::Log4perl->get_logger;
+ my $message = sprintf "delete all information about package %s version %s",
+ $package->package_name, $package->version;
+
+ $logger->info( $message );
+
+ # delete all information about the package
+ # this includes authorship, main info, job queue, dependencies, oq values
+ $package->opr_oq_result->delete;
+ $package->opr_package_dependencies->delete;
+ $package->opr_package_author->delete;
+ $package->delete;
+
+ return 1;
+}
+
+sub delete_comment {
+ my ($self,$job) = @_;
+
+ $self->table( 'opr_comments' )->search({
+ comment_id => $job->package_id;
+ })->delete;
+
+ return 1;
+}
+
+sub config {
+ my ($self,$config) = @_;
+
+ $self->{__config__} = $config if @_ == 2;
+ return $self->{__config__};
+}
+
+sub table {
+ my ( $self, $name ) = @_;
+
+ return $self->{__schema__}->resultset( $name );
+}
+
+sub _init_db {
+ my ( $self ) = @_;
+
+ my $config = $self->config;
+ my $user = $config->get( 'db.user' );
+ my $passwd = $config->get( 'db.passwd' );
+ my $host = $config->get( 'db.host' );
+ my $db = $config->get( 'db.name' );
+ my $type = $config->get( 'db.type' );
+
+ $self->{__schema__} = OTRS::OPR::DB::Schema->connect(
+ "DBI:$type:$db:$host",
+ $user,
+ $passwd,
+ );
+}
+
+sub job_id {
+ my ( $self, $id ) = @_;
+
+ $self->{__job_id__} = $id if @_ == 2;
+ return $self->{__job_id__};
+}
+
+sub old_state {
+ my ( $self, $state ) = @_;
+
+ $self->{__old_state__} = $state if @_ == 2;
+ return $self->{__old_state__};
+}
+
+1;
34 lib/OTRS/OPR/Exporter/Aliased.pm
@@ -0,0 +1,34 @@
+package OTRS::OPR::Exporter::Aliased;
+
+use strict;
+use warnings;
+
+sub import {
+ my ($class,@methods) = @_;
+
+ no strict 'refs';
+
+ my $caller = caller();
+ my @ok = @{ $class . '::EXPORT_OK' };
+
+ METHOD:
+ for my $method ( @methods ) {
+
+ my $ref = ref $method;
+ if ( $ref and $ref eq 'HASH' ) {
+
+ KEY:
+ for my $key ( keys %{$method} ) {
+ next KEY if !grep{ $key eq $_ }@ok;
+
+ my $new_name = $method->{$key};
+ *{ $caller . '::' . $new_name } = *{ $class . '::' . $key };
+ }
+ }
+
+ next METHOD if !grep{ $_ eq $method }@ok;
+ *{ $caller . '::' . $method } = *{ $class . '::' . $method };
+ }
+}
+
+1;
83 lib/OTRS/OPR/Web/Admin.pm
@@ -0,0 +1,83 @@
+package OTRS::OPR::Web::Admin;
+
+use strict;
+use warnings;
+
+use parent qw(OTRS::OPR::Web::App);
+
+use OTRS::OPR::DB::Helper::User qw(check_credentials);
+use OTRS::OPR::Web::App::Prerun;
+
+sub setup {
+ my ($self) = @_;
+
+ $self->main_tmpl( $self->config->get('templates.admin') );
+
+ my $startmode = 'start';
+ my $param = $self->param( 'run' );
+ if( $param ){
+ $startmode = $param;
+ }
+
+ $self->start_mode( $startmode );
+ $self->mode_param( 'rm' );
+ $self->run_modes(
+ AUTOLOAD => \&start,
+ start => \&start,
+ login => \&login,
+ logout => \&logout,
+ do_login => \&do_login,
+ );
+}
+
+sub start {
+ my ($self) = @_;
+
+ # redirect to page configured in admin.startpage
+ $self->redirect( $self->base_url . '/' . $self->config->get( 'admin.startpage' ) );
+}
+
+sub login {
+ my ($self) = @_;
+
+ # show the login form
+ $self->template( 'admin_login' );
+}
+
+sub do_login {
+ my ($self) = @_;
+
+ my %params = $self->query->Vars;
+ my $user = $self->check_credentials( \%params );
+
+ # successful login
+ if( $user ) {
+
+ # redirect to page configured in admin.startpage
+ $self->redirect( $self->base_url . '/' . $self->config->get( 'admin.startpage' ) );
+ }
+ else {
+
+ # show login form and show error message
+ $self->notify({
+ type => 'error',
+ include => 'notifications/login_unsuccessful',
+ });
+ $self->login;
+ }
+}
+
+sub logout {
+ my ($self) = @_;
+
+ $self->session->logout;
+
+ $self->notify({
+ type => 'success',
+ include => 'notifications/logout_successful',
+ });
+
+ $self->login;
+}
+
+1;
35 lib/OTRS/OPR/Web/Admin/Author.pm
@@ -0,0 +1,35 @@
+package OTRS::OPR::Web::Admin::Author;
+
+use strict;
+use warnings;
+
+use base qw(OTRS::OPR::Web::App);
+use CGI::Application::Plugin::Redirect;
+
+use OTRS::OPR::DAO::User;
+
+use OTRS::OPR::Web::App::Session;
+
+sub cgiapp_prerun{
+ my ($self) = @_;
+
+ my $session = OTRS::OPR::Web::App::Session->new;
+ if( $session->is_expired ){
+ $session->delete;
+ if( $self->get_current_runmode eq 'logout' ){
+ $session->logout;
+ }
+ my $index = $self->_config->{admin};
+ $ENV{HTTP_HOST} ||= 'perlnews';
+ my $url = 'http://' . $ENV{HTTP_HOST} . $index . '/login';
+ unless( $self->get_current_runmode eq 'login' ){
+ $self->redirect( $url ) ;
+ }
+ }
+ else{
+ $session->update_session;
+ $self->user( $session );
+ }
+}
+
+1;
35 lib/OTRS/OPR/Web/Admin/Misc.pm
@@ -0,0 +1,35 @@
+package OTRS::OPR::Web::Admin::Misc;
+
+use strict;
+use warnings;
+
+use base qw(OTRS::OPR::Web::App);
+use CGI::Application::Plugin::Redirect;
+
+use OTRS::OPR::DAO::User;
+
+use OTRS::OPR::Web::App::Session;
+
+sub cgiapp_prerun{
+ my ($self) = @_;
+
+ my $session = OTRS::OPR::Web::App::Session->new;
+ if( $session->is_expired ){
+ $session->delete;
+ if( $self->get_current_runmode eq 'logout' ){
+ $session->logout;
+ }
+ my $index = $self->_config->{admin};
+ $ENV{HTTP_HOST} ||= 'perlnews';
+ my $url = 'http://' . $ENV{HTTP_HOST} . $index . '/login';
+ unless( $self->get_current_runmode eq 'login' ){
+ $self->redirect( $url ) ;
+ }
+ }
+ else{
+ $session->update_session;
+ $self->user( $session );
+ }
+}
+
+1;
237 lib/OTRS/OPR/Web/Admin/Package.pm
@@ -0,0 +1,237 @@
+package OTRS::OPR::Web::Admin::Package;
+
+use strict;
+use warnings;
+
+use base qw(OTRS::OPR::Web::App);
+use CGI::Application::Plugin::Redirect;
+use Scalar::Util;
+
+use OTRS::OPR::DAO::Package;
+use OTRS::OPR::DB::Helper::Comment {page => 'cpage'};
+use OTRS::OPR::DB::Helper::Job qw(create_job find_job);
+use OTRS::OPR::DB::Helper::Package qw(page);
+use OTRS::OPR::DB::Helper::User {list => 'user_list'};
+use OTRS::OPR::Web::App::Prerun qw(cgiapp_prerun);
+use OTRS::OPR::Web::App::Session;
+use OTRS::OPR::Web::Utils qw(prepare_select page_list);
+
+sub setup{
+ my ($self) = @_;
+
+ $self->main_tmpl( $self->_config->get('templates.admin') );
+
+ my $startmode = 'list';
+ my $param = $self->param( 'run' );
+ if( $param ){
+ $startmode = $param;
+ }
+
+ $self->start_mode( $startmode );
+ $self->mode_param( 'rm' );
+ $self->run_modes(
+ AUTOLOAD => \&list_packages,
+ list => \&list_packages,
+ delete_package => \&delete_package,
+ undelete_package => \&undelete_package,
+ co_maint => \&set_comaintainer,
+ save_co_maint => \&save_comaintainer,
+ comments => \&comments,
+ delete_comment => \&delete_comment,
+ undelete_comment => \&undelete_comment,
+ );
+}
+
+sub list_packages : Permission('list_packages') {
+ my ($self) = @_;
+
+ my $config = $self->config;
+
+ my %params = $self->query->Vars;
+ my $search_term = $params{search_term};
+ my $page = $params{page} || 1;
+
+ if ( !looks_like_number($page) or $page <= 0 ) {
+ $page = 1;
+ }
+
+ my ($packages,$pages) = $self->page( $page, $search_term );
+ my $pagelist = $self->page_list( $pages, $page );
+
+ $self->template( 'admin_package_list' );
+ $self->stash(
+ PACKAGES => $packages,
+ PAGES => $pagelist,
+ );
+}
+
+sub delete_package : Permission( 'delete_package' ) : Json {
+ my ($self) = @_;
+
+ # the package is not deleted, it's just marked to be deleted and
+ # a new job is created
+ my $config = $self->config;
+ my $package = $self->param( 'package' );
+
+ if ( !looks_like_number($package) or $package <= 0 ) {
+ return { error => 'invalid package' };
+ }
+
+ my $delete_until;
+
+ my ($package_obj) = $self->table( 'opr_package' )->find( $package );
+ if ( $package_obj ) {
+ $delete_until = time + $config->get( 'deletion.span.package' );
+ $package_obj->deletion_flag( $delete_until );
+ $package_obj->update;
+ }
+
+ my $job_id = $self->create_job({
+ id => $package,
+ type => 'delete',
+ });
+
+ return { delete_until => $delete_until };
+}
+
+sub undelete_package : Permission( 'undelete_package' ) : Json {
+ my ($self) = @_;
+
+ my $package = $self->param( 'package' );
+
+ if ( !looks_like_number($package) or $package <= 0 ) {