What I've Made in 2015

dayvonjersen 2015-12-03T19:26:44Z #post-mortem

In which I start to write about all my accomplishments and end up crying about my biggest failure.

This has probably been my most prolific year of coding, both in terms of lines of code and number of individual projects.

Whether any of it is any good is another story…

In this post I will list and give a short overviewlongwinded unnecessary exposition of what I’ve been working on in 2015, in mostlysomewhat chronological order.

Table of Contents

  1. Bunzilla [php,mysql,html/css/js]

  2. taglib-php [c++,php]

  3. Yet Another Flexbox CSS Grid Framework [css,sass]

  4. webcomponents-starter-kit [html/css/js]

  5. specificity-graph [php]

  6. sirupeuse [html/css/js,kitchen-sink]

  7. go v i b r a n t [go]

  8. sorbetière [go]

  9. keyfinder [c]

  10. other [various]

  11. yesyoucan [php]

  12. Sorbet


Bunzilla

Initial Development Period: January

Maintained: sporatically from February - November

Status: Ongoing, mostly on hold, idk it’s fine don’t worry about it

bunzilla.ga

github.com/dayvonjersen/bunzilla

github.com/dayvonjersen/bunzilla-materialize


I made this bug tracker mostly because I have a giant mess of handwritten notes and had many more thoughts than that which I needed to write down for the production of Sorbet, which I’ll get to later.

I’ll admit, I probably did not look hard enough for existing solutions, but the well-known bug trackers such as Bugzilla were unappealing in their verbosity and serious business attitude. I wanted something that matched my own attitude toward development: lighthearted, carefree, optimistic.

But mostly I wanted to make something with Material Design and get comfortable with PHP again. I learned how to code from making forum software, and a bug tracker really is just a forum with some extra metadata.

I was inspired in no small part by the development of Special Ops, which was a forum developed almost entirely by one person, who kept track of what he needed to do by posting messages to himself on the forum. Even though to an outsider it read like a mental breakdown, it seemed to be an effective, productive strategy for him.

I did the same thing during the development of Bunzilla, simultaneously keeping track of what I needed to do while testing out the application itself.

back-end

The back-end consists of an MVC-style “framework” which I made from scratch, minus the M.

m

There are no models, instead I use PDO making SQL queries manually, taking advantage of JOIN and ORDER BY and a few other useful SQL features.

Bunzilla uses MySQL exclusively.

C

Using Apache’s mod_rewrite, “routes” are automatically dispatched to methods on “controllers”, for example

GET /report/view/12

translates to

$controller = new report();
$controller->view(12);

This is something I’m surprised more frameworks don’t do, instead requiring you to specify routes manually in some fashion.

This and some of the library classes I made for Bunzilla have found their way into Sorbet, with some additional flexibility, namely the ability to define a static “route” method on controllers to route requests manually if so desired and complexity I won’t describe here.

There is also a simple caching mechanism in Bunzilla to avoid having to SELECT * FROM tables which rarely change, such as categories, statuses, tags, and priorities. When the tables are updated from the control panel, they cache is deleted and regenerated on the next request. Additionally, the custom CSS generated from the custom colors on these tables is also cached.

v

The front-end uses a lot of 3rd party stuff, including materializecss and highlightjs (full list in the README).

I heavily customized the UI, interpreting (mostly incorrectly, because as we all know there is a right and a wrong way to be artistic) Material Design in my own way, incorporating the sidebar menu from the Google Nexus 7 product page, and a few of my own ideas.

I also made a toolbar widget in JS for inserting html tags into post bodies, and a LOT of custom, awful JS and CSS hacks to bring it all together into a hot mess cohesive whole.

There are no templates, just pure PHP. This was a shortcut, and is a maintainability nightmare.

However, it was much more natural given my spaghetti code origins to create prototypal layouts and try out things and change them. I have no regrets.

The framework however supports multiple template “engines”, which simply looks in the tpl/ directory for a corresponding folder containing a view matching the current $template variable.

For the same route, multiple views may be available including

This approach has also made its way into Sorbet.

post-mortem

The development of Bunzilla has certainly (re-)taught me a lot and given me a lot of code and/or concepts to reuse in my main project.

