pricecharts

track prices of consumer electronics
Log | Files | Refs | README

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:
MMakefile | 5+++--
Mgen_index | 106++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Dhtml/index.tt2 | 46----------------------------------------------
Dhtml/pricechart.css | 50--------------------------------------------------
Dhtml/search.tt2 | 18------------------
Dhtml/wrapper.tt2 | 26--------------------------
Alogo/best buy.svg | 42++++++++++++++++++++++++++++++++++++++++++
Alogo/samsung.svg | 152+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpc_fcgi | 2+-
Apricechart.css | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Att/chart_list.tt | 11+++++++++++
Att/index.tt | 46++++++++++++++++++++++++++++++++++++++++++++++
Att/link_list.tt | 13+++++++++++++
Att/search.tt | 18++++++++++++++++++
Att/wrapper.tt | 28++++++++++++++++++++++++++++
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>