Friday, August 3, 2012

JSON to Google Docs for Trello

I want to have all Trello data into a Google Docs sheet.
So I wrote this (and with copying snippets from here and there):


// Arnold P. Siboro
// August 2012

   
function myFunction() {
  //blabla
  throw 'Congratulations, you have successfully installed XXX ';
}
function onOpen() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = sheet.getLastRow();
  //sheet.setActiveCell()
 
  //var object = getJSONdata();
  var object = getTrelloJSONdata();
 
  sheet.clear();

 
  for (var i=0; i    sheet.getRange(i+1,1).setValue(object.cards[i].name);
    sheet.getRange(i+1,2).setValue(object.cards[i].desc);
    //throw object.checklists.length;

  checklists="";
  checkItems="";
    for (var j=0; j     
      //throw object.cards[i].idChecklists.length;
      for (var k=0; k     
        if(object.checklists[j].id==object.cards[i].idChecklists[k]) {
          //throw object.checklists[j].name+" "+object.checklists[j].id+" "+object.cards[i].idChecklists[k];
          checklists=checklists + "["+object.checklists[j].name +"]\n";
          //throw checklists;
          //throw object.checklists[j].checkItems.length;
          for (var l=0; l            checklists=checklists+(l+1)+") "+object.checklists[j].checkItems[l].name+"\n";
          }
          checklists=checklists+"\n";
        }
      }
      //throw checklists;
    }
    sheet.getRange(i+1,3).setValue(checklists);
    //throw object.lists.length;
   
    lists="";
    for (var j=0; j      if(object.lists[j].id==object.cards[i].idList) {
        lists=lists + object.lists[j].name + "\n";
        //throw lists;
      }
      //throw lists;
    }
    sheet.getRange(i+1,4).setValue(lists);

    actions="";
    for (var j=0; j      if(object.actions[j].data.card)
        if(object.actions[j].data.card.idShort==object.cards[i].idShort) {
          if(object.actions[j].type="commentCard" && object.actions[j].data.text) actions=actions + object.actions[j].data.text + "\n";
        //throw actions;
        }
      //throw actions;
    }
    sheet.getRange(i+1,5).setValue(actions);
   
  }
 //throw object.cards.toSource();
 //throw object.cards.length;

}

//not used now, as this does not handle login into Trello
function getJSONdata() {
  var url = SERVER_BASE_URL
  var payload = "";
  var response = UrlFetchApp.fetch(url, {method:'get', payload:payload, contentType:"application/x-www-form-urlencoded"});
  if (response.getResponseCode() == 200) {
    return JSON.parse(response.getContentText());
   
  }
}
function getTrelloJSONdata() {
  //Use OAuth and Trello's API to automatically login

     
    var oauthConfig = UrlFetchApp.addOAuthService("trello");
  oauthConfig.setAccessTokenUrl("https://trello.com/1/OAuthGetAccessToken");
  oauthConfig.setRequestTokenUrl("https://trello.com/1/OAuthGetRequestToken");
  oauthConfig.setAuthorizationUrl("https://trello.com/1/OAuthAuthorizeToken");
  // Replace these with the values you get from
  // https://trello.com/1/appKey/generate
  oauthConfig.setConsumerKey("");
  oauthConfig.setConsumerSecret("");
  var requestData = {
    "method": "GET",
    "oAuthServiceName": "trello",
    "oAuthUseToken": "always"
  };
  /*
  var result = UrlFetchApp.fetch(
      "https://api.trello.com/1/members/me/boards",
      requestData);
  */
 
  //And then get the whole JSON data
   var result = UrlFetchApp.fetch(
  "https://api.trello.com/1/boards/?actions=all&actions_limit=1000&cards=all&lists=all&members=all&member_fields=all&checklists=all&fields=all",
      requestData);
 
  //throw result.getContentText();
  return JSON.parse(result.getContentText());
}

function authorizeToTrello() {
  var oauthConfig = UrlFetchApp.addOAuthService("trello");
  oauthConfig.setAccessTokenUrl("https://trello.com/1/OAuthGetAccessToken");
  oauthConfig.setRequestTokenUrl("https://trello.com/1/OAuthGetRequestToken");
  oauthConfig.setAuthorizationUrl("https://trello.com/1/OAuthAuthorizeToken");
  // Replace these with the values you get from
  // https://trello.com/1/appKey/generate
  oauthConfig.setConsumerKey("");
  oauthConfig.setConsumerSecret("");
  var requestData = {
    "method": "GET",
    "oAuthServiceName": "trello",
    "oAuthUseToken": "always"
  };
  var result = UrlFetchApp.fetch(
      "https://api.trello.com/1/members/me/boards",
      requestData);
  Logger.log(result.getContentText());
}

