commit 13fb8891c9612676a946149182e2ab85989a524a
parent ce598697addcad8e8d4ecd2098503349ef33f1cc
Author: Kyle Milz <kyle@getaddrinfo.net>
Date: Wed, 18 Mar 2015 22:12:02 -0600
gen_index: start generating a tree of html files
Make new vendor and manufacturer listing pages that refer to detailed product
listings.
Diffstat:
15 files changed, 457 insertions(+), 160 deletions(-)
diff --git a/Makefile b/Makefile
@@ -6,6 +6,7 @@ DEV_BIN=/home/kyle/src/pricechart
BINS=price_scraper product_scraper gen_index pc_fcgi gen_svg
# WARNING stupid idiom used below if adding > 1 item to LIBS!!
LIBS=PriceChart.pm
+HTML=tt logo pricechart.css
install:
cp $(BINS) $(USR_LOCAL_BIN)/
@@ -17,8 +18,8 @@ install:
mkdir -p $(HTDOCS)/pricechart
mkdir -p $(HTDOCS)/pricechart/svg
- cp -R html/* $(HTDOCS)/pricechart/
- chown -R www $(HTDOCS)/pricechart
+ cp -R $(HTML) $(HTDOCS)/pricechart/
+ chown -R www:daemon $(HTDOCS)/pricechart
uninstall:
# rm /etc/rc.d/pc_fcgi
diff --git a/gen_index b/gen_index
@@ -8,6 +8,7 @@ use Getopt::Std;
use File::Copy;
use PriceChart;
use Template;
+use URI::Escape;
my %args;
@@ -18,42 +19,113 @@ $| = 1 if ($args{v});
my $cfg = get_config();
my $dbh = get_dbh($cfg->{"http"}, undef, $args{v});
-my $work_dir = $cfg->{"http"}{"chroot"} . $cfg->{"http"}{"htdocs"};
-print "info: work dir: $work_dir\n" if ($args{v});
+my $work_dir = $cfg->{http}{chroot} . $cfg->{http}{htdocs};
+print "info: working dir: $work_dir\n" if ($args{v});
my $config = {
INTERPOLATE => 1,
POST_CHOMP => 1,
EVAL_PERL => 1,
- INCLUDE_PATH => $work_dir,
+ INCLUDE_PATH => "$work_dir/tt",
OUTPUT_PATH => $work_dir
};
-my $template = Template->new($config);
+my $template = Template->new($config)
+ || die Template->error() . "\n";
-my $query = "select count(distinct manufacturer) from products";
-my ($m) = $dbh->selectrow_array($query);
+# xmkdir $cfg->{http} . "/manufacturers";
+my $sql = "select distinct manufacturer from products";
+# my $manuf_sth = $dbh->prepare($sql);
+# $manuf_sth->execute();
+# while (my ($manufacturer) = $manuf_sth->fetchrow_array()) {
+my $manufacturers = $dbh->selectall_arrayref($sql);
+my @manufacturer_list;
+for my $manufacturer (@$manufacturers) {
+ $manufacturer = $manufacturer->[0];
+ my $manuf_lc = lc($manufacturer);
-$query = "select count(part_num) from products";
-my ($p) = $dbh->selectrow_array($query);
+ $sql = "select part_num, manufacturer, description from products where manufacturer = ?";
+ my $part_nums = $dbh->selectall_arrayref($sql, undef, $manufacturer);
+ printf("info: manufacturers/$manuf_lc.html: %i products\n",
+ scalar @$part_nums) if ($args{v});
-$query = "select count(distinct vendor) from prices";
-my ($v) = $dbh->selectrow_array($query);
+ my $vars = {
+ name => $manufacturer,
+ products => $part_nums,
+ };
+ $template->process("chart_list.tt", $vars,
+ "manufacturers/$manuf_lc.html"); # error checking!
+
+ push @manufacturer_list, [$manufacturer, $manuf_lc];
+}
+
+# manufacturers.html
+my $vars = {
+ name => "Manufacturers",
+ name_lc => "manufacturers",
+ num_manufacturers => scalar @manufacturer_list,
+ manufacturers => \@manufacturer_list,
+};
+print "info: manufacturers.html\n";
+$template->process("link_list.tt", $vars, "manufacturers.html")
+ || die "template: " . $template->error() . "\n";
+
+
+# vendors/*.html
+$sql = "select distinct vendor from prices";
+my $vendors = $dbh->selectall_arrayref($sql);
+my @vendor_list;
+for my $vendor (@$vendors) {
+ $vendor = $vendor->[0];
+ my $vendor_lc = lc($vendor);
+
+ $sql = "select distinct part_num from prices where vendor = ?";
+ my $part_nums = $dbh->selectall_arrayref($sql, undef, $vendor);
+ printf("info: vendors/$vendor_lc.html: %i products\n",
+ scalar @$part_nums) if ($args{v});
+
+ my $vars = {
+ name => $vendor,
+ products => $part_nums,
+ };
+ $template->process("chart_list.tt", $vars,
+ "vendors/$vendor_lc.html"); # error checking!
+
+ push @vendor_list, [$vendor, uri_escape($vendor_lc)];
+}
+
+# vendors.html
+$vars = {
+ name => "Vendors",
+ name_lc => "vendors",
+ num_manufacturers => scalar @$vendors,
+ manufacturers => \@vendor_list,
+};
+print "info: vendors.html\n";
+$template->process("link_list.tt", $vars, "vendors.html")
+ || die "template: " . $template->error() . "\n";
+
+# index.html
+$sql = "select count(part_num) from products";
+my ($p) = $dbh->selectrow_array($sql);
+
+$sql = "select count(distinct vendor) from prices";
+my ($v) = $dbh->selectrow_array($sql);
my $time = time - (7 * 24 * 60 * 60);
-$query = "select description from products where first_seen > $time";
-my $new_products = $dbh->selectall_arrayref($query);
+$sql = "select description from products where first_seen > $time";
+my $new_products = $dbh->selectall_arrayref($sql);
my $n = @$new_products;
-print "info: $m manufacturers, $p products ($n new), $v vendors\n" if ($args{v});
-my $vars = {
+# print "info: manufacturers, $p products ($n new), $v vendors\n" if ($args{v});
+$vars = {
num_vendors => $v,
- num_manufacturers => $m,
+ num_manufacturers => scalar @$manufacturers,
num_products => $p,
num_new => $n,
- new_products => $new_products
+ new_products => $new_products,
};
-$template->process("index.tt2", $vars, "index.html")
+$template->process("index.tt", $vars, "index.html")
|| die "template: " . $template->error() . "\n";
$dbh->disconnect();
diff --git a/html/index.tt2 b/html/index.tt2
@@ -1,46 +0,0 @@
-[% WRAPPER wrapper.tt2 %]
- <div class="column">
- <h1>Welcome</h1>
-
- <p> Welcome to <em>Price</em>Chart, a price comparison
- service for consumer electronics.
- Currently <b>[% num_products %]</b> products from
- <b>[% num_manufacturers %]</b> manufacturers are tracked across
- <b>[% num_vendors %]</b> retailers.</p>
-
- <p> To start, try searching for a product or manufacturer in the
- search box at the top right. </p>
-
- <p> <em>Price</em><b>Chart</b> periodically looks up and saves
- the prices of products. These prices are converted to charts
- where determining which retailer is the best to purchase from is
- easy.</p>
- </div>
-
- <div class="column">
- <h1>Motivation</h1>
-
- <p> <em>Price</em><b>Chart</b> is meant to be a consumer
- purchasing tool. It is intended to give the consumer insight
- into retail pricing which they would not normally have. </p>
-
- <p> A common practice when purchasing something new is <em>price
- comparison</em>. A consumer decides on a certain product
- they are interested in and then look around for the best deal.
- That is what this service does. It automates <em>price
- comparisons</em>. </p>
-
- <p> This is important because the price difference between
- different retailers for the same product is often hundreds of
- dollars if not more. </p>
- </div>
-
- <div class="column">
- <h1>New Products ([% num_new %])</h1>
- <ul>
- [% FOREACH new_product IN new_products %]
- <li>[% new_product.0 %]
- [% END %]
- </ul>
- </div>
-[% END %]
diff --git a/html/pricechart.css b/html/pricechart.css
@@ -1,50 +0,0 @@
-.clear_both {
- clear: both;
-}
-
-fieldset {
- border: 0px;
- float: right;
-}
-
-input {
- font-size: 1em;
-}
-
-p {
- line-height: 1.5em;
-}
-
-#footer {
- text-align: center;
-}
-
-#title {
- font-size: 2em;
- color: black;
- text-decoration: none;
- float: left;
- text-shadow: 2px 2px #DDD;
-}
-
-.column {
- width: 40%;
- padding-left: 5%;
- padding-right: 5%;
-
- float: left;
-}
-
-.product {
- border: 1px solid black;
- padding: 10px;
- margin: 10px;
-}
-
-@media (max-width: 640px) {
- .column {
- width: 90%;
- padding-left: 5%;
- padding-right: 5%;
- }
-}
diff --git a/html/search.tt2 b/html/search.tt2
@@ -1,18 +0,0 @@
-[% WRAPPER wrapper.tt2 %]
- <p>Found <b>[% num_results %]</b> search
- [% IF num_results == 1 %]
- result
- [% ELSE %]
- results
- [% END %]
- for <b>[% query %]</b>:</p>
-
- [% FOREACH part_num IN results %]
- <div class="product">
- <b>[% part_num.1 %]</b> [% part_num.0 %]<br>
- [% part_num.2 %] <br>
- <object data="/svg/[% part_num.0 %].svg" type="image/svg+xml">
- </object>
- </div>
- [% END %]
-[% END %]
diff --git a/html/wrapper.tt2 b/html/wrapper.tt2
@@ -1,26 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="viewport" content="width=device-width" />
- <title>PriceChart</title>
- <link rel="stylesheet" type="text/css" href="/pricechart.css" />
-</head>
-<body>
- <a id="title" href='/'><em>Price</em><b>Chart</b></a>
- <form method="get" action="/search.html">
- <fieldset>
- <input type="text" name="q" />
- <input type="submit" value="Search">
- </fieldset>
- </form>
- <hr class="clear_both">
-
- [% content %]
-
- <hr class="clear_both">
- <div id="footer">
- <a href="mailto:kyle@getaddrinfo.net">Feedback/Donate</a>
- </div>
-</body>
-</html>
diff --git a/logo/best buy.svg b/logo/best buy.svg
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="300px" height="223.76px" viewBox="-76.006 558.537 300 223.76" enable-background="new -76.006 558.537 300 223.76"
+ xml:space="preserve">
+<path fill="#010101" d="M18.726,598.938l-43.586,34.055l-4.878,51.686l36.158,42.294l159.266,14.924l12.041-127.77L18.726,598.938z
+ M-14.094,665.54c-2.451-0.232-4.248-2.418-4.017-4.869c0.24-2.452,2.419-4.249,4.87-4.017c2.451,0.23,4.248,2.409,4.016,4.869
+ C-9.456,663.975-11.634,665.772-14.094,665.54z"/>
+<path fill="#F6EB16" d="M19.761,601.836l-42.004,32.481l-4.862,49.326l34.858,40.457l155.587,14.89l11.479-122.263L19.761,601.836z
+ M-6.649,661.764c-0.365,3.884-3.809,6.726-7.686,6.36c-3.883-0.372-6.725-3.818-6.361-7.702c0.374-3.875,3.819-6.717,7.703-6.352
+ C-9.117,654.442-6.276,657.887-6.649,661.764z"/>
+<polygon fill="#010101" points="49.501,628.554 84.698,631.916 83.687,642.458 67.836,640.943 67.514,644.338 81.974,645.722
+ 81.046,655.387 66.668,654.021 66.305,657.854 82.511,659.403 81.551,669.424 46.097,666.027 "/>
+<path fill="#010101" d="M89.948,657.034l-6.659,9.823c0,0,8.365,4.496,19.969,5.506c11.585,1.027,20.083-2.294,22.808-7.841
+ c2.732-5.533-0.539-11.829-5.905-13.574c-5.374-1.739-14.692-3.595-13.723-5.442c0.97-1.838,6.817-1.458,10.369,0.026
+ c3.553,1.482,4.522,2.367,4.522,2.367l6.112-8.736c0,0-6.493-4.754-18.644-5.476c-12.157-0.72-21.093,5.368-21.714,11.023
+ c-0.629,5.657,3.006,8.994,8.53,11.016c0,0,4.688,1.508,8.223,2.277c3.528,0.779,5.772,3.104,1.557,3.934
+ C101.178,662.766,92.507,659.651,89.948,657.034z"/>
+<polygon fill="#010101" points="138.322,649.434 127.961,648.446 129.121,636.247 169.022,640.057 167.863,652.256 157.494,651.263
+ 155.076,676.612 136.161,674.808 "/>
+<path fill="#010101" d="M52.441,671.387l18.31,1.656l-1.946,21.268c0,0-1.806,5.102,4.29,5.688c6.104,0.582,5.831-4.901,5.831-4.901
+ l2.004-20.995l18.385,1.757l-2.36,24.745c0,0-2.169,13.508-24.654,11.362c-22.477-2.145-22.17-16.356-22.17-16.356L52.441,671.387z"
+ />
+<polygon fill="#010101" points="120.4,677.88 125.651,688.224 132.426,679.031 153.768,681.06 133.858,700.786 132.318,716.902
+ 113.593,715.113 115.101,699.263 99.133,675.933 "/>
+<path fill="#010101" d="M40.623,688.737c0,0,7.711-1.516,7.513-9.393c-0.199-7.884-15.935-9.838-15.935-9.838l-25.972-2.575
+ l-3.544,37.606c0,0,20.729,2.179,26.765,2.667c6.038,0.479,18.204-0.034,19.405-7.811C50.047,691.611,40.623,688.737,40.623,688.737
+ z M22.892,677.972c0,0,7.976-0.737,7.537,3.005c-0.447,3.734-8.025,2.047-8.025,2.047L22.892,677.972z M21.227,697.15l0.415-6.111
+ c0,0,9.971-0.373,9.647,3.909C30.966,699.229,21.227,697.15,21.227,697.15z"/>
+<path fill="#010101" d="M36.83,645.647c0,0,7.711-1.516,7.512-9.393c-0.199-7.874-15.934-9.846-15.934-9.846l-25.98-2.567
+ l-3.536,37.606c0,0,20.729,2.18,26.758,2.659c6.037,0.497,18.203-0.024,19.404-7.803C46.254,648.521,36.83,645.647,36.83,645.647z
+ M19.256,634.98c0,0,7.984-0.729,7.544,3.006c-0.447,3.734-8.024,2.045-8.024,2.045L19.256,634.98z M17.6,654.17l0.414-6.121
+ c0,0,9.962-0.364,9.648,3.917C27.339,656.239,17.6,654.17,17.6,654.17z"/>
+<path fill="#010101" d="M153.909,684.753c0.157-1.664,1.64-2.89,3.305-2.732c1.664,0.157,2.898,1.647,2.741,3.313
+ c-0.157,1.664-1.648,2.891-3.313,2.733C154.977,687.9,153.751,686.418,153.909,684.753z M159.208,685.258
+ c0.141-1.415-0.786-2.534-2.045-2.649c-1.267-0.125-2.386,0.805-2.517,2.212c-0.141,1.415,0.786,2.532,2.045,2.657
+ C157.958,687.595,159.076,686.675,159.208,685.258z M155.929,683.205l1.267,0.123c0.829,0.075,1.242,0.407,1.176,1.127
+ c-0.058,0.588-0.422,0.837-0.986,0.837l0.778,1.581l-0.662-0.058l-0.737-1.565l-0.389-0.032l-0.142,1.473l-0.637-0.058
+ L155.929,683.205z M156.426,684.729l0.555,0.059c0.38,0.033,0.711,0.016,0.753-0.448c0.042-0.396-0.315-0.496-0.646-0.528
+ l-0.571-0.06L156.426,684.729z"/>
+</svg>
diff --git a/logo/samsung.svg b/logo/samsung.svg
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="567.938px" height="85.244px" viewBox="0 0 567.938 85.244" enable-background="new 0 0 567.938 85.244"
+ xml:space="preserve">
+<g>
+ <polygon fill="#074CA1" points="121.635,3.169 87.297,3.169 73.672,80.147 94.69,80.147 103.42,20.206 105.512,20.206
+ 114.243,80.147 135.26,80.147 "/>
+ <polygon fill="#074CA1" points="221.298,80.147 220.329,22.257 218.393,22.257 208.516,80.147 187.849,80.147 177.972,22.257
+ 176.036,22.257 175.067,80.147 155.462,80.147 158.614,3.169 191.507,3.169 197.314,45.7 199.05,45.7 204.857,3.169 237.75,3.169
+ 240.903,80.147 "/>
+ <polygon fill="#074CA1" points="342.15,63.162 342.085,3.169 363.713,3.169 363.713,62.147 363.701,62.465 363.706,62.776
+ 363.727,63.087 363.764,63.392 363.815,63.69 363.883,63.985 363.965,64.274 364.063,64.558 364.171,64.833 364.294,65.103
+ 364.431,65.365 364.579,65.619 364.741,65.865 364.914,66.103 365.098,66.331 365.293,66.55 365.499,66.759 365.715,66.957
+ 365.941,67.146 366.176,67.321 366.42,67.485 366.673,67.64 366.935,67.778 367.203,67.906 367.479,68.021 367.762,68.121
+ 368.052,68.207 368.348,68.278 368.648,68.335 368.956,68.375 369.268,68.399 369.584,68.408 369.9,68.399 370.212,68.375
+ 370.519,68.335 370.82,68.278 371.116,68.207 371.406,68.121 371.688,68.021 371.965,67.906 372.233,67.778 372.495,67.64
+ 372.747,67.485 372.991,67.321 373.227,67.146 373.453,66.957 373.669,66.759 373.875,66.55 374.07,66.331 374.254,66.103
+ 374.428,65.865 374.589,65.619 374.737,65.365 374.874,65.103 374.997,64.833 375.107,64.558 375.203,64.274 375.285,63.985
+ 375.352,63.69 375.404,63.392 375.441,63.087 375.462,62.776 375.467,62.465 375.455,62.147 375.455,3.169 397.04,3.169
+ 397.04,63.511 397.003,64.799 396.887,66.046 396.695,67.253 396.431,68.418 396.096,69.543 395.692,70.626 395.224,71.669
+ 394.691,72.671 394.1,73.632 393.449,74.551 392.744,75.431 391.985,76.269 391.177,77.063 390.32,77.819 389.418,78.535
+ 388.473,79.209 387.487,79.842 386.465,80.435 385.406,80.983 384.315,81.494 383.194,81.963 382.045,82.39 380.871,82.776
+ 379.674,83.122 378.458,83.426 377.223,83.688 374.711,84.093 372.159,84.331 369.587,84.405 367.015,84.313 364.463,84.06
+ 361.951,83.64 360.717,83.368 359.5,83.056 358.304,82.701 357.13,82.306 355.981,81.869 354.86,81.392 353.77,80.872
+ 352.712,80.312 351.689,79.71 350.705,79.067 349.761,78.383 348.859,77.657 348.003,76.892 347.195,76.083 346.438,75.233
+ 345.732,74.343 345.083,73.411 344.491,72.438 343.961,71.423 343.493,70.367 343.091,69.271 342.756,68.131 342.493,66.951
+ 342.302,65.729 342.188,64.467 "/>
+ <polygon fill="#074CA1" points="488.809,3.169 470.088,3.169 470.088,51.322 469.644,51.322 447.847,3.169 424.766,3.169
+ 424.766,80.147 443.485,80.147 443.485,35.17 443.932,35.17 464.35,80.147 488.809,80.147 "/>
+ <polygon fill="#074CA1" points="263.819,64.985 263.819,54.813 285.354,54.813 285.205,59.414 285.221,60.476 285.284,61.487
+ 285.339,61.974 285.411,62.444 285.503,62.897 285.616,63.337 285.752,63.757 285.829,63.96 285.912,64.158 286.002,64.353
+ 286.1,64.541 286.203,64.726 286.313,64.903 286.434,65.076 286.559,65.244 286.691,65.406 286.835,65.563 286.986,65.714
+ 287.146,65.858 287.313,65.999 287.49,66.132 287.677,66.259 287.872,66.38 288.077,66.494 288.293,66.603 288.52,66.703
+ 288.754,66.798 289,66.886 289.258,66.967 289.805,67.106 290.398,67.219 291.039,67.301 291.729,67.353 291.88,67.354
+ 292.033,67.354 292.188,67.345 292.344,67.33 292.501,67.31 292.659,67.28 292.818,67.247 292.979,67.206 293.298,67.106
+ 293.617,66.985 293.936,66.839 294.249,66.67 294.559,66.478 294.857,66.263 295.15,66.024 295.434,65.769 295.702,65.487
+ 295.957,65.187 296.195,64.866 296.419,64.524 296.621,64.164 296.803,63.784 296.962,63.386 297.098,62.969 297.205,62.533
+ 297.285,62.081 297.337,61.61 297.355,61.124 297.343,60.621 297.295,60.103 297.211,59.567 297.088,59.019 296.925,58.453
+ 296.721,57.874 296.475,57.281 296.182,56.675 296.025,56.388 295.859,56.106 295.684,55.837 295.498,55.573 295.302,55.317
+ 295.098,55.067 294.658,54.59 294.184,54.135 293.671,53.701 293.124,53.286 292.545,52.886 291.29,52.122 289.915,51.386
+ 286.844,49.912 283.405,48.286 279.674,46.33 277.721,45.173 275.724,43.866 273.69,42.389 271.63,40.717 271.327,40.5
+ 271.033,40.27 270.747,40.027 270.47,39.772 270.2,39.505 269.939,39.227 269.441,38.637 268.975,38.005 268.54,37.334
+ 268.134,36.628 267.758,35.888 267.411,35.117 267.091,34.319 266.799,33.496 266.534,32.651 266.079,30.906 265.721,29.106
+ 265.455,27.275 265.274,25.435 265.173,23.606 265.146,21.814 265.187,20.081 265.291,18.428 265.45,16.878 265.66,15.454
+ 265.878,14.4 266.156,13.386 266.495,12.413 266.891,11.479 267.342,10.584 267.847,9.729 268.403,8.913 269.008,8.136
+ 269.661,7.396 270.358,6.694 271.099,6.029 271.88,5.402 272.7,4.812 273.557,4.258 274.449,3.74 275.373,3.258 276.327,2.812
+ 277.31,2.4 278.319,2.023 279.353,1.681 281.483,1.097 283.687,0.648 285.943,0.33 288.241,0.139 290.561,0.074 292.885,0.132
+ 295.197,0.31 297.48,0.605 299.722,1.015 301.9,1.537 304,2.168 306.007,2.905 307.9,3.747 308.802,4.205 309.668,4.689
+ 310.497,5.197 311.289,5.729 312.041,6.286 312.75,6.866 313.415,7.469 314.033,8.095 314.603,8.744 315.121,9.415 315.587,10.107
+ 315.799,10.462 315.998,10.821 316.182,11.187 316.352,11.557 316.507,11.933 316.646,12.313 316.771,12.699 316.88,13.09
+ 316.974,13.486 317.051,13.887 317.111,14.293 317.156,14.704 317.184,15.12 317.193,15.541 317.193,26.169 297.555,26.161
+ 297.725,21.701 297.718,20.709 297.661,19.778 297.609,19.336 297.539,18.91 297.449,18.502 297.338,18.112 297.271,17.924
+ 297.202,17.74 297.125,17.562 297.041,17.388 296.95,17.219 296.854,17.055 296.747,16.896 296.635,16.743 296.514,16.594
+ 296.386,16.451 296.248,16.313 296.104,16.181 295.949,16.055 295.786,15.934 295.613,15.818 295.432,15.709 295.24,15.605
+ 295.039,15.507 294.827,15.416 294.605,15.33 294.373,15.25 294.13,15.177 293.609,15.049 293.043,14.948 292.428,14.873
+ 291.764,14.825 291.047,14.804 290.788,14.825 290.52,14.863 290.241,14.917 289.956,14.988 289.666,15.076 289.373,15.182
+ 289.078,15.304 288.784,15.444 288.492,15.601 288.204,15.776 287.923,15.969 287.648,16.179 287.386,16.407 287.134,16.653
+ 286.895,16.917 286.672,17.2 286.566,17.349 286.466,17.501 286.37,17.659 286.279,17.821 286.193,17.987 286.114,18.159
+ 286.04,18.335 285.973,18.516 285.909,18.701 285.854,18.892 285.805,19.086 285.764,19.286 285.729,19.49 285.699,19.7
+ 285.68,19.914 285.667,20.132 285.663,20.356 285.667,20.584 285.68,20.818 285.701,21.056 285.771,21.546 285.88,22.058
+ 286.027,22.587 286.217,23.138 286.45,23.708 286.729,24.298 287.29,24.994 287.868,25.656 288.462,26.287 289.068,26.888
+ 290.324,28.005 291.625,29.019 292.966,29.941 294.339,30.786 295.736,31.563 297.154,32.285 302.868,34.864 305.653,36.136
+ 307.004,36.809 308.317,37.523 309.585,38.29 310.803,39.122 311.39,39.566 311.961,40.031 312.516,40.518 313.053,41.028
+ 313.573,41.564 314.073,42.127 314.554,42.717 315.014,43.337 315.452,43.989 315.868,44.674 316.26,45.392 316.628,46.146
+ 316.971,46.938 317.288,47.769 317.578,48.638 317.84,49.55 318.073,50.505 318.277,51.504 318.451,52.55 318.593,53.644
+ 318.78,55.979 318.832,58.524 318.74,61.29 318.5,64.287 318.349,65.431 318.128,66.534 317.84,67.601 317.486,68.628
+ 317.069,69.617 316.592,70.569 316.057,71.481 315.465,72.358 314.818,73.196 314.121,73.997 313.375,74.76 312.582,75.485
+ 311.744,76.174 310.863,76.825 309.943,77.44 308.985,78.019 307.992,78.56 306.966,79.063 305.909,79.532 304.823,79.964
+ 303.712,80.358 302.576,80.72 300.242,81.331 297.841,81.801 295.391,82.129 292.908,82.315 290.413,82.364 287.925,82.272
+ 285.46,82.045 283.039,81.681 280.678,81.181 278.396,80.546 276.213,79.778 275.164,79.345 274.146,78.878 273.162,78.378
+ 272.214,77.847 271.305,77.281 270.436,76.685 269.609,76.056 268.828,75.394 268.094,74.699 267.411,73.974 266.779,73.216
+ 266.202,72.427 265.681,71.604 265.443,71.185 265.22,70.753 265.012,70.315 264.819,69.869 264.643,69.416 264.483,68.954
+ 264.339,68.485 264.212,68.009 264.103,67.524 264.01,67.031 263.935,66.532 263.878,66.024 263.839,65.509 "/>
+ <polygon fill="#074CA1" points="26.53,0 23.182,0.216 20.113,0.617 18.679,0.884 17.312,1.192 16.008,1.542 14.769,1.93
+ 13.591,2.356 12.474,2.818 11.416,3.314 10.417,3.844 9.475,4.405 8.589,4.997 7.757,5.618 6.979,6.266 6.252,6.939 5.577,7.637
+ 4.951,8.358 4.373,9.101 3.842,9.863 3.357,10.644 2.917,11.442 2.52,12.255 2.165,13.083 1.851,13.923 1.577,14.775 1.34,15.636
+ 1.141,16.506 0.978,17.382 0.849,18.263 0.753,19.148 0.657,20.924 0.68,22.699 0.81,24.458 1.039,26.192 1.356,27.889
+ 1.751,29.537 2.215,31.123 2.737,32.637 3.307,34.066 3.915,35.398 4.552,36.624 5.207,37.729 5.871,38.702 6.202,39.136
+ 6.532,39.533 6.859,39.891 7.182,40.208 7.5,40.484 7.656,40.606 7.811,40.717 9.871,42.389 11.905,43.866 13.902,45.173
+ 15.855,46.33 19.586,48.286 23.025,49.912 26.097,51.386 27.471,52.122 28.726,52.886 29.306,53.286 29.852,53.701 30.363,54.135
+ 30.839,54.59 31.278,55.067 31.483,55.317 31.679,55.573 31.864,55.837 32.04,56.106 32.206,56.388 32.361,56.675 32.654,57.281
+ 32.902,57.874 33.106,58.453 33.269,59.019 33.391,59.567 33.476,60.103 33.523,60.621 33.537,61.124 33.517,61.61 33.466,62.081
+ 33.385,62.533 33.277,62.969 33.143,63.386 32.983,63.784 32.802,64.164 32.599,64.524 32.377,64.866 32.138,65.187 31.882,65.487
+ 31.613,65.769 31.332,66.024 31.039,66.263 30.738,66.478 30.43,66.67 30.116,66.839 29.798,66.985 29.479,67.106 29.158,67.206
+ 28.999,67.247 28.84,67.28 28.682,67.31 28.524,67.33 28.368,67.345 28.214,67.354 28.061,67.354 27.91,67.353 27.22,67.301
+ 26.579,67.219 25.986,67.106 25.438,66.967 25.181,66.886 24.935,66.798 24.699,66.703 24.474,66.603 24.258,66.494 24.053,66.38
+ 23.857,66.259 23.671,66.132 23.494,65.999 23.326,65.858 23.167,65.714 23.016,65.563 22.874,65.406 22.739,65.244 22.613,65.076
+ 22.495,64.903 22.383,64.726 22.28,64.541 22.183,64.353 22.093,64.158 22.01,63.96 21.933,63.757 21.797,63.337 21.684,62.897
+ 21.592,62.444 21.52,61.974 21.465,61.487 21.401,60.476 21.386,59.414 21.536,54.813 0,54.813 0,64.985 0.02,65.509 0.059,66.024
+ 0.116,66.532 0.191,67.031 0.283,67.524 0.393,68.009 0.52,68.485 0.664,68.954 0.824,69.416 1,69.869 1.192,70.315 1.4,70.753
+ 1.624,71.185 1.862,71.604 2.382,72.427 2.959,73.216 3.591,73.974 4.274,74.699 5.008,75.394 5.789,76.056 6.616,76.685
+ 7.484,77.281 8.395,77.847 9.342,78.378 10.327,78.878 11.344,79.345 12.394,79.778 14.577,80.546 16.858,81.181 19.219,81.681
+ 21.64,82.045 24.104,82.272 26.593,82.364 29.088,82.315 31.57,82.129 34.021,81.801 36.422,81.331 38.756,80.72 39.892,80.358
+ 41.003,79.964 42.089,79.532 43.146,79.063 44.172,78.56 45.166,78.019 46.124,77.44 47.043,76.825 47.924,76.174 48.762,75.485
+ 49.555,74.76 50.301,73.997 50.999,73.196 51.644,72.358 52.236,71.481 52.772,70.569 53.249,69.617 53.666,68.628 54.02,67.601
+ 54.308,66.534 54.529,65.431 54.679,64.287 54.92,61.29 55.012,58.524 54.96,55.979 54.773,53.644 54.631,52.55 54.458,51.504
+ 54.253,50.505 54.02,49.55 53.758,48.638 53.468,47.769 53.151,46.938 52.809,46.146 52.44,45.392 52.048,44.674 51.632,43.989
+ 51.194,43.337 50.734,42.717 50.254,42.127 49.753,41.564 49.234,41.028 48.696,40.518 48.141,40.031 47.57,39.566 46.983,39.122
+ 45.766,38.29 44.498,37.523 43.185,36.809 41.834,36.136 39.048,34.864 33.335,32.285 31.918,31.563 30.519,30.786 29.146,29.941
+ 27.806,29.019 26.504,28.005 25.25,26.888 24.643,26.287 24.049,25.656 23.471,24.994 22.909,24.298 22.63,23.708 22.397,23.138
+ 22.208,22.587 22.06,22.058 21.952,21.546 21.882,21.056 21.86,20.818 21.848,20.584 21.844,20.356 21.848,20.132 21.86,19.914
+ 21.88,19.7 21.907,19.49 21.942,19.286 21.985,19.086 22.034,18.892 22.089,18.701 22.151,18.516 22.22,18.335 22.294,18.159
+ 22.374,17.987 22.46,17.821 22.551,17.659 22.646,17.501 22.747,17.349 22.852,17.2 23.075,16.917 23.314,16.653 23.566,16.407
+ 23.83,16.179 24.104,15.969 24.385,15.776 24.673,15.601 24.964,15.444 25.259,15.304 25.554,15.182 25.847,15.076 26.137,14.988
+ 26.422,14.917 26.7,14.863 26.969,14.825 27.228,14.804 27.944,14.825 28.609,14.873 29.223,14.948 29.79,15.049 30.31,15.177
+ 30.554,15.25 30.786,15.33 31.008,15.416 31.22,15.507 31.421,15.605 31.612,15.709 31.794,15.818 31.967,15.934 32.13,16.055
+ 32.284,16.181 32.429,16.313 32.566,16.451 32.695,16.594 32.815,16.743 32.928,16.896 33.033,17.055 33.131,17.219 33.222,17.388
+ 33.306,17.562 33.383,17.74 33.454,17.924 33.518,18.112 33.63,18.502 33.72,18.91 33.79,19.336 33.842,19.778 33.898,20.709
+ 33.905,21.701 33.735,26.161 53.375,26.169 53.375,15.541 53.359,14.966 53.321,14.405 53.262,13.858 53.182,13.324 53.081,12.803
+ 52.959,12.295 52.818,11.801 52.657,11.319 52.477,10.85 52.279,10.393 52.062,9.948 51.828,9.515 51.577,9.095 51.309,8.686
+ 51.024,8.289 50.725,7.904 50.409,7.53 50.079,7.167 49.734,6.815 49.375,6.474 48.617,5.825 47.808,5.218 46.952,4.65
+ 46.052,4.124 45.113,3.634 44.137,3.183 43.128,2.767 42.091,2.385 39.943,1.721 37.723,1.181 35.457,0.755 33.176,0.434
+ 30.909,0.207 "/>
+ <polygon fill="#074CA1" points="543.49,85.187 545.95,85.244 548.239,85.198 550.365,85.053 552.334,84.813 554.151,84.485
+ 555.822,84.075 556.605,83.841 557.354,83.586 558.069,83.313 558.753,83.024 559.403,82.717 560.023,82.394 560.613,82.054
+ 561.173,81.7 561.704,81.331 562.206,80.948 562.682,80.553 563.131,80.146 563.554,79.724 563.951,79.292 564.325,78.851
+ 564.675,78.397 565.002,77.937 565.307,77.466 565.59,76.987 565.854,76.501 566.096,76.009 566.319,75.51 566.713,74.496
+ 567.039,73.465 567.304,72.422 567.513,71.372 567.673,70.319 567.789,69.272 567.868,68.231 567.938,66.199 567.93,64.261
+ 567.875,60.833 567.875,39.862 542.505,39.862 542.505,51.024 547.678,51.024 547.678,64.215 547.671,64.501 547.649,64.782
+ 547.614,65.06 547.565,65.332 547.503,65.601 547.429,65.862 547.342,66.121 547.242,66.373 547.131,66.618 547.009,66.856
+ 546.875,67.089 546.731,67.313 546.577,67.531 546.412,67.741 546.238,67.94 546.055,68.135 545.862,68.317 545.661,68.492
+ 545.451,68.656 545.234,68.812 545.01,68.955 544.777,69.089 544.538,69.211 544.293,69.322 544.041,69.421 543.784,69.509
+ 543.521,69.583 543.253,69.646 542.979,69.692 542.702,69.729 542.421,69.75 542.136,69.758 541.851,69.75 541.568,69.729
+ 541.291,69.692 541.019,69.646 540.75,69.583 540.487,69.509 540.229,69.421 539.979,69.322 539.732,69.211 539.494,69.089
+ 539.262,68.955 539.036,68.812 538.819,68.656 538.61,68.492 538.409,68.317 538.217,68.135 538.033,67.94 537.858,67.741
+ 537.694,67.531 537.54,67.313 537.396,67.089 537.262,66.856 537.14,66.618 537.028,66.373 536.93,66.121 536.843,65.862
+ 536.768,65.601 536.706,65.332 536.657,65.06 536.622,64.782 536.601,64.501 536.594,64.215 536.594,21.259 536.601,20.974
+ 536.622,20.692 536.657,20.415 536.706,20.142 536.768,19.874 536.843,19.61 536.93,19.353 537.029,19.101 537.14,18.855
+ 537.262,18.617 537.396,18.384 537.54,18.159 537.694,17.942 537.858,17.732 538.033,17.532 538.217,17.339 538.409,17.156
+ 538.61,16.981 538.819,16.817 539.036,16.662 539.262,16.518 539.494,16.385 539.732,16.262 539.979,16.151 540.229,16.052
+ 540.487,15.965 540.75,15.89 541.019,15.828 541.291,15.779 541.568,15.744 541.851,15.723 542.136,15.716 542.421,15.723
+ 542.702,15.744 542.979,15.779 543.253,15.828 543.521,15.89 543.784,15.965 544.041,16.052 544.293,16.151 544.538,16.262
+ 544.777,16.385 545.01,16.518 545.234,16.662 545.451,16.817 545.661,16.981 545.862,17.156 546.055,17.339 546.238,17.532
+ 546.412,17.732 546.577,17.942 546.731,18.159 546.875,18.384 547.009,18.617 547.131,18.855 547.242,19.101 547.342,19.353
+ 547.429,19.61 547.503,19.874 547.565,20.142 547.614,20.415 547.649,20.692 547.671,20.974 547.678,21.259 547.678,28.362
+ 567.875,28.362 567.875,19.567 567.837,18.458 567.79,17.917 567.725,17.385 567.643,16.862 567.542,16.347 567.424,15.841
+ 567.289,15.344 567.139,14.855 566.971,14.376 566.787,13.905 566.588,13.443 566.373,12.99 566.143,12.546 565.639,11.684
+ 565.077,10.856 564.461,10.064 563.793,9.307 563.074,8.585 562.309,7.898 561.497,7.246 560.644,6.629 559.749,6.048
+ 558.817,5.501 557.85,4.99 556.848,4.514 555.815,4.072 554.755,3.666 553.668,3.294 551.426,2.657 549.106,2.159 546.731,1.802
+ 544.317,1.584 541.885,1.506 539.451,1.568 537.038,1.77 534.662,2.111 532.344,2.592 530.102,3.212 529.016,3.575 527.955,3.973
+ 526.923,4.405 525.922,4.872 524.954,5.374 524.021,5.91 523.128,6.482 522.274,7.088 521.464,7.729 520.698,8.406 519.98,9.116
+ 519.313,9.862 518.696,10.643 518.136,11.458 517.632,12.307 517.402,12.745 517.188,13.192 516.988,13.647 516.805,14.111
+ 516.638,14.584 516.486,15.065 516.354,15.555 516.234,16.054 516.135,16.562 516.052,17.078 515.987,17.603 515.94,18.136
+ 515.903,19.229 515.903,67.599 515.909,68.326 515.94,69.035 515.995,69.726 516.075,70.396 516.178,71.049 516.303,71.683
+ 516.45,72.297 516.619,72.896 516.81,73.474 517.021,74.036 517.251,74.58 517.501,75.106 517.771,75.619 518.058,76.112
+ 518.363,76.591 518.686,77.053 519.023,77.498 519.379,77.929 519.749,78.344 520.135,78.743 520.535,79.129 520.949,79.499
+ 521.815,80.197 522.731,80.841 523.691,81.431 524.691,81.969 525.727,82.457 526.793,82.897 527.886,83.295 529.001,83.647
+ 530.134,83.959 532.435,84.466 534.753,84.83 537.053,85.067 539.3,85.196 541.457,85.229 "/>
+</g>
+</svg>
diff --git a/pc_fcgi b/pc_fcgi
@@ -101,7 +101,7 @@ while ($request->Accept() >= 0) {
results => $products
};
- $template->process("search.tt2", $vars) or print $template->error();
+ $template->process("tt/search.tt", $vars) or print $template->error();
}
syslog(LOG_INFO, "shutdown");
closelog();
diff --git a/pricechart.css b/pricechart.css
@@ -0,0 +1,54 @@
+.clear_both {
+ clear: both;
+}
+
+fieldset {
+ border: 0px;
+ float: right;
+}
+
+input {
+ font-size: 1em;
+}
+
+p {
+ line-height: 1.5em;
+}
+
+#footer {
+ text-align: center;
+}
+
+#title {
+ font-size: 2em;
+ color: black;
+ text-decoration: none;
+ float: left;
+ text-shadow: 2px 2px #DDD;
+}
+
+.column {
+ width: 40%;
+ padding-left: 5%;
+ padding-right: 5%;
+
+ float: left;
+}
+
+.product {
+ border: 1px solid black;
+ padding: 10px;
+ margin: 10px;
+}
+
+@media (max-width: 640px) {
+ .column {
+ width: 90%;
+ padding-left: 5%;
+ padding-right: 5%;
+ }
+}
+
+.logo {
+ height: 75px;
+}
diff --git a/tt/chart_list.tt b/tt/chart_list.tt
@@ -0,0 +1,11 @@
+[% WRAPPER wrapper.tt %]
+ <h1>[% name %]</h1>
+ [% FOREACH part_num IN products %]
+ <div class="product">
+ <b>[% part_num.1 %]</b> [% part_num.0 %]<br>
+ [% part_num.2 %] <br>
+ <object data="/svg/[% part_num.0 %].svg" type="image/svg+xml">
+ </object>
+ </div>
+ [% END %]
+[% END %]
diff --git a/tt/index.tt b/tt/index.tt
@@ -0,0 +1,46 @@
+[% WRAPPER wrapper.tt %]
+ <div class="column">
+ <h1>Welcome</h1>
+
+ <p> Welcome to <em>Price</em>Chart, a price comparison
+ service for consumer electronics.
+ Currently <b>[% num_products %]</b> products from
+ <b>[% num_manufacturers %]</b> manufacturers are tracked across
+ <b>[% num_vendors %]</b> retailers.</p>
+
+ <p> To start, try searching for a product or manufacturer in the
+ search box at the top right. </p>
+
+ <p> <em>Price</em><b>Chart</b> periodically looks up and saves
+ the prices of products. These prices are converted to charts
+ where determining which retailer is the best to purchase from is
+ easy.</p>
+ </div>
+
+ <div class="column">
+ <h1>Motivation</h1>
+
+ <p> <em>Price</em><b>Chart</b> is meant to be a consumer
+ purchasing tool. It is intended to give the consumer insight
+ into retail pricing which they would not normally have. </p>
+
+ <p> A common practice when purchasing something new is <em>price
+ comparison</em>. A consumer decides on a certain product
+ they are interested in and then look around for the best deal.
+ That is what this service does. It automates <em>price
+ comparisons</em>. </p>
+
+ <p> This is important because the price difference between
+ different retailers for the same product is often hundreds of
+ dollars if not more. </p>
+ </div>
+
+ <div class="column">
+ <h1>New Products ([% num_new %])</h1>
+ <ul>
+ [% FOREACH new_product IN new_products %]
+ <li>[% new_product.0 %]
+ [% END %]
+ </ul>
+ </div>
+[% END %]
diff --git a/tt/link_list.tt b/tt/link_list.tt
@@ -0,0 +1,13 @@
+[% WRAPPER wrapper.tt %]
+ <div class="column">
+ <h1>[% name %] List ([% num_manufacturers %])</h1>
+ <ul>
+ [% FOREACH manufacturer IN manufacturers %]
+ <li><a href="/[% name_lc %]/[% manufacturer.1 %].html">
+ <img class="logo" src="/logo/[% manufacturer.1 %].svg">
+ [% manufacturer.0 %]</img>
+ </a>
+ [% END %]
+ </ul>
+ </div>
+[% END %]
diff --git a/tt/search.tt b/tt/search.tt
@@ -0,0 +1,18 @@
+[% WRAPPER wrapper.tt %]
+ <p>Found <b>[% num_results %]</b> search
+ [% IF num_results == 1 %]
+ result
+ [% ELSE %]
+ results
+ [% END %]
+ for <b>[% query %]</b>:</p>
+
+ [% FOREACH part_num IN results %]
+ <div class="product">
+ <b>[% part_num.1 %]</b> [% part_num.0 %]<br>
+ [% part_num.2 %] <br>
+ <object data="/svg/[% part_num.0 %].svg" type="image/svg+xml">
+ </object>
+ </div>
+ [% END %]
+[% END %]
diff --git a/tt/wrapper.tt b/tt/wrapper.tt
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width" />
+ <title>PriceChart</title>
+ <link rel="stylesheet" type="text/css" href="/pricechart.css" />
+</head>
+<body>
+ <a id="title" href="/"><em>Price</em><b>Chart</b></a>
+ <a href="/manufacturers.html">Manufacturers</a>
+ <a href="/vendors.html">Retailers</a>
+ <form method="get" action="/search.html">
+ <fieldset>
+ <input type="text" name="q" />
+ <input type="submit" value="Search">
+ </fieldset>
+ </form>
+ <hr class="clear_both">
+
+ [% content %]
+
+ <hr class="clear_both">
+ <!--div id="footer">
+ <a href="mailto:not_real@getaddrinfo.net">Feedback/Donate</a>
+ </div-->
+</body>
+</html>