Wednesday, October 31, 2012

Un-follow All Twitter Followings

My Twitter account was hacked.  I'm think I read about a Twitter breach at some time, or maybe I had a weak password.  I also ignored the weird follower & following emails I was getting.  Its my own fault, but I just wasnt worried about it.

I decided to check out a new Twitter App on Android today.  When I logged in, I saw all kinds of weird posts that I hadnt made, followers I'd never heard of, and over 1k of people I was following - I think I was following 2 people when I had previously checked.

So I changed my password, deleted the bogus tweets and then moved on to address the 1k of people I was following.  Turns out, this is kind of difficult.  There are some pay apps you can do it with, or you can click through all of the people and unfollow.  Awesome....

I had an idea.  Since the twitter page will load all of my people as I scroll, I could write something that walked the DOM and handled this issue for me.  I assumed Twitter had jQuery installed, so I opened up Firebug's console and hacked it together.

Here is the Javascript :

$("span.button-text.following-text").each(function(iIndex, oElement){
    var oElement = $(oElement);
    if (oElement.css("display") != "none"){
        oElement.click();
    }
})

The script will only click on the buttons with "Following" in the text, so you dont have to scroll all the buttons into view at once.  You also dont have to worry about it toggling the buttons.

Done.  If anyone from Twitter reads this, it would be nice if you guys provided a feature for this.  

Tuesday, January 3, 2012

New Year, New Gig

Its a new year and I've started at a new job. Not just a new job, but new job using new technology located in a new state far enough away to have a new climate. Fun Stuff right?

Since this is a technology blog, I'm going to speak to that. I will no longer be using Grails in my daily work life. My new job has me dealing with both Java and .NET web applications. I still intend to keep up with Grails, but realistically I wont be paying as much attention as before. Regarding my Grails plugins, I plan to maintain the jQuery-UI plugin up. The YUI plugin will probably die off unless someone asks me for it.

To be honest, I'm not sure how much I'll be able to write about my new work - I have to ask my boss. In the mean time, I should have more time for side projects and code adventures - so I'll share those instead.

Sunday, September 25, 2011

Simplifying External TagLibs with Proxies

I am the proud author of the jQuery-UI-Widget Grails Plugin.   I built this plugin to enable Grails developers the ability to create jQuery-UI widgets without dealing with JavaScript directly.   This allows Grails developers to use the resources they are familiar with while still building cool, rich User Interface components.

This post isnt about my plugin.  Instead, its about how engineers can better utilize plugins like mine.  

One of the challenges I've faced when leading a team of developers is this... How can I enforce all components of a certain type are built the same way, especially when I dont control the construction of the component itself.  A non-abstract example of this issue is this... Developers on my team are all creating jQuery-UI AutoCompletes via the TagLib.  How do I ensure all the AutoComplete configuration properties are the same?

The answer is simple.  You require all instantiations of the component to go through your own code.  This is called the Proxy Pattern.  In practice, you create a wrapper that your developers call.  This wrapper is responsible for setting the standard configuration properties for the component and creating the component itself.  The ability to override or further customize the component can be easily implemented as well.

Lets look at an example using a custom Grails Tag and my jQuery-UI-Widget plugin.  I'm going to encapsulate the jQuery-UI AutoComplete in my own tag.

def myautocomplete = { attrs, body ->

 // grab the id
 def id = attrs.remove("id")

 // create a config to pass to taglib
 def acConfig = [:]
 // pass the id along to the config
 acConfig.id = id
 // throughput the widget config or create a new one
 acConfig.config = attrs.remove("config") ?: [:]
 // enforce the delay property 
 acConfig.config.delay = 200 
 // set the minLength property if not overridden by instance config
 acConfig.config.minLength = acConfig.minLength ?: 1 

 //call the jquery-ui taglib
 out << jqueryui.jquiAutoComplete(acConfig, body)

}

This Tag is a Proxy to the jQuery-UI TagLib's jquiAutoComplete tag. The config is passed along to the target tag after any defaults are set. Doing this allows me to enforce a standard for our application's jQuery-UI Widgets.




Thats is. The idea is pretty simple overall, but flexible enough to allow my team to build the Widgets we need for our application. I've applied this approach to jQuery-UI Widgets, YUI2 Widgets and DataTables.

Tuesday, September 6, 2011

Extending jQuery-UI Widgets

I recently needed to extend the jQuery-UI AutoComplete Widget for a few custom features. The act of extending the Widget was relatively easy, but its not the entire story. Simply extending the jQuery-UI Widget will cause you to lose native functionality. Here is what I'm talking about...

