Skip to content

Posts by admin:

    So How Do You Convince Google App Engine to Create Your Datastore Indexes

    September 3rd, 2010

    Creating indexes on Google App Engine / Java (gae/j) is an easy job. You don’t even have to think about it (well, for some time)

    For etohum admin application we used gae/j and it has been almost two years and gae/j has been improved a lot, but still, it has some really annoying features (bugs — I am not sure how to named them).

    This time, it is the Datastore Indexes. Some of the pages requires indexes like

    which turns out to be confusing for the auto generation tool. If, let’s say, you change the order of the last two fields,

    like this

    you will not get it automatically.

    Even if you explicitly define it in your  datastore-indexes.xml file

    <datastore-index kind="Application" ancestor="false" source="manual">
     <property name="applciationIsFinished" direction="asc"/>
     <property name="isSpam" direction="asc"/>
     <property name="sezonId" direction="asc"/>
     <property name="bitisTarihi" direction="desc"/>
     <property name="basvuruTarihi" direction="desc"/>
     </datastore-index>
    

    And the workaround for the problem is stated in the last paragraph of Using Automatic Index Configuration documentation

    It’s a good idea to occasionally move index configuration from datastore-indexes-auto.xml to datastore-indexes.xml, then disable automatic index configuration and test your app in the development server. This makes it easy to maintain indexes without having to manage two files, and ensures that your testing will reproduce errors caused by missing index configuration.

    So change the datastore-indexes.xml file and add manually the all required indexes and upload the application.

    <datastore-indexes autoGenerate="false">

    You can change it back to auto generate after make sure the desired indexes are created.

    ps. A tip about gae/j is that it is considerable faster when it is 4AM-7AM at the west coast of North America.

    No Comments "

    iOS Shouldn’t Have 6 Device Orientations

    August 30th, 2010

    For a small iPad project, I happened to use iPad’s orientation stuff. As it turns out, there is always a catch.

    In UIDevice class , you see the following orientations:

    typedef enum
    {
        UIDeviceOrientationUnknown,
        UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
        UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
        UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
        UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
        UIDeviceOrientationFaceUp,              // Device oriented flat, face up
        UIDeviceOrientationFaceDown             // Device oriented flat, face down
    } UIDeviceOrientation;
    

    But for a view controller’s parent, there are only four

    self.parentViewController.interfaceOrientation only has

    typedef enum
    {
        UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
        UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
        UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
        UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
    } UIInterfaceOrientation;
    

    So the problem arises when you try to layout according to

      [UIDevice currentDevice].orientation
    

    When the device orientation is UIDeviceOrientationFaceUp or UIDeviceOrientationFaceDown, you get 3 orientation changed calls. One is the up and down, than a landscape, than again up or down.

    This is, to be honest, completely broken. It is clear that, since the status bar can be located to four locations on the screen, there should be 4 device orientations, not 6. The FaceUp and FaceDown should be a different property I guess (gravityOrientation or sth like that)

    ps. Some links that can help if you have issues with this up&down thing

    No Comments "

    Adding Short Sound Clips to iPhone/iPad Apps

    August 24th, 2010

    There are lots of ways of playing/recording audio in your iPhone/iPad app, and probably this is why it took me a while to decide which one to chose,

    Here are the alternatives (List of Audio APIs) –

    • System Sound API — very short – limited file type – no control
    • AVAudioPlayer class — objC
    • Audio Toolbox — recording – streaming – controls
    • Audio Units — audio processing
    • OpenAL — 3D positional sound (Yes, just like OpenGL)

    Since what I need is just to play a short audio clip w/out any looping or any other control, I choose System Audio API.

    As always, Google is the first address to ask howto use System Audio AP, How To Play Audio With The iPhone SDK is a step by step guide, but it takes the starting point from a sample code project from Apple, which is no longer available.

    Another one is the sample code project SysSound which contains an iOS4 specific feature so that it will not work on iPad.

    So how to play an audio clip w/out hassling that much?

    Here is the code snippet : (don’t forget to add the AudioToolbox framework)
    #include
    ….

    -(void)playSound
    {
    	SystemSoundID shortSound;
    	NSURL* audioFile = [NSURL fileURLWithPath:[[NSBundle mainBundle]
    				pathForResource:[NSString stringWithFormat:@"filename" ofType:@"wav"]];
    	AudioServicesCreateSystemSoundID((CFURLRef)audioFile, &shortSound); 
    
    	//playing it
    	AudioServicesPlaySystemSound(shortSound);
    
    	//cleanup
    	AudioServicesDisposeSystemSoundID(shortSound);
    
    }
    

    No Comments "

    Implementing Paging on Google App Engine Java (gae/j) and GWT — the query cursor way

    August 12th, 2010

    For the etohum admin application application, we used Goole App Engine Java (gae/j) two years ago, back then, the way to implement paging was not that easy. Because of that we came up with our custom way and implemented a combination of memcached+servlet+cron jobs update mechanism which introduced many bugs and took many hours to reach perfection.

    Since Burak hoca asks for an enhancements recently, we go through the app engine documentation and see this new feature query cursors which is excellent for paging.

    The idea behind query cursors is pretty simple, make a query for the first page, pass the cursor data to the client. When you need the second page,  instead of  making a query from scracth, use the cursor data to get the next page’s data.

    In our case the RPC call  getApplications(String cursor) is called. For the first page, cursor data is passed as null, so we make the query as follows:

    if (cursorString == null)
    {
    	//
    	Query query = pm.newQuery(Application.class);
    	query.setOrdering("basvuruTarihi desc");
    	query.setRange(0, 15);
    
    	results = (List) query.execute();
    
    	Cursor cursor = JDOCursorHelper.getCursor(results);
    	resultWrapper.setCursorData(cursor.toWebSafeString());
    
    	for (Iterator iterator = results.iterator(); iterator.hasNext();)
    	{
    		Application applicationFromDatabase = (Application) iterator.next();
    		app = DunyaTurkOlsunUtil.createApplicationDTO(applicationFromDatabase);
    		resultAppList.add(app);
    	}
    	resultWrapper.setResultAppList(resultAppList);
    }
    

    So this code above fetch the first page and cursor string. On the client side, inside GWT, we hold the cursor string for each page in an arraylist, so that we can handle going back and forth between the pages.

    When the user asks for the second pages, the following code block executes

    else
    {
    	Cursor cursor = Cursor.fromWebSafeString(cursorString);
    	Map extensionMap = new HashMap();
    	extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, cursor);
    	Query query = pm.newQuery(Application.class);
    	query.setOrdering("basvuruTarihi desc");
    
    	query.setExtensions(extensionMap);
    	query.setRange(0, 15);
    
    	results = (List) query.execute();
    	resultWrapper.setCursorData(JDOCursorHelper.getCursor(results).toWebSafeString());
    
    	for (Iterator iterator = results.iterator(); iterator.hasNext();)
    	{
    		Application applicationFromDatabase = (Application) iterator.next();
    		app = DunyaTurkOlsunUtil.createApplicationDTO(applicationFromDatabase);
    		//
    		resultAppList.add(app);
    	}
    	resultWrapper.setResultAppList(resultAppList);
    }
    
    //
    This works even faster than memcached version of ours. 
    
    ps. By the way, there is still no way of passing JDO objects through RPC calls which is sad for GWT apps on GAE/J/
    

    No Comments "

    Weird Grails Deployment Problem — MissingMethodException yada yada

    August 11th, 2010

    We host Remotespots on a Tomcat 6 server on eapps. As we changed the UI design, we deployed a new version of it yesterday, but the scaffold views seems broken with the following error:

    Error 500: Executing action [list] of controller [app.InvitationCodeController] caused exception: groovy.lang.MissingMethodException: No signature of method: static app.InvitationCode.list() is applicable for argument types: (org.codehaus.groovy.grails.web.servlet.mvc.GrailsParameterMap) values: [[action:list, controller:invitationCode, max:10]]
    Servlet: grails
    URI: /app/grails/invitationCode/list.dispatch
    Exception Message: No signature of method: static app.InvitationCode.list() is applicable for argument types: (org.codehaus.groovy.grails.web.servlet.mvc.GrailsParameterMap) values: [[action:list, controller:invitationCode, max:10]]
    Caused by: No signature of method: static app.InvitationCode.list() is applicable for argument types: (org.codehaus.groovy.grails.web.servlet.mvc.GrailsParameterMap) values: [[action:list, controller:invitationCode, max:10]]
    Class: script12814638559751136092009
    At Line: [13]
    

    With the Stack Trace:

    groovy.lang.MissingMethodException: No signature of method: static app.InvitationCode.list() is applicable for argument types: (org.codehaus.groovy.grails.web.servlet.mvc.GrailsParameterMap) values: [[action:list, controller:invitationCode, max:10]]
    
    	at app.InvitationCodeController$_closure2.doCall(script12814638559751136092009.groovy:13)
    
    	at app.InvitationCodeController$_closure2.doCall(script12814638559751136092009.groovy)
    
    	at org.apache.shiro.web.servlet.ShiroFilter.executeChain(ShiroFilter.java:687)
    
    	at org.apache.shiro.web.servlet.ShiroFilter.doFilterInternal(ShiroFilter.java:616)
    
    	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
    
    	at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
    
    	at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
    
    	at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:769)
    
    	at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:698)
    
    	at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:891)
    
    	at java.lang.Thread.run(Thread.java:619)
    

    Although it runs on the local server grails run-app, the same problem occurs with grails run-war, and also on the Tomcat 6 on eapps. So after a little Googling, here is the magical solution:

    grails clean

    This solves the problem :)

    These are the links that can help:

    No Comments "

    Using Different AWS S3 Buckets on Different Rails Environments

    August 10th, 2010

    Below is the process for using different buckets on Amazon S3 with your production and development environments (Paperclip)

    1. Add config vars to your Heroku environment  http://blog.heroku.com/archives/2009/4/7/config-vars/

    heroku config:add S3_BUCKET=production-bucket-name S3_KEY=8N029N81 S3_SECRET=9s83109d3+583493190
    

    2. Add the same constants to your .profile file

    export S3_BUCKET=development-bucket-name
    export S3_KEY=888888888
    export S3_SECRET=999999999

    ps . Blog Post on Heroku about AWS S3 — http://blog.heroku.com/archives/2009/4/7/config-vars/

    ps2. and yes this post is also about  heatmap.me which is my pet project for online heatmap generation.

    No Comments "

    Weird Grails+Adobe+Mac OS X Error

    August 3rd, 2010
    2010-08-03 19:00:21.793 java[3891:60f] Error loading /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types:  dlopen(/Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types, 262): no suitable image found.  Did find:
    /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types: no matching architecture in universal wrapper
    java: OpenScripting.framework - scripting addition "/Library/ScriptingAdditions/Adobe Unit Types.osax" declares no loadable handlers.
    

    Yes this seems to be a Mac issue, the solution is as follows:

    Solution 1: Update the Adobe Unit Types.osax to version 2.1.0.

    1. Click this link to download the Adobe Unit Types.osax version 2.1.0 file.
    2. Choose /Library/ScriptingAdditions.
    3. Move the existing Adobe Unit Types.osax file to a backup location.
    4. Copy the downloaded version of the Adobe Unit Types.osax file to the /Library/ScriptingAdditions folder. Select Yes to authenticate this operation.
    5. Restart your computer.

    This is from the link http://kb2.adobe.com/cps/516/cpsid_51615.html

    No Comments "

    Sending E-mail with Rails via Gmail (Spoiler Alert! this is for dummies)

    July 30th, 2010

    Yes, Rails is super cool, everything is super easy, and so far I really fall in love with it. But why is it that hard to send an e-mail via Gmail !?!

    So after messing up a couple of git branches, I finally get it work, yey!

    Here are the steps:

    • Watch the railscast about sending email
    • Install the gem with TLS
    • sudo gem install ambethia-smtp-tls -v '1.1.2' --source http://gems.github.com
    • Add the following to your environment.rb (Be careful after the Rails::Initializer.run do |config| block. )
    • #to the top of file
      require 'smtp-tls'
      
      ...
      #to the very end of the file
      ActionMailer::Base.smtp_settings =
      {
          :address => "smtp.gmail.com",
          :port => 587,
          :domain => "gmail.com",
          :user_name => "dkberktas",#not with @gmail.com
          :password => "xxxyyyzzz",
          :authentication => :plain,
          :enable_starttls_auto => true
      }
    • Run the mailer generator by
    • script/generate mailer user_mailer
      
    • Go to UserMailer class and add the method
    •   def registration_confirmation()
          recipients  "xxx@gmail.com"
          from        "xxx@gmail.com"
          subject     "Thank you for being that awesome"
          body        "no I am just kidding" #if you want to pass parameter do it like this -- > ":user => user"
        end
      
    • Add a sample method to application controller and add it to the routes.rb
    • #in application controller
        def mailDeneme
          UserMailer.deliver_registration_confirmation()
          render :text => "OK"
        end
      #in routes.rb
      map.mail  '/mail',  :controller => 'application', :action => 'mailDeneme'
      

    If you see an error like this:

    Net::SMTPAuthenticationError (530 5.7.0 Must issue a STARTTLS command first.

    You miss the item above about  installing smtp-tls gem. Read it again again, or check this forum post.

    ps. This is the official rails guide.
    ps2. this is another link.

    No Comments "

    Background Jobs in Rails — Delayed_job

    July 22nd, 2010

    Rails has lots of options for background jobs, the list below is a collection of link that help my choose Delayed Jobs which is a simple and capable enough one.

    • Blog post which is a good summary of alternatives — (kind of a survey)
    • A related question on StackOverflow
    • Blog post about Delayed Job link
    • Heroku suggests Delayed Job, so this is the one I am looking for ;)
    • and finally this is the Heroku guide for using Delayed Job
    • Railcast about Delyaed_job
    • Tip&Tricks

    If you are interested, we are using Delayed Job for creating our heatmaps for remotespots usability testing site. Heatmap project will probably work as a separate project so that others can also use it for creating heatmaps on top of their images. Stay tuned for the heatmap side project!

    Steps for Delayed_job

    • Install the plugin from github (from collectiveideas) with
    • script/plugin install git://github.com/collectiveidea/delayed_job.git
    • Create the model
    • script/generate delayed_job
      rake db:migrate
    • You can set priority and a certain time for the job to be put on queue.
    • send_later(:your_method_name, -3, 3.days.from_now)

    No Comments "

    Summary of Web Application Libraries for iPhone

    July 17th, 2010

    PastryKit — it is from Apple, but it is not public,  you can see it from the iPhone User Guide, it will be released to public hopefully.

    Sencha Touch — you should definitely see their kitchen sink, it is pretty cool.but there is no commercial license yet.

    and the winner is ...

    iUi — not that many people using it I guess. I build a site with it, if it is sth fast and easy to learn, iUi can do the job.

    jqtouchdemos seem very nice, probably better than iUi in terms of current release capabilities and size of community.

    iWebkitdemo seems promising, but not ready for prime time.

    SproutCore — not for iPhone specificly, but its demo seems nice.

    So my choice for the next task is jqtouch. not iui this time.

    No Comments "