Blog

typewriter with paper
published: 3/3/24 1:01 a.m.

Back up

I don't know when my website went down, but it's been down for a while.

Getting it backup has been difficult. Most of the technologies it's based on are 5 years old. I think there was a specific issue with gunicorn that kept it from reloading.

I spent today moving my db from postgres 10 to postgres 14. Updating all the requirements.... Django changed from 2 to 5.

Personally, I think it's time to rewrite this in a new technology. New to me. Might be a chance to rebuild this in Java/Spring.

grid of bingo boards
published: 12/13/21 3:03 a.m.

AoC Day 12

Long Days...

I started a post 12 hours ago about how Day 12 was giving me the opportunity to revisit graph theory.

Well, I revisited. Then I wrote Part one, and it made me feel pretty smart. Then I drew a blank on part two. Then I was interrupted by a needing to perform Wordpress installs on Docker containers to use as a test bed for another project I'm working on. Because I rarely use Docker, I needed to revisit docker theory as well. With a little Wordpress theory thrown in for good measure.

Hours later, coming back to part two was daunting. I had written up pseudo code on my whiteboard. It was close to working out, but I kept having to go back and clean up the mistakes. Keep tweaking the code until it passed the tests. It moved a lot slower than when I wrote the pseudo code. I can't tell if the clean up was harder or if exhaustion makes me slower.

All in all it's finished. I'm a little dissatisfied with my performance, but only 30,000 people finished globally. That's 20% of the people that finished Day 1

typewriter with paper
published: 12/10/21 12:12 a.m.

ReportLab

So, Let's say you have... a couple dozen quotes to create for some customers. Option one: make some coffee, open up Wave, and work your way down the spreadsheet one painful quote at a time. Let's estimate 2 uncomfortable hours.

Option two: Clean up the data in your spread sheet. Write a program to import the data, and create PDFs. Much more interesting... significantly longer time. Maybe.... near the end, one might decide to do it manually... we'll see.

So far I'm working my way through option one. The first step was finding out what it takes to write a PDF. I was expecting/hoping for something like creating a web page. One of the options for creating PDFs in python is called ReportLab. It's been around for a decade or two and I'm pretty sure it's the framework my credit card company uses to create pdfs.

It's more than able to create the reports and making them look good. It reminds me of building websites in vanilla js. Doable, easier than it looks, but still a pain in the ass.

grid of bingo boards
published: 12/6/21 4:04 a.m.

AoC Day 4

I generally want to do visualizations on my advent of code projects, but normally do not have the time. I did my initial programming of Day 4 in python then converted it to JS. It was fairly easy to create the grid and run the visualization once that was done.

I'm left... wanting to improve the page. Add a number call out, add an overlay to each board, etc., etc., but the weekend was full of many projects and there is only so much time. I want to add the page to my website, but I'm a little apprehensive of taking on that much work with so many other things in the pipeline.

Ascii art image of Santa's holiday route
published: 12/3/21 6:06 p.m.

Advent of Code Day 3

Took a bit longer to make it through my AoC problems today. I kept reversing my bits.

Yesterday, I wrote a tiny script to create a daily directory, download and save my problem input to a file in that directory and create a starter.py file. That time savings, probably 30 seconds, makes AoC a little more pleasant to play.

my solution: https://github.com/tyday/AdventofCode2021/tree/main/Day03

best solution I've seen all day: https://www.reddit.com/r/adventofcode/comments/r7x4yk/2021_day_3_part_2pygame_oxy_filter/

Graph showing minor difference between lighting sources.
published: 4/13/21 12:12 p.m.

Power failures

The sensors started failing early last night. I believe sensor 2 started connecting less frequently around 7PM. They both seemed to completely lose contact around 2AM and only reconnected this morning around 7AM.

I'm trying to figure out how to implement saving to the Real Time Clock memory so that I can implement a 60 readings per hour/ one upload per hour solution. Off to google.

Graph showing minor difference between lighting sources.
published: 4/12/21 10:10 p.m.

None as of yet

I've been working on a couple coding projects around the house.

Last year at this time I had a green house project going. It was mostly to learn how to build IOT devices and deploy them. I also wanted to create a gui/display. My long-term goal was to replace my store bought weather center with a home made weather center.

What did I learn?

