Beeminder Forum

Beeminding number of webpages visited with Firefox


#1

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?


#2

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)

#3

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


#4

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.


#5

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.


#6

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"
  }
});

#7

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"
      }
    });
  }
}

#8

Nice work!