Dosta and photo galleries

Bernat Romagosa - 28 August 2010

After a pretty long vacation period I'm back home and ready to work again!
While I was working in China, two friends of mine started a small design cooperative (dosta) and I've decided to join them and take care of all the web development part. 

For the moment, since we'll most likely start getting offers in about a week, I began writing some components that we'll have to use on a very regular basis.The first one is this very simple web image gallery, which I kept terribly basic in order to be able to reuse it as much as we need.

Note that, if you want to give it a try, you'll need to create a FileDirectory (from the web config, Add → File Directory) and modify the methods fileDirectoryPath and fileDirectoryUrl accordingly.

Next step will be to "ajaxify" the hell out of it, but now I've gotta code a calendar component that we're gonna need for our first project together.

It feels good to be back on the Seaside!
Add a Comment

UTF-8 contents in Pharo and Seaside

Bernat Romagosa - 23 June 2010

In a web app I'm coding, I needed to generate UTF-8 valid text files, so that translators could submit short translations directly via the web interface.

In the end, it's as simple as follows:

| aFileStream utf8codec encodedText|
utf8codec := GRCodec forEncoding: 'utf-8'.
encodedText := self request: 'Enter a text loaded with funny chars'.
aFileStream := FileStream forceNewFileNamed: 'a_UTF8_file.txt'.
aFileStream
nextPutAll: (utf8codec decode: (encodedText)).
aFileStream close.

And now the file can hold all kinds of funny characters from every language round the universe.

Obviously, I don't get the translation by "self request:-ing" it, but this simplifies the example a lot.
Add a Comment

Checking whether a network service is up or not

Bernat Romagosa - 21 June 2010

I came up with a way to find out whether a network service is up or not, it doesn't look very elegant to me, but it does the job.

In my case, I needed to check if the mail daemon was working before attempting to send an email from my web app, so that's what I did:

