4 Hugues Ross - Blog: Getting Organized
Hugues Ross
Showing posts with label Getting Organized. Show all posts
Showing posts with label Getting Organized. Show all posts

7/16/17

Getting Organized - 6 - Tick Tock

Hello again, dear readers. Once again, it's time to make my life a little more productive. In my previous post, I grappled with my computer a little bit in order to bring my to-do list up every morning. This month, I'm going to work on my time management a little.

When I mentioned that I wanted a timer back in May, I said that I wanted "I'd like something that fits with everything else". I'm not entirely sure how many purely hypothetical beers I drank before writing that thought, but looking back it sounds more like the mutterings of the local town loony than anything important. I assure you, however, that this strange little collection of words will make sense if you read the following two paragraphs. So, y'know, you can just skip them if you're up for a challenge.

So, if you've been reading these posts religiously then you'll know that I use Awesome to manage my desktop. This gives me lots of control and customization options, but also makes using "traditional" desktop apps cumbersome at times. In this case, a quick Google search will find you endless pages of linux timer apps, coming in exactly two flavors:
  1. Pretty (useless) dialog windows that take up half your screen with fancy Large Text
  2. Icons in your system tray
Option 1 is unappealing in general, but also breaks with my window-management preferences. I could let one of these apps ignore Awesome's tiling rules, but then it would also block me from interacting with whatever's underneath it. Oh, and it's definitely not getting its own special desktop, so that's out. Option 2 would work nicely...if I had a system tray. I could add one and watch it fill with useless incongruous icons, or I could not do that and sleep well at night. But, there's another solution. Let's take a look at my bar for a moment:
Pretty much all of those nice little UI bits are custom. So, I can make my own "Option 2" that fits with the visual style of my desktop and does exactly what I want.

If you're still following along with my little scheme to make a timer but you're not sure it's quick or feasible, then I have some good news: It's done. I secretly went and did it this morning. Normally, I write and code together, but I just wasn't in the mood for 6 AM blogging. What was in the mood for was Runescape (???), and I didn't want to miss any deadlines in the process. I suppose you could say I was motivated by laziness, but I'm not about to complain!

The Implementation

The result of my mad morning keyboard mashing was just under 100 lines of Lua code. Most of that is UI boilerplate, but there's about 40 lines of actual logic in there that might interest someone, so let's give that a look:
   52 local timer = gears.timer {
   53     timeout   = 1,
   54     autostart = false,
   55     callback  = function()
   56         seconds_left = seconds_left - 1
   57         if seconds_left == 0 then
   58             awful.spawn({"mplayer", "/home/df458/assets/se/Notify01.wav"});
   59 
   60             local message = string.format("Your timer of %02d:%02d has ended", math.floor(seconds_total/3600), math.floor(seconds_total%3600/60))
   61             if seconds_total < 3600 then
   62                 message = string.format("Your timer of %02d:%02d has ended", math.floor(seconds_total/60), seconds_total%60)
   63             end
   64             naughty.notify {
   65                 title = "Time's up!",
   66                 text = message,
   67                 timeout = 300
   68             }
   69         elseif seconds_left < 0 then
   70             widget:set_visible(false)
   71             timer:stop()
   72         end
   73         progress:set_value(1 - (seconds_left / seconds_total))
   74         if seconds_left < 3600 then
   75             label:set_markup(string.format("%02d:%02d", math.floor(seconds_left/60), seconds_left%60))
   76         else
   77             label:set_markup(string.format("%02d:%02d", math.floor(seconds_left/3600), math.floor(seconds_left%3600/60)))
   78         end
   79     end
   80 }
   81 
   82 function activate_timer(seconds)
   83     seconds_left = seconds
   84     seconds_total = seconds
   85     widget:set_visible(true)
   86     progress:set_value(0)
   87     if seconds_left < 3600 then
   88         label:set_markup(string.format("%02d:%02d", math.floor(seconds_left/60), seconds_left%60))
   89     else
   90         label:set_markup(string.format("%02d:%02d", math.floor(seconds_left/3600), math.floor(seconds_left%3600/60)))
   91     end
   92     timer:start()
   93 end
As you can see, this little code block could probably use some cleaning. With that said, it works pretty well and demonstrates just how easy it is to make a timer. All I really do is set two numbers to how many seconds I want to wait, then subtract one from the 1st number every second. The second number isn't even necessary at all, but I use it to add a progress indicator. Beyond that, the rest is just making a nice text representation that switches between hour:minute to minute:second as necessary. When the timer's running, my little info are looks like this:
It's simple, sure, but it works quite well! Next time, I'll be wrapping up this series with some final touches to task management.

