The Power of Yes

Posted by Chuck Vose Fri, 30 Oct 2009 21:22:00 GMT

Cross-posted at metaltoad.com: The Power of Yes

Of all the powerful words in any language assertion is in my opinion the absolute most powerful. With affermative language we are able to create trust, enact people’s will, and begin processes. Silly of course, to take one word to mean so much but I believe everyone can agree that when a client asks for something ‘yes’ should be the thing that jumps to your lips immediately, hopefully without qualification but at times you have to add on things like ‘and it will cost x’ or ’, now lets look at the plan and see how we can make this a reality’.

But this post isn’t about clients, it’s about our language and framework choices.

When I was new to programming I said no a lot. This was in part an aspect of my first language PHP, which was perhaps as immature as I was at the time. ‘No’ was probably my biggest buzzword, maybe followed by ‘can’t’ which I justified by saying that PHP couldn’t do it. Turns out I was wrong, PHP really can do almost anything, but at the time I couldn’t. But ‘No’ was certainly an artifact of the culture. The things I do in PHP are often much harder than they need to be, at least they feel unnecessarily difficult to me now, and in this environment it is easy to say that it’s to hard. I’ve noticed since starting to use PHP again I’ve noticed ‘can’t’ creeping into my language more and more.

Ruby was the first language that was strongly oriented towards ‘yes’ both in the language and the culture. It could have been that I learned later in life or in a place that had a very strong Ruby culture (Seattle), but I suspect that the language had more to do with it than anything else. Ruby positively wants to make things faster for you so that the time between your thought and your expression of said thought grows shorter and shorter as you learn more Ruby. As such, when your language is saying ‘yes’ so often you naturally begin to start thinking this way yourself.

Drupal was a bit of a revelation to me in this regard. Drupal, as everyone knows, is a PHP app, yet despite the underlying language constructs the ui says ‘yes’ even more often than Ruby does. As my coworker pointed out, the amount of a website that gets finished before you hit the code is absolutely staggering. Maybe 90% of any given Drupal website could be accomplished by Drupal using only CCK/Views (et al) with the rest of the customizations being fairly quick using the copious APIs available to us. This is assuming that you find the correct project, in all things of course selecting the best tool for the job yields the best results.

So what are your languages saying to you every day? As products of our surroundings it is absolutely critical that we evaluate what our languages and tools say to us no just what they say about us. PHP may have a stigma, and Drupal through association, but I believe that the way it works with us is a much stronger reason to invest in exploring Drupal.

Posted in ,  | Tags , , , , , ,  | no comments

Multiple Dynamic Tabs in Brightcove 3

Posted by Chuck Vose Fri, 02 Oct 2009 17:57:00 GMT

Cross-posted at company blog: http://metaltoad.com/blog/multiple-dynamic-tabs-brightcove-3

This week I had the wonderful opportunity to work on an interesting problem that as far as I can tell hasn’t been documented. The call came out that we needed to generate a couple dynamic tabs on the top of our player for smart playlists. Now, we already have one dynamic playlist so I thought it was going to be a fairly simple logical step up to three but I was really, really wrong. If you read issue 3 of the pragprog magazine you’re probably thinking a lot about parallel and asynchronous processing. So it was extremely exciting to have come to a parallelization problem in my day to day activities. I’ll explain the problem:

In order to load a playlist into a brightcove player with the Player API you have to have already fetched the videos from the server using getMediaCollectionAsynch, getMediaInGroupAsynch, or getMediaAsynch. With one dynamic tab it’s pretty easy to use getMediaInGroupAsynch because you can assume that the only time the MEDIA_COLLECTION_LOAD event is going to fire is when your call has returned. But when you’re loading up two or more media items asynchronously you can no longer make that assumption.

If you’re just pulling down pre-defined playlists it’s super easy to drop something like the following in your onMediaCollectionLoad listener:

function onMediaCollectionLoad (e) {
  if (e.mediaCollection === null) {}
  else {
    tabBar.insertTabAt(e.mediaCollection, 0);
  }
}

