Category Archives: Development

Bulk upload to WordPress

Hi everyone,

Got some exciting news! I just got my very first application uploaded and approved on the Apple App store! I’ve been wanting to do something for quite some time but just haven’t been able to figure what I actually want to do.

But, for some time I have been using WordPress to keep track of my daily tasks, projects and general goals as well as using it to post whatever I do in terms of IT and Development. I keep track of a lot of photos on my phone that goes up to WordPress and I always thought the interface from the Phone was clunky. Logging in, Go to Media Library, Adding photos with the extra JS that took place on the phone just didn’t work for me. On top of that all the images were uploaded with a weird rotation.

I figured that this would be nice to have, a small app does nothing but that. I knew WordPress had XMLRPC for managing library (see Annoyed with WordPress) so it shouldn’t be too hard. That being said. I now have my own application uploaded to the app store that does just that.

I used Xamarin as a development platform. I’ve been a fan of Xamarin since it was still monotouch (let’s be honest. Obj-C is no fun).

 

Full page features:

Bulk Upload for WordPress

Some roadmap things

I know there’s more work to be done but the application does what it’s supposed to. Anyways, some things that’ll happen soon:

  • Improve the upload status with images and success/failure messages
  • Multi-site support
  • Use camera to upload (is this even useful?)
  • A nicer looking icon (current one is garbage)
  • More modern iOS design?
  • Share photos into the app from photo library.

Allowing digest auth with CORS on Chrome and LIGHTTPD

LigHTTPD is a very popular web server to use nowadays and it powers a lot of devices. I’ve mainly seen it in rasberry pi’s and other smaller servers but it’s powerful nonetheless.

Today I did some fiddling around with CORS to get data passed through another domain than the site was residing on. It all seemed fairly easy as it’s just a simple header to add to your server response, as described on enable cors

Turned out it wasn’t that easy. The server with the APIs are armed with Digest authentication for authorization and chrome has made it a must to send HTTP OPTIONS to check some parameters from the server.

Chrome needs in order to authenticate:

  • Access-Control-Allow-Origin: *
  • Access-Control-Expose-Headers: WWW-Authenticate
  • Access-Control-Allow-Headers: Authorization
  • Access-Control-Allow-Methods: POST, GET, OPTIONS

That’s easy enough with LigHTTPDs extra environment header in the server configuration:

setenv.add-response-header = (
"Access-Control-Allow-Origin" => "*",
"Access-Control-Expose-Headers" => "WWW-Authenticate",
"Access-Control-Allow-Headers" => "Authorization",
"Access-Control-Allow-Methods" => "POST, GET, OPTIONS"

)

But, that isn’t enough. If you have set up a rule in your server configuration that you require to authenticate, Chrome will fail when it gets 401 on it’s OPTION request and will not continue. In order to get that worked around I had to do some modifications in mod_auth to make sure it doesn’t authenticate on HTTP OPTIONS. It was an easy hack to implement once you figured out the functions and where to look.

All the needed code was:

//Hack to make OPTIONS pass through AUTH filter with just sending the headers needed by CORS on Chrome
const char *htm = get_http_method_name(con->request.http_method);
if(strcmp(htm,"OPTIONS") == 0){
con->http_status = 200;
con->mode = DIRECT;
return HANDLER_FINISHED;
}

I’ve attached the modified .c file for some convenience. I used the latest (to date) official release 1.4.39. Hope this helps anyone out there who needs to use digest over CORS with LigHTTPD.

mod_auth

/Marcus

Running Python on Axis devices

Axis’ platform for running applications on the camera itself is really great. For you who haven’t seen ACAP share I really suggest you click yourself over there to see what it’s all about.

As mentioned in other posts, Axis have created an embedded platform where you can install applications on the different devices to add features to the edge. This can be analytics that is looking for something unique like a people counter or advanced cross line-type detection. It can also be for simpler tasks like sending a message using a service platform similar to the pushbullet integration that I published here some time ago.

The only downside is that to develop these applications you have to know C which can be tough for the average script kiddie who just wants to perform something small. So, in order to solve some of the more simple scripting that you can be interested in doing. On ACAP Share there’s a PHP application that allows someone to write a PHP script that can be executed on a camera. This is a great application if you’re looking to use smaller APIs for your task.

PHP is extremely popular and allows you to do a number of great things. Python is another extremely popular language. Soo.. Enough said, below is the compiled ACAP and how to build it if you have the environment.

