-
Notifications
You must be signed in to change notification settings - Fork 0
Update Search client to Search API v3 #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
These methods should be kept around so not to make any breaking changes.
Not related to this PR, but I haven't noticed it until now :)
To make it easier to differentiate between Twingly::Search::VERSION and Twingly::Search::Client::SEARCH_VERSION. Client::SEARCH_API_VERSION makes it clear that it is the version of the API, not the version of the client.
|
Should we update the example to use
|
|
The reason there were so many lines removed here ( |
|
Just a thought, should we keep I feel like we are "in between" a major release (breaking changes to I'm thinking this could be a minor version bump if we keep WDYT @roback ? |
That is already the case (https://github.com/twingly/twingly-search-api-ruby/pull/65/files#diff-085b0a7f794a0d2f3248b1ff247629eeR15) :) I just switched to using
I thought these changes would break something at first, but you're right, it seems like there are no breaking changes. |
Oh, missed that, smart. :) |
|
I'm thinking like this:
|
jage
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we deprecate Query#language=? I'm thinking it should be specified in the search query.
I think we should "always" keep start/end-time though since it's very helpful when iterating over many results.
👍 I didn't think about language at all, but yes, it would be a good idea to deprecate it at the same time as well.
Exactly my thinking :) |
Same changes as in the ruby client (twingly/twingly-search-api-ruby#65)
diff --git a/examples/find_all_posts_mentioning_github.js b/examples/find_all_posts_mentioning_github.js
index 3140807..76a08a8 100644
--- a/examples/find_all_posts_mentioning_github.js
+++ b/examples/find_all_posts_mentioning_github.js
@@ -2,11 +2,16 @@ var Client = require('../').Client;
var async = require('async'); // this package is optional: npm install async
var SearchPostStream = function(keyword, language) {
+ var languageQuery = language ? 'lang:' + language : '';
this.client = new Client(null, 'MyCompany/1.0');
this.query = this.client.query();
- this.query.pattern = 'sort-order:asc sort:published ' + keyword
- this.query.language = language || '';
- this.query.startTime = new Date((new Date()).setHours((new Date()).getHours() - 240));
+ this.query.searchQuery = 'sort-order:asc '
+ + languageQuery
+ + ' sort:published '
+ + keyword;
+
+ // 1 day ago
+ this.query.startTime = new Date(new Date().getTime() - (1000 * 60 * 60 * 24));
};
SearchPostStream.prototype.each = function () {
@@ -26,7 +31,10 @@ SearchPostStream.prototype.each = function () {
for(var i = 0; i < result.posts.length; i++) {
console.log(result.posts[i].url);
}
- self.query.startTime = result.posts[result.posts.length-1].published;
+ if(result.posts.length > 0) {
+ self.query.startTime = result.posts[result.posts.length-1].publishedAt;
+ }
+
cb(false);
}
});
@@ -34,5 +42,5 @@ SearchPostStream.prototype.each = function () {
);
};
-var stream = new SearchPostStream('(github) AND (hipchat OR slack) page-size:20')
+var stream = new SearchPostStream('github OR (hipchat AND slack) page-size:20')
stream.each();
diff --git a/examples/hello_world.js b/examples/hello_world.js
index 2e2c58d..8011a5f 100644
--- a/examples/hello_world.js
+++ b/examples/hello_world.js
@@ -2,7 +2,7 @@ var Client = require('../').Client;
var client = new Client();
var query = client.query();
-query.pattern = '"hello world"';
+query.searchQuery = '"hello world"';
query.startTime = new Date((new Date()).setHours((new Date()).getHours() - 2));
query.execute(function(error, result){
if (error != false) {
diff --git a/lib/client.js b/lib/client.js
index 50699e0..8a61fec 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -26,7 +26,8 @@ var Client = function(apiKey, userAgent) {
}
this.BASE_URL = 'https://api.twingly.com';
- this.SEARCH_PATH = '/analytics/Analytics.ashx';
+ this.SEARCH_API_VERSION = "v3";
+ this.SEARCH_PATH = "/blog/search/api/" + this.SEARCH_API_VERSION + "/search";
this.VERSION = '1.0.0';
this.apiKey = apiKey;
diff --git a/lib/errors.js b/lib/errors.js
index 11ad9d8..0f92b4f 100644
--- a/lib/errors.js
+++ b/lib/errors.js
@@ -15,11 +15,16 @@ function TwinglyError(message) {
Error.captureStackTrace(this, arguments.callee);
this.name = 'TwinglyError';
this.message = message;
- this.fromApiResponseMessage = function(message) {
- if(message.indexOf('API key') >= 0) {
- return new TwinglyAuthError(message);
+ this.fromApiResponse = function(code, message) {
+ var codeStr = code.toString();
+ var fullMessage = message + " (code:" + code + ")";
+
+ if(codeStr.indexOf('400') == 0 || codeStr.indexOf('404') == 0) {
+ return new TwinglyQueryError(fullMessage);
+ } else if(codeStr.indexOf('401') == 0 || codeStr.indexOf('402') == 0) {
+ return new TwinglyAuthError(fullMessage);
} else {
- return new TwinglyServerError(message);
+ return new TwinglyServerError(fullMessage);
}
};
}
diff --git a/lib/parser.js b/lib/parser.js
index 3580c9a..bbf2a45 100644
--- a/lib/parser.js
+++ b/lib/parser.js
@@ -1,4 +1,4 @@
-var xpath = require('xpath'), dom = require('xmldom').DOMParser;
+var parseString = require('xml2js').parseString;
var Result = require('./result');
var Post = require('./post');
var TwinglyError = require('./errors').TwinglyError;
@@ -13,72 +13,104 @@ var Parser = function() {};
* @param {Parser~parseCallback} callback
*/
Parser.prototype.parse = function(document, callback){
- var doc = new dom().parseFromString(document);
-
- if(xpath.select("//*[local-name(.)='operationResult' and namespace-uri(.)='http://www.twingly.com'][@resultType='failure']", doc).length > 0) {
- callback(handleFailure(xpath.select("//*[local-name(.)='operationResult' and namespace-uri(.)='http://www.twingly.com'][@resultType='failure']/text()", doc)[0].toString()), null);
- } else if(xpath.select("//twinglydata", doc).length == 0) {
- callback(handleNonXmlDocument(doc), null);
- } else {
- callback(false, createResult(doc));
+ var parserOptions = {
+ preserveChildrenOrder: true,
+ explicitArray: false,
}
+ parseString(document, parserOptions, function (err, result) {
+ if(result && result.twinglydata) {
+ callback(false, createResult(result.twinglydata));
+ } else if(result && result.error) {
+ callback(handleFailure(result.error), null);
+ } else {
+ callback(handleNonXmlDocument(document), null);
+ }
+ });
};
/**
* @callback Parser~parseCallback
* @param {TwinglyError} error
* @param {Result} result
*/
-
-var createResult = function(data_node){
+var createResult = function(dataNode){
var result = new Result();
- result.numberOfMatchesReturned = parseInt(data_node.documentElement.getAttribute('numberOfMatchesReturned'));
- result.numberOfMatchesTotal = parseInt(data_node.documentElement.getAttribute('numberOfMatchesTotal'));
- result.secondsElapsed = parseFloat(data_node.documentElement.getAttribute('secondsElapsed'));
+ result.numberOfMatchesReturned = parseInt(dataNode.$.numberOfMatchesReturned);
+ result.numberOfMatchesTotal = parseInt(dataNode.$.numberOfMatchesTotal);
+ result.secondsElapsed = parseFloat(dataNode.$.secondsElapsed);
+ result.incomplete = dataNode.$.incompleteResult == "true";
- var posts = xpath.select('//post[@contentType="blog"]', data_node);
- for(var i = 0; i < posts.length; i++) {
- result.posts.push(parsePost(posts[i]));
+ var posts = dataNode.post;
+ if (typeof(posts) != 'undefined') {
+ for(var i = 0; i < posts.length; i++) {
+ result.posts.push(parsePost(posts[i]));
+ }
}
return result;
};
-var parsePost = function(element){
- var post_params = {'tags': []};
- for(var i = 0; i < element.childNodes.length; i++) {
- if((element.childNodes[i].tagName != '')&&(element.childNodes[i].tagName != undefined)) {
- if(element.childNodes[i].tagName == 'tags') {
- post_params[element.childNodes[i].tagName] = parseTags(element.childNodes[i]);
- } else {
- if(element.childNodes[i].childNodes[0] != undefined) {
- post_params[element.childNodes[i].tagName] = element.childNodes[i].childNodes[0].nodeValue;
- } else {
- post_params[element.childNodes[i].tagName] = '';
- }
- }
+var parsePost = function(postNode){
+ var postParams = {'tags': [], 'links': [], 'images': []};
+ var arrayTagNames = ['tags', 'links', 'images'];
+
+ for(var propertyName in postNode) {
+ var property = postNode[propertyName];
+ var parsedProperty;
+ switch(propertyName) {
+ case 'tags':
+ parsedProperty = parseArray(property.tag);
+ break;
+ case 'links':
+ parsedProperty = parseArray(property.link);
+ break;
+ case 'images':
+ parsedProperty = parseArray(property.image);
+ break;
+ case 'coordinates':
+ parsedProperty = parseCoordinates(property);
+ break;
+ default:
+ parsedProperty = property;
+ break;
}
+ postParams[propertyName] = parsedProperty;
}
+
var post = new Post();
- post.setValues(post_params);
+ post.setValues(postParams);
return post;
};
-var parseTags = function(element){
- var tags = [];
- var nodes = xpath.select('child::tag/text()', element);
- for(var i = 0; i < nodes.length; i++) {
- tags.push(nodes[i].nodeValue);
+var parseArray = function(property){
+ // Property.link is a function instead of undefined
+ if(typeof(property) == 'undefined' || typeof(property) == 'function') {
+ return [];
+ } else {
+ return property;
}
- return tags;
};
+var parseCoordinates = function(property) {
+ if(property.length == 0) {
+ return {};
+ }
+
+ return {
+ 'latitude': property.latitude,
+ 'longitude': property.longitude,
+ };
+}
+
var handleFailure = function(failure){
- return (new TwinglyError()).fromApiResponseMessage(failure);
+ code = failure.$.code;
+ message = failure.message;
+
+ return (new TwinglyError()).fromApiResponse(code, message);
};
var handleNonXmlDocument = function(document){
- var response_text = xpath.select('//text()', document)[0].toString();
+ var response_text = "Failed to parse response: " + document.toString();
return new TwinglyServerError(response_text);
};
diff --git a/lib/post.js b/lib/post.js
index 9b13d74..d1839a9 100644
--- a/lib/post.js
+++ b/lib/post.js
@@ -1,32 +1,51 @@
/**
* A blog post
*
+ * @property {string} id - the post ID (Twingly internal identification)
+ * @property {string} author - the author of the blog post
* @property {string} url - the post URL
* @property {string} title - the post title
- * @property {string} summary - the blog post text
+ * @property {string} text - the blog post text
* @property {string} languageCode - ISO two letter language code for the language that the post was written in
- * @property {Date} published - the date when the post was published
- * @property {Date} indexed - the date when the post was indexed by Twingly
+ * @property {string} locationCode - ISO two letter country code for the location of the blog
+ * @property {Object.<string, number>} coordinates - an object containing latitude and longitude from the post RSS
+ * @property {string[]} links - all links from the blog post to other resources
+ * @property {string[]} tags - the post tags/categories
+ * @property {string[]} images - image URLs from the post (currently not populated)
+ * @property {Date} indexedAt - the time, in UTC, when the post was indexed by Twingly
+ * @property {Date} publishedAt - the time, in UTC, when the post was published
+ * @property {Date} reindexedAt - timestamp when the post last was changed in our database/index
+ * @property {string} inlinksCount - number of links to this post that was found in other blog posts
+ * @property {string} blogId - the blog ID (Twingly internal identification)
+ * @property {string} blogName - the name of the blog
* @property {string} blogUrl - the blog URL
- * @property {string} blogName - name of the blog
- * @property {number} authority - the blog's authority/influence {@link https://developer.twingly.com/resources/search/#authority}
- * @property {number} blogRank - the rank of the blog, based on authority and language {@link https://developer.twingly.com/resources/search/#authority}
- * @property {string[]} tags - tags
+ * @property {number} blogRank - the rank of the blog, based on authority and language. {@link https://developer.twingly.com/resources/ranking/#blogrank}
+ * @property {number} authority - the blog's authority/influence. {@link https://developer.twingly.com/resources/ranking/#authority}
*
* @constructor
*/
+
var Post = function(){
+ this.id = '';
+ this.author = '';
this.url = '';
this.title = '';
- this.summary = '';
+ this.text = '';
this.languageCode = '';
- this.published = new Date(Date.parse('1970-01-01T00:00:01Z'));
- this.indexed = new Date(Date.parse('1970-01-01T00:00:01Z'));
- this.blogUrl = '';
+ this.locationCode = '';
+ this.coordinates = {};
+ this.links = [];
+ this.tags = [];
+ this.images = [];
+ this.indexedAt = new Date(Date.parse('1970-01-01T00:00:01Z'));
+ this.publishedAt = new Date(Date.parse('1970-01-01T00:00:01Z'));
+ this.reindexedAt = new Date(Date.parse('1970-01-01T00:00:01Z'));
+ this.inlinksCount = 0;
+ this.blogId = '';
this.blogName = '';
- this.authority = 0;
+ this.blogUrl = '';
this.blogRank = 0;
- this.tags = [];
+ this.authority = 0;
};
/**
@@ -35,25 +54,68 @@ var Post = function(){
* @param {object} params - containing blog post data
*/
Post.prototype.setValues = function(params){
+ this.id = params['id'];
+ this.author = params['author'];
this.url = params['url'];
this.title = params['title'];
- this.summary = params['summary'];
+ this.text = params['text'];
this.languageCode = params['languageCode'];
- this.published = new Date(Date.parse(params['published'].replace(' ', 'T')));
- this.indexed = new Date(Date.parse(params['indexed'].replace(' ', 'T')));
- this.blogUrl = params['blogUrl'];
- this.blogName = params['blogName'];
- if(!isNaN(parseInt(params['authority']))) {
- this.authority = parseInt(params['authority']);
+ this.locationCode = params['locationCode'];
+ this.coordinates = params['coordinates'];
+ this.links = params['links'];
+ this.tags = params['tags'];
+ this.images = params['images'];
+ this.indexedAt = new Date(Date.parse(params['indexedAt'].replace(' ', 'T')));
+ this.publishedAt = new Date(Date.parse(params['publishedAt'].replace(' ', 'T')));
+ this.reindexedAt = new Date(Date.parse(params['reindexedAt'].replace(' ', 'T')));
+ if(!isNaN(parseInt(params['inlinksCount']))) {
+ this.inlinksCount = parseInt(params['inlinksCount']);
} else {
- this.authority = 0;
+ this.inlinksCount = 0;
}
+ this.blogId = params['blogId'];
+ this.blogName = params['blogName'];
+ this.blogUrl = params['blogUrl'];
if(!isNaN(parseInt(params['blogRank']))) {
this.blogRank = parseInt(params['blogRank']);
} else {
this.blogRank = 0;
}
- this.tags = params['tags'];
+ if(!isNaN(parseInt(params['authority']))) {
+ this.authority = parseInt(params['authority']);
+ } else {
+ this.authority = 0;
+ }
};
+/**
+ * @deprecated Please use {#text} instead
+ */
+Object.defineProperty(Post.prototype, 'summary', {
+ get: function summary() {
+ console.warn('[DEPRECATION] `summary` is deprecated, use `text` instead');
+ return this.text;
+ }
+});
+
+/**
+ * @deprecated Please use {#indexedAt} instead
+ */
+Object.defineProperty(Post.prototype, 'indexed', {
+ get: function indexed() {
+ console.warn('[DEPRECATION] `indexed` is deprecated, use `indexedAt` instead');
+ return this.indexedAt;
+ }
+});
+
+/**
+ * @deprecated Please use {#publishedAt} instead
+ */
+Object.defineProperty(Post.prototype, 'published', {
+ get: function published() {
+ console.warn('[DEPRECATION] `published` is deprecated, use `publishedAt` instead');
+ return this.publishedAt;
+ }
+});
+
module.exports = Post;
diff --git a/lib/query.js b/lib/query.js
index 7ee2829..27488bf 100644
--- a/lib/query.js
+++ b/lib/query.js
@@ -5,7 +5,7 @@ var TwinglyQueryError = require('./errors').TwinglyQueryError;
* There is no need create a new instance manually, instead use {@link Client#query}.
*
* @property {Client} client - the client that this query is connected to
- * @property {string} pattern - the search query
+ * @property {string} searchQuery - the search query
* @property {string} language - language to restrict the query to
* @property {Date} startTime - search for posts published after this time (inclusive)
* @property {Date} endTime - search for posts published before this time (inclusive)
@@ -20,13 +20,27 @@ var Query = function(client) {
this.client = client;
- this.pattern = '';
+ this.searchQuery = '';
this.language = '';
this.startTime = null;
this.endTime = null;
};
/**
+ * @deprecated Please use {#searchQuery} instead
+ */
+Object.defineProperty(Query.prototype, 'pattern', {
+ get: function pattern() {
+ console.warn('[DEPRECATION] `pattern` is deprecated, use `searchQuery` instead');
+ return this.searchQuery;
+ },
+ set: function pattern(value) {
+ console.warn('[DEPRECATION] `pattern` is deprecated, use `searchQuery` instead');
+ this.searchQuery = value;
+ }
+});
+
+/**
* Returns the request url for the query
*
* @returns {string}
@@ -72,16 +86,24 @@ Query.prototype.urlParameters = function() {
* @returns {Object.<string,string|number>}
*/
Query.prototype.requestParameters = function(){
- if (this.pattern.length == 0) {
- throw new TwinglyQueryError('Missing pattern');
+ var fullSearchQuery = this.searchQuery;
+ if(this.language.length > 0) {
+ fullSearchQuery += " lang:" + this.language;
+ }
+ if(this.startTime != null) {
+ fullSearchQuery += " start-date:" + timeToString(this.startTime);
}
+ if(this.endTime != null) {
+ fullSearchQuery += " end-date:" + timeToString(this.endTime);
+ }
+
+ if (fullSearchQuery == 0) {
+ throw new TwinglyQueryError('Search query cannot be empty');
+ }
+
return {
- 'key': this.client.apiKey,
- 'searchpattern': this.pattern,
- 'documentlang': this.language,
- 'ts': timeToString(this.startTime),
- 'tsTo': timeToString(this.endTime),
- 'xmloutputversion': 2
+ 'apikey': this.client.apiKey,
+ 'q': fullSearchQuery,
}
};
diff --git a/lib/result.js b/lib/result.js
index a6c5322..ce10bed 100644
--- a/lib/result.js
+++ b/lib/result.js
@@ -13,6 +13,7 @@ var Result = function(){
this.secondsElapsed = 0.0;
this.numberOfMatchesTotal = 0;
this.posts = [];
+ this.incomplete = false;
};
/**
diff --git a/package.json b/package.json
index 9f9bfc4..97e5b8a 100644
--- a/package.json
+++ b/package.json
@@ -8,8 +8,7 @@
"url": "git://github.com/twingly/twingly-search-api-node.git"
},
"dependencies": {
- "xmldom": "^0.1.22",
- "xpath": "0.0.21"
+ "xml2js": "^0.4.17"
},
"devDependencies": {
"chai": "^3.5.0",
diff --git a/test/cassettes/search_for_spotify_on_sv_blogs.js b/test/cassettes/search_for_spotify_on_sv_blogs.js
index f7f7e58..58a4875 100644
--- a/test/cassettes/search_for_spotify_on_sv_blogs.js
+++ b/test/cassettes/search_for_spotify_on_sv_blogs.js
@@ -2,14 +2,15 @@ module.exports = exports = function(nock) {
var refs = [];
refs[0] = nock('http://api.twingly.com:443')
- .get('/analytics/Analytics.ashx?key=test-key&searchpattern=spotify%20page-size%3A10&documentlang=sv&ts=&tsTo=&xmloutputversion=2')
- .reply(200, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><twinglydata numberOfMatchesReturned=\"10\" secondsElapsed=\"0.24\" numberOfMatchesTotal=\"305875\"><post contentType=\"blog\">\r\n <url>http://vaziodamente.tumblr.com/post/139081128152</url>\r\n <title><![CDATA[Union by Deptford Goth]]></title>\r\n <summary><![CDATA[Union by Deptford Goth]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:42:39Z</published>\r\n <indexed>2016-02-11 00:47:55Z</indexed>\r\n <blogUrl>http://vaziodamente.tumblr.com/</blogUrl>\r\n <blogName><![CDATA[O Vazio]]></blogName>\r\n <authority>0</authority>\r\n <blogRank>1</blogRank>\r\n <tags>\r\n <tag><![CDATA[music]]></tag>\r\n <tag><![CDATA[spotify]]></tag>\r\n </tags>\r\n</post><post contentType=\"blog\">\r\n <url>http://www.startupanchor.com/student-com-bags-60m-to-grow-the-reach-of-its-student-digs-marketplace</url>\r\n <title><![CDATA[Student.com Bags $60M To Grow The Reach Of Its Student Digs Marketplace]]></title>\r\n <summary><![CDATA[Student.com, an accommodation marketplace founded back in 2011 (as ‘Overseas Student Living’ before rebranding last year) to focus specifically on the needs of international students, is announcing a $60 million combined Series B and C round today, led by global investment firm VY Capital. Horizons Ventures, Expa, Spotify founders Daniel Ek and Martin Lorentzon and Hugo Barra from Xiaomi also participated in the round. \r\nThe platform aims to simplify the accommodation search for international students needing to secure a base for their studies from a distance. And, on the flip side, it links landlords with a lucrative supply of overseas students who, given how much they are paying to study abroad, are probably more interested in knuckling down and studying on that in-room desk rather than throwing bedroom-trashing parties in their digs. \r\nStudent.com sits in the middle of these two parties, taking its commission cut from bookings. It claims to have taken in $110 million in bookings last year alone, from students in more than 100 countries. Landlords using its platform pay a commission on the total rental period, which it says is typically an academic year, but can be shorter a shorter timeframe, such as a summer, or as long as three years. \r\nThe company is not disclosing how many landlords it has signed up to its platform at this stage (nor will it confirm how many student users it has) but will say it works with “all major landlords in all key destinations” — a statement it says yields a total of 750,000 beds in its currently covered 426 destinations, which it says are in close proximity to more than 1,000 universities. \r\n“We provide landlords with global reach and scale which means access to international students in hundreds of countries across the world,” say the founders when asked how they incentivize landlords to sign up. “We also bring significant value in making the marketing and booking process much smoother from end to end.” \r\nThe new funding will be used for market expansion, the company said today, with plans to expand across the U.S., Latin America and the Middle East in the coming months. The new financing will also be used to grow its team — currently more than 200-people strong, spread over seven locations — and to invest in its tech platform. \r\n \r\n \r\n Source link \r\nThe post Student.com Bags $60M To Grow The Reach Of Its Student Digs Marketplace appeared first on Startup Anchor.]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:33:13Z</published>\r\n <indexed>2016-02-11 00:34:31Z</indexed>\r\n <blogUrl>http://www.startupanchor.com/</blogUrl>\r\n <blogName><![CDATA[Startup Anchor]]></blogName>\r\n <authority>0</authority>\r\n <blogRank>1</blogRank>\r\n <tags>\r\n <tag><![CDATA[Fundings and Exits]]></tag>\r\n </tags>\r\n</post><post contentType=\"blog\">\r\n <url>http://www.edaccessible.com/2016/02/11/tech-investors-from-spotify-xiaomi-vy-capital-and-horizon-bet-on-study-abroad-site-student-com</url>\r\n <title><![CDATA[Tech Investors from Spotify, Xiaomi, VY Capital and Horizon Bet On Study Abroad Site Student.com]]></title>\r\n <summary><![CDATA[http://ift.tt/eA8V8J \r\nChina’s emerging middle class is hitting the road. After decades of economic and political barriers, the winners of China’s capitalist surge are using their cash and freedom to travel the world. Despite current Chinese economic crisis, China’s travel market grew 19% in 2015, according to Barron’s. The investment magazine, in a […] \r\nVía Forbes Real Time http://ift.tt/1o4qgtG]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:28:29Z</published>\r\n <indexed>2016-02-11 00:40:16Z</indexed>\r\n <blogUrl>http://www.edaccessible.com/</blogUrl>\r\n <blogName><![CDATA[EdAccessible]]></blogName>\r\n <authority>41</authority>\r\n <blogRank>3</blogRank>\r\n <tags>\r\n <tag><![CDATA[Photos]]></tag>\r\n </tags>\r\n</post><post contentType=\"blog\">\r\n <url>https://blissfulconnection.wordpress.com/2016/02/11/alison-wonderland</url>\r\n <title><![CDATA[Alison Wonderland]]></title>\r\n <summary><![CDATA[Alex Sholler also known as Alison Wonderland was born on September 1986 in Sydney, Australia. This 29 year old DJ and producer was signed to EMI Music Australia, which is part of Universal Music Australia. She began her musical career as a career as a cellist in the Sydney Youth Opera and later the bassist in an indie band. In 2014 she embarked on a national tour playing in warehouses across Australia. Wonderland’s debut album, Run, was released on 20 March 2015. Her genre varies from trap, future garage, chill wave, alternative dance and EDM. She truly knows how to play with sound and is not afraid to deviate from the norm. She once said in an interview, when asked if she ever played classical music in her set: “actually, yes. I once opened a set with a Strauss track which features a cello. It was a proud moment, I actually got the crowd to waltz. `You can also hear the intense violin and cello sound in her music.Alison Wonderland gained popularity after her debut single “Get Ready” which features rapper Fishing was released on January 1, 2013. Soon after on June 27, 2014 her debut EP “Calm Down” was released and peaked at 38 on the ARIA chart, which preceded with singles “I Want U” and “Cold”. \r\n“On February 11, 2015 Wonderland released the lead single from her debut album titled “U Don’t Know” which featured Wayne Coyne from The Flaming Lips along with the music video which gained popularity because of Christopher Mintz-Plasse’s lead role in the video against Wonderland. It managed to peak at 63 on the ARIA charts. The single currently has over 3 Million streams on Spotify as of Janurary 20, 2016. Her debut album Run was then released on March 20, 2015 in Australia and April 7, 2015 in the United States. It featured many Australian artists including Slumberjack, and SAFIA as well as producers from around the world such as Djemba Djemba, Awe, and Lido. “ \r\nAlison Wonderland is an incredible artist due to her entire devotion throughout her album, not only is she a producer but also a vocalist, and her album is original and different. Alison Wonderland was nominated for two ARIA awards in 2015, Best Dance Release (for the single ‘Run’) and Best Video (for “U Don’t Know” featuring Wayne Coyne). The latter being a publicly voted category. She was one of eight nominees to gain exactly two nominations, other nominees included The Veronicas, 5 Seconds Of Summer, the Australian Brandenburg Orchestra, Meg Mac, Peking Duk and more. \r\nShe is a very interesting person. She wants to keep her personal life secretive. She doesn’t want people to know her age, nor even her real name. She also truly hates labels. She does not want to be regarded as a feminist. She wants people to judge her by the music she makes. Alison hates that she is constantly called and viewed as a female DJ. She is a DJ, and a good one at it, and would like to be compared to all DJs in the music industry, even if it is dominated by men. \r\n \r\nShe recently stated in an interview: “I don’t want it to be about being a girl. I just want to be an artist,” she says. “The fact that in every interview I get asked about females in the music industry is a reflection on how females in the industry are perceived.” \r\n \r\n“You see a little blonde girl up on stage, and what do you think?” she says. “People doubt if I’m actually mixing up on stage, and I think that if I was a guy they would never question that. That really pisses me off.” To debunk this perception, Wonderland uses a GoPro camera to film her hands, projecting the images to the crowd. Even so “people still doubt me,” she says, but adds that her sceptics are dwindling. \r\nI personally remember the first time I got to see Alison Wonderland live, it was at Electric Forest 2015, and I was amazed. Such a small girl but such incredible energy and a big personality. She immediately intrigued me. Such a cute voice yet such an immense personality. Her music contained so much bass, and I could not stop moving. \r\n \r\n“On stage, splashes of strobe lights showcase an energy that belies the delicacy of her frame. Even Wonderland’s video clips are infused with an edgy rebellion. Her most out-there single, Get Ready, features young girls rapping the lyrics, their faces painted in Goth-inspired clown make-up, black tears running down their cheeks. \r\nWonderland does not shy away from this point: her artistic identity is constructed to deliberately downplay “the woman aspect”. For example, she says this is the reason she wears oversized T-shirts to her shows. And despite her disavowal of gender, Wonderland openly acknowledges that the path to the top is a fight, not a ride. For women, she says, the fight for respect is an additional hurdle. \r\n“I’m quite competitive with men, and I remember when I started, I would get judged. So I’d go home and I’d practise every week, and I’d come back with a new trick. And that’s how I got better. It just motivated me to keep going. “So what if, quite by accident, Alison Wonderland became an idol for young girls hoping to follow in her footsteps? \r\n“I hope so, I really do. If that’s what I became, I’d be happy. “ \r\nI’m very excited to get to see her tonight (10-02-2016) at Belmont in Montreal. I believe it’s going to be a fantastic show and that she will absolutely kill it. \r\nCitation: http://www.smh.com.au/entertainment/alison-wonderland-warns-dont-label-me-a-female-dj-20140729-zsyw9.html#ixzz3znnkzQAA \r\nSydney morning herald]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:24:19Z</published>\r\n <indexed>2016-02-11 00:24:41Z</indexed>\r\n <blogUrl>https://blissfulconnection.wordpress.com/</blogUrl>\r\n <blogName><![CDATA[Blissful Connection]]></blogName>\r\n <authority>0</authority>\r\n <blogRank>1</blogRank>\r\n <tags>\r\n <tag><![CDATA[Uncategorized]]></tag>\r\n </tags>\r\n</post><post contentType=\"blog\">\r\n <url>http://www.clickshared.com/student-com-bags-60m-to-grow-the-reach-of-its-student-digs-marketplace</url>\r\n <title><![CDATA[Student.com Bags $60M To Grow The Reach Of Its Student Digs Marketplace]]></title>\r\n <summary><![CDATA[Student.com, an accommodation marketplace founded back in 2011 (as ‘Overseas Student Living’ before rebranding last year) to focus specifically on the needs of international students, is announcing a $60 million combined Series B and C round today, led by global investment firm VY Capital. Horizons Ventures, Expa, Spotify founders Daniel Ek and Martin Lorentzon and Hugo Barra from Xiaomi also participated in the round. \r\nThe platform aims to simplify the accommodation search for international students needing to secure a base for their studies from a distance. And, on the flip side, it links landlords with a lucrative supply of overseas students who, given how much they are paying to study abroad, are probably more interested in knuckling down and studying on that in-room desk rather than throwing bedroom-trashing parties in their digs. \r\nStudent.com sits in the middle of these two parties, taking its commission cut from bookings. It claims to have taken in $110 million in bookings last year alone, from students in more than 100 countries. Landlords using its platform pay a commission on the total rental period, which it says is typically an academic year, but can be shorter a shorter timeframe, such as a summer, or as long as three years. \r\nThe company is not disclosing how many landlords it has signed up to its platform at this stage (nor will it confirm how many student users it has) but will say it works with “all major landlords in all key destinations” — a statement it says yields a total of 750,000 beds in its currently covered 426 destinations, which it says are in close proximity to more than 1,000 universities. \r\n“We provide landlords with global reach and scale which means access to international students in hundreds of countries across the world,” say the founders when asked how they incentivize landlords to sign up. “We also bring significant value in making the marketing and booking process much smoother from end to end.” \r\nThe new funding will be used for market expansion, the company said today, with plans to expand across the U.S., Latin America and the Middle East in the coming months. The new financing will also be used to grow its team — currently more than 200-people strong, spread over seven locations — and to invest in its tech platform. \r\n \r\n \r\n Source link \r\nThe post Student.com Bags $60M To Grow The Reach Of Its Student Digs Marketplace appeared first on Click Shared.]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:20:07Z</published>\r\n <indexed>2016-02-11 00:45:22Z</indexed>\r\n <blogUrl>http://www.clickshared.com/</blogUrl>\r\n <blogName><![CDATA[Click Shared]]></blogName>\r\n <authority>0</authority>\r\n <blogRank>1</blogRank>\r\n <tags>\r\n <tag><![CDATA[All in one Blog]]></tag>\r\n </tags>\r\n</post><post contentType=\"blog\">\r\n <url>http://www.maagg.com/blog/scholar-com-baggage-60m-to-improve-the-achieve-of-its-scholar-digs-market</url>\r\n <title><![CDATA[Scholar.com Baggage $60M To Improve The Achieve Of Its Scholar Digs Market]]></title>\r\n <summary><![CDATA[Scholar.com, an lodging marketplace launched again in 2011 (as ‘Overseas Scholar Living’ in advance of rebranding very last yr) to target particularly on the needs of international pupils, is announcing a $60 million mixed Sequence B and C spherical now, led by international expense agency VY Funds. Horizons Ventures, Expa, Spotify founders Daniel Ek and […]]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:14:22Z</published>\r\n <indexed>2016-02-11 00:15:02Z</indexed>\r\n <blogUrl>http://www.maagg.com/</blogUrl>\r\n <blogName><![CDATA[MAAGG]]></blogName>\r\n <authority>5</authority>\r\n <blogRank>1</blogRank>\r\n <tags>\r\n <tag><![CDATA[Tech]]></tag>\r\n <tag><![CDATA[Daniel Ek]]></tag>\r\n <tag><![CDATA[Horizons Ventures]]></tag>\r\n <tag><![CDATA[Hugo Barra]]></tag>\r\n <tag><![CDATA[Overseas Scholar Living]]></tag>\r\n </tags>\r\n</post><post contentType=\"blog\">\r\n <url>http://www.lipsandlash.co/2016/02/11/the-weather-feels</url>\r\n <title><![CDATA[The “Weather” Feels]]></title>\r\n <summary><![CDATA[I’m not sure about you, but I know that for me, as the weather changes, so do my musical interests. As the winter progresses, my acoustic and indie folk inclinations rise. I am a devoted fan to singer-songwriters like Ben Howard, Ed Sheeran, Gabrielle Aplin, Lewis Watson, and many other talented artists from the UK. However, this winter, I’ve seen myself drift from such artists and genres. \r\nUnlike my typical winters, this one has completely thrown me off and I blame that on the unusual weather patterns. My preferred genres this season seemed to have turned to “chill” and electronic. I’ve been really digging Snakehips, Disclosure, Kygo, Flume, Modi, and a plethora of others within this range. What made this unconscious mindset change so dramatically? Well, definitely the warm weather (though there have been a few frigid days thrown in the mix) and probably the use of the “Discover” tab on Spotify. I’ve never really opted for this tool until I came across some of my favorite “undiscovered” artists on there. I thought, “Hey, why not? I might as well give it a try!” so I pressed play, placed the songs on shuffle, and as the beats progressed, I noticed myself adding the suggestions to some of my ongoing playlists. I discovered so many new artists that were unknown to me prior and through clicking around their profiles, I continuously searched the related artists and discovered even more artists that weren’t and still aren’t mainstream. \r\nWhile listening to these songs, my goose bumps were “spooked” in such a positive way that I continuously kept creating “… & chill” playlists and compiling new, what I like to call “vibing”, songs into these curated mixes. Although I have felt some detachment to my beloved, heart-wrenching love ballads and soft acoustic guitar rhythms, I have been loving the songs that I can just sit, stare, and think about nothing as these beats crash amongst me.]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:09:08Z</published>\r\n <indexed>2016-02-11 00:19:46Z</indexed>\r\n <blogUrl>http://www.lipsandlash.co/</blogUrl>\r\n <blogName><![CDATA[LIPS & LASHES]]></blogName>\r\n <authority>0</authority>\r\n <blogRank>1</blogRank>\r\n <tags>\r\n <tag><![CDATA[Music]]></tag>\r\n <tag><![CDATA[chill]]></tag>\r\n <tag><![CDATA[disclosure]]></tag>\r\n <tag><![CDATA[electronic]]></tag>\r\n <tag><![CDATA[flume]]></tag>\r\n <tag><![CDATA[kygo]]></tag>\r\n <tag><![CDATA[modi]]></tag>\r\n <tag><![CDATA[snakehips]]></tag>\r\n <tag><![CDATA[vibes]]></tag>\r\n <tag><![CDATA[winter]]></tag>\r\n </tags>\r\n</post><post contentType=\"blog\">\r\n <url>http://www.ft.com/cms/s/0/d68e637c-cfdb-11e5-831d-09f7778e7377.html?ftcamp=published_links/rss/companies_technology/feed//product</url>\r\n <title><![CDATA[Student.com gets $60m from Spotify backers]]></title>\r\n <summary><![CDATA[Student accommodation marketplace saw $110m in bookings last year]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:05:57Z</published>\r\n <indexed>2016-02-11 00:25:22Z</indexed>\r\n <blogUrl>http://www.ft.com/companies/technology</blogUrl>\r\n <blogName><![CDATA[Technology]]></blogName>\r\n <authority>200</authority>\r\n <blogRank>5</blogRank>\r\n</post><post contentType=\"blog\">\r\n <url>http://www.ft.com/cms/s/0/d68e637c-cfdb-11e5-831d-09f7778e7377.html?ftcamp=published_links/rss/companies_us/feed//product</url>\r\n <title><![CDATA[Student.com gets $60m from Spotify backers]]></title>\r\n <summary><![CDATA[Student accommodation marketplace saw $110m in bookings last year]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:05:57Z</published>\r\n <indexed>2016-02-11 00:27:09Z</indexed>\r\n <blogUrl>http://www.ft.com/companies/us</blogUrl>\r\n <blogName><![CDATA[US & Canadian companies]]></blogName>\r\n <authority>799</authority>\r\n <blogRank>7</blogRank>\r\n</post><post contentType=\"blog\">\r\n <url>https://bookkeepingadvice.wordpress.com/2016/02/11/tech-investors-from-spotify-xiaomi-vy</url>\r\n <title><![CDATA[Tech Investors from Spotify, Xiaomi, VY]]></title>\r\n <summary><![CDATA[Tech Investors from Spotify, Xiaomi, VY Capital and Horizon Bet On Study Abroad Site Student.com http://ow.ly/3bb3Kg]]></summary>\r\n <languageCode>en</languageCode>\r\n <published>2016-02-11 00:05:43Z</published>\r\n <indexed>2016-02-11 00:28:46Z</indexed>\r\n <blogUrl>https://bookkeepingadvice.wordpress.com/</blogUrl>\r\n <blogName><![CDATA[Book Keeping Advice]]></blogName>\r\n <authority>0</authority>\r\n <blogRank>1</blogRank>\r\n <tags>\r\n <tag><![CDATA[Uncategorized]]></tag>\r\n </tags>\r\n</post></twinglydata>", { server: 'nginx',
- date: 'Thu, 11 Feb 2016 00:57:45 GMT',
- 'content-type': 'text/xml; charset=utf-8',
- 'content-length': '20090',
+ .get('/blog/search/api/v3/search?apikey=test-key&q=spotify%20page-size%3A10%20lang%3Asv')
+ .reply(200, "<?xml version=\"1.0\" encoding=\"utf-8\"?><twinglydata numberOfMatchesReturned=\"10\" secondsElapsed=\"0.257\" numberOfMatchesTotal=\"26086\" incompleteResult=\"false\"><post><id>3516755559169806807</id><author>annielindqvist</author><url>http://nouw.com/annielindqvist/kladkod-henrik-berggren-30025570</url><title>Klädkod: Henrik Berggren</title><text>Skogskyrkogården, Tallkrogen, Gubbängen, Hökarängen. Jag hoppar av Hökarängen och går hem till mig. Förbi centrum och Matdax, den billigaste mataffären i Stockholm, tre kexchoklad för en guldpeng. Idag åkte jag i motsatt riktning för att ta flyget till (skrev nästan hem till) Göteborg. Jag ska överraska en kompis, som jag vet är för ointresserad för att läsa det här, grilla hos mamma och pappa och imorgon vara Malins plus en på inflyttningskalas. Emelia har tydligen blivit hooked på styr och ställ så vi ska cykla runt i Gbg-solen, det tänker jag får bli söndagsgöra. Nu lyfter vi och landar förhoppningsvis om cirkus en timme. Och juste, jag hör inte vad någon säger just ny, lyssnar på https://open.spotify.com/album/4jdSZtOrRqIbFbsWHVVHhH.</text><languageCode>sv</languageCode><locationCode>se</locationCode><coordinates /><links><link>https://open.spotify.com/album/4jdSZtOrRqIbFbsWHVVHhH</link></links><tags /><images /><indexedAt>2017-05-05T08:06:00Z</indexedAt><publishedAt>2017-05-05T08:05:39Z</publishedAt><reindexedAt>2017-05-05T10:06:00Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>10228636730578919218</blogId><blogName>annielindqvist blogg</blogName><blogUrl>http://nouw.com/annielindqvist</blogUrl><blogRank>1</blogRank><authority>0</authority></post><post><id>18122167907151679490</id><author>Markus Larsson</author><url>http://bloggar.aftonbladet.se/musikbloggen/2017/05/vacker-aterkomst-med-henrik-berggren/</url><title>Vacker återkomst med Henrik Berggren</title><text>Den vackra resignationen med Henrik Berggren. Foto: Anders Deros\r\n\r\nHenrik Berggren \r\nWolf’s heart \r\nWoah Dad!/Border \r\n\r\nROCK Det är nio år sedan som Broder Daniel tog farväl på festivalen Way Out West. \r\nRedan då kändes det som om bandet levde på övertid, att de hade spelat ut sin roll, att det var dags att gå. Avskedet blev ännu mer logiskt efter att gitarristen Anders Göthberg dog. \r\nOch frågan är vad bandets frontfigur och sångare Henrik Berggren har för betydelse i dag? ”Wolf’s heart” är skivan som ingen trodde skulle släppas. \r\nI en intervju med Nöjesguiden berättar Berggren att han mest ville bevisa för sig själv och andra att han kunde ”skriva och skapa sig själv” även i den här åldern. Henrik Berggren fyller 43 år i november. \r\nEfter att ha fått diagnosen kroniskt trötthetssyndrom beskriver Berggren sitt liv i intervjuer som en spöktillvaro, att halva hans jag redan gått över till den andra sidan. Han har gett upp hoppet om att bli frisk. \r\nHan låter ensam och isolerad när han pratar. Även musiken på ”Wolf’s heart” känns inspelad utan någon kontakt med omvärlden. Ofta är det lättare att härleda låtarna till gammal och anrik rock från 70- eller 80-talet än till något som händer där ute just nu. \r\nInledande ”Hold on to your dreams” lägger sig så nära ”Don’t fear the reaper” med Blue Öyster Cult att man väntar på att skådespelaren Christopher Walken ska störta in i rummet och skrika ”More cowbell!”. I ”I need protection” påminner musiken om ”Crazy on you” med Heart. Och ”Wild child” kanske får någon att leta upp Secret Service på Spotify. \r\nDet är säkert enkelt att avfärda Henrik Berggren i dag. Det är alltid lätt att fnysa åt artister som tar sig själva och sin rock på ett lika stort, distanslöst och teatraliskt allvar. \r\nMen när Henrik Berggren sjunger ”hold on to your dreams” och ”I wanna live” har det en djupare och mer akut betydelse. Han om någon vet hur viktigt det kan vara att få skrika ut de orden från en scen för att kunna fylla sitt liv med någon sorts mening och syre. \r\nDen resignerade atmosfären på ”Wolf’s heart” blir dessutom alltmer sällsynt. Det är alltid värdefullt att få höra något som inte har en tanke på att passa in i en mall, ett nöjesprogram på tv eller flirtar med Spotify. \r\nMen framför allt är melodierna precis lika vackra och starka som på albumen ”Broder Daniel forever” och ”Cruel town”. \r\nDet är som att hitta en ros i en spricka i asfalten. \r\n\r\nBÄSTA SPÅR: ”Hold on to your dreams” eller ”I need protection”. Mörk magi. \r\nVISSTE DU ATT… Theodor Jensen, Joel Alme, Henning Fürst, Nino Keller och Mattias ”Svålen” Bärjed backar Henrik Berggren under hans konserter senare i år? Låter makalöst på papperet. \r\nLYSSNA OCKSÅ PÅ: ”Shake some action” med Flamin’ Groovies. Gitarrerna på ”Wolf’s heart” ringer med samma klang. \r\n\r\nLÄS FLER SKIVRECENSIONER HÄR! \r\n \r\nInlägget Vacker återkomst med Henrik Berggren dök först upp på Musikbloggen.</text><languageCode>sv</languageCode><locationCode>se</locationCode><coordinates /><links /><tags><tag>Markus Larsson</tag><tag>Pop</tag><tag>Rock</tag><tag>Skivrecension</tag><tag>Henrik Berggren</tag><tag>recension</tag><tag>Wolf's heart</tag></tags><images /><indexedAt>2017-05-05T06:57:17Z</indexedAt><publishedAt>2017-05-05T06:38:22Z</publishedAt><reindexedAt>0001-01-01T00:00:00Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>2477368698016143722</blogId><blogName>Musikbloggen</blogName><blogUrl>http://bloggar.aftonbladet.se/musikbloggen</blogUrl><blogRank>3</blogRank><authority>55</authority></post><post><id>3908041977787516266</id><author>Mattias Kling</author><url>http://bloggar.aftonbladet.se/musikbloggen/2017/05/vilken-utmarkt-comeback-at-the-drive-in/</url><title>Vilken utmärkt comeback, At The Drive-In</title><text>Höga hopp till liten nytta på Bråvallafestivalen förra året. Foto: Izabelle Nordfjell/TT\r\n\r\nAt The Drive-In \r\nIn•ter a•li•a \r\nRise/Warner \r\n\r\nPOSTCORE/ALTROCK En av förra årets mer smärtsamma felsatsningar, helt i klass med Einstürzende Neubauten på Getaway Rock 2015, stod Bråvallafestivalen för. Som eftermiddagsunderhållning hade jag och mina mer finsmakarintresserade bekanta hoppats mycket på en viss comebacktrupp från El Paso men då At The Drive-In klev upp på scenen under ett rätt eftermiddagssurt molntäcke upptäckte vi att de som brydde sig – det var just vi. Och högst en handfull fler. Resultatet blev trots detta, eller kanske precis därför, ett explosivt framträdande som slutade med att sångaren Cedric Bixler-Zavala slog sönder trumsetet. \r\nHändelsen säger egentligen mer om Norrköpingsfestivalens publikprofil – serveras pärlor till svin kommer dessa ändå alltid att doppa trynet i sin sedvanliga foderhink – än om bandet i sig. För när det gäller innovativ och avig rockmusik från skarven mellan 90- och 00-tal gick Texas-bandet i den absoluta spetsen, vilket inte minst blir tydligt av att millenniegiven ”Relationship of command” ofta nämns i samma respektfulla sammanhang som exempelvis Refuseds ”The shape of punk to come” (1998). \r\nBeröringspunkterna med nämnda Umeå-kollektiv är också stora när At The Drive-In nu återvänder med sin första studioskiva på 17 år. Tankarna om att förena konstrock med punk, hardcore och funk som en gång gav ensemblen legendarstatus finns kvar och de spinner i mångt och mycket vidare utifrån de progressiva ambitioner som präglade föregångaren – men med den sobra erfarenhet som ytterligare nära två decennier kan ge. Den utmanande tiden i The Mars Volta har gett Bixler-Zavala större mod att hålla tillbaka lika mycket som han exploderar och de något brådmogna ambitionerna som präglade tredje skivan, och som kom att bli bidragande till bandets uppbrott, sätts här i ett mer sansat sammanhang. \r\nMärk väl, vare sig öppningskanonaden ”No wolf like the present”, den tillbakahållet industriella ”Ghost-tape no 9” eller förstasingeln ”Hostage stamps” är lättlyssnade enligt någon gängse definition. At The Drive-In tänjer och bänder fortfarande på låtstrukturer och rytmbyggen på ett högst egensinnigt vis, fjärran från mittfårans massinbjudande tongångar. \r\nMen när det gäller avigt innovativ rockmusik lär det bli väldigt svårt att överträffa ”In•ter a•li•a” i år. \r\nBÄSTA SPÅR: ”Incurably innocent”. \r\nLÄS FLER NYA SKIVRECENSIONER HÄR! \r\n \r\nInlägget Vilken utmärkt comeback, At The Drive-In dök först upp på Musikbloggen.</text><languageCode>sv</languageCode><locationCode>se</locationCode><coordinates /><links><link>https://en.wikipedia.org/wiki/El_Paso,_Texas</link><link>https://open.spotify.com/album/0BrySJeJIdjsGkJDn2nXbc</link><link>https://open.spotify.com/album/7nRBGER6aKyfDrOO0pQTKR</link><link>https://en.wikipedia.org/wiki/The_Mars_Volta</link></links><tags><tag>Hardcore</tag><tag>Mattias Kling</tag><tag>Rock</tag><tag>Skivrecension</tag><tag>At The Drive-In</tag><tag>Bråvalla</tag><tag>Cedric Bixler-Zavala</tag><tag>einstürzende neubauten</tag><tag>Refused</tag><tag>The Mars Volta</tag></tags><images /><indexedAt>2017-05-05T06:12:08Z</indexedAt><publishedAt>2017-05-05T05:43:39Z</publishedAt><reindexedAt>0001-01-01T00:00:00Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>2477368698016143722</blogId><blogName>Musikbloggen</blogName><blogUrl>http://bloggar.aftonbladet.se/musikbloggen</blogUrl><blogRank>3</blogRank><authority>55</authority></post><post><id>1308260902624211140</id><author>Henric Wahlberg</author><url>http://calmridge.blogspot.com/2017/05/220-volt-har-slappt-sin-nya-singel.html</url><title>220 Volt har släppt sin nya singel</title><text>Det melodiösa hårdrocksbandet 220 Volt har idag släppt sin nya singel \"Fair Enough\", som finns att lyssna på via bland annat Spotify.</text><languageCode>sv</languageCode><locationCode>se</locationCode><coordinates /><links><link>https://3.bp.blogspot.com/-hMD0md7yE-4/WQwj6nyVQjI/AAAAAAABaIc/srsfWRPE0SUcN2y8Ed134KBvSHZmLk-8ACLcB/s1600/220-volt-fair-enough-500-500x500.jpg</link></links><tags /><images /><indexedAt>2017-05-05T06:35:29Z</indexedAt><publishedAt>2017-05-05T05:04:00Z</publishedAt><reindexedAt>2017-05-05T08:35:29Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>5203373980632392648</blogId><blogName>Den melodiösa bloggen</blogName><blogUrl>http://calmridge.blogspot.com</blogUrl><blogRank>3</blogRank><authority>40</authority></post><post><id>16370376317445360275</id><author /><url>http://loppantessan.blogg.se/2017/may/igar.html</url><title>Igår</title><text>Igår så kom mamma så städade vi upp lite i köket och slängde lite soppor och kartonger! Kändes bra att få de gjort.. ibland behöver man en liten knuff för att ta steget att fixa saker! 😁 Jag va sjukt trött efter gårdagen.. slutade med att jag satte mig i soffan och kolla musik videos och gjorde en liten lista på spotify! Sen gick jag och la mig typ 22:00! Nu är de ny dag och snart helg ☺️</text><languageCode>sv</languageCode><locationCode>se</locationCode><coordinates /><links /><tags><tag>2017</tag></tags><images /><indexedAt>2017-05-05T08:19:09Z</indexedAt><publishedAt>2017-05-05T05:00:00Z</publishedAt><reindexedAt>2017-05-05T10:19:09Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>6256528712491961052</blogId><blogName>Lindly</blogName><blogUrl>http://loppantessan.blogg.se</blogUrl><blogRank>1</blogRank><authority>1</authority></post><post><id>5749355264221327098</id><author>Henric Wahlberg</author><url>http://calmridge.blogspot.com/2017/05/inglorious-bjuder-pa-nya-laten-black.html</url><title>Inglorious bjuder på nya låten \"Black Magic\"</title><text>Inglorious släpper om en vecka sitt andra album och via Spotify kan man nu ta del av ett smakprov i form av låten \"Black Magic\".</text><languageCode>sv</languageCode><locationCode /><coordinates /><links><link>https://1.bp.blogspot.com/-38EXvtYsBaA/WQwda9WUZSI/AAAAAAABaIA/GD5E8sNd-uY-EbPbjKCMd96jGikPGE_MgCLcB/s1600/inglorious-2017.jpg</link></links><tags /><images /><indexedAt>2017-05-05T04:51:58Z</indexedAt><publishedAt>2017-05-05T04:51:58Z</publishedAt><reindexedAt>2017-05-05T06:51:58Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>5203373980632392648</blogId><blogName>Den melodiösa bloggen</blogName><blogUrl>http://calmridge.blogspot.com</blogUrl><blogRank>3</blogRank><authority>40</authority></post><post><id>10741961996018889023</id><author>Henric Wahlberg</author><url>http://calmridge.blogspot.com/2017/05/lyssna-pa-uriah-heeps-nya-livealbum.html</url><title>Lyssna på Uriah Heep´s nya livealbum</title><text>Legendariska Uriah Heep har idag kommit med livealbumet \"Future Echoes Of The Past - The Legend Continues\", som finns att hitta via bland annat Spotify.</text><languageCode>sv</languageCode><locationCode /><coordinates /><links><link>https://1.bp.blogspot.com/-3txlvA8WECw/WQweuqE8REI/AAAAAAABaIM/Q9VrSVDFehoAKXGoX3F0vqxc8n7laBo-gCLcB/s1600/URIAH-HEEP.jpg</link></links><tags /><images /><indexedAt>2017-05-05T04:51:58Z</indexedAt><publishedAt>2017-05-05T04:51:58Z</publishedAt><reindexedAt>2017-05-05T06:51:58Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>5203373980632392648</blogId><blogName>Den melodiösa bloggen</blogName><blogUrl>http://calmridge.blogspot.com</blogUrl><blogRank>3</blogRank><authority>40</authority></post><post><id>9154451053858823791</id><author>Sölve Dahlgren</author><url>http://www.boktugg.se/2017/05/05/det-har-var-en-gang-en-butikskedja-som-hyrde-ut-videofilmer/</url><title>Det här var en gång en butikskedja som hyrde ut videofilmer</title><text>Det här är en kort tankeställare. På bilden ser ni en butik som numera säljer mest godis. Det som en gång var kärnprodukten är nu mer eller mindre historia. \r\nIgår kväll besökte jag ett köpcentrum och gick förbi en butik som öppnade där förra året. Den tillhör dock en kedja som funnits i många år – Hemmakväll som säljer godis. \r\nSå varför är det relevant för bokbranschen? Därför att de inte alltid sålt godis. \r\nHistorien börjar 1994 i Borås. ”De glada butiksinnehavarna Per-Anders och Janne Haglund driver två butiker i Borås. De strålar samman med sina kompanjoner Hans och Roland Örtendahl samt Mats Berntsson. En trio som driver butiker i Kungälv, Stenungsund och Uddevalla. Tillsammans startar de företaget Videomix. De enskilda butikerna går nu under namnet Videomix. Företagen inom kedjan benämns även efter stad.”, skriver Hemmakväll på sin hemsida. \r\nKedjan växer vidare, 2008 byter den namn till Hemmakväll och 2013 är de uppe i 103 butiker. Under den här perioden har Netflix invaderat Sverige och fått med sig HBO, Viaplay och ett par andra aktörer som gör att folk snabbt och lätt kan streama filmer hemma i soffan – eller hängmattan. \r\nSå finns det fortfarande en marknad för hyrfilmer? Jo. Men sortimentet blir allt mindre och när man går in på hemsidan och ser relaterade produkter så ger det en viss signal om att det nog inte är film som ligger i fokus: \r\n”Gillar du den här så gillar du nog någon av dessa.” Du kan inte bara få tips på liknande filmer utan även vilka snacks som passar till filmen… \r\nDet som en gång var en hyrfilmskedja har nu förvandlats till en nöjeskedja som främst marknadsför sig med Sveriges bästa lösgodis. Hur gick det så? \r\nOch framför allt eftersom detta är Boktugg – vad kan bokbranschen lära av detta? Framför allt så bör många bokhandlare vara väl medvetna om vad som hände med köpfilmerna och köpmusiken eftersom den till och med ingick i sortimentet innan marknaden för dessa dödades av Spotify och Netflix. \r\nVi tar förvandlingen en gång till konkret. Klickar in på Hemmakvälls hemsida och klickar på ”Erbjudanden”. Fyra olika. I tur och ordning som de visas: chips, chokladkaka, glass och slutligen film. \r\nÅ ena sidan så är det imponerande att företaget lyckats förvandla sin affärsidé från att vara experter på film till att vara experter på snacks. Å andra sidan så ser jag inte riktigt hur en bokhandlare skulle kunna förvandla sin affärsidé med samma logik. Chips eller choklad och pappersböcker fungerar mindre bra. Men det kanske finns andra ”matchande” produkter? \r\nMest av allt såg jag det som en påminnelse om att teknikskiften kan förändra branscher i grunden. \r\n\r\n\r\n\t\r\nInlägget Det här var en gång en butikskedja som hyrde ut videofilmer dök först upp på Boktugg.se.</text><languageCode>sv</languageCode><locationCode>se</locationCode><coordinates /><links /><tags><tag>Bokhandel</tag><tag>Feature</tag><tag>REDAKTIONELLT</tag><tag>förändring</tag><tag>Hemmakväll</tag></tags><images /><indexedAt>2017-05-05T06:56:39Z</indexedAt><publishedAt>2017-05-05T03:37:30Z</publishedAt><reindexedAt>0001-01-01T00:00:00Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>8822746007126659955</blogId><blogName>Boktugg.se</blogName><blogUrl>http://www.boktugg.se</blogUrl><blogRank>3</blogRank><authority>37</authority></post><post><id>10219561768400390697</id><author>oklaraemilia</author><url>http://nouw.com/oklaraemilia/musik-torka-30022188</url><title>Musik-torka?</title><text>Tänkte bara slänga upp åtta utav mina nuvarande favoritlåtar! Jag lyssnar väldigt mycket på musik som ni kanske förstått så att välja EN favoritlåt finns inte på kartan för mig haha. Men här har ni iallafall åtta myslåtar. Dom är inte direkt att rekommendera på fest kanske men dom är hur mysiga och bra som helst att bara lyssna på i bussen, när man pluggar, när man är med kompisar eller när man bara vill ha lite go stämning! Så här får ni en radda med titlarna på låtarna ovan och ifall något skulle intressera er så får ni gärna kommentera vad ni fastnat för! Alltid kul att uppdatera sin Spotify-playlist lite ibland liksom! ♡ Million Miles Away - Keegan Allen ♡ Wicked Game - James Vincent McMorrow ♡ Hero - Family of the Year ♡ There's Nothing Holdin' Me Back - Shawn Mendes ♡ Ordinary Love - U2 (Mandela • Long walk to freedom) ♡ Youth - Daughter ♡ Ocean Eyes - Billie Eilish ♡ Seven Bridges Road - Eagles (live version)</text><languageCode>sv</languageCode><locationCode>se</locationCode><coordinates /><links /><tags /><images /><indexedAt>2017-05-05T03:13:59Z</indexedAt><publishedAt>2017-05-05T03:13:26Z</publishedAt><reindexedAt>2017-05-05T05:13:59Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>3452704241422427204</blogId><blogName>oklaraemilia</blogName><blogUrl>http://nouw.com/oklaraemilia</blogUrl><blogRank>1</blogRank><authority>0</authority></post><post><id>5387370369434829405</id><author>Anders Nunstedt</author><url>http://bloggar.expressen.se/andersnunstedt/2017/05/05/recension-henrik-berggrens-solodebut-fortsatter-dar-broder-daniel-slutade/</url><title>Recension: Henrik Berggren fortsätter där Broder Daniel slutade</title><text>Henrik Berggrens kind har star quality. \r\nALBUM \r\n \r\nHenrik Berggren \r\n”Wolf’s heart”\r\nGenre: Indierock. \r\nVem: Henrik Berggren, 42, var karismatisk sångare i charmanta odågorna Broder Daniel – göteborgsbandet där Håkan Hellström ingick under en period. De debuterade 1995 och tog farväl på Way Out West 2008 efter fyra album. \r\nVad: Solodebuten, som Berggren jobbat på i tio års tid. BD-kompisarna Theodor Jensen och Lars Malmros medverkar på skivan, där sångaren även tagit hjälp av Björn Olsson och Charlie Storm. Livepremiär på Gröna Lund, 24/5. \r\nBästa spår: ”Hold on to your dreams”, ”Run, Andy, run”, ”Parties”. \r\n \r\nSolodebuten – en välkommen comeback\r\n \r\n\r\n \r\nUr ett perspektiv är detta årets stora svenska pophändelse, alla kategorier. \r\nUr ett annat – not so much. \r\nIngen kan anklaga Henrik Berggren för att vara en glad opportunist som gjort allt för att smida medan järnet varit varmt. \r\n \r\n\r\nBroder Daniel spelar ”Shoreline”. Håkan Hellström på bas. \r\n \r\nDet har så att säga runnit en hel del vatten under broarna sedan det begav sig. \r\nHenrik Berggren har bytt ut sin basker mot en mössa, men Buttericks-stjärnan på kinden och det slarviga sminket är kvar. I 42-åringens värld tycks det inte ha hänt så himla mycket sedan Broder Daniel spelade ”Shoreline” i ”Sen kväll med Luuk” 2001. \r\n \r\nFlera spår inleds med samma gitarrackord som bandets signaturmelodi. Kanske är det göteborgarens svar på ”Spela ’Shoreline’”-kulten. \r\n \r\nDen dystra desperationen och den skört naiva utblicken på omvärlden är konstant. Berggrens oslipade men uttrycksfulla stämband är konserverade. Gamla vapendragare från BD-åren hörs på albumet. \r\nInte sällan låter det som uppföljaren till Broder Daniels sista album ”Cruel town”, som gavs ut för 14 år sedan. \r\n\r\n \r\nSamtidigt har världen gått vidare. Låtarna från ”Wolf’s heart” kommer inte att dominera Spotify i sommar. Ska det vara kommersiellt gångbar pop på svenska just nu ska det vara Hov1. \r\n \r\nDet innebär dock inte att den efterlängtade återkomsten från Henrik Berggren är tråkig, ointressant eller irrelevant. Snarare exakt tvärtom. \r\n \r\nTexterna är välskrivna, musiken är – till skillnad från de akustiska smakproven som dykt upp genom åren – catchy gitarrrock med tydliga refränger. Inte alla låtar är lika starka som singeln, men ingen tycks finnas där av en slump. Inte ens den lätt bisarra indievalsen ”Parties”. \r\n \r\nDet råder inga tvivel om att Berggrens indiehjärta fortfarande slår och slår och slår. ”Wolf’s heart” låter som en självklar hit på den alternativa Spotify-listan. Hans röst är väldigt välkommen tillbaka. \r\nANDERS NUNSTEDT \r\nInlägget Recension: Henrik Berggren fortsätter där Broder Daniel slutade dök först upp på Anders Nunstedt.</text><languageCode>sv</languageCode><locationCode>se</locationCode><coordinates /><links /><tags><tag>Album</tag><tag>Anders Nunstedt</tag><tag>Indie</tag><tag>Recension</tag><tag>Rock</tag></tags><images /><indexedAt>2017-05-05T05:13:43Z</indexedAt><publishedAt>2017-05-05T03:09:20Z</publishedAt><reindexedAt>0001-01-01T00:00:00Z</reindexedAt><inlinksCount>0</inlinksCount><blogId>15017250045771408961</blogId><blogName>Anders Nunstedt</blogName><blogUrl>http://bloggar.expressen.se/andersnunstedt</blogUrl><blogRank>2</blogRank><authority>14</authority></post></twinglydata>", { server: 'nginx',
+ date: 'Fri, 05 May 2017 10:46:33 GMT',
+ 'content-type': 'application/xml; charset=utf-8',
+ 'content-length': '22401',
connection: 'close',
- 'cache-control': 'private',
- 'set-cookie': [ 'SERVERID=web01; path=/' ] });
+ 'cache-control': 'no-cache',
+ pragma: 'no-cache',
+ expires: '-1' });
return refs;
diff --git a/test/cassettes/search_without_valid_api_key.js b/test/cassettes/search_without_valid_api_key.js
index ac81a37..1fa9eba 100644
--- a/test/cassettes/search_without_valid_api_key.js
+++ b/test/cassettes/search_without_valid_api_key.js
@@ -2,15 +2,16 @@ module.exports = exports = function(nock) {
var refs = [];
refs[0] = nock('http://api.twingly.com:443')
- .get('/analytics/Analytics.ashx?key=wrong&searchpattern=something&documentlang=&ts=&tsTo=&xmloutputversion=2')
- .reply(200, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><blogstream xmlns=\"http://www.twingly.com\">\r\n <operationResult resultType=\"failure\">The API key does not exist.</operationResult>\r\n</blogstream>", { server: 'nginx',
- date: 'Wed, 10 Feb 2016 23:37:40 GMT',
- 'content-type': 'text/xml; charset=utf-8',
- 'content-length': '183',
+ .get('/blog/search/api/v3/search?apikey=wrong&q=something')
+ .reply(401, "<?xml version=\"1.0\" encoding=\"utf-8\"?><error code=\"40101\"><message>Unauthorized</message></error>", { server: 'nginx',
+ date: 'Fri, 05 May 2017 11:51:05 GMT',
+ 'content-type': 'application/xml; charset=utf-8',
+ 'content-length': '97',
connection: 'close',
- 'cache-control': 'private',
- 'set-cookie': [ 'SERVERID=web03; path=/' ] });
+ 'cache-control': 'no-cache',
+ pragma: 'no-cache',
+ expires: '-1' });
return refs;
-};
+};
\ No newline at end of file
diff --git a/test/fixtures/minimal_valid_result.xml b/test/fixtures/minimal_valid_result.xml
index 6d71e5a..e71b6df 100644
--- a/test/fixtures/minimal_valid_result.xml
+++ b/test/fixtures/minimal_valid_result.xml
@@ -1,52 +1,81 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<twinglydata numberOfMatchesReturned="3" secondsElapsed="0.148" numberOfMatchesTotal="3">
-<post contentType="blog">
- <url>http://oppogner.blogg.no/1409602010_bare_m_ha.html</url>
- <title><![CDATA[Bare MÅ ha!]]></title>
- <summary><![CDATA[Ja, velkommen til høsten ...]]></summary>
- <languageCode>no</languageCode>
- <published>2014-09-02 06:53:26Z</published>
- <indexed>2014-09-02 09:00:53Z</indexed>
- <blogUrl>http://oppogner.blogg.no/</blogUrl>
- <blogName><![CDATA[oppogner]]></blogName>
- <authority>1</authority>
- <blogRank>1</blogRank>
- <tags>
- <tag><![CDATA[Blogg]]></tag>
- </tags>
-</post><post contentType="blog">
- <url>http://www.skvallernytt.se/hardtraning-da-galler-swedish-house-mafia</url>
- <title><![CDATA[Hårdträning – då gäller Swedish House Mafia]]></title>
- <summary><![CDATA[Träning. Och Swedish House Mafia. Det verkar vara ett ly…
Same changes as in the ruby client (twingly/twingly-search-api-ruby#65)
|
jage
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Great job!
Prepare the Search API client for Blog Search API v3
Todo
Query#patternandPostbackwards compatible (3678806)Query#language(ed6909f)Post#outlinks(ab41cea)