Tuesday, June 26, 2012

Counting occurences of subclasses in Django

Counting occurences of subclasses in Django

As a Django learning project I have began CONTMAN, a simple mobile content distribution system, and as expected I have ran into many different kinds of problems that I have thought it would be interesting to keep a log of... and this is it.

This might be the classic case of "When all you have is a hammer everything looks like a nail" as when I was thinking on how to design the project I came across Django inheritance and polymorphism features. "Aha! this is EXACTLY what I need" I said to myself. Now I am not so sure, but I am perhaps one of the most stubborn people in the world, so I kept going in that direction.

So I thought. I have two, maybe three different kinds of content I want to be able to distribute with this platform, for now I have "Ringtones" and "Wallpapers" (NB: I know it is not bleeding edge stuff, but keep in mind this was for learning, and I could not think of anything else at the time), and both of them are Content.

So we have a parent Content Class

class Content(models.Model):
    name = models.CharField(max_length=100)
    created_on = models.DateTimeField('created', auto_now_add = True )
    keyword = models.CharField(max_length=100)

And to children subclasses

class Ringtone(Content):
    artist = models.ManyToManyField(Artist)
    data_file = models.FileField(upload_to="uploads")

class Wallpaper(Content):
    category = models.ForeignKey(Category)
    data_file = models.ImageField(upload_to="uploads")

Ok, so there is a whole bunch of other stuff there but this is enough to get the point of this post across.

To me this was going to be very helpful in a lot of ways to mention some:

  • Delivering content would be as easy as pointing to Content.data_file (which you can't is it is clearly stated at the very end of this doc entry.)
  • The admin app would let me easily create a manager for uploading the file depending on the type (see comment above)
  • Creating reports would be very easy, just create a query set from the Content model.

This last point is the one we will be discussing. 

So it turns out that

a = Content.objects.get(pk=1)

returns a Content object, so you cannot count or fetch content using  "a.data_file".  So how can I do a simple report showing the count of each type of content available? The easy (lame) way could be to simple do two queries of Ringtone and Wallpapers as we only have those and leave Content alone. But this is not nice, in fact it reeks of bad code and self-pity. What if I later add support for "applications" and "games" Content types?

So after a nice session of Django docs + stack overflow + google I think I came across a very simple but effective solution here in stack overflow

The idea is to take advantage of the Contenttypes framework to keep track of what kind of model each object represents. This way we can aggregate easily on our query a create this type of report. So we modify the base (parent) class like this:
class Content(models.Model):
    name = models.CharField(max_length=100)
    created_on = models.DateTimeField('created', auto_now_add = True )
    keyword = models.CharField(max_length=100)
    content_type = models.ForeignKey("contenttypes.ContentType")

With this then we can easily do this:
class Content(models.Model):
>>>Content.objects.values('content_type__name').annotate(hits=Count("content_type"))
[{'hits': 1, 'content_type__name': u'ringtone'}, {'hits': 2, 'content_type__name': u'wallpaper'}]


Wednesday, February 25, 2009

Mysql and group_concat!

I'm determined to write a little more often on my blog (I've skipped 2008 altogether) because it also works as my personal notepad for the world to see. So let's get started.

Today I've discovered a wonderful new MySQL trick: group_concat and it saved me from doing tedious/slow scripting and also from trying to understand how Stored Procedures work in MySQL (which is something like arameic to me right now).

I've been working with Eventum which is a lovely open source bug tracker from the great thinkers at MySQL AB (now.. Sun). Eventum lets you add N custom fields to the issue creation and listing page, and it adds all of them to a table called eventum_issue_custom_fields. very much like this:


Each custom field has an Id, but they are all entered in different "rows" like this:
(lets say custon field "1" is the tv show name and field "2" is a short description)







IssueIdCustomFieldIdCustomFieldData
50190210
502Lame TV show
511Family Guy
512Funny Stuff


what if i wanted to select from this table the tv show name and the description in just one row?

Thinking about loops in your scripts?
Thinking about stored procedures?
Thinking it cannot be done at all?

Check this out:

SELECT IssueId,GROUP_CONCAT(CustomFieldData ORDER BY CustomFieldData SEPARATOR ',') AS value_list FROM tv_show_table GROUP BY IssueId ORDER BY IssueId

And you will get some nice stuff like:




IssueIdvalue_list
5090210, Lame TV Show
51Family Guy, Funny Stuff



How cool is that?!