Build script:

buildpython

The python binary itself:

Python_2.7.1_1_0_mipsisa32r2el

Recommended FW: 5.80+. The reason is that the package is pretty big and will need some space. We’ve seen problems with 5.60 and 5.70 firmware that doesn’t allow the package to go through due to it’s size. After 5.80 it seems fine though. (Yes, python is a big library)

It’s build to run on the MIPS architecture, meaning it will work on ARTPEC-4 and ARTPEC-5 devices but that’s it. Python version is 2.7.1 with some limitation built to it (see buildpython.sh)

When you upload the binary there’s an attached python script in that folder. Edit that and make sure you run a continuous loop on it to perform whatever you want to achieve.

ACAP is actually so powerful that you can create your own applications that are essentially script that runs off another application. To start a python script from the command line, use:

LD_LIBRARY_PATH=/usr/local/packages/python_2_7_1/lib /usr/local/packages/python_2_7_1/bin/python /path/to/script.py

This can be called from system(); as well in your C application.

Hopefully this can save some time for people who’re interested in developing in python on Axis devices.

/Marcus

Server Report Grabber

Axis Communications offer a great SDK for all their application development partners that allows anyone to create applications that runs on the cameras.

The SDK itself comes with a set of libraries and compilers for the different chipsets in the Axis devices that let you:

  • Capture frames from the devices
  • Control device parameters
  • Create web pages/CGIs
  • Create event triggers
  • License key management (if you considered commercial use)

Axis also created the RAPP (Rasterizing Processing Primitives library) that allow the developer to do low level processing image operations. It’s licensed under GPL v3.

All Axis devices runs Linux as the operating system, so it’s really up to you what you want to do in the operating system and there’s really no limit what you can do. The main language to develop the applications in is C but C++ is supported as well.

I had a task where i had to monitor changes that was being made on the camera over time and Axis already have a great feature to get information about the whole system that can be grabbed from their APIs, this is called the “Server report”. So what I came up with is an application that grabs a Server report of the camera and saves it to the preferred location. The default is the SD card slot in the camera but any directory or even mounted network devices can be used. It’s not a fancy app that does all this kinds of analytics. But it’s working as expected.

Download

Axis Parameter Class for Python

A couple of days ago I was in need of making some scripts that removed duplicate parameter groups on a couple of Axis devices. For those of you who don’t know, Axis creates Digital Surveillance Cameras with IP technology, which in practice means that It’s surveillance cameras running Linux.

All Axis devices offers an open API for developers who want to develop  that uses Axis devices. The most frequent API used is the Parameter API, that allows to change basic settings, create motion detection windows, events with triggers and so on. And this is the API that I had to implement a class for.

The class is written in Python and is pretty much an object oriented interface. Example

param1 = AxisParameter("Motion.M0.Left","1120")
#param1.name = Motion.M0.Left, param1.value = "1120"
param2 = AxisParameter("Properties.Resolution")
#param2.name = Properties.Resolution, param2.value = None

Here we have two parameters that can be accessed from the class. param1 contains a parameter with an assigned value to it, this can be used to modify an already existing parameter. param2 contains a parameter name, but have no idea of the value of it, better used to receive the parameters

To use the class, you must first import the data from it.

from AxisParameterClass import * #import both the working class and the information class

paramclass = AxisParameterClass("some.ip","username","password","vapixversion")

All arguments are optional and can be set later with the following functions

  • setIP
  • setCredentials
  • setVapixVersion

Axis currently have two API’s for handling vapix parameters. The only big difference is the URL, but still. The class will automatically try to determine the vapix version if not set before.

Receive parameters

To get parameters from a device, simply create a parameter that you’re interesting, both groups and subgroups are fine to use:

paramclass.getParameters([AxisParameter('Motion'), AxisParameter('Properties'), AxisParameter('NonExistent')])

The class will return a list of all parameters that matches the search. Is a parameter not found, the Parameter will be returned with the value None. All parameters that are found have their value as a string.

Remove parameters

Just as add. Create your list, and send to

paramclass.removeParameters([AxisParameter('Motion')])

Parameters returned have a status parameter that refers if the parameter was removed or not:

AxisParameter.status = "OK" #removed
AxisParameter.status = "Error" #not removed.

Update Parameters (Implementation still needs some work)

To update, pass the list into

paramclass.updateParameters([AxisParameter('Motion.M0.Left','1123')] )

If all works, the parameters returned will contain the same result as what you passed in.

 