6/11/17

Getting Organized - 5 - Some Awesome Work

When we last left off on my quest for good time management, I decided to share my pizza recipe instead of being productive. Clearly, I'm making good progress. Now then, it's time to do some actual programming.

Awesome!

No, that's not your cries of joy. Awesome is the Window Manager that I use on all of my machines nowadays. In addition to laying out my windows in a pleasing fashion, it also exposes a powerful lua API for customizing and scripting, well, everything. This includes the UI, allowing for some very in-depth customizations!

Last time, I made a list of tasks to complete:
  1. Automatically opening my wiki every morning
  2. A simple timer that fits with my workflow
  3. A way to create tasks remotely while at work
Today, I'm going to finish off the first task. Furthermore, Awesome is going to help me with that.

Hello, Wiki!

Originally, I said that opening my wiki in the morning would be "super-easy to do". I lied! I lied to everyone, even myself! And what a lie it was.

An Unexpected Snag

The easiest way for me to make programs start on launch is to add them to my xinitrc file. In this case, I actually can't do that. Because the terminal that I run vim in won't have its settings ready before my xinitrc finishes running. That means that if I use my xinitrc to bring up my wiki, the colors and fonts will be wrong and it'll have a horrifying scrollbar that looks like it crawled out of Windows 3.1.

Obviously, I don't want that. Awesome gives me the ability to run applications, so I can have it launch my wiki. Perfect, right? Wrong! To help debug scripts and configuration, Awesome provides a mechanism to restart it without closing anything. This is also great! However, this means that every time I restart Awesome it'll also open the wiki again. So, we have a conundrum.

The Solution

The second problem can be solved, but it'll take a few small additions. The goal here is to have Awesome run certain programs on startup, but only if it isn't restarting. To do that, I need to store some information across runs.

Conveniently, Awesome has an event that runs when it exits. Even better, that event tells you whether the exit is part of a restart or not! So, I simply write a value to a file based on whether Awesome is restarting or not. Then, Awesome can read the value when it starts and use it to make decisions. The result looks like this:
awesome.connect_signal("exit", function(restart)
    local lastrun = io.open("~/.config/awesome/lastrun", "w")
    if lastrun ~= nil then
        if restart then
            lastrun:write(0)
        else
            lastrun:write(1)
        end
        lastrun:close()
    end
end)

...

local lastrun = io.open("~/.config/awesome/lastrun", "r")
if lastrun ~= nil then
    local was_quit = lastrun:read("*n")
    if was_quit == 1 then
        for i,e in pairs(autostart_once) do
            awful.spawn(e)
        end
    end
    lastrun:close()
else
    for i,e in pairs(autostart_once) do
        awful.spawn(e)
    end
end

for i,e in pairs(autostart_each) do
    awful.spawn(e)
end

As you can see, it's actually pretty simple. Anything that I add to the autostart_once list will only start if Awesome shut down properly last time it ran. On the other hand, anything in the autostart_each list will run every time Awesome runs. This makes for a convenient solution that I can use as much as I want going forward.

So, that was a semi-complicated solution to a relatively simple problem. Come back next time for some tougher-but-more-straightforward scripting.

5/7/17

Getting Organized - 4 - Gripes and progress

Another week has passed, and here I am, still using Taskwiki. I promise that this is the last time I bring it up for a while, but I wanted to discuss some of the good and bad that I've encountered before moving on to some actual code.

This week, I haven't made too many additions to the wiki itself. My main addition was a project list, and the start of a dfgame wiki. The way the dfgame wiki is laid out, I have a task filter front-and-center. Rather than adding things to the list directly, it simply gathers all of my tasks for the project into one place. Inside the pages for each module, I can simply jot down relevant tasks, and they'll appear on the front page as a combined list.

I've also started using vimwiki (no taskwiki yet) at work! It has given me more time to get accustomed to the bindings and nuances of the plugin, so I'm pretty happy about that.

The Good

  • As it turns out, a number of annoying Taskwiki keybindings have normal Vimwiki equivalents that are much nicer! Of note is Control-Space, which creates/toggles a checkbox. Since Taskwiki runs off of checkboxes, you can use it to create new tasks or mark existing tasks as completed.