After taking the seed garden apart 1, I used the esp8266s to build some sensors to put up outside and around the house. I also picked up a raspberry pi to run its own indoor sensor and to host sensor related stuff. It came with Node-Red. Node red makes building a GUI easy. I chose to use MQTT to deliver information across the network and Node-red easily deals with MQTT. My favorite thing about Node-Red so far is that it's easy to come back to a project and figure out what it is doing and how it is doing it.

This year, we've decided to find a better place to grow tomatoes in the yard. Last year, we didn't see a good yield from our beef stake tomatoes. I built a couple light sensors with the ESP8266 modules.But, I needed to use batteries to power them instead of plugging them in. It's forced me to learn how to switch the device into low power mode as well as trouble shoot a few issues where I was losing power. I tested one in house for a couple days and it seems to have done well on battery. I just deployed to units out into the backyard. They're farther from the router and it's taking them longer to connect and transmit data. I'm wondering how much it will effect their battery life.

If the battery life is too short, I have another plan. Currently, they're connecting to the network after every reading. If I have to rework the code, I'll have them upload after an hour or two, possibly daily.

Next Steps


  1. Our garden mostly failed. I think the seed survival rate was less than 10%. Which brings me back to store bought vs home made. We were gifted an Aerogarden late this winter/early spring. It's already produced more plants than our garden last year. I think it's rate has been 100% so far. 

Conditions indicators of the arduino greenhouse
published: 3/8/20 12:12 p.m.

https

So, this morning I was surprised to wake up and discover my device had not updated in 3 hours. I tried to turn it off and on again, that didn't solve the problem, but at least the LEDs flickered on for half a second indicating it did have power and was likely working.

My first thought was that the website security certificate may have changed. So I followed up turning it off and on again with checking the /var/log/nginx/access.log which stated the following at 10:12:16 GMT

[08/Mar/2020:10:12:15 +0000] "POST /garden/api/readings.json/ HTTP/1.1" 201 113 "-" "ESP8266HTTPClient"
2600:1f16:269:da01:4e9f:c9d7:3ffe:6166 - - [08/Mar/2020:10:12:16 +0000] "GET /.well-known/acme-challenge/WrEvWgDp4cNpjjLpjglSja
1I90YFgAxTkW68YjoR2z4 HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.
org)"
2600:1f16:269:da01:4e9f:c9d7:3ffe:6166 - - [08/Mar/2020:10:12:16 +0000] "GET /.well-known/acme-challenge/ytSN6CxKtvhV19wks2bomt
q8ph6XdF6L7KjDA34aVso HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.
org)"

08/Mar/2020:10:12:15 +0000 was the time of my last successful update. I believe the next connection was from Let's Encrypt verifying that the update was successful.

I checked the certificate in my browser and it had this information at the bottom.

**Timestamp** 3/8/2020, 6:12:50 AM (Eastern Daylight Time)
**Signature Algorithm** SHA-256 ECDSA

I believe this was Let's Encrypt auto updating my certificate this morning. This is a month ahead of schedule, which reinforces that I don't know how that process works.

The issue is that the ESP2866 doesn't quite have the capability to connect to https servers. Or it does, but it requires a work around. I hard coded the SHA-1 fingerprint into the sketch. It wasn't ideal, it wasn't exactly what I wanted to do, but, I believed the certificate was good for another month, so it would work for the planned life of the project.

This morning, I will need to update the fingerprint on the sketch. I may change to using the root certificate which has a much longer life time. I may try to set a system up that auto updates the fingerprint.

Close up of ESP8266
published: 3/6/20 4:04 a.m.

ESP8266

The arduino garden project has taken a turn.

The ESP8266 is a board similar to the arduino but with a built in wifi chip. They are also very inexpensive. I was able to get three for the price of a single arduino duo.

The ESP opens up a lot of possibilities. MQTT is a message queuing system that uses wifi allowing subsciptions would allow a bunch of sensors to communicate with each other, or a central system. But for the greenhouse project I'd be able to log the info directly to the server and skip the tablet all together.

Earlier today, while I was thinking that this solves a bunch of "problems" the electricity went out. The EPS, which I was testing at the time, was suddenly unable to upload because it no longer had access to wifi. Which is bringing me to the issues I'm currently thinking over. What do I do about data? Should I store the data on the chip, or locally somehow and then check to see if the server has it from time to time and then upload old data. For this project that's overkill, but it seems like an important question.

