diff --git a/src/app/listen/listen.js b/src/app/listen/listen.js index c711c9af..035fd792 100644 --- a/src/app/listen/listen.js +++ b/src/app/listen/listen.js @@ -121,6 +121,12 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead']) $scope.startOffsetAbsolute = absoluteStartChunk.format("HH:mm:ss"); $scope.endOffsetAbsolute = absoluteEndChunk.format("HH:mm:ss"); + $scope.downloadAnnotationsLink = AudioEvent.csvLink( + { + audioRecordingId: value.id, + startOffset: value.startOffset, + endOffset: value.endOffset + }); }, function mediaGetFailure() { diff --git a/src/app/listen/listen.tpl.html b/src/app/listen/listen.tpl.html index 31eae023..f588722a 100644 --- a/src/app/listen/listen.tpl.html +++ b/src/app/listen/listen.tpl.html @@ -202,6 +202,11 @@

ng-href="{{model.media.availableAudioFormats['mp3'].url}}" title="{{ model.media.availableAudioFormats['mp3'].url && 'Download the .mp3 file' || 'This file format is not available' }}" >Audio (MP3) |  + Annotations (CSV) diff --git a/src/baw.configuration.tpl.js b/src/baw.configuration.tpl.js index 8c71d776..8770cd6a 100644 --- a/src/baw.configuration.tpl.js +++ b/src/baw.configuration.tpl.js @@ -33,7 +33,7 @@ angular.module('bawApp.configuration', ['url']) var f = fragments[i]; if ((typeof f) !== "string") { - throw "joingPathFragments: Path fragment " + f + " is not a string"; + throw "joinPathFragments: Path fragment " + f + " is not a string"; } var hasFirst = f[0] === "/"; @@ -71,7 +71,7 @@ angular.module('bawApp.configuration', ['url']) audioEvent: { list: "/audio_recordings/{recordingId}/audio_events", show: "/audio_recordings/{recordingId}/audio_events/{audioEventId}", - csv: "/audio_events/download.", + csv: "/audio_events/download.{format}", library: "/audio_events/library/paged" }, tagging: { diff --git a/src/common/100-String.format.js b/src/common/100-String.format.js index 0edb4791..34afd6f9 100644 --- a/src/common/100-String.format.js +++ b/src/common/100-String.format.js @@ -189,11 +189,18 @@ returns: 'some string with first value and second value injected using {property } //reference to the type of params - var t = typeof params; - - //if it (has format or not an object) and not an array) - if ((params.format || t != 'object') && t != 'array' ) { - params = [ params ]; //put the param inside an array + var t = Object.prototype.toString.call(params); + if (t === "[object String]") { + params = [params]; + } + else if (t === "[object Array]") { + // no op + } + else if (t === "[object Object]") { + // no op + } + else { + params = [params]; } } diff --git a/src/components/services/services.js b/src/components/services/services.js index c8c39825..be9bbd8c 100644 --- a/src/components/services/services.js +++ b/src/components/services/services.js @@ -42,43 +42,24 @@ {projectId: "@projectId", siteId: "@siteId", recordingId: '@recordingId'}); }]); - bawss.factory('AudioEvent', [ '$resource', 'conf.paths', - function ($resource, paths) { + bawss.factory('AudioEvent', [ '$resource', '$url', 'conf.paths', + function ($resource, $url, paths) { var baseCsvUri = paths.api.routes.audioEvent.csvAbsolute; - // TODO: move this to paths conf object - function makeCsvLink(options) { - var formattedUrl = baseCsvUri; - if (!angular.isObject(options)) { - // overwrite input then continue to format - options = {}; - } - - if (options.format) { - formattedUrl += options.format; - } - else { - formattedUrl += "csv"; - } - - if (options.projectId || options.siteId) { - formattedUrl += "?"; - } - - if (options.projectId) { - formattedUrl += "project_id=" + options.projectId.toString(); - } - - if (options.projectId && options.siteId) { - formattedUrl += "&"; - } - - if (options.siteId) { - formattedUrl += "site_id=" + options.siteId.toString(); - } + var csvOptions = { + format: "csv", // "csv", "xml", "json" + projectId: null, + siteId: null, + audioRecordingId: null, + startOffset: null, + endOffset: null + }; + // TODO: move this to paths conf object - return formattedUrl; + function makeCsvLink(options) { + var query = angular.extend(csvOptions, options); + return $url.formatUri(baseCsvUri, query); } var resource = resourcePut($resource, uriConvert(paths.api.routes.audioEvent.showAbsolute), diff --git a/src/components/services/services.spec.js b/src/components/services/services.spec.js new file mode 100644 index 00000000..7a16d3d2 --- /dev/null +++ b/src/components/services/services.spec.js @@ -0,0 +1,42 @@ +describe("The service suite", function () { + + var audioEventService; + var pathService; + + beforeEach(module('bawApp.services')); + + beforeEach(inject(["AudioEvent", "conf.paths", function (AudioEvent, paths) { + audioEventService = AudioEvent; + pathService = paths; + + + }])); + + it("should format the csv link correctly", function () { + var parameters = { + projectId: 12, + siteId: 13, + audioRecordingId: 42, + startOffset: 123456, + endOffset: 654321 + }; + + var expected = pathService.api.root + "/audio_events/download.csv?projectId=12&siteId=13&audioRecordingId=42&startOffset=123456&endOffset=654321"; + + var actual = audioEventService.csvLink(parameters); + + expect(actual).toBe(expected); + }); + + + it("should format the csv link correctly with an empty parameter set", function () { + var parameters; + var expected = pathService.api.root + "/audio_events/download.csv"; + + var actual = audioEventService.csvLink(parameters); + + expect(actual).toBe(expected); + + }); + +}); \ No newline at end of file diff --git a/src/components/services/url.js b/src/components/services/url.js index c4f72c95..20f7a6ac 100644 --- a/src/components/services/url.js +++ b/src/components/services/url.js @@ -49,7 +49,7 @@ angular.module('url', ['ng']). } this.encodeUriQuery = encodeUriQuery; - this.toKeyValue = function toKeyValue(obj, validateKeys) { + function toKeyValue(obj, validateKeys) { var parts = []; angular.forEach(obj, function (value, key) { if (validateKeys) { @@ -68,9 +68,10 @@ angular.module('url', ['ng']). parts.push(encodedKey + encodedValue); }); return parts.length ? parts.join('&') : ''; - }; + } + this.toKeyValue = toKeyValue; - this.formatUri = function(uri, values) { + this.formatUri = function(uri, values) { // first format string var result = uri.formatReturnUnused(values), @@ -87,23 +88,10 @@ angular.module('url', ['ng']). // formatted = formatted.slice(0, 1); //} - if (formatted.indexOf("?") === -1) { - formatted += "?"; - } - - var query = ""; - var first = true; - for (var key in unused) { + var query = toKeyValue(unused, true); - if (!unused.hasOwnProperty(key)) { - continue; - } - - query += (first ? "" : "&") + this.encodeUriQuery(key) + "=" + this.encodeUriQuery(unused[key]); - - if (first) { - first = false; - } + if (formatted.indexOf("?") === -1 && query.length > 0) { + formatted += "?"; } formatted += query; diff --git a/src/components/services/url.spec.js b/src/components/services/url.spec.js index 294f9419..4f7b402a 100644 --- a/src/components/services/url.spec.js +++ b/src/components/services/url.spec.js @@ -34,4 +34,54 @@ describe("The url service", function () { expect(result).toBe('blah=1&tornado=attack&hello&chocolate-chips=ring-ring&monkeys=dancing%20dancing'); }); + + describe("formatUri", function() { + + it("will format a templated uri", function() { + var uri = "{protocol}://www.google.com"; + var values = {protocol: "http"}; + + var expected = "http://www.google.com"; + var actual = $url.formatUri(uri, values); + + expect(actual).toBe(expected); + + }); + + + it("will format a templated uri, encoding unmatched placeholders", function() { + var uri = "{protocol}://www.google.com{path}"; + var values = {protocol: "http"}; + + var expected = "http://www.google.com%7Bpath%7D"; + var actual = $url.formatUri(uri, values); + + expect(actual).toBe(expected); + + }); + + it("will format a templated uri, inserting placeholders and then add a query string with remaining values", function() { + var uri = "{protocol}://www.google.com"; + var values = {protocol: "http", page: 1, query: "hello"}; + + var expected = "http://www.google.com?page=1&query=hello"; + var actual = $url.formatUri(uri, values); + + expect(actual).toBe(expected); + + }); + + it("will format a templated uri, removing empty values", function() { + var uri = "{protocol}://www.google.com"; + var values = {protocol: "http", page: 1, query: "hello", shouldNotBeHere: null, norI: "", orI: undefined}; + + var expected = "http://www.google.com?page=1&query=hello"; + var actual = $url.formatUri(uri, values); + + expect(actual).toBe(expected); + + }); + + }); + }); \ No newline at end of file