I also learned that when using a front-end framework, such as materializecss, it’s all or fucking nothing: you either accept their design as-is in its entirety or you shouldn’t use it. Trying to customize or change any details was like pulling teeth: a very unpleasant and unrewarding experience.

However, some of their naming conventions for CSS classes were endearing and I used them in yafcgf.

But we’re going in chronological order damn it. I’ll pull this blog post over right now I swear.


taglib-php

Initial Development Period: March - April; November, ongoing

Maintainance: Ongoing

Status: it works (mostly)

github.com/dayvonjersen/taglib-php

There’s not much I haven’t said about this, in either the nearly 6,000 word README or on my homepage, except that it’s an absolute necessity for Sorbet.

First C++ project and first PHP extension. Lot of growing pains, still a disaster in terms of the code, there are definitely some dragons in there.

But I’m happy that it works.

Unfortunately for me, but fortunately for everyone, both TagLib and PHP have released new versions, 1.10 and 7.0.0 respectfully, just as I was finishing this project up.

There may yet be quite a bit more work to do, especially in terms of portability if anyone else wants to use it.

In addition to learning way, way too much about the harmful ID3 standard, VorbisComments, and FLAC METADATA_BLOCKs; and the tinest bit of C++ knowledge, I also experimented with automated testing for the first time when developing this. Again, I used no framework but instead made the smallest possible thing which (mostly) works that I could.

And in the development of the tests themselves, I found a host of command-line utilities that when composed and their output run through a bunch of regex can do everything TagLib can. Which came as a bit of sour grapes upon realizing I could do this.

My extension is I daresay a bit faster performance-wise and more consistently easier to work with (in PHP userspace anyway) than that approach, but it certainly would have been a lot less work for an adequate solution had I realized it sooner.

But again, I have no regrets because it’s been an incredible learning experience.


The following projects were developed independently at different points in the year, but have all been incorporated into my monolithic front-end repository for Sorbet called sirupeuse:


yafcgf

(Yet Another Flexbox CSS Grid Framework)

Initial Development: June

Maintainance: no

Status: go away

dayvonjersen.github.io/yafcgf/

github.com/dayvonjersen/yafcgf/

I took the grid names from materializecss and took a bunch of concepts from various flexbox “grid frameworks”.

Just go read this.

It has been incorporated wholesale into sirupeuse, along with some additional modifications.

It is not useful in any other context, though when I started it I may have had delusions of grandeur.

If you are curious about using flexbox in your own designs, it might be a decent starting point, something to build on, but not a complete solution and certainly isn’t production-ready.

Learned:


webcomponents-starter-kit

Initial Development: July

Maintainance: no

Status: pls respond

github.com/dayvonjersen/webcomponents-starter-kit

I bought into the hype and drank the kool-aid about WebComponents, and although the ShadowDOM is a lie, CustomElements are fucking awesome.

I am (ab)using WebComponents liberally in sirupeuse, with additional build scripts and just the webcomponents.js/CustomElements.js distribution.

All thanks to an old version of Bosonic which compiles an old version of the spec where you define elements like:

<element name="my-element">
    <style>
        h1 { color: rebeccapurple }
    </style>
    <template>
        <h1>wew lad</h1>
    </template>
    <script>
    ({
        createdCallback: function() {
            this.appendChild(this.template.content.cloneNode(true));
        }
    })
    </script>
</element>

Which is lovely and lets me encapsulate widgets into black boxes.

The version of Bosonic that was available at the time ships with hundreds of megabytes of bloat (mostly related to tests, which you cannot opt out of) and a gulpfile which was inconvenient to say the least.

I think these custom elements look even better than they did before. It was easy, really. You just have to look at things objectively, see what you don’t need anymore, and trim out the fat.


Aside

Current version of Bosonic has unfortunately taken a decidedly different direction, breaking previous syntax and focusing development on a set of core elements that are glorified demos which no one cares about rather than encouraging creation of specialized widgets for independent developers which is the whole fucking point of WebComponents.

Je espère juste que l’homme fou français ne efface pas son vieux transpiler de NPM comme l’aliéné il est. Il était probablement un accident que quelque chose d’utile est sorti de ce tas de merde.

