/[suikacvs]/webroot/www/canvas/remote/server.cgi
Suika

Contents of /webroot/www/canvas/remote/server.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations) (download)
Sun May 24 13:36:58 2009 UTC (15 years, 11 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +47 -0 lines
Error occurred while calculating annotation data.
posting to hatena haiku

1 #!/usr/bin/perl
2 use strict;
3 use warnings;
4
5 my $param = {};
6 for (map {[split /=/, $_, 2]} split /[&;]/, $ENV{QUERY_STRING} || '') {
7 $param->{$_->[0]} = $_->[1];
8 }
9
10 $param->{mode} ||= '';
11 die unless $param->{date} =~ /\A[0-9]+\z/ or {list => 1, prev => 1, next => 1}->{$param->{mode}};
12
13 my $dir_name = './canvas-data';
14 my $data_file_name = sprintf '%s/data-%s.txt', $dir_name, $param->{date};
15 my $data_file_name_pattern = qr[^data-([0-9]+)\.txt$];
16
17 sub get_dates () {
18 my @date;
19 opendir my $dir, $dir_name or die "$0: $dir_name: $!";
20 for (readdir $dir) {
21 if (/$data_file_name_pattern/) {
22 push @date, $1;
23 }
24 }
25 return sort {$a <=> $b} @date;
26 }
27
28 if ($param->{mode} eq '' and $ENV{REQUEST_METHOD} eq 'POST') {
29 die if $ENV{CONTENT_LENGTH} > 100_000;
30
31 open my $data_file, '>>', $data_file_name or die "$0: $data_file_name: $!";
32 print $data_file 'time,', scalar time, "\x0A";
33 read STDIN, my $data, $ENV{CONTENT_LENGTH};
34 for (split /;/, $data) {
35 print $data_file $_, "\x0A";
36 }
37 print "Status: 204 No Content\n\n";
38 } elsif ($param->{mode} eq 'list') {
39 print "Content-Type: text/html\n\n";
40 print q[<!DOCTYPE HTML><html lang=en><title>List</title>
41 <meta name="viewport" content="width=device-width">
42 <style>
43 img {
44 width: 100px;
45 float: left;
46 }
47 ul {
48 margin: 0;
49 padding: 0;
50 }
51 li {
52 display: block;
53 margin: 0;
54 padding: 0;
55 clear: left;
56 }
57 li + li {
58 margin-top: 0.3em;
59 border-top: gray thin solid;
60 padding-top: 0.2em;
61 }
62 </style>];
63 print q[<ul>];
64 print q[<li><a href="client.html?mode=editor">new</a>];
65
66 for my $date (reverse get_dates) {
67 printf q[<li><img src="canvas-data/data-%s.txt.png"> %s <a href="client.html?mode=viewer;date=%s">view</a> <a href="client.html?mode=editor;date=%s">edit</a> <a href="client.html?mode=editor;import-date=%s">clone</a> <a href="canvas-data/data-%s.txt">data</a>],
68 $date,
69 (scalar localtime ($date / 1000)),
70 $date,
71 $date,
72 $date,
73 $date;
74 }
75
76 print q[</ul>];
77 } elsif ($param->{mode} eq 'next') {
78 for (get_dates) {
79 next if $_ <= $param->{date};
80 my $mode = $ENV{HTTP_REFERER} =~ /viewer/ ? 'viewer' : 'editor';
81 my $url = qq<http://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}/../client.html?mode=$mode;date=$_>;
82 $url =~ s/[^\x21-\x7E]/_/g;
83 print "Status: 302 Found\nLocation: $url\n\n";
84 }
85 print "Status: 302 Found\nLocation: http://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}/../client.html?mode=editor\n\n";
86 } elsif ($param->{mode} eq 'prev') {
87 my $date;
88 for (get_dates) {
89 last if $_ >= $param->{date};
90 $date = $_;
91 }
92 if (defined $date) {
93 my $mode = $ENV{HTTP_REFERER} =~ /viewer/ ? 'viewer' : 'editor';
94 my $url = qq<http://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}/../client.html?mode=$mode;date=$date>;
95 $url =~ s/[^\x21-\x7E]/_/g;
96 print "Status: 302 Found\nLocation: $url\n\n";
97 } else {
98 print "Status: 204 Not Found\n\n";
99 }
100 } elsif ($param->{mode} eq 'png' and $ENV{REQUEST_METHOD} eq 'POST') {
101 die if $ENV{CONTENT_LENGTH} > 100_000;
102
103 read STDIN, my $url, $ENV{CONTENT_LENGTH};
104 die unless $url =~ s[^data:image/png;base64,][];
105
106 require MIME::Base64;
107 my $png = MIME::Base64::decode_base64 ($url);
108
109 open my $data_file, '>', $data_file_name . '.png' or die "$0: $data_file_name.png: $!";
110 print $data_file $png;
111
112 my $l_url = qq<http://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}/../$data_file_name.png>;
113 print "Status: 201 Created\nLocation: $l_url\nContent-Type: text/plain\n\n";
114 } elsif ($param->{mode} eq 'haiku' and $ENV{REQUEST_METHOD} eq 'POST') {
115 die if $ENV{CONTENT_LENGTH} > 100_000;
116
117 my $url = $ENV{HTTP_X_DATA_URL};
118 unless ($url) {
119 read STDIN, $url, $ENV{CONTENT_LENGTH};
120 }
121 die unless $url =~ s[^data:image/png;base64,][];
122
123 require MIME::Base64;
124 my $png = MIME::Base64::decode_base64 ($url);
125
126 my $boundary = '';
127
128 if ($ENV{BOUNDARY}) {
129 $boundary = $ENV{BOUNDARY};
130 } else {
131 $boundary .= [0..9, 'A'..'Z', 'a'..'z']->[rand 62] for 1..30;
132 #print "Content-Type: multipart/form-data; boundary=$boundary\x0D\x0A\x0D\x0A";
133 }
134
135 my $source = 'Remote Canvas';
136 if ($ENV{HTTP_USER_AGENT} =~ /Nintendo DSi/) {
137 $source .= ' (DSi)';
138 } else {
139 $source .= ' (Web)';
140 }
141
142 my $body = "--$boundary\x0D\x0AContent-Type: image/png\x0D\x0AContent-Disposition: form-data; name=file; filename=$boundary.png\x0D\x0A\x0D\x0A$png\x0D\x0A--$boundary\x0D\x0AContent-Disposition: form-data; name=source\x0D\x0A\x0D\x0A$source\x0D\x0A--$boundary--\x0D\x0A";
143
144 require LWP::UserAgent;
145 my $ua = LWP::UserAgent->new;
146 my $req = HTTP::Request->new (POST => q<http://h.hatena.ne.jp/api/statuses/update.json>);
147 $req->authorization_basic ($ENV{PHP_AUTH_USER}, $ENV{PHP_AUTH_PW});
148 $req->content_type ('multipart/form-data; boundary=' . $boundary);
149 $req->content ($body);
150 my $res = $ua->request ($req);
151 warn $req->headers->as_string;
152 warn $res->as_string;
153
154 if ($res->is_success) {
155 print "Status: 201 Posted\nContent-Type: text/plain\n\n" unless $ENV{VIA_PHP_PROXY};
156 print 201;
157 } else {
158 print "Status: 401 Failed\nContent-Type: text/plain\n\n" unless $ENV{VIA_PHP_PROXY};
159 print 401;
160 }
161 } else {
162 print "Content-Type: text/plain\n\n";
163 open my $data_file, '<', $data_file_name or die "$0: $data_file_name: $!";
164 while (<$data_file>) {
165 print $_;
166 }
167 }

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24  
Google Analytics is used in this page; Cookies are used. 忍者AdMax is used in this page; Cookies are used. Privacy policy.