lice! : Category Code and such, everything about Code and such page 3

MushCoder 0.08

Good news! Or bad news as you take it… As version 0.1 may be take a bit longer then even I expected so here is a mid way release.

It does not feature all the stuff I wanted to see for versionj 0.1 but a few improvements that make it far more usuable (hence why 0.08 and not 0.02)

Changes

  • Formating / Unformating of mushcode
  • improved highlighting
  • completely rewritten engine
  • improved compatibility to non Penn Mushes
  • fixed saving of files

You can get the file
here

Posted by Heinz N. 'Licenser' Gies Sun, 27 May 2007 17:43:00 GMT


MushCoder 0.1 Preview

OKay there won’t be a new update for somet time as some BIG things are coming, werll a bit bigger … so they might take a few days. Which includes rewriting good aprts of the datamanagement and stuff like that.

A nicer userinterface is also planned, neat functionality and all that nifty stuff. So to make waiting easyer here are a few screenshots of the thing I’m working no – reworked gui.

Left is still the tree with the objects, in picture
4
and
5 you see how one can now easiely add new objects. Also I made some new pictures for the different types – well I got the idea from XCode cause I liked it, color and letter simple but easy to spot. You can see that in picture
8

Okay so that are a few things that are coming in 0.1 :) stay tuned!

Finally a list of all pics I took:
1
2
3
4
5
6
7
8

Posted by Heinz N. 'Licenser' Gies Sun, 20 May 2007 23:40:00 GMT


MushCoder 0.01

Okay more good news! After another one and a half day of haaard work on this I added a few new features and removed a few bugs I found!

What is new?

  • Parentheses matching:Yap works neat as long as you don’t do ugly things in your code like not escaped parentheses!
  • Syntax Colors: Looks much better now!
  • Icon: I got down to make two icons, one for the files another one for the app itself – I like them!
  • removing objects: You can now remove objects again from your list of objects – might be handy ;P
  • Object names: Names are displayed instead of DB’Refs
  • somethig else: I forgot what it was but it’s usefull I’m certain about that!