isMailServerRunnning
[^(Socket pingPorts: #(25) on: 'localhost' timeOutSecs: 1) notNil] on: Error do: [^false]

I'm sure there are much better solutions (even already built-in in Pharo) but I couldn't find them... anyone?
Add a Comment

Zipping files

Bernat Romagosa - 17 June 2010

I spent like 2 hours trying to figure out how to enclose a couple of files into a zip archive from within Pharo, which is something I really needed to do for a web app I'm coding.

As usual, the solution was so easy and obvious that I'm almost enraged:

(ZipArchive new) 
   addFile: 'someFile.ext';
   addFile: 'someOtherFile.ext';
   writeToFileNamed: 'aZipArchive.zip'
Add a Comment

Comma separated elements of any collection in a string

Bernat Romagosa - 10 June 2010

Oh how I love it when I stumble upon methods like asCommaString, sendable to each and every subclass of Collection!

This method creates a string with all the elements of the collection -converted into strings- separated by commas... I've been stupidly doing this manually up to five minutes ago:

|someCollection|
someCollection := OrderedCollection with: Date today with: 'Some text' with: 3 with: #aSymbol.
someCollection asCommaString

This returns the expected string:

 '10 June 2010, Some text, 3, aSymbol'
Add a Comment

Chinese Tutor on Seasidehosting

Bernat Romagosa - 19 May 2010

Today I had to test some application I'm developing for the company I'm working in, so I uploaded my image to Seasidehosting, and since I'm using the same image for both projects, I accidentally got the Chinese Tutor online too, so there you go in case you want to try it live:

http://edutech.seasidehosting.st/seaside/chinesetutor

Please try to restrain from destroying my image, it's totally unprotected and only used for testing purposes.

Thanks! ;)
Add a Comment

How to implement a simple search engine

Bernat Romagosa - 15 May 2010

Raimon Grau asked me a couple of weeks ago how did I implement the search functionality in this blog, so I thought I might share it on teh internetz instead of just explaining it to him.

The mechanics behind it are really simple, and it takes no more than 10 minutes to implement a search engine when the content to be searched is organized in OrderedCollections, which is the case. Basically, we need the object that holds our data to accept a new argument:

OurDatabaseObject class >> getPostsMatchingKeyword: aKeyword

aKeyWord ifNotEmpty: [
    ^ Repository select: [ :aPost | (aPost content asLowercase includesSubString: aKeyWord asLowercase) ]]
ifEmpty: [
    ^ Repository.
    ]

Note that we lowercase the whole thing in the selection condition, so our search is gonna be case insensitive.

Now we just need our search box to modify the instance variable keyword:

OurRenderingComponent >> renderSearchBoxOn: html

html textInput callback: [ :value | self keyword: value ].


And, of course, the blog renderer has to do something with this keyword too:

OurBlogRenderer >> renderPostsOn: html

(OurDatabaseObject getPostsMatchingKeyword: self keyword) do: [
:eachPost | self renderPost: eachPost ]

That's it, hope it helped!
Add a Comment

Chinese Learning Tutor

Bernat Romagosa - 29 April 2010

For a while I've had the idea of building a small piece of software to help me keep and study my Chinese vocabulary, so with some free time I've had in the weekend and some days after work I've put something together.

It's a quite simple flashcard app and doesn't do much for the moment, but I'm realising how much faster I'm coding now, for an application like this would have cost me a long time to code a while ago...

Ladies and gentlemen, the Chinese Learning Tutor:



The search function:


You can save and recover flashcard sets:


I've implemented a very simple game in which you are asked to enter the translation for a random flashcard:


So far, it's proving quite useful to my learning process, there are some issues to clean up like the input method for new flashcards...

... which is a simple series of self requests, but for the moment the whole thing works and is 100% usable. I plan on uploading it somewhere in a few days, when I'm in the mood and stuff.

Oh, I almost forgot, you can find it at: http://www.squeaksource.com/chinesetutor.html
Add a Comment

Scorer Download History

Bernat Romagosa - 21 April 2010

Sourceforge automatically updates this graph every day:

http://sourceforge.net/project/stats/graph/detail-graph.php?group_id=260864&ugn=scorer&type=prdownload&mode=alltime&file_id=0&graph=1

What the hell happened on October?
Add a Comment

Simple image persistence and object serialization

Bernat Romagosa - 29 March 2010

Imagine you have a web application featuring simple image-based persistence, let's say you're very careful and backup your code every time you modify something, you also you save the image automatically every time you add/remove an object from the database (God forbid there was a power cut and all contents went down the drain).

All these measures are indeed necessary but not enough, sometimes things break unexplainably, sometimes images just decide to corrupt themselves beyond repair. In those cases, these security measures will only help you recover your code (of course, I mean "only"), but you'll sure as hell lose all those contents that you and all users have been adding and modifying for such a long precious irrecoverable time.

That's exactly what happened to me, forcing me to think of a solution which is, for sure, not the most efficient nor the most beautiful, but hey that's as far as I get:

We create a method that serializes any given object into a file, we do that using a ReferenceStream, and we save the file with the given filename and the extension .obj, which is of course totally arbitrary and irrelevant.

SomeClass >> serialize: anObject withName: aString
    | rr |
    rr := ReferenceStream fileNamed: aString , '.obj'.
    rr nextPut: anObject.

Now, whenever we wanna serialize an object -i.e. the user collection- we can easily do:

self serialize:  (MyDatabaseClass users) withName: 'serializedUsers'

It might be a good idea to do this automatically every time a new user is added, removed or modified. It might also not. You'll probably have to judge by yourself depending on your needs, application traffic and value of the information to serialize.

So now we can add a button somewhere in our application (say, the admin panel) that allows us to recover these users in case of nuclear apocalypse:

MyDatabaseClass readUsersFromFileNamed: 'serializedUsers.obj'

The above method should look as follows:

MyDatabaseClass class >> readUsersFromFileNamed: aFileName   
    Users := ((ReferenceStream fileNamed: aFileName) next).

And ta-da, we're back to pre-disaster.
Add a Comment

Don't mess with me unless you're one of my kind

Bernat Romagosa - 28 March 2010

While coding the Bot Programming Arena, I came across a little problem, as I wanted some of the properties of the bots to not be readable or writeable by other bots, thus preventing the bot programmer from cheating by "teleporting" their bot to a particular position, or from being able to know the position of other bots in the field.

This really posed a problem, because those properties have to be readable and writeable by other methods, how otherwise would we be able to actually move the bot or detect whether it hit an object?

The solution is provided by the almighty thisContext, by asking it to tell us the class of the sender of a particular message. If that class should not be allowed to run this method, we fire an error message, otherwise we proceed:


position
    (thisContext sender methodClass = Bot)
        ifTrue: [^position]
        ifFalse: [self error: 'You cannot access a bot''s position from ' , thisContext sender methodClass asString]


Could it get any simpler?
Add a Comment

Retrieving an external CSS file

Bernat Romagosa - 26 February 2010

When deploying this blog it occurred to me that modifying the CSS would be terribly annoying if it was "hardcoded" in the image, so I decided to store it in another file I can modify via ssh or ftp.

Here's what the MyRootComponent >> style method looks like now:

style

  |aCSSFile theCSSdata|

  aCSSFile  := FileStream fileNamed: '/var/www/style.css'.
  theCSSdata  := aCSSFile  contentsOfEntireFile.
  aCSSFile  close.

  ^theCSSdata
Add a Comment

Finally, my own domain

Bernat Romagosa - 25 February 2010

It's been a real pain, first I wanted to get bytheseaside.st, but for some reason the money transfer didn't work the two times I tried to register it. I sent e-mails and requests without any luck whatsoever, so finally I gave up.

Then I tried to get asmalltalkbytheseasi.de, but it seems you absolutely need to reside in Germany to own a .de domain (unless, of course, you pay 30 extra euros for them to overlook this mandatory requirement).

So today I spent a good deal of hours configuring the domain, DNSs, Apache2, and tweaking the whole thing because the CSS wouldn't render properly and the images and links to the FileLibrary wouldn't work at all.

To get it working, I followed this guidelines:

http://book.seaside.st/book/advanced/deployment/deployment-apache/configure-apache

I'm running a Debian Etch server with Apache 2.2 in it, so I also had to do the following:

Troubleshooting the Proxy. On some systems the above configuration may not suffice to get Seaside working. Check the error_log and if you get an error messages in the Apache log saying client denied by server configuration just remove the file /etc/mods-enabled/proxy.conf from the configuration.

That's when I realized that images and links to the FileLibrary were not working at all, and after googling, asking at #seaside, and exchanging some e-mails in the seaside list, I finally gave up without having figured out what the hell the problem was, so I solved it by coping all the files to a static folder in my server and referencing them in absolute URLs, now the website works perfectly!

By the way, I know it's not the most beautiful design ever, but still, if you wanna take a look at the CSS, you can check http://67.223.242.82/style.css
Add a Comment

Autosaver

Bernat Romagosa - 22 February 2010

Some months ago my laptop crashed in the middle of a delicate transaction and my pharo image was corrupted beyond repair. The changes file was so absolutely huge that I spent more than 16 hours trying to recover everything I had lost, I asked #squeak and #pharo, I desperately processed the changes file with VIM, I googled like crazy, I went through the whole changeset checking the changes I wanted to apply, etc. All of these resulted in me deciding it was much better to start over from the last time I had filed out the whole category.

The day I finished re-coding the whole thing I wrote a small pharo app that would automatically file out a given category every X minutes, and now that I'm finally using Monticello in a regular basis, I've uploaded it there.

You can find it
here, to use it just doIt: Autosaver new.

By the way, I plan to some day tweak it a little bit so that it actually saves the whole project in Monticello, which is way better than only filing out the category locally...
Add a Comment

Bot Programming Arena

Bernat Romagosa - 17 February 2010

Dear all,

I've been checking out how Monticello works and I finally decided to upload a little project I've been working on in my spare time.

BotArena is an attempt to build a bot battle programming game using Morphic. One can feed different bots with different pieces of code, then send them to an arena and watch them fight.

Check it out here:

http://www.squeaksource.com/botArena.html

Some aspects of the design are still to be reviewed, and the code is still very immature.

Add a Comment

Blog up and running!

Bernat Romagosa - 10 November 2009

Hi all!

I finally developed my own blog in Seaside. This is where I'll be posting stuff about Smalltalk, Seaside, my personal projects and so on.

I've migrated all contents from my previous website, which was just a very simple site hosted by Googlepages, so please take a look at all the existing posts if you want to know what I've been up to during this year.

I know this blog is lacking a couple -or more- features, like RSS feeds (will implement it ASAIC) and pagination (not a problem yet, but it will be when the amount of posts grows).

Now, a little bit about myself:

I graduated in business computer science at UOC (Open University of Catalonia) on June 2009, which took me way too long due to several reasons, some of them being that I switched universities (first one was UPC, Polytechnical University of Catalonia), I "wasted" my first college years learning how to play Go, lived in China for a while, and worked part-time ever since I finished high school.

My interest in Smalltalk began as I took an introductory course taught by Jordi Delgado (who later on tutored my final degree project) at Citilab. After the course ended we all decided to create a Smalltalk Workgroup (GTS), where we have been sharing experiences, knowledge and code for almost a year already!

Recently, we have been coding an API for FluidDB, a very interesting database being developed by a team led by Terry Jones. You can check out what we've done so far in our Squeaksource site.

For the rest of my own projects you can just check my previous posts in this blog.

Feel free to contact me anytime at my personal e-mail address: tibabenfortlapalanca (at) gmail (dot) com
Add a Comment

Ten years later...

Bernat Romagosa - 25 September 2009

It's been a long while, but September brought work back and I finally decided to improve the scoring system in Scorer. You can now find Scorer 0.7b as usual at the right side of this page.
Add a Comment

A Smalltalk by the Seaside: Screencast

Bernat Romagosa - 25 June 2009

As a part of my final degree project, which I have already finished, I've recorded a screencast introducing how to build a website with static contents, users and a simple image-based database in 34 minutes. Please bear in mind this is my very first screencast, I made it in the hope that it'd be useful for beginners and maybe some things are not done in the most effective way, for example I don't use Magritte to build forms, which I think would be a bit too much for someone who has just read a couple of tutorials and wants to build his first website as fast as possible while understanding what he's doing.

It can be found in HD quality in http://www.vimeo.com/5130619

Another part of my project consisted in writing a manual -called "A Smalltalk by the Seaside"- on how to build common websites in Seaside, which also includes a short introduction to Magritte and a chapter on how to build a blog (based in the screencast by Ramon Leon on the same topic), but before publishing it I have to ask my university about licensing and stuff... I hope I'll be able to distribute it very soon :)

Any opinion is welcome! Thanks to everybody in this list as well as the people in #seaside and #squeak for helping me out with some problems I stumbled upon!

Add a Comment

Scorer for GNU/Linux

Bernat Romagosa - 30 April 2009

I've just moved all project files to a Sourceforge project and built the executable package for GNU/Linux. It comes with the Squeak virtual machine along with all necessary plugins for sound and X11, so it should work under any distro; so far it's been proven to work in Debian and Ubuntu, should you find any problems running it under your distro please let me know! 

Have fun!
Add a Comment

Manual for Scorer

Bernat Romagosa - 27 April 2009

Today I've finished writing the manual for Scorer, you can find it in two languages (Catalan & English) at the right column of the website.

The note you have to guess is the one placed first next to the key, represented here by the green line:

Add a Comment

Scorer 0.6b

Bernat Romagosa - 24 April 2009

I had some free time today and I implemented the option to choose between treble and bass keys. I still have to i18n-ize the whole thing...
Add a Comment

Scorer 0.5b

Bernat Romagosa - 20 April 2009

As I promised a while ago, I have implemented 5 different difficulty levels for Scorer, according to the needs of the students using it at the school I work at. I'll appreciate all comments and suggestions!
Add a Comment

Scorer 0.4b

Bernat Romagosa - 3 April 2009

Scorer is my first piece of software developed under Squeak, its aim is to help music students get skillful at reading music scores. It's mainly designed for kids, but it actually helped me too ^__^.

The idea was taken from Score-Reading-Trainer (http://scret.sourceforge.net/), written by J. Pablo Fernandez.

In the game you have to guess the first note of the pentagram by clicking on the corresponding button. If you guess it right, new notes will keep coming. Every mistake makes you score less points, and after three mistakes you won't be scoring anymore for this particular note. I'll soon add a functionality for changing the note names to English notation and I'm also planning to implement four different difficulty levels for children of all ages. All of this should be finished before the end of easter.

Scorer is free software licensed under the GPLv3 and you can download it by following the links at the right column of this site.

The published version works for Windows (that's what they use at the school I work at), but of course you can run the squeak image in any other operating system. For instance, in *nix you'd do: 

$ squeak scorer.image

And that should work.

I must thank the Smalltalk Workgroup I belong to (see http://smalltalk.cat) for their help, as well as my work colleague and friend Biel Ballester (see http://www.myspace.com/bielballester) who teaches music at the school and let his pupils be the guinea pigs for my evil experiments ;)

Add a Comment

HOWTO: Build a simple Seaside website in 30 minutes

Bernat Romagosa - 2 April 2009

A few days ago I wrote a simple tutorial which was meant to be an easy and quick introduction to Seaside. This shouldn't be the first manual you read, I strongly recommend you to give an eye to A Walk on the Seaside and An Introduction to Seaside first. After having read both I found there was a little lack of information for beginners, and that's why I wrote this little HowTo, which should teach you pretty fast how to get your first simple website working and should help you understand a little better how Seaside works.

Link to the tutorial

Add a Comment
software
blog
squeak
pharo
screencast
botArena
chineseTutor
fluiddb
GTS
howto
games
gnu/linux
dosta
seaside
scorer
components

Scorer 0.7b GNU/Linux
Scorer 0.7b Win32
Scorer 0.7b source
Manual (Català)
Manual (English)

SCREENCAST: A Smalltalk by the Seaside

HOWTO: Build a simple website in 30 minutes