But hey, at least it’s not Polymer or React.

Aside to the Aside

Polymer is actually pretty nice. I very briefly fooled around with it, but it comes with a commitment to use only WebComponents in your front-end rather than as progressive enhancement to existing HTML, CSS, and JS.


specificity-graph

Initial Development: August 14

Maintainance: no

Status: done

github.com/dayvonjersen/specificity-graph

I made this with just a touch of obsession for a full day in August.

I was watching a presentation by Harry Roberts when he showed a line-graph of CSS specificity over line number.

I paused the video, said to myself “I want that” and 6 hours later this popped out.

I’ve added it to the end of the automated build process in sirupeuse.


sirupeuse

Un sirop parfaite est le fondement d’un sorbet parfaite pour la musique sirupeuse

Initial Development: June - present, ongoing

Maintainance: ongoing

Status: getting there

closed source

Well I guess it’s about time I explained what sirupeuse is. I’m going to give a high-level overview omitting some details.

It will probably be open source eventually.

Sirupeuse is the front-end “framework” for Sorbet, comprised of a monolithic repository with the following structure:

sirupeuse/
├── assets
├── doc
│   └── dist
├── html
├── js
├── icons
│   ├── build.sh
│   ├── dist
│   └── src
├── sorbet.css
│   ├── build.sh
│   ├── dist
│   └── src
├── sorbet.js
│   ├── build.sh
│   ├── dist
│   └── src
├── sorbetto
│   ├── build.sh
│   ├── dist
│   └── src
├── specificity-graph
├── watch
│   └── main.go
└── webcomponents
    ├── build.sh
    ├── dist
    └── src
assets/

Final build output directory. I liked that name more than “build” or “dist” for the final output, and Sorbet uses an “assets” directory so it’s consistent like that.

Consists of three subdirectories currently: image, logo, and webfont

And three built/generated assets: icons.svg, sirupeuse.css and sirupeuse.js

All assets are tracked by git, which is arguably a really bad thing, and is probably single handedly responsible for the repo’s 14MB size on disk, but if the rest of the build process were to be replaced there’s something to compare against.

doc/

I am generating automatically with the build process documentation for the following things:

And using Markdown.pl (the original one by daringfireball) to make them into HTMLs.

html/

A bunch of throwaway mockups, demos, and testfiles.

It’s a really productive, enlightening, and fulfilling creative process for me to be able to “design in the browser” by mocking out and playing with ideas in simple static HTML files and put those concepts into the actual distributed CSS and JS later if they’re a good idea.

So I track them, not because they’re the code I want, but they’re the code I deserve.

js/

Included third-party libraries which are compiled into the final sirupeuse.js

Currently: CustomElements.js from webcomponents.js, keymaster.js, mustache.js, pjax-standalone.js, and a scoped-css-polyfill.js.

Feel free to google those.

node_modules/

(.gitignore’d, obviously)

package.json

All npm modules I’m using for various build scripts, including ones which are installed globally.


Now the actual substance to this project:

icons/

A bunch of (freely available) SVG icons which I’m using in conjunction with a WebComponent to be able to render icons thusly:

<ic-on>login</ic-on>

I did not create any of the icons themselves, but I am optimizing (stripping them of all excess metadata and whitespace) using a tool I specifically created I call

svgfuck

svgfuck iterates through a src/ directory and attempts to parse each svg as XML into a php array using a library I made but have yet to release in its current form called xhtml5

svgfuck iterates through the array, keeping only what is a recognized tag or attribute (interactively asking the user to name unidentified icons), saving prettified svgs to a tmp/ directory (for either debugging or keeping by manually copying the tmp/ directory to the src/ directory only because I have PTSD after accidentally deleting all 100+ icons a couple of times) and then writes them all, without excess whitespace or a single \n to dist/icons.svg.

xhtml5

…is not something I made this year, but I’ll mention it briefly.

It was a misguided attempt to write HTML templates in PHP using array syntax, e.g.

$html['body']['p'] = 'Hello world';
echo $xhtml5->loadArray(['html'=>$html]); // <!doctype html><html><body><p>Hello world</p></body></html>

