-
- Chat.
- tawk.to is the chat app for live chat (talk to users on your site, like “need help with x?”). It’s free.
- minnit.chat is the chat app for group chat (users talking to each other). It’s also free, for max 40 simultaneous users. https://minnit.chat/. Created a room, played around with it – I liked it a lot.
- Tried chatcamp.io as well. Their website was pretty bad. Broken register link, bad UX on the dashboard, poor documentation.
- The problem with these group chat embeds: they force user accounts on THEIR platform. I couldn’t find a single app that allowed you to simply forward the user accounts that you already have on your site. It’s honestly as simple as a single unique key; even email would work just fine. You just need a string to display in the chatroom. I understand the design though. They want user traffic on their own platform, they don’t just want you to use them for storage space and chat functionality.
- Closed the ticket as won’t-fix: https://gitlab.com/bmahlstedt-group/supercontest/issues/22.
- I’m not sure if GitLab issues have a resolution field.
- I love that GitLab correctly calls them Merge Requests instead of Pull Requests, but they went with the legacy “Issues” instead of “Tickets” which I’m less happy about.
- Went through the tough mudder pics from our event and collected the ones with us. About 3 for each, at 3 separate obstacles. Uploading your photo and having them find your pics is easier than searching yourself.
- Supercontest.
- Closed the user league creation ticket. https://gitlab.com/bmahlstedt-group/supercontest/issues/67. Will reopen later if need be.
- Closed the final “Long Term” milestone.
- Last remaining ticket: stripe. I do wanna play with this one. https://gitlab.com/bmahlstedt-group/supercontest/issues/29.
- Tried customizing the navbar for flask-admin. Copying the templates over isn’t perfect because then you can’t upgrade the pkg. In addition, they have a full html template, you can’t extend your own header, so that’s not ideal. This was the same with graphiql; I’m surprised. It’s not hard, I guess they just don’t expect you to embed such a full page as a subset of another page. I guess you could just use an iframe.
- Neither graphql or flask-admin were designed for iframe embed. I’d have to subclass some of the internals to reroute some templates, and again, I’d be making it more of a pain to upgrade than anything else. It’s fine as-is; getting my banner on top is not worth it.
- Turned autocomplete=”off” on the feedback form so the “petty’s mom” surprise wouldn’t be shown before you type, if you’d already done it at any point in history.
- Went ahead and added the convenient late pick form in the admin view. It tells you the week and season, you pick the user and teams from dropdowns, then it commits and emails them. Nice.
- Closed the ticket: https://gitlab.com/bmahlstedt-group/supercontest/issues/118.
- Added Petty to admin.
- Started playing with stripe. Submitted application to activate the account (business info basically).
- They have Stripe Atlas, which is a pretty cool service that helps you form a C Corp, generate the docs, get a tax ID number, etc.
- Used the wizard to start the “Checkout” tutorial. Accepting one time payments, from an https website, etc.
- Got the TNF patriots pick correct. +17. Nobody picked the giants.
- NE defense has the 2nd most points out of any offensive player (only McCaffrey higher) and they have the 10th most for avg/week
- PPV.
- As of Oct 18 (1 year ago), Mayweather Pacquiao is the best selling PPV of all time: 4.6m buys.
- Mayweather McGregor is 2nd at 4.3m buys.
- Khabib McGregor is 3rd at 2.5m buys. They drop off pretty quick.
- Amazing UFC teaser commentary: https://www.youtube.com/watch?v=X7WywdwqK3o.
- Steve kerr reaction to trump calling him a little boy about china dodging: https://streamable.com/8saxb.
- Good summary by Buffett: https://www.youtube.com/watch?v=vl2aP8dlIn4. Human investing makes sense. People get pumped, and you get huge bull markets for short times, then they stay stagnant for years because they’re looking in the rear view mirror, doubting it will continue so gold.
- Now that the gigantic majority of trading is ML, this will change. Sure, you’ll have explosions like crypto, but the general trend is more programmatic.
- In basketball, true shooting percentage (TS%) weighs free throws lower and 3-pointers higher, so it’s a more balanced metric for measuring your shooting efficiency than field goal percentage (FG%). You’re penalized less for missing a 3 because it’s harder, etc.
- “Vegetable Oils” are usually just blanket terms for trans fats. You’re better off with a seed oil like flax or sesame oil, because you’re getting the actual oil and fat from from the source.
- Cool inside look at the nutrition program for the patriots: https://www.youtube.com/watch?v=9iDTAzD2hT4.
- They get every meal provided, even in the offseason.
- You can customize and special-request items, if you want.
- They go through 70lbs of poultry, 25lbs red meat, 25lbs fish, and tons of vegetables every day.
- Everything organic, grassfed, freerange. The usual.
- They do a ton of smoothies.
- The whole program is surprisingly equivalent to my daily meals.
- Read up a little bit on bootstrap forms and validation.
- You can have subsequent form inputs base their options on previous selections (e.g. season -> week). You have to put these conditions, and subsequent queries (post to server for new choices) in javascript. It’s dynamic. There’s no shortcut.
-
- Gitlab/sentry:
- I don’t think you can default an assignee for tickets or MRs in gitlab (yet).
- Moved my project from my user namespace to a group. This is like an epic across projects, combining them together to see all tickets, etc. You can also see cycle analytics.
- Updated my remote urls to bmahlstedt-group/supercontest.git (updated namespace). Did this on my local machine and sbsc prod.
- Resolved the old AnonymousUserMixin sentry issue.
- Added the supercontest repo to sentry, and integrated the app in gitlab, so all my source commits are available to sentry.
- Blandish – to flatter someone manipulatively.
- MLB postseason is now in the semifinals. Nationals and Cardinals in the NLCS, Yankees and Astros? in ALCS.
- The carnivore diet is absent of vitamin C, vitamin E, and fiber.
- flask-user utilizes flask-login, not flask-security.
- Tony Bennett is currently 93 years old. Frank Sinatra died at age 82 in 1998.
- Supercontest.
- Fixed a few small bugs. Some wording.
- Added sentry releases.
- Rejiggered the picks_open logic to natively include is_current_week. Restructured the IF logic in the your-picks/all-picks routes to be extremely clear about the scenarios, and which info bubbles to present to the user based on timing (no lines, no picks, post-picks, picks-closed, etc).
- Integrated flask-admin.
- The main benefit is that you get ModelViews out of the box, allowing a web interface to create/edit/delete/search the database.
- The secondary benefit is just organization. My dashboard, scheduler, and all the other custom admin views for the supercontest can be added to the general /admin navbar.
- Added the model views. Protected with CRSF (flask_admin.forms.SecureForm) and restricted to an authenticated user with the admin role.
- I now have 8 tables in the app.
- There was an apscheduler os write error that sentry reported: https://sentry.io/organizations/bmahlstedt-org/issues/1266918507/?project=1773879. Not sure.
- Remembering 15 years ago to college applications, since I’m starting to do the same with job apps; I’m much more of a sniper than a machine gunner.
- I’ve used ~100m of 2000 (5%) of my shared runner pipeline quota.
-
- Supercontest.
- Added a global @app.before_request to print the email of the user for all requests, to make the logs more clear.
- Made the matchups js a lot smarter about iterating through picks. Instead of going over all matchups rows and comparing to picks, it gives the ids to the td cells and then targets the specific row, just iterating over the picks instead of all matchups.
- It now adds a 2px border to cells for complete games, to distinguish between what is finished and what isn’t. This happens on the your-picks and all-picks views.
- Fixed the emailer. The problem was the asyncronous job adding. APscheduler is a piece of shit, from all my experience with it so far. Jobs added before scheduler.start() will trigger properly, but having another view call add_job later has never successfully triggered that job. Now, it just adds the email reminder at app start (for prod app only). I left the scheduler admin view around, but put warnings that it doesn’t really work due to apscheduler.
- I’ve been more conscious about pushing, now that I have CI set up. I batch a lot more local commits now. This will save the 2k min limit on the shared runners.
- In setting up CI/CD on the droplet yesterday, I had accidentally removed the public key in /home/bmahlstedt/.ssh/authorized_keys (the one that corresponds to my private .ssh/digitalocean). I added it back (/root/.ssh still had it), and I could ssh again.
- In moving source checkouts over from github to gitlab, I lost all the backups (they aren’t tracked in vcs). This is fine, I have a new one with all the current data.
- Changed the matchups template to use picks_open as well.
- Added cards to the messages above each view’s table. Styled better.
- Added the roles table, create admin, added myself. Updated all views to use this properly. https://gitlab.com/bmahlstedt/supercontest/issues/115.
- First MR, ticket closure, master kickoff, deploy; all that ci/cd went well in gitlab.
- Wednesday deployment, changed banner.
- Quick bugfix with picks: https://gitlab.com/bmahlstedt/supercontest/issues/117.
- Sentry:
- List of importable integrations: https://github.com/getsentry/sentry-python/tree/master/sentry_sdk/integrations.
- Added sqlalchemy.
- You can’t add the gitlab integration for sentry unless your project is in a group (not owned by single user) – https://github.com/getsentry/sentry-plugins/issues/458.
- Changed sentry to only run in prod mode, so the local dev instance doesn’t eat up my sentry monthly event limit.
- The uncaught “AnonymousUserMixin object has no attribute id” errors were from queries.is_user_in_league in the url_value_preprocessor. I protected that with if current_user.is_authenticated, so we shouldn’t see those anymore.
- Protected all other current_user calls too (FMD’s get_current_user_email, etc).
- Note for future apps: if you’re ever calling current_user outside of a view or other function where the user is guaranteed to be logged in (protected by @login_required or such), you should condition the current_user object on is_authenticated.
- Left the email notifications for every exception ON. I don’t anticipate spam, now that the AnonymousUserMixin error is fixed.
- Flask debug toolbar changed its default to disable the profiler. I re-enabled it.
- Lol not the biggest jon jones fan but completely agree with this: https://www.reddit.com/r/MMA/comments/df49ql/jon_jones_to_izzy_im_not_out_here_searching_for/. Izzy is annoying.
- Created an radnet account to access my MRI results.
- https://myradiologyconnectportal.com/Exam.
- Bad: “There are mild degenerative changes of the coronoid process.”
- Good: “There are no areas of abnormal signal involving the trochlea or capitellum. There are no areas of abnormal signal involving the radial head. The radial collateral ligament and attachment of the common extensor tendon and ulnar collateral ligament and attachment of the common flexor tendons are normal. There is no triceps or biceps tendon tear. There are no soft tissue masses. No ulnar nerve lesion is identified.“
- You can make waiver claims on tuesday night for ff. I had thought that it was wednesday all season so far.
- Ortho appointment in Van Nuys. Basically just said it’s ok, go to PT. 10 appointments concluded with 0 treatment.
- Picked up DL from Brews Brothers after.
- Ate lunch at Dave’s Hot Chicken in NoHo. It was amazing. First time I’ve been impressed with outside food in a long time. 20min wait around noon.
- Loving Terry Reid’s music. Always liked seed of memory, but had never heard faith to arise or any of the others. Unfortunately, that whole album isn’t on spotify. He sounds a lot like Robert Plant, and the music is chill.
- pylint no-else-return has always been a dumb rule. Flow is so much more clear when it’s explicit about the else.
- I’ve said it many times before, but unfamiliarity is the root of most discrimination. Racism would be nearly extinct if the whole world spoke the same language. Then you could tackle the minority remainder, the heart of the problem; anger.
- In gitlab, you don’t need to put a pound sign in the branch name! This makes command-line-git a lot easier. You still put it in the commit message though.
-
- My 15(?) year old wix website has finally been cancelled (which is probably for the better).
- “And the day came when the risk to remain tight in a bud was more painful than the risk it took to blossom.” – Anais Nin
- Finished Once Upon a Time in Hollywood.
- Smoked the pastrami beef ribs that had cured for 6 days. Amazing flavor.
- Next set of beef ribs, I want to try wrapping earlier, closer to the time you would for brisket. I’m curious how much it changes tenderness vs bark.
- Paid off the remaining balance on the sequoia hospital bill from years ago; was like $220.
- Cancelled the amex.
- They tried to give two incentives, one for miles (20k) and one for cashback ($175), both requiring that you spend 3k in 3 months.
- The companion pass is forfeited (I had 1), and the annual fee is not prorated (there were 4 months left in that this billed year).
- Removed my amex from google play. Removed the amex browser bookmark. Mint automatically made it inactive, I didn’t have to do anything!
- I would like the Vitamix A3500 – it’s so much better than my ninja, and I use it at least once daily. It’s $525. I’ll probably wait until after I move.
- The Strassburg sock is definitely helpful for plantar faciitis. WFH makes it a lot easier to get hours in during the day, since I find it annoying to fall asleep wearing.
- Put the 2020 reg on the Ducati. It’s yellow, so it looks better than the blue 2019 sticker.
- Watch Rob Zombie’s new 3 From Hell, the third installment in the series after House of 1000 Corpses -> The Devil’s Rejects.
- The carolina reaper single chip is sold out online, but I just discovered that the riteaid on aviation/artesia has these 3 flavors:

