Skip to content

Commit

Permalink
"Added two new api services for team goals and team information. Clea…
Browse files Browse the repository at this point in the history
…ned up general code. Allowed PORT to be set when running the api service"
  • Loading branch information
ammuench committed Sep 14, 2015
1 parent 2f15eba commit 964ae60
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 27 deletions.
105 changes: 93 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,68 @@
# extra-life-api
A simple API based on Express and Cheerio for showing donations, goals, and team from Extra-Life.org
Now up on NPM : https://www.npmjs.com/package/extra-life-api
A simple API layer based on Express and Cheerio for showing donations, goals, and team info from Extra-Life.org

Why?
------
I've ran a custom website for our Extra Life team last year, and we had a ton of success with it (we raised over $1700 dollars)! However, one of the most difficult things was constantly updating donations and other info while we were doing it (which started to fall apart once we hit th 20 hour mark or so). As a result, I decided to make a web scraper that does the job for you!!
[I ran a custom website for our Extra Life team last year](http://alexmuench.net/extralife), and we had a ton of success with it (we raised over $1700 dollars)! However, one of the most difficult things was constantly updating donations and other info while we were doing it (which started to fall apart once we hit th 20 hour mark or so). As a result, I decided to make a web scraper that does the job for you!!

Installation
------
Either locally or on a web-sever, either clone this package, or install from npm with:
```javascript
You can manually install this by cloning this github repo
```bash
https://github.com/ammuench/extra-life-api.git
```
then running
```bash
npm install
```
from within the project folder.

You can install through NPM by running
```bash
npm install extra-life-api
```

Once downloaded, move to the base module folder and simply run:

```javascript
```bash
node server
```
And you're good to go! The app should default to port 8081.
And you're good to go! The app should default to port 8081. If you wish to run on a different port, you can specify it while starting the service

```bash
PORT=1234 node server
```

If you want to run this as a constant process on your webserver, I suggest looking into [ForeverJs](https://github.com/foreverjs/forever)

Configuration
------
By default the service will accept all incoming requests. If you wish to restrict this, you can go to line 7 of server.js and edit the following:

```javascript
app.all('*', function(req, res, next){
if (!req.get('Origin')) return next();
// use "*" here to accept any origin
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS');
res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Authentication, AdminAccess');
if ('OPTIONS' == req.method) return res.send(200);
next();
});
```
to change your server restrictions and whatnot

API
------
There are 3 endpoints which can be accessed once the express server is up and running. Each endpoint must be passed the individual's 'Participant ID'. This can be found by going to your public page, and checking the end of the URL:
There are 3 endpoints which can be accessed once the express server is up and running. Each endpoint must be passed the individual's 'Participant ID' or a team's 'Team ID'. These can be found by going to your personal profile page or team profile page, and checking the end of the URL:

**Participant ID**

extra-life.org/index.cfm?fuseaction=donordrive.participant&participantID=**[PARTICIPANT ID HERE]**

http://www.extra-life.org/index.cfm?fuseaction=donordrive.participant&participantID= **ID HERE**
**Team ID**

extra-life.org/index.cfm?fuseaction=donorDrive.team&teamID=**[TEAM ID HERE]**


* **/usergoals/[userid]**
Expand All @@ -50,7 +86,8 @@ http://www.extra-life.org/index.cfm?fuseaction=donordrive.participant&participan
"image":"",
"donateURL":"",
"team":"",
"teamURL":""
"teamURL":"",
"profleURL": ""
}
```

Expand All @@ -77,12 +114,56 @@ http://www.extra-life.org/index.cfm?fuseaction=donordrive.participant&participan
]
}
```
* **/teamgoal/[teamid]**
* Provides a json object with information about a team's donation goals and current status
* Returns the response:
```javascript
{
"goal": 2000,
"raised": 0
}
```
* **/teaminfo/[teamid]**
* Provides a json object with a basic team information and an array of all current team members. Each team member object has their name, amount raised, profile URL, profile ID, and image URL
* Returns the response:
```javascript
{
"name": "",
"teamURL": "",
"teamImage": "",
"members": [
{
"name": "",
"raised": "",
"URL": "",
"pID": "",
"image": ""
},{
"name": "",
"raised": "",
"URL": "",
"pID": "",
"image": ""
},{
"name": "",
"raised": "",
"URL": "",
"pID": "",
"image": ""
}
]
}
```
License
------
This content is released under the [MIT License](https://opensource.org/licenses/MIT)
Shamless Plug
------
If you like this work, donate to my Extra Life page at:
http://www.extra-life.org/index.cfm?fuseaction=donordrive.participant&participantID=144846
If you like this work, you can [donate to my Extra Life page here](http://www.extra-life.org/index.cfm?fuseaction=donordrive.participant&participantID=144846).
Also, if you'd like to see our custom Extra-Life Campaign page (which uses this middleware as our API service!), [please check us out here](http://alexmuench.net/extralife)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "extra-life-api",
"version": "0.1.5",
"version": "0.2.0",
"description": "Fetch donation goals and info from Extra Life profiles!",
"main": "server.js",
"author": "Alex Muench",
Expand Down
101 changes: 87 additions & 14 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,19 @@ app.get('/usergoal/:id', function(req, res){
setKey('goal', goal);
res.send(userGoalsJson)
}else{
console.log('Error parsing goal URL');
console.log('Error parsing userGoal URL');
res.send({status: 500, message: "There was an error trying to make your request"});
}
});
});