I wrote it in 2012, its original intended use came from a bad and unrealistic idea, and no one should do things that way on purpose.

It is however sometimes useful to parse and render XML with.


sorbet.css/

My actual CSS for the design of Sorbet. Consists of the aforementioned yafcgf which is part of a larger src/ directory consisting of numerically-indexed filenames starting with numbers from 0000 - 7999, each thousand representing a “category” of CSS, in order:

0000: settings, mostly CSS4 variables, @font-face, that sort of thing

1000: tools, gimmicks such as responsive typography and a fake text-outline

2000: generic, CSS reset is in here

3000: base, styles for HTML elements, proprietary browser pseudo elements, and additional typography styles are here

4000: object, the grid, which is generated in a _grid subfolder ends up in here, along with other such layout objects

5000: component, forms, tooltips, anything that may be used in multiple contexts but is styled in a distinctive way, expects a specific set of parent and siblings (in the case of tooltips it’s actually [attr] selectors which have a high specificity)

6000: module, highly stylized, “complete-solution” elements where appearance is explictly defined, such as buttons, tables, flashmessages, links, I have colors in here, text-shadow effects; the works.

7000: trump, utility classes (read: CSS hacks) to override something else, e.g. to ensure display:none, margin-bottom:0, etc actually apply in any case no matter what.

This is part of a method described in the earlier linked talk by Harry Roberts I link to in specificity-graph.

The CSS4 variables I’m able to use courtesy of myth.

The build process consists of cat, autoprefixer, and myth. I’m not using any additional gimmicks preprocessing such as Sass, apart from to generate the grid.

sorbet.js/

Currently just a global, singleton object containing utilities, such as a unique id generator function, and a function to show and dismiss flash messages.

Majority of JavaScript is in the WebComponents and

sorbetto/

My HTML5 Audio Player for Sorbet.

It is a WebComponent with a global, singleton object called Sorbetto which handles the player state and behavior.

There can be only one player on a single page, by design.

Very much a work in progress.

webcomponents/

Previously I mentioned my webcomponents-starter-kit which I have deconstructed and rebuilt into a process I use here to create encapsulated widgets for everything from custom form elements – such as <input type="text">s with floating <label>s , a toggle button very similar in behavior to Polymer’s paper-toggle-button or whatever they call it, and stylized <select>s – to accordions and tabs to simple wrappers around <svg> for icons, a spinning loader thing, and fitter-happier-text.

Each one is kinda a mess of incredibly over-specific CSS, whose compiled output I tack onto the very end of sorbet.css and js that might make you facepalm and/or cry.

But the nice thing is that they’re all individual, separate concerns so I can change them independent of each other or compose them together or whatever. Shit’s cash yo.


Lastly I’ll describe the build tools briefly

Each of the above core parts of sirupeuse has a build.sh and a dist/ directory.

A master build script calls each build.sh, looks in their dist/ directory and concatenates sirupeuse.css and sirupeuse.js, also spitting out statistics such as filesize and compressed filesize and the specificity graph as well

The build script is called by a watcher task, which I had first written in python but have since replaced with one I wrote in go, which follows. Both used the Windows API to scan for filesystem changes rather than use polling which is what all node things have no choice but to use.

*nix has inotify

package main

import "log"
import "os"
import "os/exec"
import "strings"
import "path/filepath"
import "time"
import winfs "golang.org/x/exp/winfsnotify"

func run(task string) error {
    //  log.Println("would run", task)
    //  return nil
    cmd := exec.Command("sh", "-c", task)
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    start := time.Now()
    err := cmd.Run()
    end := time.Now()
    //out, err := cmd.CombinedOutput()
    //log.Printf("%s", out)
    log.Println("finished", task, end.Sub(start))
    return err
}

