2/17/13

work here

I need to pay some people using the oDesk api. There is the custom payment api, but it requires an engagement, and all I have is a username.. so somehow I need to find an engagement from a username..

the engagements api let's me supply a provide reference. Let's try that..

hm.. I don't actually have provider references, I have usernames.. I could have saved their references, but I didn't. Hm.. I could make everyone log in again, and this time save their provider reference..

I guess we want "status=active"..

ok, it seems to work. But there may be more than one engagement, so I'll need to figure out which one I want. I know the team rooms that people were hired into, so I guess I'll find the engagement that is in one of those team rooms.

ok, here are some steps
1. add environment variables for PAYER, which will be me for now
2. store the token for the PAYER when they login (we'll need it to make API calls on their behalf)
3. from now on, when people login, store their ref
4. write a script to gather everyone's ref, by:
    - listing all the engagements for all the teamrooms I care about,
    - and matching these with people's usernames (which is listed in the engagement as provider__id)

let's add _.omit to u.js.. done

working on 1.. using _.omit to do an upsert: I have an object "user" with all the stuff for a user, including the _id. I want to find a user with that _.id, and if I fail, I want to set all the user's properties using { $set : user }, but I can't, because _id is in user, and mongodb doesn't want me to $set the _id, so I use { $set : _.omit(user, '_id') }.. now I should care about an error (whereas I didn't with insert, since an error probably meant that the user was already there).. oh yeah, and we want to grab the ref too.. ok, let's try logging in locally.. first, let's make sure a user for me is already there locally.. yup.. now let's try logging in and see if my information gets appropriately updated.. (and get another CD playing)..

ugg, it's caching an old page.. how to clear the cache? I wish there was just a button for that (or better yet, why doesn't refreshing the page clear it? I suppose it makes sense in some cases, but I don't think I would mind if refreshing always cleared the cache for the current page, because that's usually my goal when refreshing..).. ahh, Command-Shift-R (for mac)..

oops, it didn't set the token, because I forgot to do something with the PAYER environment variable..

ugg, it's still logged in.. how to clear cookies for the current page? ahh, I can delete them from the Resources tab in Chrome JavaScript debugger panel thing.

success. I got the tokens. I guess I've done 1, 2 and 3. Now on to 4. What should this script be called? It is a temporary thing I think, since in general, I'll be getting people's refs as they login, so I'll have those on hand in order to lookup their engagements. So maybe let's call this temp.js..

hm.. I notice that I'm still using an old technique in february-fire that I updated in nar-nar. I could update february-fire, but that would mean testing it. I think I'll leave it, and just do things the new way in new projects. Retroactive fixing is cumbersome, and projects will die eventually anyway.

ok, I got my user, now let's make an oDesk API call with the token.. success..

ok, first, I need to list all my teamrooms, to get the refs for the ones I care about.. I'll also want to store these for future reference when trying to get the correct engagement for someone, since it will need to be one of these rooms..

oops, node-odesk wants just 'team/v2/teamrooms', not 'api/team/v2/teamrooms'.

hm.. I have access to 13 team rooms.

(put on another CD)..

ok, I found the teamrooms I'm interested in. Now we want to get the engagement for each team..

hm.. node-odesk forces me to manually add query parameters for GET requests. I'd rather pass them in as an object, just like for POST requests. I think I'll change this in node-odesk and send them a pull-request.. and probably they'll reject it and make me feel stupid somehow, per usual..

..I guess the first step is to make the change locally (as in in the version inside my node_modules directory), and test it, then we can copy it into my forked version of node-odesk..

seems to work, let's put it in our fork and check it in.. ok, here's my commit.. and here's the pull request.  We'll see what comes of that.

ok, we were trying to list the engagements in a team. It's giving me back 10 engagements, but there are many more. It gives some pagination information:



"total_count": "990",
"total_items": "2",
"paging": {
    "offset": "0",
    "count": "10"
}


I assume there are 990 items.. but what does total_items=2 mean? Hm.. anyway.. let's see, how do we tell it to give us the next page.. (put on another CD.. maybe I should call them albums..)

hm.. I had this error: I had the code fs.writeFileSync('./_output.txt', blah), but I forgot to require 'fs', so that was undefined, but it didn't display the error :( — hm.. it seems like node's process.on('uncaughtException', function (err) {}) doesn't catch ReferenceError's..

hm.. ok, so here's what to expect when calling api/hr/v2/engagements under different conditions:
- if there are multiple engagements to return, then there will be an array in result.engagements.engagement.
- if there is just one engagement to return, then result.engagements.engagement will be it (it will not be inside an array)
- if there are no engagements to return, then result.engagements.engagement will not exist at all (it will not be an empty array)
I'm guessing the reason for this is that the oDesk API can return xml as well, and this is the way it converts xml stuff into json.

ok, I think I'll write a utility function for grabbing lists of stuff. I've had to do this before for getting offers, and I can see a similarity..

interesting.. need to concatenate multiple arrays together, and the fastest way seems to be  [].concat.apply([], arrays), which I believe because of some guys speed test..

great, it works.. I wonder if it is worth trying to add to node-odesk.. I'd need to convert it not to use fibers.. I think I'll do it if they accept my other pull request, otherwise not..

ok, let's get all the engagements.. we've gotten the ones for one team, but there are multiple teams to get..

well, I want to store that utility function somewhere while I wait for the node-odesk people.. maybe a gist.. maybe I'll just put it here.. it's not quite gist worthy (since it currently relies on my personal utility library)

function getAll(path, params) {
var kind = path.match(/([^\/]+)s(\?|$)/)[1]
var kinds = kind + 's'
if (!params) params = {}

var accum = []
var offset = 0
var pageSize = 100
var p = _.promiseErr()
while (true) {
params.page = offset + ';' + pageSize
o.get(path, params, p.set)
var a = p.get()[kinds]
var b = a[kind]
if (b) {
if (b instanceof Array)
accum.push(b)
else
accum.push([b])
}
offset += pageSize
if (offset >= a.lister.total_count)
break
}
return [].concat.apply([], accum)
}

ok, I have all the engagements.. I guess what I want to do now is iterate through each user in the database, find the engagement for their username, and store their ref back in the database (ultimately we'll be getting their engagement from the ref, and at that time, we'll probably cache the engagement reference too, but I want to make sure that code works, so I won't do it here, even though I'll have the engagement refs.. though.. I probably won't normally have so many to do at once.. maybe.. well, it will be in at least an hour long cron job, and I think it can finish inside of an hour, so that's fine)..

hm.. I want _.find.. need to add it to u.js.. done..

ok, I updated everyone's ref.

though, there were about 7 people that I couldn't find an engagement for.. I should ask about these people.. ok, it looks like I know who 5 of them are (2 of them are my test accounts), so I just need to ask about 2.. and between those 2 people, they've only answered 1 question, so it may not be a big deal.

so now I need to write a script for paying people.

let's think about that..


No comments:

Post a Comment