Recent posts http://marteinn.se/blog/feed/atom/ 2016-05-05T17:31:16Z Werkzeug Logging Flask Exceptions to Slack http://marteinn.se/blog/logging-flask-exceptions-to-slack 2016-05-05T17:31:16Z 2016-05-05T17:31:16Z marteinn <p>I recently integrated a slack based logging in Flask and managed to put together a small guide as a gist, enjoy!</p> <p>[gist id=18bd85db1a908361858ab6976294680d]</p> Log cabin http://marteinn.se/blog/log-cabin 2015-11-08T16:58:38Z 2015-11-08T16:58:38Z marteinn <p><img src="[uploads]Icon_256x256.png" alt="logo-promo" width="150" height="150" class="alignleft size-thumbnail wp-image-837" /></p> <p>Happy to announce my latest project, a Time Tracker for Mac called Log Cabin. </p> <p>There are plenty of time trackers out there, but I have never used anything that suited my needs, so I decided to roll my own.</p> <p><strong>What makes this tracker different?</strong> - It has a really easy to use time tracker with itunes-like controls - Editing is super easy through a view anyone can recognize, a ical/google calendar view. - Export with markdown support - Being able to write comments (it sounds weird but plenty of trackers misses this) - A progress bar so you can keep track of your daily goal (comes in the next update)</p> <p>If this sounds like something for you, please <a href="https://itunes.apple.com/se/app/log-cabin-time-tracker/id1052867105?mt=12">try it out</a> (we currently have a 33% discount) and let me know what you think!</p> Directory based fabricrc with fabric http://marteinn.se/blog/directory-based-fabricrc-with-fabrid 2015-09-06T14:50:10Z 2015-09-06T14:50:10Z marteinn <p>I'm a big fan of Fabric, such a big fan that I decided to base a deploy tool around it. But once small annoyance I have is how it deals with <a href="http://docs.fabfile.org/en/latest/usage/env.html#rcfile">fabricrc files</a>. If not supplied in the fab command, fabric will look for a file in <code>$HOME/.fabricrc</code>. Since I always use project based fabricrc files it ends up with me having to supply fabricrc on every command call.</p> <p>So I put together a little script to change this, what this script does is to look for .fabricrc or fabricrc.txt in the directory where fab is run, before looking in <code>$HOME</code>.</p> <p>[gist id=8bd1ff236014b0123d7d]</p> Using the Fetch Api with Django Rest Framework http://marteinn.se/blog/using-the-fetch-api-with-django-rest-framework 2015-08-03T14:50:37Z 2015-08-03T14:50:37Z marteinn <p>The <a href="https://developer.mozilla.org/en/docs/Web/API/Fetch_API">fetch api</a> is a pretty cool thing that can really simplify client networking code. So how would one go about to use it with django-rest-framework?</p> <h2>Server</h2> <p>First, make sure you use the SessionAuthentication in Django. Put this in your settings.py</p> <h3>Django rest framework</h3> <p><code>python REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication' ] }</code></p> <h3>Client</h3> <p>Then start with including the getCookie method from the <a href="https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax">Django Docs</a>.</p> <p>Finally use the <code>fetch</code> method to call your endpoint.</p> <p>```python var myData = { hello: 1 };</p> <p>fetch("/api/v1/endpoint/5/", { method: "put", credentials: "same-origin", headers: { "X-CSRFToken": getCookie("csrftoken"), "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify(myData) }).then(function(response) { return response.json(); }).then(function(data) { console.log("Data is ok", data); }).catch(function(ex) { console.log("parsing failed", ex); }); ```</p> <p>Easy!</p> Summary of 2014 http://marteinn.se/blog/summary-of-2014 2015-01-19T21:21:50Z 2015-01-19T21:21:50Z marteinn <p>2014 was a productive year for me. I would round it up like this: less cms/more frameworks (at work), two new side projects and a couple of open source libraries out in the open.</p> <h2>Work</h2> <p>My second year as a developer at Fröjd, while running MadeInStockholm on the side. Really enjoying this combination.</p> <h2>Programming</h2> <p><strong>Python</strong></p> <p>I got to do a lot more Python this year, mostly by shipping a couple of Django projects, both at work and home. Also dug deeper into Flask by building a static blog generator. Spent time on tooling by creating a capistrano'ish Fabric clone. Created a couple of smaller os-libraries. Attended DjangoCon in Stockholm.</p> <p><strong>Android</strong></p> <p>Spent most of my spare time, and during summer, work time, with Android. Got more into modularity and package handling through Gradle, finally threw out Eclipse and replaced it with Android Studio. Tried out a couple of libraries, those worth mentioning are: Volley, OkHttp and ButterKnife. Java comes pretty natual to me.</p> <p><strong>iOS</strong></p> <p>In opposit of Java, Objective-C does not come naturally to me at all, I put some of the blame on XCode. So I tried out AppCode from Intellji and liked it. Started to move away from storyboard based layouts towards building interfaces programmatically. Learned package handling with CocoaPods and improved my logging with Lumberjack.</p> <p><strong>JS</strong></p> <p>Started to play around with Angular on a couple of projects, switched AMD to CommonJS, through Browserify. Unexpectedly got into a full blown Node.js project at work based on Restify and MongoDB. Attended Nordic.js - which was awesome!</p> <p><strong>PHP</strong></p> <p>Literally business as usual, since I only use PHP at work. My most memorable work this year was setting up standards and putting together wordpress boilerplates.</p> <h2>Tools</h2> <p>Besides programming languages I did changes among my dev tools. Found a screen replacement in tmux and finally replaced janus with my own Vundle based Vim package.</p> <h2>Projects</h2> <p><strong><a href="http://muteparrot.com">MuteParrot</a></strong></p> <p>Spent a bit of the summer building this music discovery tool, it finds new music releases, rates them and makes them easy to access through streaming services. Lots of Django, BeautifulSoup and Angular.</p> <p><strong><a href="https://play.google.com/store/apps/details?id=se.madeinstockholm.abetterremote">For Boxee - A Better Remote</a></strong></p> <p>A easy to use Boxee remote for Android. You can read more about it <a href="http://marteinn.se/blog/for-boxee-a-better-remote/">here</a>.</p> <p><strong><a href="http://vinylwallapp.com">VinylWall</a></strong></p> <p>Spent the first half of 2014 providing VW with a steady stream of features, mostly related to social features, as well as a more minimalistic redesign.</p> <h2>Open Source</h2> <p><strong><a href="https://github.com/marteinn/AtomicPress">AtomicPress</a></strong></p> <p>Blog system built in Flask through Flask-Freeze with FTP and S3 publishing.</p> <p><strong><a href="https://github.com/marteinn/genres">Genres</a></strong></p> <p>Python library that digs through music reviews and attempts to find the genres discussed in review.</p> <p><strong><a href="https://github.com/marteinn/wpparser">Wpparser</a></strong></p> <p>Digs through wordpress exports file and returns a well formatted python dict.</p> <p><strong><a href="https://github.com/marteinn/Android-AppLog">Android-AppLog</a></strong></p> <p>A super simple Android logging tool that in short replaces <code>Log</code> and accepts a wide range of parameters (no more casting) and gives details about the whereabouts of the log statement.</p> <p><strong><a href="https://github.com/marteinn/Android-Config">Android-Config</a></strong></p> <p>Lets you load define and load settings by xml files through Androids raw cataloge.</p> <p><strong><a href="https://github.com/marteinn/Android-FontManager">Android-FontManager</a></strong></p> <p>Uses decorators to apply fonts through a dependecy injection manner. Does not support fragments yet.</p> <p><strong><a href="https://github.com/marteinn/Android-Features">Android-Features</a></strong></p> <p>Provides a way of enabling/disabling feature flags in Android.</p> <h2>2015</h2> <p>Finally, these are my goals for 2015.</p> <ol> <li>Try out React.js</li> <li>Build something in Swift</li> <li>Play with Docker</li> <li>More Linux - more systools.</li> <li>Continue on the Vim path.</li> <li>Better mobile dev TDD</li> <li>Read more programming books (starting with Test Driven Development with Python)</li> <li>Start to use twitter again</li> <li>Tinker with Ansible</li> <li>Ship ship ship!</li> </ol> Trying out Objective-Clean http://marteinn.se/blog/trying-out-objective-clean 2014-10-12T11:45:11Z 2014-10-12T11:45:11Z marteinn <p>A issue I have when it comes to Objective-C is consistency. With iOS I work in bursts, I can go from working 2-3 months daily with the platform, to not touching it for 5-6 months. With those routines you could end up with pretty inconsistent code. Since the language is using header files, has plenty of ways of writing code and with no clear style guide (like PEP8 for Python) I think things are already difficult to begin with.</p> <p>But I still though my code was pretty unified. Until I tried <a href="objclean.com">Objective-Clean</a>.</p> <p>Objective-Clean is a tool built by a third party developer (non Apple) that generates and makes sure style guides are followed. It is easy to set up and works with both latest XCode and CocoaPods.</p> <p>But it is not without flaws. Since the validation runs as a custom shell it can be a bit slow. I also noticed a couple of issues with the validation, these are the things I discovered:</p> <h3>Mistreated multiplication sign</h3> <p>My biggest problem is that the validator treats the multiplication sign wrong when used in a math context.</p> <p>Look at this line:</p> <pre><code>float imageArea = self.frame.size.width-(margin*2); </code></pre> <p>Looks fair right? Here the validator returns the error <code>bjClean: There should be a space before the *, but not after</code>. It is because it handles it as a method signature.</p> <p>You can see it when you rearrange the code a bit. This passes validation.</p> <pre><code>float imageArea = self.frame.size.width-(margin *2); </code></pre> <h3>Validation in comments</h3> <p>The validator treats comments as code, you can see this if you would type <code>// Do this + that</code> with no spaces between math operators as a setting. It is not a big issue, but I would prefer if comments was ignored altogether.</p> <h3>Pragma mark above row collides with method closing row.</h3> <p>This is also a big issue. Sometimes the validator ignores the setting where pragma mark requires num lines above in favor for num empty lines below method closing brace.</p> <pre><code>-(void) hello { [self sayHello]; } # pragma mark Delegate </code></pre> <p>This line complains that there needs to be 1 empty row below method closing brace, while at the same time I have a 2 empty rows above pragma mark.</p> <h2>Conclusion</h2> <p>With that said, I've already contacted Code Clean (who makes the app) and will update this post with my findings. Issues or not, consistensy is for the win. The $10 the app costs is well worth it and I've already made it a part of my Objective-C toolbelt.</p> <p>I've also posted my style guide <a href="https://gist.github.com/marteinn/32fed00d12e266313828">here</a>, for those who are interested.</p> Hello AtomicPress! http://marteinn.se/blog/hello-atomicpress 2014-10-05T20:10:44Z 2014-10-05T20:10:44Z marteinn <p>This project originated from last year when I started to experiment with Flask and Frozen-Flask to build a site generator. It was pretty cool how much you could do with a relative small codebase. (After all, Flask started as a joke[2]). I ended up building madeinstockholm.se using those libraries.</p> <p>Another opportunity came two weeks ago when someone hacked my Wordpress blog and I decided to build a replacement[1]. Using the static file approach was the obvious choice, since its pretty hard to hack... Once again hello Flask.</p> <p>Sure, I looked at the alternatives, Octopress, Jekyll, Pelican, Hyde (there are plenty out there), but they where heavy in features, I wanted something lighter and I like to code.</p> <p>So I built AtomicPress, a lightweight, for developers, static generator built to handle Wordpress exports well. I even based the db structure after Wordpress to make users porting from Wordpress more at home, and made sure building themes and extensions would be simple. This system also ships with the ability to deploy sites to both S3 and FTP.</p> <p>I will continue to make improvements where I see fit, with a rss feed as the next feature on the list. </p> <p>Sounds interesting? Take a look: <a href="https://github.com/marteinn/AtomicPress">AtomicPress on Github</a>. You can find a example implementation under <code>/examples</code> in the repro and installing is done through <code>pip install atomicpress</code>.</p> <p><em>References:</em></p> <ol> <li> <p>My fault, since it's hosted on a shared hosting account I started ten years ago.</p> </li> <li> <p>Reference: <a href="http://en.wikipedia.org/wiki/Flask_(web_framework)#History">http://en.wikipedia.org/wiki/Flask_(web_framework)#History</a></p> </li> </ol> <p><strong>(tl;dr: I build a flask based blog generator who handles Wordpress well. Take a <a href="https://github.com/marteinn/AtomicPress">look</a>).</strong></p> For Boxee - A Better Remote http://marteinn.se/blog/for-boxee-a-better-remote 2014-09-22T21:10:40Z 2014-09-22T21:10:40Z marteinn <img src="[uploads]logo-promo-150x150.png" alt="logo-promo" width="150" height="150" class="alignleft size-thumbnail wp-image-837" /> <p> I've been meaning to write about my boxee app for a while now, but hasn't gotten around to it until now. </p> <h3>Background</h3> <p> It all started when the remote for my Boxee device stopped working, I began to research and found out that it is not an uncommon issue, in fact it is propably the most common one. </p> <p> I went on Google Play and looked for replacement apps instead and tried a few ones out, but lets just say, they left me with a slight nausea (<a href="https://play.google.com/store/search?q=Boxee&c=apps&hl=en">have a look for yourself</a>). </p> <p> So I decided to write my own remote, after about two weeks of spare time work I managed to get something up and running. Something I would end up naming "A Better Remote - For Boxee". </p> <p> Under the hood it's a straightforward Android app that is optimized for 4.0 (ICS) with okhttp from square as the most prominent third part library. </p> <h3>The tricky parts.</h3> <p> <ol> <li>The keyboard. Getting the keyboard to display correctly was harder then it looks, by using a command called `getKeyboardText` a xml dump is retrived that contains keyboard visibility. That command is then used for pinging the device for visibility.</li> <li>Discovery. To find the actual device was tricky, by broadcasting on port 2563 with a hard coded shared key, challange and application we get the necessary details, achieved with DatagramSocket and DatagramPacket.</li> <li>Lag. One of the features of the app is the hold down to repeat button functionality, the problem is that since the Boxee sports a traditional web server (Apache?) to receive the commands they are sometime queued, which results in lag. I avoided some of the lag by acually slowing down the interval commands are sent.</li> </ol> </p> <h3>Release:</h3> <p> I went on to sell it on Google Play. I did not expect a lot of downloads, but it is performing better then expected, with a 4.6 rating and 82 purchases. </p> <p> So if you are looking for a Boxee remote replacement, please <a href="https://play.google.com/store/apps/details?id=se.madeinstockholm.abetterremote&hl=en">try it out</a>, let me know what you think! </p> Authorizing a Rdio application in Django http://marteinn.se/blog/authorizing-a-rdio-application-in-django 2014-08-16T17:16:52Z 2014-08-16T17:16:52Z marteinn authorize_rdio.py is a quick and easy Django command for authorizing a Rdio application with requests+requests oauth. [gist id=20d09e14c95672266fe0] Drop it in your apps management/commands, then run: python manage.py authorize_rdio KEY SECRET. (The official Rdio documentation was written for <a href="http://www.rdio.com/developers/docs/web-service/oauth/ref-signing-requests">oauth2</a>). AppLog on The Central Repository http://marteinn.se/blog/applog-on-the-central-repository 2014-06-14T14:25:57Z 2014-06-14T14:25:57Z marteinn Just wanted to say that I have taken the time and published my Android logger <a href="https://github.com/marteinn/Android-AppLog">AppLog</a> on <a href="http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22applog%22">The Central Repository</a>. <br /><br /> You can include it as a dependency like this in your build.gradle: [code] dependencies { compile 'se.marteinn.utils.logging:applog:2.1.2' } [/code] For anyone interested in publishing libraries to The Central Repository, I recommend reading <a href="http://gmariotti.blogspot.se/2013/09/publish-aar-file-to-maven-central-with.html">Publish an aar file to Maven Central with Gradle</a>. I also recommend using <a href="https://github.com/chrisbanes/gradle-mvn-push">gradle-mvn-push</a> for publishing. AppLog - A simpler Android Logger http://marteinn.se/blog/applog-a-simpiler-android-logger 2014-05-18T22:29:30Z 2014-05-18T22:29:30Z marteinn The Android logger has always annoyed me, it tends to do just the bare minimum, a message is printed but no details regarding method invoking the print and no formatting support. And all those TAGS. We basically end up with lots of repetitive code. <br /><br /> That's why I built AppLog, a simple and smarter logger for Android. It makes the TAGS optional, supports String.format and makes type handling easier. <br /><br /> AppLog is available on GitHub if you want to try it out. <a href="https://github.com/marteinn/Android-AppLog">https://github.com/marteinn/Android-AppLog</a> <br /><br /> Feedback and ideas are of course much appreciated. Ten Google Play tips/tricks http://marteinn.se/blog/ten-google-play-tipstricks 2014-05-17T10:08:24Z 2014-05-17T10:08:24Z marteinn I wrote a blog post with Google Play optimization tips for Android called <a href="http://www.frojd.se/blogg100/ten-google-play-tips-tricks-60-100">Ten Google Play tips/tricks</a> for the frojd.se blog. It touches mostly store listing and best practice dealing with comments and updates. Feedback is if course super welcome, just drop a comment below! I (Love) Discogs checksum and implementation example http://marteinn.se/blog/i-love-discogs-checksum-and-implementation-example 2014-05-11T22:54:03Z 2014-05-11T22:54:03Z marteinn The checksum for the fallback "I (Love) Discogs" discogs uses when image requests are faulty is <strong>c58c26d726f1a8e0f3436db79a8122a0</strong>. I also wrote a quick example on how you could check for it (in Python). [gist id=1541e41d60b45be37019] Tastypie: Reusing the resource serialization outside api http://marteinn.se/blog/tastypie-reusing-json-serialization-outside-api 2014-05-02T17:36:28Z 2014-05-02T17:36:28Z marteinn I needed to use Tastypies resource serialization outside the api context, so this is how you do it. [gist id=b4a88868f0366904de0d] Got any suggestions? <a href="https://gist.github.com/marteinn/b4a88868f0366904de0d">Fork it.</a> Summary of 2013 http://marteinn.se/blog/summary-of-2013 2014-01-05T19:19:43Z 2014-01-05T19:19:43Z marteinn <p>This is my first year in review post, it has been a crazy year so it is much needed.</p> <h3>Work</h3> <p> Lets start with work. In the end of 2012 I started working as a developer at Fröjd and a few months after I left the startup I co-founded in 2012 (things just didn't meet my expectations). </p> <h3>Programming</h3> <p> Flash<br /> I started my career as a Flash Developer and made my living on it for ten years, but projects started to shift in 2011 and 2013 was the first year where I didn't touch Flash at all (honestly I didn't touch Flash much in 2012 either). </p> <p> Objective-c<br /> After spending a few hackdays at work with Xcode I took the time and sat down, evenings and weekends, and really got into objective-c. Being an old Flash dev really helped to speed things up and it's easy to build custom components (I'm looking at you Android). Not my favorite platform but you can do amazing things. </p> <p> Android<br /> Picked up Android in late 2012 and continued to spend time with java and Android. The platform has matured a lot in the past year, compared to when I got started, trying to see if it was even possible to build a good looking app. </p> <p> Python<br /> Used Flask on a few projects, really liked it. Didn't spend as much time with Django compared to 2012. Still love it though. Amazing community. </p> <p> JS<br /> Got into require.js and amd loading. Played around with mustache. Got to do some heavier mvc stuff with Backbone. </p> <p> PHP<br /> Spent a lot of time with PHP at work. Tools are maturing, like composer and hhvm. WP-Cli for Wordpress is also nice. </p> <h3>Projects</h3> <p> <a href="http://madeinstockholm.se">MadeInStockholm</a><br /> After ending my previous startup endeavour I co-founded MadeInStockholm, a lean startup that I work with on my spare time, right now we manage three products: </p> <p> <a href="http://vinylwallapp.com">VinylWall</a><br /> Shipped originally in September 2012 for Android and has gotten so many updates since then, we also launched a iPhone app in the summer and a gamification system. It's just the beginning. </p> <p> <a href="http://silo.vinylwallapp.com">Silo</a><br /> A side project that has spun out from VinylWall needing better searchable data, it's a music data api built in Flask based on Solr. More stuff will happen here. </p> <p> <a href="http://www.russiandance.se">Russian Dance</a><br /> Brought back Russian Dance from the dead and gave it a well deserved App Engine platform update and tons of js fixes. </p> <h3>Open source</h3> <p> <em>Started to spend more time contributing to the os community, but so far only to my own repositories.</em> </p> <p> <a href="https://github.com/marteinn/Jetty-Solr-Fabric-Boilerplate">Jetty+Solr Fabric Boilerplate</a> Built a fabric boilerplate that lets you install and configure Solr+Jetty on a Ubuntu box. </p> <p> <a href="https://github.com/marteinn/Madeinstockholm.se---Website">Madeinstockholm.se---Website</a><br /> Used madeinstockholm.se as an example on how flask freeze works </p> <p> <a href="https://github.com/marteinn/dotfiles">My dotfiles</a><br /> Since I have two workstations now, I started to unify my settings and gather them in a repro. </p> <p> <em>Also took the chance to open source some of my old Birth frameworks.</em> </p> <p> <a href="https://github.com/marteinn/Rio">Rio</a><br /> A very lightweight component framework. </p> <p> <a href="https://github.com/marteinn/robotlegs-viewmachine">View Machine</a><br /> A RobotsLegs add on, inspired by Djangos route management. </p> <h3>2014</h3> <p> And finally, these are my goals for 2014. <ol> <li>Mobile. Play more with ios and android. </li> <li>JS: Play around with angular, tdd and browserify. </li> <li>More Django.</li> <li>Learn more git. There are so many inner workings I would like to get to know.</li> <li>VIM. So much to learn.</li> <li>Open source: contribute more.</li> <li>Play more with Linux and my raspberry pi.</li> <li>Attend more meetups.</li> <li>Convert this blog to Pelican...</li> <li>Ship ship ship!</li> </ol> </p> <p> Thats it for now! Follow me on <a href="http://twitter.com/marteinn_se">@marteinn_se</a> </p> VinylWall 2.0 http://marteinn.se/blog/vinylwall-2-0 2013-11-16T12:27:00Z 2013-11-16T12:27:00Z marteinn <img class="alignleft size-thumbnail wp-image-659" alt="VW_PlayStore" src="[img src="VW_PlayStore-150x150.png"]" width="150" height="150" /> We have been hard at work and it's finally time to say hello to VinylWall 2.0 for <a href="https://play.google.com/store/apps/details?id=net.vinylwall.app">Android</a> and <a href="https://itunes.apple.com/app/id635737755?mt=8">iOS</a>. <p> <strong>This version includes the following features:</strong> <ul> <li>A profile page that will give you a better overview of your collection.</li> <li>Badges: A achievement system that rewards collectors with badges depending on a combination of records, artists and record formats. You can find them under your profile page.</li> <li>Easier collecting through our very own <a href="http://silo.vinylwallapp.com" title="Silo">Silo</a> music api, that delivers more relevant searches. - Sorting: The iOS version shipped initially without sorting, it's added now.</li> </ul> <p> Got feedback? Ping us on <a href="http://twitter.com/vinylwallapp">@vinylwallapp</a> Fabric boilerplate for Jetty+Solr http://marteinn.se/blog/fabric-boilerplate-for-jettysolr 2013-11-02T18:45:59Z 2013-11-02T18:45:59Z marteinn <p> Interested in getting started with Solr+Flask? This is a boilerplate that I built that might get you off the ground. It's a fabric script that helps you to setup Java, Jetty and Solr on Ubuntu (tested on 12.04). It also creates and initializes a Solr core based on provided schema files. </p> <p> You can find it <a href="https://github.com/marteinn/Jetty-Solr-Fabric-Boilerplate">Jetty+Solr Fabric Boilerplate</a> </p> <p> PS: Got ideas or improvement tips? Talk to me on <a href="http://twitter.com/marteinn_se">@marteinn_se</a> </p> Case: Static site generation through flask+flask freeze http://marteinn.se/blog/case-static-site-generation-through-flaskflask-freeze 2013-06-08T16:28:13Z 2013-06-08T16:28:13Z marteinn <p> After releasing MadeInStockholm.se i thought to myself, this can be a good example on how you can generate a static site through Flask. So behold, <a href="https://github.com/marteinn/Madeinstockholm.se---Website">Madeinstockholm.se---Website</a> on GitHub. </p> <p> It features SQLAlchemy, Flask-Admin, S3 deployment (through Boto) and some Grunt, everything should be covered in the readme. I had tons of fun building this, so enjoy! </p> Android: Checking when ListView has reached the end. http://marteinn.se/blog/android-understanding-when-listview-has-reached-the-end 2013-06-02T19:54:12Z 2013-06-02T19:54:12Z marteinn This goes among the same lines as my InteractiveScrollView class for android, that fires a event when the scrolling has reached the end. This does exactly the same thing, but for ListView. [gist id=3757968] I actually wrote this a while back but forgot to put it up here. Anyways, if you have any comments/ideas. Fork it! Debugging Tastypie using Django Debug Toolbar http://marteinn.se/blog/debugging-tastypie-using-django-debug-toolbar 2013-06-02T14:35:23Z 2013-06-02T14:35:23Z marteinn I'm a big fan of Django Debug Toolbar and wanted to debug my Tastypie based api using just that, after some googling I found the following <a href="http://stackoverflow.com/a/14647943">implementation</a>. It's exactly what I needed, where api result are wrapped in html and therefore triggers the toolbar through middleware. Problem is that the solution is hardcoded. So I took a more flexible approach. [gist id=5693665] Got any suggestions? <a href="https://gist.github.com/marteinn/5693665">Fork it.</a> Hello VinylWall http://marteinn.se/blog/hello-vinylwall 2013-05-12T21:54:56Z 2013-05-12T21:54:56Z marteinn <img class="alignleft size-thumbnail wp-image-659" alt="VW_PlayStore" src="[img src="VW_PlayStore-150x150.png"]" width="150" height="150" /> <p> After a two rewrites and lots of weekend work i'm very happy to introduce <a href="https://itunes.apple.com/app/id635737755?mt=8">VinylWall for iOS</a>! </p> <h3>VinylWall?</h3> <p> VinylWall is a record tag service that we released last year. It acts as your collection database and basically makes sure you do not buy duplicates and find out the ones you are missing. </p> <p> We have also gone through vinylwall.net, changed the domain to <a href="http://vinylwallapp.com">vinylwallapp.com</a> and applied a well deserved makeover, I think it looks great. </p> <p> We shipped this app originally for android a few months back, and it is far from forgotten, the latest updates includes both a updated profile and lots of ux fixes. Take a look - <a href="https://play.google.com/store/apps/details?id=net.vinylwall.app">VinylWall at Google Play</a> </p> <p> And finally I'm also happy to announce my new venture <a href="http://madeinstockholm.se">Made In Stockholm</a>. It's basically us (me and my friend Mattias) releasing web projects that we build for the sake of building. </p> <p> <strong>Interested in how we built the ios app? </strong> Take a look at the <a href="http://www.marteinn.se/blog/wp-content/uploads/animation.gif">work-in-progress loop</a> I put together. I think it's quite enjoyable. </p> Replace home screen in Flask-Admin http://marteinn.se/blog/replace-home-screen-in-flask-admin 2013-05-09T09:37:38Z 2013-05-09T09:37:38Z marteinn Couldn't find any info on how to replace the default Home screen for <a href="https://github.com/mrjoes/flask-admin">Flask-Admin</a>, so this is how you do it. [gist id=5546293] Having trouble using authenticating with api using Basic Auth on Android? http://marteinn.se/blog/having-trouble-using-authenticating-with-api-using-basic-auth-on-android 2012-09-24T17:15:55Z 2012-09-24T17:15:55Z marteinn You might want to take a look at your Base64 encoding. Make sure you use <strong>Base64.NO_WRAP</strong>, not <strong>Base64.DEFAULT</strong>, as I did. What NO_WRAP does is to make sure the string stays on one line, DEFAULT however does not (which will make tons of web servers very unhappy). Working example: [code lang="java"] String basicAuth = Base64.encodeToString((username+":"+password).getBytes(), Base64.NO_WRAP); [/code] That is all. Thanks <a href="http://stackoverflow.com/questions/8172730/in-android-how-to-concatenate-base64-encoded-strings">Stackoverflow</a> API resource implementation of Tastypie apikey http://marteinn.se/blog/api-resource-implementation-of-tastypie-apikey 2012-09-08T15:46:45Z 2012-09-08T15:46:45Z marteinn Note: This solution is since Tastypie 0.9.13 dated, take a look at <a href="https://gist.github.com/mkubenka/5142319">mkubenka's solution</a> instead. I was developing a mobile app and wanted to take advantage of tastypies apikey authentication, and had a hard time finding a example implmenentation. So here it goes, a quick example of a api resource for apikey, using Basic Auth for authentication. [gist id=3675459] Request url looks something like this (bare in mind everything except /token/auth/ is matter of your settings). [code] http://localhost:8000/api/v1/token/auth/ [/code] The json response will look like this. [code lang="javascript"] { "key" : "128dhsabh2jbyhasd91uundsa1" } [/code] Got any ideas on improvement? <a href="https://gist.github.com/3675459">Fork it</a>. <del datetime="2012-09-15T12:46:10+00:00">Update: It seems like GitHub has for some reason set all my gist files to private mode. I will get to the bottom of this!</del> Having problem with Google Maps rendering grey boxes? http://marteinn.se/blog/having-problem-with-google-maps-rendering-grey-boxes 2012-05-23T15:04:32Z 2012-05-23T15:04:32Z marteinn Such as this one? <img src="http://marteinn.se/blog/wp-content/uploads/google-maps-example.png" /> If you are dealing with visibility on the map parent element (show/hide), the answer is to trigger a resize of the map element (after showing the parent element of course). [code lang="javascript"] $parentElement.show(); google.maps.event.trigger(myMap,"resize"); [/code] Simple as pie! (Thanks to <a href="http://stackoverflow.com/a/10136411">Stackoverflow</a>) Use subdomain with S3 and django-storages (using boto) http://marteinn.se/blog/use-subdomain-with-s3-and-django-storages-using-boto 2012-05-10T23:27:08Z 2012-05-10T23:27:08Z marteinn (I take for granted that everything else is installed and working properly) Put this in your settings.py. Now django-storages will use the bucket-name as url root. [code lang="python"] from boto.s3.connection import VHostCallingFormat AWS_S3_CALLING_FORMAT = VHostCallingFormat() [/code] Getting PIL to run on Ubuntu 11.04 in Virtualenv http://marteinn.se/blog/getting-pil-to-run-on-ubuntu-11-04-in-virtualenv 2012-04-29T17:14:29Z 2012-04-29T17:14:29Z marteinn There are tons of posts out there showing different solutions, but not always pointing out platforms or with/without virtualenv. This code snippet explains how I got PIL to run in Ubuntu 11.04 using Virtualenv on a EC2 instance, plain and simple. [code lang="bash"] # Install image libraries sudo apt-get install libjpeg-dev libjpeg62 libjpeg62-dev zlib1g-dev libfreetype6 libfreetype6-dev # Install pip sudo apt-get install python-pip # Install virtualenv sudo pip install virtualenv # Create virtual env virtualenv --no-site-packages myproject.com # Activate it source bin/activate # Run Pillow (a PIL drop-in replacement) pip install Pillow [/code] Credits: <a href="http://stackoverflow.com/a/7015085">Stackoverflow</a> Note to self: Ident authentication failed for user 'Ubuntu' http://marteinn.se/blog/note-to-self-ident-authentication-failed-for-user-ubuntu 2012-04-25T14:53:18Z 2012-04-25T14:53:18Z marteinn Having problem with authentication failed using postgresql and you know your .pgpass is correct? Try using -U to indicate user. Example: [code lang="bash"] pg_dump -U postgres db_name | gzip > /backup.gz [/code] Remove SVN - AppleScript droplet http://marteinn.se/blog/remove-svn-applescript-droplet 2011-07-04T18:57:15Z 2011-07-04T18:57:15Z marteinn Well, I know this type of droplet's has been written before, but I have not seen much code shared. So here's my take on it. Do like this. Just drop your folder, or folders if you like, onto the app and all the .svn folders will be cleaned. [code lang="applescript"] on open current_files repeat with current_file in current_files -- validate if the file as a folder if (current_file as string) ends with ":" then try set current_file_path to (POSIX path of the current_file as string) do shell script "find '" & current_file_path & "' -name '.svn' | xargs rm -Rf" end try end if end repeat end open [/code] I also added this as a gist under github. So please feel free to fork! <a href="https://gist.github.com/1063705">https://gist.github.com/1063705</a> Introducing AtomCart http://marteinn.se/blog/introducing-atomcart 2011-02-13T21:02:13Z 2011-02-13T21:02:13Z marteinn <p> I was actually supposed to release this project a couple of weeks ago, but work interfered (it always seems to do so). Anyhow here is AtomCart. AtomCart is basicly a very lightweight shopping cart in its purest form (hence the name), built in javascript as a jQuery plugin. It does nothing else except hold a very lightweight interface shopping cart, that supports adding/removing cart items and basic sum calculations. Dead simple and very easy to implement. </p> <p> AtomCart is hosted on Github, so you can find it here: <a href="https://github.com/marteinn/AtomCart">https://github.com/marteinn/AtomCart</a> </p> AS3Flobile: Altering the ScrollList dataProvider without forcing a scroll position reset. http://marteinn.se/blog/as3flobile-altering-the-scrolllist-dataprovider-without-forcing-a-scroll-position-reset 2010-10-25T02:44:34Z 2010-10-25T02:44:34Z marteinn I was working with the AS3Flobile component ScrollList (its a great <a href="http://custardbelly.com/blog/?p=173">framework</a> when doing mobile flash-development) and had the need to modify the dataProvider (I was making a continuous scroller), but everytime I changed the dataProvider the scroller would reset the scroll-position to x = 0, y = 0. After a little tinkering, I came up with a quick and dirty way to force the ScrollList to move to a position without a animation, and by doing so, making sure that the scroller starts at the same position as where we left off. <p> <em>Of course, if anyone has a better solution, just post a comment at the end of this post!</em> </p> <p> Here it goes. </p> <p> <strong>1. First we need to extend the BaseScrollViewportStrategy class. This could look something like this:</strong> </p> [code lang="actionscript3"] package se.marteinn.app.controls.viewport.context { import com.custardbelly.as3flobile.controls.viewport.context.BaseScrollViewportStrategy; import com.custardbelly.as3flobile.controls.viewport.context.IScrollViewportStrategy; import flash.geom.Point; public class CustomScrollViewportStrategy extends BaseScrollViewportStrategy implements IScrollViewportStrategy { public function moveToStaticPoint( point:Point ):void { _currentScrollPositionX = point.x; _currentScrollPositionY = point.y; _coordinate.x = _currentScrollPositionX; _coordinate.y = _currentScrollPositionY; } } } [/code] <p> <strong>2. Then we need to extend ScrollList and add this method: moveToStaticPoint and then override getDefaultScrollContext.</strong> </p> [code lang="actionscript3"] // This method sets a new scrolling position on both the ScollList itself and the strategy instance. public function moveToStaticPoint ( point:Point ) : void { var strategy:CustomScrollViewportStrategy; strategy = _scrollContext.strategy as CustomScrollViewportStrategy; _currentScrollPosition = point; strategy.moveToStaticPoint( point ); _listHolder.x = point.x; _listHolder.y = point.y; } // And this method makes sure that we implement the new strategy element. override protected function getDefaultScrollContext():IScrollViewportContext { return new ScrollViewportMouseContext( new CustomScrollViewportStrategy() ); } [/code] <strong>3. After that. You can use ScrollList like this.</strong> [code lang="actionscript3"] var scrollList:MyScrollList; // Dump the scrollPosition (clone() is important). We will use this position after the dataProvider has changed position = scrollList.scrollPosition.clone(); // Do your stuff. for instance alter the dataProvider of the scroll list // scrollList.dataProvider = updatedContent; // Finish it off by running the moveToStaticPoint method. The ScrollList will now be set at the same position as where we started. scrollList.moveToStaticPoint( position ); [/code] Finding your Google App Engine directory under OSX (with GoogleAppEngineLauncher installed) http://marteinn.se/blog/finding-your-google-app-engine-directory-under-osx-with-googleappenginelauncher-installed 2010-10-03T23:30:37Z 2010-10-03T23:30:37Z marteinn I stumbled upon this dilemma when I was trying to create a pydev google app engine project in the <a href="http://www.aptana.com/">AptanaStudio 3</a> edi, to complete the wizard I had to set my google app engine directory. <p> <img src="[img src="Skärmavbild-2010-10-04-kl.-00.15.39.png"]" /> </p> <p> After a bit of searching, I realized that the "google_appengine" directory was not placed in public on my harddrive, but hidden inside the GoogleAppEngineLauncher.app package (right klick on the application - choose show content). </p> <p> So, if you run GoogleAppEngineLauncher on your mac, the path to your google app engine root is this: <code>/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/</code> </p> Android: InteractiveScrollView http://marteinn.se/blog/interactivescrollview 2010-06-04T03:20:14Z 2010-06-04T03:20:14Z marteinn This post is a simple follow up to <a href="http://www.marteinn.se/blog/?p=485">Android: Understanding when ScrollView has reached the bottom</a> where I have created a small plug and play widget which notifies when scroll bottom has been reached through a listener. <p> It works like this: InteractiveScrollView inherits from ScrollView and overrides onScrollChanged to validate scroll position. If bottom has been reached, onBottomReachedListener triggers. </p> <strong>Usage:</strong> [code lang="java"] InteractiveScrollView scrollView; scrollView = (InteractiveScrollView) findViewById( R.id.scrollView); scrollView.setOnBottomReachedListener(new InteractiveScrollView.OnBottomReachedListener() { @Override public void onBottomReached() { // bottom reached } }); [/code] <p> You can find the gist <a href="https://gist.github.com/marteinn/9427072a">here</a>. </p> Android: Understanding when ScrollView has reached the bottom http://marteinn.se/blog/android-determinate-when-scrollview-has-reached-the-bottom 2010-05-12T23:15:54Z 2010-05-12T23:15:54Z marteinn This snippet is pretty mutch as the title says, an example in detecting when ScrollView has reached the bottom. In this sample I extend ScrollView and then overrides the onScrollChanged method (inherited from View). [code lang="java"] @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { // Grab the last child placed in the ScrollView, we need it to determinate the bottom position. View view = (View) getChildAt(getChildCount()-1); // Calculate the scrolldiff int diff = (view.getBottom()-(getHeight()+getScrollY())); // if diff is zero, then the bottom has been reached if( diff == 0 ) { // notify that we have reached the bottom Log.d(ScrollTest.LOG_TAG, "MyScrollView: Bottom has been reached" ); } super.onScrollChanged(l, t, oldl, oldt); } [/code] Cheers to <a href="http://www.mail-archive.com/android-developers@googlegroups.com/msg32372.html">this</a> thread for helping me getting the calculations right. <strong>Update:</strong> You can find a full implementation here: <a href="https://gist.github.com/marteinn/9427072">InteractiveScrollView.java</a> Patching NetStreamClient http://marteinn.se/blog/patching-netstreamclient 2010-02-14T11:55:41Z 2010-02-14T11:55:41Z marteinn I couple of days ago I noticed that my conceptual NetStreamClient was failing when connecting it towards a NetStream, the debugger threw errors regarding missing a Proxy implementation of getProperty. <p> The problem was when building the class I took for granted that NetStream referenced against the client object and invoked the callback function from the object when a callback took place. But the fact is that when you assign a client object to netstream it saves a reference to the callback function, not the client object itself. So it was clear why my class didnt work. </p> <p> So I patched it up with the proxy implementation getProperty (it looks a bit hackish but it does the trick). </p> [code lang="actionscript3"] flash_proxy override function getProperty(name:*) : * { var qName:QName = name as QName; return function ( ...args ) : void { flash_proxy::callProperty( qName, args[0] ); } } [/code] <p> I also noticed that in my usage example I used an object instead of the NetStreamClientEvent. So this is how you "really" use it. </p> [code lang="actionscript3"] // create a instance client = new NetStreamClient(); // assign the client netStream.client = client; // then just add listeners to the client client.addEventListener( NetStreamClientEvent.CUE_POINT, client_cuePointHandler ); // an example of the handler function function client_cuePointHandler ( event:NetStreamClientEvent ) : void { // the info object holds the original data var info:Object; info = event.arguments[0]; trace( [info.name, info.time, info.cuetype] ); } [/code] <p>View the class below:</p> [gist id=fd14e19543db118f3e71] Note to self: Connecting MySQL with Django using Mamp in OSX http://marteinn.se/blog/note-to-self-connecting-mysql-with-django-using-mamp-in-osx 2010-02-14T02:45:56Z 2010-02-14T02:45:56Z marteinn Having trouble connecting your MAMP mysql database wth django? Add the path DATABASE_HOST and connect it towards [code] {path to your MAMP directory}/tmp/mysql/mysql.sock [/code] So my connection is for instance [code] DATABASE_HOST = '/Applications/MAMP/tmp/mysql/mysql.sock' [/code] And the full mysql settings for for django [code] DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. DATABASE_NAME = 'mydb' # Or path to database file if using sqlite3. DATABASE_USER = 'root' # Not used with sqlite3. DATABASE_PASSWORD = 'root' # Not used with sqlite3. DATABASE_HOST = 'localhost' # Set to empty string for localhost. Not used with sqlite3. DATABASE_PORT = '8888' # Set to empty string for default. Not used with sqlite3. DATABASE_HOST = '/Applications/MAMP/tmp/mysql/mysql.sock' [/code] Its straightforward, but good to know, since adding the mysql.sock file in a folder named tmp seems a bit odd. A nicer way of using NetStream.client http://marteinn.se/blog/a-nicer-way-of-using-netstream-client 2010-01-11T22:20:23Z 2010-01-11T22:20:23Z marteinn <strong>* UPDATE: <a href="http://www.marteinn.se/blog/?p=474">This class has been patched </a></strong> <p> After working with the NetStream class for quite some time it has always striken me how badly the <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/net/NetStream.html#client">"client"</a> approach is. </p> <strong>Default behaviour</strong> [code lang="actionscript3"] netStream.client = {onCuePoint:myCuePointCallback}; function myCuePointCallback ( point:Object ) : void { } [/code] <p> Basicly to retrive a cue point we have to assign the client property with a object populated with a needed set of callback functions, that in the end will be triggered by the NetConnection class. You rarely see this callback mechanism in as3 and it can easly get a bit confusing, mainly beacuse you need to remember the callback function names. </p> <p> So I made a specific client class for NetStream which extends the Proxy util and converts the callbacks into actual events with EventDispatcher. It works like this. </p> <strong>Usage</strong> [code lang="actionscript3"] // create a instance client = new NetStreamClient(); // assign the client netStream.client = client; // then just add listeners to the client client.addEventListener( NetStreamClientEvent.CUE_POINT, client_cuePointHandler ); client.addEventListener( NetStreamClientEvent.META_DATA, client_metaDataHandler ); // an example of the handler function function client_cuePointHandler ( info:Object ) : void { trace( [info.name, info.time, info.cuetype] ); } [/code] <p> The NetStreamClient covers the most used callbacks (such as metadata, play status), and the callbacks it cannot identify gets labeled as a Unknown call. </p> Try it out and just shout if you have any comments! <a href="http://www.marteinn.se/code/as3/NetStreamClient/NetStreamClient.zip">Download it here here</a>, or <a href="http://www.marteinn.se/code/as3/NetStreamClient/NetStreamClient.as">view the NetStreamClient class here</a>. Dealing with the NetStatus info codes http://marteinn.se/blog/dealing-with-the-netstatus-info-codes 2009-11-16T23:56:10Z 2009-11-16T23:56:10Z marteinn <p> I never liked dealing with the NET_STATUS info codes that NetStream generates, beacuse I always forget the different codes. And there is no built in class which holds the string constant as representations for the different codes. So I basicly did a very simple wrapping of the status codes from the <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/NetStatusEvent.html#info">Adobe Reference</a> into a simple to use class. </p> <strong>Usage</strong> [code lang="actionscript3"] protected function netStream_netStatus ( event:NetStatusEvent ) : void { switch( event.info.code ) { case NetStatusConstants.NETSTREAM_PLAY_START: trace("Start!"); break; } } [/code] <p> So if you are like me, with a memory like a pacific sea turtle, this might come in handy. <a href="http://www.marteinn.se/code/as3/NetStatusConstants/NetStatusConstants.zip">Download it here here</a>, or <a href="http://www.marteinn.se/code/as3/NetStatusConstants/NetStatusConstants.as">view the class here</a>. </p> Bug in the sabreamf drupal module http://marteinn.se/blog/bug-in-the-sabreamf-drupal-module 2009-11-03T23:55:30Z 2009-11-03T23:55:30Z marteinn I stumbled upon this bug while trying out the excellent <a href="http://code.google.com/p/sabreamf/wiki/Drupal">sabreamf drupal module</a> (which enables flash remoting support for drupal). The problem was that all method calls witch required arguments just failed. So after some peeking under the hood I noticed that the method name was added as a parameter, together with the regular parameters in the service call, something that in the end caused the service fail. <p> To correct this error, simply remove the $method variable from the call arguments. </p> <p> Locate the file <strong>sabreamf.module</strong> in your sabreamf drupal module folder (not to be confused with the SabreAMF folder) </p> On line 66 replace this line of code... [code] return sabreamf_method_call($method, array($method, $arguments)); [/code] ...With this [code] return sabreamf_method_call($method, $arguments); [/code] All set! Note to self: Wordpress and uploading .flv files http://marteinn.se/blog/note-to-self-wordpress-and-uploading-flv-files 2009-10-21T14:47:18Z 2009-10-21T14:47:18Z marteinn It seems like the latest version of wordpress (2.8.5) does not allow the upload of .flv files. To fix that issue, do the following: <p> <ol> <li>Locate the file wp-includes/functions.php</li> <li>Locate the function "wp_check_filetype" (line 2228)</li> </ol> </p> Then finally add the. flv mimetype into the $mimes array [code] 'flv' => 'video/flv', [/code] Done! Note to self: settings.py and mysql.sock http://marteinn.se/blog/note-to-self-settings-py-and-mysql-sock 2009-10-15T07:06:25Z 2009-10-15T07:06:25Z marteinn If the path for your mysql.sock does not correspond to the default tmp/mysql.sock you will recive the following error in osx. [code] File "/Library/Python/2.5/site-packages/MySQL_python-1.2.2-py2.5-macosx-10.5-i386.egg/MySQLdb/connections.py", line 170, in __init__ _mysql_exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)") [/code] To correct this, find the real path for your mysql.sock (mine was var/mysql/mysql.sock) and then add the following param (under the mysql related params). [code] DATABASE_HOST = '/var/mysql/mysql.sock' [/code] That should do the trick! PureMVC hints and tips http://marteinn.se/blog/puremvc-hints-and-tips 2009-10-11T13:52:58Z 2009-10-11T13:52:58Z marteinn <p> PureMVC has been my framework of choice for the last 18 months, the beginning of our relationship was a bit rocky but after a while we got to know each outher. Now, looking back at atleast the ten bigger projects I have done since, I'd say we know one another well, so well that I have learned a bunch of new hints and tips. Something I thought I might aswell share on this blog. </p> <p> Im not only making this little article as a reflection of my past experiences, but also to mark a new start for me with my new framework of choice RobotLegs, and this felt like a good way to end things :) In time I might go back to using PureMVC, perhaps not. PureMVC is anyway a great framework and alot of fun, so I hope some of these puremvc tips comes in handy! </p> <h3>1. Dare to use Proxies</h3> <p> The hardest part for me was to use Proxies. In the beginning I often ended up using a mediator when I could have used a proxy instead. Take a look at these examples. </p> <p> SizeProxy = This Proxy listens for stage resize events and sends out resize notifications all through the application. In the past I embedded this functionality into a mediator called ApplicationMediator. </p> <p> AddressProxy = This Proxy takes care of all state management related data, and do everything from setting, retriving, formatting and finally sending out notifications. In the past I had this functionality into a mediator aswell. (Shame on me!) </p> <h3>2. Keeping track of your proxies and mediators</h3> <p> Avoid always re-typing string representations when dealing with proxies and mediators. Add a static constant variable named NAME in your classes and refer to that variable any time you need to access the proxy/mediator. Like this. </p> The class [code lang="actionscript3"] package se.marteinn.puremvc.single.view { import org.puremvc.as3.interfaces.IMediator; import org.puremvc.as3.patterns.mediator.Mediator; public class ApplicationMediator extends Mediator implements IMediator { public static const NAME:String = "applicationMediator"; } } [/code] Registrating the mediator [code lang="actionscript3"]this.facade.registerMediator( new ApplicationMediator( ApplicationMediator.NAME, application ) );[/code] Retriving the mediator [code lang="actionscript3"]this.facade.retriveMediator( ApplicationMediator.NAME ) as ApplicationMediator[/code] <p> Aww, you get the idea! </p> <h3>3. Dont forget your OOP</h3> <p> Remember that Mediators are still classes that you can extend. So dont be afraid to make your own “abstract” classes. </p> Like this [code lang="actionscript3"]package se.marteinn.puremvc.single.view.states { import org.puremvc.as3.interfaces.IMediator; import org.puremvc.as3.patterns.mediator.Mediator; public class StateMediator extends Mediator implements IMediator { public function StateMediator(mediatorName:String=null, viewComponent:Object=null) { super(mediatorName, viewComponent); } public function singJohnnyCash () { trace( “Ring of fire” ); } } } [/code] And then extending it. [code lang="actionscript3"]package se.marteinn.puremvc.single.view.states { import se.marteinn.puremvc.single.view.states.StateMediator; import org.puremvc.as3.interfaces.IMediator; public class PageStateMediator extends StateMediator implements IMediator { public function PageStateMediator(mediatorName:String=null, viewComponent:Object=null) { super(mediatorName, viewComponent); singJohnnyCash(); } } }[/code] <h3>4a. Be nice to the commands</h3> <p> Keep them as clear and as re-usable as possible. Try not to manipulate mediators directly in the command, use notifications instead. (Since its all ok for a mediator to retrive notifications). </p> <p> <h3>4b. But use a command whenever you can</h3> Commands makes your application easier to understand and to work with, so use commands whenever it feels right. </p> <h3>5. Organizing notifications</h3> <p> Placing all notifications into one class (placed in the application root) helps keeping track of things. </p> [code lang="actionscript3"]package se.marteinn.puremvc.single { public class ApplicationNotifications { public static const STARTUP:String = "startup"; // preload related public static const INIT_PRELOAD:String = "initPreload"; public static const START_PRELOAD:String = "startPreload"; public static const LOAD_CONFIG:String = "loadConfig"; public static const CONFIG_LOADED:String = "configLoaded"; // yada yada.. } } [/code] And its easy to access [code lang="actionscript3"]sendNotification( ApplicationNotifications. STARTUP );[/code] <h3>6. Organizing parameters</h3> <p> To place values the application needs to actually work, such as api keys and values you dont want to store in a external config file, into its own class is a good idea. </p> [code lang="actionscript3"]package se.marteinn.puremvc.single { public class ApplicationParameters { public static const GOOGLE_MAPS_API_KEY:String = "asd234234dssdf"; } }[/code] <p> And its easy to access [code lang="actionscript3"]loadStuff( ApplicationParameters. GOOGLE_MAPS_API_KEY );[/code] </p> <h3>7. Use onRegister whenever you can on your proxies and mediators</h3> <p> My advice is not to place construction code into the constructor of proxies/methods, instead override the onRegister method and place your code there. It makes you code easier to read and give you less bugs in the future (when porting a app to multicore). Read more here <a href="http://lowpitch.com/blog/puremvc-multicore-vs-standard-singlecore/">http://lowpitch.com/blog/puremvc-multicore-vs-standard-singlecore/</a> </p> <h3>8. The namespace</h3> <p> So, how should a PureMVC namespace be organized? Well, a namespace can be organized in many forms, this is my way in doing it. </p> [code lang="actionscript3"]se.marteinn.project controller vo (My controller specific VO:s here) (My commands here) model vo (My model specific VO:s here) services (My model specific services here) (My proxies here) view components (View related components here) (My mediators here) ApplicationFacade ApplicationNotifications ApplicationParams [/code] It could also look like this: [code lang="actionscript3"]se.marteinn.project controller vo (My controller specific VO:s here) commands (My commands here) model vo (My model specific VO:s here) services (My model specific services here) proxies (My proxies here) view components (View related components here) mediators (My mediators here) ApplicationFacade ApplicationNotifications ApplicationParams [/code] <h3>9. Adding a interface to the application main class</h3> <p> To make things as flexible as possible and to simplify when installing my puremvc base into a new application, I have a interface called IApplication, where the main Application implements IApplication. That way: </p> The application class can be named whatever, as long its implementing IApplication... [code lang="actionscript3"] package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import se.marteinn.puremvc.single.IApplication; [SWF(frameRate="31", backgroundColor="#000000")] public class TestApp extends Sprite implements IApplication { protected function draw () : void { ApplicationFacade.getInstance().startup( this ); } } } [/code] ...the facade will be fine with it [code lang="actionscript3"]package se.birth.puremvc.single { import org.puremvc.as3.interfaces.IFacade; import org.puremvc.as3.patterns.facade.Facade; import se.marteinn.puremvc.single.controller.StartupCommand; public class ApplicationFacade extends Facade implements IFacade { protected static var instance:ApplicationFacade; public static function getInstance () : ApplicationFacade { if( instance == null ) instance = new ApplicationFacade (); return instance; } override protected function initializeController():void { super.initializeController(); this.registerCommand( ApplicationNotifications.STARTUP, StartupCommand ); } public function startup ( application:IApplication ) : void { this.sendNotification( ApplicationNotifications.STARTUP, application ); } } } [/code] <h3>Read more</h3> <p> If you are looking for more advice and thoughts on how to build better PureMVC applications, look at these links: </p> <p> 10 tips for working with PureMVC by Jens Krause <a href="http://www.flex-labs.de/blog/2008/10/10-tips-for-working-with-puremvc-by-jens-krause/">http://www.flex-labs.de/blog/2008/10/10-tips-for-working-with-puremvc-by-jens-krause/</a> </p> <p> Building a Flash site using PureMVC <a href="http://hubflanger.com/building-a-flash-site-using-puremvc/">http://hubflanger.com/building-a-flash-site-using-puremvc/</a> </p> <p> My own PureMVC collection of links (both Singlecore and Multicore) <a href="http://delicious.com/marteinn/puremvc">http://delicious.com/marteinn/puremvc</a> </p> <p> Last but not least, the PureMVC.org website with the all mighty guru of know it all Cliff Hall <a href="http://www.puremvc.org/">http://www.puremvc.org/</a> </p> Cheers! Note to self: Robotlegs and injections http://marteinn.se/blog/note-to-self-robotlegs 2009-10-11T10:51:07Z 2009-10-11T10:51:07Z marteinn When injecting a instance (or whatever) in robotLegs be sure to spell inject with a capital "I". <p> <strong>Bad</strong> </p> [code][inject] public var pageOnFrontProxy:PageOnFrontProxy;[/code] <p> <strong>Good</strong> </p> [code][<strong>I</strong>nject] public var pageOnFrontProxy:PageOnFrontProxy;[/code] Vacation over and eleven more months... http://marteinn.se/blog/vacation-over-and-eleven-more-months 2009-08-01T04:10:57Z 2009-08-01T04:10:57Z marteinn ..of work! Yes, after a month of well deserved vacation I am back on the force again, and I though the best way to get started is to list a few intresting links I stumbled upon the last month. <p> <strong>This is a very fancy as3 plugin, written by Simon Gregory, for textmate. Great work Simon!</strong> <a href="http://blog.simongregory.com/09/as3-autocompletion-in-textmate/">http://blog.simongregory.com/09/as3-autocompletion-in-textmate/</a> </p> <p> <strong>The best explanation I have seen regarding the puremvc multicore version. Busdriver: move that cheese!</strong> <a href="http://www.as3dp.com/2009/07/22/a-non-flex-actionscript-example-of-a-puremvc-multicore-application/">http://www.as3dp.com/2009/07/22/a-non-flex-actionscript-example-of-a-puremvc-multicore-application/</a> </p> <p> <strong>A must have collection of OSX commands. I stole this tip right of Jankees delicious (<a href="http://delicious.com/jankeesvw/">http://delicious.com/jankeesvw/</a>)</strong> <a href="http://ss64.com/osx/">http://ss64.com/osx/</a> </p> <p> <strong>A nice and breif list of various php frameworks. (Although, I am, for the time beeing sticking to my beloved Codeigniter)</strong> <a href="http://www.noupe.com/php/discussing-php-frameworks.html">http://www.noupe.com/php/discussing-php-frameworks.html</a> </p> <p> <strong>I'm for certain not Joomlas biggest fan, but this extension looks pretty fun for insane people like me who just loves to connect flash to various cms-systems. </strong><a href="http://extensions.joomla.org/extensions/miscellaneous/development/4820/details">http://extensions.joomla.org/extensions/miscellaneous/development/4820/details</a> <a href="http://figo.tandolin.co.za/adobe-air/how-to-use-jamfphp-for-joomla-remoting.htm">http://figo.tandolin.co.za/adobe-air/how-to-use-jamfphp-for-joomla-remoting.htm</a> </p> <p> <strong>Another "actionscript efficency" must read slides, from http://lostinactionscript.com/ </strong> <a href="http://docs.google.com/present/view?id=d4jrvds_0hjb794hr">http://docs.google.com/present/view?id=d4jrvds_0hjb794hr</a> </p> <p> <strong>Tips in how the secure Wordpress (I think this link was digged?)</strong> <a href="http://sixrevisions.com/wordpress/12-essential-security-tips-and-hacks-for-wordpress/">http://sixrevisions.com/wordpress/12-essential-security-tips-and-hacks-for-wordpress/</a> </p> <p> <strong>Another article that has been digged earlier. With breif comments of various php based cms systems.</strong> <a href="http://www.webdesignbooth.com/20-promising-open-source-php-content-management-systemscms/">http://www.webdesignbooth.com/20-promising-open-source-php-content-management-systemscms/</a> </p> <p> <strong>At the end of my vacation, I occupied myself with extending <a href="http://www.magentocommerce.com/">Magento</a> (My goal is to have a fully working API against flash). Anyhow, these links got my started when extending the API with custom methods</strong> <a href="http://100101.kurodust.net/2008/10/22/writing-a-magento-custom-api-call/">http://100101.kurodust.net/2008/10/22/writing-a-magento-custom-api-call/</a> <a href="http://www.magentocommerce.com/boards/viewthread/43818/">http://www.magentocommerce.com/boards/viewthread/43818/</a> </p> Thats it for now, and all these links, including several others, can be found on my <a href="http://delicious.com/marteinn">delicious</a>. Cheers! Note to self: Magento Custom API and method names http://marteinn.se/blog/note-to-self-magento-custom-api-and-method-names 2009-07-31T07:23:34Z 2009-07-31T07:23:34Z marteinn <p> Not to self: When wanting to use a PHP preserved keyword as a api method (sutch as "list"), use the <strong>&lt;method>methodName&lt;/method></strong> tag in api.xml </p> <p> Like this: <code>&lt;list translate="title" module="sales"> &lt;title>Retrieve list of orders by filters&lt;/title> </p> <p> <strong>&lt;method>items&lt;/method></strong> &lt;acl>sales/order/info&lt;/acl> &lt;/list> </code> </p> Feature request: Variables in the Flash CS export http://marteinn.se/blog/feauture-request-variables-in-flash-cs-export 2009-05-24T14:07:24Z 2009-05-24T14:07:24Z marteinn <p> I do not work very often with Flash CS these days, but those occations when I do I mostly use it for creating and deploying banners. Often its more than one banner that needs to be done, in different formats and sizes, and in almost all cases you create one original file that you later use as a base when doing the different sizes. </p> <p> This little feature would help speeding up the process a little (so you do not have to alter the export .swf name settings everytime you create a new base banner from a original). The variable width/height would represent the .fla width/height. </p> <p> This feature would help you keeping track of your banners, and will shrink the amount of errors in your deliveries, less "wrong size" named files (all you people in the banner factory knows what I am talking about!). </p> <p> Adobe, can I have it, please? :) </p> <img class="alignnone size-full wp-image-333" title="bild-40" src="[img src="bild-40.png"]" alt="bild-40" width="500" height="167" /> Note to myself http://marteinn.se/blog/note-to-myself 2009-02-20T15:10:33Z 2009-02-20T15:10:33Z marteinn <p> In MySQL, the functions CURDATE() and NOW() is <strong>not</strong> the same thing. CURDATE() does not return the current time (hours, minutes, seconds), witch NOW() does. </p> <p> Additional info here at gizmola. <a href="http://www.gizmola.com/blog/archives/51-Exploring-Mysql-CURDATE-and-NOW.-The-same-but-different..html">http://www.gizmola.com/blog/archives/51-Exploring-Mysql-CURDATE-and-NOW.-The-same-but-different..html</a> </p> I have to thank myself for 1 hour of pretty unnecessary debugging! :) #tweetcoding: 01 - First try http://marteinn.se/blog/tweetcoding-01-first-try 2009-02-19T09:46:49Z 2009-02-19T09:46:49Z marteinn <p> This is my first attempt on the tweetcoding contest held by grant skinner... and I do have to say thats its very funny indeed :) </p> <p> Note that this example does not fully use object 'o' for persistant data, yet. And to save place I also had to shortcut Math.cos (but hey, evertyhing is till in the <del datetime="2009-02-19T08:42:08+00:00">140</del> char span, sorry <strong>139</strong> chars) </p> [code] if(!i)o.h=50+r()*50,g.clear(),v=.2,c=m.cos;//43 chars ls(1,0,.4+c(i*v)*.6);//21 chars (!i?mt:lt)(m.sin(i*v)*(i*v*.2),c(i*v)*o.h-i*.1+o.h);//52 chars (i&gt;o.h*.2*100)?i=0:i++;//23 chars [/code] Compiled entry <a href="http://www.marteinn.se/blog-stuff/tweetcode-01/Tweet1.html">here</a>. <p> More about the competition <a href="http://gskinner.com/playpen/tweetcoding.html">here</a>. </p> If time allow, its possible that I will attempt to do a few variations before the final submit.