func main() {
    paths := []string{
        "icons/src",
        "sorbet.css/src",
        "sorbet.css/src/_grid",
        "sorbet.js/src",
        "sorbetto/src",
        "sorbetto/src/js",
        "webcomponents/src",
        "html"}
    w, err := winfs.NewWatcher()
    if err != nil {
        log.Fatalln(err)
    }
    for _, path := range paths {
        if err := w.Watch("./" + path); err != nil {
            log.Fatalln(err)
        }
        log.Println("watching " + path)
    }
    basedir, err := filepath.Abs(".")

    if err != nil {
        log.Fatalln(err)
    }
    //fake := make(chan struct{})
    lastran := time.Now()
    for {
    here:
        select {
        case e := <-w.Event:
            //log.Printf("Event: %#v\n", e)
            if time.Since(lastran).Nanoseconds() < 100 {
                break here
            }
            //case <-fake:
            //  e := &winfs.Event{}

            evtdir := strings.Replace(filepath.Dir(e.Name), "\\", "/", -1)
            rundir := strings.Split(evtdir, "/")[0]
            file := filepath.Base(e.Name)
            ext := filepath.Ext(file)
            task := "./build.sh"
            build_all := true

            switch ext {
            case ".swp":
                fallthrough
            case ".swo":
                fallthrough
            case ".swn":
                fallthrough
            case ".tmp":
                break here
            }
            log.Println("eventdir:", evtdir)
            switch evtdir {
            case "sorbet.css/src":
                if ext != ".css" {
                    break here
                }
            case "sorbet.css/src/_grid":
                if ext != ".scss" {
                    break here
                }
                rundir = evtdir
                task = "php -f sass_a_shit.php"
                build_all = false
            case "sorbet.js/src":
            case "sorbetto/src":
                if ext != ".js" && ext != ".css" && ext != ".html" {
                    break here
                }
                task = "./build.sh --quick"
                build_all = false
            case "sorbetto/src/js":
                if ext != ".js" {
                    break here
                }
                task = "./compile_js.sh"
                build_all = false
            case "webcomponents/src":
                if file == ".new-element.html" {
                    break here
                }
                task = "./build_single.sh " + file + " && build.sh --quick"
            case "html":
                if file == ".new.html" || ((e.Mask&winfs.FS_CREATE) == 0 && (e.Mask&winfs.FS_DELETE) == 0) {
                    break here
                }
                rundir = basedir
                task = `php -f html/build_index.php > index.html`
                build_all = false
            }
            if err := os.Chdir(rundir); err != nil {
                log.Fatalln(err)
            }
            log.Println("file:", file)
            log.Println("extension:", ext)
            log.Println("from directory:", rundir, "\n")
            log.Println("running:", task)
            if err = run(task); err != nil {
                log.Println(err)
                build_all = false
            }
            if err = os.Chdir(basedir); err != nil {
                log.Fatalln(err)
            }

            if build_all {
                if err := run("./build.sh --quick"); err != nil {
                    log.Println(err)
                }
            }
            lastran = time.Now()

        case err := <-w.Error:
            log.Println("Error:", err)
        }
    }
}

So in summary, I’m using shell scripting and go rather than grunt/gulp. Deal with it.


go-vibrant

Initial Development: September

Maintainance: none

Status: complete

github.com/dayvonjersen/vibrant

I’ve written an extensive README which is also available in the godoc.

The Material Design presentation at I/O 2014 in which they briefly showcase Android Palette must have affected my perception of what Material Design was about and my desire to have custom colors in Bunzilla, even though the actual Material Design spec limits color palettes and discourages deviation and other adopters of Material Design have taken this to heart.

But after coming across Vibrant.js, I suddenly wanted to be able to extract and use the color palette of album art and profile pictures in Sorbet to accentuate the design and make it feel more personal.

Vibrant.js’s piss-poor performance in a demo mockup I made in sirupeuse however gave me great pause.

node-vibrant’s performance wasn’t much better, so I went to find a better way.

I knew I wanted a command-line utility, either a script or a binary.

I initially tried to wrap my head around the problem and explored a myriad of from-scratch solutions, mostly trying to do it with php’s gd and later imagemagick functions, but got strange (read: wrong) results which weren’t even fast. I also looked into imagemagick’s command line suite and found out a bunch of functionality that was useful for other purposes, namely thumbnailing, and their C++ API which has been ported to go.

I had taken an interest in learning go for sorbetière, and decided to apply my knowledge to the vibrant problem; knowledge gained after following along with go-by-example and watching a bunch of talks by based Rob.