What is coming up?

  • support for big attributres (currently the code might get funny on attributes that can’t be send at once (not sure if that can ahppen at all but I am better carefull)
  • ofline editing
  • keychain support
  • auto identing for code
  • smart groups
  • internal rewrites of stuff

Again use it at your own risk: download

Posted by Heinz N. 'Licenser' Gies Sat, 19 May 2007 13:23:00 GMT


MushCoder 0.0

&tOkay,
has been long enough but finally something new here. I’ve started a new project and got it to a state where it actually can be used. It leas a lot of the planned features and surely has still quite a few bugs but hey it’s far enough to allow everyone who want’s to to have a look at it.

What is it for?

Well I am coding at times in a language named MUSHCode, it’s used in text based online RPG’s called
MUSHs
. The language used there is a LISP deviate and without any kind of aid of even an editor can be a pain. So that is where MushCoder (and I hope I find a nicer name with time) comes it, it’s supposed to be a IDE for Mushcoding.

As a note, it’s an cocoa app so won’t run under OS’s different then OS X.

What does it do?

  • Projects:
    Currently it features a simple project layout, one can create projects (which are a collection from objects and a server to connect to.
  • Source Browsing:
    You can brows the objects of a project for their attributes
  • Syntax Highlighitng : When editing a attribute MushCode gets syntax highlighted (might not be perfect)
  • Attribute Classes: base on common prefixes attributes are sorted in classes and handled differently.
  • Context sensitive unformating: This are two functions actually, for code unformating works just by removing all line breaks and tabs that are in the code you have edited (mushcode does not feature multiple lines in a attribute). For attributes that are meant to hold readable text (like descriptions) it replaces tabs and line breaks with the appropriate characters.

What is it missing?

  • Code completion
  • A icon
  • a good name
  • fool proof syntax highlighitng including bracket matching
  • a more intuitive gui
  • bug-fixes (I’m sure there are a lot still left)

Last words

Well feel free to download a
copy
. So keep in mind it’s still alpha at best, no guarantee whatsoever is given for your code, projects, computers, pets or lunch!

But if you find a bug, or have an idea about what to include feel free to mail me or drop a comment here. The mail addy is included in the about screen.

Posted by Heinz N. 'Licenser' Gies Thu, 17 May 2007 22:50:00 GMT


Watching multiple fields with Prototype

The Problem ----------- During the Work on [http://licenser.de/pages/ClockTower](ClockTower) I came across the problem to watch multiple fields for input. In details I was wanting to monitor the fields for the first and last name of a person in the database to find double entries. Prototype --------- While Prototype is just great work and hilarious to work with I found it misses a way to solve this problem in a 'nice' way. Sure Two Element.Observer Objects that get passed a function that reads both the fields values and adds then might have worked. So this would have not been a nice solution. The called function would have needed to have the readout coded in directly and it would have gotten ugly - in a sense. The Solution ------------ The solution was quite simple in the idea: An class like Element.Observer that can watch more then 1 object at a time. So the idea was there, only the code missing. The Background -------------- First step is to understand how Element.Observer works. It is based on Abstract.TimedObserver that, very bluntly said, checks every `n` seconds for a change of the element and when it has changed calls a callback function with the new value. Here a short listing of the source (from the prototype.js): Abstract.TimedObserver = function() {} Abstract.TimedObserver.prototype = { initialize: function(element, frequency, callback) { this.frequency = frequency; this.element = $(element); this.callback = callback; this.lastValue = this.getValue(); this.registerCallback(); }, registerCallback: function() { setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); }, onTimerEvent: function() { var value = this.getValue(); if (this.lastValue != value) { this.callback(this.element, value); this.lastValue = value; } } } To explain: Line 23-30 are initializing the Observer, they gather the element, and store the passed variables. The current value is fetched in line 8, **note** that `getValue()` is a virtual function not implemented in the Observer itself. In line 12-14 the timer is set up to execute the `onTimerEvent` function every few milliseconds. Line 16-22 are doing the 'real' work, the new value is fetched in line 17 and checked if it is different just one line below. If the value has changed the callback function is called with the element that is observed and the new value, also the new value is stored. Form.Element.Observer = Class.create(); Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { getValue: function() { return Form.Element.getValue(this.element); } }); Form.Element.Observer is a child class from Abstract.TimedObserver (what we discussed above) and it implements the getValue function that is more or less all it does. Changes! -------- Now it gets interesting, taking the Abstract.TimedObserver as a base and change it so it can watch more then just one field. Abstract.TimedMultiObserver = function() {} Abstract.TimedMultiObserver.prototype = { initialize: function(elements, frequency, callback) { this.frequency = frequency; this.elements = new Array(); this.values = new Array(); this.callback = callback; for(i=0;i So all in all it is quite the same we just pass an array of elements instead of a single element to the constructor. Changes are in line 8-12 we need to gather not one value via getValue() but one for each array element. The second change is in line 22-31 where the checking routine is slightly adjusted to check each of the passed elements. Another difference is that the callback function gets passed two arrays instead of two values, the first array holding the elements while the second array holds the values. Form.Element.MultiObserver = Class.create(); Form.Element.MultiObserver.prototype = Object.extend(new Abstract.TimedMultiObserver(), { getValue: function(element) { return Form.Element.getValue(element); } }); This is over all really the same as the `Form.Element.Observer`, all that differs is that we extend the `TimedMultiObserver` and not the `TimedObserver`. That is all, `Form.Element.MultiObserver` works all the same as `Form.Element.Observer` just taking more then one element to watch for.

Posted by Heinz N. 'Licenser' Gies Tue, 29 Aug 2006 05:22:00 GMT


Quick & dirty visitor stats for rails

Hey everyone, I am sure there are hundreds of nice ways to keep track of how many people visited a rails applications. From log analyzers for apache logs, over free web counters to self written code or gems that are floating through the net. And i agree all of them are nice, I currently use the neat tool from google which has a lot of features. So in the first days before I had set it up I was looking for just a simple way to see how many hits the webside had without any nifty graphics, html output or referrer analysis. I was surprised not find anything about it on google right ahead. Well a solution had to be found and as a ruby fan surely it included ruby. The original code I tossed together after a minute or two where (all assuming you’re in the logs dir of your rails app): cat production.log | grep "^Processing" > out.tmp && ruby -e 'data = Hash.new;File.open("out.tmp").each{|l| data[ip = l.split(" ")[3]] = (data[ip] || 0) + 1}; puts data.length' Now it is ugly, using files and all this but it worked which were the main idea behind it (quick and dirty), very dirty I must admit so. A few days later I talked with a friend over the topic and we came up with a lightly nicer way to do thigs: cat production.log | grep "^Processing" | ruby -e 'ips = Hash.new(0); while gets; ips[$_[/\s.*?\s.*?\s(\S+)/,1]] += 1; end; ips.length' While this already was a nice solution (and terrible ugly to read) it still worked and gave the number of hits just as the first line of code. The basic idea in both of this is to create a hash of IP’s that accessed the website and then return the length of the hash. Nice, both of them so in the end there is a much simpler what without the use of ruby (as much as I love the language) so here what came out after a bit more pondering, it don’t uses ruby any more just console commands: cat production.log | grep "^Processing" | awk '{print $4}' | sort -u | wc | awk '{print $1}' A short in detail description of what happens. `cat production.log` gets the data of the content of the logfile itself the `|` pipes the output to the next command (like one would write to the STDIN). The next step is to filter the log `grep “^Processing”` takes care of this it only leaves lines that start with the word Processing which would be (I masked the IP from that line): Processing ArticlesController#permalink (for xxx.xxx.xxx.xxx at 2006-08-01 20:53:29) [GET] The following command `awk ‘{print $4}’` gets the 4th word of the line, which in this case would be the IP of the whole request. Now we have a list of all IP’s that ever accessed the site. As there are still multiple lines from the same IP in there we need to filter them. `sort -u` takes care of this it sorts the list and remove double entries, like twice then same IP. Now all that is left is to count the lines in this file, `wc` is our friend here, it returns 3 values while the second and third don’t really interest is the first does so again `awk` will fetch the word of the resulting line we want. The last command in the chain is `awk ‘{print $1}’`. Done. Enjoy it or not ;) most other tools are more precise, accurate and give more information still it is a quick way to get a rough idea and I found good use of it.

Posted by Heinz N. 'Licenser' Gies Fri, 11 Aug 2006 20:59:00 GMT


Ajax Scaffold live search

Currently I’m working on a project using Rails and heavy Ajax coding for a browser based application for address, room and personal management. [Ajaxscafold](http://www.ajaxscaffold.com/) is an excellent tool for this and took a lot of ‘routine’ work, by providing the whole edit/new and whatnot, from me. **Step 1** - Getting rails to work. ———————————– Okay to get the easy part done quickl: gem install rails gem install ajax_scaffold_generator rails /path/to/todo cd /path/to/todo rm public/index.html Now we’ve a basic rails app set up. If there are any problems with this steps: [Google](http://google.com) is your friend, there are about one million trillion tutorials on that topic and it might be a good thing to start of with one of this, as I’m not going in details here. **Step 2** - Setting up a database and the Scaffold. —————————————————- We’re going to use migrations for this, actually only one but that will be just fine. Get to the directory we set up the rails application into. And type the following: script/generate migration CreateTodoTable create db/migrate create db/migrate/001_create_todo_table.rb This will create a database migration file we can later easily patch into the tables. Here the content of the migration file: class CreateTodoTable < ActiveRecord::Migration def self.up create_table 'todos' do |t| t.column 'name', :string t.column 'description', :text end end def self.down drop_table 'todos' end end With that done the next step will be to run `rake migrate` to have rake set up our table, and we’re done her too. At this point we’ve an all nice and shiny database, table and a basically running rails, (hopefully) if not just make it work. All left to do is to generate the scaffolds, which again is ‘ruby simple’ to be exact only a single command: script/generate ajaxscaffold Todo **Step 3** - Adjust the templates. ———————————- To add the search features we need to make a few adjustments to the templates, fist we alter the `app/views/todos/component.rhtml`and replace:
<% new_params = params.merge(:controller => ‘/todos’, :action => ‘new’) %> <%= loading_indicator_tag(new_params) %> <%= link_to_remote "Create New", { :url => new_params, :loading => “Element.show(‘#{loading_indicator_id(new_params)}’);” }, { :href => url_for(new_params), :class => “create” } %>
With the new code for search field, we don’t need a form as we want to make it dynamically updating, and use a observer instead of it. We set the update to an empty string so it don’t overwrites any other elements, as we will only return an java script:
<% new_params = params.merge(:controller => ‘/todos’, :action => ‘new’) %> <%= loading_indicator_tag(new_params) %> <%= link_to_remote "Create New", { :url => new_params, :loading => “Element.show(‘#{loading_indicator_id(new_params)}’);” }, { :href => url_for(new_params), :class => “create” } %> <% search_params = params.merge(:controller => ‘/todos’, :action => ‘search’) %> <%= text_field_tag :search %><%= loading_indicator_tag search_params %> <%= observe_field(:search, :frequency => 0.5, :update => ”, :loading => “Element.show(‘#{loading_indicator_id(search_params)}’)”, :complete => “Element.hide(‘#{loading_indicator_id(search_params)}’)”, :url => search_params) %>
Okay so far the first step, but it would be too easy if that would be all. We need to give the footer an ID, so we can later easiely set new paginnation links via javascript. In the same file, at the very bottom change: by adding of `id=”todo-pagination”` to the `
`tag to: One more to go, we need to adjust the pagination links to make sure they work correctly with the search, and don’t screw us over once they are used. Open the file `app/views/todos/_pagination_links.rhtml`. We are making two adjustments, first we need to make sure the pagination links call the `search` action and not the `update_component` action, also we need pass the search string along. For this we need to change: <% pagination_params = params.merge(:controller => ‘/todos’, :action => ‘component_update’) %> to the following: <% if @search %> <% pagination_params = params.merge(:controller => ‘/todos’, :action => ‘search’, :search => @search) %> <% else %> <% pagination_params = params.merge(:controller => ‘/todos’, :action => ‘component_update’) %> <% end %> Last to go in this section, we need to change the `:updata` parameter for the two links to: :update => @search ? ” : scaffold_content_id(pagination_params) }, Okay I was not abselutely honest, we still need to create a new file `app/views/todos/search.rjs` to format our search results and have a javascript output. It is fairly simple and should look like this: if @successful page.replace_html scaffold_tbody_id(params), :partial => ‘todo’, :collection => @todos, :locals => { :hidden => false } page.replace_html ‘todo-pagination’, :partial => ‘pagination_links’, :locals => { :paginator => @paginator, :search => @search } else page.replace_html scaffold_messages_id(@options), :partial => ‘messages’ end **Step 4** - The code! ———————- First we need to slightly adjust the `pagination_ajax_links` helper function, the place to to put it is `app/helpers/todos_helper.rb`. The function should look like the following (nearly the same as the original just that it changes the ‘update’ section): def pagination_ajax_links(paginator, params) pagination_links_each(paginator, {}) do |n| link_to_remote n, { :url => params.merge(:page => n ), :loading => “Element.show(‘#{loading_indicator_id(params.merge(:action => ‘pagination’))}’);”, :update => params[:search] ? ” :scaffold_content_id(params) }, { :href => url_for(params.merge(:page => n )) } end end Well we’re coming close to what we want, mainly left now is to add the search action to the controller, so we open the file `app/controllers/todos_controller.rb”` and insert the following function: def search @search = params[:search] || request.raw_post || request.query_string @options = { :scaffold_id => params[:scaffold_id], :action => “search”, :search => @search } update_params :default_scaffold_id => “todo”, :default_sort => nil, :default_sort_direction => “asc” @sort_sql = Todo.scaffold_columns_hash[current_sort(params)].sort_sql rescue nil @sort_by = @sort_sql.nil? ? “#{Todo.table_name}.#{Todo.primary_key} asc” : @sort_sql + ” ” + current_sort_direction(params) search = ‘%’ + @search + ‘%’ search_fields = [‘name’, ‘description’] conditions = [ search_fields.map{|p| “#{p}” }.join(’ LIKE ? OR ‘) + ’ LIKE ?’ ]; search_fields.each do || conditions << search end @paginator, @todos = paginate(:todos, :conditions => conditions, :order => @sort_by, :per_page => default_per_page) @successful = !@todos.empty? @flash[:error] = “Nothing found for search string #{@search}.” if !@successful render(:action => ‘search.rjs’) end A little explanation, line **2** we get the search string in whatever way it may be passed, line **3-6** are usual handling for sorting the output. In line **7** we add `%` around our search string, this are wild-cards in SQL you can add only one in the end but I prefer this way. Right next we define the fields over what we want to search, in our case, both name and description. `conditions` holds the search’s ‘WHERE’ statement for the SQL SELECT, the each loop over the `search_field` in line **12** fills the `conditions` array with the search elements, you can read up details on how this works in the [rails API](http://api.rubyonrails.org), for now all that matters is that, every `?` in our search string gets replaced with one of the following elements of the array. Finally we call the pagination and do some error handling and in the very end render the `search.rjs`. **Step 5** - Last words. ———————— Okay we’re done here, have fun and enjoy this new funky feature for your app. If there are any ideas, questions, suggestions don’t be shy to let me know or ask. Also as a **warning** currently this do not do any fallback if no javascrip is present but I may write a tutorial on that up on a later date this text is long enough as it is.

Posted by Heinz N. 'Licenser' Gies Sun, 30 Jul 2006 13:54:00 GMT


Typo & Coderay

Well I’ve decided to play with that Typo thing, nice very nice to be exact. Now I flipped through the admin settings and found that even syntax highlight for code is supported, even nicer, so the used highlighter is somewhat limited and as odds are a friend of mine (named murphy) and myself worked on syntax highlighting a good while ago with very good results and I happen to know that there is a ruby offspring of said efforts (ported and extended by murphy) that is still maintained. To cut a long story short, I am too curious about how things work to not make a Typo plugin to support Coderay and well here we go I did it, using the provided `` plugin as a base. Here a little help how to set it up. 0. Why the hassle? —————— There are a number of reasons, first would be cause I wanted to see how extendable Typo is while that might not be of any interest for someone else there are still other reasons. The first would be that Coderay simply provides more languages then the original shipped syntax highlighter. For example C (and deviates), html, or more important rhtml. Second would be the simple fact that Coderay is very damn precise about highlighting, while that don’t matters for ‘easy’ languages like C that are very strict in their syntax it **does** matter for languages like ruby. Here a little example about how good it works (from the plugin help): class MyClass def MyFun “abcde #{(“#{my_int_arg} times”)*my_int_arg }” end end Note the nested code blocks in the string, also regular expressions are matched very good. Third is that it is just very fast compared to other highlighters, while it don’t matters for a one line code sample it can matter when codes get bigger or more. 1. Get coderay ————– A gem is provided so it is not a big problem installation is simple: gem install coderay Which should install Coderay and all it’s dependencies. Thanks to the great ruby gems systems it’s not hard eh? the rest is neither so lets go on. 2. Set up Typo ————– This is not all that easy but it stays simple if you’ve a fundamental gasp about the file system of your operating system. To begin with download the [controller](http://heinz.licenser.de/coderay_controller.rb.bz2) (it is provided as a attachment) I assume you’re running under a *nix shell in the example so here we go: wget http://heinz.licenser.de/coderay_controller.rb.bz2 You can also just download it via browser and later upload it to your side but well I explain how I would do it not all possible ways so bear with me ;). Okay next step is to copy the controller to the right place. Typo is so nice to make it easy to do the installation of plugins, so having the file in the right place will be enough to have it running in the first place. The path for text-filters is: `components/plugins/textfilters/` assuming you’re into the typo root directory. Also I assume you downloaded the controller into your home directoy. Okay here step by step what to do: cd cp ~/coderay_controller.rb components/plugins/textfilters/ Tada, that part done if you’re running the installation under another user you may want to adjust the ownership (unless you understand and already know how to do that you most likely don’t have to worry about it). Okay restart typo and oh happy joy you can post code! typo restart 3. Syntax sugar ————— Now you’ve an working Coderay highlighter (hopefully) but it don’t highlights much unless you put the CSS styles nicely. Easiest way is to use the CSS files Coderay already provides all you’ve to do will be: cd coderay_stylesheet >> public/stylesheets/administration.css coderay_stylesheet >> public/stylesheets/user.css And all looks nice and shiny! Feel free to adjust the styles to how you like it or just leave them how we liked it ;) There we go all is done! Hopefully at least this worked just fine for me. Non the less if you run over a problem let me know about it.

Posted by Heinz N. 'Licenser' Gies Sat, 29 Jul 2006 17:15:00 GMT