the actual eventum query would be:

SELECT icf_iss_id,group_concat(icf_value order by icf_value separator ',') as values_list from eventum_issue_custom_field where icf_fld_id=2 OR icf_fld_id=1 group by icf_iss_id order by icf_iss_id;

Because i only want fields with id 1 or 2.


Bye!

Friday, February 20, 2009

Freetds, DBD-Sybase, Fedora 10


This is an update to an earlier entry

If you want to install DBD-Sybase Perl Module and use freetds in Fedora 10
you must install a patch for it to work. My versions are freetds-0.82, DBD-Sybase-1.09 and of course Fedora 10.




Find your way to the FreeTDS source directory, such that this command
works:

$ grep '\$Id' include/cspublic.h
static const char rcsid_cspublic_h[] = "$Id: cspublic.h,v 1.61 2008/09/08
17:50:25 jklowden Exp $";

Your ID will be different; it should match what's in the patch: 1.58.

Then "man patch" is your friend. Like it says,

usually just

patch
is all you need, as in:

$ patch < /path/to/your/cspublic.BLK_VERSION_150.patch

Then build and install per usual.


(shamelessly stolen from http://lists.ibiblio.org/pipermail/freetds/2009q1/024260.html)


Enjoy!!

Wednesday, October 24, 2007

Solving asterisk´s HDLC Abort Issue


Have you encountered the following msgs in your /var/log/asterisk/messages?

Oct 23 16:54:51 NOTICE[3345] chan_zap.c: PRI got event: HDLC Abort (6) on Primary D-channel of span 1
Oct 23 16:54:54 NOTICE[3345] chan_zap.c: PRI got event: HDLC Bad FCS (8) on Primary D-channel of span 1

if so... you've come to the right place. This is a very tricky one. There are mailing lists with tons of messages regarding this issue scattered throught the web, but none of the them actually follow throught what causes this and how to solve it.

The tricky part is that you system may probably seem to work, you can receive and place calls, but every now and then... all of the calls get dropped at the same time. "Must have been a quirk" you say to yourself even though you know such thing does not exist. Then a few minutes afterward... again. And that YELLOW alarm is now staring you in the eyes with that smug in his face....

PRI configuration is not for the faint of heart, that is for sure. But this message 99 times out of hundred is a harware incompatibility issue, not ISDN config.

High-Level Data Link Control or HDLC is a bit-oriented synchronous data link layer protocol, HDLC was introduced into Digium systems in order to allow data and voice to be used/routed in the same card. This is a good thing, the bad thing is that it relies on more on the system clock for timing. And new motherboards and kernels do not play nice with this settings and old telephony cards.

This may be caused due to IRQ interrupt sharing, APIC, HD params, but to put it plain and simple: YOUR TELEPHONY CARD DOES NOT LIKE YOUR MOTHERBOARD. I wish i had seen that sentence a few months ago.

This was exactly the case with my Proliant ML150 G3 server, which has an Intel Motherboard and specially an Intel Onboard ethernet card. I had a TE110p, which has been my workhorse in several other settings, so it was strange for me that it failed on me so often. As it turns out, Digium's TE110P is the picky girl type, it does not play well with others because of its chipset (TigerJet). Digium was aware of this, so they had to go back to the drawing board and came up with what they like to call "VoiceBus Technology" which basically works a whole lot better.

So here it is, plain and simple if you have a TE110P card having this problems, you MUST update your card to a newer version or get a motherboard that works with that TE110P and hold on to it, hard. They are getting harder to find by the minute. So the solution: Buy a TE120P with the new VoiceBus technology or just run to the Sangoma Camp.


I wish i had a magical bash script that solved this issue... but this time you must take the expensive road.

Luckily you may have found this blog very early in the guessing process of solving this issue and saved a ton of time. Trust me, i was seconds away of trying voodoo or any other sort of black magic.


Hope this helps!


Alex






Thursday, August 30, 2007

Flex: Checkboxes,repeaters,

Recently I've discovered this GREAT tool called Flex from Adobe, which solved one of my great problems: I can do a little bit of scripting but i am NO designer, so usually my GUIs end up giving a very bad impression of the overall app. Flex is here to save the day. Flex allows anyone to create streamlined, compatible GUIs in no time. But there is so much more to Flex than just GUIs. It uses both MXML and ActionScript so you have easy MXML interface creation along with a full Object Oriented language.

It is INCREDIBLE how all of us have being spoiled into stateful programming, I have had the hardest time trying to think stateless. So i have take baby steps.

This next Flex program is very simple, but it exemplifies some of Flex's main features.

So here it is:


xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="creationCompleteHandler();"
>


private function creationCompleteHandler():void
{
userRequest.send();
}
]]>