After many failed attempts at diciphering and interpreting the Java source for Android Palette (I have no computer science background and mistakenly thought I could do it with a straightforward single pass through all the pixels rather than averaging their color and using priority queues), I happened across someone’s standalone implementation of the Android code and just translated it, line by line, concept by concept to go, embracing the priority queue.

I made a reference command line tool and a shittysimple webapp and shared it.

I learned that image analysis is more complicated than it seems.

It was also my first time making a library proper rather than as part of a standalone application.


sorbetière

La production d’un sorbet nécessite une machine magnifique

Initial Development: Late August

Maintainance: minimal

Status: we get signal

closed source

I just realized sorbetière is importing a package that uses polling instead of inotify. Damn it. BRB

Eh, I’ll change that later.

Sorbetière is a daemon which watches an “incoming” directory for new audio files and enqueues them, using a load balancer from Concurrency is Not Parallelism for processing with a suite of command line utilities, depending on their format, placing the processed files into an “output” directory. Simultaneously, it listens on a UNIX socket over which it sends status information about queued files, and if they’re running, sends the overall progress (which the command line tools all spit to stdout or stderr).

I happened to create this just before the word “microservice” entered the popular lexicon. I prefer “daemon”.

Audio file processing is a major component of Sorbet, which is the reason I made the taglib-php extension as well. In order to have uploads for music, the user-provided file must be vetted, properly tagged, and made into downloadable assets.

It’s worth noting also that I always wanted to have a progress bar on the UI for how far along the processing step is. One of the features missing from soundcloud in the early days was this, and as a producer anxious to immediately share his latest, dopest track with the world and spam links to it to everyone he knows, there’s nothing worse than staring at that “This track is currently being processed” and hitting F5 for 3 minutes before sending them the link. Then again there’s nothing worse than “friends” who tell you the link is broken and lose interest immediately instead of waiting the 3 minutes with you… I digress.

When conceptualizing Sorbet, I didn’t consider that running utilities like LAME and FLAC would be so CPU intensive and time-consuming until I actually thought about it.

I looked into all number of solutions, including SLURM, cron, GNU parallel, and task-spooler (which I will use for image processing instead) and came up with a bunch of shell scripts to do the right thing™, but I realized this wouldn’t scale past maybe 2 simultaneous invokations.

For one, having PHP dispatch the shell script then try to keep track of the PID is a massive hack and threading PHP for asynchronicity is tenuous at best. Then on top of this I would need to be parsing the command line tool output for their current progress percentage and sending this information back to the browser in the form of either a hanging HTTP connection or Server-Sent Events.

It was just too much to be doing end-to-end in PHP, highly error-prone, and an awful hack.

Go’s siren song of concurrency was too hard to resist for this problem.

The language was perfect for this application, using channels and select statements everywhere to create a load balancing queue, channels to send the parsed progress% int on and having the UNIX socket server thing as well. Incredibly fast and stable and the code is easy to reason about.

The idea to use a watcher task admittedly came from tools like grunt and gulp which use node’s fsWatcher or whatever and is ideal for how one usually handles file uploads from PHP with move_uploaded_file

Sorbetière calls the following command line utilities using package “os/exec”’s Command:


keyfinder

Initial Development: August 16th

Maintainance: pls no

Status: complete

closed source github.com/dayvonjersen/keyfinder_gui

A very shittysimple C command line tool which reads a WAV file using some modified example code I found from a google search and calls libKeyFinder which is the only open-source key signature detection audio analysis library in existence.

My tool likes to segfault sometimes, it is actually the slowest command in the sorbetière toolchain (which is embarassing considering the others do more actual work), and actually it’s too specialized, fragile and frankly embarassing overall to share publicly.

I don’t even care if it could be improved. It’s a stopgap solution and if and when I actually get some money it might be worth buying a license for proper key signature detection software or taking the time to engineer such a tool entirely from scratch using algorithms and math and shit.


other

Things.


These sidebars were unanticipated I swear