app.get('/userinfo/:id', function(req, res){
var userInfoJson = { name : "", image : "", donateURL: "", team: "", teamURL: ""};

var profileId = req.params.id;

var profileUrl = 'http://www.extra-life.org/index.cfm?fuseaction=donordrive.participant&participantID=' + profileId;

var userInfoJson = { name : "", image : "", donateURL: "", team: "", teamURL: "", profileURL: profileUrl};

request(profileUrl, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
Expand All @@ -59,27 +60,24 @@ app.get('/userinfo/:id', function(req, res){


$('#participant-name').filter(function(){
var data = $(this);

name = data.children('h1').text();
name = $(this).children('h1').text();

userInfoJson.name = name;

});

$('.avatar').filter(function(){
var data = $(this);

image = data.children('img.profile-img').attr('src');
image = $(this).children('img.profile-img').attr('src');

userInfoJson.image = image;

});

$('.btn-support-card').filter(function(){
var data = $(this);

donateURL = data.attr('href');
donateURL = $(this).attr('href');

userInfoJson.donateURL = donateURL;

Expand All @@ -98,7 +96,7 @@ app.get('/userinfo/:id', function(req, res){

res.send(userInfoJson);
}else{
console.log('Error parsing profile URL');
console.log('Error parsing userInfo URL');
}

});
Expand All @@ -118,7 +116,7 @@ app.get('/recentDonations/:id', function(req, res){
$('.donor-detail').each(function(i, elem){
var data = $(this);
var donorObj ={};
donorObj.name = data.children('strong').text().split(' made')[0];
donorObj.name = data.children('strong').text();
donorObj.name = donorObj.name.replace(/(\r\n\t|\n|\r|\t)/gm,"");
donorObj.date = data.children('small').text();
donorObj.date = donorObj.date.replace(/(\r\n\t|\n|\r|\t)/gm,"");
Expand All @@ -132,11 +130,86 @@ app.get('/recentDonations/:id', function(req, res){

res.send(userDonationsJson);
}else{
console.log('Error parsing goal URL');
console.log('Error parsing recentDonations URL');
res.send({status: 500, message: "There was an error trying to make your request"});
}
});
});

app.listen('8081')
console.log('Magic happens on port 8081');
app.get('/teamgoal/:id', function(req, res){
var teamGoalsJson = { goal : "", raised : ""};

var setKey = function(key, value){
teamGoalsJson[key.toString()] = value;
// console.log(key + ': ' + teamGoalsJson[key.toString()]);
// console.log('set key value');
}

var teamId = req.params.id;

var teamGoalUrl = 'http://www.extra-life.org/index.cfm?fuseaction=widgets.ajaxWidgetCompileHTML&callback=jsonpCallback&language=en&teamid0=' + teamId + '&eventid0=525&type0=thermometer&currencyformat0=none&orientation0=horizontal';

request(teamGoalUrl, function(error, response){
if(!error){
var test = response.body.toString().split('jsonpCallback(')[1].split('}});')[0]
var raised = test.split('dd-thermo-raised')[1].split('<')[0].split(',').join('');
raised = parseInt(raised.split('$')[1].split('\\')[0]);
// console.log(raised);
setKey('raised', raised);
var goal = test.split('Goal: </span>')[1].split('</strong')[0];
goal = parseInt(goal.split('$')[1].split('\\')[0].split(',').join(''));
setKey('goal', goal);
res.send(teamGoalsJson)
}else{
console.log('Error parsing teamGoal URL');
res.send({status: 500, message: "There was an error trying to make your request"});
}
});
});

app.get('/teaminfo/:id', function(req, res){

var teamInfoId = req.params.id;

var teamInfoUrl = 'http://www.extra-life.org/index.cfm?fuseaction=donordrive.teamParticipants&teamID=' + teamInfoId;

var teamInfoJson = {name: "", teamURL: teamInfoUrl, teamImage: "", members:[]};

request(teamInfoUrl, function(error, response, html){
if(!error){
var $ = cheerio.load(html);

$('#team tbody tr').each(function(i, elem){
var data = $(this).children('td').children('a');
var memberObj ={name:"", raised: "", URL: "", pID: "", image: ""};
memberObj.name = data.children('span').children('strong.block').text();
memberObj.name = memberObj.name.replace(/(\r\n\t|\n|\r|\t)/gm,"");
memberObj.raised = data.children('span').children('.gray').children('small:first-child').children('strong').text();
var memberURL = data.attr('href');
memberObj.URL = memberURL;
memberObj.pID = memberURL.split('participantID=')[1];
memberObj.image = 'http:' + data.children('span').children('.member-avatar').attr('src');
teamInfoJson.members.push(memberObj);
});

$('#team-name').filter(function(){
teamInfoJson.name = $(this).children('h1').text();
})

$('.profile-img').filter(function(){
teamInfoJson.teamImage = 'http:' + $(this).attr('src');
})

res.send(teamInfoJson);
}else{
console.log('Error parsing teamInfo URL');
res.send({status: 500, message: "There was an error trying to make your request"});
}
});
});

var port = process.env.PORT || 8081;

app.listen(port);
console.log('Extra-Life API running on port ' + port);
exports = module.exports = app;

0 comments on commit 964ae60

Please sign in to comment.