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

Commit

Permalink
Merge pull request #66 from Jason-Abbott/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
Jason-Abbott authored Apr 10, 2017
2 parents 9e43aa4 + 306145c commit 10ca63b
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 204 deletions.
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"version": "2.0.0",
"isShellCommand": true,
"showOutput": "always",
"suppressTaskName": true,
Expand Down
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
## 2.1.4
## 2.2.1
- Update Google tokens and fix authorization views

## 2.2.0
- Use in-memory caching rather than Redis for views
- Update dependencies

## 2.1.3
- Adjust layout for iPad
- Remove "Photography" from title
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2016 Jason Abbott
Copyright (c) 2017 Jason Abbott

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
2 changes: 1 addition & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,5 @@ function applyMiddleware(app) {
function filter(regex, fn) {
return (req, res, next) => {
if (regex.test(req.originalUrl)) { fn(req, res, next); } else { next(); }
}
};
}
77 changes: 38 additions & 39 deletions lib/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,22 @@ const compress = require('zlib');
const prefix = 'api:';
const viewKey = 'view';
const mapKey = 'map';

/**
* Whether key with prefix exists
* @param {String} key
* @param {String} hashKey
* @param {Boolean} enabled Whether caching is enabled
* @returns {Promise.<Boolean>}
* @param {string} key
* @param {string} hashKey
* @param {boolean} enabled Whether caching is enabled
* @returns {Promise.<boolean>}
*/
const exists = (key, hashKey, enabled) => enabled
? redis.exists(key, hashKey)
: Promise.resolve(false);

//region Cache item

