banjalukaforum.com https://banjalukaforum.com/ |
|
Utils https://banjalukaforum.com/viewtopic.php?f=18&t=13698 |
Stranica 1 od 1 |
Autoru: | che.guevara [ 10 Maj 2005, 21:34 ] |
Tema posta: | Utils |
Tu i tamo zatreba mi neki bezveze program. Jednostavan i glup. I ne mogu da ga nadjem na netu nigdje. I onda moram da ga napravim sam ![]() Evo šta se izrodilo iz svega toga Program za poređenje dvaju foldera status: radi odlično koliko ja znam potreba: za igru battle for wesnoth, http://www.wesnoth.org Kod: ## SIMPLE PATCH MAKER
## by FreeCraft ## email: freecraft@gmail.com ## i would like if you could donate some spam to my mail adress XD ## PUBLIC RELEASE 0.1b import os from os.path import join from shutil import copy2, rmtree def spam(old = "wesnoth_old", new = "wesnoth_new", patch="wesnoth_patch"): """ This function does all the work! All parameters are dir names. Name of variables are descriptive i think. All of them are relative to current/script/ folder, so place the script in folder above old and new wesnoth folders. Egh, I don't want to confuse you... here is all what you need to do> 1) make a directory "patchmaker" 2) put this script into that directory 3) copy the old wesnoth binary files to folder ./patchmaker/wesnoth_old 4) recompile the project 5) copy the new wesnoth bins to folder ./patchmaker/wesnoth_new 6) run this program and choose the default option 7) everything that is changed will be copied in folder ./patchmaker/wesnoth_patch 8) zip or tar.bz2 that folder and upload it to wesnoth downloads page :) Well, this was an explanation for dummies, I know you are enough smart to figure it out yourself, but I wanted to be descripitive and clear, so other people could use it too. Don't forget that this program is quite usable in other situations too. I'm planing to make a good program from this! Something, really usefull :D """ abs_patch = join(os.getcwd(), patch) abs_new = join(os.getcwd(), new) abs_old = join(os.getcwd(), old) print "patch=%s\nnew=%s\nold=%s" % (abs_patch, abs_new, abs_old) # fist delete the patch dir if already exists print "Creating directory ..." try: rmtree(abs_patch) except Exception, exclamation: pass os.mkdir(abs_patch) print "Creating log files ..." logchanged = file("logchanged.txt",'w') print "Starting directory walk ..." print "-" * 50 root = os.curdir os.chdir(join(os.curdir,new)) for path, dirs, files in os.walk(''): print "Walking the dir '%s'" % (path) for filename in files: rel_path = join(root, path, filename) oldfile = join(abs_old, rel_path) newfile = join(abs_new, rel_path) print '-' + rel_path if fchanged(oldfile, newfile): logchanged.write("File " + newfile + " is changed or it is new...\n") copy2(newfile, join(abs_patch,path,filename)) print "Creating directories" [makedir(join(abs_patch, path, dirname)) for dirname in dirs] logchanged.close() def makedir(path): # just make the dir, with no exception raised try: os.mkdir(path) except Exception: pass def fchanged(old, new): """ this is something like interface --- """ return not compare_bytes(old, new) def compare_bytes(path1, path2): """ The file comparision function Returns True if equal, False if different Also returns False if exception is Raised ie - file not found. """ try: if os.path.getsize(path1) != os.path.getsize(path2): return False f1, f2 = file(path1), file(path2) except Exception, msg: return False # here, comparision is done by xKB block comparision blocksize = 4 * 1024 while True: a, b = f1.read(blocksize), f2.read(blocksize) if len(a)==0: f1.close() f2.close() return True if a != b: f1.close() f2.close() return False def compare_lines(text1, text2): """ The file comparision function Returns True if equal, False if different Also returns False if exception is Raised ie - file not found. Diference between this one and compare_bytes function is that this compares lines, not blocks, anyway, it might be useless, but however :) """ try: if os.path.getsize(path1) != os.path.getsize(path2): return False f1, f2 = file(text1), file(text2) except Exception, msg: return False # compare line-by-line for line in f1.xreadlines(): if line!=f2.readline(): f1.close() f2.close() return False f1.close() f2.close() return True if __name__=="__main__": print "Main started ..." print "Use Ctrl-C or Ctrl-D to exit at any time ..." answer = raw_input("Use default?") yes = ('','\n','yes','Yes','YES','y','Y') if answer in yes: print "Use defaults - YES" spam() else: print "Use defaults - NO \nEnter custom values:" spam(old=raw_input("Old dir name: "), new=raw_input("New dir name: "), patch=raw_input("Patch dir name: ")) raw_input("Press enter to quit program!") |
Autoru: | Vertygo [ 13 Maj 2005, 17:21 ] |
Tema posta: | |
Ne koristim je ali u svakom slucaju fino od tebe sto si postovao istu, mozda zatreba nekada ![]() |
Autoru: | che.guevara [ 14 Maj 2005, 14:07 ] |
Tema posta: | |
Program za pravljenje html Thumbnaila - svrha: ide po folderima i pravi html stranice od slika - status: pa radi, ali slike morate da napravite sa IrfanViewom (i thumbove) i onda ih ovaj program "skrpi" u html - todo: napraviti da program sam može od većeg fajla da napravi manji (thumbnail) - etc - potreba: pa profesor mi je dao 500 slika i zamolio me da napravim thumbnail od njih ... ... ... irfan view + python i sve piči ko svjetlo!!! Kod: # PROGRAM: Thumbnail Creator
# AUTOR: Srecko Toroman # toroman@blic.net """ pravi thumbnails od slika. po defaultu, ime slike je x.y a ime njenog thumbnaila je thumb_x.y - slike se fino mogu obraditi koristenjem IrfanView-a """ import os thumbprefix = "thumb_" # prefix_x.y extenzije = (".jpg",".jpeg",".gif") # y - ekstenzije visina = 120 sirina = 160 def main(cwd, stil=""): thumb = """ <td width=%d align=center> <a href="%s"><img src="%s" border="0"></a> </td> """ % (sirina) htmlpocetak = r"""<!doctype html public "-//w3c//dtd html 4.01 transitional//en"> <html> <head> <title> %s </title>%s <meta name="robots" content="all"> <meta generator="toroman_thumbnail"> </head> <body bgcolor="#B00000"> <div align="center"> <p><font color="#FEDEAC" size="+7">%s</font></p> <p> </p> <table border = 0> """ for p,ds,fs in os.walk(cwd,True): html = file(os.path.join(p,"index.html"),'w') naslov = os.path.split(p)[1] html.write( htmlpocetak % (naslov, stil, naslov) ) mod = 0 # svaka 5. slika u novi red started = False for f in [a for a in fs if not a.startswith(thumbprefix)]: if f[f.rindex('.'):].lower() in extenzije: if mod % 5 == 0: if not started: started=True else: html.write("</tr>") html.write("<tr height=%d>" % (visina)) mod=0 mod+=1 html.write(thumb % (f, "thumb_" + f) ) html.write('''</tr><table></div></body></html>''') html.close() |
Autoru: | mangia [ 14 Maj 2005, 15:41 ] |
Tema posta: | |
bez zelje za ikakvom polemikom imas u Konqueror-u opciju za paravljenje tumb. tj Create image gallery. |
Autoru: | che.guevara [ 14 Maj 2005, 17:41 ] |
Tema posta: | |
Hvala na informaciji! |
Autoru: | Digresija [ 14 Maj 2005, 20:35 ] |
Tema posta: | |
Ima to i ACDSee, a cini mi se i da PhotoShop ima neki alat za kreiranje galerije slika i generisanjem HTML stranice sa doticnim slikama. Nije fora koristiti te third-party alate i programe, nego je fora npr. zadati folder (direktorijum) sa full-size slikama, od kojih ce se nekim programom automatski generisati HTML stranice sa slikama. Ili - da zadas neki FTP ili HTTP sajt i folder, pa da moze i te slike obradjivati. Pa zatim npr. da mozes zipovane slike (npr. 50 slika u jednom .zip fajlu) tim programskim rjesenjem unzipovati i te slike obraditi... i td. To i jos mnogo vise trenutno ima ugradjeno u PHP projektu pod nazivom Gallery. Zanimljivo bi bilo vidjeti recimo uradjeno to u Javi ili Pythonu uz potpuno objasnjenje kako se sta podesava i koristi. |
Autoru: | che.guevara [ 14 Maj 2005, 21:38 ] |
Tema posta: | |
Čekaj digresija, da li ti meni to predlažeš da napravim neku pravu aplikaciju ![]() Ovo je ipak "util", ako misliš da bi bilo isplativo praviti nešto ovakvo u pythonu ... možda i uradim, mada mislim da nema od toga "ljeba"... jednostavno, postoje mnoga free/shareware riješenja, a meni je u tom trenutku trebalo nešto jednostavno ... i šta mi je lakše? Da vršljam po netu ili da sam napišem? Pa vidiš ... sam da napišem ![]() |
Autoru: | Digresija [ 14 Maj 2005, 23:42 ] |
Tema posta: | |
Da, postoji mnogo raznih free i shareware rjesenja... Ne moras ti uraditi citavu aplikaciju. Ja sam samo naveo par stvari, kojima bi taj svoj util mogao prosiriti. ![]() No, ako imas ideju za neku aplikaciju, koja jos ne postoji na trzistu ili za neku aplikaciju, koja postoji, ali bi se mogla bolje odraditi - javi se. Uvijek sam raspolozen za razmjenu konstruktivnih i inovativnih misljenja. ![]() |
Autoru: | RAbbit [ 14 Jun 2005, 23:07 ] |
Tema posta: | |
Jeste li vi ikad korisitili Macromedia Dreamweaver mx 2004?Tako je jednostavan a sve to ima tamo ![]() |
Autoru: | che.guevara [ 15 Jun 2005, 21:30 ] |
Tema posta: | |
RAbbit je napisao: Jeste li vi ikad korisitili Macromedia Dreamweaver mx 2004?Tako je jednostavan a sve to ima tamo
![]() Bez napadanja, ali da li si ikad sam sebi obrisao nos, ili ti uvijek mama briše? Što bi reko onaj Bamboocha - to je metafora. Dreamweaver je za glupe Amere. Mi i Kinezi koristimo neke druge stvari ![]() Python rulz, Digresija, samo da te informišem, malo sam "ojačao" skripte, sad imam dvije, jednu koja šeta po folderima i smanjuje slike + pravi thumnail i drugu koja to spoji u html. E sad malo studiram pyGTK biblioteku i HTMLGen tako da će za jedno pola godine (sve laaagaano) biti potpuna aplikacija, ako me nešto ne iznervira ... U međuvremenu napisao sam još neki util i pokoji pdf sa uputstvom, staviću to ovdje, ako nekog zainteresuje možda. Baš je očajno ovo kad nemaš šta da radiš, pa onda "ovako" ![]() Al, uči se zato ![]() |
Autoru: | Vertygo [ 17 Jun 2005, 11:50 ] |
Tema posta: | |
Zbog cega mislis da je program za amatere ? Ja vise gledam program iz ugla funkcionalnosti i po meni dw je sasvim ok program za rad sa html-om pa i server side lang. kao sto je php. Ako je nasminkan ne znaci da je nefunkcionalan. Uzmimo za primjer Blender 3D, program za 3D modeliranje koji koristi Python kao njegov scripting engine. Program je kao sto bi ti napisao "Šminka" ali je open-source i krajnje je funkcionalan !!! |
Autoru: | che.guevara [ 17 Jun 2005, 22:59 ] |
Tema posta: | |
Vertygo je napisao: Uzmimo za primjer Blender 3D, program za 3D modeliranje koji koristi Python kao njegov scripting engine. Program je kao sto bi ti napisao "Šminka" ali je open-source i krajnje je funkcionalan !!!
Nemoj da stavljash Blender u istu kapu sa DreamWeaver-om ! Evo zastho> - 3d dizajniranje je kompleksna stvar za razliku od pisanja HTML-a i blender je stoga mnogo ozbiljnija aplikacija - blender NIJE shminka, oni koriste svoj gui koji pokrece (vjerovatno) glui biblioteka za OpenGL interfejs i tu nistha nije loshe, jer je sve to potrebno, i mnogo je prakticnije od klasicnog Widget interfejsa - blender je besplatan, za razliku od MX Studija koji kostha mnogo vishe nego stho vecini ljudi koji ga koriste treba (npr, ovom liku, RAbbit-u, hej, bez uvrede, samo komentarishem onako, mozda grijeshim, ali teshko). Evo bash sam nestho radio sa algoritmima, i ima jedan problem, naime, data su vam dva stringa i treba pronaci "najmanje edit rastojanje" jednog stringa od drugog. Ovaj algoritam se poceo koristiti siroko i naveliko od kako je genetska biologija uznapredovala. Uz pomoc ovo algoritma mogu se usporediti geni dvaju zivotinja i predpostaviti nacin na koji je neka vrsta evoluirala (a ne citati "informacije" iz biblije kao onaj degen stho ga stalo pushtaju na VIkomu i ostalim smecarskim televizijama). Dakle, Kod: a= raw_input("Unesi prvi string: ") b= raw_input("Drugi: ") lena = len(a) lenb = len(b) sed = [range(0,lenb+1) for each in xrange(0, lena+1)] for i in xrange(0,lena+1): sed[i][0]=i for j in xrange(1,lenb+1): sed[0][j]=j a=' ' + a b=' ' + b import copy editops = copy.deepcopy(sed) print "######## ALGORITAM ########" for i in xrange(1,lena+1): for j in xrange(1, lenb+1): x = sed[i][j-1]+1 y = sed[i-1][j]+1 z = sed[i-1][j-1] if a[i]!=b[j]: z+=1 m = min(x,y,z) sed[i][j] = m if x == m: editops[i][j] = "->" elif y == m: editops[i][j] = "|" elif z == m: editops[i][j] = "\" print "###### distance : " for line in sed: print line print "ukupna duzina ", sed[lena][lenb], '####' print "###### edit operacije (ovo je obrnuti ispis, jXi matrica, samo radi uvidjaja u proces ): " for line in editops: print line print "###### rekurzija radi ispisivanja pravih operacija..." i=lena j=lenb operations = [] while i>0 and j>0: field = sed[i][j] x, y, z = sed[i][j-1], sed[i-1][j], sed[i-1][j-1] m = min(x,y,z) operation = "" if x == m: operation = "ubaci na %d. mjest znak '%s'" % (i,b[j]) field2 = x j-=1 elif y == m: operation = "obrishi %d. znak ('%s')" % (i,b[j]) field2 = y i-=1 else: operation = "zamjeni %d'. slovo ('%s') sa slovom '%s'" % (i,a[i],b[j]) field2 = z j-=1 i-=1 if field != field2: operations.append(operation) operations.reverse() for operation in operations: print operation raw_input( "####### POSAO JE GOTOV #######" ) Zahvaljujem se A. Mladenu na dokumentaciji i objasnjenjima ! Program mozete naci i na mom sajtu, http://www.znalac.tk stim stho je tamo malo ruznije jer josh se nisam najbolje upraksao sa ploneom, mada ce tamo biti bolje - jednog dana ![]() Btw, moram sve da vas obavijestim da me jedno vrijeme nece biti na internetu, jer moram malo da "smanjim", naime, telefonski racun dodje i do 50KM (mislim na net samo) josh kad se dodaju ostali pozivi --- previshe. Tako da, ako me neko hitno treba, neka poshalje pm alfu on zna moj broj telefona ... ![]() ![]() Ma necu ja izdrzati, ipak cu dolaziti bar dva puta nedeljno, ali necu provjeravati sve postove i ostala s***a koja samo troshe vrijeme ![]() Podforum Programiranje smatram ozbiljnim i korisnim, naravno ![]() PS> Evo sad editujem poruku, da ispishem neke primjere, ali ne koristeci genetski kod, vec imena i zeze ![]() programiranje gramofon Kod: zamjeni 1'. slovo ('p') sa slovom 'g' obrishi 3. znak ('r') obrishi 4. znak ('r') zamjeni 8'. slovo ('i') sa slovom 'o' zamjeni 9'. slovo ('r') sa slovom 'f' zamjeni 10'. slovo ('a') sa slovom 'o' obrishi 12. znak ('n') obrishi 13. znak ('n') karla del ponte krava prljava Kod: zamjeni 2'. slovo ('a') sa slovom 'r' zamjeni 4'. slovo ('l') sa slovom 'a' ubaci prije 5. mjesta znak 'v' zamjeni 7'. slovo ('d') sa slovom 'p' zamjeni 8'. slovo ('e') sa slovom 'r' zamjeni 10'. slovo (' ') sa slovom 'j' zamjeni 11'. slovo ('p') sa slovom 'a' zamjeni 12'. slovo ('o') sa slovom 'v' zamjeni 13'. slovo ('n') sa slovom 'a' obrishi 14. znak ('a') obrishi 15. znak ('a') i ipak evo poente programa, dakle kad se unese neki genetski kod (samo cetiri baze, znate ono iz biologije, piramidinska, purinska etc) abbcabbabcbcbabdbcba babbcbabcbbcbbcbadd Kod: zamjeni 1'. slovo ('a') sa slovom 'b'
zamjeni 5'. slovo ('a') sa slovom 'b' zamjeni 7'. slovo ('b') sa slovom 'a' zamjeni 12'. slovo ('c') sa slovom 'b' obrishi 14. znak ('b') obrishi 16. znak ('b') ubaci prije 20. mjesta znak 'd' ubaci prije 20. mjesta znak 'd' Eto toliko, heh lol brate ovaj program je shega prava ![]() |
Autoru: | che.guevara [ 17 Jun 2005, 23:19 ] |
Tema posta: | |
Auuu, sad sam skonto jedan bug ... Svi primjeri su netacni, izvinjavam se, ne da mi se korigovati, kad popravim "situaciju" postavicu taj "opravljeni". Ne znam stha mi bi pa nisam provjeravao program .... Sorry ![]() U principu, program je dobar, ali imam neki bug kod rekurzije ![]() |
Autoru: | Digresija [ 18 Jun 2005, 02:47 ] |
Tema posta: | |
@che.guevara: Daj batali taj degenerator, sta ce nam to? ![]() |
Autoru: | che.guevara [ 20 Jun 2005, 00:33 ] |
Tema posta: | |
Heh, evo jedan jednostavan util. Za one koji ne znaju da koriste grep ili nemaju linux. Radi se o programu koji pretrazuje fajlove za nekim patternom. Ja sam ga napisao kad mi je bilo potrebno da pronadjem sve TODO linije u *jednom* java projektu. Ali evo sad moze da radi i sa regularnim izrazima (al je malcice spor onda ![]() Kod: import os
print "GREP like search" print "Prilagodjeno tupavim korisnicima windowsa" fold = raw_input( "Koji folder zelite da pretrazite? (trenutni) " ) if fold=="": fold = './' rek = raw_input(" Zelite li rekurzivno trazenje? (D/n)").lower() if rek=="d": rek=True else: rek=False patt = int(raw_input(""" Koju vrstu uporedjivanja zelite? \t1. Pocetak linije \t2. Kraj linije \t3. Podstring linije \t4. regexp (default: 3) ? """)) strs = [] print "ok, sad unesite uslove (npr TODO pa onda FIXME)" while 1: u = raw_input("?") if u=="": break strs.append(u) exts = [] print "unesite ekstenzije (.nestho)" while 1: u = raw_input("?") if u=="": break exts.append(u) def match_start(line): global strs r=[] for st in strs: if line.startswith(st): r.append(st) return r def match_end(line): global strs r=[] for st in strs: if line.endswith(st): r.append(st) return r def match_in(line): global strs r=[] for st in strs: if st in line: r.append(st) return r import re def match_re(line): r=[] for reg in strs: if re.match(reg,line): r.append(reg) return r matchfun = { 1:match_start, 2:match_end, 3:match_in, 4:match_re }[patt] for p,ds,fs in os.walk('./src',rek): print p for f in fs: i = f.rfind('.') if i<0: continue if f[i:] not in exts: continue fpath = os.path.join(p,f) fp=file(fpath,'r') currentline=0 for line in fp: line=line.strip() currentline+=1 r = matchfun(line) if len(r)==0: continue print "\tU fajlu", fpath, "linija %d \n\t%s\n\t" % (currentline, line),"odgovara uslovima: " for m in r: print '\t',m, fp.close() Ona onako radi, malo sam je doradjivao danas, (tj juce uvece ![]() Btw, u vezi onog gore programa, "degeneratora", ma odlican je on!.. Ako si genetski inze/injer. I ako ti se potrefi da ti program proradi, err. Bug sam popravio, ali josh uvijek nestho ne valja. Malko sam studirao jednu knjigu iz koje sam naucio taj isti algoritam i shvatio sam da je greska do knjige. Izgleda da je i algoritam u knjizi nepotpun. Ali cesto program radi (u slucajevima kad se zaista koristi genetsk kod), medjutim nije 100% pouzdan. ba |
Autoru: | che.guevara [ 17 Avg 2005, 00:25 ] |
Tema posta: | |
E bash sam spetljao stvar sa ovim zadnjim programom. Al bash ne radi. Skroz sam uprskao. To cu opet iz pocetka... A za danas imam slijedece: Program koji prikazuje zauzece prostora po extenzijama fajlova Svrha: Interesuje vas gdje vam je otishao prostor sa diska? Ovaj mali program ce vam ispisati kratke statisticke podatke, a najvaznije je to sto sortira zauzece po ekstenzijama fajlova. Tako mozete saznati da li vam prostor jedu filmovi, muzika, source (!?) ili nesto cetvrto ... Evo i koda: Kod: ulaz = raw_input("Ime polaznog direktorijuma ? (trenutni) ")
if len(ulaz): pocetna_putanja = ulaz else: pocetna_putanja = "." ulaz = raw_input("Unesite velicinu najmanje jedinice. \nOvo je velicina praznog fajla na disku. \nUobicajena vrijednost je 16KB. ? (16) ") if len(ulaz): velicina_klastera = int(ulaz) else: velicina_klastera = 16 import os from stat import * ekstenzije = {} #extenzija => [broj_fajlova, realno_zauzece, zauzece_na_disku] for putanja, direktorijumi, fajlovi in os.walk(pocetna_putanja): for fajl in fajlovi: orgfajl, fajl = fajl, fajl.lower() ima_ekstenziju = fajl.rfind(".") velicina_u_KB = long(os.stat(os.path.join(putanja, orgfajl))[ST_SIZE] / 1024) if velicina_u_KB % velicina_klastera == 0: velicina_u_KB_na_disku = velicina_u_KB else: velicina_u_KB_na_disku = (velicina_u_KB / velicina_klastera + 1) * velicina_klastera if ima_ekstenziju: ekstenzija = fajl[ima_ekstenziju:] else: ekstenzija = "" statistika = ekstenzije.get(ekstenzija, [0,0,0]) # num, size, realsize statistika[0] += 1 statistika[1] += velicina_u_KB statistika[2] += velicina_u_KB_na_disku ekstenzije[ekstenzija] = statistika print "EXTENZIJA - BROJ FAJLOVA - VELICINA - VELICINA NA DISKU (KB)" for ekstenzija in ekstenzije: statistika = [str(item).ljust(10) for item in ekstenzije[ekstenzija]] print ekstenzija print statistika[0], statistika[1], statistika[2] Ovo je privremena verzija, nisam je pročistio ... Biće uskoro ... Eto testirajte ako vam treba. |
Autoru: | che.guevara [ 18 Avg 2005, 16:50 ] |
Tema posta: | |
Ekstra Српски Слободан Софтвер ![]() Зашто постоји бијела боја када се не види на овој подлози !?? МОДЕРАТОР ! Ej ljudi napravio sam od ove zeze baš fin program. Evo da pogledate, idite na ovu stranicu tamo imate zip fajl sa programom i screen shot čisto da vidite kako izgleda stvar ... http://toroman.tollfreepage.com/zauzece ... tenzijama/ ![]() Komentari plz ? Hm, ja sam zadovoljan ![]() |
Autoru: | Frenki [ 19 Avg 2005, 09:05 ] |
Tema posta: | |
a kako da to pokrene ko nema pyton ? |
Autoru: | che.guevara [ 19 Avg 2005, 23:13 ] |
Tema posta: | |
* Squall * je napisao: a kako da to pokrene ko nema pyton ?
Pishe se Python. A cita se Pejton ili Pajton. Neki ga citaju i Piton ali Python je ipak ime dobio po covjeku a ne po zmiji. E, dakle, tesko da bi radilo na kurblu, jel tako? Dakle, sta ti fali da skinesh python i te gtk zavrzlame? Python je 10 MB, GTK sa GIMP-om (odlican program za slike) oko 15 MB i pygtk je nesto minorno, recimo 2 MB. A sve vishe programa zavisi od ovoga ... Pogotovo od pythona, odlican je, ma najbolji ![]() |
Stranica 1 od 1 | Sva vremena su u UTC [ DST ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |