Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

もろもろ

  • Loading branch information...
commit 5661c383181d5ccfb7efd0d771ecb1f10e687b6a 1 parent f0649b7
@kazeburo authored
View
81 eg/alter_for_primary.pl
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use FindBin;
+use utf8;
+use DBIx::Sunny;
+use Encode;
+use File::Copy;
+use Digest::MD5 qw/md5_hex/;
+
+my $root_dir = "$FindBin::Bin/..";
+my $dbh = DBIx::Sunny->connect_cached('dbi:SQLite:dbname='.$root_dir.'/data.o/gforecast.db','','',{
+ sqlite_use_immediate_transaction => 1,
+});
+
+$dbh->do(<<EOF);
+CREATE TABLE IF NOT EXISTS graphs_new (
+ id INTEGER NOT NULL PRIMARY KEY,
+ service_name VARCHAR(255) NOT NULL,
+ section_name VARCHAR(255) NOT NULL,
+ graph_name VARCHAR(255) NOT NULL,
+ number INT NOT NULL DEFAULT 0,
+ description VARCHAR(255) NOT NULL DEFAULT '',
+ sort UNSIGNED INT NOT NULL DEFAULT 0,
+ gmode VARCHAR(255) NOT NULL DEFAULT 'gauge',
+ color VARCHAR(255) NOT NULL DEFAULT '#00CC00',
+ ulimit INT NOT NULL DEFAULT 1000000000,
+ llimit INT NOT NULL DEFAULT 0,
+ sulimit INT NOT NULL DEFAULT 100000,
+ sllimit INT NOT NULL DEFAULT 0,
+ type VARCHAR(255) NOT NULL DEFAULT 'AREA',
+ stype VARCHAR(255) NOT NULL DEFAULT 'AREA',
+ meta TEXT NOT NULL DEFAULT '',
+ created_at UNSIGNED INT NOT NULL,
+ updated_at UNSIGNED INT NOT NULL,
+ UNIQUE (service_name, section_name, graph_name)
+)
+EOF
+
+$dbh->do(<<EOF);
+CREATE TABLE IF NOT EXISTS prev_graphs_new (
+ graph_id INT NOT NULL,
+ number INT NOT NULL DEFAULT 0,
+ subtract INT,
+ updated_at UNSIGNED INT NOT NULL,
+ PRIMARY KEY (graph_id)
+)
+EOF
+
+my $rows = $dbh->select_all('SELECT * FROM graphs');
+foreach my $old ( @$rows ) {
+ $dbh->query(
+ 'INSERT INTO graphs_new (service_name, section_name, graph_name,
+ number, description, sort, gmode, color, ulimit, llimit,
+ sulimit, sllimit, type, stype, created_at, updated_at)
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
+ map { $old->{$_} }
+ qw/service_name section_name graph_name number description sort gmode color ulimit llimit sulimit sllimit type stype created_at updated_at/
+ );
+ my $id = $dbh->last_insert_id;
+ my $old_prev = $dbh->select_row('SELECT * FROM prev_graphs WHERE service_name=? AND section_name=? AND graph_name=?',
+ $old->{service_name}, $old->{section_name}, $old->{graph_name} );
+ if ($old_prev) {
+ $dbh->query('INSERT INTO prev_graphs_new (graph_id, number, subtract, updated_at) VALUES (?,?,?,?)',
+ $id, $old_prev->{number}, $old_prev->{subtract}, $old_prev->{updated_at});
+ }
+}
+
+$dbh->query('DROP TABLE graphs');
+$dbh->query('DROP TABLE prev_graphs');
+
+$dbh->query('ALTER TABLE graphs_new RENAME to graphs');
+$dbh->query('ALTER TABLE prev_graphs_new RENAME to prev_graphs');
+
+my $rows_new = $dbh->select_all('SELECT * FROM graphs');
+foreach my $row ( @$rows_new ) {
+ my $old = md5_hex( join(':',map { Encode::encode_utf8($_) } $row->{service_name},$row->{section_name},$row->{graph_name}) );
+ my $new = md5_hex( Encode::encode_utf8($row->{id}) );
+ move( "$root_dir/data.o/$old.rrd","$root_dir/data.o/$new.rrd");
+}
View
114 lib/GrowthForecast/Data.pm
@@ -8,6 +8,7 @@ use Time::Piece;
use Digest::MD5 qw/md5_hex/;
use List::Util;
use Encode;
+use JSON;
use Log::Minimal;
sub new {
@@ -20,6 +21,7 @@ my $_on_connect = sub {
my $dbh = shift;
$dbh->do(<<EOF);
CREATE TABLE IF NOT EXISTS graphs (
+ id INTEGER NOT NULL PRIMARY KEY,
service_name VARCHAR(255) NOT NULL,
section_name VARCHAR(255) NOT NULL,
graph_name VARCHAR(255) NOT NULL,
@@ -34,21 +36,20 @@ CREATE TABLE IF NOT EXISTS graphs (
sllimit INT NOT NULL DEFAULT 0,
type VARCHAR(255) NOT NULL DEFAULT 'AREA',
stype VARCHAR(255) NOT NULL DEFAULT 'AREA',
+ meta TEXT NOT NULL DEFAULT '',
created_at UNSIGNED INT NOT NULL,
updated_at UNSIGNED INT NOT NULL,
- PRIMARY KEY (service_name, section_name, graph_name)
+ UNIQUE (service_name, section_name, graph_name)
)
EOF
$dbh->do(<<EOF);
CREATE TABLE IF NOT EXISTS prev_graphs (
- service_name VARCHAR(255) NOT NULL,
- section_name VARCHAR(255) NOT NULL,
- graph_name VARCHAR(255) NOT NULL,
+ graph_id INT NOT NULL,
number INT NOT NULL DEFAULT 0,
subtract INT,
updated_at UNSIGNED INT NOT NULL,
- PRIMARY KEY (service_name, section_name, graph_name)
+ PRIMARY KEY (graph_id)
)
EOF
return;
@@ -65,6 +66,22 @@ sub dbh {
$self->{dbh};
}
+sub inflate_row {
+ my ($self, $row) = @_;
+ $row->{created_at} = localtime($row->{created_at})->strftime('%Y/%m/%d %T');
+ $row->{updated_at} = localtime($row->{updated_at})->strftime('%Y/%m/%d %T');
+ $row->{md5} = md5_hex( Encode::encode_utf8($row->{id}) );
+ my $ref = decode_json($row->{meta}||'{}');
+ $ref->{adjust} = '*' if ! exists $ref->{adjust};
+ $ref->{adjustval} = '1' if ! exists $ref->{adjustval};
+ $ref->{unit} = '' if ! exists $ref->{unit};
+ my %result = (
+ %$ref,
+ %$row
+ );
+ \%result
+}
+
sub get {
my ($self, $service, $section, $graph) = @_;
my $row = $self->dbh->select_row(
@@ -72,43 +89,49 @@ sub get {
$service, $section, $graph
);
return unless $row;
- $row->{created_at} = localtime($row->{created_at})->strftime('%Y/%m/%d %T');
- $row->{updated_at} = localtime($row->{updated_at})->strftime('%Y/%m/%d %T');
- $row->{md5} = md5_hex( join(':',map { Encode::encode_utf8($_) } $row->{service_name},$row->{section_name},$row->{graph_name}) );
- $row;
+ $self->inflate_row($row);
}
-sub get_for_rrdupdate {
- my ($self, $service, $section, $graph) = @_;
+sub get_by_id {
+ my ($self, $id) = @_;
+ my $row = $self->dbh->select_row(
+ 'SELECT * FROM graphs WHERE id = ?',
+ $id
+ );
+ return unless $row;
+ $self->inflate_row($row);
+}
+
+sub get_by_id_for_rrdupdate {
+ my ($self, $id) = @_;
my $dbh = $self->dbh;
my $data = $dbh->select_row(
- 'SELECT * FROM graphs WHERE service_name = ? AND section_name = ? AND graph_name = ?',
- $service, $section, $graph
+ 'SELECT * FROM graphs WHERE id = ?',
+ $id
);
return if !$data;
$dbh->begin_work;
my $prev = $dbh->select_row(
- 'SELECT * FROM prev_graphs WHERE service_name = ? AND section_name = ? AND graph_name = ?',
- $service, $section, $graph
+ 'SELECT * FROM prev_graphs WHERE graph_id = ?',
+ $data->{id}
);
my $subtract;
if ( !$prev ) {
$subtract = 'U';
$dbh->query(
- 'INSERT INTO prev_graphs (service_name, section_name, graph_name, number, subtract, updated_at)
- VALUES (?,?,?,?,?,?)',
- $service, $section, $graph, $data->{number}, undef, $data->{updated_at});
+ 'INSERT INTO prev_graphs (graph_id, number, subtract, updated_at)
+ VALUES (?,?,?,?)',
+ $data->{id}, $data->{number}, undef, $data->{updated_at});
}
elsif ( $data->{updated_at} != $prev->{updated_at} ) {
$subtract = $data->{number} - $prev->{number};
$dbh->query(
- 'UPDATE prev_graphs SET number=?, subtract=?, updated_at=? WHERE service_name = ? AND section_name = ? AND graph_name = ?',
- $data->{number}, $subtract, $data->{updated_at},
- $service, $section, $graph,
+ 'UPDATE prev_graphs SET number=?, subtract=?, updated_at=? WHERE graph_id = ?',
+ $data->{number}, $subtract, $data->{updated_at}, $data->{id}
);
}
else {
@@ -117,12 +140,8 @@ sub get_for_rrdupdate {
}
$dbh->commit;
-
- $data->{created_at} = localtime($data->{created_at})->strftime('%Y/%m/%d %T');
- $data->{updated_at} = localtime($data->{updated_at})->strftime('%Y/%m/%d %T');
- $data->{md5} = md5_hex( join(':',map { Encode::encode_utf8($_) } $data->{service_name},$data->{section_name},$data->{graph_name}) );
$data->{subtract} = $subtract;
- $data;
+ $self->inflate_row($data);
}
sub update {
@@ -136,18 +155,17 @@ sub update {
$number += $data->{number};
}
$dbh->query(
- 'UPDATE graphs SET number=?, updated_at=? WHERE service_name = ? AND section_name = ? AND graph_name = ?',
- $number, time,
- $service, $section, $graph,
+ 'UPDATE graphs SET number=?, updated_at=? WHERE id = ?',
+ $number, time, $data->{id}
);
}
else {
my @colors = List::Util::shuffle(qw/33 66 99 cc/);
my $color = '#' . join('', splice(@colors,0,3));
$dbh->query(
- 'INSERT INTO graphs (service_name, section_name, graph_name, number, description, color, created_at, updated_at)
- VALUES (?,?,?,?,?,?,?,?)',
- $service, $section, $graph, $number, "", $color, time, time
+ 'INSERT INTO graphs (service_name, section_name, graph_name, number, color, created_at, updated_at)
+ VALUES (?,?,?,?,?,?,?)',
+ $service, $section, $graph, $number, $color, time, time
);
}
my $row = $self->get($service, $section, $graph);
@@ -157,13 +175,14 @@ sub update {
}
sub update_graph {
- my ($self, $service, $section, $graph, $description, $sort, $gmode, $color, $type, $stype, $llimit, $ulimit, $sllimit, $sulimit ) = @_;
+ my ($self, $id, $args) = @_;
+ my @update = map { delete $args->{$_} } qw/description sort gmode color type stype llimit ulimit sllimit sulimit/;
+ my $meta = encode_json($args);
my $dbh = $self->dbh;
$dbh->query(
- 'UPDATE graphs SET description=?, sort=?, gmode=?, color=?, type=?, stype=?, llimit=?, ulimit=?, sllimit=?, sulimit=?
- WHERE service_name = ? AND section_name = ? AND graph_name = ?',
- $description, $sort, $gmode, $color, $type, $stype, $llimit, $ulimit, $sllimit, $sulimit,
- $service, $section, $graph,
+ 'UPDATE graphs SET description=?, sort=?, gmode=?, color=?, type=?, stype=?,
+ llimit=?, ulimit=?, sllimit=?, sulimit=?, meta=? WHERE id = ?',
+ @update, $meta, $id
);
return 1;
}
@@ -197,32 +216,31 @@ sub get_graphs {
);
my @ret;
for my $row ( @$rows ) {
- $row->{created_at} = localtime($row->{created_at})->strftime('%Y/%m/%d %T');
- $row->{updated_at} = localtime($row->{updated_at})->strftime('%Y/%m/%d %T');
- $row->{md5} = md5_hex( join(':', map { Encode::encode_utf8($_) } $row->{service_name},$row->{section_name},$row->{graph_name}) );
- push @ret, $row;
+ push @ret, $self->inflate_row($row);
}
\@ret;
}
-sub get_all_graphs {
+sub get_all_graph_id {
my $self = shift;
$self->dbh->select_all(
- 'SELECT service_name, section_name, graph_name FROM graphs',
+ 'SELECT id FROM graphs',
);
}
sub remove {
- my ($self, $service, $section, $graph ) = @_;
+ my ($self, $id ) = @_;
my $dbh = $self->dbh;
+ $dbh->begin_work;
$dbh->query(
- 'DELETE FROM graphs WHERE service_name = ? AND section_name = ? AND graph_name = ?',
- $service, $section, $graph
+ 'DELETE FROM graphs WHERE id = ?',
+ $id
);
$dbh->query(
- 'DELETE FROM prev_graphs WHERE service_name = ? AND section_name = ? AND graph_name = ?',
- $service, $section, $graph
+ 'DELETE FROM prev_graphs WHERE graph_id = ?',
+ $id
);
+ $dbh->commit;
}
View
32 lib/GrowthForecast/RRD.pm
@@ -64,8 +64,12 @@ sub update {
my @jp_fonts = grep { -f $_ } zglob("/usr/share/fonts/**/sazanami-gothic.ttf");
sub graph {
my $self = shift;
- my ($gmode, $span, $from, $to, $data) = @_;
+ my $data = shift;
+ my $args = shift;
+ my ($gmode, $span, $from, $to, $width, $height) = map { $args->{$_} } qw/gmode t from to width height/;
$span ||= 'd';
+ $width ||= 390;
+ $height ||= 110;
my $period_title;
my $period;
@@ -126,10 +130,10 @@ sub graph {
if ( $gmode eq 'subtract' ) { $period_title = "[subtract] $period_title" }
my ($tmpfh, $tmpfile) = File::Temp::tempfile(UNLINK => 0, SUFFIX => ".png");
- my @args = (
+ my @opt = (
$tmpfile,
- '-w', 390,
- '-h', 110,
+ '-w', $width,
+ '-h', $height,
'-a', 'PNG',
'-t', "$period_title",
'-l', 0, #minimum
@@ -137,9 +141,11 @@ sub graph {
'-x', $xgrid,
'-s', $period,
'-e', $end,
+ '--slope-mode',
+ '--disable-rrdtool-tag',
);
-
- push @args, '--font', "DEFAULT:0:".$jp_fonts[0] if @jp_fonts;
+ push @opt, '--only-graph' if $args->{graphonly};
+ push @opt, '--font', "DEFAULT:0:".$jp_fonts[0] if @jp_fonts;
my $i=0;
my $type = ( $gmode eq 'subtract' ) ? $data->{stype} : $data->{type};
@@ -147,19 +153,19 @@ sub graph {
my $llimit = ( $gmode eq 'subtract' ) ? $data->{sllimit} : $data->{llimit};
my $ulimit = ( $gmode eq 'subtract' ) ? $data->{sulimit} : $data->{ulimit};
my $file = $self->path($data);
- push @args,
+ push @opt,
sprintf('DEF:%s%dt=%s:%s:AVERAGE', $gdata, $i, $file, $gdata),
- sprintf('CDEF:%s%d=%s%dt,%s,%s,LIMIT', $gdata, $i, $gdata, $i, $llimit, $ulimit),
+ sprintf('CDEF:%s%d=%s%dt,%s,%s,LIMIT,%d,%s', $gdata, $i, $gdata, $i, $llimit, $ulimit, $data->{adjustval}, $data->{adjust}),
sprintf('%s:%s%d%s:%s ', $type, $gdata, $i, $data->{color}, $data->{graph_name}),
- sprintf('GPRINT:%s%d:LAST:Cur\: %%4.1lf%%s', $gdata, $i),
- sprintf('GPRINT:%s%d:AVERAGE:Avg\: %%4.1lf%%s', $gdata, $i),
- sprintf('GPRINT:%s%d:MAX:Max\: %%4.1lf%%s', $gdata, $i),
- sprintf('GPRINT:%s%d:MIN:Min\: %%4.1lf%%s\l', $gdata, $i);
+ sprintf('GPRINT:%s%d:LAST:Cur\: %%4.1lf%%s%s', $gdata, $i, $data->{unit}),
+ sprintf('GPRINT:%s%d:AVERAGE:Avg\: %%4.1lf%%s%s', $gdata, $i, $data->{unit}),
+ sprintf('GPRINT:%s%d:MAX:Max\: %%4.1lf%%s%s', $gdata, $i, $data->{unit}),
+ sprintf('GPRINT:%s%d:MIN:Min\: %%4.1lf%%s%s\l', $gdata, $i, $data->{unit});
$i++;
eval {
- RRDs::graph(map { Encode::encode_utf8($_) } @args);
+ RRDs::graph(map { Encode::encode_utf8($_) } @opt);
my $ERR=RRDs::error;
die $ERR if $ERR;
};
View
92 lib/GrowthForecast/Web.pm
@@ -21,6 +21,19 @@ sub rrd {
$self->{__rrd};
}
+filter 'get_graph' => sub {
+ my $app = shift;
+ sub {
+ my ($self, $c) = @_;
+ my $row = $self->data->get(
+ $c->args->{service_name}, $c->args->{section_name}, $c->args->{graph_name},
+ );
+ $c->halt(404) unless $row;
+ $c->stash->{graph} = $row;
+ $app->($self,$c);
+ }
+};
+
get '/' => sub {
my ( $self, $c ) = @_;
my $services = $self->data->get_services();
@@ -57,7 +70,7 @@ get '/list/:service_name/:section_name' => sub {
$c->render('list.tx',{ graphs => $rows });
};
-get '/graph/:service_name/:section_name/:graph_name' => sub {
+get '/graph/:service_name/:section_name/:graph_name' => [qw/get_graph/] => sub {
my ( $self, $c ) = @_;
my $result = $c->req->validator([
't' => {
@@ -83,17 +96,29 @@ get '/graph/:service_name/:section_name/:graph_name' => sub {
rule => [
[sub{ HTTP::Date::str2time($_[1]) }, 'invalid To datetime'],
],
- }
+ },
+ 'width' => {
+ default => 390,
+ rule => [
+ ['NATURAL','invalid width'],
+ ],
+ },
+ 'height' => {
+ default => 110,
+ rule => [
+ ['NATURAL','invalid height'],
+ ],
+ },
+ 'graphonly' => {
+ default => 0,
+ rule => [
+ [['CHOICE',qw/0 1/],'invalid only flag'],
+ ],
+ },
]);
- my $row = $self->data->get(
- $c->args->{service_name}, $c->args->{section_name}, $c->args->{graph_name},
- );
- $c->halt(404) unless $row;
-
my $img = $self->rrd->graph(
- $result->valid('gmode'), $result->valid('t'), $result->valid('from'),
- $result->valid('to'), $row
+ $c->stash->{graph}, $result->valid->as_hashref
);
$c->res->content_type('image/png');
@@ -101,14 +126,9 @@ get '/graph/:service_name/:section_name/:graph_name' => sub {
return $c->res;
};
-post '/graph/:service_name/:section_name/:graph_name' => sub {
+post '/graph/:service_name/:section_name/:graph_name' => [qw/get_graph/] => sub {
my ( $self, $c ) = @_;
- my $row = $self->data->get(
- $c->args->{service_name}, $c->args->{section_name}, $c->args->{graph_name},
- );
- $c->halt(404) unless $row;
-
my $result = $c->req->validator([
'description' => {
default => '',
@@ -126,6 +146,24 @@ post '/graph/:service_name/:section_name/:graph_name' => sub {
[['CHOICE',qw/gauge subtract both/], '値が正しくありません'],
],
},
+ 'adjust' => {
+ default => '*',
+ rule => [
+ ['NOT_NULL', '値がありません'],
+ [['CHOICE','*','/'], '値が正しくありません'],
+ ]
+ },
+ 'adjustval' => {
+ default => '1',
+ rule => [
+ ['NOT_NULL', '正しくありません'],
+ ['NATURAL', '1以上の数値にしてください'],
+ ],
+ },
+ 'unit' => {
+ default => '',
+ rule => [],
+ },
'color' => {
rule => [
['NOT_NULL', '正しくありません'],
@@ -177,9 +215,10 @@ post '/graph/:service_name/:section_name/:graph_name' => sub {
return $res;
}
+
$self->data->update_graph(
- $c->args->{service_name}, $c->args->{section_name}, $c->args->{graph_name},
- map { $result->valid($_) } qw/description sort gmode color type stype llimit ulimit sllimit sulimit/
+ $c->stash->{graph}->{id},
+ $result->valid->as_hashref
);
$c->render_json({
@@ -187,29 +226,20 @@ post '/graph/:service_name/:section_name/:graph_name' => sub {
});
};
-post '/graph/:service_name/:section_name/:graph_name/delete' => sub {
+post '/graph/:service_name/:section_name/:graph_name/delete' => [qw/get_graph/] => sub {
my ( $self, $c ) = @_;
- my $row = $self->data->get(
- $c->args->{service_name}, $c->args->{section_name}, $c->args->{graph_name},
- );
- $c->halt(404) unless $row;
-
- $self->data->remove($c->args->{service_name}, $c->args->{section_name}, $c->args->{graph_name});
- $self->rrd->remove($row);
+ $self->data->remove($c->stash->{graph}->{id});
+ $self->rrd->remove($c->stash->{graph});
$c->render_json({
error => 0,
});
};
-get '/api/:service_name/:section_name/:graph_name' => sub {
+get '/api/:service_name/:section_name/:graph_name' => [qw/get_graph/] => sub {
my ( $self, $c ) = @_;
- my $row = $self->data->get(
- $c->args->{service_name}, $c->args->{section_name}, $c->args->{graph_name},
- );
- $c->halt(404) unless $row;
- $c->render_json($row);
+ $c->render_json($c->stash->{graph});
};
post '/api/:service_name/:section_name/:graph_name' => sub {
View
4 lib/GrowthForecast/Worker.pm
@@ -79,10 +79,10 @@ sub run {
next if $pid; #main process
#child process
- my $all_rows = $self->data->get_all_graphs;
+ my $all_rows = $self->data->get_all_graph_id;
for my $row ( @$all_rows ) {
debugf( "update %s", $row);
- my $data = $self->data->get_for_rrdupdate($row->{service_name},$row->{section_name},$row->{graph_name});
+ my $data = $self->data->get_by_id_for_rrdupdate($row->{id});
$self->rrd->update($data);
}
exit 0;
View
20 views/list.tx
@@ -30,7 +30,7 @@
<h3><: $graph.graph_name :> グラフ設定変更</h3>
</div>
-<div class="modal-body">
+<div class="modal-body" style="height:330px; overflow: auto">
<div class="alert-message error hide">
<p>System Error! <a href="#">try again</a>.</p>
</div>
@@ -80,6 +80,24 @@
<span id="pref-form-<: $~graph.index :>-type" class="validator-message help-inline"></span></div>
</div>
+<div class="clearfix">
+<label for="">データ調整</label>
+<div class="input">
+<div class="inline-inputs">
+値
+<select name="adjust" class="small">
+<option value="*">×</option>
+<option value="/">÷</option>
+</select>
+<input class="small" name="adjustval" />
+単位
+<input class="small" name="unit" />
+</div>
+<span id="pref-form-<: $~graph.index :>-adjust" class="validator-message help-block"></span>
+<span id="pref-form-<: $~graph.index :>-adjustval" class="validator-message help-block"></span>
+<span id="pref-form-<: $~graph.index :>-unit" class="validator-message help-block"></span>
+</div>
+</div>
<div class="clearfix">
<label for="">グラフの色</label>
Please sign in to comment.
Something went wrong with that request. Please try again.