The Bad

  • Turning my first good point around: Why does Taskwiki bother making and teaching custom keybindings for Vimwiki features? They're much less convenient and harder to use in general.
  • Taskwiki doesn't seem to have any convenient ways of inputting projects and tags for your tasks. You can do it as part of a filter, but otherwise you need to edit the task after creating it.
  • I decided to give task dependencies in Taskwiki a shot, but there's one big problem that I realized: Because of my date filters, dependencies with different due dates can simply not show up sometimes. As a result, dependencies are pretty much useless outside of project pages.

Time to code!

Now that I've played around with Taskwiki long enough to make it a part of my workflow and see the uses (and flaws) of the tool, it's time to fill in the holes. I've come up with a few tasks:
  1. I don't want to open my wiki every morning. Instead, I'd like to have that happen automatically. Thankfully, this is super-easy to do.
  2. I need a timer. It's easy for me to take a five minute break, then wake up after several hours of doing something else. I could look for a timer program, but timers are pretty simple and I'd like something that fits with everything else.
  3. I need a simple way to create tasks while I'm at work. This is probably going to be a tricky one to pull off, but I have some ideas.
Now, because this post is secretly a horrifying bait-and-switch, I'm not actually going to write any code yet. Instead, I'll be teaching you the secret art of baking a delectable 12" thin-crust pizza from scratch on a weekday.


You'll need the following ingredients:
  • 1 1/4 cups of flour
  • 1/2 cup of lukewarm water
  • 1/2 tsp salt
  • 1/2 tsp instant yeast
  • 2 tbsp olive oil
  • 1/4 cup tomato sauce
  • Enough mozzarella, possibly more
  • A few pinches of thyme and oregano
  • 1 small clove of garlic (optional, but recommended)
  • 1 tbsp dry minced garlic (optional, but recommended)
  • Toppings of your choice (optional, but recommended)

A few notes

Before we begin, I want to give a quick shoutout to King Arthur Flour. They have a ton of great ingredients and recipes, and the dough for this pizza is adapted from one of their Ciabatta recipes.

Disclaimer: I'm not an expert on cheeses, this advice is based entirely on personal experience.

The night before...

  1. The night before you plan on baking, mix together 1/2 cup of flour, 1/3 cup of lukewarm water, and some yeast. The precise amount of yeast isn't too important, just keep it between a pinch and 1/4 tsp.
  2. Cover the bowl and put it somewhere warm overnight.


