mudkip
Work experience includes founding a startup, reverse-engineering IoT hardware and most social networking sites, building my own home automation system (akin to home assistant), being a graphic designer, cryptocurrency hardware consultant (and interim project manager / product owner), discovering 0 days for at least one FAANG, and putting DOOM on a microwave. https://tylerfreedman.com/sociallink/ and https://tylerfreedman.com/hindsight/ are good examples of the (personal) work I've done that covers most bases.
Location: Toronto, Ontario, Canada
Remote: Yes, as well as hybrid
Willing to relocate: Maybe
Technologies: Ruby on Rails, PostgreSQL, etc
Résumé/CV: https://tylerfreedman.com/resume
Email: mail @ ^
In comparison, the Venta requires almost zero maintenance, and the entire machine is basically indestructible. The electronics pop out if you press the two buttons on top, which means you can hose the entire thing down in a bathtub if you want. You could probably put the whole thing in the dishwasher if you really wanted to, but I haven't tried that myself.
I tried Parsec on one machine and was super disappointed. Video quality and latency were fine, but audio sounded like crap, despite streaming at 512kbps. Since there's no option to stream uncompressed audio, and no debug options to figure out why it sounded so terrible, I had to write off their entire product as unusable.
I did end up trying Parsec, since I saw some people recommending it, and that was terrible. Latency was fine (~10ms software <-> software) and video quality was alright, but audio quality was terrible despite being set to the highest option - which is especially bad, because there's no option to send uncompressed audio, and whatever "optimization work" they were doing to reduce bandwidth made their entire product unusable, despite the fact that there's no need to try saving 1mbps over a wired LAN.
As for the less technical people, they tend to be significantly more annoyed at Facebook when I tell them that their old comment threads / messages are likely incoherent junk.
The ideal solution to comment threads would be to replace the usernames of people who simply delete their account with [deleted], but keep the content unless someone explicitly overwrites it. The biggest issue isn't that the content is gone (any given comment), but that nobody knows how many things are missing. It would be much better (with no loss in privacy) to at minimum just replace those comments with null text and a null owner, to at least show that 3 rows used to be here, between these existing rows.
To be clear, if I want to create the equivalent of a data-hoarder bunker, I don't think there's anything wrong with that. I do, however, agree that sharing things with people that couldn't see it themselves (expanding the original audience) isn't something anyone should ever do. I'd also like to point out that once someone removes something from Facebook (or any other service, for that matter), the authenticity of copies of that information is now debatable - I could scrape a bunch of stuff and show people, but you have no way of proving whether or not that information is authentic. For all you know, my script makes any posts%5 super racist.
The code is currently in two repositories - the first is a generic runtime I wrote that provides certain subsystems to a bunch of unrelated plugins (a small percentage of the total number of plugins relate to social networking), so I would either need to open source that repository as well, or port those plugins to something else. While I legally own the code for the first repository, it currently forms the basis of a company I founded (the social network plugins were written as a joke for personal reasons, and have no business use case - it was just easier to do this way), so I'd rather not release that just yet. I'd either need to replace the calls in those plugins (not too difficult, just annoying), or release those plugins without patching those calls with a disclaimer saying something like "drop replacement scheduling service here". Almost all of the runtime calls used by the social networking plugins are basically just for scheduling how frequently they should re-scrape things, and use almost none of the other features.
The second repository is in charge of actually viewing/browsing the data, and doesn't concern itself with repeatedly obtaining it. This repository will likely be open sourced soon, once I make the UI nicer and fix some bugs. It also contains some 'one and done' import code, for loading in data from things that just need to run once (importing from legacy chat systems, like Hangouts, Windows Phone's SMS DB, Adium, Pidgin, and a few IRC clients I no longer use anymore).
As for the social networking plugins in the first repo, these fall into one of two categories: the first are "things that access legitimate APIs, or otherwise just grab public data (e.g. YouTube)". The second category, which is mostly just Facebook, is "this logs in as you with your username/password and downloads a bunch of shit by actively impersonating you". The first category isn't really encumbered in any way, only the second one is.
In the case of Facebook, there's a few specific issues that I have to deal with. The first is that there's a bunch of exploits that it uses in order to scrape everything, and they could theoretically be patched if someone at Facebook sees what I'm doing (which is also partially why I'm not using my real name here). The second is that some of the code may or may not be correct - I've had situations while developing it where I made a basic assumption that turned out to be wrong (like objects having one primary key, comments only going two layers deep, or guessing the wrong author of a post by the username in the URL). Since this is mostly guesswork, I occasionally have to mark a bunch of rows as 'untrusted', and invalidate them if I find that an assumption I made turns out to be very wrong. This has happened a few times, and it wouldn't be nice to tell people that their DB dumps have a bunch of errors and they should just throw it all away. Scraping is hugely problematic if you don't fully understand what you're grabbing (as an example, if you just download the HTML for a given page, you can't necessarily grab the images later as all the URLs have expiry tokens in them, so the HTML scraper also needs to be aware of photos). There are certain object types that I haven't fully figured out how to decode, and I don't want to have tons of people constantly re-indexing the same URLs over and over again because some code I wrote is buggy.
[0] One hilarious side effect of replacing the object's ownership is that technically, all of the messages Alice received wishing her "Happy Birthday" appear to be written by herself. You have to find the additional TAO edges to reconstruct the true post author.
Part 1:
A couple years ago, I noticed that the number of photos I was tagged in kept going up and down, as a couple of people I knew would disable their accounts occasionally, and re-enable them a couple weeks later.
I manually the images from them, but wanted a way to automatically scrape any images I was tagged in, so I wouldn't need to do this manually.
I got myself a Facebook Graph API key and created a sample app with full account permissions, only to discover that Facebook won't let you export photos you're tagged in (that you didn't take). The numbers the API reports are wrong, and there's no indication that it's being purposely redacted.
As a result, I wrote a tool that crawls a profile given a set of authenticated cookies, and essentially clicks the download link automatically on every photo. This worked decently well for a couple years, and continues to work to this day.
Part 2:
I had some spare time on my hands in December 2019, and wanted to write a tool to browse chat logs from across a variety of services (Facebook Chat, Hangouts, SMS), such that you'd be able to click a name and see a chronological discussion, regardless of what service it was on. I downloaded the Facebook data dump, figuring that was the easiest way to get access to my Messenger data.
The Messenger dump revealed a few things that surprised me: * The character encoding is messed up, and requires decoding as Latin1, then re-encoding as UTF-8
* Some messages are straight up missing, despite being in the UI. The dump is supposed to include attachments (images are included), but is missing audio messages / voice snippets, presumably among others.
* If a user has deleted their Facebook account, the username will appear solely as 'Facebook User', so now you need to figure out who you were actually talking to. Some conversations were very obvious, but others involved wasting a ton of time on and involved dumb techniques (like finding Adium logs of the same chat from an old computer).
To identify certain conversations, I started scrolling back through certain Facebook posts (which I wrote), to figure out who had been at certain events with me (to narrow things down). I read a bunch of comment threads that didn't appear to make much sense to me, until I realized that anyone who deletes their account also has their comments removed, so basically all old comment threads are somewhat nonsensical if anyone in the conversation has since deleted their account. For comparison, deleting a reddit account changes the ownership of a comment/post to [deleted], which seems much more appropriate.
Presumably wall posts (including happy birthday messages) from people who have since deleted their accounts are also removed, which is exceedingly shitty - if someone sends you a greeting card and then dies several years later, it's not like the post office comes to your house to take your cards back in the middle of the night.
Part 3:
Because of this, I figured that the only way to mitigate future data loss on Facebook is to consistently archive things. Since the 'download your data' tool is basically useless, I started work on a tool that scrapes the site and "decompiles" pages into raw directed graph DB rows, which can be re-rendered into a new version of the site. It features a reasonably complete implementation of Facebook's TAO (https://www.facebook.com/notes/facebook-engineering/tao-the-...) on top of PostgreSQL, and works decently well - notably, it also maintains things like proper links to profiles and stores all assets offline.
Writing a bug-compatible "decompiler"/"recompiler" taught me several things about how the site works (or rather, doesn't). Here's a small list of errata I've discovered along the way:
* Objects can have multiple FBIDs
* FBIDs can contain comments/reactions
* Since there may exist multiple FBIDs for a given object, it's quite common for multiple comment threads to exist for a given item, such that commenters on one don't see the responses on the other (and vice versa). Several of my friends have confirmed finding disjointed discussions on their posts after discovering this bug.
* Facebook has several types of deprecated reactions that they store in the DB, which cannot traditionally be viewed from the site anymore. Sucks to be you if you reacted to something that way.
* Certain objects can get lost in their UI, with no easy way to find them. Uploading a photo in a post will put it in your Timeline Photos album, but uploading a photo as a comment to someone else's post will basically make it impossible to find again.
* The number of reactions/comments on a given post is often wrong - this isn't the traditional bug due to eventual consistency, but rather is due to not adjusting the counts for items when a person deletes their account. To a certain degree, this will show you how many people that interacted on something have departed the site.