Say I want to extend the jQuery-UI Widget...
$.widget("ui.myAC", $.ui.autocomplete, {
    myMethod : function(){
    },
    myOverride : function(){
        self.myOverride()
    }
});

Doing this allows me to instantiate my custom widget...
$("#myInput").myAC({});

However... the following wont work.
$("#myInput").myAC("search", "%");

Calling the widgets public methods will fail. A little debugging shows me that jQuery-UI doesnt think that method exists. Hmm... I extended a jQuery-UI Widget, but I lost the native methods. Boo!

Since jQuery-UI Widget extension has changed recently, Google didnt provide me with an obvious answer. However, I kept stumbling upon this thing called a Bridge.

Lets try it...
$.widget.bridge("myAC", $.ui.myAC);

Woot! I now have access to the native methods. Now my custom widget is fully functional.

I could attempt to explain all the different things $.widget.bridge does for us, but I'd do a poor job. Here are some folks that have already explained it.
Eric Hynds
Alex Sexton

Monday, August 1, 2011

Grails Plugins and Default Configs

I've been working on Grails plugins for jQueryUI and YUI2.  One of my ideas was to use a default config within my plugin, which the plugin consumer could override and modify the config values for their usage.

Unfortunately, Grails doesn't provide this feature by default.  You can use the plugin's Config.groovy for settings when you test, but it doesnt work when the plugin is being ran from an app.  Unless...  you do the following.

Lets say your creating the next awesome plugin.  We'll call it Foo.

1.  Create a groovy config file that is unique to your plugin.  Mine is FooConfig.groovy. Inside, put your config values.
fooConfig {
  fooVar = "Hello World"
}

2.  Load your new config via the FooGrailsPlugin.groovy file.  This code is a modified version of the code found in Spring-Security-Core plugin.  Thanks Burt.
def doWithSpring = {
  mergeConfig(application)
}
private void mergeConfig(GrailsApplication app) {
  ConfigObject currentConfig = app.config.grails.fooConfig
  ConfigSlurper slurper = new ConfigSlurper(Environment.getCurrent().getName());
  ConfigObject secondaryConfig = slurper.parse(app.classLoader.loadClass("FooConfig"))

  ConfigObject config = new ConfigObject();
  config.putAll(secondaryConfig.fooConfig.merge(currentConfig))

  app.config.grails.fooConfig = config;
}

3.  Finally, we need to make our plugin config reload when a config is changed elsewhere in the application.
def onConfigChange = { event ->
  this.mergeConfig(application)
}

Thats it. Thats all I had to do. Now I can use default configs within my plugin and allow my plugin consumers to customize. Fun Stuff.

Here is an example of customization...
grails.fooConfig.fooVar = "I've been updated!"

Full Disclosure : I havent tested this in a deployed WAR yet.
Works from run-war.

Referenced Links
Post 1
Post 2

Monday, June 13, 2011

Debugging Grails Controllers & Closures in IntelliJ

We're using IntelliJ at work for our Grails development.  IntelliJ is a solid IDE with great Grails support.  I should have no complaints... but this one issue has been nagging at me.  When using IntelliJ to debug Grails, I couldn't use the Watch Window to interrogate a Controller Action's arguments.

Setting a watch variable to params or request in the following action closure yields...
Cannot find local variable 'params'
def myAction = {
}

Of course, if we set the params argument to a reference, then we can interrogate it. So we know the object is there... so what gives?
def myAction = {
  def myParams = params
  def myRequest = request
}

The answer is simple and opaque at the same time. Closures aren't methods. I'm guilty of forgetting this and Grails is great about hiding this fact from us.  However, IntelliJ isn't that smart.  When debugging in IntelliJ, we have ask the Closure the right question.
this.getProperty("params")

Ah Ha! There is my params argument in IntelliJ.  Now I can stop writing println everywhere...

More info on Closures
Formal Definition
Informal Guide

Thursday, May 19, 2011

Grails, Envers and Blob

We've added Hibernate Envers to our Grails project.  Thus far, Envers has handled all our object versioning requirements...  Until we tried to use a Blob.

@Audited
class Data {
    Blob data
}

org.hibernate.MappingException : Type not supported for auditing: org.hibernate.type.BlobType, on entity Data, property 'data'.

What is the solution?  Envers does not throw an exception for a Byte Array, so replace Blob with it.  However, MySQL will map the Byte Array to a TinyBlob, which may not work for you.  You can modify this by updating the GORM DSL on the domain.

@Audited
class Data {
    byte[] data
    static mapping = {
        data sqlType: 'blob'
    }
}

This resolved the problem for us.