- I like the haunted ghost pepper the best, then salsa verde, then chile limon.
- Kubernetes/GCP.
- Good article on kubernetes: https://www.digitalocean.com/community/tutorials/an-introduction-to-kubernetes. Very useful for orchestrating many containers across many machines together. Metrics, storage options, scalability, ML resources, much more through the full GCP suite.
- Created a project (supercontest) on GCP and removed the default API Project and My First Project.
- Enabled the Google Compute Engine API for this project.
- n1-standard-1 machine, just 1 vCPU and 3.75G mem (the smallest standard machine).
- Billing is by resource. It’s like 3 cents per cpu hour and 0.5 cents per gb mem hour, so the n1-standard-1 is about 5 cents per hour, or about a dollar a day, or about $30/mo. My digital ocean droplet is $5/mo.
- With the $300 promotion on signup, looks like I can test this for free pretty easily.
- Ended up staying with digital ocean for now. I don’t need any of the other GCP products (compute, storage, ml, etc). The one attractive feature is scalability, but I can upgrade with DO as well.
- GPG key = GNU Privacy Guard.
- Sentry.
- Created account, added the flask integration to supercontest.
- For the free plan, you can record 5,000 errors per month and it keeps history 1 month back. That’s 160 errors a day.
- Linked my gitlab project to the sentry api, created auth token.
- GitLab.
- If your project is public, and you have gitlab ultimate, then you get a security dashboard and dependency list. Pretty cool, but I obviously can’t take advantage of this.
- In general, I’ve been very pleased with the experience on this platform. Moreso than the atlassian stack, jenkins, etc.
- Added the deploy stage to my yml. Added the variable SSH_PRIVATE_KEY (for the droplet) to gitlab. Added it as a known host directly through ssh-keyscan.
- Gitlab runs the deployment as root, and the deployment has ansible pull new source on southbaysupercontest.com, so I had to make sure the machine had the proper ssh keys under the root account (not just mine). sudo cp -r ~/.ssh/ /root
- Ansible doesn’t maintain docker images officially anymore, but some user groups keep them around (albeit not very current). Also…you have to specifically install ansible after you pull the image lol.
- Did not integrate prometheus; there’s already a metrics agent that digitalocean provides to its droplets. I put a link to the external DO dashboard in gitlab tho.
- Updated the readme to indicate where metrics were, as well as SCM, CI/CD, etc. The GitLab and DigitalOcean logos (clearbit) look good.
- Modified my view to be fluid.
- The minutes you’ve used in CI/CD are at https://gitlab.com/profile/pipeline_quota.
- Integrated with sentry so that error tracking was in gitlab as well.
- I don’t need to use the container registry associated with the project, although this feature is great. My workflow is not build -> test -> pushImage -> deploy, so a record of all the image artifacts in a registry is less important. I test the source and then build the image right at deploy time, which is more than satisfactory until I start scaling the test/review app portion of things.
- Sometimes dpkg will prompt for config changes (like apt does for install y/n). Use -o DPkg::Options::=”–force-confnew”
- Changed my mem usage alert on the droplet from 90 to 95%.
-
- Gitlab.
- Migrated all projects from github to gitlab.
- Added the public ssh keys from both bmahlstedt-xps13 and southbaysupercontest.com.
- Delete the checked out repos, then recloned from the gitlab url (you could also just set the remote url).
- Privatized and archived all my projects on github, with a pointer to gitlab.
- Cool features:
- Got initial CI set up to run test-python on commits. Using shared runners for now, 2000 min/month should be enough. The wait times are zero. If needed, I’ll register my own machine as the runner (since I’m the only developer, and the machine is guaranteed up).
- Using custom stages, rather than autodevops. That’s a cool feature though.
- Added build and coverage badges to the readme.
- Google Cloud Platform.
- Kubernetes is obviously the google production container orchestration platform. Gitlab has lots of integrations with it, as well as Google Cloud Platform in general. I should try it out.
- GKE = Google Kubernetes Engine.
- Started a trial with GCP.
- Removed pay-with-points from my amazon card. You’re losing the cashback if you pay with points. Just always use the card, and withdraw all the cashback from the chase account whenever you want.
- Homemade protein bars for my mom yesterday. Pecans, oats, prunes, cinnamon, protein.
- Won both fantasy games. Went from 0-4 in yahoo, last place, to highest scorer of the week. 2.5 in sbsc.
- Placed fresh order.
- Supercontest.
- Put in the niners pick for jcriss and econstan.
- Changed FMD to monitoring level 1 for the user and scheduler blueprints, while leaving my main and season blueprints at 3.
- Finished the algorithms and data structures book, added all notes to google drive.
- Ordered a small bedroom trash can, since amazon lost the other delivery (got refund).
- I would like to do a hanging display for all the tough mudder headbands I have. The most basic is just wood blocks, maybe 1×8″ with 1/2″ thickness, then hook screws connecting them on both sides.