/**
* Create view cache item with eTag and compressed content
* @param {String} key Page slug
* @param {String|GeoJSON.FeatureCollection} htmlOrJSON
* @param {string} key Page slug
* @param {string|GeoJSON.FeatureCollection} htmlOrJSON
* @returns {Promise.<ViewCacheItem>}
*/
const createItem = (key, htmlOrJSON) => new Promise((resolve, reject) => {
Expand All @@ -39,10 +38,10 @@ const createItem = (key, htmlOrJSON) => new Promise((resolve, reject) => {
});

/**
* @param {String} key Root Redis key
* @param {String} hashKey Hash field key
* @param {String|GeoJSON.FeatureCollection} value HTML or JSON
* @param {Boolean} enabled Whether caching for this root key is enabled
* @param {string} key Root Redis key
* @param {string} hashKey Hash field key
* @param {string|GeoJSON.FeatureCollection} value HTML or JSON
* @param {boolean} enabled Whether caching for this root key is enabled
* @returns {Promise.<ViewCacheItem>}
*/
const addItem = (key, hashKey, value, enabled) => createItem(hashKey, value)
Expand All @@ -51,6 +50,7 @@ const addItem = (key, hashKey, value, enabled) => createItem(hashKey, value)
/**
* Convert view cache to string
* @param {ViewCacheItem} item
* @returns {object}
*/
const serializeItem = item => JSON.stringify({
buffer: item.buffer.toString(C.encoding.HEXADECIMAL),
Expand All @@ -59,44 +59,43 @@ const serializeItem = item => JSON.stringify({

/**
* @param {ViewCacheItem} item
* @returns {object}
*/
const deserialize = item => is.value(item)
? { buffer: Buffer.from(item.buffer, C.encoding.HEXADECIMAL), eTag: item.eTag }
: null;

//endregion

/**
* Manage cache interaction
*/
module.exports = {
prefix,
/**
* Retrieve cached value
* @param {String} key
* @param {String} [hashKey]
* @param {string} key
* @param {string} [hashKey]
* @returns {Promise}
*/
getItem: (key, hashKey) => redis.getObject(prefix + key, hashKey),

/**
* @param {String} key
* @param {String|Object} hashKeyOrValue
* @param {Object} [value] Value to cache if hash key is given
* @param {string} key
* @param {string|object} hashKeyOrValue
* @param {object} [value] Value to cache if hash key is given
* @returns {Promise}
*/
add: (key, hashKeyOrValue, value) => redis.add(prefix + key, hashKeyOrValue, value),

/**
* All keys with standard prefix
* @returns {Promise.<String[]>}
* @returns {Promise.<string[]>}
*/
keys: ()=> redis.keys(prefix + '*'),

/**
* Remove cached items
* @param {String|String[]} key
* @param {String|String[]} [hashKey]
* @param {string|string[]} key
* @param {string|string[]} [hashKey]
* @returns {Promise}
*/
remove: (key, hashKey) => redis.remove(
Expand All @@ -109,20 +108,20 @@ module.exports = {
*/
view: {
/**
* @param {String} key Page slug
* @param {string} key Page slug
* @returns {Promise.<ViewCacheItem>}
*/
getItem: key => redis.getObject(viewKey, key).then(deserialize),

/**
* @returns {Promise.<String[]>}
* @returns {Promise.<string[]>}
*/
keys: ()=> redis.keys(viewKey),

/**
* Add or replace value at key
* @param {String} key Page slug
* @param {String} text HTML or JSON
* @param {string} key Page slug
* @param {string} text HTML or JSON
* @returns {Promise.<ViewCacheItem>}
*/
add: (key, text) => addItem(viewKey, key, text, config.cache.views),
Expand All @@ -131,15 +130,15 @@ module.exports = {

/**
* Whether cache view exists
* @param {String} key
* @returns {Promise.<Boolean>}
* @param {string} key
* @returns {Promise.<boolean>}
*/
exists: key => exists(viewKey, key, config.cache.views),

/**
* Add value only if it doesn't already exist (mainly for testing)
* @param {String} key Page slug
* @param {Buffer|String} buffer Zipped view content
* @param {string} key Page slug
* @param {Buffer|string} buffer Zipped view content
* @returns {Promise}
*/
addIfMissing(key, buffer) {
Expand All @@ -150,7 +149,7 @@ module.exports = {

/**
* Remove cached page views
* @param {String|String[]} keys
* @param {string|string[]} keys
* @returns {Promise}
*/
remove: keys => redis.remove(viewKey, keys),
Expand All @@ -162,42 +161,42 @@ module.exports = {
*/
map: {
/**
* @param {String} key Page slug
* @param {string} key Page slug
* @returns {Promise.<ViewCacheItem>}
*/
getItem: key => redis.getObject(mapKey, key).then(deserialize),

/**
* @returns {Promise.<String[]>}
* @returns {Promise.<string[]>}
*/
keys: ()=> redis.keys(mapKey),

/**
* Add or replace value at key
* @param {String} key Page slug
* @param {string} key Page slug
* @param {GeoJSON.FeatureCollection} geoJSON Zipped view content
* @returns {Promise.<ViewCacheItem>}
*/
add: (key, geoJSON) => addItem(mapKey, key, geoJSON, config.cache.maps),

/**
* Whether cache map exists
* @param {String} key
* @returns {Promise.<Boolean>}
* @param {string} key
* @returns {Promise.<boolean>}
*/
exists: key => exists(mapKey, key, config.cache.maps),

/**
* Remove cached GeoJSON
* @param {String|String[]} key
* @param {string|string[]} key
* @returns {Promise}
*/
remove: key => redis.remove(mapKey, key),

/**
* Add value only if it doesn't already exist (mainly for testing)
* @param {String} key Page slug
* @param {Buffer|String} buffer Zipped view content
* @param {string} key Page slug
* @param {Buffer|string} buffer Zipped view content
* @returns {Promise}
*/
addIfMissing(key, buffer) {
Expand Down
6 changes: 3 additions & 3 deletions lib/extensions.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* Remove pattern from string
* @param {RegExp} re
* @returns {String}
* @extends {String}
* @this {String}
* @returns {string}
* @extends {string}
* @this {string}
*/
String.prototype.remove = function(re) { return this.replace(re, ''); };

Expand Down
52 changes: 26 additions & 26 deletions lib/flickr.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ require('https').globalAgent.maxSockets = 200;

/**
* Load response from cache or call API
* @param {String} method Name of Flickr API method to call
* @param {String} idType Type of Flickr ID whether photo, set, collection, etc.
* @param {String} id FlickrAPI object ID
* @param {FlickrOptions|Object} [options]
* @param {string} method Name of Flickr API method to call
* @param {string} idType Type of Flickr ID whether photo, set, collection, etc.
* @param {string} id FlickrAPI object ID
* @param {FlickrOptions|object} [options]
* @returns {Promise.<Flickr.Response>}
*/
function call(method, idType, id, options = {}) {
Expand All @@ -87,10 +87,10 @@ function call(method, idType, id, options = {}) {

/**
* Invoke API when method result isn't cached
* @param {String} method
* @param {String} idType
* @param {String} id
* @param {FlickrOptions|Object} options
* @param {string} method
* @param {string} idType
* @param {string} id
* @param {FlickrOptions|object} options
* @returns {Promise.<Flickr.Response>}
* @see http://www.flickr.com/services/api/response.json.html
*/
Expand Down Expand Up @@ -139,8 +139,8 @@ function callAPI(method, idType, id, options) {

/**
* Parse Flickr response and handle different kinds of error conditions
* @param {String} body
* @param {String} key
* @param {string} body
* @param {string} key
* @returns {Flickr.Response}
*/
function parse(body, key) {
Expand Down Expand Up @@ -176,8 +176,8 @@ function parse(body, key) {
/**
* Retry service call if bad response and less than max retries
* @param {function} fn Call to retry
* @param {String} key
* @return {Boolean} whether call could be retried
* @param {string} key
* @return {boolean} whether call could be retried
*/
function retry(fn, key) {
let count = 1;
Expand All @@ -197,7 +197,7 @@ function retry(fn, key) {

/**
* Clear retry count and log success
* @param {String} key
* @param {string} key
*/
function clearRetries(key) {
if (is.defined(retries, key) && retries[key] > 0) {
Expand All @@ -208,11 +208,11 @@ function clearRetries(key) {

/**
* Setup standard parameters
* @param {String} method Name of flickr API method to call
* @param {String} [idType] The type of ID whether photo, set or other
* @param {String} [id] ID of the flickr object
* @param {Object} [args] Additional parameters
* @returns {String}
* @param {string} method Name of flickr API method to call
* @param {string} [idType] The type of ID whether photo, set or other
* @param {string} [id] ID of the flickr object
* @param {object} [args] Additional parameters
* @returns {string}
*/
function parameterize(method, idType, id, args = {}) {
let qs = '';
Expand Down Expand Up @@ -265,8 +265,8 @@ module.exports = {
},

/**
* @param {String} requestToken
* @param {String} verifier
* @param {string} requestToken
* @param {string} verifier
* @returns {Promise}
*/
getAccessToken(requestToken, verifier) {
Expand Down Expand Up @@ -296,31 +296,31 @@ module.exports = {
}),

/**
* @param {String} id
* @param {string} id
* @returns {Promise.<Flickr.SetInfo>}
*/
getSetInfo: id => call(method.set.INFO, type.SET, id, { value: r => r.photoset, allowCache: true }),

/**
* @param {String} id
* @param {string} id
* @returns {Promise.<Flickr.Size[]>}
*/
getPhotoSizes: id => call(method.photo.SIZES, type.PHOTO, id, { value: r => r.sizes.size }),

/**
* @param {String} id
* @param {string} id
* @returns {Promise.<Flickr.SetInfo[]>}
*/
getPhotoContext: id => call(method.photo.SETS, type.PHOTO, id, { value: r => r.set }),

/**
* @param {String} id
* @param {string} id
* @returns {Promise.<Flickr.EXIF>}
*/
getExif: id => call(method.photo.EXIF, type.PHOTO, id, { value: r => r.photo.exif, allowCache: true }),

/**
* @param {String} id
* @param {string} id
* @returns {Promise.<Flickr.PhotoSummary[]>}
*/
getSetPhotos: id => call(method.set.PHOTOS, type.SET, id, {
Expand All @@ -336,7 +336,7 @@ module.exports = {
/**
* The documentation says signing is not required but results differ even with entirely
* public photos -- perhaps a Flickr bug
* @param {String[]|String} tags
* @param {string[]|String} tags
* @returns {Promise.<Flickr.PhotoSummary[]>}
* @see https://www.flickr.com/services/api/flickr.photos.search.html
*/
Expand Down
Loading

0 comments on commit 10ca63b

Please sign in to comment.