ESP8266 pinout

Design layout of greenhouse app
published: 3/2/20 7:07 p.m.

XAML

I started the C# of the project in a WinForms kind of place. The windows and code were tightly linked. I spent part of last week reworking the code to separate the project into a mvvm pattern. It's more work, but I find it very comforting that I can just delete a window and start over. I still need to create some converters to display the Unix Timestamp as a date. I would like to add charts in the next iteration.

<Window x:Class="Arduino_Greenhouse.View.DisplayWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Arduino_Greenhouse.View"
        xmlns:vm="clr-namespace:Arduino_Greenhouse.ViewModel"
        mc:Ignorable="d"
        Title="DisplayWindow"
        WindowState="Maximized" d:DesignWidth="1642.688" d:DesignHeight="763.75"
        >
    <Window.Resources>
        <vm:DisplayVM x:Key="vm"/>
    </Window.Resources>

    <Grid DataContext="{StaticResource vm}">
        <Grid.RowDefinitions>
            <RowDefinition Height="3*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0,0" StartPoint="1,1">
                <GradientStop Color="#fff2ab" Offset="0.88" />
                <GradientStop Color="#99da8f" Offset="0.33" />
                <GradientStop Color="#9382bb" Offset="0" />
            </LinearGradientBrush>
        </Grid.Background>

        <!--<Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>-->
        <Grid 
        Margin="50"
            VerticalAlignment="Center"
            HorizontalAlignment="Stretch"
            >

            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <StackPanel Grid.Column="0" Width="Auto" >
                <TextBlock Text="Environment" FontSize="48" TextAlignment="Center"/>
                <TextBlock Text="{Binding sensorReading.temp1, StringFormat={}{0:f1} °F}" FontSize="48" TextAlignment="Center"/>
                <TextBlock Text="{Binding sensorReading.rh1, StringFormat={}{0}% RH}" FontSize="48" TextAlignment="Center"/>
            </StackPanel>
            <StackPanel Grid.Column="1" Width="Auto">
                <TextBlock Text="Greenhouse" FontSize="48" TextAlignment="Center"/>
                <TextBlock Text="{Binding sensorReading.temp2, StringFormat={}{0:f1} °F}" FontSize="48" TextAlignment="Center" />
                <TextBlock Text="{Binding sensorReading.rh2, StringFormat={}{0}% RH}" FontSize="48" TextAlignment="Center" />
            </StackPanel>
            <StackPanel Grid.Column="3" Grid.Row="0" Width="Auto">
                <TextBlock Text="Conditions" FontSize="48" TextAlignment="Center"/>
                <TextBlock Text="{Binding sensorReading.light, StringFormat=Light: {0}}"   FontSize="48" TextAlignment="Center" />
                <TextBlock Text="{Binding sensorReading.timestamp, StringFormat={}Time: {0:f1}}" FontSize="48" TextAlignment="Center"/>
            </StackPanel>
        </Grid>
        <!--
            Here lies the connection buttons
        -->
        <StackPanel Orientation="Horizontal" Grid.Row="2" DataContext="{StaticResource vm}">
            <Button x:Name="btnGetPorts" 
                    Content="Get Ports" 
                    HorizontalAlignment="Left" Margin="10" Grid.Row="1" VerticalAlignment="Center" Width="75" 
                    Command="{Binding GetComPortsCommand}"
                    />
            <ComboBox x:Name="cboPorts"
                      ItemsSource="{Binding ComPortList, NotifyOnSourceUpdated=True}"
                      SelectedIndex="0"
                      SelectedItem="{Binding SelectedComPort, UpdateSourceTrigger=PropertyChanged}"
                      HorizontalAlignment="Left" Margin="10" Grid.Row="1" VerticalAlignment="Center" 
                      Width="120" RenderTransformOrigin="0.777,2.853"/>
            <Button  x:Name="btnConnect" 
                     Command="{Binding ConnectToArduinoCommand}"
                     CommandParameter="{Binding SelectedComPort}"
                     Content="{Binding ConnectButtonContent, NotifyOnSourceUpdated=True}"
                     HorizontalAlignment="Left" Margin="10" Grid.Row="1" VerticalAlignment="Center" Width="75">

            </Button>
            <CheckBox x:Name="cbUpload" Content="Upload to server" HorizontalAlignment="Left" Margin="10" Grid.Row="1"  VerticalAlignment="Center" />
        </StackPanel>


    </Grid>