I briefly wanted to learn Python earlier this year. I actually I just wanted to learn something other than PHP, having previously floundered around with Ruby and Perl and tortured myself with blindly writing C for an Arduino project and C++ for taglib-php, with no actual interest in the language itself and all its esoteria.

So I wanted to learn Python. Did Google’s Python Class. I even tried contributing to the best IRC bot ever made and this project, and as briefly mentioned my watcher task for sirupeuse was originally in Python.

But something about the language just doesn’t resonate with me.

Julia showed a lot of promise as a new language to learn as well, having clearly been inspired by Python, but is not at the point where, how should I say it… I mean it’s a nice language and all, good concepts, potentially a lot of fun, but it’s slow and developing with it is a little error-prone and I’m not interested in working on the language itself in order to fix these things, I just want to use it.

Same reason I haven’t taken an interest in Perl6 despite being aware of it for quite some time, and loving their ideas.

These languages are very much still in development. They require heavy investment from developers and are not in need of regular end users who aren’t ready to get their hands dirty with the internals and contribute back.

I just want to learn a new language ;_;

So I ended up learning Go, which only a few years ago was in the same position, and which I was skeptical of what with its foreign syntax and terminology, but it ended up being quick to learn and fun to use. It has also taught me in a more effective way about type safety, pointers, and concurrency having come from exclusively dynamically typed languages.


yesyoucan

Initial Development: yesterday you said tomorrow

Maintainance: don’t let your dreams be dreams

Status: JUST DO IT

github.com/dayvonjersen/yesyoucan/


sorbet

Initial Development: ongoing

Maintainance: ongoing

Status: ongoing

closed source

So now we come to my veritable raison d’être.

The project which has consumed my every thought for the past 3+ years encounting.

The project which has been responsible for nearly everything I’ve made this year.

The project which keeps me going in spite of myself.

The reason why I have spent all this time recapturing my knowledge of programming and learning so much new material.

The reason why I wish to abandon any thought of being a professional chef.

The only reason I have left to live for.

OK maybe that’s overly dramatic.

Sorbet is a self-publishing platform for DJs and electronic music producers I have been developing for too long a couple years now.

Started with Rails. Then Sinatra. Then went back to PHP.

Looked at all number of frameworks. Didn’t like them

Built the first incarnation with PHP and using XSLT. Got caught up in the details. Realized it was a disaster.

The tipping point was probably trying to use XSLT functions on the clients (IE, Firefox, and Chrome) before realizing that even though IE11 looks modern, it’s the same pile of dogshit IE6 was under the hood. Its JavaScript APIs, particularly for XSLT deviate needlessly and nonsensically from the other browsers, but Chrome is even worse.

List of grievances against Chrome:

unremovable hard-coded border on <img> alt text

intent to remove <style scoped> (which fucking passed)

intent to remove -webkit-hyphens and IGNORE hyphens: auto

and the coup de gras

INTENT TO REMOVE XSLT (not passed yet)

I’m so upset.

But not nearly as upset as I was when I realized that IE does not support fucking ogg-fucking-vorbis and that that totally destroys all my conception of having an ogg preview to minimize bandwidth and storage consumption. Now I would have to make another format for preview which would undoubtably have a larger filesize and comparatively worse audio quality.

So fuck Microsoft. Fuck IE.

Not supporting IE.

*calming down*

Anyway, before starting from scratch again, I had intended to use XSLT in Bunzilla and since I now realized that XSLT was a liability and probably the bottleneck I was experiencing in productivity anyway, I used the development of Bunzilla to figure out what kind of web application framework to have.

But rather than find a replacement for XSLT I used almost no ajax in Bunzilla and used straight-up old-fashioned PHP for templating. Which was theraputic but not a solution for Sorbet.

After much deliberation and looking over every possible solution out there for templating, I’ve decided on Mustache.

I don’t like Mustache syntax, I think the way you have to structure data is restrictive and harmful.

However, it’s the only technology which is comparable to XSLT in terms of portability. Should I decide to write the backend in something other than PHP at least I can take the templates with me. But more importantly, I can render Mustache on the client and the server using the same (gently massaged) data.

Why not do all the template rendering on the client?

Why not do all the template rendering on the server?

