support relative paths
@ -1,5 +1,5 @@
|
|||||||
output_dir: public/
|
output_dir: ../links/public/
|
||||||
links:
|
links:
|
||||||
source: data/links/links.yaml
|
source: ../links/data/links/links.yaml
|
||||||
template: templates/links/links.html
|
template: ../links/templates/links/links.html
|
||||||
static_dir: static/
|
static_dir: ../links/static/
|
||||||
|
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 393 KiB |
Before Width: | Height: | Size: 410 KiB |
Before Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 490 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 765 KiB |
Before Width: | Height: | Size: 609 KiB |
Before Width: | Height: | Size: 693 KiB |
Before Width: | Height: | Size: 630 KiB |
Before Width: | Height: | Size: 795 KiB |
Before Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 294 KiB |
Before Width: | Height: | Size: 315 KiB |
Before Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 247 KiB |
Before Width: | Height: | Size: 230 KiB |
Before Width: | Height: | Size: 298 KiB |
Before Width: | Height: | Size: 346 KiB |
Before Width: | Height: | Size: 158 KiB |
Before Width: | Height: | Size: 420 KiB |
Before Width: | Height: | Size: 311 KiB |
Before Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 462 KiB |
Before Width: | Height: | Size: 439 KiB |
Before Width: | Height: | Size: 537 KiB |
Before Width: | Height: | Size: 351 KiB |
Before Width: | Height: | Size: 498 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 283 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 150 KiB |
Before Width: | Height: | Size: 259 KiB |
Before Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 595 KiB |
Before Width: | Height: | Size: 557 KiB |
Before Width: | Height: | Size: 573 KiB |
Before Width: | Height: | Size: 414 KiB |
Before Width: | Height: | Size: 135 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 341 KiB |
Before Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 39 KiB |
@ -1,13 +0,0 @@
|
|||||||
404
|
|
||||||
###
|
|
||||||
:date: 2022-10-16 00:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: Website
|
|
||||||
:slug: 404
|
|
||||||
:status: hidden
|
|
||||||
|
|
||||||
|
|
||||||
404
|
|
||||||
~~~
|
|
||||||
|
|
||||||
Please go back and try again. Page is missing.
|
|
@ -1,36 +0,0 @@
|
|||||||
About
|
|
||||||
######
|
|
||||||
:date: 2022-05-01 00:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: About
|
|
||||||
:slug: about
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
About Tyrel
|
|
||||||
===========
|
|
||||||
|
|
||||||
|
|
||||||
Senior Software Engineer with a back end focus. Specializing in Python and Go.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Licenses
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
* I have a Ham Radio License (Amateur Radio)
|
|
||||||
* I have a Restricted Radiotelephone Operator Permit (RR - for flying in certain countries)
|
|
||||||
* I have a General Mobile Radio Service (GMRS)
|
|
||||||
* I have a North Carolina Driver's License
|
|
||||||
* I have a North Carolina "Boater Education Card" (boating license for those of us born after 1988-01-31)
|
|
||||||
* I have a North Carolina Motorcycle Endorsement/License
|
|
||||||
* I have a Pilot's license
|
|
||||||
* I am an Ordained Minister at the Universal Life Church Monastery
|
|
||||||
* I am a North Carolina Notary Public - Commission expiring May 30, 2027
|
|
||||||
|
|
||||||
|
|
||||||
Site notes
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
This blog is proudly powered by `Pelican <https://getpelican.com/>`_, which takes great advantage of Python.
|
|
||||||
|
|
||||||
The Theme is modified from `Blue Penguin Dark <https://github.com/tcarwash/blue-penguin-dark>`_ Theme
|
|
@ -1,13 +0,0 @@
|
|||||||
Active Projects
|
|
||||||
###############
|
|
||||||
:date: 2022-10-16 00:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:slug: active-projects
|
|
||||||
:status: draft
|
|
||||||
|
|
||||||
I'm always tooling around on a couple things in the background to keep myself fresh with some programming languiages.
|
|
||||||
|
|
||||||
* `itor <https://gitea.tyrel.dev/tyrel/itor>`_ - a flashcard tool, create and practice with flash cards. 100% meant as a BubbleTea learning tool for TUIs in Go.
|
|
||||||
|
|
||||||
* `Frank Tank <https://gitea.tyrel.dev/tyrel/frank_tank.git>`_ - Manipulating a water heater from a NodeMCU and Stepper motor.
|
|
@ -1,23 +0,0 @@
|
|||||||
Blogroll
|
|
||||||
########
|
|
||||||
:date: 2022-11-07 00:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: Blogroll
|
|
||||||
:slug: blogroll
|
|
||||||
:status: draft
|
|
||||||
|
|
||||||
|
|
||||||
* Blogs I Read
|
|
||||||
|
|
||||||
* `Ned Batchelder's blog <https://nedbatchelder.com/blog>`_
|
|
||||||
* `Andrey Petrov <https://shazow.net/>`_
|
|
||||||
* `bitprophet.org on bitprophet.org <https://bitprophet.org/>`_
|
|
||||||
* `bitquabit <https://www.bitquabit.com/>`_
|
|
||||||
* `Julia Evans <http://jvns.ca>`_
|
|
||||||
* `Nik Kantar <https://www.nkantar.com>`_
|
|
||||||
* `Sam.Codes <https://blog.sam.codes/>`_
|
|
||||||
* `Stories by Jess Shapiro on Medium <https://medium.com/@transgingerjess?source=rss-44663d5275a4------2>`_
|
|
||||||
* `The Industrious Rabbit - Blog <https://theindustriousrabbit.com>`_
|
|
||||||
* `The Industrious Rabbit - Videos <https://www.youtube.com/channel/UCV37kgKv2uoFimfxaFKoXOA>`_
|
|
||||||
* `__fredeb.dev <https://fredeb.dev/>`_
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
Contact
|
|
||||||
#######
|
|
||||||
:date: 2022-10-15 00:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: Contact
|
|
||||||
:slug: contact
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
To Contact Me: `Email <mailto:email@tyrel.dev>`__
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
Notary Public
|
|
||||||
=============
|
|
||||||
:date: 2022-12-06 00:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: Notary
|
|
||||||
:slug: notary-public
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
|
|
||||||
I am a North Carolina Notary Public, located in Durham, North Carolina.
|
|
||||||
|
|
||||||
I can perform notarial acts in all 100 counties.
|
|
||||||
|
|
||||||
If you want to use my services, I charge $5 per stamp (The maximum that NC allows you, and $0 for Absentee Ballots).
|
|
||||||
|
|
||||||
|
|
||||||
To prepare, first familiarize yourself with `How to get something notarized <https://www.nationalnotary.org/resources-for/public/how-to-prepare-for-notarization>`_.
|
|
||||||
|
|
||||||
Then, to request my services, `Email me <mailto:email@tyrel.dev>`_ or `Book Me <https://cal.com/tyrelsouza>`_
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
Now
|
|
||||||
###
|
|
||||||
:date: 2023-03-12 00:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: Now
|
|
||||||
:slug: now
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
`What is this? <https://nownownow.com/about>`_
|
|
||||||
|
|
||||||
June 2023
|
|
||||||
---------
|
|
||||||
|
|
||||||
* I was laid off from EverQuote in a round of layoffs.
|
|
||||||
|
|
||||||
April 2023
|
|
||||||
----------
|
|
||||||
|
|
||||||
* Set up FreeDOS on an old Dell Vostro 1720 - so I can now use things like TurboC, WordStar, and play old DOS Games.
|
|
||||||
* Set up Amiberry with AmigaOS Workbench3.1 on a flash drive, so I can tool around with Amiga finally.
|
|
||||||
* Ordered a Godot course on Zenva from HumbleBundle. I'm glad to finally peek at it at least, always interested me as a game engine.
|
|
||||||
* Astrid is two months old now, and not sleeping the best, but growing bigger.
|
|
||||||
* Making some new parent friends. Helped one new father move. Walked with a couple in our neighborhood about to have a baby and hopefully we stay connected.
|
|
||||||
* Grandmother is out of the hospital after having two heart stints put in, and giving us a scare with potential fatal surgery.
|
|
||||||
|
|
||||||
March 2023
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
* Wife had our first child Astrid Mina, on March 2, 2023. On Parental leave until April 26.
|
|
||||||
* Still working at EverQuote, on a different team now that does Go, React and Ruby.
|
|
||||||
* Haven't flown in a while, taking some time off because of some `mental health reasons <https://k3tas.radio/airband/2022/10/24/david-dezendorf/>`_, and now with a kid, no time for a bit.
|
|
@ -1,34 +0,0 @@
|
|||||||
References
|
|
||||||
##########
|
|
||||||
:date: 2022-11-04 00:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: References
|
|
||||||
:slug: references
|
|
||||||
:status: draft
|
|
||||||
|
|
||||||
Blog Citations
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* 2023
|
|
||||||
|
|
||||||
* Another citation from my friend Nik. `Self Hosting: Resolved? <https://nkantar.com/blog/2023/04/self-hosting-resolved/>`_
|
|
||||||
|
|
||||||
* 2020
|
|
||||||
|
|
||||||
* My friend Nik has a blog, and I pointed out an alternative so he `Cited Me <https://www.nkantar.com/blog/dict-setdefault-rocks/>`_.
|
|
||||||
|
|
||||||
Work Blogs
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
* 2021
|
|
||||||
|
|
||||||
* I wrote a blog post about our `Command Line Interface <https://blog.tidelift.com/hey-software-engineers-the-tidelift-subscription-has-command-line-integration-now>`_ that we are building at Tidelift. (Note: I am no longer employed by Tidelift nor work on this project)
|
|
||||||
|
|
||||||
|
|
||||||
Interviews
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
* 2021
|
|
||||||
|
|
||||||
* `Daily Tar Heel - Covid19 Standby List Twitter Opinions <https://www.dailytarheel.com/article/2021/03/university-standby-covid-19-vaccine>`_ (Nothing special, just gave my opinion on UNC's Standby Covid Vaccinations nearby.)
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
|||||||
Resume
|
|
||||||
######
|
|
||||||
:author: tyrel
|
|
||||||
:category: Resume
|
|
||||||
:slug: resume
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
|
|
||||||
`2023 Resume <{attach}/pdfs/Tyrel-Souza-Resume-2023.pdf>`_
|
|
||||||
|
|
||||||
Also `Online Resume <https://read.cv/tyrel/>`_ for more up to date resume.
|
|
||||||
|
|
||||||
NOTE: I live in North Carolina and am only entertaining Remote Roles right now.
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
Senior Software Engineer with focus on Python, Django, Go. Technology enthusiast and IOT tinkerer. Private pilot. Amateur radio operator.
|
|
||||||
|
|
||||||
EXPERIENCE
|
|
||||||
----------
|
|
||||||
|
|
||||||
EverQuote — Boston, MA — Senior Software Engineer >>> January 2022 - June 2023
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* Email Remarketing Team
|
|
||||||
|
|
||||||
* Ported a Python2.7 monolith to Python3 microservices using FastAPI, and Kafka.
|
|
||||||
* Automated a daily task for two analysts to be able to be run in only a few moments which saves 18 hours per week of analyst time.
|
|
||||||
* Built a UI for manipulating database settings to aid in automating work for analysts.
|
|
||||||
* Migrated a handful of repositories from CircleCI testing to GitHub Actions.
|
|
||||||
* Ported multiple long running scripts and command line tools from Python 2.7 to Python 3.
|
|
||||||
* Migrated alerts system platform from PagerDuty to Opsgenie
|
|
||||||
|
|
||||||
* Consumer Engagement Team
|
|
||||||
|
|
||||||
* Launched a web service using Go and React (in TypeScript) to assist Sales Reps to provide alternative insurance company matches.
|
|
||||||
* Transitioned multiple projects from Atlassian Bamboo to GitHub Actions.
|
|
||||||
|
|
||||||
Tidelift — Boston, MA — Software Engineer III >>> April 2018 - December 2021
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* `Command Line Interface <https://tidelift.com/cli>`_
|
|
||||||
|
|
||||||
* Developed binary CI/CD tool in Go to analyze software dependencies for security/licensing problems
|
|
||||||
* Added ability to create users and manage repositories from the command line
|
|
||||||
* Expanded personal project into company product
|
|
||||||
|
|
||||||
* Tidelift core redesign and pivot
|
|
||||||
|
|
||||||
* Pivoted from solely a vulnerability scanner to supporting a catalog of open source dependencies
|
|
||||||
* Part of small team developing Tidelift 2.0/3.0
|
|
||||||
* Developed front end Vue, and back end Ruby on Rails
|
|
||||||
* Worked on many Sinatra microservices.
|
|
||||||
|
|
||||||
* Expanded open source code under https://libraries.io to support more languages.
|
|
||||||
|
|
||||||
* Added new languages manifests support
|
|
||||||
* Programmed in multiple projects with code all available as open source on github
|
|
||||||
* `Bibliothecary <https://github.com/librariesio/bibliothecary>`_: Added ability to detect dependencies in manifests for Poetry, pip-compile, pipfile,
|
|
||||||
* `Conda Parser <https://github.com/librariesio/conda-parser>`_: Developed ingestor of Conda environment files, parsing environment.yml files
|
|
||||||
* `Conda API <https://github.com/librariesio/conda-api>`_: Programmed web scraping of Anaconda to detect new packages, and REST API endpoints for packages
|
|
||||||
|
|
||||||
|
|
||||||
Addgene — Cambridge, MA — Software Engineer >>> March 2015 - March 2018
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* Wrote code to support front end ecommerce site, and back end inventory management system using Django, Django Rest Framework, jQuery, Bootstrap
|
|
||||||
* Rewrote file storage backend to keep on Amazon S3 instead of local in-house file system
|
|
||||||
|
|
||||||
* Released my own custom Django module as a result
|
|
||||||
|
|
||||||
* Trained non-developers in Python
|
|
||||||
* Helped start and expand a “non-developer developer” club
|
|
||||||
* Created mircoservices to support 3rd party API integration
|
|
||||||
|
|
||||||
|
|
||||||
Akamai — Cambridge, MA — Sr. Software Engineer >>> July 2014 - March 2015
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* Wrote an API with Python/Flask that the front end could communicate with
|
|
||||||
|
|
||||||
* Checked if email was a valid user in Salesforce, then sent the user an email from a template
|
|
||||||
|
|
||||||
* Rewrote the backend for an internal dashboard to load data in 0.1 second, down from 10 seconds
|
|
||||||
|
|
||||||
Propel Marketing — Quincy, MA — Software Engineer >>> September 2012 - July 2014
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* Built CMS to host and build hundreds of customer websites using Django, jQuery, Bootstrap
|
|
||||||
* Created custom widgets, custom styling, custom templates, and more
|
|
||||||
|
|
||||||
|
|
||||||
Appropriate Solutions Inc — Peterborough, NH — Software Developer >>> July 2010 - September 2012
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* Built multiple client websites in Django, jQuery, Bootstrap.
|
|
||||||
|
|
||||||
SKILLS
|
|
||||||
------
|
|
||||||
|
|
||||||
* Python, Go, Django, Flask, Linux, Docker, Git, Mercurial, Postgres, MySQL, MariaDB, Amazon AWS (S3 mostly) Google Cloud Storage, REST APIs, Kafka, Redis, memcached, Sidekiq, RabbitMQ, Eclipse Mosquitto
|
|
||||||
|
|
||||||
EDUCATION
|
|
||||||
---------
|
|
||||||
|
|
||||||
* Keene State College - B.S. Applied Computer Science (Honors Society), Minor in Mathematics (Honors Society), Dean's List
|
|
||||||
|
|
||||||
PERSONAL PROJECTS
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
* `Django DBFileStorage <https://gitlab.com/Tyrel/django-dbfilestorage>`_ Goal: to continue running CI tests on a remote storage when working on moving file storage to S3 without incurring additional AWS charges.
|
|
||||||
|
|
||||||
|
|
||||||
CONTRACTING WORK
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Benchtop Devices
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
* Multiple C# Desktop programs, interfacing via serial to get results about pressure tests, calculate decay rates, printing results to pdfs, label machines, and local Sqlite databases. Custom per each client.
|
|
||||||
|
|
||||||
* Clients include: Waymo, FlexFlow, Hypertherm
|
|
||||||
|
|
||||||
* Python/Django and VueJS tool to convert pressure test results from the Cincinnati Test Blackbelt Machine, to PDFs.
|
|
||||||
|
|
||||||
VOLUNTEERING
|
|
||||||
------------
|
|
||||||
|
|
||||||
* Boston Athletic Association Amateur Radio Operator - 2019 Boston Marathon
|
|
@ -1,43 +0,0 @@
|
|||||||
Python Progress Bar
|
|
||||||
###################
|
|
||||||
:date: 2011-12-21 03:52
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: Python
|
|
||||||
:slug: python-progress-bar
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I was looking for a nice progress bar today at work to show progress rather than just printing "\ **Waiting 30 seconds…**\ " and having the script do nothing, I wanted to have a progress bar show.
|
|
||||||
|
|
||||||
I found a progress bar from `Corey Goldberg <http://code.google.com/p/corey-projects/source/browse/trunk/python2/progress_bar.py>`__
|
|
||||||
|
|
||||||
I did make a couple changes, and have uploaded my changes to my GitHub account.
|
|
||||||
|
|
||||||
newPythonProgressBar [deadlink]
|
|
||||||
|
|
||||||
To use this progressbar, it is very easy.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
# To Setup
|
|
||||||
from progress_bar import ProgressBar
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
def updateBar(step):
|
|
||||||
p.update_time(step)
|
|
||||||
sys.stdout.write("%s\r" % p)
|
|
||||||
sys.stdout.flush()
|
|
||||||
#
|
|
||||||
# to call
|
|
||||||
#
|
|
||||||
wait_time = 100 # seconds
|
|
||||||
p = ProgressBar(wait_time)
|
|
||||||
p.empty_char = "."
|
|
||||||
p.unit = "^"
|
|
||||||
for step in range(wait_time+1):
|
|
||||||
updateBar(step)
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
It will look like this when you use it
|
|
||||||
|
|
||||||
``[###...............7%..................] 7^/100^``
|
|
@ -1,32 +0,0 @@
|
|||||||
Custom Django URLField
|
|
||||||
######################
|
|
||||||
:date: 2012-01-05 03:55
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: python, django
|
|
||||||
:slug: custom-django-urlfield
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
For work I had to write a custom url model field. This model field when setting up accepts a default protocol, and a list of other protocols.
|
|
||||||
|
|
||||||
When checking the protocol, the url is split by "://". If the split has one or two parts, then the url is validly formed.
|
|
||||||
|
|
||||||
In the event of a single element split, there is no protocol specified. When there is no protocol, the url is prepended with the default protocol specified. If there is a protocol, it is checked to make sure it exists in a union of the default protocol and other protocols. If it is not, a ValidationError is raised letting the user know that the protocol is not accepted.
|
|
||||||
|
|
||||||
This can all be found at On my github [deadlink].
|
|
||||||
|
|
||||||
I have a couple ways I could have done this better and probably will. Improvements would be just one parameter called parameters in which it is checked if there is at least one element. Passing this, when there is no protocol specified, the first element is the default one.
|
|
||||||
|
|
||||||
This would be a little cleaner.
|
|
||||||
|
|
||||||
this example would allow for http, https, ssh, spdy and mailto, anything else would error out.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
facebook_page = URLField(default_protocol="http", protocols=["https","ssh","spdy","mailto"])
|
|
||||||
|
|
||||||
The way I could improve this would be
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
facebook_page = URLField(protocols=["https","https","ssh","spdy","mailto"])
|
|
@ -1,53 +0,0 @@
|
|||||||
You can un-expire a GPG key.
|
|
||||||
############################
|
|
||||||
:date: 2012-01-13 03:54
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: linux, gpg
|
|
||||||
:slug: you-can-un-expire-a-gpg-key
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
Today we had a problem at work on a system.
|
|
||||||
Without getting into too much detail as to give away secrets behind the verbal NDA I am behind, I will just say that it had to do with a GPG public key of mine that was expired on a dev machine, accidentally propagating during install to a production machine.
|
|
||||||
This key had a sub key as well, so figuring out this was tricky.
|
|
||||||
|
|
||||||
To start, you can list your gpg keys like so:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ gpg --list-keys
|
|
||||||
|
|
||||||
|
|
||||||
This will list keys such as
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
pub 4096R/01A53981 2011-11-09 [expires: 2016-11-07]
|
|
||||||
uid Tyrel Anthony Souza (Five year key for email.)
|
|
||||||
sub 4096R/C482F56D 2011-11-09 [expires: 2016-11-07]
|
|
||||||
|
|
||||||
To make this not expire, (same steps to change expiration date to another time), you must first edit the key
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ gpg --edit-key 01A53981
|
|
||||||
|
|
||||||
|
|
||||||
You will then see a gpg prompt ``gpg>``
|
|
||||||
|
|
||||||
Type "expire" in and you will be prompted for how long to change it to
|
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
Changing expiration time for the primary key.
|
|
||||||
Please specify how long the key should be valid.
|
|
||||||
0 = key does not expire
|
|
||||||
<n> = key expires in n days
|
|
||||||
<n>w = key expires in n weeks
|
|
||||||
<n>m = key expires in n months
|
|
||||||
<n>y = key expires in n years
|
|
||||||
|
|
||||||
You are then done setting the expiration on the primary key, if you have sub key, doing this is as easy as typing ``key 1`` and repeating the expiration step.
|
|
||||||
|
|
||||||
To finish and wrap things up, type ``save`` and you are done.
|
|
@ -1,15 +0,0 @@
|
|||||||
Vertical Bars In Graphite
|
|
||||||
#########################
|
|
||||||
:date: 2012-02-08 15:10
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: graphite, statsd
|
|
||||||
:slug: vertical-bars-in-graphite
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I am working with txStatsD and Graphite. I was having the hardest problem looking through the txStatsD code today finding how to graph something as an event, not a data point. I eventually went into every option on the graphite dashboard and found an option to make a bar.
|
|
||||||
|
|
||||||
.. figure:: {static}/images/2012/02/graphite-menu.png
|
|
||||||
:alt: menu in graphite showing draw nonzero as infinite
|
|
||||||
|
|
||||||
This is the option that you must use when you want to mark events. For example we want to know "Server restarted", we would use this technique, as it doesn't make sense to aggregate "server restarted". Using nonzero as infinite is a good way to show an event took place.
|
|
@ -1,25 +0,0 @@
|
|||||||
Hubspot
|
|
||||||
#######
|
|
||||||
:date: 2012-02-17 15:10
|
|
||||||
:author: tyrel
|
|
||||||
:category: Personal
|
|
||||||
:tags: hackathon
|
|
||||||
:slug: hubspot
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I was invited to a Hackathon that one of our client's client was throwing. Being that I love programming and learning, I decided I would go.
|
|
||||||
|
|
||||||
The event was in Cambridge, MA. I arrive early, (my friend said there would be a lot more traffic than there was at that time of day) so I got a tour of office. It's situated in an old, what I believe to be, factory building. The coolest part of the office was that they had whiteboard paint on every wall surface, complete with markers of course.
|
|
||||||
|
|
||||||
The event started and people who were attending had tossed up ideas on the white board. A couple people wanted to integrate LinkedIN with HubSpot. Another person wanted to integrate Eventbrite with HubSpot, to get information to/from event goers after the event ends. I didn't like any of those ideas and my only experience with HubSpot is their Leads API, so I stuck to what I know.
|
|
||||||
|
|
||||||
I had an idea for an app the second I walked in the door, it was like magic. My main hassle was that HubSpot's Canvas integration REQUIRES HTTPS. Now, my web host is DreamHost and I am kind of cheap, so of course I don't have any way to host a HTTPS site immediately. A big part of me wanted to bite the bullet and order a secure server from DreamHost, or setup another linode, but I felt that I've been spending a lot of money lately and that I would figure out a way. Adrian, my contact at HubSpot, of who I am working with on the PPC project(more on that later), walked by and saved me.
|
|
||||||
|
|
||||||
He asked if I had ever used GoogleAppEngine. Of course I hadn't because I was under the belief that it cost money to use, but then I realized I was thinking of Amazon's EC2. I sign up for GAE and within an hour I have a HelloWorld site setup. The slow part was installing Python2.5 so I could use the same version that GAE used and not have to fix a lot of backwards compatibility errors between 2.5->2.7.
|
|
||||||
|
|
||||||
After I had a site up that could do HTTPS I dove into programming for my HubSpot app. The app I am doing for work graphs leads per day combined with Google AdWords data per day. I decided to do something different. My app is still a graph, as graphs are fun and easy to understand by everyone.
|
|
||||||
|
|
||||||
This app graphs a set of leads and shows how many leads happened in a given hour for the previous day. Given extra time I would have added an interface to specify the day to graph leads, but last night my time was severely limited by the fact that I had to setup my environment for GoogleAppsEngine.
|
|
||||||
|
|
||||||
Improvements I can and want to do to this app are database, faster processing, and being able to select a date. I almost wanted to break down and learn NodeJS for this, because from my understanding of the event driven nature of NodeJS would be a lot easier to load data over a longer period of time, than to just load it all at once and timeout with HubSpot's Jakarta Commons-HttpClient.
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
Some BASH tips
|
|
||||||
##############
|
|
||||||
:date: 2012-03-08 03:56
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: bash, linux
|
|
||||||
:slug: some-bash-tips
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I realize I haven't updated in a while. I haven't had much free time recently as I've been working on a project for my father in C# after work hours. This is a great change from only working in Python and JavaScript recently. I'm making a program that will analyze test results from a plasma torch for a company called HyperTherm. My father built the physical machine, but the employees want something that they can better see the results of a passed torch unit, or a failed torch unit. This program has a bar code scanner that scans the tool used in the test and matches it up to the lot of torch parts. Another added feature is the ability to print a white label that says "UNIT PASSED" or a giant red label that says the unit failed and which of the 8 tests failed were.I had to learn how to use delegates, as my serial event listener is on a separate thread and I can't update labels, or parts of the User Interface without them. Still working on it, hopefully will wrap it up by Saint Patrick's day.
|
|
||||||
|
|
||||||
|
|
||||||
I recently found a cool command in BASH that I hadn't previously known. ``C-o`` will execute the current line, and then bring the following line up from BASH history. If you have a set of commands you want to execute again, rather than having to press up 20 times, hit enter, press up 19 times, hit enter, and so on… You can just hit up 20 times. Press C-o as many times as you need to.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ touch a
|
|
||||||
$ touch b
|
|
||||||
$ touch c
|
|
||||||
# [up] [up] [up]
|
|
||||||
$ touch a [C-o]
|
|
||||||
$ touch b [C-o]
|
|
||||||
$ touch c [C-o]
|
|
||||||
|
|
||||||
As you can see there, all I had to do was go back to the ``$ touch a`` line, and hit control-o three times and it touched the files again!
|
|
@ -1,20 +0,0 @@
|
|||||||
Ganymede, Twilio
|
|
||||||
################
|
|
||||||
:date: 2012-05-04 23:30
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: nodejs, twilio
|
|
||||||
:slug: ganymede-twilio
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
Last night I wrote the beginnings of my first NodeJS application. Is application even the correct word?
|
|
||||||
|
|
||||||
I've been meaning to try out the cool API by Twilio, which is used for SMS and VoiceCalling. I decided to design a system that will be two+ endpoints. One is the main server which will listen for UDP messages. When it receives the correct UDP message, configured in the config(`konphyg <https://github.com/pgte/konphyg>`_) files, it will fire off a message to Twilio and send me a text message.
|
|
||||||
|
|
||||||
The next steps, which I should be getting to tonight, are to create the Arduino portion and the serial listener. The Arduino will have a button that will send a message over serial to another NodeJS listener. This will decide if the press was good enough, if it passes the debouncing filter, and then fire a message to the main Ganymede server.
|
|
||||||
|
|
||||||
This could be used as a little text message doorbell for when you have your music on too loud. I don't believe I will ever sell this, as it's just for me to get into NodeJS, but It would be fun to share with friends.
|
|
||||||
|
|
||||||
The source so far is located on my github at [DEADLINK].
|
|
||||||
|
|
||||||
I will write more as the project continues about the different technologies and comment on my choices in the source a little bit.
|
|
@ -1,27 +0,0 @@
|
|||||||
Hypertherm
|
|
||||||
##########
|
|
||||||
:date: 2012-05-07 23:30
|
|
||||||
:author: tyrel
|
|
||||||
:category: Personal
|
|
||||||
:slug: hypertherm
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
For the past three months I have been upgrading and rewriting version 2 of my software for Hypertherm. I am under a contract for my father's company. His company is developing a machine to test how well air flows (laminar flow) through a plasma cutting torch head, and how much air leaks out over a certain time (delta pressure loss).
|
|
||||||
|
|
||||||
This has been a nice adventure. I am talking to the tester over serial, reading in a hand scanner (barcodes and acts as a keyboard easy), talking to a DYMO printer and using a database.
|
|
||||||
|
|
||||||
The serial communication was pretty straightforward. I started a new thread and listen for serial all the time. The tricky part with that was that because it was on another thread, I needed a delegate to talk to my UI when I did things like change the picture from blank to a big red X, or update a label.
|
|
||||||
|
|
||||||
The hand scanner wasn't even a factor that took longer than 10 minutes, I just pop up a dialog box asking for input.
|
|
||||||
|
|
||||||
The DYMO printer was the hardest part. This took me a month to figure out, I kept fighting with the printer. I could figure out how to print to the left roll, the ones we setup as as the passing labels, but I couldn't for the life of me figure out how to get it to print to the right label, using a custom label. I tried to load the labels into data and use a StreamWriter/StreamReader object to treat that as the label, but it kept printing one that had, for reasons unknown to me, been locked into the printer. I finally gave up on using the interface they provided and am writing the label to a temporary file. The file is in the user's %appdata% directory in a sub directory that it will not be mistakenly written to, so I feel safe doing it this way. Granted, the machine is a single purpose machine, once this program is installed it will only run this program day and night.
|
|
||||||
|
|
||||||
Once I got the printer working, I checked it in to github and realized it took me way longer than anticipated. I learned a lot about .NET development (by no means everything, or even most things, just a lot compared to what I did know before [nothing].)
|
|
||||||
|
|
||||||
Tonight while developing I decided to video some aspects of the Program.
|
|
||||||
|
|
||||||
The following four links are videos, showing parts of the program and machine in action.
|
|
||||||
|
|
||||||
* [Hosted on Qik - no longer available]
|
|
||||||
* [Hosted on Qik - no longer available]
|
|
||||||
* [Hosted on Qik - no longer available]
|
|
@ -1,31 +0,0 @@
|
|||||||
Harry Delmolino
|
|
||||||
###############
|
|
||||||
:date: 2012-05-25 03:56
|
|
||||||
:author: tyrel
|
|
||||||
:category: Personal
|
|
||||||
:tags: friends
|
|
||||||
:slug: harry-delmolino
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I met this random kid online on IRC a year and a half ago (I believe it was December 19th, 2010). His name was HarryD. We got talking and one time he mentioned that he was going to hike Mount Monadnock. That is near me so we got talking and he said he lived near North Hampton, MA. That was cool that I met some random kid who lived near me. He was only 17 at the time.
|
|
||||||
|
|
||||||
Eventually we met up because my new girlfriend lived near NoHo in Holyoke. One day I went down to see her and met up with him. He was wearing all brown, so I joked that he was a UPS delivery guy. We hung out for a bit, I think I met his friend Sam that day. Then I left and went home. For the next year we would hang occasionally, usually I would go down and visit NoHo because it was easy for him to Bike to and he worked there. We went bowling, once or twice, and he came up for this super bowl to watch Star Wars instead because screw sports!
|
|
||||||
|
|
||||||
I think that was the last time I saw him.
|
|
||||||
|
|
||||||
On this Saturday, May 19th, 2012, he was riding his bicycle in North Hampton and collided with a car, sending him flying off and smacking his head on the edge of the curb. There are some other details which I am not 100% sure about. He then was in the hospital until Tuesday May 22, 2012 at which time he passed away.
|
|
||||||
|
|
||||||
We used to talk every day, either on IRC, AIM or gTalk. His account on IRC (no_numbers_here) is still active because his VPS for http://harry.is is still paid for and online until the next billing period. Its so sad seeing his name online and not being able to send a "hey dood" or some other random greeting, then start talking about computers, python, bikes, etc.
|
|
||||||
|
|
||||||
Harry was an avid cyclist. I am reading stories that even if he had to go thirty feet, he would hop on his bike to get there. He got me interested in cycling as well. He was going to sell me a bike, but the I was talking to a friend and he gave me on, so I never bought it. Which as it turns out was good as he wanted to give that to his new girlfriend.
|
|
||||||
|
|
||||||
I was planning on hanging out with him next weekend, as he was busy with something this weekend that I can't remember. I wanted to take him target shooting, and wanted to eventually be in enough shape to go hiking with him. None of this ever came to fruition.
|
|
||||||
|
|
||||||
Harry Delmolino, we may not have been as close as we could have been, but you definitely made a difference in my life for the better and I never got to thank you for this.
|
|
||||||
|
|
||||||
|
|
||||||
Edit:
|
|
||||||
-----
|
|
||||||
I went to the Calling Hours today and I was only there maybe a half hour, but there were so many people there. It's amazing that a man so young has touched so many lives of so many people, and had accomplished so much. People might say "Oh we was just a kid, he was only 18″ but if they looked at the accomplishments of this young man, they would realize how grown up he was.
|
|
||||||
|
|
||||||
I think his mother and father might eventually delete his Facebook, so I went back and took a screenshot of one of our last conversations so I can remember. Everything he said usually warranted a laugh.
|
|
@ -1,43 +0,0 @@
|
|||||||
CFEngine3 Install on CentOS 5.7
|
|
||||||
###############################
|
|
||||||
:date: 2012-05-25 03:57
|
|
||||||
:author: tyrel
|
|
||||||
:category: Outdated
|
|
||||||
:tags: cfengine, centos
|
|
||||||
:slug: cfengine3-install-on-centos-5-7
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
| Today I was tasked with installing CFEngine3 on CentOS-5.7 (A little outdated). When installing CFEngine-3.3.1 I kept getting an error that I couldn't find libtokyocabinet.so.9. I had to set my prefix to /usr/ because the location that tokyocabinet was installing my libraries to was not being read by CFEngine's make script.
|
|
||||||
| To do this (I am using tokyocabinet 1.4.47)
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
wget http://fallabs.com/tokyocabinet/tokyocabinet-1.4.47.tar.gz
|
|
||||||
tar -xzvf tokyocabinet-1.4.47.tar.gz
|
|
||||||
cd tokyocabinet-1.4.47/
|
|
||||||
./configure --prefix=/usr/
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
Then I was able to ./configure && make && make install cfengine3 without any problems.
|
|
||||||
|
|
||||||
So my overall script looked something like this:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
wget http://fallabs.com/tokyocabinet/tokyocabinet-1.4.47.tar.gz
|
|
||||||
tar -xzvf tokyocabinet-1.4.47.tar.gz
|
|
||||||
cd tokyocabinet-1.4.47/
|
|
||||||
./configure --prefix=/usr/
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
wget http://cfengine.com/source-code/download?file=cfengine-3.3.1.tar.gz
|
|
||||||
tar -xzvf cfengine-3.3.1.tar.gz
|
|
||||||
cd cfengine-3.3.1
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
sudo cp /var/cfengine/bin/cf-* /usr/bin/
|
|
@ -1,67 +0,0 @@
|
|||||||
Getting started in Python Part 1
|
|
||||||
################################
|
|
||||||
:date: 2013-07-02 03:59
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: python, pip, virtualenv
|
|
||||||
:slug: getting-started-in-python-part-1
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I have a friend who is interested in becoming a Python developer. He has some Python experience with CodeAcademy, but he of course wants to take this a step further and develop on his own computer. I figure I'd give him a few pointers, and I know this has been rehashed a million times, but what the hell, why not blog on it again.
|
|
||||||
There are a few important things to learn besides the actual language itself. The first I am going to discuss is has to deal with installing packages, then followed up closely with Python's path trickery. Finally I'm going to wrap up by discussing some software related to development, that could be used for any language, but I use daily in my work as a Python Software Engineer. Let's get started.
|
|
||||||
|
|
||||||
PIP
|
|
||||||
---
|
|
||||||
|
|
||||||
Python is a wonderful language, but how useful would it be if you had to rewrite everything by hand? Not useful at all. That's why the lovely pip developers were born. `PIP <https://pypi.python.org/pypi/pip>`__ (executable pip) is a package manager written for Python. It's very simple to use, and in my opinion is way better than easy_install. To use pip you need to know at a minimum three commands.
|
|
||||||
|
|
||||||
``pip install``
|
|
||||||
|
|
||||||
This command does exactly what it says on the box. It queries PyPI (Python Package Index) and downloads the latest version of the package on the server. It then installs it to your site-packages.
|
|
||||||
|
|
||||||
``pip uninstall``
|
|
||||||
|
|
||||||
This deletes all files associated with the package supplied. 100% simple.
|
|
||||||
|
|
||||||
``pip freeze``
|
|
||||||
This shows what packages are installed on your system and what versions. If you supply ‐‐local it will show what packages are installed in your current environment.
|
|
||||||
These three commands will get you started with package management, there are more commands you can find by looking through the help documents.
|
|
||||||
|
|
||||||
Virtualenv
|
|
||||||
----------
|
|
||||||
|
|
||||||
If you notice I mentioned a current environment in my previous ``pip freeze`` explanation, here is why. Python has a default place that it looks when you reference a package. This is generally in something like ``/usr/lib/python2.7/site-packages/`` or ``C:\Python27\lib``. There is a set of scripts called ``virtualenv`` that creates an environment where you run it with a complete copy of your Python executable, and a blank (unless you copy them over) site-packages directory. You can then install any packages there activate the virtual environment. When activated you use those specific versions, no matter the version of what is installed on your system.
|
|
||||||
|
|
||||||
Let's show an example of the first time use of ``virtualenv``:
|
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ sudo pip install virtualenv # Only time you might need sudo, try without first.
|
|
||||||
$ virtualenv myenv # Create the virtual environment
|
|
||||||
$ source myenv/bin/activate # Activate the virtual environment
|
|
||||||
(myenv)$ python -c "import MYPACKAGE; print MYPACKAGE"
|
|
||||||
|
|
||||||
Notice how it says your package is not in ``/usr/lib/python2.7/site-packages/`` ? That's because you're using ``virtualenv`` to tell your copied python to use that library instead. There are many reasons you would want to use a virtual environment. The most frequent reason is to preserve version numbers of installed packages between a production and a development environment. Another reason virtualenv is useful if you do not have the power to install packages on your system, you can create a virtual environment and install them there.
|
|
||||||
|
|
||||||
Virtualenvwrapper
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
After you create a virtual environment, you just run``source bin/activate`` and it will activate the virtual environment. This can get tedious knowing exactly where your virtual environments are all the time, so some developers wrote some awesome scripts to fix that problem. This is called``virtualenvwrapper`` and once you use it once, you will always want to use it more. What it does is that it has you create a hidden directory in your home directory, set that to an environment variable and references that directory as the basis for your virtual environments. The installation of this is pretty easy, you can``pip install virtualenvwrapper`` if you want, or download the package and compile by hand.
|
|
||||||
|
|
||||||
Once installed correctly, you can run the command ``mkvirtualenv envname`` to create a virtual environment. You can then run``workon envname`` from anywhere, and it will activate that environment. For example, you could be at``/var/www/vhosts/www.mysite.com/django/`` and run``workon envname`` and it would activate the environment from there. This isn't a required package (none of them are really…) as I went a couple years without using``virtualenvwrapper``, but it is very useful and now I use it every day. Some tips I use with my setup of``virtualenvwrapper`` is that I use the postactivate scripts to automatically try to change into the proper project directory of my environment. This also means I usually name my``virtualenv`` after my project name for easy memory. It makes no sense to have a project called "cash_register" but the``virtualenv`` be called "fez". This is how I change to the right project after activating my ``virtualenv``. This goes in ``$WORKON_HOME/postactivate``
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
#!/bin/bash
|
|
||||||
# This hook is run after every virtualenv is activated.
|
|
||||||
# if its a work or a personal project (Example)
|
|
||||||
proj_name=$(echo $VIRTUAL_ENV|awk -F'/' '{print $NF}')
|
|
||||||
if [[ -e "/Users/tsouza/PersonalProjects/$proj_name" ]]
|
|
||||||
then
|
|
||||||
cd ~/PersonalProjects/$proj_name
|
|
||||||
else
|
|
||||||
cd ~/WorkProjects/$proj_name
|
|
||||||
fi
|
|
||||||
|
|
||||||
This about wraps up part one of this two part blog series. Next time I will discuss how to use Git and how to configure SublimeText2 and Aptana Studio for use with Python. Stay tuned!
|
|
@ -1,31 +0,0 @@
|
|||||||
Help, I have too many Django ManyToMany Queries [FIXED]
|
|
||||||
#######################################################
|
|
||||||
:date: 2013-08-06 04:00
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: python, django, bugs
|
|
||||||
:slug: help-i-have-too-many-django-manytomany-queries-fixed
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
My boss tasked me with getting the load time of 90 seconds(HOLY CARP!) on one page down. First thing I did was install the Django Debug Toolbar to see what was really happening.
|
|
||||||
|
|
||||||
There are currently 2,000 users in the database, the way our model is setup is that a UserProfile can have other UserProfiles attached to it in one of three M2M relations, which in the Django Admin would cause 2,000 queries PER M2M field. This is very expensive as obviously you don't want 10,000 queries that each take 0.3ms to take place.
|
|
||||||
|
|
||||||
The solution, after a day and a half of research is to override the **formfield_for_manytomany** method in the Admin class for our UserProfile object.
|
|
||||||
|
|
||||||
Our solution is to prefetch for any M2M that are related to the current Model.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
|
||||||
if db_field.__class__.__name__ == "ManyToManyField" and \
|
|
||||||
db_field.rel.to.__name__ == self.model.__name__:
|
|
||||||
kwargs['queryset'] = db_field.rel.to.objects.prefetch_related("user")
|
|
||||||
return super(UserProfileInline, self).formfield_for_manytomany(
|
|
||||||
db_field, request, **kwargs)
|
|
||||||
|
|
||||||
This goes inside our admin class **UserProfileInline(admin.StackedInline)**. Simple clean and easy to drop into another ModelAdmin with minimal changes.
|
|
||||||
|
|
||||||
Other things I pondered was to set all our M2M's as raw_id_fields, then using Select2 or Chosen, query our UserProfiles when the related users were being selected. This would take a lot of load off the initial page load, but is more of a bandaid rather than a real fix.
|
|
||||||
|
|
||||||
I tried to override the Admin class's **def queryset(self, request):** but this was not affecting anything.
|
|
@ -1,36 +0,0 @@
|
|||||||
How to not trigger a post_save in Django, but still modify data.
|
|
||||||
################################################################
|
|
||||||
:date: 2013-11-13 03:58
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: django, python
|
|
||||||
:slug: how-to-not-trigger-a-post_save-in-django-but-still-modify-data
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
Recently I have been diving into using signals with Django, which of course are pretty neat.
|
|
||||||
|
|
||||||
I am working on a website for work which in the most basicexplanation, is a task management site. Recently I have added in the ability to subscribe to tasks and get emails, I did this by connecting to the post_save signal. I only email out when a task is changed, not created (of course, no one would be subscribed to it). This worked flawlessly and "emails" out to anyone who is subscribed. I say that in quotes, because I haven't actually hooked it up to a real SMTP server, and only use
|
|
||||||
|
|
||||||
.. code-block:: shell
|
|
||||||
|
|
||||||
python -m smtpd -n -c DebuggingServer localhost:1025
|
|
||||||
|
|
||||||
which will output any emails to stdout. But I digress… A problem arose when I was working on ordering tasks.
|
|
||||||
|
|
||||||
I store an integer in the "ordering" column, which any authenticated user can drag the row to a new location and that will reorder the task. I did this after I setup the emailing signal, so I didn't think about an email being sent out for EVERY task being changed.
|
|
||||||
|
|
||||||
I tried a lot of different things, and was debating some that would be a bit messy. Among those ideas were trying to store the past values in another table, but that would get expensive fast. The reason I tried this was because I wanted to see if the ordering was the only thing that changed, and if that was the case, not send an email. I eventually found a thread on StackOverflow that says to use update on the queryset to not trigger the signal.
|
|
||||||
|
|
||||||
You can do this by doing something like this:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from app.models import ModelName
|
|
||||||
|
|
||||||
def reorder(request):
|
|
||||||
new_order = request.POST.get('new_order', None)
|
|
||||||
pk = request.POST.get('modelname_pk', None)
|
|
||||||
if new_order:
|
|
||||||
ModelName.objects.filter(pk=pk).update(ordering=new_order)
|
|
||||||
|
|
||||||
I am not sure if this is the proper way save changes and not trigger a post_save signal, but this is the way that worked for me so I figured I would document this.
|
|
@ -1,43 +0,0 @@
|
|||||||
Readline
|
|
||||||
########
|
|
||||||
:date: 2014-06-21 04:01
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: readline, linux, cli
|
|
||||||
:slug: readline
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
A lot of times when I stop at someone's computer and help them in the terminal, I use a Readline command and people say "How the heck did you do that?"
|
|
||||||
|
|
||||||
Let me first backup and explain what Readline is. From the GNU Readline Documentation - "The GNU Readline library provides a set of functions for use by applications that allow users to edit command lines as they are typed in." By default, Readline is set up in Emacs mode, no you don't have to have an extra four fingers to use Readline, most of the commands are simple.
|
|
||||||
|
|
||||||
Here are a couple of the commands I use daily:
|
|
||||||
|
|
||||||
|
|
||||||
Movement
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
- To move to the beginning of a line, you press ``C-a``
|
|
||||||
- To move to the end of a line you press ``C-e``
|
|
||||||
|
|
||||||
Killing and Yanking
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
- To cut the rest of the line from where your cursor is, to the end, you press ``C-k``
|
|
||||||
- To delete one word you press ``C-w``
|
|
||||||
- To paste either of the two previous back you can press ``C-y``
|
|
||||||
|
|
||||||
Miscellaneous
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
- To clear the screen and get to a fresh start, you can press ``C-l``
|
|
||||||
- To end your session you can send a ``C-d`` (This will send an end of file character)
|
|
||||||
- To search for a command you typed recently, press ``C-r`` and start typing, it will search backwards. ``C-r`` again will search for an earlier match.
|
|
||||||
- The inverse of ``C-r`` is ``C-s``, they function the same.
|
|
||||||
- To open your ``$EDITOR`` to edit the current shell command you wish to write, press ``C-x C-e``
|
|
||||||
|
|
||||||
Finally, don't forget about ``C-c``. While not specifically Readline, it's very useful because it sends the SIGINT signal to the program, which if just on the command line, will not execute the line you have type, and give you a new line with nothing on it. A nice clean start.
|
|
||||||
|
|
||||||
To find out a lot more, read the documentation at `the Readline Commands Docs <http://www.gnu.org/software/bash/manual/html_node/Bindable-Readline-Commands.html>`__ I even learned some things while writing this up, apparently pressing ``C-x $`` will list off all the possible usernames. Good to know, and good to always keep learning.
|
|
||||||
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
First day back in Java since college
|
|
||||||
####################################
|
|
||||||
:date: 2014-10-01 04:03
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: java
|
|
||||||
:slug: java
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
Recently I decided I wanted to learn Java again. I last programmed in Java when I was in College and that was the main language they taught in. I wouldn't say I was a great Java developer, although I completed every Java course well enough to get an A or better.
|
|
||||||
|
|
||||||
I want to relearn Java because for the past four years I have primarily focused on Python. While it is a great language, I feel I need a change from what I'm focusing on now with primarily web based programming.
|
|
||||||
|
|
||||||
I decided to refresh myself with Java and read a "Java for Python developers" guide, which was a great refresher. After that I sat around wondering what to program, inspiration wasn't coming quickly. I settled on a SSH Configuration Manager, which is something I've wanted for a while now.
|
|
||||||
|
|
||||||
This Configuration Manager will read in your ~/.ssh/config files, and show you what hosts you have in a GUI interface. The great part of it will be that you can also create new ssh configurations, without having to remember every little detail. There will be a lot of help tooltips, and pre-fills as well. I have a pretty basic idea of what I want it to look like. Ideally a list on the far left with +/- buttons to add a new Host, and to the right of that will be another hierarchy list of all the key groups you can change, with the most common (that I or people I talk to) being in a "General" or "Common" list. To the right of that will be the actual keys and values you change. I think I would like to be able to "favorite" keys that you use frequently. This way when you create a new host entry, you can quickly fill out your usual configurations be it only adding an IdentityFile and User. Another feature I thought of would be copying/templating, for example being able to create a new "work based server" configuration by just copying one you already have.
|
|
||||||
|
|
||||||
Some of the options will be a bit tricky, a couple of them are along the lines of allowing "yes", "no", "ask", or an integer, and I haven't figured out exactly how I want to manage that yet.
|
|
||||||
|
|
||||||
Currently I have a model that only has getters/setters and toString support, there's a lot of them so it's already a 1050 line file last I checked. Next time I work on this project I want to start with data validation and learning how to write tests in Java. I think learning good BDD or TDD habits while learning a "new" language would definitely benefit me.
|
|
@ -1,25 +0,0 @@
|
|||||||
SSH Agent on "boot"
|
|
||||||
###################
|
|
||||||
:date: 2015-01-09 04:03
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: linux, ssh
|
|
||||||
:slug: ssh-agent-on-boot
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I had a friend complain that he had to keep adding his ssh key to his ssh-agent every time he rebooted. I have a really easy bit of shell code you can put into your .bashrc or your .zshrc file:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
SSHKEYFILE=/path/to/your/ssh/key/file
|
|
||||||
ssh-add -l | grep -q $SSHKEYFILE
|
|
||||||
RC=$?
|
|
||||||
if [ $RC -eq 1 ]
|
|
||||||
then
|
|
||||||
ssh-add -t 86400 $SSHKEYFILE
|
|
||||||
echo "Added key internal to keychain."
|
|
||||||
fi
|
|
||||||
|
|
||||||
This will check every time your bash or zsh rc file is sourced for your key in the currently added keys, and if it's not, it will add it.
|
|
||||||
|
|
||||||
This has the benefit of not requiring you to put in your password every time you connect to a remote machine if you password your ssh keys (which you should).
|
|
@ -1,10 +0,0 @@
|
|||||||
Python Debugger
|
|
||||||
###############
|
|
||||||
:date: 2015-01-13 04:02
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: python, pdb
|
|
||||||
:slug: python-debugger
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
When I worked at Propel Marketing, my dev team used to have presentations on things they loved. I love the Python debugger. It's very useful and I believe a proper understanding of how to use a debugger, will make you a better programmer. Here is a presentation on the debugger I made for my team. https://prezi.com/cdc4uyn4ghih/python-debugger/
|
|
@ -1,20 +0,0 @@
|
|||||||
Too many open files
|
|
||||||
###################
|
|
||||||
:date: 2015-01-28 04:02
|
|
||||||
:author: tyrel
|
|
||||||
:category: Tech
|
|
||||||
:tags: python, linux, ulimit, bugs
|
|
||||||
:slug: too-many-open-files
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
When I worked at Propel Marketing, we used to outsource static websites to a third party vendor, and then host them on our server. It was our job as developers to pull down the finished website zip file from the vendor, check it to make sure they used the proper domain name, (they didn't a lot of the time,) and make sure it actually looks nice. If these few criteria were met, we could launch the site.
|
|
||||||
|
|
||||||
Part of this process was SCPing the directory to our sites server. The sites server was where we had Apache running with every custom static site as a vhost. We would put the website in ``/var/www/vhosts/domain.name.here/`` and then create the proper files in sites-available and sites-enabled (more on this in another entry). After that the next step was to run a checkconfig and restart Apache.
|
|
||||||
|
|
||||||
Here's where it all went wrong one day. If I can recall correctly, my boss was on vacation so he had me doing a bit of extra work and launching a few more sites than I usually do. Not only that, but we also had a deadline of the end of the month which was either the next day, or the day after. I figure I'll just setup all mine for two days, and then have some extra time the next day for other things to work on. So I started launching my sites. After each one, I would add the domain it was supposed to be at into my ``/etc/hosts`` file and make sure it worked.
|
|
||||||
|
|
||||||
I was probably half way done with my sites, and suddenly I ran into one that didn't work. I checked another one to see if maybe it was just my network being stupid and not liking my hosts file, but no, that wasn't the problem. Suddenly, EVERY SITE stopped working on this server. Panicking, I delete the symlink in sites-enabled and restart Apache. Everything works again. I then proceed to put that site aside, maybe something in the php files breaks the server, who knows, but I have other sites I can launch.
|
|
||||||
|
|
||||||
I setup the next site and the same thing happens again, no sites work. Okay, now it's time to freak out and call our sysadmin. He didn't answer his phone, so I call my boss JB. I tell him the problem and he says he will reach out to the sysadmin and see what the problem is, all the while I'm telling JB "It's not broken broken, it just doesn't work, it's not my fault" etc etc. A couple hours later, our sysadmin emails us back and says he was able to fix the problem.
|
|
||||||
|
|
||||||
It turns out, there's a hard limit to the number of files your system can have open per user, and this was set to 1000 for the www-data user. The site I launched was coincidentally the 500th site on that server, each of them having an access.log and an error.log. These two files apparently constantly open on each site for apache to log to. He was able to change www-data's ulimit to a lot higher, (I don't recall now what it was) and that gave a lot more leeway in how many sites the sites server could host.
|
|
@ -1,12 +0,0 @@
|
|||||||
May 26, 2021 - First flight as a PPL
|
|
||||||
####################################
|
|
||||||
:author: tyrel
|
|
||||||
:category: flying
|
|
||||||
:tags: flying
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
On April 26th, I took my first flight as a Private Pilot. I was flying with a CFI for a checkout to rent planes from the Wings of Carolina club, so the flight was nothing really to talk much about. It was really hot, and my first flight in almost 5 months, so I was definitely rusty.
|
|
||||||
|
|
||||||
Mostly using this flight as a stepping stone to try out the GPX viewer§. I flew a PA28-161 - Warrior II - N8080A for One hour. Flew from KTTA, up north west a bit, did a few steep turns, then back to KTTA.
|
|
||||||
|
|
||||||
§ - Not ported over, no JS on this blog.
|
|
@ -1,37 +0,0 @@
|
|||||||
May 27, 2021 - Second flight as a PPL
|
|
||||||
#####################################
|
|
||||||
:author: tyrel
|
|
||||||
:category: flying
|
|
||||||
:tags: flying
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I was able to sneak in a cooler morning flight in N8080A. I took my motorcycle to the airport, but forgot my yoke mount so I was iPad-less. We had to wait for a long while to get fuel because the services truck was filling the HU-16 that had arrived a few days beforehand. There was also a C-27 taking off, super cute, Feels like a baby C-130!
|
|
||||||
|
|
||||||
.. figure:: {static}/images/2021/05/20210527_hu16.jpg
|
|
||||||
:alt: Grumman HU-16 Albatross
|
|
||||||
|
|
||||||
Grumman HU-16 Albatross
|
|
||||||
|
|
||||||
.. figure:: {static}/images/2021/05/20210527_c27.jpg
|
|
||||||
:alt: Alenia C-27J Spartan
|
|
||||||
|
|
||||||
Alenia C-27J Spartan
|
|
||||||
|
|
||||||
We went up, took a few minutes to do another 45° bank turn. I did that a little better, less shaky. Then he had me practice some emergency descents. I didn't do as well at those as I should. I need faster ADM skills. That will come with time, one of my big weaknesses is emergency things, so it's one thing I'm excited to start practicing.
|
|
||||||
|
|
||||||
After the emergency procedures, he had me practice rudder control. Putting in enough rudder while turning to hold on target before the turn and rolling out while pointing at a target - but rolling out. I'm much better at rolling out than rolling in, so I'm excited to have a new procedure to practice. One of the things I like a lot about this CFI giving me the checkout to borrow planes, is that he's young. He doesn't have these really old ways of thinking about things and I appreciate that.
|
|
||||||
|
|
||||||
After the higher altitude stuff, he wanted to see some short-field landings. The first time in the pattern we had to extend our downwind A LOT, there were three people on long finals, so our downwind was funky and long. I'm still getting used to this plane and the runway so by the time we were about to touch down, the other plane in front of us was still on the runway (albeit turning onto taxiway A3 a mile down the runway) so he said go around, as technically the other plane was still on the runway and things could go wrong even with that far separation.
|
|
||||||
|
|
||||||
Did a go around and the next two short fields were okay. We got off at Taxiway A2 I think, and then took taxiway A back to the ramp. When we got to the intersection with A and A1 there was another plane getting ready to cross the threshold, but it was a Cessna 172… high wing! They didn't notice that there was a taildragger apparently norad coming on a 45° final, not straight in and almost rolled into the runway. Luckily the CFI I was with shouted STOP on the CTAF and they stopped, seconds before an incursion! EEEEK!
|
|
||||||
|
|
||||||
Wrapped up, and planned our third checkout ride, it'll be down to KFAY, a controlled field. Should be on June 2nd and then I'll be cleared to rent the planes and feel like a full member of the Wings of Carolina!
|
|
||||||
|
|
||||||
Unfortunately no GPX file, but I have a screenshot.
|
|
||||||
|
|
||||||
|
|
||||||
.. figure:: {static}/images/2021/05/20210527_track.png
|
|
||||||
:alt: GPX Track across the Raleigh Durham area west of Jordan Lake
|
|
||||||
|
|
||||||
GPX Track across the Raleigh Durham area west of Jordan Lake
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
WOC Final Checkout Ride
|
|
||||||
#######################
|
|
||||||
:author: tyrel
|
|
||||||
:category: flying
|
|
||||||
:tags: flying
|
|
||||||
:status: published
|
|
||||||
|
|
||||||
I can finally rent planes through Wings of Carolina! Flew today and the CFI passed me.
|
|
||||||
|
|
||||||
I was a bit nervous about the North Carolina weather so I text the instructor to see if we could leave an hour early for the controlled airspace portion of the checkout. He said let's shoot for 3:30, we took off at 4 because he gave me a bit of ground instruction on the systems in N8116J. (Also we couldn't figure out the radio, so had to push a few buttons to get comms working. It seems when 16J was in the shop, they had undone all the COM1 COM2 selection buttons, which caught us off guard.)
|
|
||||||
|
|
||||||
We took off, then flew south to Fayetteville (KFAY), Luke showed me the auto pilot, how to climb, descend, turn to a heading, so we enabled that on the flight to KFAY. 20 miles north, called approach, I fumbled my radio A LOT. I definitely need more controlled airspace practice. ATC Talks FAST. It's hard to fly the plane and copy things down, I think I need to start using a pen and paper, not Foreflight for ATC remarks, it'll be much easier. I put a FieldNotes book in my flight bag the other day, time to use it! After a few more fumbles (I copied back the altimeter, not the altitude, talk about stress!) I was cleared to land. Squawked 0210 and landed on runway 22 almost straight in, I took a right handed base, it was weird! There were no commercial flights so they were at a lull of traffic which is why I just got the RWY22 CLEAR TO LAND. Unfortunately (or Fortunately..) LIVE ATC and KFAY approach are down so I have no recording of my fumbles. Would have been nice to hear them again so I could learn.
|
|
||||||
|
|
||||||
We landed, taxied back to runway 22, and then said we were taking off VFR. Squawked 0212 now and departed, stayed runway heading until they said turn right heading 320 staying at or below 2500. Then a bit later they said fly flight plan heading I turned 355 and then we finally got out of their airspace. There's two airports there, KFAY and Simmons Army Airfield (KFBG), so their airspace looks like a cell dividing, two round circles and of course we bisected it the long way.
|
|
||||||
|
|
||||||
Out of their airspace Luke said "I have the controls", then banked hard 60 degrees right, and pointed down. He said "If you're ever VFR and inadvertently hit IMC weather, and get into an unusual attitude, hit this button [LVL] and presto, the wings will level." which of course they did. Auto pilot is still wild to me, I never flew with it in N43337, so it's going to take a lot to get used to, but I'm sure I'll start loving it.
|
|
||||||
|
|
||||||
We then called 10mi on the 45 for RWY22, did a touch and go, (I came in a little higher than I wanted I still need to learn the sight pictures for this airport, but oof it's FLAT still.) took off did the pattern once more and did a full stop.
|
|
||||||
|
|
||||||
On this flight, I learned the GPS a little bit more, the touch screen menu will make selecting comms so much easier, glad they have these consistently in all their planes. I also learned AutoPilot, I need to find a flight sim model with this auto pilot (I did get a Logitech/Saitek Multi Panel with AutoPilot on it this weekend, so good timing!) that I can learn how the IAS, ALT, VS, HDG buttons work better. HDG and ALT I get, those just hold heading and alt, but airspeed and vertical speed climbs are still magical!
|
|
||||||
|
|
||||||
Luke then signed me off, so I'm clear to rent any of the PA-28-161 that they have at Wings of Carolina. I told him I want to learn how to fly the Mooney M20J soon, I'm excited to get my complex endorsement.
|
|