</Window>
Spider lurks in the middle of a web
published: 3/2/20 4:04 a.m.

Markdown

I spent the greater part of the day attempting to upgrade the blogging capability of this site with markdown.

I've been planning on making the change for ages and this morning I ran across this post

"I was building a tiny microservice which would let the client side application securely authenticate with GitHub. After writing the only required API, I wanted to render the README.md file on the index page."

The lack of any type of styling in the previous sentence indicates I need to add blockquotes to my css style list. It's a pretty simple implementation. I've used it in Wagtail, but I didn't feel like my site needs all that wagtail brings along with it. I didn't want to have to redo all my fields with wagtail stream fields.

import markdown
from django import template
from django.template.defaultfilters import stringfilter
from pygments.formatters import HtmlFormatter

register = template.Library()

@stringfilter
@register.filter(name='markdown', is_safe=True)
def markdown_to_html(value):
    md_template_string = markdown.markdown(value, extensions=['extra', 'codehilite'])
    return md_template_string
    # formatter = HtmlFormatter(style="tango",full=True,cssclass="codehilite")
    # css_string = formatter.get_style_defs()
    # md_css_string = "<style>" + css_string + "</style>"

    # md_template = md_css_string + md_template_string
    # return md_template


# register.filter('markdown', markdown_to_html)

Most of this code has been commented out. It was initially used to experiment with the various pygment formatters. I'm afraid I'm going to run into problems with this implementation but I'm happy with it so far. And it makes blogging significantly more enjoyable than it was before.

analyzing web images with mozilla's developer tools
published: 10/21/19 2:02 a.m.

Responsive images. Part III

Added the elements from the weather app to the blog, project and front pages. The most difficult part was tracking down all the places it needed to be changed.

Initially, I only added a srcset attribute. I was a little disappointed that the browser kept choosing the largest or second to largest size. Coming back to it today I see that the sizes attribute was easy to use. I thought it was only applicable when using a media condition (max-width:480px). but all I needed to do was enter the image size. I was even able to use relative widths. Very simple, very cool.

Next: merge with master.

typewriter with paper
published: 10/19/19 11:11 p.m.

Responsive images

One of the things that has bugged me is that my images are not responsive. Since I've been working on rotating the images, it seemed like the perfect time to make the images responsive.

I decided to go simple. Instead of saving the location of the of the responsive images in the DB I decided to simply add images to the media folder. There are two steps to the process. First you have to add images then you have to get the list of images. Adding the images was simple enough, very similar to rotating them. The second step was a little more difficult.

Initially I added a get_srcset function to the observation model. The function assumed that the images would be named a certain way image.jpg image_1000.jpg, image_500.jpg, image_100.jpg. This way almost worked but I ran into issues in the html. If I didn't give width information with the images then the browser just picked the smallest image. When I added width information it was based on the assumption that image_1000.jpg had a width of 1000. But in cases where the image was taller than wide that wouldn't be correct.

I think I could have gotten width information when I ran the get_srcset function, but it seemed like repeated queries of the filesystem was a waste. So I added another field to the Db (source_set) intending to fill it when I built the images. This ran into its own problem. I had to save the observation after giving it the source set information. But I was running the function that created the responsive images in a post_save signal. If I added Observation.save() to the signal it just ran the function over and over. This required learning about disconnecting and reconnecting the django signaling system. It's a simple fix, and it seems to be working.

I'm about to move this to the live server. I'll have to monitor it to make sure it works correctly.

Photo by Sharon Pittaway on Unsplash
published: 10/19/19 3:03 a.m.

Weird errors - part 2

I set up Django signals to rotate images on save. I then ran a quick save program from the shell and checked out my images. There is no exif data in the images, but not all the images were rotated correctly. I think some of the images lacked the rotation information to begin with, but I'm not sure. Will monitor to see if it continues rotating images correctly.

The next step I need to take is setting up image sizing and then deploying the pictures using and srcset to stop using these oversized images.

typewriter with paper
published: 10/19/19 1:01 a.m.

Weird errors - part 1

So. It turns out Django has a limit on upload size of 2.5M. If a file is larger than 2.5 it goes straight to a temporary file, is manipulated and then copied over to the /Media folder. Files saved from memory have the permission of the owner (644) but files saved from the temporary folder have (644). Adjusting FILE_UPLOAD_PERMISSIONS allowed me to change this so the permissions are correct.