However if you’re using getMediaInGroupAsynch or getMediaAsynch it can be difficult to figure out why the listener is getting called. For us we had three playlists of dynamic data but outside of comparing the resulting array to the original array (inefficient and error-prone) there is no way of knowing which asynch call asked for these videos.

But maybe we don’t care. All we care about is that the videos are loaded completely when we insert the tabs into the player right? So we stop relying on order and just make sure that all the videos are loaded into the player before adding some tabs. To do this I maintained a request counter (which could be called a counting semaphone were you so inclined. Before each request I increment the counter and when the request is filled I decrement the counter. When the counter hits 0 I know that all requests have been filled and I can safely add all the tabs at once.

Your code could probably look something like this:

var tab_count = 0;
var popular_tab;

function onTemplateReady (e) {
  tabBar = exp.getElementById("playlistTabs");

  if (popular.length > 0) {
    tab_count = tab_count + 1;
    popular_tab = true;
    content.getMediaInGroupAsynch(popular);
  }
}

function onMediaCollectionLoad (e) {
  if (e.mediaCollection === null) {
    // Do nothing
  }
  else {
    // Make sure that these playlists coming back are coming from 
    // getMediaInGroupAsynch. Otherwise their id would be positive.
    if (e.mediaCollection.id < 0) {
      // Add all media to the player's memory. 
      var mediaDTOs = new Array();
      jQuery.each(e.mediaCollection.mediaIds, function(i, val) {
        mediaDTOs.push(content.getMedia(val));
      });

      // Decrement the counter. When this hits zero we'll have filled all reqs.
      tab_count = tab_count - 1;

      if (tab_count == 0) {
        // Make sure this is one of the playlists we were going to add.   
        if (popular_tab) {
          popular_playlist = {
            displayName: "Most Viewed Videos",
            mediaIds: popular
          };
          tabBar.insertTabAt(content.createRuntimeMediaCollection(popular_playlist, 'playlist'), 0);
        }
      }
    }
  }
}

Here’s hoping this helps you out in your quest for multi-tabbed players and managing asynchronous loading.

Posted in  | Tags , , , , , , ,  | no comments

An Unexpected Occurence With Git: How Git Saved The Day Today

Posted by Chuck Vose Fri, 25 Sep 2009 21:49:00 GMT

Cross-posted from the Company Blog

In my experiences in the past working with external contractors is often a pain, especially the final merge where you try to incorporate all their code. I’ve always been a huge proponent of Subversion for SCM but today I saw an example where Git knocked the socks off of Subversion.

Time came and code needed to be merged into trunk. While discussing our options someone noticed that there was a .git file in the project directory and put the pieces together. While Subversion relies on a central repo Git has no such requirement and the contractor had included his git repo with the file which meant that we had his complete revision history available to us as well as an extremely easy method of applying diffs.

Normally merging was a pain but today we issued these commands, watched the output, then shared high-fives and a beer.

cd imported_files
git log
*write down the first couple chars of the SHA1 of the first commit
git diff --no-prefix {sha of first commit}..HEAD > patchfile
cd trunk
patch -p0 < ../imported_files/patchfile

Who knew it was going to be so easy!?

So the moral of the story: If you’re working with people that may not be in your office or you expect to get a tarball/zip of their work you could do no better than Git for version control. You get to see their complete history and work with it.

I’ll bet that someone out there smarter than myself actually knows how to replay the git commits so you can keep the revision history as well. Git is cool!

Note: Patch instructions based on these directions

Tags , ,  | no comments

Fun with stakeout.rb

Posted by Chuck Vose Mon, 21 Sep 2009 22:55:00 GMT

Cross-posted to the company blog at: Fun with stakeout.rb

Having only left Rubyville a couple weeks ago there are still a lot of Ruby-based utilities that I still find incredibly handy. One such utility that I’ve recently fallen hopelessly in love with is stakeout.rb from: http://pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/StakingOutFi…

Stakeout monitors your filestructure waiting for changes to happen and when they do it runs some command in the shell. Think about all the things you would like to happen when you change a file. Clear your cache? Refresh your browser via AppleScript? Run your PHPUnit tests? Program your Roomba vacuum to spin in a circle and sing for you? YES!

Take the code from the above webpage and drop it in a file called stakeout.rb. If you’re running Linux or OS X you probably already have Ruby. If you’re running windows I doubt the Ruby code would even work but do let me know if you do get it running and create a script for it.

After that simply run something like: ruby stakeout.rb ‘php drush.php clear cache’ sites/all/modules//

Now try editing and saving one of your module files. Success?

Rejoice!

Posted in  | Tags , , ,  | no comments

Converting from Brightcove 2 and loading arbitrary videos

Posted by Chuck Vose Fri, 18 Sep 2009 23:19:00 GMT

Cross-posted to: Company blog version

Over the last two weeks I’ve been working on a project to convert one of our client’s websites to Brightcove 3 players. As I am quite new to drupal but not to PHP you can imagine that many of the problems I had were unrelated to brightcove itself but there were a few aspects that I thought were worth documenting for those who are in the (surprisingly) enviable position of doing this migration.

First off I want to mention how huge of an upgrade it was going between 2 and 3. It may not look like it from the player aspect, many of the players look largely the same, but the backend work was tremendous. In addition to creating a spectacular new studio for uploading media and creating playlists they redesigned the players to allow greater customization without having to build your own swf player. What’s best about the backend changes is that if you really want you can actually keep your v2 players and still use the updated studio to manage your media as well as using the updated Media API to directly query their database for content to display. But what’s been crucial for us is the new Player API which allows us to use javascript to customize the actions of the player, load videos manually, and generally cause incredible ruckus without having to recompile the player itself.

To the point though, there is one mammoth gotcha in the upgrade between v2 and v3: if you’re specifying videos via the params (ie: almost every one of us) videos, the playlists they’re in, and the player both are in, must be from the same account. Additionally, videos must belong to the playlist that’s currently loaded as well or it just will ignore your selection.

Before I believe it was a little loosey goosey about where things came from but now there is this hard restriction. A little arbitrary feeling but there are ways of working around it. Here’s how we ended up working around the problem of having videos that didn’t have a playlist or that we just wanted to load in a different order:

In order to get a list of videos into javascript quickly and easily I used drupal_to_js and let it sort out the details. This was in my module file.

  <script language="JavaScript" type="text/javascript">
    videos = '. drupal_to_js($videos) .';
  </script>

In our js file we create the variables we need, (remember to put var in the front or ie will flip out) and add listeners. TEMPLATE_READY will be called when the template is fully loaded and MEDIA_COLLECTION_LOAD will be called anytime there’s a switch between playlists or if we use the getMediaInGroupAsynch() function.

var player;
var video, exp, social, content;
var tabBar, videoList;

function onTemplateLoaded(pPlayer) {

  player  = bcPlayer.getPlayer(pPlayer);
  video   = player.getModule(APIModules.VIDEO_PLAYER);
  exp     = player.getModule(APIModules.EXPERIENCE);
  content = player.getModule(APIModules.CONTENT);

  exp.addEventListener(BCExperienceEvent.TEMPLATE_READY, onTemplateReady);
  if (videos != null){
    content.addEventListener(BCContentEvent.MEDIA_COLLECTION_LOAD, onMediaCollectionLoad);
  }
}

When the player is loaded we want to load in a new set of videos. We don’t need to do anything with the return value because it will be caught by the listener we defined earlier in the js file.

function onTemplateReady(e) {
  tabBar = exp.getElementByID("playlistTabs");
  videoList = exp.getElementByID("videoList");

  if (videos != null) {
    content.getMediaInGroupAsynch(videos);
  }
}

Finally we get to actually use the videos returned to the player. It’s worth noting that the videos var here is exactly the same as above, a comma delimited list of video_ids. getMediaInGroupAsynch() doesn’t actually do anything with the videos it loads, it just loads them in the player so that we can use them later.

function onMediaCollectionLoad(e) {
  if (e.mediaCollection == null) {
  // Do nothing because no results came back. Must have been all disabled videos. 
  }
  else {
    //once the ids have been fetched from the service, create the runtime lineup.
    var playlist = {
      displayName: "Selected Videos",
      mediaIds: videos
    };
    var runtimeLineup = content.createRuntimeMediaCollection(playlist,"playlist");
    tabBar.insertTabAt(runtimeLineup, 0);

    // Select the new tab we created.
    tabBar.setSelectedIndex(0);

    // Select the correct video and play it.
    videoList.setSelectedIndex(0);
    video.loadVideo(list.getSelectedData());
  }
}

Now you may be saying to yourself, why can’t I just specify a list of videos in the @videoList param? To which I have to say that I have no idea. The documentation even suggests that this is perfectly possible but in fact it isn’t. In the meantime we’re just going to have to learn how to use the Player API, it’s probably good for us anyways. It certainly was good for me and highly entertaining!

Posted in  | Tags , , ,  | no comments

Quick Post

Posted by Chuck Vose Tue, 21 Apr 2009 09:39:00 GMT

I have nothing of interest to post today but out of a dedication to keep people reading I post regardless.

Over the last week I’ve been spending a lot of time studying and researching for thesis, a requirement for graduation from this Chinese program. My thesis is vaguely related to the Internet as it exists in China; naturally it is pretty much a front for me to spend a lot of extra time playing video games in the Internet cafes (wang ba).

But the wang ba is a different beast from the Internet cafe entirely. In a wang ba there is no wifi (or if there is there’s no reason and nowhere to sit to use it), instead there’s row upon row of computer desks. The one we go to must have 150 computers in the main room. Each of these computers is networked to a fast network storage array with plenty of space for… you guessed it, VIDEO GAMES GALORE! I’ve hit the jackpot! Except I can’t read Chinese and the icons are usually different so I end up just trying random games every day. Those icons that I do recognize though I’m getting quite good at.

Now here’s the real difference between a wang ba and a LAN (local area network) center (which would be the American equivalent), all the games are 100% illegal which means that there’s no way to play online, right? Wrong! Through a clever loophole most games still allow LAN games even if they’re illegal. So there are multiple services in China that will allow you to set up a “LAN” game across the entirety of Shanghai so that any number of people can hook up to your “LAN” and play together. How freaking cool is that workaround?

Classtime. Fly safe everyone.

Posted in  | Tags , , , , , ,  | 1 comment

Short interesting proverbs

Posted by Chuck Vose Thu, 16 Apr 2009 14:15:00 GMT

Tale of three monks

In the beginning there was one monk on a mountain. There was a lake at the bottom of the mountain but his studies were at the top. When he was thirsty, and he usually was from carrying the water so far, he had to hike down and carry the heavy bucket all the way up the mountain.

At some point a second monk arrived and they lashed the bucket to a bamboo rod and balanced it between their shoulders. Their studies improved and they were less tired.

Thinking that more of the same would be a good thing when a third monk arrived they rejoiced but found that there was never any water when they wanted it. Everyone trekked down the mountain at some point but there was always some conflict about who would stay and rest while the other two hiked.

This is a loose telling constructed from what Ben told me. It may have missed some of the points but it came up when we were talking about why the dishes never get done. I believe the numbers are approximate and pretty much always work for numbers > 1. We see this all the time when we live alone versus living with one or more others.

What is the moral? Find a way to lash the task to a bamboo rod so that it is easier no matter how many people are in the house/group. When everyone works together at once there is no conflict. Of course this doesn’t scale at all unless by some fluke everyone in the house is home and not exhausted at the same time (a rarity in most college houses I believe).

There’s a lot of depth to this, lots to think about.

-Edit-

Ben suggests that maybe the answer is to sign a contract or kick one of the monks off the mountain. Watching him smile after he’s launched a very successful joke is just about the best thing I can think of.

Warm feet, cool head

This was something that Ben hadn’t heard of but when I told him about it he said that it made perfect sense considering the Chinese views on foot warmth.

The meaning is roughly that the way to success isn’t through rash actions but can be achieved through calmness and good self-care (self-care is a major part of Chinese life). The feet are the locus point for many acupuncture points and as such if they are cold perhaps your organs are suffering.

Interestingly enough, my Econ teacher independently confirmed the value of good foot care recently as well. He mentioned that in pre-college and in many areas of life sandals are considered poor form, not just because of the obvious fashion formality problems, but also because it shows a lack of respect to the person speaking. If you don’t take care of your organs then you can’t pay attention which means you don’t really care enough. So sandals are a sure-fire way to piss off your teacher and show them just how you feel!

773861 army

This isn’t a proverb, just interesting. When people started migrating to the cities for increased wages they say that the only people left in the towns were members of the 773861 army.

  • 77 is a symbol for old people. Possibly related to the first day of the second Sino-Japanese war but I’m not sure about that. Ben says this is a plausible explanation but he’s also unclear.
  • 3/8 is women’s day
  • 6/1 is children’s day

Conclusion

China is cool. All those things about getting in trouble because of some weird thing are really true here. Also, never mention pork in Xi’an, there’s actually a chance that you’ll get beaten to death. It’s happened before.

Posted in  | Tags , , , , , , ,  | 2 comments

Twitter

Posted by Chuck Vose Tue, 07 Apr 2009 11:35:00 GMT

Okay, I’ve been writing little notes to Erica for the last couple weeks and I feel bad because I’m leaving out a bunch of awesome people. So with that I unleash to the world my twitter account. Please read my little thoughts there and I’ll try to continue to update the blog as well.

http://twitter.com/vosechu

Posted in  | Tags  | 2 comments

Screw Ritalin

Posted by Chuck Vose Sat, 04 Apr 2009 01:18:00 GMT

It’s been about two weeks since I last wrote, I’ve been trying to spend most of my freetime with Erica on the phone but I just don’t get much freetime anymore. So I apologize but I’m also really far away so what are you going to do about it punk?

At rate, last night I had a dream. I’ve been calling it “Screw Ritalin” all morning and I would like to share it with you. Many years ago there was a woman in my life who constantly inspired me to do wild new things. She still inspires me on occasion just by looking back at how life was at the time, it was some of the best years of my life I think. I was utterly sexless (at least for a while), I was interesting, inspired, and I had a job that worked relatively well with my Adhd.

Last night in my dream I was at a new college. Every morning I would espouse my opinions, I forget what she called them but it was incorrect word choice I remember, something like ‘marketing’. And every morning she would fawn over me and respect me. However in the dream at some point during the year I started taking Ritalin and she disappeared. When I finally found her I asked why we didn’t speak and she told me that she missed my morning speeches, that when I started Ritalin I stopped making those wild speeches to her.

This is not the first time someone has told me this and unfortunately I believe the times match up perfectly to blame Ritalin completely. What worries me is that I wonder if I’ve changed also and Ritalin just facilitated the change. What if I’m actually boring off of Ritalin too and I’ve permanently made myself dull and uninspired?

In keeping with the title I’m stopping Ritalin today. I still need a stimulant of course, I’m American afterall, but I think that my stimulant of choice will be tea for a while. I’m eager to see how this works out.

Posted in  | Tags , , , ,  | 9 comments

Trouble

Posted by Chuck Vose Fri, 20 Mar 2009 02:30:00 GMT

Today I had an exam that went well, at least the written part seemed to go well. But the spoken part was fairly dull and my teacher lambasted me for not speaking Chinese enough outside of class. Specifically she said that while all the other students are learning new words outside of class I am not, nor am I learning new grammar structures. Of course she is right so I’m going to make an attempt to speak only Chinese and keep a book handy for new phrases I learn. Maybe next exam will be better.

When a subject matter is inherently multi-person it doesn’t help to be self-taught.

Posted in  | 1 comment

Older posts: 1 2 3 ... 5