Tuesday, June 12, 2012

Cloud backup solution

Google Drive is released. So which is best, Google Drive, Dropbox, SkyDrive, etc? As I previously wrote, my interest is in having a backup solution that exactly backups files from Mac, including its data forks, extra attributes, finder flags etc.
So, it's time to take bbouncer out of the shelf again. Google Drive is said to be not preserving all of the above nooks and crannies of Mac file system, so I tried with Dropbox first, which was mentiond on Google searchland as faithful to Mac file system. I mounted the Dropbox drive (actually it is not a drive, just a directory), and then ran the following command to copy bbouncer's test files:

sudo rsync -aNHAXxvuPE --fileflags --protect-args --force-change  /Volumes/Src/   /Users/asiboro/Downloads/Dst

I then ran bbouncer to do the test:

./bbouncer verify -d /Volumes/Src/ ~asiboro/Downloads/Dst/

The result is as follows:

Verifying:    basic-permissions ... ok (Critical)
Verifying:           timestamps ... ok (Critical)
Verifying:             symlinks ... ok (Critical)
Verifying:    symlink-ownership ... ok
Verifying:            hardlinks ... ok (Important)
Verifying:       resource-forks ...
grep: ./some-file/rsrc: Not a directory
   Sub-test:             on files ... FAIL (Critical)
cmp: ./hl-rfork1/rsrc: Not a directory
   Sub-test:  on hardlinked files ... FAIL (Important)
Verifying:         finder-flags ... ok (Critical)
Verifying:         finder-locks ... ok
Verifying:        creation-date ... ok
Verifying:            bsd-flags ... ok
Verifying:       extended-attrs ...
   Sub-test:             on files ... ok (Important)
   Sub-test:       on directories ... ok (Important)
   Sub-test:          on symlinks ... ok
Verifying: access-control-lists ...
   Sub-test:             on files ... ok (Important)
   Sub-test:              on dirs ... ok (Important)
Verifying:                 fifo ... ok
Verifying:              devices ... ok
Verifying:          combo-tests ...
   Sub-test:  xattrs + rsrc forks ... ok
   Sub-test:     lots of metadata ... ok 
Ouch.. resource fork related test failed.
I tried copying not to Dropbox but regular directory on disk, the result is the same. OK, something fishy here. After some searching, I found out that the resource fork is there, only that it is not on /rsrc but /..namedfork/rsrc. I am running Mac OS X Lion, and it seems that /rsrc is deprecated and it won't work anymore.

So, I edited test.d/30-resource-forks.test from bbouncer distribution and change all /rsrc to /..namedfork/rsrc, ran the test again and now here is the result:

Verifying:    basic-permissions ... ok (Critical)
Verifying:           timestamps ... ok (Critical)
Verifying:             symlinks ... ok (Critical)
Verifying:    symlink-ownership ... ok 
Verifying:            hardlinks ... ok (Important)
Verifying:       resource-forks ... 
   Sub-test:             on files ... ok (Critical)
   Sub-test:  on hardlinked filez ... ok (Important)
Verifying:         finder-flags ... ok (Critical)
Verifying:         finder-locks ... ok 
Verifying:        creation-date ... ok 
Verifying:            bsd-flags ... ok 
Verifying:       extended-attrs ... 
   Sub-test:             on files ... ok (Important)
   Sub-test:       on directories ... ok (Important)
   Sub-test:          on symlinks ... ok 
Verifying: access-control-lists ... 
   Sub-test:             on files ... ok (Important)
   Sub-test:              on dirs ... ok (Important)
Verifying:                 fifo ... ok 
Verifying:              devices ... ok 
Verifying:          combo-tests ... 
   Sub-test:  xattrs + rsrc forks ... ok 
   Sub-test:     lots of metadata ... ok 

Cool.

But not yet. I just realized that I was just running the test against Dropbox directory on this Mac. It's not a volume, so it is probably just like any regular directory except that Dropbox is syncing it with the server...

Sunday, April 1, 2012

In search of RARP server for MacOS

OK, I did not actually find a working RARP server solution on MacOS X, but I found a solution for setting that Yamaha RTX. It turned out that it does not have an IPv4 by default, but it has an IPv6 by default.