Download

It can all be downloaded from github, licensed under MIT, so feel free to do whatever you like with it 🙂
https://github.com/marcusfollrud/AxisParameterPython 

Annoyed with WordPress

Yesterday I was faced with a problem from a friend who has a wordpress blog hosted at wordpress.com. The problem was that the 3GB space on the blog was filled up with the images to his blog posts. The reason that it was already used was due to the fact of that the images were uploaded with their original size, which are of course with todays cameras kind of big.

Got me thinking. WordPress already offers the functionality of scaling images in the Media Library, but doing that one by one is very time consumin, and to be frank, it’s extremely boring :-) , this took me onto google to see if there’s any xmlrpc api function (since WordPress supports this) that would let me do so. No, but I can upload images using wp.uploadFile, and it seems to support overwriting. Great!

Or was it? No. Firstly, the overwrite functionality doesn’t overwrite the particular image you’re interest in overwriting. It creates a new one, and removes the old one not even the name in the database is the same, all of a sudden it includes some sort of reference name to the old file, that you’re obviously interested in.

Piece of code:

if ( !empty($data['overwrite']) && ($data['overwrite'] == true) ) {
			// Get postmeta info on the object.
			$old_file = $wpdb->get_row("
				SELECT ID
				FROM {$wpdb->posts}
				WHERE post_title = '{$name}'
					AND post_type = 'attachment'
			");

			// Delete previous file.
			wp_delete_attachment($old_file->ID);

			// Make sure the new name is different by pre-pending the
			// previous post id.
			$filename = preg_replace('/^wpid\d+-/', '', $name);
			$name = "wpid{$old_file->ID}-{$filename}";
		}

As can be seen here when overwriting, we look up the old image (based on the parameter $name) and deletes the file from the upload directory, but take a look at the next couple of lines. WordPress choses to create a new table row in `posts` with the old filename based on the old id and then adds a new filename.

For me, and everybody else who just wanted to replace/edit their image without  a huge hassle all of a sudden got a lot more work to do. Instead of having the same url to the image there’s a new one, if folder were used for adding images to posts (etc: /wp-content/uploads/2011/09) which results in that we have to edit all the posts who directly link to the image and not just a media library entry.

Why didn’t WP just replace that particular file in the system, as we actually were interested in overwriting it. Ah well, editing the posts shouldn’t be too much of a big mess right? Nah, editing a post isn’t hard at all. Download all the posts with getPages and just replace the old url with the new one for the images (even if a post from 2010 will have image links to 2012, not very stylish)

Oh, and another thing i noticed. When using wp.uploadFile the $name parameter must add a file type prefix, such as ”.jpg”, or it won’t be uploaded. This is not a big problem, unless you wanted to overwrite an image that was uploaded from the web GUI where your description ended up being ”Hello donkey kong” without an file type prefix. That file won’t be able to be overwritten (replaced) by another image.

So basically, I can’t achieve what I want, and it really annoys me.

Of course, the best way of achieving this is to just use  an FTP server, download the images from their folders, scale them with imagemagick or any good piece of software out there and just upload them again. But wordpress.com doens’t support FTP:ing, which I’m totally fine with, and totally understand.

Ok. WordPress is the greatest blog platform out there, so far I’ve never had any hassle myself as I have complete access to the system, but if don’t have that, It lacks some features that I’d like to have :(

I could just write a plugin that does this, but as I cannot upload plugins to wp.com that approach also fails. I’m locked out of doing my scaling on the images, unless I want to be a script kiddie and use the AJAX interface with Wireshark traces and somewhat reverse engineering but this isn’t the right way of doing things.

I think I’ll just sit down, add a feature to scale images on class-wp-xmlrpc-server.php and if I’m lucky, it’ll end up on the official release for wordpress.org, and it might work on wordpress.com as well one day, at least that’s what I’m hoping for, so that all the rest of you guys can get your used space down a little bit!

/marcus

dopingkollen.se

Hej VĂ€nner!

För nĂ„gra dagar sedan hade jag och nĂ„gra vĂ€nner en diskussion kring kosttillskott och “misstagsdoping”. Finns misstagsdoping egentligen? Behöver man kosttillskott? FrĂ„gorna var mĂ„nga och vi hade vĂ€l ungefĂ€r lika mĂ„nga svar. Men samtidigt som jag var mitt uppe i diskussionen pĂ„gick dĂ€r parallellt en hĂ€rlig problemlösning i bakhuvudet som bara kommer fram vid programmeringstillfĂ€lle. Hur skulle det vara ifall man hade en databas som hade koll pĂ„ vilka produkter som var stĂ€mplade som dopingklassade?Med innehĂ„llsförteckning, lĂ€nkar mot nyheter osv osv?

Av att döma utav Riksidrottsförbundets lista pÄ medel som inte Àr tillÄtna blir man lÀtt blind, och t.om ger upp. DÀr finns helt enkelt inget bra sÀtt att se ifall ett kosttillskott Àr dopingklassat eller inte.

Samma dag som diskussionen satte igÄng var jag fullt igÄng med att göra nÄgot av det. Tekniskt intresserad som jag Àr lade jag nog mest tyngd pÄ vilka komponenter jag skulle anvÀnda. Valen blev följande:

DooPHP blev valt av den anledningen att det Àr vÀldigt komplett, men ÀndÄ förvÄnansvÀrt snabbt och enkelt att anvÀnda.
jQuery för enkelheten med JavaScript och dynamiska webbsidor.
mySQL var lika enkelt att vÀlja, jag behöver bara en enkel tabell med korsreferenser. sqlite hade sÀkert funkat, men DooPHP har grymt stöd för CRUD och tabellrelationer, som inte verkade vara helt stött med sqlite.

SÄ, jag satte mig ner och började skrida till verket. Efter nÄgra timmar har jag en sida uppe som ligger pÄ http://dopingkollen.se.

Dopingkollen Ă€r en kollaborativ sida dĂ€r alla kan söka, Ă€ndra och lĂ€gga till produkter. Det som behövs Ă€r produktens titel samt dess innehĂ„llsförteckning. NĂ€r produkten finns i databasen jĂ€mförs den direkt med RF’s lista och ger information ifall produkten gick igenom eller inte.

Enkelt och smidigt, men designen behöver jobbas pÄ, och det gör jag :).

Förutom sidan i sigsjÀlv Àr dÀr ett API, se http://dopingkollen.se/api, gjort i REST + JSON, för enkel och bandbreddssparande implementering.

SÄ, nÀsta steg Àr att gÄ igÄng sidan i sin enklaste form, vara nöjd med designen. DÀrefter blir det ett nytt spÀnnande projekt som jag tÀnkte lÄta vara Open Source, en Android app som implementerar zxing, dÀr man kan anvÀnda sin mobilkamera för att skanna en EAN-kod och dÀrefter fÄr resultatet direkt i luren nÀr man stÄr i affÀren och ska bestÀmma sig för vilket kosttillskott man funderar pÄ att köpa.

 

 

Goals of 2011

Haha, just read my old post regarding the goals I had set in 2010. Did any of them come true? – No.

This is how it went:

#1 MonoTouch app
I did start an iPhone application with MonoTouch, but the API for the application is was developing on never got completed so it just died. Would’ve been a great app that’s for sure

#2 Payson drupal module.
Also got started, even got quite far actually, but my leaving of the drupal site I was part of (linuxportalen.se) resulted in a non-complete code. Besides, I have a shallow memory that there were some problems with drupal when it came to directly hook into POST parameters, which were needed by the Payson API. When i think about it I should’ve just made a hacky php that connected to the database with the proper result, but if I’m not mistaken mind was set to do it “the proper” way, which resulted in a no go.

#3 Community site based on Django
Ah, i really loved python back in early 2010, and I still do, but when I did some research I found tornado server of better use, as I started to more and more like to writer proper API’s, instead of views with hooks of code.

I stopped with the Django project after some time, got back to PHP, created a small framework and started developing the new community site, which also kind of died along with my interest in the Swedish Linux community (yeah, it was meant to replace linuxportalen) whom were too much interested of internal conflicts plus distro war.

But, through the year I looked up some different Web frameworks for PHP, and I found DooPHP, a wonderful and fast framework which is easy to learn and use. There’s a small project going on there, without a release date though, just something I do when I’m bored.

So to sum it up, none of my plans happened with the spare time I had part from my ordinary job, but it’s ok, none of them were too important, even though it looked like it when I think back about it.

 

Goals of 2011
Ha ha, right, I won’t set up any goals this year. I spend far too little time in front of the computer when I’m not working and the truth is, there are other things in life far more important to cherish and enjoy besides techie stuff. But hey, do I find something not too big and fun, I’ll probably do it :-).

Take care,
Marcus