Perl
LINE NEWS
LINE (@nipotan)
@nipotan
nipotan
https://github.com/nipotan
LINE 3
http://nipotan.com
livedoor News LINE NEWS
•
•
•
•
LINE
livedoor News livedoor Blog
BLOGOS LINE NEWS
Perl
Sledge Sledge
Pickles Amon2
LINE NEWS
●
● Amon2
● JSON API
● Web
● Admin CMS
Jul 2013
MAU
300
( 2012 2 )
LINE NEWS
LINE NEWS DIGEST
LINE Messaging API -
https://developers.line.me/ja/docs/messaging-api/reference/
MAU
600
LINE NEWS DIGEST
● Perl
● Imager
●
●
LINE NEWS DIGEST
use strict;
use warnings;
use utf8;
use Imager;
use Imager::Font;
my $header = Imager->new(xsize => 1040, ysize => 140); #
$header->box(filled => 1, color => '#ffffff');
my $logo = Imager->new(file => '/path/to/line-news-logo.png'); #
$header->compose(src => $logo, tx => 36, ty => 40);
#
my $hiragino_w3 = Imager::Font->new(file => ‘/path/to/hiragino-kakugo-w3.otf');
my $hiragino_w6 = Imager::Font->new(file => '/path/to/hiragino-kakugo-w6.otf');
#
my $go = 'YAPC::Okinawa ';
my $bbox = $hiragino_w3->bounding_box(string => $go, size => 28); #
my $x = 1040 - 36 - $bbox->pos_width; # 36 px
$header->string(
font => $hiragino_w3,
text => $go,
x => $x,
y => 80,
size => 28,
color => '#a0a0a0',
aa => 1,
);
LINE NEWS DIGEST
LINE NEWS DIGEST
0%
55%
my $headline = Imager->new(file => '/path/to/yapcjapan2018.png');
# y 370 793 423 px
# 0% 55%
# 1040x1
my $line = Imager->new(
xsize => 1040,
ysize => 1,
channels => 4, # alpha channel
);
$line->box(filled => 1, color => '#000000'); #
my $opacity = 0.00;
my $increment_per_line = (0.55 - $opacity) / 423; # 1 px
for my $y (370 .. 793) {
$headline->compose(
src => $line,
tx => 0,
ty => $y,
opacity => $opacity,
);
$opacity += $increment_per_line;
}
LINE NEWS DIGEST
#
my $tp = Imager->new(
xsize => 1040,
ysize => 794,
channels => 4, # alpha channel
);
#
my $title = 'YAPC::Japan ';
#
my $description = '2018 3 3 OIST@ Perl ';
#
$tp->string(
font => $hiragino_w6,
text => $title,
x => 36,
y => 684,
size => 70,
color => '#000000',
aa => 1,
);
$tp->string(
font => $hiragino_w3,
text => $description,
x => 36,
y => 748,
size => 40,
color => '#000000',
aa => 1,
);
# 43%
$headline->compose(src => $tp, tx => 0, ty => 0, opacity => 0.43);
LINE NEWS DIGEST
$headline->string(
font => $hiragino_w6,
text => $title,
x => 36,
y => 682,
size => 70,
color => '#ffffff',
aa => 1,
);
$headline->string(
font => $hiragino_w3,
text => $description,
x => 36,
y => 746,
size => 40,
color => '#ffffff',
aa => 1,
);
LINE NEWS DIGEST
my $img01 = Imager->new(file => '/path/to/ao-no-doukutsu.jpg');
my $line = Imager->new(
xsize => 386,
ysize => 1,
channels => 4,
);
$line->box(filled => 1, color => '#000000');
my $opacity = 0.00;
my $increment_per_line = (0.55 - $opacity) / 203;
for my $y (171 .. 374) {
$img01->compose(
src => $line,
tx => 0,
ty => $y,
opacity => $opacity,
);
$opacity += $increment_per_line;
}
my $tp = Imager->new(
xsize => 386,
ysize => 375,
channels => 4,
);
$tp->string(
font => $hiragino_w3,
text => ' ',
x => 36,
y => 338,
size => 40,
color => '#000000',
aa => 1,
);
$img01->compose(src => $tp, tx => 0, ty => 0, opacity => 0.43);
$img01->string(
font => $hiragino_w3,
text => ' ',
x => 36,
y => 336,
size => 40,
color => '#ffffff',
aa => 1,
);
LINE NEWS DIGEST
my @titles = (
‘ ’, ' ',
‘ ', ' ',
' ',
);
my @text_news;
for my $i (0 .. 4) {
my $text = Imager->new(xsize => 654, ysize => 150); #
$text->box(filled => 1, color => '#ffffff');
my $line = Imager->new(xsize => 654, ysize => 2); #
$line->box(filled => 1, color => '#dde0e6');
$text->paste(left => 0, top => 148, img => $line);
$text->string(
font => $hiragino_w3,
text => $titles[$i],
x => 36,
y => 91,
size => 41,
color => '#000000',
aa => 1,
);
push @text_news, $text;
}
LINE NEWS DIGEST
#
my $footer = Imager->new(xsize => 1040, ysize => 140);
$footer->box(filled => 1, color => '#ffffff');
my $arrow = Imager->new(file => '/path/to/arrow.png');
$footer->compose(src => $arrow, tx => 984, ty => 53);
$footer->string(
font => $hiragino_w6,
text => ' ',
x => 36,
y => 84,
size => 36,
color => '#284096',
aa => 1,
);
LINE NEWS DIGEST
#
my $base = Imager->new(xsize => 1040, ysize => 1824);
$base->box(filled => 1, color => '#ffffff');
$base->paste(left => 0, top => 0, img => $header);
$base->paste(left => 0, top => 140, img => $headline);
$base->paste(left => 0, top => 934, img => $img01);
$base->paste(left => 0, top => 1309, img => $img02);
my $y = 934;
for my $i (0 .. 4) {
$base->paste(left => 386, top => $y + $i * 150, img => $text_news[$i]);
}
$base->paste(left => 0, top => 1684, img => $footer);
LINE NEWS DIGEST
Imager
Apr 2016Apr 2015
LINE
Web App
Feb 2017
LINE 5
Dec 2015
LINE
LINE NEWS
MAU
1200
MAU
2200
MAU
4100
MAU
5900
…
● LINE NEWS DIGEST
●
Request count
1 LINE NEWS
By Facebook
Instant
Articles
By Google
AMP
By SmartNews
Smart
View
0.5
●
● SPA (Single-Page Application)
● HTML
●
● id auto paging
●
● + localStorage
0.5
UIT++
●
● CDN
● CDN
●
● Cache-Control
● HTTP/2
● origin HTTP/1.1 CDN
● static content proxy connection reuse
0.5
● KVS
● HTTP
● PSGI
●
● Primary Key Array
●
● Primary Key get() || get_multi()
0.5
MISSION COMPLETED
LINE NEWS
● LINE NEWS vs Perl
● Perl
● Java
● Perl 5 vs Java 9
● Perl & Java 3
● Perl
● Perl …
LINE NEWS
● Perl:Java 6:4 ( )
●
● Web API http://d.hatena.ne.jp/naoya/20060228/1141094456
●
●
● Java
● Java
● Perl
● Perl Web API Java
● “ ” …
LINE NEWS
● Perl
● Java GOOD
● Perl
● LINE Perl
●
LINE
● Shibuya Perl Mongers #1 (Jan 31, 2003)
● 15 20 Perl
● YAPC::Asia (2006 2015) Perl
● 40 …
● Okinawa Perl Mongers
●
THANK YOU

Perlで実装されたLINE NEWSの裏側

  • 1.
  • 2.
  • 3.
    livedoor News LINENEWS • • • • LINE
  • 4.
    livedoor News livedoorBlog BLOGOS LINE NEWS Perl Sledge Sledge Pickles Amon2
  • 5.
  • 6.
    ● ● Amon2 ● JSONAPI ● Web ● Admin CMS Jul 2013 MAU 300
  • 7.
    ( 2012 2) LINE NEWS
  • 8.
    LINE NEWS DIGEST LINEMessaging API - https://developers.line.me/ja/docs/messaging-api/reference/ MAU 600
  • 9.
  • 10.
  • 11.
    use strict; use warnings; useutf8; use Imager; use Imager::Font; my $header = Imager->new(xsize => 1040, ysize => 140); # $header->box(filled => 1, color => '#ffffff'); my $logo = Imager->new(file => '/path/to/line-news-logo.png'); # $header->compose(src => $logo, tx => 36, ty => 40); # my $hiragino_w3 = Imager::Font->new(file => ‘/path/to/hiragino-kakugo-w3.otf'); my $hiragino_w6 = Imager::Font->new(file => '/path/to/hiragino-kakugo-w6.otf'); # my $go = 'YAPC::Okinawa '; my $bbox = $hiragino_w3->bounding_box(string => $go, size => 28); # my $x = 1040 - 36 - $bbox->pos_width; # 36 px $header->string( font => $hiragino_w3, text => $go, x => $x, y => 80, size => 28, color => '#a0a0a0', aa => 1, ); LINE NEWS DIGEST
  • 12.
  • 13.
    my $headline =Imager->new(file => '/path/to/yapcjapan2018.png'); # y 370 793 423 px # 0% 55% # 1040x1 my $line = Imager->new( xsize => 1040, ysize => 1, channels => 4, # alpha channel ); $line->box(filled => 1, color => '#000000'); # my $opacity = 0.00; my $increment_per_line = (0.55 - $opacity) / 423; # 1 px for my $y (370 .. 793) { $headline->compose( src => $line, tx => 0, ty => $y, opacity => $opacity, ); $opacity += $increment_per_line; } LINE NEWS DIGEST
  • 14.
    # my $tp =Imager->new( xsize => 1040, ysize => 794, channels => 4, # alpha channel ); # my $title = 'YAPC::Japan '; # my $description = '2018 3 3 OIST@ Perl '; # $tp->string( font => $hiragino_w6, text => $title, x => 36, y => 684, size => 70, color => '#000000', aa => 1, ); $tp->string( font => $hiragino_w3, text => $description, x => 36, y => 748, size => 40, color => '#000000', aa => 1, ); # 43% $headline->compose(src => $tp, tx => 0, ty => 0, opacity => 0.43); LINE NEWS DIGEST
  • 15.
    $headline->string( font => $hiragino_w6, text=> $title, x => 36, y => 682, size => 70, color => '#ffffff', aa => 1, ); $headline->string( font => $hiragino_w3, text => $description, x => 36, y => 746, size => 40, color => '#ffffff', aa => 1, ); LINE NEWS DIGEST
  • 16.
    my $img01 =Imager->new(file => '/path/to/ao-no-doukutsu.jpg'); my $line = Imager->new( xsize => 386, ysize => 1, channels => 4, ); $line->box(filled => 1, color => '#000000'); my $opacity = 0.00; my $increment_per_line = (0.55 - $opacity) / 203; for my $y (171 .. 374) { $img01->compose( src => $line, tx => 0, ty => $y, opacity => $opacity, ); $opacity += $increment_per_line; } my $tp = Imager->new( xsize => 386, ysize => 375, channels => 4, ); $tp->string( font => $hiragino_w3, text => ' ', x => 36, y => 338, size => 40, color => '#000000', aa => 1, ); $img01->compose(src => $tp, tx => 0, ty => 0, opacity => 0.43); $img01->string( font => $hiragino_w3, text => ' ', x => 36, y => 336, size => 40, color => '#ffffff', aa => 1, ); LINE NEWS DIGEST
  • 17.
    my @titles =( ‘ ’, ' ', ‘ ', ' ', ' ', ); my @text_news; for my $i (0 .. 4) { my $text = Imager->new(xsize => 654, ysize => 150); # $text->box(filled => 1, color => '#ffffff'); my $line = Imager->new(xsize => 654, ysize => 2); # $line->box(filled => 1, color => '#dde0e6'); $text->paste(left => 0, top => 148, img => $line); $text->string( font => $hiragino_w3, text => $titles[$i], x => 36, y => 91, size => 41, color => '#000000', aa => 1, ); push @text_news, $text; } LINE NEWS DIGEST
  • 18.
    # my $footer =Imager->new(xsize => 1040, ysize => 140); $footer->box(filled => 1, color => '#ffffff'); my $arrow = Imager->new(file => '/path/to/arrow.png'); $footer->compose(src => $arrow, tx => 984, ty => 53); $footer->string( font => $hiragino_w6, text => ' ', x => 36, y => 84, size => 36, color => '#284096', aa => 1, ); LINE NEWS DIGEST
  • 19.
    # my $base =Imager->new(xsize => 1040, ysize => 1824); $base->box(filled => 1, color => '#ffffff'); $base->paste(left => 0, top => 0, img => $header); $base->paste(left => 0, top => 140, img => $headline); $base->paste(left => 0, top => 934, img => $img01); $base->paste(left => 0, top => 1309, img => $img02); my $y = 934; for my $i (0 .. 4) { $base->paste(left => 386, top => $y + $i * 150, img => $text_news[$i]); } $base->paste(left => 0, top => 1684, img => $footer); LINE NEWS DIGEST
  • 20.
  • 21.
    Apr 2016Apr 2015 LINE WebApp Feb 2017 LINE 5 Dec 2015 LINE LINE NEWS MAU 1200 MAU 2200 MAU 4100 MAU 5900
  • 22.
  • 23.
  • 24.
  • 25.
    ● ● SPA (Single-PageApplication) ● HTML ● ● id auto paging ● ● + localStorage 0.5 UIT++
  • 26.
    ● ● CDN ● CDN ● ●Cache-Control ● HTTP/2 ● origin HTTP/1.1 CDN ● static content proxy connection reuse 0.5
  • 27.
    ● KVS ● HTTP ●PSGI ● ● Primary Key Array ● ● Primary Key get() || get_multi() 0.5
  • 28.
  • 29.
  • 30.
    ● LINE NEWSvs Perl ● Perl ● Java ● Perl 5 vs Java 9 ● Perl & Java 3 ● Perl ● Perl … LINE NEWS
  • 31.
    ● Perl:Java 6:4( ) ● ● Web API http://d.hatena.ne.jp/naoya/20060228/1141094456 ● ● ● Java ● Java ● Perl ● Perl Web API Java ● “ ” … LINE NEWS
  • 32.
    ● Perl ● JavaGOOD ● Perl ● LINE Perl ● LINE
  • 33.
    ● Shibuya PerlMongers #1 (Jan 31, 2003) ● 15 20 Perl ● YAPC::Asia (2006 2015) Perl ● 40 … ● Okinawa Perl Mongers ●
  • 34.