- There’s a ufc event every Saturday for the next 6 Saturdays, and they’re all good.
-
- Tough mudder yesterday was great. It was on the easier side (only 8 miles), but I saw a few new obstacles and got the pink headband. Awesome to do it with Eric. Plantar fasciitis did surprisingly ok.
- Fogo de chao. Prime rib and filet were good, as always. Beef rib, sirloin, new york, pork rib, picanha, chicken – everything else just can’t compare to the smoker.
- Cal lost to the ducks, warriors lost to the lakers (pregame).
- Watched the comain and main for ufc 243. Dan hooker is awesome. Adesanya looked fantastic but is annoying as hell. Too cocky and had one of the dumbest walkouts I’ve ever seen. Tried to make it a choreogrpahed performance like WWE and boxing. Gtsoh.
- Supercontest
- Entering the python shell is not resource-cheap. It creates an entirely new instance of the app. Not with a server, but will all the other frills; apscheduler, etc.
- Submitted late picks for Cam, Wes, Raj, Jesse Thompson, Ben Yezer, and Phil Twist.
- Credit card research.
- BoA preferred rewards offers 5.25/3.5/1.75, which is pretty damn good but you have to have 100k+ in your combined BoA/Merrill accounts. Otherwise it’s 3/2/1. If you have that much sitting in your account, then you can gain a lot more by moving it somewhere with higher growth rather than reaping higher cashback.
- While looking at NEW cards, I saw that there’s a better version of my old card. This is a ridiculous mistake. I’ve had an Amazon Rewards card since July 2013, which earns 3% back on Amazon. If you have Prime, which I do, you can upgrade to the Amazon Prime Rewards card, which gets 5% back. It did not automatically upgrade me, and I never noticed. I exported an order report, and I have spent $30,000 since July 2013 on Amazon. I missed $600 free dollars by not clicking the button. Chase will ship a new card automatically, even if the upgrade was done on amazon.com (I called Chase to confirm).
- Made my last payment on AmEx Platinum Delta Skymiles, will cancel in the next couple days. I no longer do business with Delta. The miles won’t expire as long as I maintain my Delta account; the amex card is not necessary. I can finish off the remaining ~135k miles whenever I want, as well as the buddy pass this year.
- Looking for purely cash back. Gas is easy with the motorcycle. Not a big traveler, don’t need air/hotel. Already a bomb chef, don’t need restaurant rewards.
- Chase ultimate rewards program is good for certain use cases. You can regard all “points” as basically 1% cashback, with some variation. In reality, a point can be anywhere from 0.8 to 1.5 cents, and can change based on what you’re redeeming them for as well. The most common use case is for travel, where you can get 1.25-1.5x the value of your points. You can also share points between cards, which is useful for people with business cards – they can use the points earned on work trips toward their personal rewards program. It’s only raw chase cards – cobranded cards (like my amazon) don’t share. Because of this, and the de-emphasis on travel, I don’t need a card in the chase ultimate program in particular.
- Cashback-focal cards with no annual fee and no rotating schedule:
- Citi double cash. 2%.
- HSBC cash rewards mastercard. 1.5%. $150 bonus once if you spend 10k in first year.
- Paypal cashback mastercard. 2%.
- Capital one quicksilver cash rewards. 1.5%. $150 bonus once if you spend 0.5k in first 3 months.
- Chase freedom unlimited. 1.5%. $300 bonus if you spend 20k in first year.
- (Chase freedom doesn’t count because they rotate categories, which I don’t need).
- Amex cash magnet. 1.5%. $150 bonus once if you spend 1k in the first 3 months.
- Decided to go with citi double cash. Highest basic cashback. I already have visa through my amazon prime rewards card, and this one is mastercard. Applied and accepted.
- Common, boring mistakes: https://medium.com/signal-v-noise/the-4-questions-you-should-stop-asking-during-your-one-on-one-meetings-ed7431da11aa.

- Cool NFL data of score combo possibilities: https://nflscorigami.com/.
-
- Redis can read a json 16x faster than postgres.
- “Vice signaling” (as opposed to virtue signaling) is a cool trait. Admitting one’s faults, weaknesses, etc. I like that in people.
- Petty finally sent me the list of people who had paid so far. Added them to the prod table, lb looks much better now.
- enter-python-prod
- paid_league_2019 = db.session.query(League).filter(League.season_id == Season.id, Season.season == 2019, League.name == ‘Paid’).one()
- user = db.session.query(User).filter(User.email.like(‘%petty%’)).one()
- paid_league_2019.users.append(user)
- Repeat 3-4 for any other users
- db.session.commit()
- 33 so far. More are planning to pay (Art, Wes, Harner, …).