Skip to content
This repository has been archived by the owner on May 6, 2020. It is now read-only.

Commit

Permalink
Merge branch 'ithinkihaveacat-integrate-amp-story'
Browse files Browse the repository at this point in the history
  • Loading branch information
pietergreyling committed Sep 18, 2018
2 parents 19bb9bc + 2de9dbe commit 57dbe0d
Show file tree
Hide file tree
Showing 66 changed files with 12,796 additions and 1,349 deletions.
17 changes: 17 additions & 0 deletions amp-story/gae/.gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# This file specifies files that are *not* uploaded to Google Cloud Platform
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
# $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore

# Node.js dependencies:
node_modules/
3 changes: 3 additions & 0 deletions amp-story/gae/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
amp-story-linter
*.js
26 changes: 26 additions & 0 deletions amp-story/gae/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Install dependencies:

```sh
$ npm run install-local-dependencies
$ npm install
```

Run locally:

```sh
$ tsc
$ npm run start
```

Run locally with restart on `*.hbs` or `*.js` change:

```sh
$ npm run watch
```

Deployment:

```sh
$ gcloud config set core/project PROJECT # set default project (if necessary)
$ npm run deploy
```
6 changes: 6 additions & 0 deletions amp-story/gae/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Make results persistent
- Generate URL with "url" query string parameter
- Share via share component
- Do some rendering on server side
- Loader would be nice
- Support V1 format
45 changes: 45 additions & 0 deletions amp-story/gae/amp-cors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Copyright 2018 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { NextFunction, Request, Response } from "express";

export default (serverOrigin: string) => {
return (req: Request, res: Response, next: NextFunction) => {
if (!req.accepts("json")) {
return next();
}
const sourceOrigin = req.query.__amp_source_origin;
if (!sourceOrigin) {
return next();
}
let origin;
if (req.headers.origin) {
origin = req.headers.origin;
} else if (req.headers["amp-same-origin"] === "true") {
origin = serverOrigin;
} else {
return next();
}

res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Origin", origin);
res.setHeader("Access-Control-Expose-Headers", [
"AMP-Access-Control-Allow-Source-Origin",
]);
res.setHeader("AMP-Access-Control-Allow-Source-Origin", sourceOrigin);
next();
};
};
137 changes: 137 additions & 0 deletions amp-story/gae/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* Copyright 2018 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as fs from "fs";
import {URL} from "url";

import * as cheerio from "cheerio";
import * as debug from "debug";
import express = require("express");
import {compile, registerHelper} from "handlebars";
import {default as fetch, Request, RequestInit, Response} from "node-fetch";

import ampCors from "./amp-cors.js";
import * as validate from "./amp-story-linter";

const log = debug("linter");

const UA_GOOGLEBOT_MOBILE = [
"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36",
"(KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36",
"(compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
].join(" ");

const ORIGIN = process.env.ORIGIN || `https://${process.env.PROJECT_ID}.appspot.com`;

const PORT = (() => {
if (process.env.NODE_ENV === "production") {
return 8080;
} else {
return (new URL(ORIGIN)).port || 80;
}
})();

const INDEX = (() => {
registerHelper("escape", (name) => {
return `{{${name}}}`;
});
const template = compile(fs.readFileSync("index.hbs").toString());
return template({
canonical: ORIGIN,
});
})();

const app = express();

app.use((req, res, next) => {
if (process.env.NODE_ENV === "production") {
res.setHeader("strict-transport-security", "max-age=31556926");
}
next();
});

app.use(ampCors(ORIGIN));

app.get("/", (req, res) => {
res.status(200);
res.setHeader("content-type", "text/html");
// res.send(JSON.stringify(req.query));
res.send(INDEX);
res.end();
});

app.get("/lint", async (req, res, next) => {
const url = req.query.url;
if (!url) {
res.status(400);
res.setHeader("content-type", "application/json");
res.send(JSON.stringify({
message: "no [url] query string parameter provided",
status: "error",
}));
res.end();
return;
}

try {
log({url});
console.log({url});
const r = await fetch(url, {
headers: {
"user-agent": UA_GOOGLEBOT_MOBILE,
},
});
if (!r.ok) {
res.status(200);
res.setHeader("content-type", "application/json");
res.send(JSON.stringify({
message: `couldn't load [${url}]`,
status: "error",
}));
res.end();
r.text().then(console.error);
return;
}
const $ = cheerio.load(await r.text());
const context = { $, url, headers: {} };
const data = await validate.testAll(context) as {[key: string]: validate.Message};
res.status(200);
res.setHeader("content-type", "text/json");
const body = (() => {
if (req.query.type === "summary") {
return Object.keys(data).filter((k) => data[k].status !== "OKAY").join(",");
} else {
return JSON.stringify(data, undefined, 2);
}
})();
res.send(body);
res.end();
} catch (e) {
console.error(e);
res.status(e.code === "ENOTFOUND" ? 400 : 500); // probably caller's fault if ENOTFOUND
res.setHeader("content-type", "application/json");
res.send(JSON.stringify({
message: `couldn't load [${url}]`,
status: "error",
}));
res.end();
}
});

app.listen(PORT, () => {
console.log(`App listening at ${ORIGIN}`);
console.log("Press Ctrl+C to quit.");
});
16 changes: 16 additions & 0 deletions amp-story/gae/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright 2017, Google, Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

runtime: nodejs8
env_variables:
PROJECT_ID: amp-story-validator-dev
Loading

0 comments on commit 57dbe0d

Please sign in to comment.