Programmering

Bildgalleri

Då har man spenderat en hel dags kodande plus ett par förmiddagar tidigare i veckan för att få fram ett fungerande bildgalleri. Galleriet är skrivet som en modul till bloggsystemet och verkar fungera ok iaf, lite funktioner fattas men det är helt användbart.

Ska slänga upp det i denna bloggen och använda det för att ladda upp lite screenshots och sånt i, får se när det blir av bara ;)

Jahapp, förra spamskyddshacket var i princip ordugligt. Spärrade ingenting. Istället har jag idag byggt ihop ett snabbt litet hack som matchar på vanligt förekommande strängar istället och automatbannar på en matchning. Jag har funderat på att lägga in detta i bloggsystemet länge, alternativt som modul. Får hoppas att detta skydd fungerar bättre.

Cheers.

Jag har utrustat bloggsystemet med ett enkelt spamskydd som jag tror ska skydda mot den typ av spam denna bloggen har blivit utsatt för. Det hela går ut på att om systemet får en anslutning från samma IP inom en femsekunders period bannas IP-nummret automatiskt. Detta gäller dock bara om anslutningarna inte kommer från samma session, med andra ord kan man surfa runt på sidan utan problem. Men att t.ex. surfa in på sidan med två olika webbläsare inom femsekundersintervallen kommer inte att gå.

I framtiden, om skyddet fungerar, så ska det gå att inaktivera och aktivera det i inställningspanelen samt ställa in hur lång tid tillbaka det ska kolla efter upprepade anslutningar. Fem sekunder verkar vara en rätt ok tid, just nu. Men det är möjligt att jag kommer att öka den till tio.

Cheers.

Boten anna - the source

Nu var det faktiskt någon som efterfrågade sourcen till min enkla bot. Efter lite redigeringar av den så tror jag att den ska fungera. Jag har dock bara testat den under Linux (Debian Sarge och Gentoo), ingen support kommer att ges på andra OS än Debian :) Men jag tror inte att det är så mycket som ska strula.

code:

#!/usr/bin/perl

#Written and maintained by dr slizer

use Socket;

#Some bot settings
$BotName = \'Anna\';
$BotDescription = \'Jag är en bot!\';
$BotPassword = \'\';
$debug = 1; #Show debug messages (all incomming and outgoing traffic) in STDOUT
$ShowPMs = 1; #Show PMs in STDOUT if the come from an OP

#Some hub settings
$hostname = \'\';
$port = 411;

#----Beginning of script----#

$Name = \'Boten anna\';
$Version = \'0.1\';

@OpList = ();