However, while looking through the images, I noticed that I'm very findable using the exif information uploaded with the images. The weird thing about that is opening an image with Pillow (django's image handling module) and then saving it again strips all the exif information from the image. So, it's clearly not that manipulated when the image is initially uploaded.

So... steps that have to be taken.

1.) Fix it so that images are correctly rotated upon upload. 2.) Strip the exif information from the images.

Photo by Sharon Pittaway on Unsplash
published: 10/19/19 12:12 a.m.

Weird errors

I've been running into some problems with my weather app.

The new iphone doesn't honor the font-size 16 fix that seemed to allow the form to look nice on my older iphone.

It turns out I've been taking photos upside down on my phone. The web page doesn't honor exif data, which is something I didn't know. It turns out there was a fix built into firefox 6 years ago, but it's still in experimental stages in firefox (and I can't get it to work. I believe the image needs to be in the css and not in ) and not available in any other browser. Oddly enough, the images display accurately in Safari.

Additionally, while looking into this tonight, I've run into another problem. Django is saving images to the media folder with the wrong permissions. There's no read access to anyone but the owner. So, I have to figure the problem out.

I'm writing this post here simply to run an experiment where I add a photo to this post to see if the issue is throughout Django or simply with the weather app.

edit So.... oddly enough, this picture upload worked. The error is somewhere in the weather app.

Photo by Sharon Pittaway on Unsplash

Heat map graph of Columbus temperatures in July 2019
published: 7/22/19 4:04 p.m.

Adventures in Graphing

I've been working on a weather logging addition to my website. I took a weather course a few months ago and decided to do the logging on my site rather than on paper or in google sheets. It seemed like a decent way to combine web development with an elective.

It's working ok. The only issue I'm having is showing the data. It's in a big ugly table. Which is ok on desktop but not very nice on mobile. I decided to try to do some data visualization tutorials in an attempt to find something that might work to present my data better.

The course I found was super basic. But, it turns out I needed that level. I don't know my way around graphs very well.

I'm a few days into the course now. I've been applying it to the data I've been working with. The heat map won't solve my issue, but it was my first attempt to work with live data.

Black hole lensing
published: 5/21/19 2:02 a.m.

Clearing space

Spent the past two days developing a system to save performer images to the ComFest server rather than relying on the links provided by the performer. Jared was gathering image information and supplying it to the google sheet where the acts are approved. It seemed most of the links were facebook and it seems like the links have a time limit to them. I'm not sure how long they last, but last year I noticed the images were no longer populating in the Web App when I checked it a few months after the festival. Jared was running into issues where he could see the image during the festival but other people could not, probably due to caching.

There is one advantage to the current system. Other servers bear the load.

So we have the link to the image stored in a text string. I've passed that string off to the PWA as well as the new schedule plugin I built for the wordpress website. The images are whatever size was uploaded. Anything from a couple hundred pixels in width to a couple thousand.

The new system takes those links and then copies a 400pixel and 100pixel image onto our server with the median size being 17Kb and 2Kb. On the wordpress site we're using a 100px square for the image. Currently they average 80Kb in size. Changing to our hosted icons leads to a 97% reduction in size! We should reduce a 18Mb load to 440Kb.

I ran into some issues while deploying it today. I added TimeDate fields to the table to hold information on when the image was successfully downloaded, and last changed. I used an if conditional to determine whether the file saved to the DB needed to be changed. It worked in my dev environment but failed when I ran it in production. I believe it has something to do with the way I iterated through changes while developing. I ended up scrapping the time based conditional that limited the number of times a file would attempt to update to once a day.

Testing. Testing would fix this problem. Or limit its chances of causing destructive problems.

Anyway. I have the back end in place. The images are saving and the api is serving their location. I now have to implement them in the PWA and in the wordpress plugin.

Spider lurks in the middle of a web
published: 4/11/19 4:04 p.m.

Road less travelled

It's supposed to be the journey not the destination, but I spend a lot of my programming time wandering down not-programming avenues.

Currently, I'm setting up the new server for ComFest. It's similar to the setup I used for this server except with Wordpress instead of Django. Also, it's a production/real site and I'm super concerned with its ability to handle traffic during the festival, its security, and its ability to run... well. Like, I don't care if my server root is trying to email me and can't I do care if the ComFest server is having a problem but cannot reach anyone.

The issue I've been fighting with the last few days is setting up a mailing system on the server. I just need root to be able to send things. I don't need to handle anything more. I tried following some tutorials that use postfix. But it turns out, after struggling to understand why it wasn't forwarding correctly, it's because postfix doesn't use /etc/aliases to forward anything to a non-local email. I think I came up with a solution last night, but I'd messed up so many other settings that I reset the server to an earlier configuration. I'm taking a couple classes today on setting up postfix, and hopefully, the new knowledge, combined with the experience of the past couple days will allow me to get this right.

typewriter with paper
published: 3/22/19 5:05 p.m.

New project

Have spent the past week moving the wordpress half of a website over to a cloud server on digital ocean. A lot of it was spent refreshing myself on how DO works, linux etc. Meghan and I did a lot of the move by hand rather than copying directories/and the db over. We wanted a fresh start. I don't know how important that is in the grand scheme of things but it seemed like a good idea at the time.

I spent the past couple days working on speeding up the service. The day to day traffic of the site is small, but during it's peak it sees 15k people per day. Most of those are in a short amount of time. I wanted to make sure the server could handle it.

I ran some tests on loader.io and my site completely froze up at @ 140 concurrent users. Woulldn't load after the test stopped and forced me to restart the server. I'm not sure but I think mySql locked up.

I had been looking into caching the server using fastcgi and varnish, but the instructions I found online seemed to indicate I would need to run nginx as a proxy server to intercept https. I found other information that nginx was flat out quicker than apache. If I needed nginx anyway, it made sense to drop apache and switch to nginx. However, the varnish installation seemed difficult and I found a very easy set of instructions to use nginx and redis.

Redis is used to cache requests to the DB while fastcgi is used to cache pages. At least, I think this is what's happening. After spending several hours tweaking the site settings, reading and rereading the instructions and scouring the internet for explanations about why things weren't working I was able to get things switched over and running.

My issues with concurrent users dropped away immediately. During the first test, before the crash, response times were approaching ten seconds. After switching to nginx, even though it didn't cause the server to crash I was still getting 8-10 second response times before the test program would start to receive too many 500 responses to keep going.

After setting up fastcgi, my problems fell away. I was able to easily serve 250 concurrent user with an average response time of 44ms. I did a follow up test today with 1000 users and the response time went up to 170ms.

card catalogs
published: 2/28/19 7:07 p.m.

Holy smoke

Moved the database over to the Postgresql db that was 'running' since the day this droplet was created.

It was both easier and more difficult than anticipated. I thought moving the data around would be the hard part but it was knowing/remembering how to create db, create role etc in the database that was hard.

Danny Devito holding a paddy's pub egg.
published: 12/24/18 1:01 a.m.

Small successes

I was able to get the project model to work. I spent a bunch of time researching ContentTypes and generic content/relationships. In the end, I was unable to wrap my head around it and went for a much simpler many to many field. It worked and I am pretty pleased about it. Though, as I write about this small victory it becomes clear how small it was. And that is how my programming goes, my friends. Very small iterations.

chrysalis hangs from a branch
published: 12/21/18 7:07 p.m.

Future changes

So many things need to be improved here.

I just realized the blog edit page needs to be updated as well. Which brings up an additional problem I'm running into. What looks like a simple change to the model leads to changes in code in a lot of different places. It's hard to keep up with it. Maybe testing is the answer, but how would a page that had tests designed to determine if a blog post had a post and a title fail when I added a photo to it?

The css styling needs to change with width. It works well on phone. But there are giant margins on my laptop. I don't know what I was thinking when I made that decision.

I would love to change the blog photos to a separate model that took an original photo and created multiple smaller versions of it so that I could use instead of . It would be nice to have a list of photos that already existed to choose from rather than adding a new photo each time.

typewriter with paper
published: 12/21/18 6:06 p.m.

Changes

Updated this site. The photos in the blog post now upload a photo to MEDIA_ROOT instead of just being a link to a photo name and then searching for that photo in static/images. It's a very simple solution and I'm appreciative to the folks at Django for figuring it out.

I'm going to have to merge with the master branch and discard changes to the db on my home server. Hopefully I don't lose any posts. I think there may be a lesson in here about backing up databases.

typewriter with paper
published: 12/21/18 3:03 a.m.

'Rastlin

Fist fought Django for 12 hours today.

Trying to set up a quick and easy way to upload all of the products to the fluidol site.

This morning I attempted to use a utility function to read an xlxs spreadsheet and automagically add them using the models. But I couldn't get the models to load. I fought and fought attempting to add the utilities folder as an app. Finally, I went in a different direction and added a management/commands folder to my core app. (my core app isn't named as such, but that seems like a much better name than the one I'm using.)

I used Django's built in ImageField when i put together the product model. It was significantly simpler to use than I thought it would be. I could copy an image url into the field and it would download it and add it to my media_root.

I was hoping it would be just as easy to use it to programmatically add the images from the xlxs spreadsheet. It wasn't. In the end I had to save the images myself into the media_root folder and then save the name in the db. It finally worked but it took a lot of reading and searching on the internet to make my way there.

Other issues I'm having. 1. I kept the settings.py out of the git. I'm running into issues where there are diffences between my installs and I'm forgetting to update them across computers. 2. The db got really weird today. The desktop is all up to date but the db on the laptop was not. When I ran make migrations/migrate it kept telling me their were no migrations needed. For the longest time I couldn't get it to even look at the fluidol_index app. I could see the migrations in the folder, but it wasn't paying attention to them. I don't think my Installed Apps was configured correctly.

After a lot of fiddling it worked, but I'm not sure why.

  1. The virtual environment has been weird as hell too. I started using Spyder to do some work. Being able to work with variables and such from the command line has been fantastic. But I'm beginning to wonder if there isn't some environment interference. That doesn't make sense to me. It seems like the command line you're operating on should be in it's own environment. But I had an instance of being able to use beautiful soup from the vscode command line without it being pip installed. It seems like it was using the environment settings from spyder/anaconda.
typewriter with paper
published: 11/22/18 2:02 p.m.

Git lessons

I started out on master branch by mistake, made some changes and caught myself before committing them. It turns out your changes merge into the branch you checkout into. So it was as simple as switching to development, committing them there, then switching back to master and merging. Why all the extra steps? I'm trying to keep to using development as the place where I make my changes. I'm afraid of what will happen if I merge master into development rather than the other way.

This, btw, is a test entry to see if the new generic post thing is working on the front page. I'm going to have to commit this change so that the master will be updated with the blog post change. It seems like a waste of a commit. There's so much left to learn about proper handling of test environment vs production environment. Also, this is a gentle reminder that I'm still using sqlite on the production server.

Spider lurks in the middle of a web
published: 11/20/18 4:04 a.m.

Web Design

A.) This is finally starting to come together. B.) Adobe stock photo is the best. C.) I need to start recording my thoughts as I have them.