[Bindable]
var jailh:Array =new Array;
]]>


public function addToarray(Mymine:String):void{
var match:String = Mymine;
var isChecked:int = 0 ;
for (var i:int = 0; i < jailh.length; i++)
{
if (jailh[i] == match) {
dwindow.text="";
if (jailh.length == 1)
{
dwindow.text +="\n Will shift array"+ '\n'
jailh.shift();}
else
{
dwindow.text +="\n splice:\t"+i+','+(i+1)+'\n'
jailh.splice(i,i+1);
}
isChecked=1;

dwindow.text +="Deleted"+ '\n'
dwindow.text +="Current Length! " +String(jailh.length)+ '\n' ;
myarray.text=jailh.join("\n");
break;
}
}
if (isChecked==0){
jailh.push(Mymine);
dwindow.text="Current Length " +String(jailh.length);
myarray.text=jailh.join("\n");
}
}

]]>





































Basically this is a series of checkboxes that are pulled from an XML using an HTTPService call, then when checked they are added to an array... if the are checked again they are looked up for a match in the array, if there is a match the values are deleted.

Hopefully this will help someone, I know that if I had found such an example It would have saved me hours!


Thanks!

Alejandro

Friday, June 1, 2007

Finding out id of last inserted record using DBI+perl+MySQL

Countless times... and i mean COUNTLESS times i have encountered the pitfall of.... how to find out the value of the autoincrement field of an insert statement, or to put it in layman terms: How do i identify that last insert i did?

Well the answer had been smiling back at me the whole time. Those smart people who wrote the perl DBI::Mysql module had thought of that and came up with mysql_insertid function.

Let's get to it!

$sql="insert into sdata(somedata) values(\"somevalue\")";
$sth = $dbh->prepare($sql);
$sth->execute();
$id = $dbh->{ q{mysql_insertid}};
$sth->finish();


Now $id holds the value of Id (my autoincrement field in that table).

A thing of beauty!! Hope this helps! bye!



Saturday, April 7, 2007

Forgotten Basic Bash Tools (and some obscure tips)

Wow, i did not realize it had been so long since my last post. For all of you out there that check my blog: sorry. In my own behalf I was busy busy getting engaged and a couple of life altering ordeals. And since this is not related to Linux (Auuu Auuu! (....just watched 300, if you watched im sure you have laughed there!)) I will not extend myself there.

Ok, so I know that most people that want to become a Linux/*NIX/Darwin "expert" immediately dive into the bare bones essentials like how to change directory, rename files... and then crash course into some scripting program like php, ruby, or my weapon of choice perl, and that is that. But they miss a lot of the subtle and beautiful programs included with most distros. Some of them have been around since there very first days of UNIX like, cat or tail and some made it later. But they are powerful and elegant, just try doing some in front of your geek friends, you will earn their awe and probably some resentment along the way.

Lets get started:

tac: the evil twin brother of cat (which stands for concatenate, not the sneaky feline), and it does exactly what cat does (concatenate and print files to standard output) but with a twist. It does it in reverse. So by now like in a M. Night Shyamalan movie, things are all falling into place in your head. Just like cat, tac is the perfect UNIX philosophy example: It does ONE thing, and it does it well.

Ex:

[alex@galapago ~]$cat hello.txt
Hello
my
friends!

[alex@galapago ~]$tac hello.txt
friends!
my
Hello

Simple, elegant and functional, it has a couple of useful switches there. Mix it up with other bash commands, throw in some pipes and voilá you've got yourself a masterpiece.


split : Based on actual events-- Not so long ago i was asked to split a file into several files every million lines, and I thought to myself, "This is an easy job for perl" and indeed it was. Later on i found that i had missed this beautiful command named split whose function in to do exactly that (in less time)

For example

alex@alex-desktop:~/numbers$ cat numbers.txt
one
two
three
four
five
six

And we wish to split in files with three lines:

alex@alex-desktop:~/numbers$ split -l 3 numbers.txt div

div here repre

alex@alex-desktop:~/numbers$ ls
divaa divab numbers.txt
alex@alex-desktop:~/numbers$ cat divaa
one
two
three