Listen, voice in my head, there are situations where client-side rendering is appropriate, such as within the current page like with infinite scroll or other lazy-loaded data, and there are others where server-side rendering is appropriate such as for initial page load.

No one likes staring at your smug, centred full-screen spinning loading icon for 30 seconds while your fucking Angular/Meteor/100,000LoC SPA consisting of 20MB of minified, gzipped, >tfw the botnet wants me to starve JS bloated lagfest of an abomination brings their CPU to its knees and manages to consume more RAM than a fucking video game on maxxed out settings.

Just because you can, doesn’t mean that you should.

Furthermore, moving application logic to the client just isn’t necessary. Everyone talks about all these invented problems and unnecessary added complexity to web applications when everything is possible using traditional HTML forms and using JavaScript and CSS as progressive enhancement.

A website should work without JavaScript. This is a guiding principle, not an absolute rule. It’s not like I care about supporting lynx or the blame-JavaScript-first sysadmin crowd.

But links and forms on the page should work no matter what and the site should not rely on the client doing application logic when it comes to designing a website which is meant to be linked to and shared.

Such a model might very well be appropriate for applications which happen to run in the browser, such as email clients, spreadsheets, games, UI design prototyper drawing tool things, photoshop in the browser, and other such, long-running, persistent applications which really could be their own standalone program.

I’m writing this in Haroopad which uses node-webkit I’m pretty sure. Don’t quote me on that.

Brackets and Atom are also editors which use browser technologies as a platform. There’s nothing wrong with that, it’s just not what I want to make.

And but so

Perhaps unsurprisingly, I haven’t really gotten anywhere in all this time.

I’ve spent a lot too much of time planning and conceptualizing and ranting to myself about what the perfect music platform should look like, for both creators and listeners, to publish, share, buy, sell, and promote new, original music and learning each and every thing under the sun which it would take to build, from scratch. every. single. minute. seemingly insignificant. feature.

By myself.

In addition to all the legal considerations, logistics such as hosting, storage, and bandwidth, considerations for UI/UX, considering all the other competeting services in the market.

Not to mention design. What should it look like? Thankfully I found enough inspiration and free PSDs online to make up for my lack of (visual) artistic talent.

And you know what the worst part is? I’m not even supposed to be here today!

I just wanted to make a complete portfolio of all of the music I’ve ever made.

That’s it.

I just wanted more than 4 hours on soundcloud.

I wanted my own personal soundcloud clone. Without limits. Sans frontiers.

I mean I had cloned GameFAQs. That wasn’t so hard. Oh boy here we go

Listen to you, you sound like an asshole!

shh.

Look, yes, it was a bygone era. It’s over. And I missed the boat on the spinoff thing. That ship sailed without me and crashed into a glacier on its own.

And we’re in the midst now of the next dotcom bubble. They let the normies in on muh secret club and the hypetrain shows no signs of stopping. Facebook and Twitter are worth more money than God, and Google has taken over the world.

The world has changed, or is it me that’s new? A different set of morals, from a different set of clues. So still I wonder. Is this all there is to life? The ever changing cycles in a world that’s damp and rife.

There must be more. Yeah, in my heart I hold to this. I’ve known the joy of love and I’ve seen the peace and bliss, but as you know all things must end.

OK no but really

I have a lot of emotional stake in this thing. And yes I have big plans, too much planned, going against pretty much every single word of advice I’ve ever come across when it comes to startups or even business in general.

But that’s exactly the point. I’m not building a business. I don’t want to make money.

I want to create the platform which will enable any amateur DJ/producer to directly share, sell, and promote their own work based on its merit.

I want to create the platform for everyone who loves House music, techno music, electro, IDM, and all forms of dance music to discover new sounds, new artists, and be inspired.

I want to bring nations and nations of all Jackers under one House.

All of our humanity has been sacrificed to the altar of making a quick buck. And what we’re left with are sociopaths appealing to the lowest common denominator in order to produce the most profit for the least amount of value with no promise that their “product” will even be there tomorrow.

I just know good music, man. When I was looking to make this album a lot of you motherfuckers were out on some electron, electro-clash, on some motherfucking acid trip.

Right, so about Sorbet…

idk I’m working on it