digitasketches.io is in full effect
I changed the layout to be centered with a max width. note that if there isn't a max width given to the body then there won't be proper margins since it'll fill the space automatically. I also threw in a gradient to the background, following a neo-retro late 90s color scheme. it's a little off but it'll do.
adding videos was somewhat odd with vite and vscode on a remote machine. it is important to just work in the public-internet port forward environment.
I found quimbie on dafont and i really like it as a h1 font. not sure if i'll like it as an h2 font as well. this website won't house any code so the three fonts needed will be for
for body copy i found "semi casual" on Dafont. I really like this typeface.
firing up digital sketches!
in dev folder, i'm triggering a new svelte project named digitalsketches-io
. I need to remember to use dashes for project names and dots for the web hosting folder name.
i followed my notes from 20231115 to build up digitalsketches-io. Now I'll copy over the ship.sh
and edit it for use with a different domain/folder.
I had a standard html page parked on the web folder - I moved it to old.digitalsketches.io. Before i can run npm run ship
i will need to add it to the package.json
config file.
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"ship": "./ship"
},
excellent, digitialsketchs.io shipped without issue
in pacstrap, making the favicon a disk and changing the top level name so that it shows correctly in tabs (modified in app.html).
i'm creating a folder in lib
called vid
to store references to video sources. I copied in the F1 RC car blender timelapse video as a test.
fun failure - the video will not load (and nothing will load) using npm run dev and opening a port forward in vscode (why? who knows.). the solution was to cast the npm command into host and port mode.
this means i need to screen it into the background so I don't have to run the command again. tiny web services
screen -S digitalsketches-io -m npm run dev -- --host --port 57001
thanksgiving development
the svelte set up is automated through npm
npm create svelte@latest svelte-tiny-note
using the automated project tool
once complete, there is a propt to cd
into the project and run npm install
to get things running.
we can already assign the vite server to a free port on the web services computer (in this case port 59000 is open). we'll hard code this to tinywebservices.com for access later.
screen -S svelte-tiny-note -m npm run dev -- --host --port 59000
from here let's imagine that there are two branches to follow
after writing it out, it seems clear that we should fisrt hook up the svelte project to do what we want since we are prototyping. these projects will live on port ranges until they mature to being their own subdomains (and eventually their own full domains)
in svelte, our app.html
should get a title
tag so we can see the title in the browser tab rather than the ugly url.
we should also be changing the favicon - i am using the ballot box icon from favicon.io.
great, tab and favicon are set
in our +page.svelte
we want to throw a function to call the server and return the response. we then want an await block to handle the response.
i know that there are conventions here that i'm not aware of. for example, using on mount for the fetch call or binding a variable
in the script
tag, make a boilerplate fetch GET.
const ContactServer = async () => {
const response = await fetch('http://100.14.63.251:58000/server');
return await response.json();
}
and just below
{#await ContactServer()}
<p>contacting server</p>
{:then response}
<p>{response.response}</p>
{:catch error}
<p>server is down</p>
{/await}
we should see a responnse of "tiny notes server is active"
we want to keep an set of notes and be able to POST a new note
following the steps from the other day
Routes
folder__init__.py
api.py
i'll start by making the file Note.py
and create the get and post functions in the Route class
class Route:
async def on_get(self, request, response):
response.media = {"response" : "Note GET"}
return
async def on_post(self, request, response):
bodyData = await request.get_media()
print(f'Note POST: {bodyData.note}')
response.media = {"response" : f'Note POST: {bodyData.note}'}
return
note that we have already made an assertion about our data: there is a JSON that has a "note" : "my text string in here"
from here, we need to add the Note file to the __init__.py
file. I will use the verbose +=
style to keep each file on its own line.
__all__ = ['Server']
__all__ += ['Note']
...
and add to api.py
api.add_route('/server', Server.Route())
api.add_route('/note', Note.Route())
kill and restart the falcon api
we now need to post a test JSON object. we'll have a simple PST called from a button binding (remember svelte!). this includes wrapping the button call in a lambda () => {CallFunc()}
<button on:click={()=>{PostServer()}}>POST</button>
the js for the button and message go as
let message = {"note":"hello server"}
const PostServer = async () => {
const response = await fetch("http://100.14.63.251:58000/note", {
method: "POST",
headers: {
"Content-Type" : "application/json"
},
body: JSON.stringify(message)
});
return await response.json();
}
oh gosh im resurfacing little canary!!
first thing is to look at reactive variables using $: message = "";
and then binding it to a textarea
<textarea name="note" id="note" cols="30" rows="10" bind:value={message}></textarea>
now we need a way to store our notes.
brute force is to store notes in a single plaintext file. other brute force is to save individual plaintext files. let's use individual files since the filename can be the time and id.
start by making a new folder in the falcon project called Notes
. We'll use a function that takes a string and then writes it to a file titled by the timestamp in seconds
async def WriteNote(entry: str):
noteTime = str(int(time.time()))
print(noteTime)
async with aiofiles.open(f'Notes/{noteTime}', 'w') as noteFile:
await noteFile.write(entry)
we can somewhat invert the process to read the note back in
async def ReadNote(noteTime):
noteContents = ""
async with aiofiles.open(f'Notes/{noteTime}', 'r') as noteFile:
noteContents = await noteFile.read()
return noteContents
and back in svelte, we can just use a simple fetch and bind to trigger the call
$: singleNote = "";
const GetSingleNote = async () => {
const response = await fetch("http://100.14.63.251:58000/note");
return await response.json();
}
we can then extend to have the correct json return over response.media
async def on_get(self, request, response):
noteData = await ReadNote("1700793263")
print(f'{noteData}')
response.media = {"note" : f'{noteData}'}
return
and the total html block looks like
<textarea name="note" id="note" cols="30" rows="10" bind:value={message}></textarea>
<br>
<button on:click={()=>{PostServer()}}>POST</button>
<br><br>
<button on:click={()=>{GetSingleNote()}}>GET note</button>
<p>{singleNote}</p>
for another time, we need a route for getting all the notes - maybe a /notes or a /note/all
but that's for a different day
a pattern for microservices
I'd like to outline a way to design software applications that take advantage of distributed systems. In this way, I need to make the front end do the user interfacing logic without binding to a specific technology (build the same solution as easily with svelte and unity).
The type of development I want to do follows three ideas
I have 4 desktops open on my mac
to set up a project in a single window, i create a top-level folder defining the project and then two folders for each tech stack inside
this looks like Demo > (svelte project) (falcon project)
I am not a fan of how deeply indented ul
tags are
However, trying to select a nested ul and not make it deeply nested seems like a selection hack that I don't know yet. Giving up for now.
I want the simplest version of an input field where I write a note and it gets stored on a server. Then a list of my notes in date order
step one, fire up a falcon project and a svelte project. here I am using the malamute account on webservices computer. There is a folder called demos and I will start the new folder structure with this application. The new project and folder will be called tiny-note
and its subfolders are called svelte-tiny-note
and falcon-tiny-note
I need to determine what my falcon skeleton code is.
start the falcon project by creating the start-server.sh
script. The script is designed to minimize the terminal gymnastics and memorization of the gunicorn command
#!/bin/bash
bash -c "screen -S demo-tiny-note -m gunicorn -b=0.0.0.0:58000 api:api -w 1 -k uvicorn.workers.UvicornWorker"
p.s. i added these snippets to my ref page!
From this stage, we need to ensure that we can lauch the script by using chmod u+x start-server.sh
The structure of the rest of the project goes as
Routes
folderRoutes
folder is a python module with an __init__.py
that has entries for all the route class defs usedOur entry point, api.py
has a simple boilerplate to start. We need two imports, the falcon library that gives us our HTTP funtionality and our own Routes folder. Then we create our falcon api object ensuring that CORS is enabled.
import falcon.asgi
from Routes import *
api = falcon.asgi.App(cors_enable=True)
moving on to our routes - create the Routes
folder and inside make an __init__.py
file and a Server.py
file. We'll start by adding the simplest falcon response boilerplate. The following will allow us to read back a JSON object (the response) in our browser
class Route:
async def on_get(self, request, response):
response.media = {"response" : "tiny notes server is active"}
With our server route file made, we need to add it to the import list. to start we'll add a line
__all__ = ['Server']
that will allow api.py
to see the server.route class.
We can now add a new route definition to our api.py
file
import falcon.asgi
from Routes import *
api = falcon.asgi.App(cors_enable=True)
api.add_route('/server', Server.Route())
we are done making our minimum viable API (MVapi). To test and see if I did everything right, i'll just call ./start-server.sh
in the terminal.
It works! In firefox, going to the route (ip:port/server) gives a simple JSON response of "response": "tiny notes server is active"
. At this point, we can leave the server running since it is in a screen session - detatch from it with ctrl-a d
to continue to add http routes, we will repeat the process for every new thing we want
__init__.py
api.py
this framework should allow us to breeze through new features and applications with minimal code and confusion (i can only hope)
now we need our frontend up.
writing more notes about website configs
malamute.us needs to have the correct configuration. i went through the entire nginx configuration and added try_files $uri $uri/index.html $uri.html /index.html;
. however this doesn't seem to be the only fix. I need svelte to generate pages in folders so that the trailing slash dir works correctly. in +layout.js
where the line export const prerender = "true"
is
dropped a single :global(a)
block in the +layout.svelte
file setting text-decoration: none
Fixing code padding cropping (i.e. i dont see rounded corners when the code padding goes off the edge of the p). nevermind actually - the rounded corners are not present because the code block is overflowing and the text in split to the next line (not a new box)
tiny web services is the go to link location for all my dev work. i want to be able to check a dev link (i.e. a constantly running vite instance) whenever i make minor changes.
gotta click that image to get in cause that totally makes sense.
Port range is set across 57000-57029 since I doubt to extend past 30 different dev sites on this network.
we want to launch the dev site in the background. somehow i want to automate this in the future
screen -S pacstrap-io -m npm run dev -- --host --port 57002
there is no wrapping so i set the pre
tag style to overflow-x: scroll
. this looks much cleaner.
I added an extra anchor link (with right justified icon) to the Vite dev server. Vite is still my preferred way to read this. I thought there were more entries than there actually are
I removed the old links to the port range set at 59000 - these should be pointed to demo site (rather than the mix of demo and domain-name sites).
a pivot.
rather than keep notebook entries as routes-per-day, I will start keeping notebook entries as routes-per-month with each h1
marking the day-date for the entry (ordered like canary-notes with latest-on-top)
for now, i'll keep the the two previous notes pages as single pages. i'm adding the 202311
link to the top and will only use it from now on. There shouldn't be a problem with any of this in terms of loading size since it will only ever be text and codeblocks on this blog.
i want to write some rules of web engagement. it's a mix of values and practicality. let's get drafty.
is the pacstrap notebook a place for ideas? i want to write as many tiny applications as possible for the tiny phone. this includes solidfying the tiny file drop, but also extending into other tiny app ideas - like a tiny record-outdoor-atm locations app.
combine this with 3d gaussian splatting. we would be unstoppable.