typewriter with paper
published: 11/14/18 12:12 a.m.

Lost

I've lost focus. I'm creating a header based on a Django girls tutorial, when I was initially just copying a site I quickly put together with Wix.

I need to get it togther.... and quick.

typewriter with paper
published: 11/13/18 7:07 p.m.

New new post

This is a test of the posting system. This is only a test.

typewriter with paper
published: 11/13/18 4:04 a.m.

Favorable Winds

Today's been a good day. Website up. There is actual code on the front page. I picked a font for the headers/website name that I like. I picked a name for the site I like. Secured the site with let's encrypt.

typewriter with paper
published: 11/10/18 1:01 a.m.

Fifth post

Listen, strange women lyin' in ponds distributin' swords is no basis for a system of government. Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony. Not necessarily. I could be arguing in my spare time.

Come and see the violence inherent in the system. Help! Help! I'm being repressed! Nobody expects the Spanish Inquisition!

We interrupt this program to annoy you and make things generally irritating. This is boring. Let's go watch a stoning.

What is the capital of Assyria? It's a Mr. Death, dear. He's here about the reaping. I told you to lay off the beans, you whore! I cut down trees, I skip and jump, I like to press wildflowers. I put own womens' clothing, and hang around in bars.

typewriter with paper
published: 11/10/18 1:01 a.m.

Second post

need to add some additional posts to test it out.

typewriter with paper
published: 11/10/18 1:01 a.m.

First post

Setting up a blogging platform from my website.

Maybe it wasn't necessary? Don't know.

I'm thinking about how well Wordpress handles blogging and how poorly this will handle it. How will I add photos, etc?

}