$tcpProtocolNumber = getprotobyname(\'tcp\') || 6;
socket(SOCKET, PF_INET(), SOCK_STREAM(), $tcpProtocolNumber) || die(\"** Socket: $!\");

$address = (gethostbyname($hostname))[4];
$internetPackedAddress = pack(\'Sna4x8\', AF_INET(), $port, $address);

print(\"** Connecting to $hostname:$port...\\n\");

connect(SOCKET, $internetPackedAddress) or die (\"** Connect: $!\");

print(\"** Connected\\n\");

$input_buffer = \'\';
$buffer = \'\';

$active = 1;

while ($active)
{
	#Clearing the buffer
	$buffer = \'\';

	$get_data=1;
	
	#This loop read on \"protocol line\" from the socket
	while($get_data)
	{
		#Reading one byte from the buffer
		recv(SOCKET, $input_buffer, 1, 0);
		
		#print \"$input_buffer\\n\";
		
		#If the buffer doesn\'t contain any data the connection was reset by the server
		#and we will exit this loop and shutdown the bot
		if($input_buffer eq \'\')
 		{
 			$active=0;
			$get_data=0;
			print(\"** Disconnected\\n\");
 		}
		
		#If the buffer contatins |, we exit the loop because the line is complete
		#If not we append the read byte to $buffer
		if($input_buffer eq \'|\')
		{
			$get_data=0;
		}
		else
		{
			$buffer=$buffer.$input_buffer;
		}
	}
	
	#Some debugging of incoming data
	if($debug && $active){ print \'>> \'.$buffer.\"\\n\";}
	
	@current = split(/ /, $buffer);
	
	#The first entry in the array is the command
	if(@current[0] eq \'$Lock\')
	{
		#We got lock, we\'re sending $Key and $ValidateNick
		send_data(\'$Key \'.Lock2Key(@current[1], 0x05).\'|\');
		send_data(\'$ValidateNick \'.$BotName.\'|\');
	}
	elsif(@current[0] eq \'$GetPass\')
	{
		print(\"** Sending password...\\n\");
		send_data(\'$MyPass \'.$BotPassword.\'|\');
	}
	elsif(@current[0] eq \'$ValidateDenide\')
	{
		#Something\'s wrong with our nick, shutting down the script
		print(\"** Invalid nickname\\n\");
		$active=0;
	}
	elsif(@current[0] eq \'$BadPass\')
	{
		#Wrong password, shutting down the script
		print(\"** Invalid password\\n\");
		$active=0;
	}
	elsif(@current[0] eq \'$HubIsFull\')
	{
		#The hub is full, shutting down the script
		print(\"** The hub is full\\n\");
		$active=0;
	}
	elsif(@current[0] eq \'$Hello\')
	{
		if(@current[1] eq $BotName)
		{
			#Wieeeeee, we are welcome in the hub :)
			send_data(\'$Version 1,0091|\');
			send_data(\'$GetNickList|\');
			send_data(\'$MyINFO $ALL \'.$BotName.\' \'.$BotDescription.\'$ $BOT1$BOT$0$|\');
		}
	}
	elsif(@current[0] eq \'$OpList\')
	{
		my(@new_Ops) = split(/\\$\\$/, @current[1]);
		my($index) = scalar @OpList;
		
		foreach $cur_op (@new_Ops)
		{
			if(!in_array($cur_op, @OpList))
			{
				@OpList[$index] = $cur_op;
				$index++;
			}
		}
	}
	elsif(@current[0] eq \'$Quit\')
	{
		if(in_array(@current[1], @OpList))
		{
			my(@new_OpList) = ();
			my($index) = 0;
			foreach $cur_op (@OpList)
			{
				if($cur_op ne @current[1])
				{
					@new_OpList[$index]=$cur_op;
					$index++;
				}
			}
			@OpList = @new_OpList;
		}
	}
	elsif(@current[0] eq \'$To:\')
	{
		#Checking if the message really is to the bot, it should be but you never know ;)
		if(@current[1] eq $BotName)
		{
			#Merging all arguments to the command into one string 
			my($arg) = \'\';
			my($i) = 6;
			while ($i<@current)
			{
				if($arg ne \'\')
				{
					$arg=$arg.\' \';
				}
				$arg=$arg.@current[$i];
				$i++
			}
			
			if($ShowPMs && !$debug && in_array(@current[3], @OpList))
			{
				print($current.\"\\n\");
			}
			
			#We let the command sub take care of the message
			command(@current[3], @current[5], $arg);
		}
	}
    else
    {   
        my($first) = substr(@current[0], 0, 1);
        if($first ne \'$\')
        {   
            #Main chat message
            if(@current[0] ne \'<Anna>\')
            {
                #Very quick and dirty matching ;)
                if($buffer =~ \' anna \' or $buffer =~ \' Anna \' or $buffer =~ \' Basshunter \' or $buffer =~ \' basshunter \')
                {
                    send_data(\'<\'.$BotName.\'> Jag är en bot!|\');
                }
            }
        }
    }
}

close(SOCKET);

sub command
{
	my($user, $command, $arg) = @_;
	#Removing new line char from $arg
 	$arg =~ s/\\n//ig;
	
	##Administrator functions
	if($command eq \'+shutdown\' && in_array($user, @OpList))
	{
		print(\"** $user ordered me to shutdown\\n\");
		$active = 0;
	}
	if($command eq \'+ops\')
	{
		send_data(\'$To: \'.$user.\' From: \'.$BotName.\' $<\'.$BotName.\'> I\\\'m aware of these operators:|\');
		foreach $cur_op (@OpList)
		{
 			send_data(\'$To: \'.$user.\' From: \'.$BotName.\' $<\'.$BotName.\'> \'.$cur_op.\'|\');
		}
	}
}

sub in_array
{
	my($value) = shift;
	my(@array) = @_;
	
	for(@array)
	{
		return 1 if $_ eq $value;
	}
	return 0;
}

sub send_data
{
	my($data) = @_;
	if($debug){print(\"<< $data\\n\");}
	send(SOCKET, $data, 0) or die(\"** Failed sending data: $!\");
}

sub Lock2Key
{
        @_ == 2 or die \"** Usage: convertLockToKey( lock , xorkey )\";
        my @lock = split( // , shift );
        my $xor_key = scalar( shift );
        my $i;
        my @key = ();

        # convert to ordinal
        foreach( @lock ) {
                $_ = ord;
        }
        # calc key[0] with some xor-ing magic
        push( @key , ( $lock[0] ^ $lock[ $#lock - 1 ] ^ $lock[ $#lock ] ^ $xor_key ) );
        # calc rest of key with some other xor-ing magic
        for( $i = 1 ; $i < @lock ; $i++ ) {
                push( @key , ( $lock[$i] ^ $lock[$i - 1] ) );
        }
        # nibble swapping
        for( $i = 0 ; $i < @key ; $i++ ) {
                $key[$i] = ( ( $key[$i] << 4 ) & 0xF0 ) | ( ( $key[$i] >> 4 ) & 0x0F );
        }
        # escape some
        foreach( @key ) {
                if ( $_ == 0 || $_ == 5 || $_ == 36 || $_ == 96 || $_ == 124 || $_ == 126 ) {
                        $_ = sprintf( \'/%%DCN%03i%%/\' , $_ );
                } else {
                        $_ = chr;
                }
        }
        # done
        return join( \'\' , @key );
}

Buggfixar

Nu känns det verkligen som inte tiden räcker till. Bloggsystemet tar så mycket tid att det inte är klokt. Todolistan är full med massa smågrejer som måste fixas och desto mer jag pillar med systemet desto fler småbuggar upptäcker jag. Inga större problem har jag inte stött på än, som tur är.

Det skulle faktiskt vara riktigt skönt att få ut en publik alphaversion inom en snar framtid, så att man kan ta tankana ifrån systemet och fokusera på något annat. Eller, någon annan del av projektet iaf. Jag måste ta mig tid och skriva ett bildgalleriplugin till bloggen. Det ska faktiskt bli riktigt intressant att skriva en litet större modul för att se hur saker och ting fungerar.

Men nu ser sängen väldigt lockande ut, cheers.

Buggar

Buggar är nog bland det tråkigaste som finns. Att behöva dyka ner i gamal avslutat kod för att ändra den istället för att kunna fokusera på de nya funktioner man har i huvudet.

Det som har strular ikväll är escaping av tecken, men jag tror att det är löst nu. Någorlunda i alla fall. Litet fulhack så länge som förhoppningsvis kommer att ersättas med en ny permanent lösning ;) Men vi vet alla hur det är med sånt =)

Jag har nu jobbat flera dagar med att införa ett gruppbaserat rättighetssystem i bloggen och nu börjar jag närma mig slutet. Det är verkligen coolt måste jag säga. Detta stöd gör att man kan använda systemet till mycket mer än ett enkelt bloggsystem. Man kan ha system där flera skribenter tillåts skriva. Man kan då styra vilka som får skriva i olika sektioner, vilka som får kommentera i olika sektioner osv. Riktigt trevligt faktiskt. Detta gör att man kan ha systemet som grund i en hel siteuppbyggnad egentligen. Det går då att använda det som ett, någorlunda enkelt, CMS (content management system) eller nyhetssystem.

Det som återstår nu är att skriva om post.php som har behövt ses över väldigt länge nu. Förhoppningsvis kan jag göra det klart idag och då blir det uppdatering av detta systemet för att testa hur allt fungerar "live".

Ser att jag har haft över tusen besökare i bloggen nu, väldigt trevligt :)

Cheers.

Nu har jag fått en stor dos inspiration och detta kommer att leda till att bloggsystemet får en av sina största förändringar på väldigt länge. Ett gruppbaserat rättighetssystem. Det hela går ut på att man kan skapa olika grupper i systemet som man i detalj kan ange vilka rättigheter de har och var de har dem. T.ex. ska man kunna ställa in i vilka sektioner en grupp kan posta inlägg t.ex. En användare kan vara med i en grupp och äger då den gruppens alla rättigheter.

Mycket intressant projekt detta, har nästan i detalj i huvudet hur det ska genomföras. Var tvungen att skriva ner lite av det igår bara så jag inte ska glömma bort det. Har ungefär en timme nu jag kan programmera, får se hur långt jag kommer.

Denna ändring leder självklart till att jag kommer att lägga in stöd för att skapa och redigera användare. Mycket trevligt. Blir nog så att jag hoppar över att släppa "alpha 1" och hoppar direkt på "alpha 2". När nu det blir.

Idag har det blivit en hel del skrivet på bloggsystemet. Möjlighet att välja vilka kategorier som ska visas i index.php och vilka katergorier som ska visas i sektionslistningen. Väldigt användbart i framtiden, om man vill integrera mer med bloggen. Jag har börjat testa det lite här, genom att skapa en sektion kallad nyheter som varken visas på bloggens startsida eller i sektionslistningen.

Jag har också skrivit ett grundläggande interface för moduler. Tanken med detta är att man ska kunna lägga till extensions utan att behöva modifiera koden. Det finns ett enkelt gränssnitt för att aktivera och inaktivera moduler samt länkar till modulens egna administrationsinterface.

Interfacet består också av möjlighet att lägga till länkar i huvudmenyn genom att lägga till dem i en array.

Jag tror detta kommer att bli trevligt, det jag ska göra nu är att utveckla lite med detta modulsystemet som grund. Det första jag ska göra är att skriva om denna siten till en modul. Blir egentligen inte så mycket modifikation utan det blir snarare bara att göra ett interface för att lägga till länkar i huvudmenyn.

Huvudsaken är hela tiden att inte behöva modifiera bloggsystemets kod.

Jag har också skrivit ett bildgalleri tidigare som jag ska modifiera och förbättra avsedvärt, detta ska jag skriva som en modul till bloggen. Mest för att jag är väldigt intresserad av att ha ett bildgalleri på denna siten, skulle vara väldigt smidigt :)

Kanske skulle koda lite till, efter jag har rest och sträckt lite på mig.

Cheers.

Outputbuffering

Bloggsystemet har fått tillökning i form av outputbuffering, latest posts och stöd för felhantering. Detta leder till att ett fint felmeddelande kommer att visas när en MySQL-fråga misslyckas. Jag är inte riktigt där än visserligen, jag måste lägga till "or error()" efter varje SQL-fråga. Detta kommer att ta lite tid men när det är klart är mycket vunnet. Mycket lättare att hitta fel när man får felmeddelande ;)

Har inte mycket mer att säga, det har inte blivit så mycket skrivet idag som jag hade önskat. Men felhanteringen är en mycket viktig komponent som är användbart inför framtiden.

Jag är sugen på att börja skriva på ett modulsystem, men jag vet inte riktigt hur jag vill lägga upp det än.

Cheers.

Blog ahead

Jag har kommit på ett namn på bloggsystemet, blog ahead. Jag vet inte riktigt om jag är nöjd med det, men det var det bästa jag kunde komma på. Om någon har något bättre förslag, tveka inte att lägga en kommentar ;)

Jag har varit så pass duktig att jag har börjat färdigställa en alpharelease. Problemet är bara att jag har fått så mycket nya fina idéer jag vill försöka lägga in i systemet. De kommer visserligen inte med i första alphan, men jag har bara sån lust att skriva på dem så jag gör det istället för att fixa ett installscript =)

Det jag har funderat på mest är ett extensionssystem, egentligen borde det inte vara jättesvårt att skriva om man gör det någorlunda enkelt. Har massvis med idéer och jag har faktiskt grejer jag kan testa att implementera som extensions. Jag har bland annat skrivit ett bildgalleri, fullt med skräpkod och andra grejer, men det går att rensa upp. När jag ändå håller på med upprensningen av den koden, som jag har planerat länge, så kan jag skriva om galleriet så det passar som extiension i bloggen. Det skulle också vara jäkligt nice för min site, eftersom jag har velat ha ett bildgalleri där. Men eftersom det jag hade var så fult gjort ville jag inte använda det.

Det här blir nog bra till slut, man kan ju hoppas iaf :)

Jag trodde inte jag kunde lösa det, inte utan att ta hjälp av Sweclockers i alla fall. Kanske ska börja med att beskriva problemet. Självklart handlar det om bloggsystemet ;)

Två tabeller, en innehållande bloggposter och en innehållande kommentarer. På indexsidan väljs de poster som ska skrivas ut först, sedan görs en query för att ta reda på antalet kommentarer för just den aktuella posten som skrivs ut för tillfället. Vilket är väldigt inefftivt eftersom det görs en massa, egentligen, onödiga queries. Jag har velat hämta all data med en query men har inte lyckats. Inte förrän nu. Har experimenterat och läst MySQL-docsen utan att komma på hur jag ska ordna det.

Men skam den som ger sig, ännu lite mer läsande angående JOIN och mer experimenterande har gett mig en lösning. Som jag är säker på ska fungera :) Nu ska den bara in i bloggsourcen också.
SQL-frågan (självklart utan någon förfining):

code:

SELECT posts.id, posts.topic, count(comments.id) as count FROM posts LEFT JOIN comments ON posts.id=comments.pid WHERE posts.bid=1 group by posts.id ORDER BY posts.date ASC LIMIT 0, 15;

Detta var den grejen jag helst ville rätta till innan jag släppte någon version av bloggen och nu verkar det som att det är löst. Det är konstigt, på förmiddagen försöker man koda men man kommer ingenstans. På natten flyter allt så bra så det inte är klokt :)

Cheers.

MySQL

SQL är verkligen ett kraftfullt språk. Pulade lite idag med hur sektionslistningen visas i bloggen, igår implementerade jag bara så att namnet på sektionen visas. Men jag ville ha så att även antalet inlägg i den berörda sektionen visades efter namnet, jag visste dock inte riktigt hur jag skulle åstakomma det med bara en SQL-fråga. Idag såg jag en tråd på sweclockers om ett MySQL-problem och jag blev inspirerad, GROUP BY kanske skulle gå att använda? Upp med MySQL docsen och läsa, hittade inte mycket matnyttigt egentligen, visste inte direkt vad jag skulle söka på. Nästa steg? Mysql-klienten. Bara att starta mysql och börja experimentera med queries, efter tio minuter hade jag en som fungerade och den är nu implementerad i bloggen. Jag tror att jag kan optimera bland annat arkivet med mina nya kunskaper, inte helt säker men jag tror det.

Om det är någon som är intresserad av frågan som löste mitt problem så är kommer den här (har inte snyggat till den något :)):

code:

select blogs.name, blogs.id, COUNT(posts.bid) as count from blogs, posts where posts.bid=blogs.id group by blogs.name order by blogs.name ASC;

Sektioner

Fick inget kodat alls i helgen så nu på morgonen var sugen enormt. Det var riktigt skönt att köra igång editorn och börja skriva. Resultatet blev ett bloggsystem med stöd för sektioner. Håller just nu på med att flytta över massa gammla inlägg till de nya sektionerna, det tar tyvärr sin tid.

Kom underfund med under kodandets gång att post.php måste skrivas om, det är inte ens spaghettikod, det ser ut som en potatissallad! Frågan är bara när jag ska orka göra det. Det känns så tråkigt att skriva om något man har skrivit, speciellt när det är så här tidigt i utvecklingsfasen som detta projekt ändå är.

Men om jag lyckas komma upp i någorlunda tid på morgonen i fortsättningen av veckan är jag optimistiskt, då kanske det blir en release denna veckan. Man kan ju alltid hoppas i alla fall.

Andra projekt

Bloggmjukvaran kommer inte att släppas i början av veckan, så mycket är säkert. Antagligen kommer den inte att släppas alls denna veckan. Det är inte alls så mycket som måste fixas, egentligen inget mer än ett installscript och lite docs. Men jag lägger nog lite tid på min DC-bot för tillfället istället för att fixa iordning det sista på bloggsystemet. Fick helt enkelt en jäkla lust att koda lite Perl när jag smällde upp några fina Aterms och startade VIM :)

Sedan känns det mycket roligare att koda lite grundläggande funktioner i en logbot än att fixa ett installscript till ett bloggsystem.

Koden kallar, cheers.