Beeminding number of webpages visited with Firefox

I want to beemind the number of webpages loaded with Firefox. My computer and phone are logged into my Firefox account so they’re all saved in history.

How can I beemind this? Is there any Firefox extension or integration I could use so beeminder gets the number of webpages I load each day?

1 Like

Ooh, @dannyobrien hacked up something to send this number from Firefox to Beeminder in 2012! No idea if this will work 7 years later but, well, here it is:

I realise I will never actually get around to improving the code below, which has my Firefox profile hardcoded and other horrors, but I thought it might still be useful for you as is an example. What I found interesting about the graph it plotted was the turquoise swath really did seem to reflect what I’d perceived about some heavy work I did, followed by some increasing recent goofing off.

def webvisits(startdate,enddate):
    magic = "select count(*) from moz_places, moz_historyvisits where moz_historyvisits.visit_date > %s*1000000 and moz_historyvisits.visit_date < %s*1000000 and moz_places.id = moz_historyvisits.place_id;" % (startdate, enddate)
    return subprocess.check_output(["/usr/bin/sqlite3", "/home/danny/.mozilla/firefox/123blahblah.default/places.sqlite", magic]).strip()

import datetime
import time

def main(args):
    today = datetime.date.today()
    for i in range(today.toordinal()-5, today.toordinal()+1):
        start = datetime.date.fromordinal(i)
        end = datetime.date.fromordinal(i+1)
        s_stamp = time.mktime((start.year, start.month, start.day, 0,0,0,0,0,0))
        e_stamp = time.mktime((end.year, end.month, end.day, 0,0,0,0,0,0))
        start_str = str(start).replace('-',' ')
        print start_str, webvisits(s_stamp, e_stamp)
1 Like

Wow thanks! Where does this code go? This is JavaScript right?

Oh, duh, it’s a GreaseMonkey script, right?
I’m still not understanding - where does it send info to beeminder? Looks like it just prints the info in the last line.

Seems like an easier way to go would be to just use the API to ping beeminder every time I load a page. Then I wouldn’t need to mess with SQLite, just have a greasemonkey script on my phone and laptop that autopings beeminder.

This works perfectly in GreaseMonkey:

// ==UserScript==
// @name     Beeminder
// @version  1
// @grant    GM.xmlHttpRequest
// ==/UserScript==

GM.xmlHttpRequest({
  method: "POST",
  url: "https://www.beeminder.com/api/v1/users/zedmango/goals/web/datapoints.json",
  data: "auth_token=myauthtoken&value=1",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded"
  }
});
1 Like

My new GreaseMonkey script! Since you can only enter 150 data points a day, I changed the script so it increments the datapoint for today if there already is one.

// ==UserScript==
// @name     Beeminder
// @version  1
// @grant    GM.xmlHttpRequest
// ==/UserScript==

// get most recent datapoint and send to update
GM.xmlHttpRequest({
  method: "GET",
  url: "https://www.beeminder.com/api/v1/users/zedmango/goals/web/datapoints.json?auth_token=myauthtoken",
  onload: function(response) {
    update(JSON.parse(response.responseText)[0]);
  }
});

// if it matches today's date, increment count by 1, otherwise add a new datapoint
function update(latest) {
  var today = new Date();
  var daystamp = latest.daystamp;
  var id = latest.id;
  var newValue = parseInt(latest.value) + 1;
  
  if (  parseInt(daystamp.substr(0,4)) == today.getFullYear()
     && parseInt(daystamp.substr(4,2)) == 1 + today.getMonth()
     && parseInt(daystamp.substr(6,2)) == today.getDate()
     ) {    
    GM.xmlHttpRequest({
      method: "PUT",
      url: "https://www.beeminder.com/api/v1/users/zedmango/goals/web/datapoints/" + id + ".json",
      data: "auth_token=myauthtoken&value=" + newValue.toString(),
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      }
    });
  }
  else {
    GM.xmlHttpRequest({
      method: "POST",
      url: "https://www.beeminder.com/api/v1/users/zedmango/goals/web/datapoints.json",
      data: "auth_token=myauthtoken&value=1",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      }
    });
  }
}
1 Like

Nice work!

1 Like