The next morning...

  1. In a medium/large mixing bowl, combine the the mixture that you prepared with 1/6 cup of lukewarm water, 1/2 tsp salt, and about 1/4 tsp instant yeast. Add the olive oil and dry minced garlic, and stir the mixture together until it's combined.
  2. Add 3/4 cup of flour and continue until the mixture starts to turn into a solid mass. At this point, you'll want to keep adding small amounts of flour and mix/knead with your hands until you have a ball of slightly sticky dough.
  3. Rub a little bit of olive oil into a clean bowl or rising bucket and add the dough, then cover it and stick it into the fridge. (If you're doing this step in the afternoon, skip the fridge and go directly to the next step)

That evening...

  1. After about 8 hours in the fridge, take out the dough container and let it continue to rise for an hour. If you just prepared the dough, let it rise for 3 hours instead. While you wait, prepare your toppings.
  2. After this final rise, sprinkle flour onto a clean work surface and roll out your dough into a rough circle. Don't overdo it, try to keep the circle around 10". sprinkle flour onto your pan/baking sheet, and carefully transfer the dough to it. Using your hands, spread the dough out to the desired size, pressing your fingers to leave a slight lip at the edge.
  3. Set the oven to 500F (or however high your oven goes), and immediately place your dough inside. Let it bake for a few minutes until it just barely begins to brown, then remove the dough and place it on the stove. This step will cook the dough ever-so-slightly, making for a crispier crust. If the center of the dough has begun to puff up, carefully press it back down (be careful here, you don't want to get burned).
  4. Quickly add the sauce, garlic, cheese, herbs, and toppings in that order, and put the finished pizza back in the oven to bake. There's no universal bake time for pizza, because ovens vary in temperature. Instead, I recommend watching for the cheese to melt and brown to know when the pizza is finished.
  5. Pull out your pizza, place it on a rack to cool, and enjoy! The number of steps may seem off-putting, but I assure you that this recipe can be done without too much effort. Good luck!

4/23/17

Getting Organized - 3 - Impressions on Taskwiki

It's been a week since I started playing around with taskwiki, and I'm going to share my thoughts on it so far. Two weeks isn't enough to get a truly complete view of the plugin, but I still have a few things that I can discuss.

At this point, I've set up a nice segmented todo list on the front page of my wiki. By carefully assembling some taskwarrior filters, I've created 3 main sections: Today, This Week, and This Month. The sections are pretty self-explanatory. I haven't played around with making tasks for my projects yet, so for now it's mostly a way to track chores and real life commitments. So far, it has been pretty helpful in that regard!

I gave my initial thoughts on taskwiki in my previous post, and now that I've had more time with it I've compiled a more detailed list of thoughts:

The good

  •  It takes out a lot of the tedium of using taskwarrior, and it's easier to commit to. Having an interactive interface lets me keep it open all the time, rather than forcing me to remember to pull it up regularly.
  • Using taskwarrior's filters with taskwiki makes them much easier to deal with. Without taskwiki, I'd need to type out (or tab-complete) several filters and call taskwarrior with each one. With taskwiki, I can use filters with more of a "set it and forget it" attitude.

The bad

  • I ran into an annoying bug today. Taskwiki updates the status of your tasks when you save the page. However, if a task is shown in several spots then these copies can conflict with each other. For instance, you could mark a task as done, then see it "un-mark" itself because another copy wasn't marked. I doubt it'll happen very often, but it's an inconsistency that will surely return to annoy me in the future.
  • To add a new task to a list, you can just add a new line at the end. This is good! However, adding a new line at the heading with the filter or in the middle of the list doesn't add a new task. This makes the feature much more vexing than it really ought to be.
  • Setting a specific date on a task feels pretty inflexible, because you need to write out the date (e.g. 2017-05-01 rather than 05-01 or May 1). To get around this, I've set up my lists to choose dates for me when I add tasks to them.
  • Even with my list in front of me, I still tend to ignore things outside of the "Today" category. If I set a task for something that I need to do this week, I probably won't pay it much attention until the date gets close. This isn't a taskwiki problem, but I definitely need to do something about it.

To sum up the above list, I like the convenience of taskwiki but it has several niggling issues that annoy me. For now, I think I can live with them.

Next week will be something different, but I'll be back with more thoughts once I start making wiki pages for my projects.

4/10/17

Getting Organized - 2 - Looking at Options

Last week, I wrote about my plan to try and help myself get organized. After that, I spent the week trying out tools and planning.

What's available?

The taskwarrior site has a tools page, where a number of tools and scripts are listed. There weren't many that looked useful, but I was able to find a handful of relevant tools and tried them out.

Tasky

Doesn't work. It's a few years old, so I suppose that's to be expected.

Taskswamp

Taskswamp is a python script that creates a tmux session with predefined taskwarrior filters. Basically, it lets you create a window with several tabs, each displaying different views of your tasks.

Some thoughts

  1. Taskswamp doesn't update its view without user intervention. This means that you have to press a button to refresh whenever the window is resized or your tasks change.
  2. It also fails to start up properly unless you open another tmux session first. I could use a script to do that automatically, but it's still a little bit of extra effort.
  3. Lastly, it puts the new session inside of Xterm. It doesn't offer a choice of terminals, or check environment variables for your default terminal. That's unfortunate, although I could probably live with it.

Tasknc


(note: text redacted)
Tasknc is an interactive curses-based client for taskwarrior. It theoretically supports all of the basic features of taskwarrior, such as creating, editing, and deleting tasks.

Some thoughts

  1. Tasknc doesn't seem to be actively developed. This is unfortunate, because it has a few bugs.
  2. Unlike Taskswamp, the view will automatically refresh when the window is resized. You still have to refresh it when your tasks change, but that's ok because it supports all the basic editing actions from within its UI.
  3. Deleting a task seems to make the application hang indefinitely. In addition, the add task command seems to display the wrong information. Both of these issues seem to have a workaround, but basic features being broken without extra configuration isn't a good sign going forward.

Taskwiki

So taskwiki is actually pretty great! It acts as an extension to the 'vimwiki' vim plugin. Basically, vimwiki lets you make...wait for it...wikis in vim. Taskwiki takes the concept a step further, by adding the ability to just throw a little checklist into any wiki page which automagically becomes a set of tasks managed by taskwarrior. Basically, it gives you a text-based method of managing your tasks.

You might be wondering why I like taskwiki so much, despite the fact that it fulfills none of my stated goals. It took me some thinking to figure out why I was so attracted to it, but I think I've figured out the reason: It gives your tasks a greater context. Sure, you can add tags and projects in taskwarrior, but this lets you organize and annotate those tasks however you want. You can make a new page in your wiki, write down some general description of something you want to do, then add a checklist of actionable goals to it. Those goals can then show up in checklists elsewhere, where you can check on their status or update them, and in the main wiki page you can add notes and other details as you make progress. Personally, I find that very exciting.

Some thoughts

  1. Taskwiki is actively developed/maintained. This is good.
  2. Resizes nicely, but you have to manually refresh your tasks.
  3. It was a huge pain to set up (about an hour of work). This is no longer important, but I figured it was good to mention.

Constructing a plan

I didn't find anything that really fills the niche that I'm looking for. I think I can adopt taskwiki to handle some of my needs, but I'll also need to make something to fill some of the gaps. So, here's the plan:
  1. Try to use taskwiki seriously for a while. I want to see how well using a wiki for organization actually works in practice, and there's only one way to do that. Next week, I'm going to write up a more detailed overview of vimwiki and taskwiki.
  2. After that, I'm going to start building some scripts to cover the features that I want. While I can't precisely say what I'll need yet, I'm expecting that I'll want some way to be directly notified of upcoming tasks, and I'll probably also want a way to quickly pull up the wiki when I log in.
Ad before you get worried about dfgame, don't! I've been working on it behind the scenes, and you'll hear more about my progress in a few weeks.

4/3/17

Getting Organized - 1 - Selection

One problem that I've been dealing with these past few months is organization. As the past 4 1/2 years of blogging should have made clear, I am not very good at managing my time and priorities. Now that I'm working 40 hours a week, the problem has gotten bad enough to seriously annoy me. So, I've decided to try and solve this problem the only way I know how: With software.

Looking back

I've tried a few pieces of software for keeping track of important dates and tasks. None of them have really stuck so far, so my first instinct was to write my own solution. However, I'm not going to do that. After seriously considering the idea for a minute, I've reached the obvious conclusion that creating a new project to try and improve my time situation is only going to make things worse. Instead, I decided to try and look at the problems with previous approaches and solve them.

Something???

In the months before and just after starting this blog, I was using some kind of todo list software. I remember almost nothing about it, including the name, and I can't find it anymore.

Google Calendar

During my college career, I used Google Calendar to keep track of classes and events. Beyond that, I never really bothered with it. My main issue with Google Calendar is the fact that it's an online service. I prefer to keep most of my applications off the web, mostly because webapps:
  1. Take up a disproportionately large amount of system resources to run.
  2. Won't work without an internet connection (duh).
  3. Take up an extra tab in my web browser.
  4. Usually collect personal information to sell/profit from.
 I see the appeal for most "normal people", but I can't stand webapps. This disqualifies Google Calendar right off the bat.

Calcurse

 For a while, I used a terminal application called Calcurse. Calcurse is an interesting program, because it gives you a nice curses-based calendar UI in the terminal. However, I had a couple of big complaints:
  1. The way that Calcurse handles todo lists leaves a lot to be desired. Unlike regular appointments, the program doesn't let you add items to your todo list with any sort of time attached. If you want to do something by next week, you need to make an appointment, rendering the todo list useless. Worse still, Calcurse won't try to warn you about the appointment ahead of time besides tossing you a notification a few hours or minutes before.
  2. In practice, Calcurse is incredibly aggravating to use. When you start it up, you have to hit enter to pass a message saying that it has loaded up. You have to do the same thing when you exit, but then it also prompts you just to be sure you want to quit after that. So, you have to hit 3 different buttons in turn to exit, for no good reason. It might not seem too bad at first, but it's super annoying and I don't know of any method to disable it. On top of that, it splits everything into 3 different panes, and you have to cycle between them with the tab key. They couldn't give you a "go back" or "go next", or just 3 buttons to select the specific mode that you want. Nope, they decided that you'd have to press tab until you got where you wanted.
 This program is a usability nightmare. I'd like to avoid using it.

Taskwarrior

...This brings me to the last option, going by things that I've used previously. Taskwarrior is a task management program that works really well for keeping todo lists and does a good job of prioritizing tasks.

I really like Taskwarrior, but I can't ever seem to make it stick. The main reason for this is probably because it's a basic command-line tool. There's no interface, only commands. This makes using it pretty inconvenient, as you can't just keep a view open to glance at or see notifications when time-sensitive tasks are coming up. Taskwarrior is more of an interface than a user-friendly application, which makes using it without any extra tools pretty annoying.

Of the options I've looked at, I think Taskwarrior is a pretty clear choice. While I still have to do some work to get it working, most of the heavy lifting will be already done for me. Hopefully, this will keep the time investment for this solution low. Hopefully, I'll be posting updates on this soon after I make more progress. Stay tuned!