Connect the Mac directly to Yamaha RTX, make sure IPv6 is enabled on the Mac. Then from terminal:

netstat -nr

You will get a IPv6 section like this:


Internet6:
Destination                             Gateway                         Flags         Netif Expire
::1                                     ::1                             UH              lo0
fe80::%lo0/64                           fe80::1%lo0                     Uc              lo0
fe80::1%lo0                             link#1                          UHL             lo0
fe80::2a0:deff:fe32:234d%en0            0:a0:de:32:23:4d                UHL             en0
fe80::ca2a:14ff:fe0f:4f25%en0           c8:2a:14:f:4f:25                UHL             lo0
ff01::/32                               ::1                             Um              lo0
ff02::/32                               ::1                             UmC             lo0
ff02::/32                               link#4                          UmC             en0

"0:a0:de:32:23:4d" is the MAC address of the Yamaha RTX, so just telnet to fe80::2a0:deff:fe32:234d%en0

telnet -6 fe80::2a0:deff:fe30:344d%en0

I am relieved I can do away with that rarpd.exe and Windows 2000!

But rarpd on Mac is still a mystery to be solved. On Ubuntu and CentOS it seems to work out of the box.

UPDATE
I forgot why I wrote the above, because it... did not work? I just found out Yamaha RTX's IPv6 address by first pinging to multicast address and see response from an IPv6 address other than the ones belong to my host (check the host's interfaces via the OS, or do "netstat -nr" and see the result, as follows:


ping6 -I en1 ff02::2
PING6(56=40+8+8 bytes) fe80::e2f8:47ff:fe12:d56c%en1 --> ff02::2
16 bytes from fe80::225:dcff:fe14:5a26%en1, icmp_seq=0 hlim=64 time=10.231 ms
^C
--- ff02::2 ping6 statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 10.231/10.231/10.231/0.000 ms



Monday, March 26, 2012

In search of RARP server on MacOS

Reverse ARP server seems to be scarce. There is one on Windows, but old, so far I could only run it on Windows 2000. At a glance, it's pretty easy on MacOS, since rarpd is installed by default. However, how to make it actually reply to reverse arp request is tricky. I could not find hands-on info on the net, only rarpd man page which gives very little info on how to actually use it. One hands-on info I found was for an old version of MacOS, while I am on Snow Leopard, where access to NetInfo has been changed to using dscl instead of nicl.

 I then tried this dscl version of the above hands-on guide:
mkdir -p /private/tftpboot) ln -s /private/tftpboot /tftpboot vi /etc/ethers #/etc/ethers 00:A0:DE:30:34:4D client sudo dscl Entering interactive mode... (type "help" for commands) > -create /Local/Default/Hosts/XX:XX:XX:XX:XX:XX 12.34.56.78 > sudo /usr/sbin/rarpd -d en0 en0: c8:2a:14:d:a3:86
But it kept just saying "rarpd: got a packet" but replied not.

 I tried various things in order to fulfill the vague requirements set on rarpd manual:
Rarpd services Reverse ARP requests on the Ethernet connected to interface. Upon receiving a request, rarpd maps the target hardware address to an IP address via its name, which must be present in both the ethers(5) and hosts(5) databases. If a host does not exist in both databases, the translation cannot proceed and a reply will not be sent. Additionally, a request is honored only if the server (i.e., the host that rarpd is running on) can "boot" the target; that is, if the directory /tftpboot/ipaddr exists, where is the target IP address. In normal operation, rarpd forks a copy of itself and runs in the background. Anomalies and errors are reported via syslog(3).
I.e.,
1) IP address and its name must be present in ethers database
2) IP address and its name must be present in hosts database
3) the directory /tftpboot/ipaddr exists, where is the target IP address But to no avail. I gave up, got a Windows 2000 to run rarpd instead :(

Monday, January 2, 2012

armv6 missing said Application Loader

When loading an iOS app built with Xcode4 to iTunes using Application Loader, it balked: "application executable is missing a required architecture. At least one of the following architecture(s) must be present: armv6" In "Architectures" change from just "$(ARCHS_STANDARD_32_BIT)" to "armv6 $(ARCHS_STANDARD_32_BIT)". Then add to info.plist file the following: UIRequiredDeviceCapabilities armv7 Make sure in "Supported Platforms" the distribution does not contain "iphonesimulator". Make sure also that "Build Active Architectures Only" is deselected for distribution.