From b3295897d2d0a615b4536121260196ac024789b7 Mon Sep 17 00:00:00 2001 From: Robbie Clutton Date: Sun, 19 Dec 2010 18:37:18 +0000 Subject: [PATCH] init --- .gitignore | 3 + .ndistro | 5 + README | 35 ++++ index.js | 1 + properties/build.json | 3 + public/images/favicon.ico | Bin 0 -> 895 bytes public/images/guardian_logo.gif | Bin 0 -> 841 bytes public/styles/screen.css | 316 ++++++++++++++++++++++++++++++++ src/app.js | 46 +++++ views/content.ejs | 2 + views/index.ejs | 25 +++ views/layout.ejs | 25 +++ views/manifest.ejs | 2 + views/partials/item.ejs | 4 + 14 files changed, 467 insertions(+) create mode 100644 .gitignore create mode 100644 .ndistro create mode 100644 README create mode 100644 index.js create mode 100644 properties/build.json create mode 100644 public/images/favicon.ico create mode 100644 public/images/guardian_logo.gif create mode 100644 public/styles/screen.css create mode 100644 src/app.js create mode 100644 views/content.ejs create mode 100644 views/index.ejs create mode 100644 views/layout.ejs create mode 100644 views/manifest.ejs create mode 100644 views/partials/item.ejs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f65786b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin +lib +modules \ No newline at end of file diff --git a/.ndistro b/.ndistro new file mode 100644 index 0000000..369ae5e --- /dev/null +++ b/.ndistro @@ -0,0 +1,5 @@ +node latest +module senchalabs connect +module visionmedia express +module visionmedia ejs +module theteam node-properties \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..c64ebd9 --- /dev/null +++ b/README @@ -0,0 +1,35 @@ +Guardian Content API for NodeJS +=============================== + +Setup +----- + +This example uses NodeJS and a number of dependencies to demonstrate a simple example of retrieving content from the Guardian Content API and present that in a web page. Dependencies are managed by [ndistro](https://github.com/visionmedia/ndistro) so should be easy to get started. Install ndistro as per instructions on that site and then run 'ndistro' on the command line. + +This will set up the following dependencies: + + - connect, a HTTP middleware library + - expressjs, a lightweight web framework + - ejs, a rendering engine for HTML + - node-properties, a small library to externalise configuration + +Once ndisto has run the following directories will have been created: bin, lib and modules. NodeJS is now setup locally and relative to the directory you are currently in. + +Running +------- + +To run the web app, run the following command + + ./bin/node index.js + +If you have not changed any defaults, the web app will load on port 3000. + +Usage +----- + +You will be required to enter a name for your query and the URI for the query. You can get the query URI by going to the [Content API Explorer](http://explorer.content.guardianapis.com). Sign up for an account (without one, you can't get HTML from the API required for this app) and use the 'content' tab to build your query. + +Notes +----- + +There is no persistence in this application, so when you start the app no queries will have been remembered. diff --git a/index.js b/index.js new file mode 100644 index 0000000..89a61f8 --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +require('./src/app'); \ No newline at end of file diff --git a/properties/build.json b/properties/build.json new file mode 100644 index 0000000..7f79472 --- /dev/null +++ b/properties/build.json @@ -0,0 +1,3 @@ +{ + "port":3000 +} \ No newline at end of file diff --git a/public/images/favicon.ico b/public/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e3f839bd179625127e7a0095cf8333dbd10ad9bb GIT binary patch literal 895 zcmZQzU<5(|0R|u`!H~hsz#zuJz@P!dKp_SNAO?xUfG{@$0|>)Fy${3g1?B%?0LVo~ zPj8=r$N(8|@d+tP-#)*Ch;N#bwy?$pf>w2e!o`8IaP>e&M}**&!>eGHV5gDQBRdJJ zYGn5SHQqhH8>=#iAkbAa3yiUv4|EmKE@TAs1<j)eAtE z0L@2M24Mq@g1i6B_L)HI-aWqycRVn_(X;^7z|}*XfovU+jiw$se27txY5w8W9dH{l zy@2d~U=Sg@AE*oH7fdIir53p15C*1tct8QAfC!lIfN=`62xv8s3-J`1uZiI@FdV#0 H3FZO-Ea&U- literal 0 HcmV?d00001 diff --git a/public/images/guardian_logo.gif b/public/images/guardian_logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..3a5092bc178492e9b34e1984bc8a10a2c7dabf06 GIT binary patch literal 841 zcmV-P1GfA}Nk%w1VT=G40J8u9|NsAnqPZDObGypdZ;+<|I%M7D>zJ^^sJzWYZ;j2_ z;qLPF#?;^U`TA9Sm@{F6A^8LV00000EC2ui0E_?@000F45XecZy*O)W#{OU^j$|1g zL?RSiQ4nSe4weAhh7hRjD~9 z5`-Ip& zm<$UR3pE2C4F(D}97#G046mRQ2QCf-D=UUSbh$%@c@8cDfdslj9>fI#ye!DQ1;4?8 zP6ZD?E}Ik$2uK4AIA7XGH%Qn)NnhJZt5|S20SKW`KcUD73I;3BaKO%$`BTX96&N5y zKqxK%nn^I^Pl}))4g&Bi5WoV#03Hy%18|W6fCldW;?;2nE?q?^tRxUDhfs)vg)Zm- zK$s$4E}2d+4p@-yWXnSd6WENY@<+xWCnqdO5>MMsrYgBrNLPu0I+X18l=A~rh|HTo zfK~uIQ*0C$8GjBLOO&Hg2}mpKL1JNUQmX+DOcf^q@5wQ!Fw)4UgP&diWD#mqp)2g# z0dLC=QM`w7TgYhPx=7mhDh0n2KvSUFnJ(76Ng7x{a4Xjo#BCAgaxkEpKFLqqX2$LK z$?V#fBgg%mx`Jo`#|804es#>njTH_ENOvF$%-dXMxd@fm?2p50S!gf7J^1e7Hby1! zNMTH9zUcvwW^Nj=U+aimAShJ|TP^`QDC9);dDw{sKt4Eib;y9Q-G*P=&5~}rPO)}D)C{P+dJYY*O1}rd9C0xZ6fNd|xXw-u)<^v#Z z6+P&{0w$@K#5q`1hnHSO`gJ5X4fy5J81Qf)(1~CDz+y}aG?Rb=2u>qm5Iz=^$B7B) z0;Y{8J{Z##m3VRFP8_%cC03P~Gys)O2H=rNCoOfQHC@oTz*ccsrwIs)9=buI6D%6S zC>4xiK#3GsS}A^`sMdf;A>i`@1quWc#;K?lA;fENIF#zEuo`iTP6t%;0DiINs%xbI TSf)$>pzbQ{u*4QiYy<#1;u2J3 literal 0 HcmV?d00001 diff --git a/public/styles/screen.css b/public/styles/screen.css new file mode 100644 index 0000000..c883fe0 --- /dev/null +++ b/public/styles/screen.css @@ -0,0 +1,316 @@ +html * { + border: medium none; + margin: 0; + padding: 0; +} +.identity h1 { + padding-bottom: 20px; +} +#wrapper { + font-family: arial,sans-serif; + margin: 20px auto; + width: 940px; +} +.identity .component { + background-color: #FFFFFF; + clear: both; + font-size: 13px; + margin-bottom: 20px; +} +.identity .component .hd { + background-color: #EDEDED; + border-top: 3px solid #0061A6; + margin-bottom: 5px; + min-height: 26px; + padding: 3px 0 14px; + position: relative; +} +.identity .component h3, .identity .component h2 { + color: #333333; + font-family: georgia,serif; + font-size: 18px; + font-weight: normal !important; + line-height: 21px; + margin: 0; + padding-left: 3px; + padding-right: 3px; +} +.identity .component h3 { + font-size: 15px; +} +.identity .component .ft { + border-top: 1px dotted #999999; + clear: both; + margin-top: 5px; + padding-top: 2px; +} +.identity .component .bd h2 { + padding-bottom: 14px; + padding-left: 0; +} +.identity .five-col { + margin: 0 auto; + width: 460px; +} +.eight-col { + margin: 0 auto; + width: 620px; +} +.identity .edge { + margin: 0; +} +.identity fieldset { + border: medium none; +} +.identity .hidden, .js .identity div.tooltip, .js .identity .edit, .identity div.tooltipHide { + display: none !important; +} +.identity span.label, .identity label { + display: block; + float: left; + width: 120px; +} +.identity label { + padding-top: 5px; +} +.identity div.field, .identity p { + clear: left; + font-size: 12px; + margin-bottom: 10px; + position: relative; +} +.identity div.actions { + padding-top: 20px; +} +.identity h4 { + margin-bottom: 10px; +} +.identity ul { + margin-left: 20px; +} +.identity ul.errors li, .identity ul.errors { + color: #FF0000; + list-style-type: none; + margin: 0 10px 0 0; + padding: 0; +} +.identity span.errors { + color: #FF0000; + list-style-type: none; + margin: 0 10px 0 0; + padding: 0; +} +.identity div.field:after, .identity p:after { + clear: both; + content: ""; + display: block; + height: 0; + visibility: hidden; +} +.identity span.radio { + float: left; + margin-right: 10px; +} +.identity span.radio label { + padding: 0 4px 0 0; + width: auto; +} +.identity div.tooltip { + background-image: url("images/triangle_bg.png"); + background-position: 0 50%; + background-repeat: no-repeat; + left: 370px; + padding: 6px 15px; + position: absolute; + top: -2px; + width: 210px; +} +.identity div.username { + padding: 20px 0 10px; +} +.identity div.username .tooltip { + top: 12px; +} +.identity div.weak, .identity div.error { + background-color: #F7D2CC; +} +.identity div.globalError, div.globalMessage { + background-color: #F7D2CC; + margin-bottom: 15px; + padding: 6px 15px; +} +.identity div.globalMessage { + background-color: #DFEBF4; +} +.identity div.medium, .identity div.helper { + background-color: #DFEBF4; +} +.identity div.strong, .identity div.password { + background-color: #CCE7CC; +} +.identity label.vague { + top: -25px; +} +.identity input.error { + border: 1px solid #F7D2CC !important; +} +.identity input.valid { + background-image: url("images/tick.gif"); + background-position: 225px 4px; + background-repeat: no-repeat; +} +.identity input[type="email"], .identity input[type="password"], .identity input[type="text"] { + border: 1px solid #999999; + min-height: 14px; + padding: 4px 22px 4px 4px; + width: 215px; +} +.identity input[type="email"]:focus, .identity input[type="password"]:focus { + border-color: #333333; +} +.identity #forgotten-password-link, .identity .check { + display: block; + margin-left: 120px; +} +.identity .check label, .identity .check input { + float: left; +} +.identity .check label { + margin-left: 5px; + padding: 0; + width: 45%; +} +.identity .check.accept .error { + left: 245px; +} +.identity .bd { + padding-top: 10px; +} +.identity a { + color: #005689; + padding: 1px; + text-decoration: none; +} +.identity a:hover { + text-decoration: underline; +} +.identity a:focus { + background-color: #005689; + color: white; +} +.identity input[type="submit"] { + float: right; +} +.identity progress { + background-color: white; + display: block; + height: 5px; + position: absolute; + right: 7px; + top: 15px; + width: 300px; +} +.identity progress[value="33"] { + border-left: 100px solid orange; + width: 200px; +} +.identity progress[value="66"] { + border-left: 200px solid orange; + width: 100px; +} +.identity progress[value="100"] { + border-left: 300px solid orange; + width: 0; +} +.identity .button { + background: url("images/button_bg.png") repeat-x scroll left bottom #0061A6; + border: 1px solid white; + color: white; + display: block; + float: right; + font-family: georgia,serif; + font-size: 16px; + height: 29px; + outline: medium none; + padding: 2px 7px 4px; +} +.identity a.button { + height: 22px; + line-height: 1.4; + padding-top: 1px; +} +.identity .button:hover { + background-color: #666666; + cursor: pointer; + text-decoration: none; +} +.identity .button:focus { + outline: 1px dotted; +} +.identity .dashboard { + margin: 0 auto; + width: 800px; +} +.identity .dashboard .five-col { + float: left; + margin: 0 20px 0 0; +} +.identity .dashboard .one-col { + float: left; + margin-right: 20px; + width: 140px; +} +.identity .dashboard .bd ul { + margin: 0; +} +.identity .dashboard .bd li { + list-style-type: none; + margin: 0; +} +.identity .dashboard .bd li.b3 { + border-top: 1px dotted #999999; + padding-bottom: 7px; + padding-top: 3px; +} +.identity .dashboard .promo .bd li { + margin-bottom: 20px; +} +.identity .dashboard .promo .bd h4 { + font-size: 12px; +} +.identity .dashboard .promo .bd a { + display: block; +} +.identity div.gnm-email { + padding-top: 30px; +} +.identity .dashboard-radio label { + display: inline; + float: none; + padding: 0; + width: auto; +} +.identity .dashboard-radio span { + display: block; + float: left; + width: 350px; +} +.identity .dashboard-radio input[type="radio"] { + position: relative; + top: 2px; +} +.identity .dashboard-radio label[for="receive-email-others-yes"], .identity .dashboard-radio label[for="receive-email-gnm-yes"] { + margin-right: 8px; +} +.identity .bd .promo-details { + border-bottom: 1px dotted #999999; + margin-bottom: 15px; +} +.identity .bd .promo-details p { + font-size: 1.1em; + line-height: 1.2; +} +.identity .bd .promo-details img { + float: left; + margin: 0 20px 10px 0; +} \ No newline at end of file diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..93d6643 --- /dev/null +++ b/src/app.js @@ -0,0 +1,46 @@ +var sys = require('sys'); +var fs = require('fs'); +var express = require('express'); +var ejs = require('ejs'); +var http = require('http'); +var props = require('properties'); + +var app = express.createServer(); +app.use(express.staticProvider(__dirname + '/../public')); +app.use(express.bodyDecoder()); + +var requests = []; + +app.get('/', function(req, res){ + res.render('index.ejs'); +}); + +app.post('/content', function(req, res){ + var request = {}; + request.name = req.body.name; + request.uri = req.body.uri; + requests[request.name] = request; + res.redirect('/content/' + request.name); +}); + +app.get('/content/:id', function(req, res){ + var q = requests[req.params.id]; + var connection = http.createClient(80, 'content.guardianapis.com'); + var request = connection.request('GET', q.uri, {'host':'content.guardianapis.com'}); + request.end(); + request.on('response', function(response){ + var apiData = ""; + response.setEncoding('utf8'); + response.on('data', function(chunk){ + apiData += chunk; + }); + response.on('end', function(){ + res.render('content.ejs', { + locals:{res:JSON.parse(apiData), + name:q.name} + }); + }); + }); +}); + +app.listen(props.port); \ No newline at end of file diff --git a/views/content.ejs b/views/content.ejs new file mode 100644 index 0000000..11272b0 --- /dev/null +++ b/views/content.ejs @@ -0,0 +1,2 @@ +

<%= name %> by guardian.co.uk

+<%- partial('item.ejs', res.response.results) %> \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs new file mode 100644 index 0000000..2cf69e6 --- /dev/null +++ b/views/index.ejs @@ -0,0 +1,25 @@ + +
+

Enter your query from the Content API

+
+ +
+ +
+
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + diff --git a/views/layout.ejs b/views/layout.ejs new file mode 100644 index 0000000..2d4fb75 --- /dev/null +++ b/views/layout.ejs @@ -0,0 +1,25 @@ + + + + + + + + Create an app from the guardian.co.uk + + + +
+
+

+ guardian.co.uk +

+ +
+ <%- body %> +
+ +
+
+ + diff --git a/views/manifest.ejs b/views/manifest.ejs new file mode 100644 index 0000000..d049b8c --- /dev/null +++ b/views/manifest.ejs @@ -0,0 +1,2 @@ +/styles/screen.css +/images/guardian_logo.gif \ No newline at end of file diff --git a/views/partials/item.ejs b/views/partials/item.ejs new file mode 100644 index 0000000..3da2630 --- /dev/null +++ b/views/partials/item.ejs @@ -0,0 +1,4 @@ +<% if (item.fields !== undefined && item.fields.body !== '') {%> +

<%= item.webTitle %>

+ <%- item.fields.body %> +<% } %> \ No newline at end of file