]> git.ipfire.org Git - ipfire.org.git/commitdiff
Merge branch 'next'
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 29 Jan 2010 16:42:28 +0000 (17:42 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 29 Jan 2010 16:42:28 +0000 (17:42 +0100)
Conflicts:

www/info.json
www/news.json
www/pages/static/ancient_download.xml
www/pages/static/cebit.xml
www/pages/static/download.xml

585 files changed:
www/banners.json
www/favicon.ico [deleted file]
www/images/buttons/cebit_96x320.png [deleted file]
www/images/buttons/download_core_96x320.png [deleted file]
www/images/tux_menu_99x100.png [deleted file]
www/include/jquery-ui.min.js [deleted symlink]
www/include/jquery.alternate.min.js [deleted file]
www/include/jquery.min.js [deleted symlink]
www/include/jquery.tablesorter.min.js [deleted file]
www/info.json
www/ipfire.py [deleted file]
www/menu.json
www/mirrors.json [new file with mode: 0644]
www/news.json
www/pages/builds.py [deleted file]
www/pages/cluster.py [deleted file]
www/pages/source.py [deleted file]
www/pages/static/__init__.py [deleted file]
www/pages/static/ancient_download.xml [deleted file]
www/pages/static/cebit.xml [deleted file]
www/pages/static/development.xml [deleted file]
www/pages/static/download.xml [deleted file]
www/pages/static/imprint.xml [deleted file]
www/pages/static/index.xml [deleted file]
www/pages/static/links.xml [deleted file]
www/pages/static/news.xml [deleted file]
www/pages/static/screenshots.xml [deleted file]
www/pages/torrent/__init__.py [deleted file]
www/pages/torrent/client/ConfigDir.py [deleted file]
www/pages/torrent/client/ConfigReader.py [deleted file]
www/pages/torrent/client/ConnChoice.py [deleted file]
www/pages/torrent/client/CreateIcons.py [deleted file]
www/pages/torrent/client/CurrentRateMeasure.py [deleted file]
www/pages/torrent/client/HTTPHandler.py [deleted file]
www/pages/torrent/client/PSYCO.py [deleted file]
www/pages/torrent/client/RateLimiter.py [deleted file]
www/pages/torrent/client/RateMeasure.py [deleted file]
www/pages/torrent/client/RawServer.py [deleted file]
www/pages/torrent/client/ServerPortHandler.py [deleted file]
www/pages/torrent/client/SocketHandler.py [deleted file]
www/pages/torrent/client/__init__.py [deleted file]
www/pages/torrent/client/bencode.py [deleted file]
www/pages/torrent/client/bitfield.py [deleted file]
www/pages/torrent/client/clock.py [deleted file]
www/pages/torrent/client/download_bt1.py [deleted file]
www/pages/torrent/client/inifile.py [deleted file]
www/pages/torrent/client/iprangeparse.py [deleted file]
www/pages/torrent/client/launchmanycore.py [deleted file]
www/pages/torrent/client/natpunch.py [deleted file]
www/pages/torrent/client/parseargs.py [deleted file]
www/pages/torrent/client/parsedir.py [deleted file]
www/pages/torrent/client/piecebuffer.py [deleted file]
www/pages/torrent/client/selectpoll.py [deleted file]
www/pages/torrent/client/subnetparse.py [deleted file]
www/pages/torrent/client/torrentlistparse.py [deleted file]
www/pages/torrent/client/zurllib.py [deleted file]
www/pages/translate/__init__.py [deleted file]
www/releases.json [new file with mode: 0644]
www/rpc.py [deleted file]
www/rpc_functions.py [deleted file]
www/rss.inc [deleted file]
www/static/css/ie6.css [moved from www/include/ie6.css with 100% similarity]
www/static/css/style.css [moved from www/include/style.css with 79% similarity]
www/static/favicon.ico [new file with mode: 0644]
www/static/images/Network-1.png [moved from www/images/Network-1.png with 100% similarity]
www/static/images/Stats1.png [moved from www/images/Stats1.png with 100% similarity]
www/static/images/Stats2.png [moved from www/images/Stats2.png with 100% similarity]
www/static/images/aktinet_logo.jpg [new file with mode: 0644]
www/static/images/art/Banner.png [moved from www/images/art/Banner.png with 100% similarity]
www/static/images/art/Banner_thumb.png [moved from www/images/art/Banner_thumb.png with 100% similarity]
www/static/images/art/CD1.png [moved from www/images/art/CD1.png with 100% similarity]
www/static/images/art/CD1_thumb.png [moved from www/images/art/CD1_thumb.png with 100% similarity]
www/static/images/art/CD2.png [moved from www/images/art/CD2.png with 100% similarity]
www/static/images/art/CD2_thumb.png [moved from www/images/art/CD2_thumb.png with 100% similarity]
www/static/images/art/Firetest1.png [moved from www/images/art/Firetest1.png with 100% similarity]
www/static/images/art/Tux.png [moved from www/images/art/Tux.png with 100% similarity]
www/static/images/art/Tux_thumb.png [moved from www/images/art/Tux_thumb.png with 100% similarity]
www/static/images/art/logo2.png [moved from www/images/art/logo2.png with 100% similarity]
www/static/images/bg-menu99.png [moved from www/images/bg-menu99.png with 100% similarity]
www/static/images/bg-shl.png [moved from www/images/bg-shl.png with 100% similarity]
www/static/images/bg-shr.png [moved from www/images/bg-shr.png with 100% similarity]
www/static/images/bg.png [moved from www/images/bg.png with 100% similarity]
www/static/images/bg1.png [moved from www/images/bg1.png with 100% similarity]
www/static/images/bittorrent.png [new file with mode: 0644]
www/static/images/box_ipfire.png [moved from www/images/box_ipfire.png with 100% similarity]
www/static/images/btn-blue.png [moved from www/images/btn-blue.png with 100% similarity]
www/static/images/btn-break.png [moved from www/images/btn-break.png with 100% similarity]
www/static/images/btn-empty.png [moved from www/images/btn-empty.png with 100% similarity]
www/static/images/btn-green.png [moved from www/images/btn-green.png with 100% similarity]
www/static/images/btn-orange.png [moved from www/images/btn-orange.png with 100% similarity]
www/static/images/btn-red.png [moved from www/images/btn-red.png with 100% similarity]
www/static/images/btn-red2.png [moved from www/images/btn-red2.png with 100% similarity]
www/static/images/btn-white.png [moved from www/images/btn-white.png with 100% similarity]
www/static/images/btn-yellow.png [moved from www/images/btn-yellow.png with 100% similarity]
www/static/images/buttons/cebit_96x320.png [new file with mode: 0644]
www/static/images/buttons/download_core_96x320.png [new file with mode: 0644]
www/static/images/cebit-171px.png [moved from www/images/cebit-171px.png with 100% similarity]
www/static/images/cebit-177px_schatten.png [moved from www/images/cebit-177px_schatten.png with 100% similarity]
www/static/images/cebit2010_logo_en.png [moved from www/images/cebit2010_logo_en.png with 100% similarity]
www/static/images/de.gif [moved from www/images/de.gif with 100% similarity]
www/static/images/development.png [moved from www/images/development.png with 100% similarity]
www/static/images/download.png [moved from www/images/download.png with 100% similarity]
www/static/images/download_button.png [new file with mode: 0644]
www/static/images/download_type_alix.png [new file with mode: 0644]
www/static/images/download_type_flash.png [new file with mode: 0644]
www/static/images/download_type_iso.png [new file with mode: 0644]
www/static/images/download_type_torrent.png [new file with mode: 0644]
www/static/images/download_type_usbfdd.png [new file with mode: 0644]
www/static/images/download_type_usbhdd.png [new file with mode: 0644]
www/static/images/download_type_xen.png [new file with mode: 0644]
www/static/images/en.gif [moved from www/images/en.gif with 100% similarity]
www/static/images/error/403.png [moved from www/images/error/403.png with 100% similarity]
www/static/images/error/404.png [moved from www/images/error/404.png with 100% similarity]
www/static/images/error/500.png [moved from www/images/error/500.png with 100% similarity]
www/static/images/features.png [moved from www/images/features.png with 100% similarity]
www/static/images/feed.png [moved from www/images/feed.png with 100% similarity]
www/static/images/flags/ad.png [moved from www/images/flags/ad.png with 100% similarity]
www/static/images/flags/ae.png [moved from www/images/flags/ae.png with 100% similarity]
www/static/images/flags/af.png [moved from www/images/flags/af.png with 100% similarity]
www/static/images/flags/ag.png [moved from www/images/flags/ag.png with 100% similarity]
www/static/images/flags/ai.png [moved from www/images/flags/ai.png with 100% similarity]
www/static/images/flags/al.png [moved from www/images/flags/al.png with 100% similarity]
www/static/images/flags/am.png [moved from www/images/flags/am.png with 100% similarity]
www/static/images/flags/an.png [moved from www/images/flags/an.png with 100% similarity]
www/static/images/flags/ao.png [moved from www/images/flags/ao.png with 100% similarity]
www/static/images/flags/ar.png [moved from www/images/flags/ar.png with 100% similarity]
www/static/images/flags/as.png [moved from www/images/flags/as.png with 100% similarity]
www/static/images/flags/at.png [moved from www/images/flags/at.png with 100% similarity]
www/static/images/flags/au.png [moved from www/images/flags/au.png with 100% similarity]
www/static/images/flags/aw.png [moved from www/images/flags/aw.png with 100% similarity]
www/static/images/flags/ax.png [moved from www/images/flags/ax.png with 100% similarity]
www/static/images/flags/az.png [moved from www/images/flags/az.png with 100% similarity]
www/static/images/flags/ba.png [moved from www/images/flags/ba.png with 100% similarity]
www/static/images/flags/bb.png [moved from www/images/flags/bb.png with 100% similarity]
www/static/images/flags/bd.png [moved from www/images/flags/bd.png with 100% similarity]
www/static/images/flags/be.png [moved from www/images/flags/be.png with 100% similarity]
www/static/images/flags/bf.png [moved from www/images/flags/bf.png with 100% similarity]
www/static/images/flags/bg.png [moved from www/images/flags/bg.png with 100% similarity]
www/static/images/flags/bh.png [moved from www/images/flags/bh.png with 100% similarity]
www/static/images/flags/bi.png [moved from www/images/flags/bi.png with 100% similarity]
www/static/images/flags/bj.png [moved from www/images/flags/bj.png with 100% similarity]
www/static/images/flags/bm.png [moved from www/images/flags/bm.png with 100% similarity]
www/static/images/flags/bn.png [moved from www/images/flags/bn.png with 100% similarity]
www/static/images/flags/bo.png [moved from www/images/flags/bo.png with 100% similarity]
www/static/images/flags/br.png [moved from www/images/flags/br.png with 100% similarity]
www/static/images/flags/bs.png [moved from www/images/flags/bs.png with 100% similarity]
www/static/images/flags/bt.png [moved from www/images/flags/bt.png with 100% similarity]
www/static/images/flags/bv.png [moved from www/images/flags/bv.png with 100% similarity]
www/static/images/flags/bw.png [moved from www/images/flags/bw.png with 100% similarity]
www/static/images/flags/by.png [moved from www/images/flags/by.png with 100% similarity]
www/static/images/flags/bz.png [moved from www/images/flags/bz.png with 100% similarity]
www/static/images/flags/ca.png [moved from www/images/flags/ca.png with 100% similarity]
www/static/images/flags/catalonia.png [moved from www/images/flags/catalonia.png with 100% similarity]
www/static/images/flags/cc.png [moved from www/images/flags/cc.png with 100% similarity]
www/static/images/flags/cd.png [moved from www/images/flags/cd.png with 100% similarity]
www/static/images/flags/cf.png [moved from www/images/flags/cf.png with 100% similarity]
www/static/images/flags/cg.png [moved from www/images/flags/cg.png with 100% similarity]
www/static/images/flags/ch.png [moved from www/images/flags/ch.png with 100% similarity]
www/static/images/flags/ci.png [moved from www/images/flags/ci.png with 100% similarity]
www/static/images/flags/ck.png [moved from www/images/flags/ck.png with 100% similarity]
www/static/images/flags/cl.png [moved from www/images/flags/cl.png with 100% similarity]
www/static/images/flags/cm.png [moved from www/images/flags/cm.png with 100% similarity]
www/static/images/flags/cn.png [moved from www/images/flags/cn.png with 100% similarity]
www/static/images/flags/co.png [moved from www/images/flags/co.png with 100% similarity]
www/static/images/flags/cr.png [moved from www/images/flags/cr.png with 100% similarity]
www/static/images/flags/cs.png [moved from www/images/flags/cs.png with 100% similarity]
www/static/images/flags/cu.png [moved from www/images/flags/cu.png with 100% similarity]
www/static/images/flags/cv.png [moved from www/images/flags/cv.png with 100% similarity]
www/static/images/flags/cx.png [moved from www/images/flags/cx.png with 100% similarity]
www/static/images/flags/cy.png [moved from www/images/flags/cy.png with 100% similarity]
www/static/images/flags/cz.png [moved from www/images/flags/cz.png with 100% similarity]
www/static/images/flags/da.png [moved from www/images/flags/da.png with 100% similarity]
www/static/images/flags/de.png [moved from www/images/flags/de.png with 100% similarity]
www/static/images/flags/dj.png [moved from www/images/flags/dj.png with 100% similarity]
www/static/images/flags/dk.png [moved from www/images/flags/dk.png with 100% similarity]
www/static/images/flags/dm.png [moved from www/images/flags/dm.png with 100% similarity]
www/static/images/flags/do.png [moved from www/images/flags/do.png with 100% similarity]
www/static/images/flags/dz.png [moved from www/images/flags/dz.png with 100% similarity]
www/static/images/flags/ec.png [moved from www/images/flags/ec.png with 100% similarity]
www/static/images/flags/ee.png [moved from www/images/flags/ee.png with 100% similarity]
www/static/images/flags/eg.png [moved from www/images/flags/eg.png with 100% similarity]
www/static/images/flags/eh.png [moved from www/images/flags/eh.png with 100% similarity]
www/static/images/flags/england.png [moved from www/images/flags/england.png with 100% similarity]
www/static/images/flags/er.png [moved from www/images/flags/er.png with 100% similarity]
www/static/images/flags/es.png [moved from www/images/flags/es.png with 100% similarity]
www/static/images/flags/et.png [moved from www/images/flags/et.png with 100% similarity]
www/static/images/flags/europeanunion.png [moved from www/images/flags/europeanunion.png with 100% similarity]
www/static/images/flags/fam.png [moved from www/images/flags/fam.png with 100% similarity]
www/static/images/flags/fi.png [moved from www/images/flags/fi.png with 100% similarity]
www/static/images/flags/fj.png [moved from www/images/flags/fj.png with 100% similarity]
www/static/images/flags/fk.png [moved from www/images/flags/fk.png with 100% similarity]
www/static/images/flags/fm.png [moved from www/images/flags/fm.png with 100% similarity]
www/static/images/flags/fo.png [moved from www/images/flags/fo.png with 100% similarity]
www/static/images/flags/fr.png [moved from www/images/flags/fr.png with 100% similarity]
www/static/images/flags/ga.png [moved from www/images/flags/ga.png with 100% similarity]
www/static/images/flags/gb.png [moved from www/images/flags/gb.png with 100% similarity]
www/static/images/flags/gd.png [moved from www/images/flags/gd.png with 100% similarity]
www/static/images/flags/ge.png [moved from www/images/flags/ge.png with 100% similarity]
www/static/images/flags/gf.png [moved from www/images/flags/gf.png with 100% similarity]
www/static/images/flags/gh.png [moved from www/images/flags/gh.png with 100% similarity]
www/static/images/flags/gi.png [moved from www/images/flags/gi.png with 100% similarity]
www/static/images/flags/gl.png [moved from www/images/flags/gl.png with 100% similarity]
www/static/images/flags/gm.png [moved from www/images/flags/gm.png with 100% similarity]
www/static/images/flags/gn.png [moved from www/images/flags/gn.png with 100% similarity]
www/static/images/flags/gp.png [moved from www/images/flags/gp.png with 100% similarity]
www/static/images/flags/gq.png [moved from www/images/flags/gq.png with 100% similarity]
www/static/images/flags/gr.png [moved from www/images/flags/gr.png with 100% similarity]
www/static/images/flags/gs.png [moved from www/images/flags/gs.png with 100% similarity]
www/static/images/flags/gt.png [moved from www/images/flags/gt.png with 100% similarity]
www/static/images/flags/gu.png [moved from www/images/flags/gu.png with 100% similarity]
www/static/images/flags/gw.png [moved from www/images/flags/gw.png with 100% similarity]
www/static/images/flags/gy.png [moved from www/images/flags/gy.png with 100% similarity]
www/static/images/flags/hk.png [moved from www/images/flags/hk.png with 100% similarity]
www/static/images/flags/hm.png [moved from www/images/flags/hm.png with 100% similarity]
www/static/images/flags/hn.png [moved from www/images/flags/hn.png with 100% similarity]
www/static/images/flags/hr.png [moved from www/images/flags/hr.png with 100% similarity]
www/static/images/flags/ht.png [moved from www/images/flags/ht.png with 100% similarity]
www/static/images/flags/hu.png [moved from www/images/flags/hu.png with 100% similarity]
www/static/images/flags/id.png [moved from www/images/flags/id.png with 100% similarity]
www/static/images/flags/ie.png [moved from www/images/flags/ie.png with 100% similarity]
www/static/images/flags/il.png [moved from www/images/flags/il.png with 100% similarity]
www/static/images/flags/in.png [moved from www/images/flags/in.png with 100% similarity]
www/static/images/flags/io.png [moved from www/images/flags/io.png with 100% similarity]
www/static/images/flags/iq.png [moved from www/images/flags/iq.png with 100% similarity]
www/static/images/flags/ir.png [moved from www/images/flags/ir.png with 100% similarity]
www/static/images/flags/is.png [moved from www/images/flags/is.png with 100% similarity]
www/static/images/flags/it.png [moved from www/images/flags/it.png with 100% similarity]
www/static/images/flags/jm.png [moved from www/images/flags/jm.png with 100% similarity]
www/static/images/flags/jo.png [moved from www/images/flags/jo.png with 100% similarity]
www/static/images/flags/jp.png [moved from www/images/flags/jp.png with 100% similarity]
www/static/images/flags/ke.png [moved from www/images/flags/ke.png with 100% similarity]
www/static/images/flags/kg.png [moved from www/images/flags/kg.png with 100% similarity]
www/static/images/flags/kh.png [moved from www/images/flags/kh.png with 100% similarity]
www/static/images/flags/ki.png [moved from www/images/flags/ki.png with 100% similarity]
www/static/images/flags/km.png [moved from www/images/flags/km.png with 100% similarity]
www/static/images/flags/kn.png [moved from www/images/flags/kn.png with 100% similarity]
www/static/images/flags/kp.png [moved from www/images/flags/kp.png with 100% similarity]
www/static/images/flags/kr.png [moved from www/images/flags/kr.png with 100% similarity]
www/static/images/flags/kw.png [moved from www/images/flags/kw.png with 100% similarity]
www/static/images/flags/ky.png [moved from www/images/flags/ky.png with 100% similarity]
www/static/images/flags/kz.png [moved from www/images/flags/kz.png with 100% similarity]
www/static/images/flags/la.png [moved from www/images/flags/la.png with 100% similarity]
www/static/images/flags/lb.png [moved from www/images/flags/lb.png with 100% similarity]
www/static/images/flags/lc.png [moved from www/images/flags/lc.png with 100% similarity]
www/static/images/flags/li.png [moved from www/images/flags/li.png with 100% similarity]
www/static/images/flags/lk.png [moved from www/images/flags/lk.png with 100% similarity]
www/static/images/flags/lr.png [moved from www/images/flags/lr.png with 100% similarity]
www/static/images/flags/ls.png [moved from www/images/flags/ls.png with 100% similarity]
www/static/images/flags/lt.png [moved from www/images/flags/lt.png with 100% similarity]
www/static/images/flags/lu.png [moved from www/images/flags/lu.png with 100% similarity]
www/static/images/flags/lv.png [moved from www/images/flags/lv.png with 100% similarity]
www/static/images/flags/ly.png [moved from www/images/flags/ly.png with 100% similarity]
www/static/images/flags/ma.png [moved from www/images/flags/ma.png with 100% similarity]
www/static/images/flags/mc.png [moved from www/images/flags/mc.png with 100% similarity]
www/static/images/flags/md.png [moved from www/images/flags/md.png with 100% similarity]
www/static/images/flags/me.png [moved from www/images/flags/me.png with 100% similarity]
www/static/images/flags/mg.png [moved from www/images/flags/mg.png with 100% similarity]
www/static/images/flags/mh.png [moved from www/images/flags/mh.png with 100% similarity]
www/static/images/flags/mk.png [moved from www/images/flags/mk.png with 100% similarity]
www/static/images/flags/ml.png [moved from www/images/flags/ml.png with 100% similarity]
www/static/images/flags/mm.png [moved from www/images/flags/mm.png with 100% similarity]
www/static/images/flags/mn.png [moved from www/images/flags/mn.png with 100% similarity]
www/static/images/flags/mo.png [moved from www/images/flags/mo.png with 100% similarity]
www/static/images/flags/mp.png [moved from www/images/flags/mp.png with 100% similarity]
www/static/images/flags/mq.png [moved from www/images/flags/mq.png with 100% similarity]
www/static/images/flags/mr.png [moved from www/images/flags/mr.png with 100% similarity]
www/static/images/flags/ms.png [moved from www/images/flags/ms.png with 100% similarity]
www/static/images/flags/mt.png [moved from www/images/flags/mt.png with 100% similarity]
www/static/images/flags/mu.png [moved from www/images/flags/mu.png with 100% similarity]
www/static/images/flags/mv.png [moved from www/images/flags/mv.png with 100% similarity]
www/static/images/flags/mw.png [moved from www/images/flags/mw.png with 100% similarity]
www/static/images/flags/mx.png [moved from www/images/flags/mx.png with 100% similarity]
www/static/images/flags/my.png [moved from www/images/flags/my.png with 100% similarity]
www/static/images/flags/mz.png [moved from www/images/flags/mz.png with 100% similarity]
www/static/images/flags/na.png [moved from www/images/flags/na.png with 100% similarity]
www/static/images/flags/nc.png [moved from www/images/flags/nc.png with 100% similarity]
www/static/images/flags/ne.png [moved from www/images/flags/ne.png with 100% similarity]
www/static/images/flags/nf.png [moved from www/images/flags/nf.png with 100% similarity]
www/static/images/flags/ng.png [moved from www/images/flags/ng.png with 100% similarity]
www/static/images/flags/ni.png [moved from www/images/flags/ni.png with 100% similarity]
www/static/images/flags/nl.png [moved from www/images/flags/nl.png with 100% similarity]
www/static/images/flags/no.png [moved from www/images/flags/no.png with 100% similarity]
www/static/images/flags/np.png [moved from www/images/flags/np.png with 100% similarity]
www/static/images/flags/nr.png [moved from www/images/flags/nr.png with 100% similarity]
www/static/images/flags/nu.png [moved from www/images/flags/nu.png with 100% similarity]
www/static/images/flags/nz.png [moved from www/images/flags/nz.png with 100% similarity]
www/static/images/flags/om.png [moved from www/images/flags/om.png with 100% similarity]
www/static/images/flags/pa.png [moved from www/images/flags/pa.png with 100% similarity]
www/static/images/flags/pe.png [moved from www/images/flags/pe.png with 100% similarity]
www/static/images/flags/pf.png [moved from www/images/flags/pf.png with 100% similarity]
www/static/images/flags/pg.png [moved from www/images/flags/pg.png with 100% similarity]
www/static/images/flags/ph.png [moved from www/images/flags/ph.png with 100% similarity]
www/static/images/flags/pk.png [moved from www/images/flags/pk.png with 100% similarity]
www/static/images/flags/pl.png [moved from www/images/flags/pl.png with 100% similarity]
www/static/images/flags/pm.png [moved from www/images/flags/pm.png with 100% similarity]
www/static/images/flags/pn.png [moved from www/images/flags/pn.png with 100% similarity]
www/static/images/flags/pr.png [moved from www/images/flags/pr.png with 100% similarity]
www/static/images/flags/ps.png [moved from www/images/flags/ps.png with 100% similarity]
www/static/images/flags/pt.png [moved from www/images/flags/pt.png with 100% similarity]
www/static/images/flags/pw.png [moved from www/images/flags/pw.png with 100% similarity]
www/static/images/flags/py.png [moved from www/images/flags/py.png with 100% similarity]
www/static/images/flags/qa.png [moved from www/images/flags/qa.png with 100% similarity]
www/static/images/flags/re.png [moved from www/images/flags/re.png with 100% similarity]
www/static/images/flags/ro.png [moved from www/images/flags/ro.png with 100% similarity]
www/static/images/flags/rs.png [moved from www/images/flags/rs.png with 100% similarity]
www/static/images/flags/ru.png [moved from www/images/flags/ru.png with 100% similarity]
www/static/images/flags/rw.png [moved from www/images/flags/rw.png with 100% similarity]
www/static/images/flags/sa.png [moved from www/images/flags/sa.png with 100% similarity]
www/static/images/flags/sb.png [moved from www/images/flags/sb.png with 100% similarity]
www/static/images/flags/sc.png [moved from www/images/flags/sc.png with 100% similarity]
www/static/images/flags/scotland.png [moved from www/images/flags/scotland.png with 100% similarity]
www/static/images/flags/sd.png [moved from www/images/flags/sd.png with 100% similarity]
www/static/images/flags/se.png [moved from www/images/flags/se.png with 100% similarity]
www/static/images/flags/sg.png [moved from www/images/flags/sg.png with 100% similarity]
www/static/images/flags/sh.png [moved from www/images/flags/sh.png with 100% similarity]
www/static/images/flags/si.png [moved from www/images/flags/si.png with 100% similarity]
www/static/images/flags/sj.png [moved from www/images/flags/sj.png with 100% similarity]
www/static/images/flags/sk.png [moved from www/images/flags/sk.png with 100% similarity]
www/static/images/flags/sl.png [moved from www/images/flags/sl.png with 100% similarity]
www/static/images/flags/sm.png [moved from www/images/flags/sm.png with 100% similarity]
www/static/images/flags/sn.png [moved from www/images/flags/sn.png with 100% similarity]
www/static/images/flags/so.png [moved from www/images/flags/so.png with 100% similarity]
www/static/images/flags/sr.png [moved from www/images/flags/sr.png with 100% similarity]
www/static/images/flags/st.png [moved from www/images/flags/st.png with 100% similarity]
www/static/images/flags/sv.png [moved from www/images/flags/sv.png with 100% similarity]
www/static/images/flags/sy.png [moved from www/images/flags/sy.png with 100% similarity]
www/static/images/flags/sz.png [moved from www/images/flags/sz.png with 100% similarity]
www/static/images/flags/tc.png [moved from www/images/flags/tc.png with 100% similarity]
www/static/images/flags/td.png [moved from www/images/flags/td.png with 100% similarity]
www/static/images/flags/tf.png [moved from www/images/flags/tf.png with 100% similarity]
www/static/images/flags/tg.png [moved from www/images/flags/tg.png with 100% similarity]
www/static/images/flags/th.png [moved from www/images/flags/th.png with 100% similarity]
www/static/images/flags/tj.png [moved from www/images/flags/tj.png with 100% similarity]
www/static/images/flags/tk.png [moved from www/images/flags/tk.png with 100% similarity]
www/static/images/flags/tl.png [moved from www/images/flags/tl.png with 100% similarity]
www/static/images/flags/tm.png [moved from www/images/flags/tm.png with 100% similarity]
www/static/images/flags/tn.png [moved from www/images/flags/tn.png with 100% similarity]
www/static/images/flags/to.png [moved from www/images/flags/to.png with 100% similarity]
www/static/images/flags/tr.png [moved from www/images/flags/tr.png with 100% similarity]
www/static/images/flags/tt.png [moved from www/images/flags/tt.png with 100% similarity]
www/static/images/flags/tv.png [moved from www/images/flags/tv.png with 100% similarity]
www/static/images/flags/tw.png [moved from www/images/flags/tw.png with 100% similarity]
www/static/images/flags/tz.png [moved from www/images/flags/tz.png with 100% similarity]
www/static/images/flags/ua.png [moved from www/images/flags/ua.png with 100% similarity]
www/static/images/flags/ug.png [moved from www/images/flags/ug.png with 100% similarity]
www/static/images/flags/um.png [moved from www/images/flags/um.png with 100% similarity]
www/static/images/flags/us.png [moved from www/images/flags/us.png with 100% similarity]
www/static/images/flags/uy.png [moved from www/images/flags/uy.png with 100% similarity]
www/static/images/flags/uz.png [moved from www/images/flags/uz.png with 100% similarity]
www/static/images/flags/va.png [moved from www/images/flags/va.png with 100% similarity]
www/static/images/flags/vc.png [moved from www/images/flags/vc.png with 100% similarity]
www/static/images/flags/ve.png [moved from www/images/flags/ve.png with 100% similarity]
www/static/images/flags/vg.png [moved from www/images/flags/vg.png with 100% similarity]
www/static/images/flags/vi.png [moved from www/images/flags/vi.png with 100% similarity]
www/static/images/flags/vn.png [moved from www/images/flags/vn.png with 100% similarity]
www/static/images/flags/vu.png [moved from www/images/flags/vu.png with 100% similarity]
www/static/images/flags/wales.png [moved from www/images/flags/wales.png with 100% similarity]
www/static/images/flags/wf.png [moved from www/images/flags/wf.png with 100% similarity]
www/static/images/flags/ws.png [moved from www/images/flags/ws.png with 100% similarity]
www/static/images/flags/ye.png [moved from www/images/flags/ye.png with 100% similarity]
www/static/images/flags/yt.png [moved from www/images/flags/yt.png with 100% similarity]
www/static/images/flags/za.png [moved from www/images/flags/za.png with 100% similarity]
www/static/images/flags/zm.png [moved from www/images/flags/zm.png with 100% similarity]
www/static/images/flags/zw.png [moved from www/images/flags/zw.png with 100% similarity]
www/static/images/ft.png [moved from www/images/ft.png with 100% similarity]
www/static/images/icons/ipfire.png [moved from www/images/icons/ipfire.png with 100% similarity]
www/static/images/icons/ipfire_sw.png [moved from www/images/icons/ipfire_sw.png with 100% similarity]
www/static/images/ipfire_download.png [new file with mode: 0644]
www/static/images/lf1.png [moved from www/images/lf1.png with 100% similarity]
www/static/images/lf2.png [moved from www/images/lf2.png with 100% similarity]
www/static/images/lf3.png [moved from www/images/lf3.png with 100% similarity]
www/static/images/lightbox/lightbox-blank.gif [moved from www/images/lightbox/lightbox-blank.gif with 100% similarity]
www/static/images/lightbox/lightbox-btn-close.gif [moved from www/images/lightbox/lightbox-btn-close.gif with 100% similarity]
www/static/images/lightbox/lightbox-btn-next.gif [moved from www/images/lightbox/lightbox-btn-next.gif with 100% similarity]
www/static/images/lightbox/lightbox-btn-prev.gif [moved from www/images/lightbox/lightbox-btn-prev.gif with 100% similarity]
www/static/images/lightbox/lightbox-ico-loading.gif [moved from www/images/lightbox/lightbox-ico-loading.gif with 100% similarity]
www/static/images/links.png [moved from www/images/links.png with 100% similarity]
www/static/images/linux_icon.png [moved from www/images/linux_icon.png with 100% similarity]
www/static/images/linux_new_media_ag.jpg [moved from www/images/linux_new_media_ag.jpg with 100% similarity]
www/static/images/logo.png [moved from www/images/logo.png with 100% similarity]
www/static/images/mac_icon.png [moved from www/images/mac_icon.png with 100% similarity]
www/static/images/mnu2l.png [moved from www/images/mnu2l.png with 100% similarity]
www/static/images/mnu2r.png [moved from www/images/mnu2r.png with 100% similarity]
www/static/images/mnu2t1.png [moved from www/images/mnu2t1.png with 100% similarity]
www/static/images/mnu2t2.png [moved from www/images/mnu2t2.png with 100% similarity]
www/static/images/n1.gif [moved from www/images/n1.gif with 100% similarity]
www/static/images/n2.gif [moved from www/images/n2.gif with 100% similarity]
www/static/images/n3.gif [moved from www/images/n3.gif with 100% similarity]
www/static/images/n4.gif [moved from www/images/n4.gif with 100% similarity]
www/static/images/n5.gif [moved from www/images/n5.gif with 100% similarity]
www/static/images/n6.gif [moved from www/images/n6.gif with 100% similarity]
www/static/images/page_icons/development.png [new file with mode: 0644]
www/static/images/page_icons/donation.png [new file with mode: 0644]
www/static/images/page_icons/download-all.png [new file with mode: 0644]
www/static/images/page_icons/download-developmemt.png [new file with mode: 0644]
www/static/images/page_icons/download-mirrors.png [new file with mode: 0644]
www/static/images/page_icons/download-mirrors_16.png [new file with mode: 0644]
www/static/images/page_icons/download-torrents.png [new file with mode: 0644]
www/static/images/page_icons/download-torrents_orginal.png [new file with mode: 0644]
www/static/images/page_icons/downloads_torrents.png [new file with mode: 0644]
www/static/images/page_icons/imprint.png [new file with mode: 0644]
www/static/images/page_icons/news.png [new file with mode: 0644]
www/static/images/page_icons/pr.png [new file with mode: 0644]
www/static/images/page_icons/screenshots.png [new file with mode: 0644]
www/static/images/page_icons/screenshots_orginal.png [new file with mode: 0644]
www/static/images/paypal-folder.png [moved from www/images/paypal-folder.png with 100% similarity]
www/static/images/pic.gif [moved from www/images/pic.gif with 100% similarity]
www/static/images/pic2.png [moved from www/images/pic2.png with 100% similarity]
www/static/images/progressbar.gif [moved from www/images/progressbar.gif with 100% similarity]
www/static/images/progressbg_black.gif [moved from www/images/progressbg_black.gif with 100% similarity]
www/static/images/progressbg_green.gif [moved from www/images/progressbg_green.gif with 100% similarity]
www/static/images/progressbg_orange.gif [moved from www/images/progressbg_orange.gif with 100% similarity]
www/static/images/progressbg_red.gif [moved from www/images/progressbg_red.gif with 100% similarity]
www/static/images/progressbg_yellow.gif [moved from www/images/progressbg_yellow.gif with 100% similarity]
www/static/images/pxe.png [moved from www/images/pxe.png with 100% similarity]
www/static/images/screens/de/final/connsched.png [moved from www/images/screens/de/final/connsched.png with 100% similarity]
www/static/images/screens/de/final/disk.png [moved from www/images/screens/de/final/disk.png with 100% similarity]
www/static/images/screens/de/final/dyndns.png [moved from www/images/screens/de/final/dyndns.png with 100% similarity]
www/static/images/screens/de/final/fwdiag.png [moved from www/images/screens/de/final/fwdiag.png with 100% similarity]
www/static/images/screens/de/final/fwlog-port.png [moved from www/images/screens/de/final/fwlog-port.png with 100% similarity]
www/static/images/screens/de/final/fwlog.png [moved from www/images/screens/de/final/fwlog.png with 100% similarity]
www/static/images/screens/de/final/ids.png [moved from www/images/screens/de/final/ids.png with 100% similarity]
www/static/images/screens/de/final/index.png [moved from www/images/screens/de/final/index.png with 100% similarity]
www/static/images/screens/de/final/ipsec.png [moved from www/images/screens/de/final/ipsec.png with 100% similarity]
www/static/images/screens/de/final/nettraffic.png [moved from www/images/screens/de/final/nettraffic.png with 100% similarity]
www/static/images/screens/de/final/nw-internal.png [moved from www/images/screens/de/final/nw-internal.png with 100% similarity]
www/static/images/screens/de/final/outgoingfw-1.png [moved from www/images/screens/de/final/outgoingfw-1.png with 100% similarity]
www/static/images/screens/de/final/outgoingfw-2.png [moved from www/images/screens/de/final/outgoingfw-2.png with 100% similarity]
www/static/images/screens/de/final/pakfire-1.png [moved from www/images/screens/de/final/pakfire-1.png with 100% similarity]
www/static/images/screens/de/final/pakfire-2.png [moved from www/images/screens/de/final/pakfire-2.png with 100% similarity]
www/static/images/screens/de/final/proxy.png [moved from www/images/screens/de/final/proxy.png with 100% similarity]
www/static/images/screens/de/final/qos-2.png [moved from www/images/screens/de/final/qos-2.png with 100% similarity]
www/static/images/screens/de/final/samba.png [moved from www/images/screens/de/final/samba.png with 100% similarity]
www/static/images/screens/de/final/system.png [moved from www/images/screens/de/final/system.png with 100% similarity]
www/static/images/screens/de/final/thumb/fwlog-port.png [moved from www/images/screens/de/final/thumb/fwlog-port.png with 100% similarity]
www/static/images/screens/de/final/thumb/index.png [moved from www/images/screens/de/final/thumb/index.png with 100% similarity]
www/static/images/screens/de/final/thumb/ipsec.png [moved from www/images/screens/de/final/thumb/ipsec.png with 100% similarity]
www/static/images/screens/de/final/thumb/pakfire-1.png [moved from www/images/screens/de/final/thumb/pakfire-1.png with 100% similarity]
www/static/images/screens/de/final/thumb/proxy.png [moved from www/images/screens/de/final/thumb/proxy.png with 100% similarity]
www/static/images/screens/de/final/thumb/qos-2.png [moved from www/images/screens/de/final/thumb/qos-2.png with 100% similarity]
www/static/images/screens/de/final/thumb/system.png [moved from www/images/screens/de/final/thumb/system.png with 100% similarity]
www/static/images/screens/de/final/xtaccess.png [moved from www/images/screens/de/final/xtaccess.png with 100% similarity]
www/static/images/screenshots/backup_de.png [moved from www/images/screenshots/backup_de.png with 100% similarity]
www/static/images/screenshots/backup_de_tn.png [moved from www/images/screenshots/backup_de_tn.png with 100% similarity]
www/static/images/screenshots/backup_en.png [moved from www/images/screenshots/backup_en.png with 100% similarity]
www/static/images/screenshots/backup_en_tn.png [moved from www/images/screenshots/backup_en_tn.png with 100% similarity]
www/static/images/screenshots/connections_de.png [moved from www/images/screenshots/connections_de.png with 100% similarity]
www/static/images/screenshots/connections_de_tn.png [moved from www/images/screenshots/connections_de_tn.png with 100% similarity]
www/static/images/screenshots/connections_en.png [moved from www/images/screenshots/connections_en.png with 100% similarity]
www/static/images/screenshots/connections_en_tn.png [moved from www/images/screenshots/connections_en_tn.png with 100% similarity]
www/static/images/screenshots/dhcp_de.png [moved from www/images/screenshots/dhcp_de.png with 100% similarity]
www/static/images/screenshots/dhcp_de_tn.png [moved from www/images/screenshots/dhcp_de_tn.png with 100% similarity]
www/static/images/screenshots/dhcp_en.png [moved from www/images/screenshots/dhcp_en.png with 100% similarity]
www/static/images/screenshots/dhcp_en_tn.png [moved from www/images/screenshots/dhcp_en_tn.png with 100% similarity]
www/static/images/screenshots/fwlog_ip_de.png [moved from www/images/screenshots/fwlog_ip_de.png with 100% similarity]
www/static/images/screenshots/fwlog_ip_de_tn.png [moved from www/images/screenshots/fwlog_ip_de_tn.png with 100% similarity]
www/static/images/screenshots/fwlog_ip_en.png [moved from www/images/screenshots/fwlog_ip_en.png with 100% similarity]
www/static/images/screenshots/fwlog_ip_en_tn.png [moved from www/images/screenshots/fwlog_ip_en_tn.png with 100% similarity]
www/static/images/screenshots/index_de.png [moved from www/images/screenshots/index_de.png with 100% similarity]
www/static/images/screenshots/index_de_tn.png [moved from www/images/screenshots/index_de_tn.png with 100% similarity]
www/static/images/screenshots/index_en.png [moved from www/images/screenshots/index_en.png with 100% similarity]
www/static/images/screenshots/index_en_tn.png [moved from www/images/screenshots/index_en_tn.png with 100% similarity]
www/static/images/screenshots/ipsec_de.png [moved from www/images/screenshots/ipsec_de.png with 100% similarity]
www/static/images/screenshots/ipsec_de_tn.png [moved from www/images/screenshots/ipsec_de_tn.png with 100% similarity]
www/static/images/screenshots/ipsec_en.png [moved from www/images/screenshots/ipsec_en.png with 100% similarity]
www/static/images/screenshots/ipsec_en_tn.png [moved from www/images/screenshots/ipsec_en_tn.png with 100% similarity]
www/static/images/screenshots/monitor.png [moved from www/images/screenshots/monitor.png with 100% similarity]
www/static/images/screenshots/networkother_de.png [moved from www/images/screenshots/networkother_de.png with 100% similarity]
www/static/images/screenshots/networkother_de_tn.png [moved from www/images/screenshots/networkother_de_tn.png with 100% similarity]
www/static/images/screenshots/networkother_en.png [moved from www/images/screenshots/networkother_en.png with 100% similarity]
www/static/images/screenshots/networkother_en_tn.png [moved from www/images/screenshots/networkother_en_tn.png with 100% similarity]
www/static/images/screenshots/outgoing_fw_de.png [moved from www/images/screenshots/outgoing_fw_de.png with 100% similarity]
www/static/images/screenshots/outgoing_fw_de_tn.png [moved from www/images/screenshots/outgoing_fw_de_tn.png with 100% similarity]
www/static/images/screenshots/outgoing_fw_en.png [moved from www/images/screenshots/outgoing_fw_en.png with 100% similarity]
www/static/images/screenshots/outgoing_fw_en_tn.png [moved from www/images/screenshots/outgoing_fw_en_tn.png with 100% similarity]
www/static/images/screenshots/pakfire_de.png [moved from www/images/screenshots/pakfire_de.png with 100% similarity]
www/static/images/screenshots/pakfire_de_tn.png [moved from www/images/screenshots/pakfire_de_tn.png with 100% similarity]
www/static/images/screenshots/pakfire_en.png [moved from www/images/screenshots/pakfire_en.png with 100% similarity]
www/static/images/screenshots/pakfire_en_tn.png [moved from www/images/screenshots/pakfire_en_tn.png with 100% similarity]
www/static/images/screenshots/proxy_de.png [moved from www/images/screenshots/proxy_de.png with 100% similarity]
www/static/images/screenshots/proxy_de_tn.png [moved from www/images/screenshots/proxy_de_tn.png with 100% similarity]
www/static/images/screenshots/proxy_en.png [moved from www/images/screenshots/proxy_en.png with 100% similarity]
www/static/images/screenshots/proxy_en_tn.png [moved from www/images/screenshots/proxy_en_tn.png with 100% similarity]
www/static/images/screenshots/qos_de.png [moved from www/images/screenshots/qos_de.png with 100% similarity]
www/static/images/screenshots/qos_de_tn.png [moved from www/images/screenshots/qos_de_tn.png with 100% similarity]
www/static/images/screenshots/qos_en.png [moved from www/images/screenshots/qos_en.png with 100% similarity]
www/static/images/screenshots/qos_en_tn.png [moved from www/images/screenshots/qos_en_tn.png with 100% similarity]
www/static/images/screenshots/samba_de.png [moved from www/images/screenshots/samba_de.png with 100% similarity]
www/static/images/screenshots/samba_de_tn.png [moved from www/images/screenshots/samba_de_tn.png with 100% similarity]
www/static/images/screenshots/samba_en.png [moved from www/images/screenshots/samba_en.png with 100% similarity]
www/static/images/screenshots/samba_en_tn.png [moved from www/images/screenshots/samba_en_tn.png with 100% similarity]
www/static/images/screenshots/services_de.png [moved from www/images/screenshots/services_de.png with 100% similarity]
www/static/images/screenshots/services_de_tn.png [moved from www/images/screenshots/services_de_tn.png with 100% similarity]
www/static/images/screenshots/services_en.png [moved from www/images/screenshots/services_en.png with 100% similarity]
www/static/images/screenshots/services_en_tn.png [moved from www/images/screenshots/services_en_tn.png with 100% similarity]
www/static/images/sh-bl.png [moved from www/images/sh-bl.png with 100% similarity]
www/static/images/sh-br.png [moved from www/images/sh-br.png with 100% similarity]
www/static/images/sh-btn.png [moved from www/images/sh-btn.png with 100% similarity]
www/static/images/sh-lft.png [moved from www/images/sh-lft.png with 100% similarity]
www/static/images/sh-rgt.png [moved from www/images/sh-rgt.png with 100% similarity]
www/static/images/sh-tl.png [moved from www/images/sh-tl.png with 100% similarity]
www/static/images/sh-top.png [moved from www/images/sh-top.png with 100% similarity]
www/static/images/sh-tr.png [moved from www/images/sh-tr.png with 100% similarity]
www/static/images/spacer.gif [moved from www/images/spacer.gif with 100% similarity]
www/static/images/sponsors/isp42.png [moved from www/images/sponsors/isp42.png with 100% similarity]
www/static/images/sponsors/isp42_2.png [moved from www/images/sponsors/isp42_2.png with 100% similarity]
www/static/images/tux.png [moved from www/images/tux.png with 100% similarity]
www/static/images/tux/ipfire_tux_128x128.png [new file with mode: 0644]
www/static/images/tux/ipfire_tux_16x16.png [new file with mode: 0644]
www/static/images/tux/ipfire_tux_256x256.png [new file with mode: 0644]
www/static/images/tux/ipfire_tux_32x32.png [new file with mode: 0644]
www/static/images/tux/ipfire_tux_48x48.png [new file with mode: 0644]
www/static/images/tux/ipfire_tux_512x512.png [new file with mode: 0644]
www/static/images/tux/ipfire_tux_64x64.png [new file with mode: 0644]
www/static/images/tux2-99.png [moved from www/images/tux2-99.png with 100% similarity]
www/static/images/tux2.png [moved from www/images/tux2.png with 100% similarity]
www/static/images/tux_menu_99x100.png [new file with mode: 0644]
www/static/images/ui-bg_flat_75_f5f5f5_40x100.png [moved from www/images/ui-bg_flat_75_f5f5f5_40x100.png with 100% similarity]
www/static/images/ui-bg_glass_75_dadada_1x400.png [moved from www/images/ui-bg_glass_75_dadada_1x400.png with 100% similarity]
www/static/images/ui-bg_glass_75_e6e6e6_1x400.png [moved from www/images/ui-bg_glass_75_e6e6e6_1x400.png with 100% similarity]
www/static/images/ui-bg_highlight-soft_75_cccccc_1x100.png [moved from www/images/ui-bg_highlight-soft_75_cccccc_1x100.png with 100% similarity]
www/static/images/win_icon.png [moved from www/images/win_icon.png with 100% similarity]
www/static/images/x-click-but04.gif [moved from www/images/x-click-but04.gif with 100% similarity]
www/static/js/cluster.js [new file with mode: 0644]
www/static/js/correctpng.js [moved from www/include/correctpng.js with 100% similarity]
www/static/js/jquery-ui.js [moved from www/include/jquery-ui-1.7.2.custom.min.js with 100% similarity]
www/static/js/jquery.js [moved from www/include/jquery-1.3.2.min.js with 100% similarity]
www/static/js/jquery.lightbox.min.js [moved from www/include/jquery.lightbox.min.js with 94% similarity]
www/static/js/jquery.progressbar.js [moved from www/include/jquery.progressbar.min.js with 87% similarity]
www/templates/base.html [moved from www/template.inc with 55% similarity]
www/templates/builds.html [new file with mode: 0644]
www/templates/downloads-all.html [new file with mode: 0644]
www/templates/downloads-development.html [new file with mode: 0644]
www/templates/downloads-mirrors.html [new file with mode: 0644]
www/templates/downloads-torrents.html [new file with mode: 0644]
www/templates/downloads.html [new file with mode: 0644]
www/templates/error-404.html [new file with mode: 0644]
www/templates/error-500.html [new file with mode: 0644]
www/templates/error.html [new file with mode: 0644]
www/templates/index.html [new file with mode: 0644]
www/templates/modules/builds.html [new file with mode: 0644]
www/templates/modules/menu-item.html [new file with mode: 0644]
www/templates/modules/menu.html [new file with mode: 0644]
www/templates/modules/news-item.html [new file with mode: 0644]
www/templates/modules/release-item.html [new file with mode: 0644]
www/templates/modules/sidebar-banner.html [new file with mode: 0644]
www/templates/modules/sidebar-item.html [new file with mode: 0644]
www/templates/modules/sidebar-release.html [new file with mode: 0644]
www/templates/news.html [new file with mode: 0644]
www/templates/sources.html [new file with mode: 0644]
www/templates/static/cebit.html [new file with mode: 0644]
www/templates/static/cluster.html [new file with mode: 0644]
www/templates/static/development.html [new file with mode: 0644]
www/templates/static/donation.html [new file with mode: 0644]
www/templates/static/imprint.html [new file with mode: 0644]
www/templates/static/pr.html [new file with mode: 0644]
www/templates/static/screenshots.html [new file with mode: 0644]
www/templates/translations.html [new file with mode: 0644]
www/translations/de_DE.csv [new file with mode: 0644]
www/web/__init__.py [deleted file]
www/web/banners.py [deleted file]
www/web/elements.py [deleted file]
www/web/http.py [deleted file]
www/web/info.py [deleted file]
www/web/javascript.py [deleted file]
www/web/json.py [deleted file]
www/web/lang.py [deleted file]
www/web/menu.py [deleted file]
www/web/news.py [deleted file]
www/webapp.py [new file with mode: 0755]
www/webapp/__init__.py [new file with mode: 0644]
www/webapp/banners.py [new file with mode: 0644]
www/webapp/builds.py [new file with mode: 0644]
www/webapp/cluster.py [moved from www/web/cluster.py with 97% similarity]
www/webapp/db.py [new file with mode: 0644]
www/webapp/handlers.py [new file with mode: 0644]
www/webapp/helpers.py [new file with mode: 0644]
www/webapp/info.py [new file with mode: 0644]
www/webapp/menu.py [new file with mode: 0644]
www/webapp/mirrors.py [new file with mode: 0644]
www/webapp/news.py [new file with mode: 0644]
www/webapp/releases.py [new file with mode: 0644]
www/webapp/translations.py [new file with mode: 0644]
www/webapp/ui_modules.py [new file with mode: 0644]
www/webapp/uriel.py [moved from www/web/urieldb.py with 98% similarity]

index 56da7d2712fc9f720381e6d14d510cc36072cfb2..56757bb2ab8bac9c36a50ae13b592aee2cc15d03 100644 (file)
@@ -1,11 +1,11 @@
-{
-       "01" : { "uri"   : "/images/sponsors/isp42.png",
-                        "title" : "<span>Hosting</span>-Sponsor",
-                        "link"  : "http://www.isp42.de/" },
-       "02" : { "uri"   : "/images/sponsors/isp42_2.png",
-                        "title" : "<span>Hosting</span>-Sponsor",
-                        "link"  : "http://www.isp42.de/" },
-       "03" : { "uri"   : "/images/cebit2010_logo_en.png",
-                        "title" : "<span>CeBIT</span> 2010",
-                        "link"  : "cebit" }
-}
+[
+       { "uri"   : "images/sponsors/isp42.png",
+         "title" : "<span>Hosting</span>-Sponsor",
+         "link"  : "http://www.isp42.de/" },
+       { "uri"   : "images/sponsors/isp42_2.png",
+         "title" : "<span>Hosting</span>-Sponsor",
+         "link"  : "http://www.isp42.de/" },
+       { "uri"   : "images/cebit2010_logo_en.png",
+         "title" : "<span>CeBIT</span> 2010",
+         "link"  : "cebit" }
+]
diff --git a/www/favicon.ico b/www/favicon.ico
deleted file mode 100644 (file)
index 52da262..0000000
Binary files a/www/favicon.ico and /dev/null differ
diff --git a/www/images/buttons/cebit_96x320.png b/www/images/buttons/cebit_96x320.png
deleted file mode 100644 (file)
index 7296fdd..0000000
Binary files a/www/images/buttons/cebit_96x320.png and /dev/null differ
diff --git a/www/images/buttons/download_core_96x320.png b/www/images/buttons/download_core_96x320.png
deleted file mode 100644 (file)
index 1d471de..0000000
Binary files a/www/images/buttons/download_core_96x320.png and /dev/null differ
diff --git a/www/images/tux_menu_99x100.png b/www/images/tux_menu_99x100.png
deleted file mode 100644 (file)
index 98fdf33..0000000
Binary files a/www/images/tux_menu_99x100.png and /dev/null differ
diff --git a/www/include/jquery-ui.min.js b/www/include/jquery-ui.min.js
deleted file mode 120000 (symlink)
index d7ade4f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-jquery-ui-1.7.2.custom.min.js
\ No newline at end of file
diff --git a/www/include/jquery.alternate.min.js b/www/include/jquery.alternate.min.js
deleted file mode 100644 (file)
index 4b15207..0000000
+++ /dev/null
@@ -1 +0,0 @@
-(function(a){a.fn.alternate=function(b,c){var d=a.extend({},a.fn.alternate.defaults,b);return this.each(function(e){var f=a(this),g=a.meta?a.extend({},d,f.data()):d;if(e%2==0&&d.even.length){f.removeClass(d.odd).addClass(d.even)}else{if(d.odd.length){f.removeClass(d.even).addClass(d.odd)}}if(c){f.click(c)}if(d.hover){f.bind("mouseenter mouseleave",function(h){a(this).toggleClass("hover")})}})};a.fn.alternate.defaults={odd:"odd",even:"even",hover:false}})(jQuery);
\ No newline at end of file
diff --git a/www/include/jquery.min.js b/www/include/jquery.min.js
deleted file mode 120000 (symlink)
index 2c88619..0000000
+++ /dev/null
@@ -1 +0,0 @@
-jquery-1.3.2.min.js
\ No newline at end of file
diff --git a/www/include/jquery.tablesorter.min.js b/www/include/jquery.tablesorter.min.js
deleted file mode 100644 (file)
index 64c7007..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-(function($){$.extend({tablesorter:new function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'.',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}var rows=table.tBodies[0].rows;if(table.tBodies[0].rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i<l;i++){var p=false;if($.metadata&&($($headers[i]).metadata()&&$($headers[i]).metadata().sorter)){p=getParserById($($headers[i]).metadata().sorter);}else if((table.config.headers[i]&&table.config.headers[i].sorter)){p=getParserById(table.config.headers[i].sorter);}if(!p){p=detectParserForColumn(table,cells[i]);}if(table.config.debug){parsersDebug+="column:"+i+" parser:"+p.id+"\n";}list.push(p);}}if(table.config.debug){log(parsersDebug);}return list;};function detectParserForColumn(table,node){var l=parsers.length;for(var i=1;i<l;i++){if(parsers[i].is($.trim(getElementText(table.config,node)),table,node)){return parsers[i];}}return parsers[0];}function getParserById(name){var l=parsers.length;for(var i=0;i<l;i++){if(parsers[i].id.toLowerCase()==name.toLowerCase()){return parsers[i];}}return false;}function buildCache(table){if(table.config.debug){var cacheTime=new Date();}var totalRows=(table.tBodies[0]&&table.tBodies[0].rows.length)||0,totalCells=(table.tBodies[0].rows[0]&&table.tBodies[0].rows[0].cells.length)||0,parsers=table.config.parsers,cache={row:[],normalized:[]};for(var i=0;i<totalRows;++i){var c=table.tBodies[0].rows[i],cols=[];cache.row.push($(c));for(var j=0;j<totalCells;++j){cols.push(parsers[j].format(getElementText(table.config,c.cells[j]),table,c.cells[j]));}cols.push(i);cache.normalized.push(cols);cols=null;};if(table.config.debug){benchmark("Building cache for "+totalRows+" rows:",cacheTime);}return cache;};function getElementText(config,node){if(!node)return"";var t="";if(config.textExtraction=="simple"){if(node.childNodes[0]&&node.childNodes[0].hasChildNodes()){t=node.childNodes[0].innerHTML;}else{t=node.innerHTML;}}else{if(typeof(config.textExtraction)=="function"){t=config.textExtraction(node);}else{t=$(node).text();}}return t;}function appendToTable(table,cache){if(table.config.debug){var appendTime=new Date()}var c=cache,r=c.row,n=c.normalized,totalRows=n.length,checkCell=(n[0].length-1),tableBody=$(table.tBodies[0]),rows=[];for(var i=0;i<totalRows;i++){rows.push(r[n[i][checkCell]]);if(!table.config.appender){var o=r[n[i][checkCell]];var l=o.length;for(var j=0;j<l;j++){tableBody[0].appendChild(o[j]);}}}if(table.config.appender){table.config.appender(table,rows);}rows=null;if(table.config.debug){benchmark("Rebuilt table:",appendTime);}applyWidget(table);setTimeout(function(){$(table).trigger("sortEnd");},0);};function buildHeaders(table){if(table.config.debug){var time=new Date();}var meta=($.metadata)?true:false,tableHeadersRows=[];for(var i=0;i<table.tHead.rows.length;i++){tableHeadersRows[i]=0;};$tableHeaders=$("thead th",table);$tableHeaders.each(function(index){this.count=0;this.column=index;this.order=formatSortingOrder(table.config.sortInitialOrder);if(checkHeaderMetadata(this)||checkHeaderOptions(table,index))this.sortDisabled=true;if(!this.sortDisabled){$(this).addClass(table.config.cssHeader);}table.config.headerList[index]=this;});if(table.config.debug){benchmark("Built headers:",time);log($tableHeaders);}return $tableHeaders;};function checkCellColSpan(table,rows,row){var arr=[],r=table.tHead.rows,c=r[row].cells;for(var i=0;i<c.length;i++){var cell=c[i];if(cell.colSpan>1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i<l;i++){getWidgetById(c[i]).format(table);}}function getWidgetById(name){var l=widgets.length;for(var i=0;i<l;i++){if(widgets[i].id.toLowerCase()==name.toLowerCase()){return widgets[i];}}};function formatSortingOrder(v){if(typeof(v)!="Number"){i=(v.toLowerCase()=="desc")?1:0;}else{i=(v==(0||1))?v:0;}return i;}function isValueInArray(v,a){var l=a.length;for(var i=0;i<l;i++){if(a[i][0]==v){return true;}}return false;}function setHeadersCss(table,$headers,list,css){$headers.removeClass(css[0]).removeClass(css[1]);var h=[];$headers.each(function(offset){if(!this.sortDisabled){h[this.column]=$(this);}});var l=list.length;for(var i=0;i<l;i++){h[list[i][0]].addClass(css[list[i][1]]);}}function fixColumnWidth(table,$headers){var c=table.config;if(c.widthFixed){var colgroup=$('<colgroup>');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('<col>').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;i<l;i++){var s=sortList[i],o=c.headerList[s[0]];o.count=s[1];o.count++;}}function multisort(table,sortList,cache){if(table.config.debug){var sortTime=new Date();}var dynamicExp="var sortWrapper = function(a,b) {",l=sortList.length;for(var i=0;i<l;i++){var c=sortList[i][0];var order=sortList[i][1];var s=(getCachedSortType(table.config.parsers,c)=="text")?((order==0)?"sortText":"sortTextDesc"):((order==0)?"sortNumeric":"sortNumericDesc");var e="e"+i;dynamicExp+="var "+e+" = "+s+"(a["+c+"],b["+c+"]); ";dynamicExp+="if("+e+") { return "+e+"; } ";dynamicExp+="else { ";}var orgOrderCol=cache.normalized[0].length-1;dynamicExp+="return a["+orgOrderCol+"]-b["+orgOrderCol+"];";for(var i=0;i<l;i++){dynamicExp+="}; ";}dynamicExp+="return 0; ";dynamicExp+="}; ";eval(dynamicExp);cache.normalized.sort(sortWrapper);if(table.config.debug){benchmark("Sorting on "+sortList.toString()+" and dir "+order+" time:",sortTime);}return cache;};function sortText(a,b){return((a<b)?-1:((a>b)?1:0));};function sortTextDesc(a,b){return((b<a)?-1:((b>a)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){$this.trigger("sortStart");var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){var $cell=$(this);var i=this.column;this.order=this.count++%2;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j<a.length;j++){if(a[j][0]!=i){config.sortList.push(a[j]);}}}config.sortList.push([i,this.order]);}else{if(isValueInArray(i,config.sortList)){for(var j=0;j<config.sortList.length;j++){var s=config.sortList[j],o=config.headerList[s[0]];if(s[0]==i){o.count=s[1];o.count++;s[1]=o.count%2;}}}else{config.sortList.push([i,this.order]);}};setTimeout(function(){setHeadersCss($this[0],$headers,config.sortList,sortCSS);appendToTable($this[0],multisort($this[0],config.sortList,cache));},1);return false;}}).mousedown(function(){if(config.cancelSelection){this.onselectstart=function(){return false};return false;}});$this.bind("update",function(){this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);}).bind("sorton",function(e,list){$(this).trigger("sortStart");config.sortList=list;var sortList=config.sortList;updateHeaderSortCount(this,sortList);setHeadersCss(this,$headers,sortList,sortCSS);appendToTable(this,multisort(this,sortList,cache));}).bind("appendCache",function(){appendToTable(this,cache);}).bind("applyWidgetId",function(e,id){getWidgetById(id).format(this);}).bind("applyWidgets",function(){applyWidget(this);});if($.metadata&&($(this).metadata()&&$(this).metadata().sortlist)){config.sortList=$(this).metadata().sortlist;}if(config.sortList.length>0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i<l;i++){if(parsers[i].id.toLowerCase()==parser.id.toLowerCase()){a=false;}}if(a){parsers.push(parser);};};this.addWidget=function(widget){widgets.push(widget);};this.formatFloat=function(s){var i=parseFloat(s);return(isNaN(i))?0:i;};this.formatInt=function(s){var i=parseInt(s);return(isNaN(i))?0:i;};this.isDigit=function(s,config){var DECIMAL='\\'+config.decimal;var exp='/(^[+]?0('+DECIMAL+'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)'+DECIMAL+'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*'+DECIMAL+'0+$)/';return RegExp(exp).test($.trim(s));};this.clearTableBody=function(table){if($.browser.msie){function empty(){while(this.firstChild)this.removeChild(this.firstChild);}empty.apply(table.tBodies[0]);}else{table.tBodies[0].innerHTML="";}};}});$.fn.extend({tablesorter:$.tablesorter.construct});var ts=$.tablesorter;ts.addParser({id:"text",is:function(s){return true;},format:function(s){return $.trim(s.toLowerCase());},type:"text"});ts.addParser({id:"digit",is:function(s,table){var c=table.config;return $.tablesorter.isDigit(s,c);},format:function(s){return $.tablesorter.formatFloat(s);},type:"numeric"});ts.addParser({id:"currency",is:function(s){return/^[£$€?.]/.test(s);},format:function(s){return $.tablesorter.formatFloat(s.replace(new RegExp(/[^0-9.]/g),""));},type:"numeric"});ts.addParser({id:"ipAddress",is:function(s){return/^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);},format:function(s){var a=s.split("."),r="",l=a.length;for(var i=0;i<l;i++){var item=a[i];if(item.length==2){r+="0"+item;}else{r+=item;}}return $.tablesorter.formatFloat(r);},type:"numeric"});ts.addParser({id:"url",is:function(s){return/^(https?|ftp|file):\/\/$/.test(s);},format:function(s){return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//),''));},type:"text"});ts.addParser({id:"isoDate",is:function(s){return/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);},format:function(s){return $.tablesorter.formatFloat((s!="")?new Date(s.replace(new RegExp(/-/g),"/")).getTime():"0");},type:"numeric"});ts.addParser({id:"percent",is:function(s){return/\%$/.test($.trim(s));},format:function(s){return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g),""));},type:"numeric"});ts.addParser({id:"usLongDate",is:function(s){return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));},format:function(s){return $.tablesorter.formatFloat(new Date(s).getTime());},type:"numeric"});ts.addParser({id:"shortDate",is:function(s){return/\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s);},format:function(s,table){var c=table.config;s=s.replace(/\-/g,"/");if(c.dateFormat=="us"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/,"$3/$1/$2");}else if(c.dateFormat=="uk"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/,"$3/$2/$1");}else if(c.dateFormat=="dd/mm/yy"||c.dateFormat=="dd-mm-yy"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/,"$1/$2/$3");}return $.tablesorter.formatFloat(new Date(s).getTime());},type:"numeric"});ts.addParser({id:"time",is:function(s){return/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);},format:function(s){return $.tablesorter.formatFloat(new Date("2000/01/01 "+s).getTime());},type:"numeric"});ts.addParser({id:"metadata",is:function(s){return false;},format:function(s,table,cell){var c=table.config,p=(!c.parserMetadataName)?'sortValue':c.parserMetadataName;return $(cell).metadata()[p];},type:"numeric"});ts.addWidget({id:"zebra",format:function(table){if(table.config.debug){var time=new Date();}$("tr:visible",table.tBodies[0]).filter(':even').removeClass(table.config.widgetZebra.css[1]).addClass(table.config.widgetZebra.css[0]).end().filter(':odd').removeClass(table.config.widgetZebra.css[0]).addClass(table.config.widgetZebra.css[1]);if(table.config.debug){$.tablesorter.benchmark("Applying Zebra widget",time);}}});})(jQuery);
\ No newline at end of file
index 400023999695905a1ff50412e456a994957e5c34..dd07e2fae339754acee9e2ebb0aaf9cb411c6963 100644 (file)
@@ -1,10 +1,5 @@
 {
-       "name"     : "IPFire",
-       "sname"    : "ipfire",
-       "slogan"   : "Security now!",
-       "releases" : { "stable"  : "IPFire 2.5 - Core 34",
-                                  "testing" : "IPFire 3.0 alpha 1" },
-       "hosting"  : { "cluster" : "minerva.ipfire.org" },
+       "cluster"  : { "hostname" : "minerva.ipfire.org" },
        "nightly_builds" : [{ "url" : "http://ftp.ipfire.org/pub/nightly-builds/",
                                                  "path" : "/srv/anonftp/pub/nightly-builds" },
                                                { "url" : "http://www.rowie.at/upload/ipfire/builds/" }],
diff --git a/www/ipfire.py b/www/ipfire.py
deleted file mode 100755 (executable)
index 6296b92..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/python
-
-import cgitb
-cgitb.enable()
-
-import sys
-import cgi
-import imputil
-
-site = cgi.FieldStorage().getfirst("site") or "index"
-
-sys.path = [ "pages",] + sys.path
-for s in (site, "static"):
-       try:
-               found = imputil.imp.find_module(s)
-               loaded = imputil.imp.load_module(s, found[0], found[1], found[2])
-               
-               p = loaded.__dict__["page"]
-
-               break
-       except ImportError, e:
-               pass
-
-p()
index 4f434781b0b407fbca49f855f61788ae25d2cdd7..6d4e099e944ebd82c05da6653325e0f90a3795d9 100644 (file)
@@ -1,18 +1,16 @@
-{
-       "10" : { "uri"  : "/index",
-                        "name" : "Home" },
-       "20" : { "uri"  : "/download",
-                        "name" : "Downloads" },
-       "30" : { "uri"  : "/screenshots",
-                        "name" : "Screenshots" },
-       "40" : { "uri"  : "http://wiki.ipfire.org/",
-                        "name" : { "de" : "Wiki", "en" : "Wiki" }},
-       "50" : { "uri"  : "http://forum.ipfire.org/",
-                        "name" : "Forum" },
-       "60" : { "uri"  : "/development",
-                        "name" : { "de" : "Entwicklung", "en" : "Development" }},
-       "70" : { "uri"  : "/links",
-                        "name" : "Links" },
-       "80" : { "uri"  : "/cebit",
-                        "name" : "<div style=\"color:#f90;\">CeBIT 2010</div>" }
-}
+[
+       { "uri"  : "/index",
+         "name" : "Home" },
+       { "uri"  : "/download",
+         "name" : "Downloads" },
+       { "uri"  : "/screenshots",
+         "name" : "Screenshots" },
+       { "uri"  : "http://wiki.ipfire.org/",
+         "name" : { "de" : "Wiki", "en" : "Wiki" }},
+       { "uri"  : "http://forum.ipfire.org/",
+         "name" : "Forum" },
+       { "uri"  : "/development",
+         "name" : { "de" : "Entwicklung", "en" : "Development" }},
+       { "uri"  : "/cebit",
+         "name" : "<div style=\"color:#f90;\">CeBIT 2010</div>" }
+]
diff --git a/www/mirrors.json b/www/mirrors.json
new file mode 100644 (file)
index 0000000..13186c1
--- /dev/null
@@ -0,0 +1,161 @@
+[
+       {
+               "name" : "IPFire Project",
+               "location" : {
+                       "city" : "Cologne",
+                       "country" : "Germany",
+                       "country_code" : "de"
+               },
+               "hostname" : "mirror1.ipfire.org",
+               "path" : "",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : true,
+                       "pakfire3" : true
+               }
+       },
+
+       {
+               "name" : "Ronald Wiesinger",
+               "location" : {
+                       "city" : "Vienna",
+                       "country" : "Austria",
+                       "country_code" : "at"
+               },
+               "hostname" : "www.rowie.at",
+               "path" : "/ipfire",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : false,
+                       "pakfire3" : false
+               }
+       },
+
+       {
+               "name" : "Jan Paul Tücking",
+               "location" : {
+                       "city" : "Karlsruhe",
+                       "country" : "Germany",
+                       "country_code" : "de"
+               },
+               "hostname" : "ipfire.earl-net.com",
+               "path" : "",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : false,
+                       "pakfire3" : false
+               }
+       },
+
+       {
+               "name" : "Markus Villwock",
+               "location" : {
+                       "city" : "Hannover",
+                       "country" : "Germany",
+                       "country_code" : "de"
+               },
+               "hostname" : "kraefte.net",
+               "path" : "/ipfire",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : true,
+                       "pakfire3" : false
+               }
+       },
+
+       {
+               "name" : "ISP42",
+               "location" : {
+                       "city" : "Hannover",
+                       "country" : "Germany",
+                       "country_code" : "de"
+               },
+               "hostname" : "mirror2.ipfire.org",
+               "path" : "",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : true,
+                       "pakfire3" : true
+               }
+       },
+
+       {
+               "name" : "Peter Schälchli",
+               "location" : {
+                       "city" : "Paris",
+                       "country" : "France",
+                       "country_code" : "fr"
+               },
+               "hostname" : "mirror3.ipfire.org",
+               "path" : "",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : true,
+                       "pakfire3" : false
+               }
+       },
+
+       {
+               "name" : "Peter Schälchli",
+               "location" : {
+                       "city" : "Cologne",
+                       "country" : "Germany",
+                       "country_code" : "de"
+               },
+               "hostname" : "mirror5.ipfire.org",
+               "path" : "",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : true,
+                       "pakfire3" : false
+               }
+       },
+
+       {
+               "name" : "Kim Barthel",
+               "location" : {
+                       "city" : "Stuttgart",
+                       "country" : "Germany",
+                       "country_code" : "de"
+               },
+               "hostname" : "ipfire.kbarthel.de",
+               "path" : "",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : false,
+                       "pakfire3" : false
+               }
+       },
+
+       {
+               "name" : "Kim Barthel",
+               "location" : {
+                       "city" : "Stuttgart",
+                       "country" : "Germany",
+                       "country_code" : "de"
+               },
+               "hostname" : "ipfire.1l0v3u.com",
+               "path" : "",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : false,
+                       "pakfire3" : false
+               }
+       },
+
+       {
+               "name" : "Sebastian Winter",
+               "location" : {
+                       "city" : "Minden",
+                       "country" : "Germany",
+                       "country_code" : "de"
+               },
+               "hostname" : "ipfiremirror.wintertech.de",
+               "path" : "",
+               "serves" : {
+                       "isos" : true,
+                       "pakfire2" : false,
+                       "pakfire3" : false
+               }
+       }
+]
index 9a6c003072b7a7d2b4c78294edf9bde972dbdb83..662913fa0ac2f87f488d9694bd4bf8e451e751e9 100644 (file)
@@ -45,7 +45,7 @@
                                        { "en" : "<p>The linux user group from Lünen
                                                                released an article about ipfire.</p>",
                                          "de" : "<p>Die Linux-User-Group aus Lünen hat einen Artikel
-                                                               Ã¼ber IPFire auf ihrer Webseite veröffentlicht.</p>"}},
+                                                               Ã¼ber IPFire auf Ihrer Webseite veröffentlicht.</p>"}},
 
                "05" : {"author"   : "Michael Tremer",
                                "mail"     : "michael.tremer@ipfire.org",
                                          "de" : "<p>Heute werden wir <strong>Core 32</strong> veröffentlichen. Es bringt die folgenden Ã„nderungen mit sich:</p>                                                      
                                                                <ul>                                                            
                                                                    <li>Update von openvpn auf Version 2.1rc20</li>
-                                                                   <li>Update von setdns.pl nun werden auch regfish.de Account richtig aktuallisiert</li>
+                                                                   <li>Update von setdns.pl nun werden auch regfish.de Account richtig aktualisiert</li>
                                                                    <li>Update von squid auf Version 2.7.STABLE7</li>
                                                                    <li>Update von ntfs3g, vielleicht behebt dieses ein paar mount Probleme</li>
                                                                    <li>Update der Hardware Datenbank</li>
                                                                    target=\"_blank\">dieses Sicherheitsproblem</a> zu blockieren.</li>
                                                                    <li>Fix von einigen Tippfehler (Device xxx reports S.M.A.R.T. etc.)</li>
                                                                    <li>Update Net-Server auf Version 0.97</li>
-                                                                       <li>Pakfire: Aktualisiert nun auch die meta db beim \"package list\" Update.<br />
-                                                                   Dieses verhindert die Benutzung von alten Abhängigkeiten bei der Paketaktualisierung.</li>
+                                                                       <li>Pakfire: AktualiSiert nun auch die meta db beim \"package list\" Update.<br />
+                                                                   Dieses verhindert die Benutzung von alten Abhängigkeiten bei der PaketaktualiSierung.</li>
                                                                </ul>
                                                                <br />"}},
 
 
                                          "de" : "<p>Das IPFire Core Development Team ist stolz zwei neue Mitglieder vorzustellen.
                                                                <strong>Stefan Schantl</strong> und <strong>Jan Paul Tücking</strong> sind von
+<<<<<<< HEAD:www/news.json
                                                                nun an Teil des Teams aufgrund ihrer beständigen und langen Mitarbeit am Projekt.</p>
+=======
+                                                               nun an Teil des Teams aufgrund Ihrer beständigen und langen Mitarbeit am Projekt.</p>
+>>>>>>> next:www/news.json
                                                                <p>
                                                                        <a href=\"http://wiki.ipfire.org/de/project/contribute\" target=\"_blank\">Wie kann ich selber zum Projekt beitragen?</a>
                                                                </p>"}},
                                          "de" : "<p>Marcus Scholz hat einen <a href=\"http://www.commander1024.de/wordpress/2009/12/ipfire-talk-in-der-warpzone/\" target=\"_blank\">Vortrag</a> Ã¼ber
                                                          IPFire in der <a href=\"http://warpzone.ms/\" target=\"_blank\">Warpzone</a> gehalten. Die dazugehörigen  
                                                          <a href=\"http://www.commander1024.de/wordpress/wp-content/uploads/2009/12/IPFire-Talk.pdf\" target=\"_blank\">Folien</a> 
+<<<<<<< HEAD:www/news.json
                                                          so wie ein <a href=\"http://qik.com/video/3807703\" target=\"_blank\">Video</a> von seiner Presentation stehen zur Verfügung.
+=======
+                                                         so wie ein <a href=\"http://qik.com/video/3807703\" target=\"_blank\">Video</a> von seiner Präsentation stehen zur Verfügung.
+>>>>>>> next:www/news.json
                                                                </p>"}},
 
                "25" : {"author"   : "Michael Tremer",
                                                                </p>",
 
                                          "de" : "<p>Heute werden wir das erste Update im Jahr 2010 veröffentlichen.  
-                                                                 Das <strong>Core 34</strong> Update kommt mit folgenden Ã„nderungen:</p>
+                                                                 Das <strong>Core 34</strong> Update weist folgende Ã„nderungen auf:</p>
                                                                <p>
                                                                <ul>
                                                                  <li><strong>Kernel Update auf 2.6.27.42</strong></li>
                                                                    <li>Update von alsa auf 1.0.22(.1)</li>
                                                                    <li>Update von v4l-dvb</li>
                                                                    <li>Update von compat-wireless auf 2.6.32.2</li>
-                                                                   <li>Standardtreiber von atheros auf ath5k getauscht</li>
-                                                                   <li>kvm-kmod hinzugefügt um die kvm api für qemu zu aktualliesieren</li>
-                                                                   <li>Atheros/Attansic atl1c Netzwerktreiber hinzugefügt</li>
-                                                                   <li>Patches für die Erkennung von Realtek 8102/8103 zu r8101 Treibern hinzugefügt</li>
-                                                                   <li>Patch für die Wake-on-Lan Probleme des Intel E100 zu beheben hinzugefügt</li>
+                                                                   <li>Wechsel des Standardtreibers von atheros auf ath5k</li>
+                                                                   <li>Ergänzung von kvm-kmod zwecks AktualiSierung der kvm api für qemu</li>
+                                                                   <li>Erweiterung um Atheros/Attansic atl1c Netzwerktreiber</li>
+                                                                   <li>Ergänzung um Patches für die Erkennung von Realtek 8102/8103 zu r8101 Treibern</li>
+                                                                   <li>Behebung der Wake-on-Lan Probleme der Intel E100 NIC durch das Hinzufügen eines Patches</li>
                                                                  </ul>
                                                                </ul>
                                                                <ul>
-                                                                 <li>usb_modeswitch 1.0.6 hinzugefügt</li>
-                                                                 <li>compile-Option für die DCF77-clocks hinzugefügt</li>
+                                                                 <li>Erweiterung um usb_modeswitch 1.0.6</li>
+                                                                 <li>NTP: Unterstützung für DCF77-Uhren</li>
                                                                  <li>Update von smartmontools auf 5.39 stable</li>
-                                                                 <li>Sicherstellung, dass das ehci_hci Modul zu erst geladen wird (behebt USB2.0-Erkennung)</li>
+                                                                 <li>Sicherstellung, dass das ehci_hci Modul zuerst geladen wird (behebt USB2.0-Erkennung)</li>
                                                                </ul>
                                                                <ul>
-                                                                 <li>IPSEC:</li>
+                                                                 <li>IPSEC-Verbesserungen:</li>
                                                                  <ul>
-                                                                   <li>Nun sind IPSec Peers auch durch IPFire erreichbar</li>
-                                                                   <li>Nicht funktionerende Crytomodule wurden aus der IPSec-Konfiguration gelöscht</li>
+                                                                   <li>IPSec Peers sind nun ebenfalls durch IPFire erreichbar</li>
+                                                                   <li>Nicht funktionierende Cryptomodule wurden aus der IPSec-Konfiguration gelöscht.</li>
                                                                  </ul>
                                                                  <li>IPTV Verbesserungen:</li>
                                                                  <ul>
                                                                    <li>Update von dhcpcd</li>
                                                                    <li>Fix für den iqmpproxy Installationscheck (pppsetup.cgi)</li>
-                                                                   <li>Verbesserung an der mac.cgi Seite, Ã„nderungen am Tabellenlayout und Beschreibungen hinzugefügt.</li>
+                                                                   <li>Verbesserung an der mac.cgi Seite, Ã„nderungen am Tabellenlayout und Ergänzungen von Beschreibungen.</li>
                                                                  </ul>
-                                                                 <li>CGI Ã„nderugen:</li>
+                                                                 <li>CGI Ã„nderungen:</li>
                                                                  <ul>
-                                                                   <li>Spendenbutton auf der Credits Seite hinzugefügt</li>
-                                                                   <li>Es wurde ein Patch hinzugefügt um das oinkmaster Verzeichniss tmp auf /var/tmp zu Ã¤ndern</li>
-                                                                   <li>\"time constraints feature\" und \"local port adressing\" zur ausgehenden Firewall hinzugefügt</li>
+                                                                   <li>Hinzufügen eines Spendenbuttons auf der Credits Seite</li>
+                                                                   <li>Erweiterung um ein Patch, zwecks Ã„nderung des oinkmaster Verzeichnisses tmp auf /var/tmp</li>
+                                                                   <li>Erweiterung um ein \"time constraints feature\" und \"local port adressing\" zur ausgehenden Firewall</li>
                                                                    <li>Neugestaltung der chpasswd.cgi</li>
                                                                    <li>Verbesserung der Pakfire \"Ping\" Beschreibung auf der pakfire.cgi</li>
-                                                                   <li>ExtraHD-Seite ist nun mehrsprachig</li>
-                                                                   <li>Behoben, dass crontab beim ramdisk restore ersetzt wurde</li>
+                                                                   <li>Erweiterung auf eine mehrsprachige ExtraHD-Seite</li>
+                                                                   <li>Beseitigung des Fehlers, dass beim RAM-Disk Restore Crontab ersetzt wurde</li>
                                                                  </ul>
                                                                  <li>Installer:</li>
                                                                  <ul>
-                                                                   <li>Installer device von /dev/tty1 nach /dev/console geändert</li>
+                                                                   <li>Änderung des Installer device von /dev/tty1 nach /dev/console geändert</li>
                                                                    <li>Update von memtest86+ auf 4.00</li>
                                                                  </ul>
                                                                  <li>Sprachen:</li>
                                                                  <ul>
-                                                                  <li>Die Unterstützung von französisch dem Installer hinzugefügt</li>
+                                                                  <li>Unterstützung der französischen Sprache beim Installer</li>
                                                                  </ul>
                                                                </ul>
                                                                </p>
                                                                <p>
-                                                               Durch den <strong>Kernelupdate</strong> ist ein <strong>Neustart</strong> von IPFire nötig! <br/>
-                                                               <strong>Achtung</strong>: Grub wird neu installiert, wenn die Konfiguration manuell geändert 
+                                                               Durch das <strong>Update</strong> des <strong>Kernels</strong> ist ein <strong>Neustart</strong> 
+                                                               von IPFire nötig! <br/>
+                                                               <strong>Achtung</strong>: Grub wird neu installiert. Wenn die Konfiguration manuell geändert 
                                                                wurde muss diese zuerst wieder hergestellt werden!<br />
-                                                               <strong>Xen</strong> User müssen vor dem Neustart der Machine auch linux-xen updaten!
-                                                               </p>"}}                                                         
+                                                               <strong>Xen</strong> User müssen vor dem Neustart der Maschine zuerst linux-xen updaten, 
+                                                               da es sonst zu Fehlern kommt!
+                                                               </p>"}},
                                                                
+               "27" : {"author"   : "Jan Paul Tuecking",
+                               "mail"     : "earl@ipfire.org",
+                               "subject"  : { "en" : "Core Update 35", "de" : "Core Update 35" },
+                               "date"     : "2010-01-28",
+                               "link"     : "",
+                               "content"  :
+                                       { "en" : "<p>Today we are going to release <strong>Core 35</strong>. 
+                                                                       It implicates following changes:</p>    
+                                                               <p>
+                                                               <ul>
+                                                             <li>Applied the latest <strong>security patches</strong> to squidGuard to prevent buffer overflows and 
+                                                                from going into emergency mode when overlong URLs are encountered</li>
+                                                             <li>Add missing modules for intersil/prism (disabled) </li>
+                                                             <li>Disabled connscheduler on general (*)</li>
+                                                             <li>Add zerofree to cleanup flash and xenimages (*)</li>
+                                                             <li>Fix for countrycode list (thx to m.a.d)</li>
+                                                               </ul>
+                                                               <ul>
+                                                                 <li>Webinterface:</li>
+                                                                 <ul>
+                                                                   <li>Fix the link to external Snort SID page</li>
+                                                                 </ul>
+                                                                 <li>Outgoing Firewall:</li>
+                                                                 <ul>
+                                                                   <li>Parse pre Core34 rules correct and enabled change logging in mode 1</li>
+                                                                   <li>Added GRE and ESP protocol to outgoing firewall</li>
+                                                                 </ul>
+                                                                 <li>Xen:</li>
+                                                                 <ul>
+                                                                   <li>Fix klogd fails on xen-kernel</li>
+                                                                   <li>Disabled start of console initscript on xen-image (*)</li>
+                                                                   <li>Change xen-image boot fstype to ext2 (*)</li>
+                                                                 </ul>
+                                                               </ul>
+                                                               </p>
+                                                               <p>
+                                                               (*) These changes have only effect on new installations of IPFire.
+                                                       </p>",
 
+
+                                         "de" : "<p>Heute werden wir <strong>Core 35</strong> veröffentlichen. 
+                                                                       Es bringt die folgenden Ã„nderungen mit sich:</p>       
+                                                               <p>
+                                                               <ul>
+                                                             <li>Die neuesten <strong>Sicherheitspatches</strong> für squidGuard wurden eingespielt, 
+                                                               diese beheben ein Pufferüberlauf und verhindert das squidGuard in den 
+                                                               \"Emergency-Mode\" bei Ã¼berlangen URLs geht</li>
+                                                             <li>Fehlende Module für intersil/prism wurden hinzugefügt.</li>
+                                                             <li>Der connscheduler ist nun immer zuerst abgeschaltet (*)</li>
+                                                             <li>Unbenutzte Blöcke in den Flash und Xen-Images vor dem komprimieren gelöscht (*)</li>
+                                                             <li>Korrektur der Ländercodeliste (Danke m.a.d)</li>
+                                                               </ul>
+                                                               <ul>
+                                                                 <li>Webinterface:</li>
+                                                                 <ul>
+                                                                   <li>Der Link für die externe Snort SID Seite wurde korrigiert</li>
+                                                                 </ul>
+                                                                 <li>Ausgehende Firewall:</li>
+                                                                 <ul>
+                                                                   <li>Alte Regeln (vor Core34) werden nun korrekt geparst und für den Modus 1 wurde das Logging aktiviert</li>
+                                                                   <li>Die Protokolle GRE und ESP wurden der Ausgehenden Firewall hinzugefügt</li>
+                                                                 </ul>
+                                                                 <li>Xen:</li>
+                                                                 <ul>
+                                                                   <li>Die Fehler vom klogd Demon im Xen-Kernel wurden behoben</li>
+                                                                   <li>Der Start der Konsolen Initskripten auf dem Xen-Image wurde herausgenommen (*)</li>
+                                                                   <li>Filesystemtyp der Bootpartition des Xen-Images wurde auf ext2 geändert (*)</li>
+                                                                 </ul>
+                                                               </ul>
+                                                               </p>
+                                                               <p>
+                                                               (*) Diese Ã„nderungen betreffen nur Neuinstallationen von IPFire.
+                                               </p>"}}
 }
 
diff --git a/www/pages/builds.py b/www/pages/builds.py
deleted file mode 100644 (file)
index 4a3b500..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-#!/usr/bin/python
-
-import os
-import time
-
-import web
-import web.elements
-import web.javascript
-
-from web.info import Info
-info = Info()
-
-def size(file):
-       size = os.path.getsize(file)
-       suffixes = [("B",2**10), ("K",2**20), ("M",2**30), ("G",2**40), ("T",2**50)]
-       for suf, lim in suffixes:
-               if size > lim:
-                       continue
-               else:
-                       return "%s%s" % (round(size/float(lim/2**10),2), suf)
-
-
-class Build(object):
-       def __init__(self, path, basedir, url):
-               self.path = path
-               self.basedir = basedir
-               self.url = os.path.join(url, path[len(basedir)+1:])
-
-               # Read .buildinfo
-               f = open("%s/.buildinfo" % path)
-               self.info = f.readlines()
-               f.close()
-
-       def __repr__(self):
-               return "<Build %s>" % self.path
-       
-       def __cmp__(self, other):
-               return cmp(float(other.get("date")), float(self.get("date")))
-       
-       def get(self, key):
-               key = key.upper() + "="
-               for line in self.info:
-                       if line.startswith(key):
-                               return line.split("=")[1].rstrip("\n")
-               return None
-
-       @property
-       def hostname(self):
-               return self.get("hostname")
-       
-       @property
-       def release(self):
-               return self.get("release")
-       
-       @property
-       def date(self):
-               return time.strftime("%Y-%m-%d %H:%M", time.localtime(float(self.get("date"))))
-       
-       @property
-       def arch(self):
-               return self.get("arch")
-       
-       @property
-       def duration(self):
-               if not self.get("duration") or self.get("duration") == "":
-                       return "--:--"
-               return time.strftime("%H:%M", time.gmtime(float(self.get("duration"))))
-       
-       @property
-       def iso(self):
-               return self.get("iso")
-       
-       @property
-       def packages(self):
-               path = "%s/packages_%s" % (self.path, self.arch,)
-               if not os.path.exists(path):
-                       return []
-               return os.listdir(path)
-       
-       @property
-       def pxe(self):
-               dir = "/srv/www/ipfire.org/pxe"
-               for iso in os.listdir(dir):
-                       # Skip non-iso files
-                       if not iso.endswith(".iso"):
-                               continue
-                       if os.readlink(os.path.join(dir, iso)) == os.path.join(self.path, self.iso):
-                               return "[PXE]"
-               return ""
-
-
-class Content(web.Content):
-       def __init__(self):
-               web.Content.__init__(self)
-       
-               self.builds = []
-               for location in info["nightly_builds"]:
-                       # Only process correctly configured locations
-                       if not location.has_key("path") or not location.has_key("url"):
-                               continue
-
-                       # Continue if path does not exist
-                       if not os.path.exists(location["path"]):
-                               continue
-
-                       for (dir, subdirs, files) in os.walk(location["path"]):
-                               if not os.path.exists("%s/.buildinfo" % dir):
-                                       continue
-                               self.builds.append(Build(dir, location["path"], location["url"]))
-               self.builds.sort()
-
-       def __call__(self, lang):
-               today = time.strftime("%A, %Y-%m-%d", time.localtime())
-               last_day = ""
-
-               ret = """<h3>Nightly builds</h3>
-                               <table id="builds">
-                                       <!-- <thead>
-                                               <tr>
-                                                       <th>&nbsp;</th>
-                                                       <th>Release</th>
-                                                       <th>Host &amp; Date</th>
-                                                       <th>Download</th>
-                                               </tr>
-                                       </thead> -->
-                                       <tbody>"""
-               
-               # if there are no builds
-               if not self.builds:
-                       ret += """<tr class="headline"><td colspan="6">There are currently no builds available.</td></tr>"""
-
-               else:
-                       for build in self.builds:
-                               # write headers
-                               day = time.strftime("%A, %Y-%m-%d", time.localtime(float(build.get("date"))))
-                               if day != last_day:
-                                       if day == today:
-                                               ret += """<tr class="headline"><td colspan="5">Today</td></tr>"""
-                                       else:
-                                               ret += """<tr class="headline"><td colspan="5">&nbsp;<br />&nbsp;<br />%s</td></tr>""" % day
-                                       last_day = day
-
-                               ret += """<tr class="build">
-                                                       <td><a href="%s" target="_blank">""" % build.url
-
-                               if day == today:
-                                       ret += """<img src="/images/icons/ipfire.png" alt="IPFire" /></a></td>"""
-                               else:
-                                       ret += """<img src="/images/icons/ipfire_sw.png" alt="IPFire" /></a></td>"""
-
-                               ret += """\
-                                                       <td>&nbsp;<br />
-                                                               <strong>%(release)s</strong> (%(arch)s) %(pxe)s<br />
-                                                               <a href="%(url)s/%(iso)s">%(iso)s</a> %(size_iso)s</td>
-                                                       <td>&nbsp;<br />
-                                                               %(hostname)s<br />
-                                                               %(date)s [%(duration)sh]</td>
-                                                       <td class="packages">%(num_packages)s <a href="%(url)s/packages_%(arch)s/" target="_blank">[PAKS]</a></td>
-                                               </tr>""" % { "release"  : build.release,
-                                                                        "hostname" : build.hostname,
-                                                                        "arch"     : build.arch, 
-                                                                        "date"     : build.date,
-                                                                        "duration" : build.duration,
-                                                                        "url"      : build.url,
-                                                                        "iso"      : build.iso,
-                                                                        "size_iso" : size(os.path.join(build.path, build.iso)),
-                                                                        "num_packages" : len(build.packages),
-                                                                        "pxe"      : build.pxe }
-
-               ret += """\
-                                       </tbody>
-                               </table>"""
-
-               return ret
-
-
-page = web.Page()
-page.content = Content()
-page.sidebar = web.elements.DevelopmentSidebar()
-
-### Disabled because it looks awful
-#page.javascript = web.javascript.Javascript(jquery=1)
-#page.javascript.jquery_plugin("alternate")
-#page.javascript.write("""
-#      <script type="text/javascript">
-#              $(function() {
-#                      $("#builds tbody tr.build").alternate({odd:'odd', even:'even'});
-#              });
-#      </script>
-#""")
diff --git a/www/pages/cluster.py b/www/pages/cluster.py
deleted file mode 100644 (file)
index 11ec869..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/usr/bin/python
-
-import web
-import web.elements
-from web.javascript import Javascript
-
-class Content(web.Content):
-       def __init__(self):
-               web.Content.__init__(self)
-
-       def __call__(self, lang):
-               ret = """<h3>Icecream Cluster Monitoring</h3>
-                       <p>Cluster's CPU load: <span id="loadbar"></span> - Job load: <span id="jobbar"></span></p>
-                               <table id="nodes">
-                                       <thead>
-                                               <tr>
-                                                       <th class="hostname">Name</th>
-                                                       <th class="arch">Arch</th>
-                                                       <th class="load">Load</th>
-                                                       <th class="jobs">Jobs</th>
-                                                       <th class="speed">Speed</th>
-                                               </tr>
-                                       </thead>
-                                       <tbody>
-                                       </tbody>
-                               </table>
-                               <p>&nbsp;<br />Number of nodes: <span id="count">-</span></p>"""
-
-               return ret
-
-page = web.Page()
-page.content = Content()
-page.sidebar = web.elements.DevelopmentSidebar()
-
-page.javascript = Javascript(jquery=1)
-page.javascript.jquery_plugin("progressbar")
-page.javascript.write("""<script type="text/javascript">
-                               nodes = new Array();
-                               id = 0;
-                               busy = false;
-
-                               update = function() {
-                                       $.getJSON("/rpc.py", { method: "cluster_get_info", id : id++ },
-                                               function(data) {
-                                                       // If we are already busy then exit
-                                                       if (busy == true) return;
-
-                                                       var count = 0;
-
-                                                       if (data.error != "null") return;
-                                                       
-                                                       busy = true;
-
-                                                       $.each(data.result.nodes, function(i, node) {
-                                                               var nodeid = node.hostname.replace(/\./g, "");
-                                                               count++;
-
-                                                               nodes[nodeid] = true;
-
-                                                               if ($("#" + nodeid).length) {
-                                                                       $("#" + nodeid + "_speed").html(node.speed);
-                                                               } else {
-                                                                       row  = "<tr id=\\"" + nodeid + "\\" class=\\"node\\">";
-                                                                       row += "  <td id=\\"" + nodeid + "_hostname\\"></td>";
-                                                                       row += "  <td id=\\"" + nodeid + "_arch\\">" + node.arch + "</td>";
-                                                                       row += "  <td><span id=\\"" + nodeid + "_loadbar\\"></span></td>";
-                                                                       row += "  <td><span id=\\"" + nodeid + "_jobs\\"></span></td>";
-                                                                       row += "  <td id=\\"" + nodeid + "_speed\\">" + node.speed + "</td>";
-                                                                       row += "</tr>";
-                                                                       $("#nodes").append(row);
-                                                               }
-                                                               $("#" + nodeid + "_loadbar").progressBar(node.load, {showText: false});
-                                                               $("#" + nodeid + "_jobs").progressBar(node.jobcount.split("/")[0], { max: node.jobcount.split("/")[1], textFormat: 'fraction'});
-                                                               if (node.installing == true) {
-                                                                       $("#" + nodeid + "_hostname").html(node.hostname + " *");
-                                                               } else {
-                                                                       $("#" + nodeid + "_hostname").html(node.hostname);
-                                                               }
-                                                       });
-
-                                                       $("#loadbar").progressBar(data.result.cluster.load);
-                                                       $("#jobbar").progressBar(data.result.cluster.jobcount.split("/")[0], { max: data.result.cluster.jobcount.split("/")[1], textFormat: 'fraction'});
-                                                       for (var nodeid in nodes) {
-                                                               if (nodes[nodeid] == false) {
-                                                                       $("#" + nodeid).remove();
-                                                                       nodes.pop(nodeid);
-                                                               } else {
-                                                                       nodes[nodeid] = false;
-                                                               }
-                                                       }
-                                                       $("#count").html(count);
-                                                       busy = false;
-                                       });
-                               }
-
-                               $(document).ready(function(){
-                                       // Init loadbar
-                                       $("#loadbar").progressBar();
-
-                                       update();
-                                       setInterval("update()", 2000);
-                               })
-                       </script>""")
diff --git a/www/pages/source.py b/www/pages/source.py
deleted file mode 100644 (file)
index 4178fa4..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/python
-
-SOURCE_BASE="/srv/sources"
-SOURCE_HASHES="/srv/www/ipfire.org/source/hashes.db"
-
-SOURCE_URL="http://source.ipfire.org"
-
-import os
-import sha
-from pysqlite2 import dbapi2 as sqlite
-
-import web
-import web.elements
-
-class SourceObject:
-       def __init__(self, db, file):
-               self.file = file
-               self.name = os.path.basename(file)
-
-               if db:
-                       self.db = db
-               else:
-                       self.db = sqlite.connect(SOURCE_HASHES)
-                       c = self.db.cursor()
-                       c.execute("CREATE TABLE IF NOT EXISTS hashes(file, sha1)")
-                       c.close()
-               
-       def data(self):
-               f = open(self.file, "rb")
-               data = f.read()
-               f.close()
-               return data
-
-       def getHash(self, type="sha1"):
-               hash = None
-               c = self.db.cursor()
-               c.execute("SELECT %s FROM hashes WHERE file = '%s'" % (type, self.name,))
-               try:
-                       hash = c.fetchone()[0]
-               except TypeError:
-                       pass
-               c.close()
-
-               if not hash:
-                       hash = sha.new(self.data()).hexdigest()
-                       c = self.db.cursor()
-                       c.execute("INSERT INTO hashes(file, sha1) VALUES('%s', '%s')" % \
-                               (self.name, hash,))
-                       c.close()
-                       self.db.commit()
-               return hash
-
-
-class Content(web.Content):
-       def __init__(self):
-               web.Content.__init__(self)
-               
-               self.dirs = []
-
-               # Open database
-               db = sqlite.connect(SOURCE_HASHES)
-               
-               for dir, subdirs, files in os.walk(SOURCE_BASE):
-                       if not files:
-                               continue
-                       fileobjects = []
-                       files.sort()
-                       for file in files:
-                               file = os.path.join(dir, file)
-                               fileobjects.append(SourceObject(db, file))
-                       self.dirs.append((os.path.basename(dir), fileobjects))
-               
-       def __call__(self, lang):
-               ret = ""
-               self.w("<h3>IPFire Source Base</h3>")
-               for dir, files in self.dirs:
-                       b = web.elements.Box(dir)
-                       b.w("<ul>")
-                       for file in files:
-                               b.w("""<li style="font-family: courier;">%(hash)s | <a href="%(url)s/%(dir)s/%(file)s">%(file)s</a></li>""" % \
-                                       { "file" : file.name,
-                                         "hash" : file.getHash() or "0000000000000000000000000000000000000000",
-                                         "dir"  : dir,
-                                         "url"  : SOURCE_URL, })
-                       b.w("</ul>")
-                       ret += b()
-               return ret
-
-page = web.Page()
-page.content = Content()
-page.sidebar = web.elements.DevelopmentSidebar()
diff --git a/www/pages/static/__init__.py b/www/pages/static/__init__.py
deleted file mode 100644 (file)
index 317aa39..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-import os
-from xml.dom.minidom import parseString
-
-import web
-from web.banners import Banners
-from web.elements import Box, Releases
-from web.news import News
-
-class Xml(object):
-       def __init__(self, file):
-               file = "%s/pages/static/%s.xml" % (os.getcwd(), file,)
-               f = open(file)
-               data = f.read()
-               f.close()
-
-               self.xml = parseString(data).getElementsByTagName("Site")[0]
-
-       def getAttribute(self, node, attr):
-               return node.getAttribute(attr).strip()
-
-       def getText(self, node):
-               ret = ""
-               for i in node.childNodes:
-                       ret += i.data
-               return ret.encode("utf-8")
-
-
-class Content(Xml):
-       def __init__(self, file,):
-               Xml.__init__(self, file)
-
-       def __call__(self, lang="en"):
-               ret = ""
-               for paragraphs in self.xml.getElementsByTagName("Paragraphs"):
-                       for paragraph in paragraphs.getElementsByTagName("Paragraph"):
-                               if self.getAttribute(paragraph, "news") == "1":
-                                       news = News(int(self.getAttribute(paragraph, "count")))
-                                       ret += news(lang).encode("utf-8")
-                                       continue
-
-                               # Heading
-                               for heading in paragraph.getElementsByTagName("Heading"):
-                                       if self.getAttribute(heading, "lang") == lang or \
-                                                       not self.getAttribute(heading, "lang"):
-                                               heading = self.getText(heading)
-                                               break
-
-                               b = Box(heading)
-
-                               # Content
-                               for content in paragraph.getElementsByTagName("Content"):
-                                       if self.getAttribute(content, "lang") == lang or \
-                                                       not self.getAttribute(content, "lang"):
-                                               if self.getAttribute(content, "raw") == "1":
-                                                       s = self.getText(content)
-                                               else:
-                                                       s = "<p>%s</p>" % self.getText(content)
-                                               b.w(s)
-                               
-                               ret += b()
-               return ret
-
-
-class Sidebar(Xml):
-       def __init__(self, file):
-               Xml.__init__(self, file)
-
-       def __call__(self, lang="en"):
-               ret = ""
-               sidebar = self.xml.getElementsByTagName("Sidebar")[0]
-               for paragraph in sidebar.getElementsByTagName("Paragraph"):
-                       if self.getAttribute(paragraph, "banner") == "1":
-                               b = Banners()
-                               ret += """<h4>%(title)s</h4><a href="%(link)s" target="_blank">
-                                               <img class="banner" src="%(uri)s" /></a>""" % b.random()
-                               continue
-                       elif self.getAttribute(paragraph, "releases") == "1":
-                               r = Releases()
-                               ret += r(lang)
-                               continue
-
-                       # Heading
-                       for heading in paragraph.getElementsByTagName("Heading"):
-                               if self.getAttribute(heading, "lang") == lang or \
-                                               not self.getAttribute(heading, "lang"):
-                                       heading = self.getText(heading)
-                                       break
-
-                       ret += "<h4>%s</h4>" % heading
-
-                       # Content
-                       for content in paragraph.getElementsByTagName("Content"):
-                               if self.getAttribute(content, "lang") == lang or \
-                                               not self.getAttribute(content, "lang"):
-                                       if self.getAttribute(content, "raw") == "1":
-                                               s = self.getText(content)
-                                       else:
-                                               s = "<p>%s</p>" % self.getText(content)
-                                       ret += s
-
-               return ret
-
-class Javascript(Xml):
-       def __init__(self, file):
-               Xml.__init__(self, file)
-
-       def __call__(self, lang="en"):
-               ret = ""
-               scripts = self.xml.getElementsByTagName("Script")
-               for script in scripts:
-                       ret += self.getText(script)
-
-               return ret
-
-
-
-page = web.Page()
-page.content = Content(page.site)
-page.sidebar = Sidebar(page.site)
-page.javascript = Javascript(page.site)
diff --git a/www/pages/static/ancient_download.xml b/www/pages/static/ancient_download.xml
deleted file mode 100644 (file)
index f7c05dc..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-       <Config>
-               <Title lang="en">Downloads</Title>
-                <Title lang="de">Downloads</Title>
-       </Config>
-       <Paragraphs>
-               <Paragraph>
-                       <Heading lang="en">ancient Downloads</Heading>
-                       <Heading lang="de">ältere Downloads</Heading>
-
-                       <Content raw="1"><![CDATA[
-                               <img src="/images/box_ipfire.png" class="floatTL" alt="Download" />
-                               ]]></Content>
-
-                       <Content lang="en"><![CDATA[
-                               Here you can find all the old downloads of the ipfire project.<br />
-                               The release of <b>2.5</b> and the
-                               good old stables <b>2.3</b>, <b>2.1</b> and     <b>1.4.9</b>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Hier findet ihr alle alten Downloads des IPFire-Projektes.<br />
-                               Die stabile Version <b>2.5</b> sowie die guten alten
-                               Versionen <b>2.3</b>, <b>2.1</b> und <b>1.4.9</b>.
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               We would like to say thanks to all the people that support this project by
-                               lending their bandwidth.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Ebenso möchten wir uns an dieser Stelle bei den Personen bedanken, die die zahlreichen Mirrorserver
-                               für das Projekt zur Verfügung stellen.
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading>IPFire 2.5 Core 33</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               This is the ISO of core update <strong>33</strong>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Das ist das ISO vom Core Update <strong>33</strong>.
-                               ]]></Content>
-                       
-                       <Content raw="1"><![CDATA[
-                               <div align="right">
-                                       <a href="http://download.ipfire.org/torrent/ipfire-2.5.i586-full-core33.iso.torrent">IPFire 2.5 core33 - TORRENT - DISK</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.i586-full-core33.iso">IPFire 2.5 core33 - HTTP - DISK</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.i586-full-core33.iso.md5">MD5</a><br /><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-hdd.i586-full-core33.img.gz">IPFire 2.5 core33 - HTTP - USB (HDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-hdd.i586-full-core33.img.gz.md5">MD5</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-fdd.i586-full-core33.img.gz">IPFire 2.5 core33 - HTTP - USB (FDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-fdd.i586-full-core33.img.gz.md5">MD5</a><br /><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.xen.i586-full-core33.tar.bz2">IPFire 2.5 core33 - XEN </a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.xen.i586-full-core33.tar.bz2.md5">MD5</a><br /><br />
-                               </div>
-                               ]]></Content>
-                               <Content lang="en"><![CDATA[
-                               <div align="right">
-                                       For <a href="http://www.pcengines.ch" target="_blank" >Alix Boards</a>: <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core33.img.gz">IPFire 2.5 core33 - HTTP - FLASH 1G</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core33.img.gz.md5">MD5</a>
-                               </div>
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div align="right">
-                                       F&uuml;r <a href="http://www.pcengines.ch" target="_blank" >Alix Boards</a>: <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core33.img.gz">IPFire 2.5 core33 - HTTP - FLASH 1G</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core33.img.gz.md5">MD5</a>
-                               </div>
-                               ]]></Content>
-               </Paragraph>
-
-               <Paragraph>
-                       <Heading>IPFire 2.5</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               This is the <strong>stable</strong> 2.5 with kernel 2.6.27.25.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Die <strong>stabile</strong> Version vom 22. Juni 2009 mit Kernel 2.6.27.25.
-                               ]]></Content>
-                       
-                       <Content raw="1"><![CDATA[
-                               <div align="right">
-                                       <a href="http://download.ipfire.org/torrent/ipfire-2.5.i586-full-core28.iso.torrent">IPFire 2.5 - TORRENT - DISK</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.i586-full-core28.iso">IPFire 2.5 - HTTP - DISK</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.i586-full-core28.iso.md5">MD5</a><br /><br />
-                                       
-<!-- DIESE DATEI IST FEHLERHAFT                                
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-hdd.i586-full-core28.img.gz">IPFire 2.5 - HTTP - USB (HDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-hdd.i586-full-core28.img.gz.md5">MD5</a><br /> 
--->
-                                       
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-fdd.i586-full-core28.img.gz">IPFire 2.5 - HTTP - USB (FDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-fdd.i586-full-core28.img.gz.md5">MD5</a><br /><br />
-                               </div>
-                               ]]></Content>
-                       <Content lang="en"><![CDATA[
-                               <div align="right">
-                                       For <a href="http://www.pcengines.ch" target="_blank" >Alix Boards</a>: <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core28.img.gz">IPFire 2.5 - HTTP - FLASH 1G</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core28.img.gz.md5">MD5</a>
-                               </div>
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div align="right">
-                                       F&uuml;r <a href="http://www.pcengines.ch" target="_blank" >Alix Boards</a>: <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core28.img.gz">IPFire 2.5 - HTTP - FLASH 1G</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core28.img.gz.md5">MD5</a>
-                               </div>
-                               ]]></Content>                                   
-               </Paragraph>
-
-               <Paragraph>
-                       <Heading>IPFire 2.3</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               This is the <strong>old stable</strong> 2.3 with kernel 2.6.25.19.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Die alte <strong>stabile</strong> Version vom 8. November 2008 mit Kernel 2.6.25.19.
-                               ]]></Content>
-                       
-                       <Content raw="1"><![CDATA[
-                               <div align="right">
-                                       <a href="http://download.ipfire.org/torrent/ipfire-2.3.i586-full.iso.torrent">IPFire 2.3 - TORRENT - DISK</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.3.i586-full.iso">IPFire 2.3 - HTTP - DISK</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.3.i586-full.iso.md5">MD5</a><br /><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.3-install-usb-hdd.i586.img.gz">IPFire 2.3 - HTTP - USB (HDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.3-install-usb-hdd.i586.img.gz.md5">MD5</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.3-install-usb-fdd.i586.img.gz">IPFire 2.3 - HTTP - USB (FDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.3-install-usb-fdd.i586.img.gz.md5">MD5</a>
-                               </div>
-                               ]]></Content>   
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading>IPFire 2.1</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               This is the old stable 2.1 with kernel 2.6.16.57.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Die stabile Version vom 8. November 2007 mit Kernel 2.6.16.57.
-                               ]]></Content>
-                        <Content lang="en"><![CDATA[
-                                <b>The team recommends using IPFire 2.3.</b>
-                                ]]></Content>
-                        <Content lang="de"><![CDATA[
-                                <b>Das Team empfielt den Einsatz von IPFire 2.3.</b>
-                                ]]></Content>
-                       
-                       <Content raw="1"><![CDATA[
-                               <div align="right">
-                                       <a href="http://download.ipfire.org/torrent/ipfire-2.1.i586-full.iso.torrent">IPFire 2.1 - TORRENT - DISK</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.1.i586-full.iso">IPFire 2.1 - HTTP - DISK</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.1.i586-full.iso.md5">MD5</a><br /><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.1-install-usb-hdd.i586.img.gz">IPFire 2.1 - HTTP - USB (HDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.1-install-usb-hdd.i586.img.gz.md5">MD5</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.1-install-usb-fdd.i586.img.gz">IPFire 2.1 - HTTP - USB (FDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.1-install-usb-fdd.i586.img.gz.md5">MD5</a>
-                               </div>
-                               ]]></Content>   
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading>IPFire 1.4.9</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               The final version was released in August 2005.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Die finale Version des IPFire wurde im August 2005 veröffentlicht.
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               <b>After 4 years, the team has decided to cease support for this release.</b>
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <b>Nach 4 Jahren produktivem Einsatz hat das Team sich entschlossen<br />
-                                  den Support für diese Version einzustellen.</b>
-                               ]]></Content>
-                       
-                       <Content raw="1"><![CDATA[
-                               <div align="right">
-                                       <a href="http://download.ipfire.org/torrent/IPFire-1.4.9-FINAL.iso.torrent">IPFire 1.4.9 - TORRENT</a><br />
-                                       <a href="http://download.ipfire.org/iso/IPFire-1.4.9-FINAL.iso">IPFire 1.4.9 - HTTP</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/IPFire-1.4.9-FINAL.iso.md5">MD5</a>
-                               </div>
-                               ]]></Content>   
-               </Paragraph>
-               
-       </Paragraphs>
-
-       <Sidebar>
-               <Paragraph releases="1" />
-
-               <Paragraph>
-                   <Heading lang="en"><![CDATA[<span>Torrent</span> clients]]></Heading>
-                       <Heading lang="de"><![CDATA[<span>Torrent</span> Clients]]></Heading>   
-                       
-                       <Content raw="1"><![CDATA[
-                               <ul class="links">
-                                       <li class="first"><img src="/images/win_icon.png" alt="Windows" align="absmiddle"><img src="/images/mac_icon.png" alt="Mac OS" align="absmiddle"> <a href="http://www.utorrent.com/" target="_blank"> &micro;torrent</a></li>
-                                       <li><img src="/images/linux_icon.png" alt="Linux" align="absmiddle"><img src="/images/mac_icon.png" alt="Mac OS" align="absmiddle"> <a href="http://www.transmissionbt.com/" target="_blank">Transmission</a></li>
-                               </ul>
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph banner="1" />
-
-       </Sidebar>
-</Site>
diff --git a/www/pages/static/cebit.xml b/www/pages/static/cebit.xml
deleted file mode 100644 (file)
index 2293691..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-       <Config>
-               <Title>CeBIT-Special</Title>
-       </Config>
-       <Paragraphs>
-               <Paragraph>
-                       <Heading lang="en">IPFire on CeBIT 2010</Heading>
-                       <Heading lang="de">IPFire auf der CeBIT 2010</Heading>
-                       
-                       <Content><![CDATA[
-                               <img class="floatTR" src="/images/cebit-177px_schatten.png" alt="CeBIT" />
-                       ]]>                     
-                       </Content>
-
-                       <Content lang="en"><![CDATA[
-                                       <strong>CeBIT</strong> 2010 will be here soon, beginning March 2nd and lasting until
-                                       March 6th in Hannover, Germany. This year will prove to be a special
-                                       one, as <strong>IPFire</strong> will be represented by its very own booth in
-                                       the <strong>Open Source Project Lounge</strong>.
-                               </p>
-                               
-                               <p>
-                                       First of all, our very special thanks go out to
-                                       <a href="http://www.linuxnewmedia.de/Produkte/Events" target="_blank">Linux New Media AG</a> and
-                                       <a href="http://www.cebit.de/opensource_d" target="_blank">Messegesellschaft</a>,
-                                       who offer free booths to selected Open Source
-                                       projects. <strong>CeBIT</strong> (a German acronym for the Center for Office and
-                                       Information Technology) is the biggest computer and telecommunications
-                                       exhibition in the world. This an excellent chance for IPFire to gain
-                                       recognition, get in touch with users and developers, and possibly find
-                                       sponsors and forge alliances. 
-                               </p>
-                               <p>
-                                       And, it is also a chance for all of you to meet the members of the
-                                       <strong>IPFire</strong> community in person.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                       Vom <em>2. bis 6. März 2010</em> findet die <strong>CeBIT</strong> in Hannover statt.
-                                       Das Besondere in diesem Jahr: <strong>IPFire</strong> wird mit einem
-                                       kleinen Stand in der <strong>Open Source Project Lounge</strong> auf der Messe vertreten sein.
-                               </p>
-
-                               <p>
-                                       Zuallererst gebührt unser Dank der
-                                       <a href="http://www.linuxnewmedia.de/Produkte/Events" target="_blank">Linux New Media AG</a>
-                                       und der <a href="http://www.cebit.de/opensource_d" target="_blank">Messegesellschaft</a>,
-                                       welche für ausgewählte OpenSource-Projekte einige kostenlose Stände zur Verfügung stellen.
-                                       Die <strong>CeBIT</strong> ist immernoch die weltgrößte Computer- und Telekommunikationsmesse,
-                                       und diese Präsentationsmöglichkeit ist natürlich eine riesige Chance, das Projekt bekannter
-                                       zu machen, mehr Nutzer und Entwickler zu erreichen, bzw. Kontakte zu knüpfen und Allianzen
-                                       zu schmieden. 
-                               </p>
-                               
-                               <p>
-                                       Ebenfalls erhaltet Ihr die einmalige Chance die Entwickler einmal persönlich kennen zu lernen,
-                                       Ideen auszutauschen, und und und...
-                               </p>]]>
-                       </Content>
-               </Paragraph>
-               <Paragraph>
-                       <Heading lang="en">Your Donations are Needed!</Heading>
-                       <Heading lang="de">Spendenaufruf</Heading>
-                       
-                       <Content><![CDATA[
-                               <img class="floatTL" src="/images/paypal-folder.png" alt="Paypal" />
-                       ]]>                                             
-                       </Content>
-                       <Content lang="en"><![CDATA[
-                                       This project is driven and maintained by volunteers in their free time.
-                                       The same goes to the booth. Even though it is being donated there are
-                                       still many costs associated with running a booth, such as flyers, CDs,
-                                       posters and other merchandise.
-                               </p>
-                               <p>
-                                       As we strive to represent <strong>IPFire</strong> as professionally,
-                                       we are asking for some extra help to take advantage of this opportunity.
-                                       All we ask is a small donation, as every little bit helps. This is a unique
-                                       opportunity to gain international recognition for the project, so your
-                                       money will be well spent.
-                               </p>
-                               <p>
-                                       Materials we will be purchasing:
-                               </p>
-                               <p>
-                                       <ul>
-                                               <li>Posters</li>
-                                               <li>Flyers</li>
-                                               <li>Discs (pressed)</li>
-                                               <li>T-Shirts, etc.</li>
-                                       </ul>
-                               </p>
-                               
-                               <p>
-                                       Our favorite way for a donation is <strong>PayPal</strong> because
-                                       it is fast and easy. If you prefer a bank donation, please send
-                                       us a short <a href="mailto:&#x6d;&#x69;&#x63;&#x68;&#x61;&#x65;&#x6c;&#x2e;&#x74;&#x72;&#x65;&#x6d;&#x65;&#x72;&#x40;&#x69;&#x70;&#x66;&#x69;&#x72;&#x65;&#x2e;&#x6f;&#x72;&#x67;" class="mail JSnocheck" title="&#x6d;&#x69;&#x63;&#x68;&#x61;&#x65;&#x6c;&#x2e;&#x74;&#x72;&#x65;&#x6d;&#x65;&#x72;&#x40;&#x69;&#x70;&#x66;&#x69;&#x72;&#x65;&#x2e;&#x6f;&#x72;&#x67;">request</a>
-                                       for our bank account number.
-                               </p>
-                               <div align="center">
-                               <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
-                                       <input type="hidden" name="cmd" value="_s-xclick">
-                                       <input type="hidden" name="hosted_button_id" value="10718640">
-                                       <input type="image" src="https://www.paypal.com/en_US/GB/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
-                                       <img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
-                               </form>
-                               </div>
-                       ]]></Content>
-
-                       <Content lang="de"><![CDATA[
-                                       Dieses Projekt wird von Freiwilligen in ihrer Freizeit betrieben und betreut, was auch
-                                       für den Stand zutrifft. Man glaubt es kaum, aber selbst, wenn man einen kostenlosen
-                                       Stand zur Verfügung gestellt bekommt, entstehen hohe Kosten für Flyer, CDs, Poster und
-                                       sonstige Merchandise-Artikel.
-                               </p>
-                               <p>
-                                       Wir möchten jedoch <strong>IPFire</strong> so professioniell wie möglich präsentieren, daher ergeht
-                                       an euch Alle ein <strong>Spenden- und Mitmachaufruf</strong>.<br />
-                                       Wir möchten diese einmalige Chance nutzen und <strong>IPFire</strong> noch bekannter machen.
-                               </p>
-                               <p>
-                                       Spenden müssen nicht unbedingt finanzieller Natur sein. Es wird auch folgendes benötigt:
-                               </p>
-
-                               <p>
-                                       <ul>
-                                               <li>Poster</li>
-                                               <li>Flyer</li>
-                                               <li>CD-ROMs (bedruckt) in großer Auflage</li>
-                                               <li>Textilien mit Aufdruck</li>
-                                       </ul>
-                               </p>
-                               
-                               <p>
-                                       Wegen des einfachen Ablaufs der Spende bevorzugen wir <strong>PayPal</strong>.
-                                       Auf <a href="mailto:&#x6d;&#x69;&#x63;&#x68;&#x61;&#x65;&#x6c;&#x2e;&#x74;&#x72;&#x65;&#x6d;&#x65;&#x72;&#x40;&#x69;&#x70;&#x66;&#x69;&#x72;&#x65;&#x2e;&#x6f;&#x72;&#x67;" class="mail JSnocheck" title="&#x6d;&#x69;&#x63;&#x68;&#x61;&#x65;&#x6c;&#x2e;&#x74;&#x72;&#x65;&#x6d;&#x65;&#x72;&#x40;&#x69;&#x70;&#x66;&#x69;&#x72;&#x65;&#x2e;&#x6f;&#x72;&#x67;">Anfrage</a>
-                                       kann eine Ãœberweisung auch per Kontonummer erfolgen.
-                               </p>
-                               <div align="center">
-                               <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
-                                       <input type="hidden" name="cmd" value="_s-xclick">
-                                       <input type="hidden" name="hosted_button_id" value="10718640">
-                                       <input type="image" src="https://www.paypal.com/de_DE/DE/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
-                                       <img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
-                               </form>
-                               </div>
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading lang="en">Sponsors</Heading>
-                       <Heading lang="de">Sponsoren</Heading>
-
-                       <Content><![CDATA[
-                               <a href="http://www.linuxnewmedia.de/" target="_blank"><img src="/images/linux_new_media_ag.jpg" alt="Linux New Media AG" /></a>
-                               <a href="http://www.aktinet.de/" target="_blank"><img src="/images/aktinet_logo.jpg" alt="Aktinet IT-Services" /></a>
-                       ]]></Content>
-               </Paragraph>
-       </Paragraphs>
-       
-       <Sidebar>
-               <Paragraph>
-                       <Heading><![CDATA[<span>Ce</span>BIT]]></Heading>                       
-                       <Content lang="en"><![CDATA[
-                               <ul class="links">              
-                                       <li class="first"><a href="#IPFire on CeBIT 2010:">CeBIT 2010</a></li>
-                                       <li><a href="#Your Donations are Needed!">Donation!</a></li>
-                                       <li><a href="#Sponsors">Sponsors</a></li>
-                               </ul>
-                       ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <ul class="links">              
-                                       <li class="first"><a href="#IPFire auf der CeBIT 2010">CeBIT 2010</a></li>
-                                       <li><a href="#Spendenaufruf">Spenden!</a></li>
-                                       <li><a href="#Sponsoren">Sponsoren</a></li>
-                               </ul>
-                       ]]></Content>
-                       
-               </Paragraph>
-               
-               <Paragraph banner="1" />
-       </Sidebar>
-</Site>
diff --git a/www/pages/static/development.xml b/www/pages/static/development.xml
deleted file mode 100644 (file)
index afcd3a7..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-       <Config>
-               <Title lang="en">Development</Title>
-               <Title lang="de">Development</Title>
-       </Config>
-       <Paragraphs>
-               <Paragraph>
-                       <Heading>Development</Heading>
-                       <Content raw="1"><![CDATA[
-                               <img src="../images/development.png" class="floatTR" alt="Download" />
-                       ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                                       Welcome to the development area of the ipfire-project.<br />
-                                       These are the development ressources. The neccessary howtos<br />
-                                       are in the wiki.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                       Willkommen im Entwicklungsbereich des IPFire-Projektes.<br />
-                                       Hier habt Ihr Zugriff auf alle Ressourcen für die Entwicklung.<br />
-                                       Die nötigen Howtos entnehmt bitte dem Wiki.
-                               ]]></Content>
-
-                       <Content lang="en"><![CDATA[
-                                       <br />There is one early development version at the moment:<br />
-                                       <strong>version 3.0</strong>, the next major release, has
-                                       reached alpha state. See the roadmap at:
-                                       <a href="http://wiki.ipfire.org/en/development/3.0" target="_blank">http://wiki.ipfire.org/en/development/3.0</a>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                       <br />Zurzeit gibt eine frühe Entwicklungsversion:<br />
-                                       <strong>Version 3.0</strong>, die nächste Major-Version, hat
-                                       den Alpha-Status erreicht. Ein Roadmap findet sich unter
-                                       <a href="http://wiki.ipfire.org/de/development/3.0" target="_blank">http://wiki.ipfire.org/de/development/3.0</a>.
-                               ]]></Content>   
-                                               
-                       <Content lang="en"><![CDATA[
-                               <br /><a href="http://www.ohloh.net/projects/compare?metric=Activity&amp;project_0=IPFire&amp;project_1=Smoothwall&amp;project_2=IPCop+Firewall" target="_blank">Comparison of IPFire to IPCop and Smoothwall on ohloh.net</a>
-                               ]]></Content>
-
-                       <Content lang="de"><![CDATA[
-                               <br /><a href="http://www.ohloh.net/projects/compare?metric=Activity&amp;project_0=IPFire&amp;project_1=Smoothwall&amp;project_2=IPCop+Firewall" target="_blank">IPFire im Vergleich mit IPCop und Smoothwall auf ohloh.net</a>
-                               ]]></Content>                           
-               </Paragraph>
-               <Paragraph>
-                       <Heading>git</Heading>
-                       <Content lang="en"><![CDATA[
-                                       Our source code repository is managed by
-                                       <a href="http://git.or.cz" target="_blank">git</a>.
-                                       Your will find a howto for working with git in our
-                                       <a href="http://wiki.ipfire.org/en/development/git" target="_blank">wiki</a>.
-                                       <br />
-                                       You may also browse the our source code on: <a href="http://git.ipfire.org/" target="_blank">http://git.ipfire.org/</a>
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                       Das Quellcode-Repository wird durch
-                                       <a href="http://git.or.cz" target="_blank">Git</a>
-                                       verwaltet. Ein Howto zum Arbeiten mit Git findet ihr
-                                       in unserem <a href="http://wiki.ipfire.org/de/development/git" target="_blank">Wiki</a>.
-                                       <br />
-                                       Browsen könnt ihr unseren Source-Code unter: <a href="http://git.ipfire.org/" target="_blank">http://git.ipfire.org/</a>
-                               ]]></Content>
-               </Paragraph>
-               <Paragraph>
-                       <Heading>source-code</Heading>
-                       <Content lang="en"><![CDATA[
-                                               The source code tarballs of the in ipfire used tools are on
-                                               <a href="http://source.ipfire.org/" target="_target">http://source.ipfire.org/</a>.<br />
-                                               All patches that are used in our distribution are stored in a git repository.
-                                               Therefore see "git" on this site.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                       Die Sourcecode-Tarballs der im IPFire verwendeten Tools findet Ihr unter
-                                       <a href="http://source.ipfire.org/" target="_target">http://source.ipfire.org/</a><br />
-                                       Alle Patches, die in der Distribution Verwendung finden werden in einem
-                                       Git-Repository verwaltet. Siehe dazu Git.
-                               ]]></Content>
-               </Paragraph>
-               <Paragraph>
-                       <Heading>bugtracker</Heading>
-                       <Content lang="en"><![CDATA[
-                                       We manage all issues in our <a href="http://bugtracker.ipfire.org" target="_blank">bugtracker</a>.<br />
-                                       It is important for development to create detailed bug reports that
-                                       we can work with them fastly.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                       Im <a href="http://bugtracker.ipfire.org" target="_blank">Bugtracker</a> findet Ihr bekannte Fehler.<br />
-                                       Für die Entwicklung ist es wichtig, dass es ausführliche Bug-Reports gibt,
-                                       die dann rasch bearbeitet werden können.
-                               ]]></Content>
-               </Paragraph>
-               <Paragraph>
-                       <Heading>nightly-builds</Heading>
-                       <Content lang="en"><![CDATA[
-                                       Compiled development versions for testing purposes
-                                       will be built (automatically).<br />
-                                       Version 3:              <a href="ftp://ftp.ipfire.org/pub/nightly-builds/" target="_blank">ftp://ftp.ipfire.org/pub/nightly-builds/</a><br />
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                       Fertig kompilierte Entwicklerversionen der aktuellen
-                                       Entwicklungszweige werden in kurzen Abständen
-                                       (automatisch) gebaut.<br />
-                                        Version 3:              <a href="ftp://ftp.ipfire.org/pub/nightly-builds/" target="_blank">ftp://ftp.ipfire.org/pub/nightly-builds/</a><br />
-                               ]]></Content>
-               </Paragraph>
-       </Paragraphs>
-       <Sidebar>
-               <Paragraph>
-                       <Heading><![CDATA[<span>Development</span> Zone]]></Heading>
-                       
-                       <Content lang="en"><![CDATA[
-                               <ul class="links">
-                                       <li class="first"><a href="#git">git</a></li>
-                                       <li><a href="#source-code">sourcecode</a></li>
-                                       <li><a href="#bugtracker">bugtracker</a></li>
-                                       <li><a href="#nightly-builds">nighty builds</a></li>
-                               </ul>
-                               ]]></Content>                           
-                       <Content lang="de"><![CDATA[
-                               <ul class="links">
-                                       <li class="first"><a href="#git">Git</a></li>
-                                       <li><a href="#source-code">Sourcecode</a></li>
-                                       <li><a href="#bugtracker">Bugtracker</a></li>
-                                       <li><a href="#nightly-builds">Nighty-Builds</a></li>
-                               </ul>
-                               ]]></Content>
-               </Paragraph>
-       </Sidebar>
-</Site>
diff --git a/www/pages/static/download.xml b/www/pages/static/download.xml
deleted file mode 100644 (file)
index a593423..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-       <Config>
-               <Title lang="en">Downloads</Title>
-                <Title lang="de">Downloads</Title>
-       </Config>
-       <Paragraphs>
-               <Paragraph>
-                       <Heading>Downloads</Heading>
-
-                       <Content raw="1"><![CDATA[
-                               <img src="/images/box_ipfire.png" class="floatTL" alt="Download" />
-                               ]]></Content>
-
-                       <Content lang="en"><![CDATA[
-                               Here you can find the latest downloads of the ipfire project.<br />
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Hier findet ihr die neusten Downloads des IPFire-Projektes.<br />
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               We would like to say thanks to all the people that support this project by
-                               lending their bandwidth.<br /><br /><br /><br /><br />
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Ebenso möchten wir uns an dieser Stelle bei den Personen bedanken, die die zahlreichen Mirrorserver
-                               für das Projekt zur Verfügung stellen.<br /><br /><br /><br />
-                               ]]></Content>
-                       
-                       <Content raw="1"><![CDATA[
-                               <div class="button">
-                                       <div class="button_text">
-                                               <a href="http://download.ipfire.org/iso/ipfire-2.5.i586-full-core34.iso">&nbsp;IPFire 2.5 - Core 34&nbsp; </a>
-                                       </div>
-                               </div>
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading>IPFire 2.5 (latest Core)</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               This is the iso including the latest core update <strong>34</strong>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Das ist das ISO inklusive dem letzten Core Update <strong>34</strong>.
-                               ]]></Content>
-                       
-                       <Content raw="1"><![CDATA[
-                               <div align="right">
-                                       <a href="http://download.ipfire.org/torrent/ipfire-2.5.i586-full-core34.iso.torrent">IPFire 2.5 core34 - TORRENT - DISK</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.i586-full-core34.iso">IPFire 2.5 core34 - HTTP - DISK</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.i586-full-core34.iso.md5">MD5</a><br /><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-hdd.i586-full-core34.img.gz">IPFire 2.5 core34 - HTTP - USB (HDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-hdd.i586-full-core34.img.gz.md5">MD5</a><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-fdd.i586-full-core34.img.gz">IPFire 2.5 core34 - HTTP - USB (FDD)</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5-install-usb-fdd.i586-full-core34.img.gz.md5">MD5</a><br /><br />
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.xen.i586-full-core34.tar.bz2">IPFire 2.5 core34 - XEN </a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.xen.i586-full-core34.tar.bz2.md5">MD5</a><br /><br />
-                               </div>
-                               ]]></Content>
-                               <Content lang="en"><![CDATA[
-                               <div align="right">
-                                       For <a href="http://www.pcengines.ch" target="_blank" >Alix Boards</a>: <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core34.img.gz">IPFire 2.5 core34 - HTTP - FLASH 1G</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core34.img.gz.md5">MD5</a>
-                               </div>
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div align="right">
-                                       F&uuml;r <a href="http://www.pcengines.ch" target="_blank" >Alix Boards</a>: <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core34.img.gz">IPFire 2.5 core34 - HTTP - FLASH 1G</a>&nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-2.5.1gb-ext2-scon.i586-full-core34.img.gz.md5">MD5</a>
-                               </div>
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading lang="en">ancient IPFire builds</Heading>
-                       <Heading lang="de">ältere IPFire Versionen</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               Ancient versions can be found by browsing to <a href="ancient_download">here</a>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Ã„ltere Versionen findet man <a href="ancient_download">hier</a>.
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading lang="en">Development builds</Heading>
-                       <Heading lang="de">Entwicklungsversionen</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               One of us builds installation images for testing purposes regularly.
-                               These are ready for download, but do not use them for systems in a productive environment.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               In regelmäßigen Abständen wird aus dem aktuellen Quellcode
-                               der Entwicklungsversionen ein installationsfähiges Image, welches man downloaden kann, erstellt.
-                               <br />Diese Versionen dienen dem Test und sind unter Umständen nicht für den
-                               Produktiveinsatz geeignet.
-                               ]]></Content>
-                       
-                       <Content raw="1"><![CDATA[
-                               <div align="right">
-                                       <a href="http://download.ipfire.org/iso/ipfire-3.0-alpha1.i686.iso">IPFire 3 - Alpha1</a>
-                                       &nbsp;
-                                       <a href="http://download.ipfire.org/iso/ipfire-3.0-alpha1.i686.iso.md5">MD5</a><br />
-                                       </div>
-                               ]]></Content>
-                       <Content raw="1" lang="en"><![CDATA[
-                               <div align="right">
-                                       <a href="builds">nightly builds</a>
-                                       </div>
-                               ]]></Content>
-                       <Content raw="1" lang="de"><![CDATA[
-                               <div align="right">
-                                       <a href="builds">Nightly Builds</a>
-                                       </div>
-                               ]]></Content>
-               </Paragraph>
-               
-       </Paragraphs>
-
-       <Sidebar>
-               <Paragraph releases="1" />
-
-               <Paragraph>
-                   <Heading lang="en"><![CDATA[<span>Torrent</span> clients]]></Heading>
-                       <Heading lang="de"><![CDATA[<span>Torrent</span> Clients]]></Heading>   
-                       
-                       <Content raw="1"><![CDATA[
-                               <ul class="links">
-                                       <li class="first"><img src="/images/win_icon.png" alt="Windows" align="absmiddle"><img src="/images/mac_icon.png" alt="Mac OS" align="absmiddle"> <a href="http://www.utorrent.com/" target="_blank"> &micro;torrent</a></li>
-                                       <li><img src="/images/linux_icon.png" alt="Linux" align="absmiddle"><img src="/images/mac_icon.png" alt="Mac OS" align="absmiddle"> <a href="http://www.transmissionbt.com/" target="_blank">Transmission</a></li>
-                               </ul>
-                               ]]></Content>
-               </Paragraph>
-
-               <Paragraph banner="1" />
-
-       </Sidebar>
-</Site>
diff --git a/www/pages/static/imprint.xml b/www/pages/static/imprint.xml
deleted file mode 100644 (file)
index 586dbe9..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-       <Config>
-               <Title lang="en">Imprint</Title>
-               <Title lang="de">Imprint</Title>
-       </Config>
-       <Paragraphs>
-               <Paragraph>
-                       <Heading>IPFire is OpenSource</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               Because of the fact that the people who started this project are living
-                               in Germany, see the <a href="/de/imprint">german legal notes</a>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Dieses Projekt ist ein Open-Source-Projekt und verfolgt keine kommerziellen Ziele.
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <b>Die Distribution "IPFire" steht unter der GPLv3 zur Verfügung und darf den Bedingung zufolge weitergegeben werden.</b>
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                                                       Michael Tremer (<a href="mailto:michael@ipfire.org">michael@ipfire.org</a>)<br />
-                                       Gerhardstrasse 8<br />
-                                       45711 Datteln<br /><br />
-
-                                       Christian Schmidt (<a href="mailto:maniacikarus@ipfire.org">maniacikarus@ipfire.org</a>)<br />
-                                       Mathildenstr. 25<br />
-                                       90489 Nürnberg<br /><br />
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <b>1. Inhalt des Onlineangebotes</b><br />
-                                       Der Autor Ã¼bernimmt keinerlei Gewähr für die Aktualität, Korrektheit, Vollständigkeit 
-                                       oder Qualität der bereitgestellten Informationen. Haftungsansprüche gegen den Autor, 
-                                       welche sich auf Schäden materieller oder ideeller Art beziehen, die durch die Nutzung 
-                                       oder Nichtnutzung der dargebotenen Informationen bzw. durch die Nutzung fehlerhafter 
-                                       und unvollständiger Informationen verursacht wurden, sind grundsätzlich ausgeschlossen, 
-                                       sofern seitens des Autors kein nachweislich vorsätzliches oder grob fahrlässiges 
-                                       Verschulden vorliegt.<br />
-                                       Alle Angebote sind freibleibend und unverbindlich. Der Autor behält es sich ausdrücklich vor, 
-                                       Teile der Seiten oder das gesamte Angebot ohne gesonderte Ankündigung zu verändern, 
-                                       zu ergänzen, zu löschen oder die Veröffentlichung zeitweise oder endgültig einzustellen.
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <b>2. Verweise und Links</b><br />
-                                       Bei direkten oder indirekten Verweisen auf fremde Internetseiten ("Links"), 
-                                       die außerhalb des Verantwortungsbereiches des Autors liegen, würde eine 
-                                       Haftungsverpflichtung ausschließlich in dem Fall in Kraft treten, in dem der 
-                                       Autor von den Inhalten Kenntnis hat und es ihm technisch möglich und zumutbar wäre, 
-                                       die Nutzung im Falle rechtswidriger Inhalte zu verhindern. <br />
-                                       Der Autor erklärt hiermit ausdrücklich, dass zum Zeitpunkt der Linksetzung keine 
-                                       illegalen Inhalte auf den zu verlinkenden Seiten erkennbar waren. 
-                                       Auf die aktuelle und zukünftige Gestaltung, die Inhalte oder die Urheberschaft 
-                                       der gelinkten/verknüpften Seiten hat der Autor keinerlei Einfluss. Deshalb distanziert 
-                                       er sich hiermit ausdrücklich von allen Inhalten aller gelinkten /verknüpften Seiten, 
-                                       die nach der Linksetzung verändert wurden. Diese Feststellung gilt für alle innerhalb 
-                                       des eigenen Internetangebotes gesetzten Links und Verweise sowie für Fremdeinträge 
-                                       in vom Autor eingerichteten Gästebüchern, Diskussionsforen und Mailinglisten. 
-                                       Für illegale, fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, 
-                                       die aus der Nutzung oder Nichtnutzung solcherart dargebotener Informationen entstehen, 
-                                       haftet allein der Anbieter der Seite, auf welche verwiesen wurde, nicht derjenige, 
-                                       der Ã¼ber Links auf die jeweilige Veröffentlichung lediglich verweist.
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <b>3. Urheber- und Kennzeichenrecht </b><br />
-                                       Der Autor ist bestrebt, in allen Publikationen die Urheberrechte der verwendeten Grafiken, 
-                                       Tondokumente, Videosequenzen und Texte zu beachten, von ihm selbst erstellte Grafiken, 
-                                       Tondokumente, Videosequenzen und Texte zu nutzen oder auf lizenzfreie Grafiken, Tondokumente, 
-                                       Videosequenzen und Texte zurückzugreifen. <br />
-                                       Alle innerhalb des Internetangebotes genannten und ggf. durch Dritte geschützten Marken- 
-                                       und Warenzeichen unterliegen uneingeschränkt den Bestimmungen des jeweils gültigen Kennzeichenrechts 
-                                       und den Besitzrechten der jeweiligen eingetragenen Eigentümer. Allein aufgrund der bloßen Nennung 
-                                       ist nicht der Schluss zu ziehen, dass Markenzeichen nicht durch Rechte Dritter geschützt sind! <br />
-                                       Das Copyright für veröffentlichte, vom Autor selbst erstellte Objekte bleibt allein beim Autor der Seiten. 
-                                       Eine Vervielfältigung oder Verwendung solcher Grafiken, Tondokumente, Videosequenzen und Texte in 
-                                       anderen elektronischen oder gedruckten Publikationen ist ohne ausdrückliche Zustimmung des Autors nicht gestattet.
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <b>4. Datenschutz </b><br />
-                                       Sofern innerhalb des Internetangebotes die Möglichkeit zur Eingabe persönlicher oder geschäftlicher Daten 
-                                       (Emailadressen, Namen, Anschriften) besteht, so erfolgt die Preisgabe dieser Daten seitens 
-                                       des Nutzers auf ausdrücklich freiwilliger Basis. Die Inanspruchnahme und Bezahlung aller 
-                                       angebotenen Dienste ist - soweit technisch möglich und zumutbar - auch ohne Angabe solcher Daten 
-                                       bzw. unter Angabe anonymisierter Daten oder eines Pseudonyms gestattet. Die Nutzung der im Rahmen 
-                                       des Impressums oder vergleichbarer Angaben veröffentlichten Kontaktdaten wie Postanschriften, 
-                                       Telefon- und Faxnummern sowie Emailadressen durch Dritte zur Ãœbersendung von nicht ausdrücklich 
-                                       angeforderten Informationen ist nicht gestattet. Rechtliche Schritte gegen die Versender von 
-                                       sogenannten Spam- Mails bei Verstössen gegen dieses Verbot sind ausdrücklich vorbehalten.
-                               ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <b>5. Rechtswirksamkeit dieses Haftungsausschlusses </b><br />
-                                       Dieser Haftungsausschluss ist als Teil des Internetangebotes zu betrachten, von dem aus auf diese 
-                                       Seite verwiesen wurde. Sofern Teile oder einzelne Formulierungen dieses Textes der geltenden 
-                                       Rechtslage nicht, nicht mehr oder nicht vollständig entsprechen sollten, bleiben die Ã¼brigen 
-                                       Teile des Dokumentes in ihrem Inhalt und ihrer Gültigkeit davon unberührt.
-                               ]]></Content>
-                               
-                       <Content lang="en"><![CDATA[
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Dieses Impressum gilt für alle mit dem IPFire-Projekt verbundenen Webseiten (Forum, etc.).
-                               ]]></Content>
-               </Paragraph>
-  </Paragraphs>
-  <Sidebar>
-  </Sidebar>
-</Site>
diff --git a/www/pages/static/index.xml b/www/pages/static/index.xml
deleted file mode 100644 (file)
index 735a063..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-       <Config>
-               <Title lang="en">Welcome</Title>
-               <Title lang="de">Willkommen</Title>
-       </Config>
-       <Paragraphs>
-               <Paragraph>
-                       <Heading lang="en">more security for your network</Heading>
-                       <Heading lang="de">mehr Sicherheit für Ihr Netzwerk</Heading>
-
-                       <Content lang="en"><![CDATA[
-                               <strong>IPFire</strong> is a linux-distribution that focusses on easy setup, good handling and a 
-                               <strong>high niveau of security</strong>.<br /> It is operable via an intuitive webinterface, which offers a
-                                lot of playground for <strong>beginners</strong> and even experienced <strong>administrators</strong>.
-                                <strong>IPFire</strong> is maintained by experienced developers, who are really concerned about security and regulary 
-                                updates to <strong>keep it secure</strong>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Das <strong>IPFire</strong>-System ist eine Linux-Distribution, welche die Zielsetzung hat ein einfach zu 
-                               installierendes Grundsystem zu bieten und dabei ein <strong>hohes Sicherheitsniveau</strong> zu gewährleisten.
-                               <strong>IPFire</strong> ist komplett Ã¼ber sein intuitiv zu bedienendes Webinterface zu konfigurieren 
-                               und bietet sowohl <strong>Anfängern</strong>, als auch erfahrenen <strong>Administratoren</strong> eine Fülle von 
-                               Einstellungsmöglichkeiten. Ein <strong>Schwerpunkt</strong> bei der Weiterentwickling legen die erfahrenen Entwickler 
-                               klar auf regelmäßige System und vor allem <strong>Sicherheitsupdates</strong>.<br /><br />
-                               ]]></Content>
-
-                       <Content lang="en"><![CDATA[
-                               <strong>IPFire</strong> ships with a custom built paket-manager called <strong>Pakfire</strong>, so the system can be 
-                               expanded with various <a href="http://wiki.ipfire.org/en/addons/start" target="_blank">addons</a>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               Durch den integrierten Paketmanager <strong>Pakfire</strong> lässt sich der <strong>IPFire</strong> mit diversen 
-                               <a href="http://wiki.ipfire.org/de/addons/start" target="_blank">Addons</a>, 
-                               bishin zu einem Server-System erweitern.
-                               ]]></Content>
-       
-                       <Content lang="en"><![CDATA[
-                               <div class="cebit_button">
-                                       <div class="cebit_button_text">                                         
-                                               <a href="cebit">CeBIT-Donation</a>
-                                       </div>
-                               </div> 
-                       ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div class="cebit_button">
-                                       <div class="cebit_button_text">                                         
-                                               <a href="cebit">CeBIT-Spende</a>
-                                       </div>
-                               </div>
-                       ]]></Content>
-
-                       <Content raw="1"><![CDATA[
-                               <img src="/images/Network-1.png" alt="IPFire Logo" />
-                               ]]></Content>
-                               
-                       <Content lang="en"><![CDATA[
-                               <br /><strong>IPFire</strong> is a <strong>GPLv3</strong>-licensed project developed and maintained by 
-                               an open <strong>community</strong> of developers.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <br /><strong>IPFire</strong> ist eine freie Software, die unter der <strong>GPLv3</strong> lizensiert ist und 
-                               von einer offenen <strong>Community</strong> entwickelt wird.
-                               ]]></Content>
-                       
-               <!--    <Content raw="1"><![CDATA[
-                               <div class="button">
-                                       <div class="button_text">
-                                               <a href="download">Download&nbsp;&nbsp;IPFire 2.5</a>
-                                       </div>
-                               </div>
-                       ]]></Content> -->
-                                       
-               </Paragraph>
-               
-               <Paragraph news="1" count="3" />
-       </Paragraphs>
-       
-       <Sidebar>
-               <Paragraph releases="1" />
-
-               <Paragraph>
-                       <Heading><![CDATA[<span>Internet Relay</span> Chat]]></Heading>
-                       <Content><![CDATA[
-                               <b>Server:</b> irc.freenode.net<br />
-                               <b>Channel:</b> #ipfire<br />
-                               <a href="http://webchat.freenode.net/?channels=ipfire" target="_blank">Web-Chat</a>
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph banner="1" />
-
-               <Paragraph>
-                       <Heading><![CDATA[<span>RSS</span> feed]]></Heading>
-
-                       <Content lang="en"><![CDATA[
-                               <a class="feed" href="news.rss">IPFire - News</a>
-                               <br />
-                               <a href="news">news archive</a><br />]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <a class="feed" href="news.rss">IPFire - News</a>
-                               <br />
-                               <a href="news">News-Archiv</a><br /><br />]]></Content>
-               </Paragraph>
-               
-       </Sidebar>
-</Site>
diff --git a/www/pages/static/links.xml b/www/pages/static/links.xml
deleted file mode 100644 (file)
index ea73492..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-        <Config>
-                <Title lang="en">Links</Title>
-                <Title lang="de">Links</Title>
-        </Config>
-        <Paragraphs>
-                <Paragraph>
-                        <Heading>Links</Heading>
-                        <Content raw="1"><![CDATA[
-                                                       <img src="../images/links.png" class="floatTR" alt="Links" />
-                                                               ]]></Content>
-                        
-                        <Content lang="en"><![CDATA[
-                                                                                                               On this page, one can find a lot of external information about the <strong>IPFire-Project</strong>.
-                                                                                                               There are some links to our partners, friends or sponsors and of course references to articles by
-                                                                                                               some magazines.
-                                ]]></Content>
-                        <Content lang="de"><![CDATA[
-                                                                                                                                       Hier findet ihr alle relevanten Links zum Projekt IPFire. Neben Partnerseiten, Freunden und
-                                                                                                                                       Sponsoren findet ihr auch Artikel Ã¼ber IPFire die von Benutzern oder anderen Projektseiten
-                                                                                                                                       und Zeitschriften verfasst wurden.
-                                ]]></Content>
-                </Paragraph>
-                <Paragraph>
-                        <Heading>Friends of IPFire</Heading>
-                        <Content lang="en"><![CDATA[
-                                                                                                               The following users do great jobs in this project. They support us by giving servers to us or
-                                                                                                               they do mirror the web pages on their own server. Because IPFire is growing fast, we need much
-                                                                                                               of such capacity.
-                                ]]></Content>
-                        <Content lang="de"><![CDATA[
-                                                                                                                                       Folgende unter aufgelistete User ermöglichen dem Projekt die Nutzung ihrer Server (Mirror, Build
-                                                                                                                                       und Root Server). An dieser Stelle noch mal ein großes Dankeschön für euren Beitrag. Die ständig
-                                                                                                                                       steigende Benutzerzahl verlangt immer schnellere Anbindungen und Datenvolumina.
-                                ]]></Content>
-                        <Content><![CDATA[
-                                                                                                                                       <table>
-                                                                                                                                         <tr>
-                                                                                                                                           <td><a href="http://www.firewall-service.com" target="_blank">http://www.firewall-service.com</a></td>
-                                                                                                                                           <td>Rene Zingel</td>
-                                                                                                                                         </tr>
-                                                                                                                                         <tr>
-                                                                                                                                           <td><a href="http://www.rowie.at" target="_blank">http://www.rowie.at</a></td>
-                                                                                                                                           <td>Ronald Wiesinger</td>
-                                                                                                                                         </tr>
-                                                                                                                                         <tr>
-                                                                                                                                           <td><a href="http://www.scp-systems.ch" target="_blank">http://www.scp-systems.ch</a></td>
-                                                                                                                                           <td>Peter Schaelchli</td>
-                                                                                                                                         </tr>
-                                                                                                                                         <tr>
-                                                                                                                                           <td><a href="http://www.kbarthel.de" target="_blank">http://www.kbarthel.de</a></td>
-                                                                                                                                           <td>Kim Barthel</td>
-                                                                                                                                         </tr>
-                                                                                                                                         <tr>
-                                                                                                                                           <td><a href="http://ipfire.earl-net.com" target="_blank">http://ipfire.earl-net.com</a></td>
-                                                                                                                                           <td>Jan Paul Tücking</td>
-                                                                                                                                         </tr>
-                                                                                                                                         <tr>
-                                                                                                                                           <td>Seite im Aufbau</td>
-                                                                                                                                           <td>Sebastian Winter</td>
-                                                                                                                                         </tr>
-                                                                                                                                       </table>
-                                                                                       <br />
-                                ]]></Content>
-                                <Content lang="en"><![CDATA[
-                                                               Marcus Scholz (Commander1024) did a <strong>talk</strong> about IPFire at the 
-                                                               <em>Warpzone</em>,
-                                                               a <a href="http://www.commander1024.de/wordpress/wp-content/uploads/2009/12/IPFire-Talk.pdf">draft</a> is available as well as a <a href="http://qik.com/video/3807703">video</a>.
-                               ]]></Content>
-                                <Content lang="de"><![CDATA[
-                                                               Marcus Scholz (Commander1024) hat einen <strong>Vortrag</strong> Ã¼ber IPFire in der 
-                                                               <em>Warpzone</em>
-                                                               gehalten, wer will kann sich das <a href="http://www.commander1024.de/wordpress/wp-content/uploads/2009/12/IPFire-Talk.pdf">Paper</a> wie auch das <a href="http://qik.com/video/3807703">Video</a> des Vortrags anschauen.
-                               ]]></Content>
-                </Paragraph>
-                <Paragraph>
-                               <Heading lang="en">IPFire in Media</Heading>
-                        <Heading lang="de">IPFire in den Medien (diverse Zeitschriften)</Heading>
-                        <Content lang="en"><![CDATA[
-                                                               Often, there are some magazines publishing articles about IPFire.
-                                                                                       This is a short list to online-versions of them (Mostly in German):
-                               ]]></Content>
-                        <Content lang="de"><![CDATA[
-                                                               Immer Ã¶fter berichten uns User und Teammitglieder von diversen Zeitschriften in denen IPFire
-                                                                                                                                       erwähnt wird. Hier sind Einige davon:
-                                ]]></Content>
-                        <Content><![CDATA[
-                                                                                                                                       <a href="http://linuxmini.blogspot.com/2007/10/ipfire-free-firewall-for-your-home-or.html">http://linuxmini.blogspot.com/2007/10/ipfire-free-firewall-for-your-home-or.html</a><br />
-                                                                                                                                       <a href="http://www.pro-linux.de/news/2006/9219.html">http://www.pro-linux.de/news/2006/9219.html</a><br />
-                                                                                                                                       <a href="http://www.kriptopolis.org/ipfire">http://www.kriptopolis.org/ipfire</a><br />
-                                                                                                                                       <a href="http://freedommafia.net/main/index.php?option=com_content&task=view&id=103&Itemid=47">http://freedommafia.net/main/index.php?option=com_content&task=view&id=103&Itemid=47</a><br />
-                                                                                                                                       <a href="http://www.lintelligence.de/news/1026">http://www.lintelligence.de/news/1026</a><br />
-                                                                                                                                       <a href="http://www.techmonkey.de/2008/09/15/ipfire-der-nachste-star-am-soho-himmel/">http://www.techmonkey.de/2008/09/15/ipfire-der-nachste-star-am-soho-himmel/</a><br />
-                                                                                                                                       <a href="http://www.pcwelt.de/start/sicherheit/firewall/news/187759/ipfire_auf_version_23_aktualisiert/">http://www.pcwelt.de/start/sicherheit/firewall/news/187759/ipfire_auf_version_23_aktualisiert/</a><br />
-                                                          ]]></Content>
-                </Paragraph>
-                <Paragraph>
-                               <Heading lang="en">Discussion about IPFire</Heading>
-                        <Heading lang="de">Boards und Foren (Diskussionen Ã¼ber IPFire)</Heading>
-                        <Content lang="en"><![CDATA[
-                                                                                                               Users' recommendations do best! - This are links to threads in boards where users talk about IPFire:
-                                ]]></Content>
-                        <Content lang="de"><![CDATA[
-                                                                                                                                       Mundpropaganda sagt man, ist die beste Werbung! Hier ein paar Boards und Foren, wo man sich
-                                                                                                                                       gepflegt Ã¼ber IPFire unterhält und Erfahrungen austauscht.
-                                ]]></Content>
-                        <Content><![CDATA[
-                                                                                                                                       <a href="http://forum.linuxcast.eu/viewtopic.php?f=13&p=438">http://forum.linuxcast.eu/viewtopic.php?f=13&p=438</a><br />
-                                                                                                                                       <a href="http://forum.golem.de/read.php?26129,1364598,1364598#msg-1364598">http://forum.golem.de/read.php?26129,1364598,1364598#msg-1364598</a><br />
-                                                                                                                                       <a href="http://www.ipcop-forum.de/forum/viewtopic.php?f=28&t=21055&hilit=IPFire">http://www.ipcop-forum.de/forum/viewtopic.php?f=28&t=21055&hilit=IPFire</a><br />
-                                                                                                                                       <a href="http://forum.cdrinfo.pl/f102/jaki-dysk-sieciowy-78524/">http://forum.cdrinfo.pl/f102/jaki-dysk-sieciowy-78524/</a><br />
-                                                                                                                                       <a href="http://forum.mini-pc-pro.de/projekt-forum/3681-epia-ipcop-router-projekt-wirft-mir-diverse-fragen-auf.html">http://forum.mini-pc-pro.de/projekt-forum/3681-epia-ipcop-router-projekt-wirft-mir-diverse-fragen-auf.html</a><br />
-                                                                                                                                       <a href="http://nachtwandler.blogage.de/entries/2008/10/4/IPFire">http://nachtwandler.blogage.de/entries/2008/10/4/IPFire</a><br />
-                                                                                                                                       <a href="http://zahlenzerkleinerer.de/1085/der-erste-ipfire-test.html">http://zahlenzerkleinerer.de/1085/der-erste-ipfire-test.html</a><br />
-                                ]]></Content>
-                </Paragraph>
-                <Paragraph>
-                               <Heading lang="en">Sites that link to here</Heading>
-                        <Heading lang="de">Nach IPFire verlinkende Seiten</Heading>
-                        <Content lang="en"><![CDATA[
-                                                                                                               We are glad to give a list of sites that link to us. So, we would do this back again:
-                                                       ]]></Content>
-                        <Content lang="de"><![CDATA[
-                                                                                                                                       Am meisten Freuen wir uns aber Ã¼ber Seitenbetreiber die einen Link auf unsere Projektseite setzen,
-                                                                                                                                       um auch andere User auf uns hinzuweisen. Hier ein paar davon:
-                                ]]></Content>
-                        <Content><![CDATA[
-                                                                                                                                       <a href="http://www.ohloh.net/projects/ipfire">http://www.ohloh.net/projects/ipfire</a><br />
-                                                                                                                                       <a href="http://forum.softgil.com/weblinks.php?cat_id=1">http://forum.softgil.com/weblinks.php?cat_id=1</a><br />
-                                ]]></Content>
-                        
-                </Paragraph>
-        </Paragraphs>
-        <Sidebar>
-                <Paragraph>
-                               <Heading lang="en"><![CDATA[<span>more</span> links]]></Heading>
-                                               <Heading lang="de"><![CDATA[<span>mehr</span> links]]></Heading>
-
-                        <Content lang="en"><![CDATA[
-                                                                                                               If there are relevant links on sites that are not known to the IPFire project, please let us know!                                                                                                                                              (via forum or irc)<br />We are grateful for any assistance!
-                                       ]]></Content>
-                        <Content lang="de"><![CDATA[
-                                                                                                                                       Solltet ihr weitere relevante Links zum Projekt IPFire irgendwo entdecken, lasst es uns bitte
-                                                                                                                                       wissen! (via Forum oder IRC)<br />Für jede Hilfe sind wir dankbar!
-                                ]]></Content>
-                </Paragraph>
-        </Sidebar>
-</Site>
diff --git a/www/pages/static/news.xml b/www/pages/static/news.xml
deleted file mode 100644 (file)
index fe2fa5f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-       <Config>
-               <Title>News</Title>
-       </Config>
-       <Paragraphs>
-               <Paragraph>
-                       <Heading lang="en">IPFire News Archive</Heading>
-                       <Heading lang="de">IPFire-News-Archiv</Heading>
-                       
-                       <Content lang="en"><![CDATA[
-                               In a big project like this, it might being simple to keep up
-                               with progress. That doesn't matter. This site will give you
-                               all information you need.<br />
-                               Additionally, you may subscribe to our 
-                               <a class="feed" href="/en/news.rss">rss feed</a>.
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               In einem Projekt wie IPFire ist es nicht leicht sich auf dem
-                               neuesten Stand zu halten. Dazu gibt es aber diese Seite, auf
-                               der man alles wichtige chronologisch angeordnet nachlesen kann.
-                               <br />
-                               Weiterhin gibt es einen 
-                               <a class="feed" href="/de/news.rss">RSS-Feed</a>, der sich abbonieren
-                               lässt.
-                               ]]></Content>
-               </Paragraph>
-
-               <Paragraph news="1" count="50" />
-       </Paragraphs>
-       
-       <Sidebar>
-               <Paragraph banner="1" />
-       </Sidebar>
-</Site>
diff --git a/www/pages/static/screenshots.xml b/www/pages/static/screenshots.xml
deleted file mode 100644 (file)
index ed54c85..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Site>
-       <Config>
-               <Title lang="en">Screenshots</Title>
-               <Title lang="de">Screenshots</Title>
-       </Config>
-       <Script><![CDATA[
-               <script src="/include/jquery.min.js" type="text/javascript"></script>
-               <script type="text/javascript" src="/include/jquery.lightbox.min.js"></script>
-               <script type="text/javascript">
-                       $(function() {
-                               $("#screenshots a").lightBox();
-                       });
-               </script>
-       ]]></Script>    
-       <Paragraphs>
-               <Paragraph><Heading>Screenshots</Heading>
-                       <Content raw="1"><![CDATA[
-                               <img src="../images/screenshots/monitor.png" class="floatTR" alt="Screenshots" />
-                       ]]></Content>
-                       
-                       <Content lang="en"><![CDATA[
-                                       Here you will find an insight into the IPFire webinterface.<br />
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                                       Hier findet Ihr einen keinen Einblick in das IPFire Webinterface.<br />
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph><Heading>System</Heading>
-                       <Content lang="en"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;                              
-                                       <a href="/images/screenshots/index_en.png" title="Home"><img src="/images/screenshots/index_en_tn.png" border="0" alt="Home"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/backup_en.png" title="Backup"><img src="/images/screenshots/backup_en_tn.png" border="0" alt="Backup"></a>
-                               </div>                          
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/index_de.png" title="Startseite"><img src="/images/screenshots/index_de_tn.png" border="0" alt="Startsete"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/backup_de.png" title="Datensicherung"><img src="/images/screenshots/backup_de_tn.png" border="0" alt="Datensicherung"></a>
-                               </div>                          
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph><Heading>Status</Heading>
-                       <Content lang="en"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;                              
-                                       <a href="/images/screenshots/services_en.png" title="Services"><img src="/images/screenshots/services_en_tn.png" border="0" alt="Services"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/networkother_en.png" title="Network (other)"><img src="/images/screenshots/networkother_en_tn.png" border="0" alt="Network (other)"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/connections_en.png" title="Connections"><img src="/images/screenshots/connections_en_tn.png" border="0" alt="Connections"></a>
-                               </div>                          
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/services_de.png" title="Dienste"><img src="/images/screenshots/services_de_tn.png" border="0" alt="Dienste"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/networkother_de.png" title="Netzwerk (sonstige)"><img src="/images/screenshots/networkother_de_tn.png" border="0" alt="Netzwerk (sonstige)"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/connections_de.png" title="Verbindungen"><img src="/images/screenshots/connections_de_tn.png" border="0" alt="Verbindungen"></a>
-                               </div>                          
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading lang="en">Network</Heading>
-                       <Heading lang="de">Netzwerk</Heading>
-                       
-                       <Content lang="en"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;                              
-                                       <a href="/images/screenshots/dhcp_en.png" title="DHCP Server"><img src="/images/screenshots/dhcp_en_tn.png" border="0" alt="DHCP Server"></a>
-                               </div>                          
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/dhcp_de.png" title="DHCP Server"><img src="/images/screenshots/dhcp_de_tn.png" border="0" alt="DHCP Server"></a>
-                               </div>                          
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph>
-                       <Heading lang="en">Services</Heading>
-                       <Heading lang="de">Dienste</Heading>
-                       
-                       <Content lang="en"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;                              
-                                       <a href="/images/screenshots/ipsec_en.png" title="IPSec"><img src="/images/screenshots/ipsec_en_tn.png" border="0" alt="IPSec"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/qos_en.png" title="Quality of Service"><img src="/images/screenshots/qos_en_tn.png" border="0" alt="Quality of Service"></a>
-                               </div>                          
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/ipsec_de.png" title="IPSec"><img src="/images/screenshots/ipsec_de_tn.png" border="0" alt="IPSec"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/qos_de.png" title="Quality of Service"><img src="/images/screenshots/qos_de_tn.png" border="0" alt="Quality of Service"></a>
-                               </div>                          
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph><Heading>Firewall</Heading>
-                       <Content lang="en"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;                              
-                                       <a href="/images/screenshots/outgoing_fw_en.png" title="Outgoing Firewall"><img src="/images/screenshots/outgoing_fw_en_tn.png" border="0" alt="Outgoing Firewall"></a>
-                               </div>                          
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/outgoing_fw_de.png" title="Ausgehende Firewall"><img src="/images/screenshots/outgoing_fw_de_tn.png" border="0" alt="Ausgehende Firewall"></a>
-                               </div>                          
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph><Heading>IPFire</Heading>
-                       <Content lang="en"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;                              
-                                       <a href="/images/screenshots/pakfire_en.png" title="Pakfire"><img src="/images/screenshots/pakfire_en_tn.png" border="0" alt="Pakfire"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/samba_en.png" title="Samba"><img src="/images/screenshots/samba_en_tn.png" border="0" alt="Samba"></a>
-                               </div>                          
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/pakfire_de.png" title="Pakfire"><img src="/images/screenshots/pakfire_de_tn.png" border="0" alt="Pakfire"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/samba_de.png" title="Samba"><img src="/images/screenshots/samba_de_tn.png" border="0" alt="Samba"></a>
-                               </div>                          
-                               ]]></Content>
-               </Paragraph>
-               
-               <Paragraph><Heading>Logs</Heading>
-                       <Content lang="en"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;                              
-                                       <a href="/images/screenshots/fwlog_ip_en.png" title="Fw-Logdgraphs (IP)"><img src="/images/screenshots/fwlog_ip_en_tn.png" border="0" alt="Fw-Logdgraphs (IP)"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/proxy_en.png" title="Proxy Reports"><img src="/images/screenshots/proxy_en_tn.png" border="0" alt="Proxy Reports"></a>
-                               </div>                          
-                               ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <div id="screenshots">
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/fwlog_ip_de.png" title="Fw-Logdiagramme (IP)"><img src="/images/screenshots/fwlog_ip_de_tn.png" border="0" alt="Fw-Logdiagramme (IP)"></a>
-                                       &nbsp;&nbsp;&nbsp;
-                                       <a href="/images/screenshots/proxy_de.png" title="Proxy-Berichte"><img src="/images/screenshots/proxy_de_tn.png" border="0" alt="Proxy-Berichte"></a>
-                               </div>                          
-                               ]]></Content>
-               </Paragraph>
-
-       </Paragraphs>
-               <Sidebar>
-               <Paragraph>
-                       <Heading lang="en"><![CDATA[<span>Screenshot</span> list]]></Heading>
-                       <Heading lang="de"><![CDATA[<span>Screenshot</span>liste]]></Heading>
-                       
-                       <Content lang="en"><![CDATA[
-                               <ul class="links">              
-                                       <li class="first"><a href="#System">System</a></li>
-                                       <li><a href="#Status">Status</a></li>
-                                       <li><a href="#Network">Network</a></li>
-                                       <li><a href="#Services">Services</a></li>
-                                       <li><a href="#Firewall">Firewall</a></li>
-                                       <li><a href="#IPFire">IPFire</a></li>
-                                       <li><a href="#Logs">Logs</a></li>
-                               </ul>
-                       ]]></Content>
-                       <Content lang="de"><![CDATA[
-                               <ul class="links">              
-                                       <li class="first"><a href="#System">System</a></li>
-                                       <li><a href="#Status">Status</a></li>
-                                       <li><a href="#Netzwerk">Netzwerk</a></li>
-                                       <li><a href="#Dienste">Dienste</a></li>
-                                       <li><a href="#Firewall">Firewall</a></li>
-                                       <li><a href="#IPFire">IPFire</a></li>
-                                       <li><a href="#Logs">Logs</a></li>
-                               </ul>
-                       ]]></Content>
-                       
-               </Paragraph>
-       </Sidebar>
-</Site>
\ No newline at end of file
diff --git a/www/pages/torrent/__init__.py b/www/pages/torrent/__init__.py
deleted file mode 100644 (file)
index 112e63b..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/python
-
-TRACKER_URL ="http://tracker.ipfire.org:6969/stats?format=txt&mode=tpbs"
-TORRENT_BASE="/srv/pakfire/data/torrent"
-
-import os
-import sha
-import urllib2
-
-from client.bencode import bencode, bdecode
-import web
-import web.elements
-
-class TrackerInfo:
-       def __init__(self, url):
-               self.info = {}
-
-               f = urllib2.urlopen(url)
-               for line in f.readlines():
-                       (hash, seeds, peers,) = line.split(":")
-                       self.info[hash] = (seeds, peers.rstrip("\n"),)
-               f.close()
-
-       def __call__(self):
-               print self.info
-
-       def get(self, hash):
-               try:
-                       return self.info[hash]
-               except KeyError:
-                       return 0, 0
-
-
-class TorrentObject:
-       def __init__(self, file):
-               self.name = os.path.basename(file)
-               f = open(file, "rb")
-               self.info = bdecode(f.read())
-               f.close()
-       
-       def __call__(self):
-               print "File : %s" % self.get_file()
-               print "Hash : %s" % self.get_hash()
-       
-       def get_hash(self):
-               return sha.sha(bencode(self.info["info"])).hexdigest().upper()
-       
-       def get_file(self):
-               return self.name
-
-
-torrent_files = []
-for file in os.listdir(TORRENT_BASE):
-       if not file.endswith(".torrent"):
-               continue
-       file = os.path.join(TORRENT_BASE, file)
-       torrent_files.insert(0, TorrentObject(file))
-
-
-tracker = TrackerInfo(TRACKER_URL)
-
-class TorrentBox(web.elements.Box):
-       def __init__(self, file):
-               web.elements.Box.__init__(self, file.name, file.get_hash())
-               self.w("""
-                       <p>
-                               <strong>Seeders:</strong> %s<br />
-                               <strong>Leechers:</strong> %s
-                       </p>""" % tracker.get(file.get_hash()))
-               self.w("""
-                       <p style="text-align: right;">
-                               <a href="http://download.ipfire.org/torrent/%s">Download</a>
-                       </p>""" % (file.name,))
-               
-
-class Content(web.Content):
-       def __init__(self):
-               web.Content.__init__(self)
-       
-       def content(self):
-               self.w("<h3>IPFire Torrent Tracker</h3>")
-               for t in torrent_files:
-                       b = TorrentBox(t)
-                       self.w(b())
-
-page = web.Page()
-page.content = Content()
-page.sidebar = web.elements.Sidebar()
diff --git a/www/pages/torrent/client/ConfigDir.py b/www/pages/torrent/client/ConfigDir.py
deleted file mode 100644 (file)
index ee2b23d..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-#written by John Hoffman
-
-from inifile import ini_write, ini_read
-from bencode import bencode, bdecode
-from types import IntType, LongType, StringType, FloatType
-from CreateIcons import GetIcons, CreateIcon
-from parseargs import defaultargs
-from __init__ import product_name, version_short
-import sys,os
-from time import time, strftime
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-try:
-    realpath = os.path.realpath
-except:
-    realpath = lambda x:x
-OLDICONPATH = os.path.abspath(os.path.dirname(realpath(sys.argv[0])))
-
-DIRNAME = '.'+product_name
-
-hexchars = '0123456789abcdef'
-hexmap = []
-revmap = {}
-for i in xrange(256):
-    x = hexchars[(i&0xF0)/16]+hexchars[i&0x0F]
-    hexmap.append(x)
-    revmap[x] = chr(i)
-
-def tohex(s):
-    r = []
-    for c in s:
-        r.append(hexmap[ord(c)])
-    return ''.join(r)
-
-def unhex(s):
-    r = [ revmap[s[x:x+2]] for x in xrange(0, len(s), 2) ]
-    return ''.join(r)
-
-def copyfile(oldpath, newpath): # simple file copy, all in RAM
-    try:
-        f = open(oldpath,'rb')
-        r = f.read()
-        success = True
-    except:
-        success = False
-    try:
-        f.close()
-    except:
-        pass
-    if not success:
-        return False
-    try:
-        f = open(newpath,'wb')
-        f.write(r)
-    except:
-        success = False
-    try:
-        f.close()
-    except:
-        pass
-    return success
-
-
-class ConfigDir:
-
-    ###### INITIALIZATION TASKS ######
-
-    def __init__(self, config_type = None):
-        self.config_type = config_type
-        if config_type:
-            config_ext = '.'+config_type
-        else:
-            config_ext = ''
-
-        def check_sysvars(x):
-            y = os.path.expandvars(x)
-            if y != x and os.path.isdir(y):
-                return y
-            return None
-
-        for d in ['${APPDATA}', '${HOME}', '${HOMEPATH}', '${USERPROFILE}']:
-            dir_root = check_sysvars(d)
-            if dir_root:
-                break
-        else:
-            dir_root = os.path.expanduser('~')
-            if not os.path.isdir(dir_root):
-                dir_root = os.path.abspath(os.path.dirname(sys.argv[0]))
-
-        dir_root = os.path.join(dir_root,DIRNAME)
-        self.dir_root = dir_root
-
-        if not os.path.isdir(self.dir_root):
-            os.mkdir(self.dir_root,0700)    # exception if failed
-
-        self.dir_icons = os.path.join(dir_root,'icons')
-        if not os.path.isdir(self.dir_icons):
-            os.mkdir(self.dir_icons)
-        for icon in GetIcons():
-            i = os.path.join(self.dir_icons,icon)
-            if not os.path.exists(i):
-                if not copyfile(os.path.join(OLDICONPATH,icon),i):
-                    CreateIcon(icon,self.dir_icons)
-
-        self.dir_torrentcache = os.path.join(dir_root,'torrentcache')
-        if not os.path.isdir(self.dir_torrentcache):
-            os.mkdir(self.dir_torrentcache)
-
-        self.dir_datacache = os.path.join(dir_root,'datacache')
-        if not os.path.isdir(self.dir_datacache):
-            os.mkdir(self.dir_datacache)
-
-        self.dir_piececache = os.path.join(dir_root,'piececache')
-        if not os.path.isdir(self.dir_piececache):
-            os.mkdir(self.dir_piececache)
-
-        self.configfile = os.path.join(dir_root,'config'+config_ext+'.ini')
-        self.statefile = os.path.join(dir_root,'state'+config_ext)
-
-        self.TorrentDataBuffer = {}
-
-
-    ###### CONFIG HANDLING ######
-
-    def setDefaults(self, defaults, ignore=[]):
-        self.config = defaultargs(defaults)
-        for k in ignore:
-            if self.config.has_key(k):
-                del self.config[k]
-
-    def checkConfig(self):
-        return os.path.exists(self.configfile)
-
-    def loadConfig(self):
-        try:
-            r = ini_read(self.configfile)['']
-        except:
-            return self.config
-        l = self.config.keys()
-        for k,v in r.items():
-            if self.config.has_key(k):
-                t = type(self.config[k])
-                try:
-                    if t == StringType:
-                        self.config[k] = v
-                    elif t == IntType or t == LongType:
-                        self.config[k] = long(v)
-                    elif t == FloatType:
-                        self.config[k] = float(v)
-                    l.remove(k)
-                except:
-                    pass
-        if l: # new default values since last save
-            self.saveConfig()
-        return self.config
-
-    def saveConfig(self, new_config = None):
-        if new_config:
-            for k,v in new_config.items():
-                if self.config.has_key(k):
-                    self.config[k] = v
-        try:
-            ini_write( self.configfile, self.config,
-                       'Generated by '+product_name+'/'+version_short+'\n'
-                       + strftime('%x %X') )
-            return True
-        except:
-            return False
-
-    def getConfig(self):
-        return self.config
-
-
-    ###### STATE HANDLING ######
-
-    def getState(self):
-        try:
-            f = open(self.statefile,'rb')
-            r = f.read()
-        except:
-            r = None
-        try:
-            f.close()
-        except:
-            pass
-        try:
-            r = bdecode(r)
-        except:
-            r = None
-        return r        
-
-    def saveState(self, state):
-        try:
-            f = open(self.statefile,'wb')
-            f.write(bencode(state))
-            success = True
-        except:
-            success = False
-        try:
-            f.close()
-        except:
-            pass
-        return success
-
-
-    ###### TORRENT HANDLING ######
-
-    def getTorrents(self):
-        d = {}
-        for f in os.listdir(self.dir_torrentcache):
-            f = os.path.basename(f)
-            try:
-                f, garbage = f.split('.')
-            except:
-                pass
-            d[unhex(f)] = 1
-        return d.keys()
-
-    def getTorrentVariations(self, t):
-        t = tohex(t)
-        d = []
-        for f in os.listdir(self.dir_torrentcache):
-            f = os.path.basename(f)
-            if f[:len(t)] == t:
-                try:
-                    garbage, ver = f.split('.')
-                except:
-                    ver = '0'
-                d.append(int(ver))
-        d.sort()
-        return d
-
-    def getTorrent(self, t, v = -1):
-        t = tohex(t)
-        if v == -1:
-            v = max(self.getTorrentVariations(t))   # potential exception
-        if v:
-            t += '.'+str(v)
-        try:
-            f = open(os.path.join(self.dir_torrentcache,t),'rb')
-            r = bdecode(f.read())
-        except:
-            r = None
-        try:
-            f.close()
-        except:
-            pass
-        return r
-
-    def writeTorrent(self, data, t, v = -1):
-        t = tohex(t)
-        if v == -1:
-            try:
-                v = max(self.getTorrentVariations(t))+1
-            except:
-                v = 0
-        if v:
-            t += '.'+str(v)
-        try:
-            f = open(os.path.join(self.dir_torrentcache,t),'wb')
-            f.write(bencode(data))
-        except:
-            v = None
-        try:
-            f.close()
-        except:
-            pass
-        return v
-
-
-    ###### TORRENT DATA HANDLING ######
-
-    def getTorrentData(self, t):
-        if self.TorrentDataBuffer.has_key(t):
-            return self.TorrentDataBuffer[t]
-        t = os.path.join(self.dir_datacache,tohex(t))
-        if not os.path.exists(t):
-            return None
-        try:
-            f = open(t,'rb')
-            r = bdecode(f.read())
-        except:
-            r = None
-        try:
-            f.close()
-        except:
-            pass
-        self.TorrentDataBuffer[t] = r
-        return r
-
-    def writeTorrentData(self, t, data):
-        self.TorrentDataBuffer[t] = data
-        try:
-            f = open(os.path.join(self.dir_datacache,tohex(t)),'wb')
-            f.write(bencode(data))
-            success = True
-        except:
-            success = False
-        try:
-            f.close()
-        except:
-            pass
-        if not success:
-            self.deleteTorrentData(t)
-        return success
-
-    def deleteTorrentData(self, t):
-        try:
-            os.remove(os.path.join(self.dir_datacache,tohex(t)))
-        except:
-            pass
-
-    def getPieceDir(self, t):
-        return os.path.join(self.dir_piececache,tohex(t))
-
-
-    ###### EXPIRATION HANDLING ######
-
-    def deleteOldCacheData(self, days, still_active = [], delete_torrents = False):
-        if not days:
-            return
-        exptime = time() - (days*24*3600)
-        names = {}
-        times = {}
-
-        for f in os.listdir(self.dir_torrentcache):
-            p = os.path.join(self.dir_torrentcache,f)
-            f = os.path.basename(f)
-            try:
-                f, garbage = f.split('.')
-            except:
-                pass
-            try:
-                f = unhex(f)
-                assert len(f) == 20
-            except:
-                continue
-            if delete_torrents:
-                names.setdefault(f,[]).append(p)
-            try:
-                t = os.path.getmtime(p)
-            except:
-                t = time()
-            times.setdefault(f,[]).append(t)
-        
-        for f in os.listdir(self.dir_datacache):
-            p = os.path.join(self.dir_datacache,f)
-            try:
-                f = unhex(os.path.basename(f))
-                assert len(f) == 20
-            except:
-                continue
-            names.setdefault(f,[]).append(p)
-            try:
-                t = os.path.getmtime(p)
-            except:
-                t = time()
-            times.setdefault(f,[]).append(t)
-
-        for f in os.listdir(self.dir_piececache):
-            p = os.path.join(self.dir_piececache,f)
-            try:
-                f = unhex(os.path.basename(f))
-                assert len(f) == 20
-            except:
-                continue
-            for f2 in os.listdir(p):
-                p2 = os.path.join(p,f2)
-                names.setdefault(f,[]).append(p2)
-                try:
-                    t = os.path.getmtime(p2)
-                except:
-                    t = time()
-                times.setdefault(f,[]).append(t)
-            names.setdefault(f,[]).append(p)
-
-        for k,v in times.items():
-            if max(v) < exptime and not k in still_active:
-                for f in names[k]:
-                    try:
-                        os.remove(f)
-                    except:
-                        try:
-                            os.removedirs(f)
-                        except:
-                            pass
-
-
-    def deleteOldTorrents(self, days, still_active = []):
-        self.deleteOldCacheData(days, still_active, True)
-
-
-    ###### OTHER ######
-
-    def getIconDir(self):
-        return self.dir_icons
diff --git a/www/pages/torrent/client/ConfigReader.py b/www/pages/torrent/client/ConfigReader.py
deleted file mode 100644 (file)
index e9353bb..0000000
+++ /dev/null
@@ -1,1068 +0,0 @@
-#written by John Hoffman
-
-from ConnChoice import *
-from wxPython.wx import *
-from types import IntType, FloatType, StringType
-from download_bt1 import defaults
-from ConfigDir import ConfigDir
-import sys,os
-import socket
-from parseargs import defaultargs
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-    
-try:
-    wxFULL_REPAINT_ON_RESIZE
-except:
-    wxFULL_REPAINT_ON_RESIZE = 0        # fix for wx pre-2.5
-
-if (sys.platform == 'win32'):
-    _FONT = 9
-else:
-    _FONT = 10
-
-def HexToColor(s):
-    r,g,b = s.split(' ')
-    return wxColour(red=int(r,16), green=int(g,16), blue=int(b,16))
-    
-def hex2(c):
-    h = hex(c)[2:]
-    if len(h) == 1:
-        h = '0'+h
-    return h
-def ColorToHex(c):
-    return hex2(c.Red()) + ' ' + hex2(c.Green()) + ' ' + hex2(c.Blue())
-
-ratesettingslist = []
-for x in connChoices:
-    if not x.has_key('super-seed'):
-        ratesettingslist.append(x['name'])
-
-
-configFileDefaults = [
-    #args only available for the gui client
-    ('win32_taskbar_icon', 1,
-         "whether to iconize do system try or not on win32"),
-    ('gui_stretchwindow', 0,
-         "whether to stretch the download status window to fit the torrent name"),
-    ('gui_displaystats', 1,
-         "whether to display statistics on peers and seeds"),
-    ('gui_displaymiscstats', 1,
-         "whether to display miscellaneous other statistics"),
-    ('gui_ratesettingsdefault', ratesettingslist[0],
-         "the default setting for maximum upload rate and users"),
-    ('gui_ratesettingsmode', 'full',
-         "what rate setting controls to display; options are 'none', 'basic', and 'full'"),
-    ('gui_forcegreenonfirewall', 0,
-         "forces the status icon to be green even if the client seems to be firewalled"),
-    ('gui_default_savedir', '',
-         "default save directory"),
-    ('last_saved', '',       # hidden; not set in config
-         "where the last torrent was saved"),
-    ('gui_font', _FONT,
-         "the font size to use"),
-    ('gui_saveas_ask', -1,
-         "whether to ask where to download to (0 = never, 1 = always, -1 = automatic resume"),
-]
-
-def setwxconfigfiledefaults():
-    CHECKINGCOLOR = ColorToHex(wxSystemSettings_GetColour(wxSYS_COLOUR_3DSHADOW))       
-    DOWNLOADCOLOR = ColorToHex(wxSystemSettings_GetColour(wxSYS_COLOUR_ACTIVECAPTION))
-    
-    configFileDefaults.extend([
-        ('gui_checkingcolor', CHECKINGCOLOR,
-            "progress bar checking color"),
-        ('gui_downloadcolor', DOWNLOADCOLOR,
-            "progress bar downloading color"),
-        ('gui_seedingcolor', '00 FF 00',
-            "progress bar seeding color"),
-    ])
-
-defaultsToIgnore = ['responsefile', 'url', 'priority']
-
-
-class configReader:
-
-    def __init__(self):
-        self.configfile = wxConfig("BitTorrent",style=wxCONFIG_USE_LOCAL_FILE)
-        self.configMenuBox = None
-        self.advancedMenuBox = None
-        self._configReset = True         # run reset for the first time
-
-        setwxconfigfiledefaults()
-
-        defaults.extend(configFileDefaults)
-        self.defaults = defaultargs(defaults)
-
-        self.configDir = ConfigDir('gui')
-        self.configDir.setDefaults(defaults,defaultsToIgnore)
-        if self.configDir.checkConfig():
-            self.config = self.configDir.loadConfig()
-        else:
-            self.config = self.configDir.getConfig()
-            self.importOldGUIConfig()
-            self.configDir.saveConfig()
-
-        updated = False     # make all config default changes here
-
-        if self.config['gui_ratesettingsdefault'] not in ratesettingslist:
-            self.config['gui_ratesettingsdefault'] = (
-                                self.defaults['gui_ratesettingsdefault'] )
-            updated = True
-        if self.config['ipv6_enabled'] and (
-                        sys.version_info < (2,3) or not socket.has_ipv6 ):
-            self.config['ipv6_enabled'] = 0
-            updated = True
-        for c in ['gui_checkingcolor','gui_downloadcolor','gui_seedingcolor']:
-            try:
-                HexToColor(self.config[c])
-            except:
-                self.config[c] = self.defaults[c]
-                updated = True
-
-        if updated:
-            self.configDir.saveConfig()
-
-        self.configDir.deleteOldCacheData(self.config['expire_cache_data'])
-
-
-    def importOldGUIConfig(self):
-        oldconfig = wxConfig("BitTorrent",style=wxCONFIG_USE_LOCAL_FILE)
-        cont, s, i = oldconfig.GetFirstEntry()
-        if not cont:
-            oldconfig.DeleteAll()
-            return False
-        while cont:     # import old config data
-            if self.config.has_key(s):
-                t = oldconfig.GetEntryType(s)
-                try:
-                    if t == 1:
-                        assert type(self.config[s]) == type('')
-                        self.config[s] = oldconfig.Read(s)
-                    elif t == 2 or t == 3:
-                        assert type(self.config[s]) == type(1)
-                        self.config[s] = int(oldconfig.ReadInt(s))
-                    elif t == 4:
-                        assert type(self.config[s]) == type(1.0)
-                        self.config[s] = oldconfig.ReadFloat(s)
-                except:
-                    pass
-            cont, s, i = oldconfig.GetNextEntry(i)
-
-#        oldconfig.DeleteAll()
-        return True
-
-
-    def resetConfigDefaults(self):
-        for p,v in self.defaults.items():
-            if not p in defaultsToIgnore:
-                self.config[p] = v
-        self.configDir.saveConfig()
-
-    def writeConfigFile(self):
-        self.configDir.saveConfig()
-
-    def WriteLastSaved(self, l):
-        self.config['last_saved'] = l
-        self.configDir.saveConfig()
-
-
-    def getcheckingcolor(self):
-        return HexToColor(self.config['gui_checkingcolor'])
-    def getdownloadcolor(self):
-        return HexToColor(self.config['gui_downloadcolor'])
-    def getseedingcolor(self):
-        return HexToColor(self.config['gui_seedingcolor'])
-
-    def configReset(self):
-        r = self._configReset
-        self._configReset = False
-        return r
-
-    def getConfigDir(self):
-        return self.configDir
-
-    def getIconDir(self):
-        return self.configDir.getIconDir()
-
-    def getTorrentData(self,t):
-        return self.configDir.getTorrentData(t)
-
-    def setColorIcon(self, xxicon, xxiconptr, xxcolor):
-        idata = wxMemoryDC()
-        idata.SelectObject(xxicon)
-        idata.SetBrush(wxBrush(xxcolor,wxSOLID))
-        idata.DrawRectangle(0,0,16,16)
-        idata.SelectObject(wxNullBitmap)
-        xxiconptr.Refresh()
-
-
-    def getColorFromUser(self, parent, colInit):
-        data = wxColourData()
-        if colInit.Ok():
-            data.SetColour(colInit)
-        data.SetCustomColour(0, self.checkingcolor)
-        data.SetCustomColour(1, self.downloadcolor)
-        data.SetCustomColour(2, self.seedingcolor)
-        dlg = wxColourDialog(parent,data)
-        if not dlg.ShowModal():
-            return colInit
-        return dlg.GetColourData().GetColour()
-
-
-    def configMenu(self, parent):
-      self.parent = parent
-      try:
-        self.FONT = self.config['gui_font']
-        self.default_font = wxFont(self.FONT, wxDEFAULT, wxNORMAL, wxNORMAL, False)
-        self.checkingcolor = HexToColor(self.config['gui_checkingcolor'])
-        self.downloadcolor = HexToColor(self.config['gui_downloadcolor'])
-        self.seedingcolor = HexToColor(self.config['gui_seedingcolor'])
-        
-        if (self.configMenuBox is not None):
-            try:
-                self.configMenuBox.Close()
-            except wxPyDeadObjectError, e:
-                self.configMenuBox = None
-
-        self.configMenuBox = wxFrame(None, -1, 'BitTorrent Preferences', size = (1,1),
-                            style = wxDEFAULT_FRAME_STYLE|wxFULL_REPAINT_ON_RESIZE)
-        if (sys.platform == 'win32'):
-            self.icon = self.parent.icon
-            self.configMenuBox.SetIcon(self.icon)
-
-        panel = wxPanel(self.configMenuBox, -1)
-        self.panel = panel
-
-        def StaticText(text, font = self.FONT, underline = False, color = None, panel = panel):
-            x = wxStaticText(panel, -1, text, style = wxALIGN_LEFT)
-            x.SetFont(wxFont(font, wxDEFAULT, wxNORMAL, wxNORMAL, underline))
-            if color is not None:
-                x.SetForegroundColour(color)
-            return x
-
-        colsizer = wxFlexGridSizer(cols = 1, vgap = 8)
-
-        self.gui_stretchwindow_checkbox = wxCheckBox(panel, -1, "Stretch window to fit torrent name *")
-        self.gui_stretchwindow_checkbox.SetFont(self.default_font)
-        self.gui_stretchwindow_checkbox.SetValue(self.config['gui_stretchwindow'])
-
-        self.gui_displaystats_checkbox = wxCheckBox(panel, -1, "Display peer and seed statistics")
-        self.gui_displaystats_checkbox.SetFont(self.default_font)
-        self.gui_displaystats_checkbox.SetValue(self.config['gui_displaystats'])
-
-        self.gui_displaymiscstats_checkbox = wxCheckBox(panel, -1, "Display miscellaneous other statistics")
-        self.gui_displaymiscstats_checkbox.SetFont(self.default_font)
-        self.gui_displaymiscstats_checkbox.SetValue(self.config['gui_displaymiscstats'])
-
-        self.security_checkbox = wxCheckBox(panel, -1, "Don't allow multiple connections from the same IP")
-        self.security_checkbox.SetFont(self.default_font)
-        self.security_checkbox.SetValue(self.config['security'])
-
-        self.autokick_checkbox = wxCheckBox(panel, -1, "Kick/ban clients that send you bad data *")
-        self.autokick_checkbox.SetFont(self.default_font)
-        self.autokick_checkbox.SetValue(self.config['auto_kick'])
-
-        self.buffering_checkbox = wxCheckBox(panel, -1, "Enable read/write buffering *")
-        self.buffering_checkbox.SetFont(self.default_font)
-        self.buffering_checkbox.SetValue(self.config['buffer_reads'])
-
-        self.breakup_checkbox = wxCheckBox(panel, -1, "Break-up seed bitfield to foil ISP manipulation")
-        self.breakup_checkbox.SetFont(self.default_font)
-        self.breakup_checkbox.SetValue(self.config['breakup_seed_bitfield'])
-
-        self.autoflush_checkbox = wxCheckBox(panel, -1, "Flush data to disk every 5 minutes")
-        self.autoflush_checkbox.SetFont(self.default_font)
-        self.autoflush_checkbox.SetValue(self.config['auto_flush'])
-
-        if sys.version_info >= (2,3) and socket.has_ipv6:
-            self.ipv6enabled_checkbox = wxCheckBox(panel, -1, "Initiate and receive connections via IPv6 *")
-            self.ipv6enabled_checkbox.SetFont(self.default_font)
-            self.ipv6enabled_checkbox.SetValue(self.config['ipv6_enabled'])
-
-        self.gui_forcegreenonfirewall_checkbox = wxCheckBox(panel, -1,
-                            "Force icon to display green when firewalled")
-        self.gui_forcegreenonfirewall_checkbox.SetFont(self.default_font)
-        self.gui_forcegreenonfirewall_checkbox.SetValue(self.config['gui_forcegreenonfirewall'])
-
-
-        self.minport_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*8, -1))
-        self.minport_data.SetFont(self.default_font)
-        self.minport_data.SetRange(1,65535)
-        self.minport_data.SetValue(self.config['minport'])
-
-        self.maxport_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*8, -1))
-        self.maxport_data.SetFont(self.default_font)
-        self.maxport_data.SetRange(1,65535)
-        self.maxport_data.SetValue(self.config['maxport'])
-        
-        self.randomport_checkbox = wxCheckBox(panel, -1, "randomize")
-        self.randomport_checkbox.SetFont(self.default_font)
-        self.randomport_checkbox.SetValue(self.config['random_port'])
-        
-        self.gui_font_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*5, -1))
-        self.gui_font_data.SetFont(self.default_font)
-        self.gui_font_data.SetRange(8,16)
-        self.gui_font_data.SetValue(self.config['gui_font'])
-
-        self.gui_ratesettingsdefault_data=wxChoice(panel, -1, choices = ratesettingslist)
-        self.gui_ratesettingsdefault_data.SetFont(self.default_font)
-        self.gui_ratesettingsdefault_data.SetStringSelection(self.config['gui_ratesettingsdefault'])
-
-        self.maxdownload_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*7, -1))
-        self.maxdownload_data.SetFont(self.default_font)
-        self.maxdownload_data.SetRange(0,5000)
-        self.maxdownload_data.SetValue(self.config['max_download_rate'])
-
-        self.gui_ratesettingsmode_data=wxRadioBox(panel, -1, 'Rate Settings Mode',
-                 choices = [ 'none', 'basic', 'full' ] )
-        self.gui_ratesettingsmode_data.SetFont(self.default_font)
-        self.gui_ratesettingsmode_data.SetStringSelection(self.config['gui_ratesettingsmode'])
-
-        if (sys.platform == 'win32'):
-            self.win32_taskbar_icon_checkbox = wxCheckBox(panel, -1, "Minimize to system tray")
-            self.win32_taskbar_icon_checkbox.SetFont(self.default_font)
-            self.win32_taskbar_icon_checkbox.SetValue(self.config['win32_taskbar_icon'])
-            
-#            self.upnp_checkbox = wxCheckBox(panel, -1, "Enable automatic UPnP port forwarding")
-#            self.upnp_checkbox.SetFont(self.default_font)
-#            self.upnp_checkbox.SetValue(self.config['upnp_nat_access'])
-            self.upnp_data=wxChoice(panel, -1,
-                        choices = ['disabled', 'type 1 (fast)', 'type 2 (slow)'])
-            self.upnp_data.SetFont(self.default_font)
-            self.upnp_data.SetSelection(self.config['upnp_nat_access'])
-
-        self.gui_default_savedir_ctrl = wxTextCtrl(parent = panel, id = -1, 
-                            value = self.config['gui_default_savedir'],        
-                            size = (26*self.FONT, -1), style = wxTE_PROCESS_TAB)
-        self.gui_default_savedir_ctrl.SetFont(self.default_font)
-
-        self.gui_savemode_data=wxRadioBox(panel, -1, 'Ask where to save: *',
-                 choices = [ 'always', 'never', 'auto-resume' ] )
-        self.gui_savemode_data.SetFont(self.default_font)
-        self.gui_savemode_data.SetSelection(1-self.config['gui_saveas_ask'])
-
-        self.checkingcolor_icon = wxEmptyBitmap(16,16)
-        self.checkingcolor_iconptr = wxStaticBitmap(panel, -1, self.checkingcolor_icon)
-        self.setColorIcon(self.checkingcolor_icon, self.checkingcolor_iconptr, self.checkingcolor)
-
-        self.downloadcolor_icon = wxEmptyBitmap(16,16)
-        self.downloadcolor_iconptr = wxStaticBitmap(panel, -1, self.downloadcolor_icon)
-        self.setColorIcon(self.downloadcolor_icon, self.downloadcolor_iconptr, self.downloadcolor)
-
-        self.seedingcolor_icon = wxEmptyBitmap(16,16)
-        self.seedingcolor_iconptr = wxStaticBitmap(panel, -1, self.seedingcolor_icon)
-        self.setColorIcon(self.seedingcolor_icon, self.downloadcolor_iconptr, self.seedingcolor)
-        
-        rowsizer = wxFlexGridSizer(cols = 2, hgap = 20)
-
-        block12sizer = wxFlexGridSizer(cols = 1, vgap = 7)
-
-        block1sizer = wxFlexGridSizer(cols = 1, vgap = 2)
-        if (sys.platform == 'win32'):
-            block1sizer.Add(self.win32_taskbar_icon_checkbox)
-#            block1sizer.Add(self.upnp_checkbox)
-        block1sizer.Add(self.gui_stretchwindow_checkbox)
-        block1sizer.Add(self.gui_displaystats_checkbox)
-        block1sizer.Add(self.gui_displaymiscstats_checkbox)
-        block1sizer.Add(self.security_checkbox)
-        block1sizer.Add(self.autokick_checkbox)
-        block1sizer.Add(self.buffering_checkbox)
-        block1sizer.Add(self.breakup_checkbox)
-        block1sizer.Add(self.autoflush_checkbox)
-        if sys.version_info >= (2,3) and socket.has_ipv6:
-            block1sizer.Add(self.ipv6enabled_checkbox)
-        block1sizer.Add(self.gui_forcegreenonfirewall_checkbox)
-
-        block12sizer.Add(block1sizer)
-
-        colorsizer = wxStaticBoxSizer(wxStaticBox(panel, -1, "Gauge Colors:"), wxVERTICAL)
-        colorsizer1 = wxFlexGridSizer(cols = 7)
-        colorsizer1.Add(StaticText('           Checking: '), 1, wxALIGN_BOTTOM)
-        colorsizer1.Add(self.checkingcolor_iconptr, 1, wxALIGN_BOTTOM)
-        colorsizer1.Add(StaticText('   Downloading: '), 1, wxALIGN_BOTTOM)
-        colorsizer1.Add(self.downloadcolor_iconptr, 1, wxALIGN_BOTTOM)
-        colorsizer1.Add(StaticText('   Seeding: '), 1, wxALIGN_BOTTOM)
-        colorsizer1.Add(self.seedingcolor_iconptr, 1, wxALIGN_BOTTOM)
-        colorsizer1.Add(StaticText('  '))
-        minsize = self.checkingcolor_iconptr.GetBestSize()
-        minsize.SetHeight(minsize.GetHeight()+5)
-        colorsizer1.SetMinSize(minsize)
-        colorsizer.Add(colorsizer1)
-       
-        block12sizer.Add(colorsizer, 1, wxALIGN_LEFT)
-
-        rowsizer.Add(block12sizer)
-
-        block3sizer = wxFlexGridSizer(cols = 1)
-
-        portsettingsSizer = wxStaticBoxSizer(wxStaticBox(panel, -1, "Port Range:*"), wxVERTICAL)
-        portsettingsSizer1 = wxGridSizer(cols = 2, vgap = 1)
-        portsettingsSizer1.Add(StaticText('From: '), 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT)
-        portsettingsSizer1.Add(self.minport_data, 1, wxALIGN_BOTTOM)
-        portsettingsSizer1.Add(StaticText('To: '), 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT)
-        portsettingsSizer1.Add(self.maxport_data, 1, wxALIGN_BOTTOM)
-        portsettingsSizer.Add(portsettingsSizer1)
-        portsettingsSizer.Add(self.randomport_checkbox, 1, wxALIGN_CENTER)
-        block3sizer.Add(portsettingsSizer, 1, wxALIGN_CENTER)
-        block3sizer.Add(StaticText(' '))
-        block3sizer.Add(self.gui_ratesettingsmode_data, 1, wxALIGN_CENTER)
-        block3sizer.Add(StaticText(' '))
-        ratesettingsSizer = wxFlexGridSizer(cols = 1, vgap = 2)
-        ratesettingsSizer.Add(StaticText('Default Rate Setting: *'), 1, wxALIGN_CENTER)
-        ratesettingsSizer.Add(self.gui_ratesettingsdefault_data, 1, wxALIGN_CENTER)
-        block3sizer.Add(ratesettingsSizer, 1, wxALIGN_CENTER)
-        if (sys.platform == 'win32'):
-            block3sizer.Add(StaticText(' '))
-            upnpSizer = wxFlexGridSizer(cols = 1, vgap = 2)
-            upnpSizer.Add(StaticText('UPnP Port Forwarding: *'), 1, wxALIGN_CENTER)
-            upnpSizer.Add(self.upnp_data, 1, wxALIGN_CENTER)
-            block3sizer.Add(upnpSizer, 1, wxALIGN_CENTER)
-        
-        rowsizer.Add(block3sizer)
-        colsizer.Add(rowsizer)
-
-        block4sizer = wxFlexGridSizer(cols = 3, hgap = 15)        
-        savepathsizer = wxFlexGridSizer(cols = 2, vgap = 1)
-        savepathsizer.Add(StaticText('Default Save Path: *'))
-        savepathsizer.Add(StaticText(' '))
-        savepathsizer.Add(self.gui_default_savedir_ctrl, 1, wxEXPAND)
-        savepathButton = wxButton(panel, -1, '...', size = (18,18))
-#        savepathButton.SetFont(self.default_font)
-        savepathsizer.Add(savepathButton, 0, wxALIGN_CENTER)
-        savepathsizer.Add(self.gui_savemode_data, 0, wxALIGN_CENTER)
-        block4sizer.Add(savepathsizer, -1, wxALIGN_BOTTOM)
-
-        fontsizer = wxFlexGridSizer(cols = 1, vgap = 2)
-        fontsizer.Add(StaticText(''))
-        fontsizer.Add(StaticText('Font: *'), 1, wxALIGN_CENTER)
-        fontsizer.Add(self.gui_font_data, 1, wxALIGN_CENTER)
-        block4sizer.Add(fontsizer, 1, wxALIGN_CENTER_VERTICAL)
-
-        dratesettingsSizer = wxFlexGridSizer(cols = 1, vgap = 2)
-        dratesettingsSizer.Add(StaticText('Default Max'), 1, wxALIGN_CENTER)
-        dratesettingsSizer.Add(StaticText('Download Rate'), 1, wxALIGN_CENTER)
-        dratesettingsSizer.Add(StaticText('(kB/s): *'), 1, wxALIGN_CENTER)
-        dratesettingsSizer.Add(self.maxdownload_data, 1, wxALIGN_CENTER)
-        dratesettingsSizer.Add(StaticText('(0 = disabled)'), 1, wxALIGN_CENTER)
-        
-        block4sizer.Add(dratesettingsSizer, 1, wxALIGN_CENTER_VERTICAL)
-
-        colsizer.Add(block4sizer, 0, wxALIGN_CENTER)
-#        colsizer.Add(StaticText(' '))
-
-        savesizer = wxGridSizer(cols = 4, hgap = 10)
-        saveButton = wxButton(panel, -1, 'Save')
-#        saveButton.SetFont(self.default_font)
-        savesizer.Add(saveButton, 0, wxALIGN_CENTER)
-
-        cancelButton = wxButton(panel, -1, 'Cancel')
-#        cancelButton.SetFont(self.default_font)
-        savesizer.Add(cancelButton, 0, wxALIGN_CENTER)
-
-        defaultsButton = wxButton(panel, -1, 'Revert to Defaults')
-#        defaultsButton.SetFont(self.default_font)
-        savesizer.Add(defaultsButton, 0, wxALIGN_CENTER)
-
-        advancedButton = wxButton(panel, -1, 'Advanced...')
-#        advancedButton.SetFont(self.default_font)
-        savesizer.Add(advancedButton, 0, wxALIGN_CENTER)
-        colsizer.Add(savesizer, 1, wxALIGN_CENTER)
-
-        resizewarningtext=StaticText('* These settings will not take effect until the next time you start BitTorrent', self.FONT-2)
-        colsizer.Add(resizewarningtext, 1, wxALIGN_CENTER)
-
-        border = wxBoxSizer(wxHORIZONTAL)
-        border.Add(colsizer, 1, wxEXPAND | wxALL, 4)
-        
-        panel.SetSizer(border)
-        panel.SetAutoLayout(True)
-
-        self.advancedConfig = {}
-
-        def setDefaults(evt, self = self):
-          try:
-            self.minport_data.SetValue(self.defaults['minport'])
-            self.maxport_data.SetValue(self.defaults['maxport'])
-            self.randomport_checkbox.SetValue(self.defaults['random_port'])
-            self.gui_stretchwindow_checkbox.SetValue(self.defaults['gui_stretchwindow'])
-            self.gui_displaystats_checkbox.SetValue(self.defaults['gui_displaystats'])
-            self.gui_displaymiscstats_checkbox.SetValue(self.defaults['gui_displaymiscstats'])
-            self.security_checkbox.SetValue(self.defaults['security'])
-            self.autokick_checkbox.SetValue(self.defaults['auto_kick'])
-            self.buffering_checkbox.SetValue(self.defaults['buffer_reads'])
-            self.breakup_checkbox.SetValue(self.defaults['breakup_seed_bitfield'])
-            self.autoflush_checkbox.SetValue(self.defaults['auto_flush'])
-            if sys.version_info >= (2,3) and socket.has_ipv6:
-                self.ipv6enabled_checkbox.SetValue(self.defaults['ipv6_enabled'])
-            self.gui_forcegreenonfirewall_checkbox.SetValue(self.defaults['gui_forcegreenonfirewall'])
-            self.gui_font_data.SetValue(self.defaults['gui_font'])
-            self.gui_ratesettingsdefault_data.SetStringSelection(self.defaults['gui_ratesettingsdefault'])
-            self.maxdownload_data.SetValue(self.defaults['max_download_rate'])
-            self.gui_ratesettingsmode_data.SetStringSelection(self.defaults['gui_ratesettingsmode'])
-            self.gui_default_savedir_ctrl.SetValue(self.defaults['gui_default_savedir'])
-            self.gui_savemode_data.SetSelection(1-self.defaults['gui_saveas_ask'])
-
-            self.checkingcolor = HexToColor(self.defaults['gui_checkingcolor'])
-            self.setColorIcon(self.checkingcolor_icon, self.checkingcolor_iconptr, self.checkingcolor)
-            self.downloadcolor = HexToColor(self.defaults['gui_downloadcolor'])
-            self.setColorIcon(self.downloadcolor_icon, self.downloadcolor_iconptr, self.downloadcolor)
-            self.seedingcolor = HexToColor(self.defaults['gui_seedingcolor'])
-            self.setColorIcon(self.seedingcolor_icon, self.seedingcolor_iconptr, self.seedingcolor)
-
-            if (sys.platform == 'win32'):
-                self.win32_taskbar_icon_checkbox.SetValue(self.defaults['win32_taskbar_icon'])
-#                self.upnp_checkbox.SetValue(self.defaults['upnp_nat_access'])
-                self.upnp_data.SetSelection(self.defaults['upnp_nat_access'])
-
-            # reset advanced too
-            self.advancedConfig = {}
-            for key in ['ip', 'bind', 'min_peers', 'max_initiate', 'display_interval',
-        'alloc_type', 'alloc_rate', 'max_files_open', 'max_connections', 'super_seeder',
-        'ipv6_binds_v4', 'double_check', 'triple_check', 'lock_files', 'lock_while_reading',
-        'expire_cache_data']:
-                self.advancedConfig[key] = self.defaults[key]
-            self.CloseAdvanced()
-          except:
-            self.parent.exception()
-
-
-        def saveConfigs(evt, self = self):
-          try:
-            self.config['gui_stretchwindow']=int(self.gui_stretchwindow_checkbox.GetValue())
-            self.config['gui_displaystats']=int(self.gui_displaystats_checkbox.GetValue())
-            self.config['gui_displaymiscstats']=int(self.gui_displaymiscstats_checkbox.GetValue())
-            self.config['security']=int(self.security_checkbox.GetValue())
-            self.config['auto_kick']=int(self.autokick_checkbox.GetValue())
-            buffering=int(self.buffering_checkbox.GetValue())
-            self.config['buffer_reads']=buffering
-            if buffering:
-                self.config['write_buffer_size']=self.defaults['write_buffer_size']
-            else:
-                self.config['write_buffer_size']=0
-            self.config['breakup_seed_bitfield']=int(self.breakup_checkbox.GetValue())
-            if self.autoflush_checkbox.GetValue():
-                self.config['auto_flush']=5
-            else:
-                self.config['auto_flush']=0
-            if sys.version_info >= (2,3) and socket.has_ipv6:
-                self.config['ipv6_enabled']=int(self.ipv6enabled_checkbox.GetValue())
-            self.config['gui_forcegreenonfirewall']=int(self.gui_forcegreenonfirewall_checkbox.GetValue())
-            self.config['minport']=self.minport_data.GetValue()
-            self.config['maxport']=self.maxport_data.GetValue()
-            self.config['random_port']=int(self.randomport_checkbox.GetValue())
-            self.config['gui_font']=self.gui_font_data.GetValue()
-            self.config['gui_ratesettingsdefault']=self.gui_ratesettingsdefault_data.GetStringSelection()
-            self.config['max_download_rate']=self.maxdownload_data.GetValue()
-            self.config['gui_ratesettingsmode']=self.gui_ratesettingsmode_data.GetStringSelection()
-            self.config['gui_default_savedir']=self.gui_default_savedir_ctrl.GetValue()
-            self.config['gui_saveas_ask']=1-self.gui_savemode_data.GetSelection()
-            self.config['gui_checkingcolor']=ColorToHex(self.checkingcolor)
-            self.config['gui_downloadcolor']=ColorToHex(self.downloadcolor)
-            self.config['gui_seedingcolor']=ColorToHex(self.seedingcolor)
-            
-            if (sys.platform == 'win32'):
-                self.config['win32_taskbar_icon']=int(self.win32_taskbar_icon_checkbox.GetValue())
-#                self.config['upnp_nat_access']=int(self.upnp_checkbox.GetValue())
-                self.config['upnp_nat_access']=self.upnp_data.GetSelection()
-
-            if self.advancedConfig:
-                for key,val in self.advancedConfig.items():
-                    self.config[key] = val
-
-            self.writeConfigFile()
-            self._configReset = True
-            self.Close()
-          except:
-            self.parent.exception()
-
-        def cancelConfigs(evt, self = self):
-            self.Close()
-
-        def savepath_set(evt, self = self):
-          try:
-            d = self.gui_default_savedir_ctrl.GetValue()
-            if d == '':
-                d = self.config['last_saved']
-            dl = wxDirDialog(self.panel, 'Choose a default directory to save to', 
-                d, style = wxDD_DEFAULT_STYLE | wxDD_NEW_DIR_BUTTON)
-            if dl.ShowModal() == wxID_OK:
-                self.gui_default_savedir_ctrl.SetValue(dl.GetPath())
-          except:
-            self.parent.exception()
-
-        def checkingcoloricon_set(evt, self = self):
-          try:
-            newcolor = self.getColorFromUser(self.panel,self.checkingcolor)
-            self.setColorIcon(self.checkingcolor_icon, self.checkingcolor_iconptr, newcolor)
-            self.checkingcolor = newcolor
-          except:
-            self.parent.exception()
-
-        def downloadcoloricon_set(evt, self = self):
-          try:
-            newcolor = self.getColorFromUser(self.panel,self.downloadcolor)
-            self.setColorIcon(self.downloadcolor_icon, self.downloadcolor_iconptr, newcolor)
-            self.downloadcolor = newcolor
-          except:
-            self.parent.exception()
-
-        def seedingcoloricon_set(evt, self = self):
-          try:
-            newcolor = self.getColorFromUser(self.panel,self.seedingcolor)
-            self.setColorIcon(self.seedingcolor_icon, self.seedingcolor_iconptr, newcolor)
-            self.seedingcolor = newcolor
-          except:
-            self.parent.exception()
-            
-        EVT_BUTTON(self.configMenuBox, saveButton.GetId(), saveConfigs)
-        EVT_BUTTON(self.configMenuBox, cancelButton.GetId(), cancelConfigs)
-        EVT_BUTTON(self.configMenuBox, defaultsButton.GetId(), setDefaults)
-        EVT_BUTTON(self.configMenuBox, advancedButton.GetId(), self.advancedMenu)
-        EVT_BUTTON(self.configMenuBox, savepathButton.GetId(), savepath_set)
-        EVT_LEFT_DOWN(self.checkingcolor_iconptr, checkingcoloricon_set)
-        EVT_LEFT_DOWN(self.downloadcolor_iconptr, downloadcoloricon_set)
-        EVT_LEFT_DOWN(self.seedingcolor_iconptr, seedingcoloricon_set)
-
-        self.configMenuBox.Show ()
-        border.Fit(panel)
-        self.configMenuBox.Fit()
-      except:
-        self.parent.exception()
-
-
-    def Close(self):
-        self.CloseAdvanced()
-        if self.configMenuBox is not None:
-            try:
-                self.configMenuBox.Close ()
-            except wxPyDeadObjectError, e:
-                pass
-            self.configMenuBox = None
-
-    def advancedMenu(self, event = None):
-      try:
-        if not self.advancedConfig:
-            for key in ['ip', 'bind', 'min_peers', 'max_initiate', 'display_interval',
-        'alloc_type', 'alloc_rate', 'max_files_open', 'max_connections', 'super_seeder',
-        'ipv6_binds_v4', 'double_check', 'triple_check', 'lock_files', 'lock_while_reading',
-        'expire_cache_data']:
-                self.advancedConfig[key] = self.config[key]
-
-        if (self.advancedMenuBox is not None):
-            try:
-                self.advancedMenuBox.Close ()
-            except wxPyDeadObjectError, e:
-                self.advancedMenuBox = None
-
-        self.advancedMenuBox = wxFrame(None, -1, 'BitTorrent Advanced Preferences', size = (1,1),
-                            style = wxDEFAULT_FRAME_STYLE|wxFULL_REPAINT_ON_RESIZE)
-        if (sys.platform == 'win32'):
-            self.advancedMenuBox.SetIcon(self.icon)
-
-        panel = wxPanel(self.advancedMenuBox, -1)
-#        self.panel = panel
-
-        def StaticText(text, font = self.FONT, underline = False, color = None, panel = panel):
-            x = wxStaticText(panel, -1, text, style = wxALIGN_LEFT)
-            x.SetFont(wxFont(font, wxDEFAULT, wxNORMAL, wxNORMAL, underline))
-            if color is not None:
-                x.SetForegroundColour(color)
-            return x
-
-        colsizer = wxFlexGridSizer(cols = 1, hgap = 13, vgap = 13)
-        warningtext = StaticText('CHANGE THESE SETTINGS AT YOUR OWN RISK', self.FONT+4, True, 'Red')
-        colsizer.Add(warningtext, 1, wxALIGN_CENTER)
-
-        self.ip_data = wxTextCtrl(parent = panel, id = -1, 
-                    value = self.advancedConfig['ip'],
-                    size = (self.FONT*13, int(self.FONT*2.2)), style = wxTE_PROCESS_TAB)
-        self.ip_data.SetFont(self.default_font)
-        
-        self.bind_data = wxTextCtrl(parent = panel, id = -1, 
-                    value = self.advancedConfig['bind'],
-                    size = (self.FONT*13, int(self.FONT*2.2)), style = wxTE_PROCESS_TAB)
-        self.bind_data.SetFont(self.default_font)
-        
-        if sys.version_info >= (2,3) and socket.has_ipv6:
-            self.ipv6bindsv4_data=wxChoice(panel, -1,
-                             choices = ['separate sockets', 'single socket'])
-            self.ipv6bindsv4_data.SetFont(self.default_font)
-            self.ipv6bindsv4_data.SetSelection(self.advancedConfig['ipv6_binds_v4'])
-
-        self.minpeers_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*7, -1))
-        self.minpeers_data.SetFont(self.default_font)
-        self.minpeers_data.SetRange(10,100)
-        self.minpeers_data.SetValue(self.advancedConfig['min_peers'])
-        # max_initiate = 2*minpeers
-
-        self.displayinterval_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*7, -1))
-        self.displayinterval_data.SetFont(self.default_font)
-        self.displayinterval_data.SetRange(100,2000)
-        self.displayinterval_data.SetValue(int(self.advancedConfig['display_interval']*1000))
-
-        self.alloctype_data=wxChoice(panel, -1,
-                         choices = ['normal', 'background', 'pre-allocate', 'sparse'])
-        self.alloctype_data.SetFont(self.default_font)
-        self.alloctype_data.SetStringSelection(self.advancedConfig['alloc_type'])
-
-        self.allocrate_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*7,-1))
-        self.allocrate_data.SetFont(self.default_font)
-        self.allocrate_data.SetRange(1,100)
-        self.allocrate_data.SetValue(int(self.advancedConfig['alloc_rate']))
-
-        self.locking_data=wxChoice(panel, -1,
-                           choices = ['no locking', 'lock while writing', 'lock always'])
-        self.locking_data.SetFont(self.default_font)
-        if self.advancedConfig['lock_files']:
-            if self.advancedConfig['lock_while_reading']:
-                self.locking_data.SetSelection(2)
-            else:
-                self.locking_data.SetSelection(1)
-        else:
-            self.locking_data.SetSelection(0)
-
-        self.doublecheck_data=wxChoice(panel, -1,
-                           choices = ['no extra checking', 'double-check', 'triple-check'])
-        self.doublecheck_data.SetFont(self.default_font)
-        if self.advancedConfig['double_check']:
-            if self.advancedConfig['triple_check']:
-                self.doublecheck_data.SetSelection(2)
-            else:
-                self.doublecheck_data.SetSelection(1)
-        else:
-            self.doublecheck_data.SetSelection(0)
-
-        self.maxfilesopen_choices = ['50', '100', '200', 'no limit ']
-        self.maxfilesopen_data=wxChoice(panel, -1, choices = self.maxfilesopen_choices)
-        self.maxfilesopen_data.SetFont(self.default_font)
-        setval = self.advancedConfig['max_files_open']
-        if setval == 0:
-            setval = 'no limit '
-        else:
-            setval = str(setval)
-        if not setval in self.maxfilesopen_choices:
-            setval = self.maxfilesopen_choices[0]
-        self.maxfilesopen_data.SetStringSelection(setval)
-
-        self.maxconnections_choices = ['no limit ', '20', '30', '40', '50', '60', '100', '200']
-        self.maxconnections_data=wxChoice(panel, -1, choices = self.maxconnections_choices)
-        self.maxconnections_data.SetFont(self.default_font)
-        setval = self.advancedConfig['max_connections']
-        if setval == 0:
-            setval = 'no limit '
-        else:
-            setval = str(setval)
-        if not setval in self.maxconnections_choices:
-            setval = self.maxconnections_choices[0]
-        self.maxconnections_data.SetStringSelection(setval)
-
-        self.superseeder_data=wxChoice(panel, -1,
-                         choices = ['normal', 'super-seed'])
-        self.superseeder_data.SetFont(self.default_font)
-        self.superseeder_data.SetSelection(self.advancedConfig['super_seeder'])
-
-        self.expirecache_choices = ['never ', '3', '5', '7', '10', '15', '30', '60', '90']
-        self.expirecache_data=wxChoice(panel, -1, choices = self.expirecache_choices)
-        setval = self.advancedConfig['expire_cache_data']
-        if setval == 0:
-            setval = 'never '
-        else:
-            setval = str(setval)
-        if not setval in self.expirecache_choices:
-            setval = self.expirecache_choices[0]
-        self.expirecache_data.SetFont(self.default_font)
-        self.expirecache_data.SetStringSelection(setval)
-       
-
-        twocolsizer = wxFlexGridSizer(cols = 2, hgap = 20)
-        datasizer = wxFlexGridSizer(cols = 2, vgap = 2)
-        datasizer.Add(StaticText('Local IP: '), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.ip_data)
-        datasizer.Add(StaticText('IP to bind to: '), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.bind_data)
-        if sys.version_info >= (2,3) and socket.has_ipv6:
-            datasizer.Add(StaticText('IPv6 socket handling: '), 1, wxALIGN_CENTER_VERTICAL)
-            datasizer.Add(self.ipv6bindsv4_data)
-        datasizer.Add(StaticText('Minimum number of peers: '), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.minpeers_data)
-        datasizer.Add(StaticText('Display interval (ms): '), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.displayinterval_data)
-        datasizer.Add(StaticText('Disk allocation type:'), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.alloctype_data)
-        datasizer.Add(StaticText('Allocation rate (MiB/s):'), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.allocrate_data)
-        datasizer.Add(StaticText('File locking:'), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.locking_data)
-        datasizer.Add(StaticText('Extra data checking:'), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.doublecheck_data)
-        datasizer.Add(StaticText('Max files open:'), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.maxfilesopen_data)
-        datasizer.Add(StaticText('Max peer connections:'), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.maxconnections_data)
-        datasizer.Add(StaticText('Default seeding mode:'), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.superseeder_data)
-        datasizer.Add(StaticText('Expire resume data(days):'), 1, wxALIGN_CENTER_VERTICAL)
-        datasizer.Add(self.expirecache_data)
-        
-        twocolsizer.Add(datasizer)
-
-        infosizer = wxFlexGridSizer(cols = 1)
-        self.hinttext = StaticText('', self.FONT, False, 'Blue')
-        infosizer.Add(self.hinttext, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL)
-        infosizer.SetMinSize((180,100))
-        twocolsizer.Add(infosizer, 1, wxEXPAND)
-
-        colsizer.Add(twocolsizer)
-
-        savesizer = wxGridSizer(cols = 3, hgap = 20)
-        okButton = wxButton(panel, -1, 'OK')
-#        okButton.SetFont(self.default_font)
-        savesizer.Add(okButton, 0, wxALIGN_CENTER)
-
-        cancelButton = wxButton(panel, -1, 'Cancel')
-#        cancelButton.SetFont(self.default_font)
-        savesizer.Add(cancelButton, 0, wxALIGN_CENTER)
-
-        defaultsButton = wxButton(panel, -1, 'Revert to Defaults')
-#        defaultsButton.SetFont(self.default_font)
-        savesizer.Add(defaultsButton, 0, wxALIGN_CENTER)
-        colsizer.Add(savesizer, 1, wxALIGN_CENTER)
-
-        resizewarningtext=StaticText('None of these settings will take effect until the next time you start BitTorrent', self.FONT-2)
-        colsizer.Add(resizewarningtext, 1, wxALIGN_CENTER)
-
-        border = wxBoxSizer(wxHORIZONTAL)
-        border.Add(colsizer, 1, wxEXPAND | wxALL, 4)
-        
-        panel.SetSizer(border)
-        panel.SetAutoLayout(True)
-
-        def setDefaults(evt, self = self):
-          try:
-            self.ip_data.SetValue(self.defaults['ip'])
-            self.bind_data.SetValue(self.defaults['bind'])
-            if sys.version_info >= (2,3) and socket.has_ipv6:
-                self.ipv6bindsv4_data.SetSelection(self.defaults['ipv6_binds_v4'])
-            self.minpeers_data.SetValue(self.defaults['min_peers'])
-            self.displayinterval_data.SetValue(int(self.defaults['display_interval']*1000))
-            self.alloctype_data.SetStringSelection(self.defaults['alloc_type'])
-            self.allocrate_data.SetValue(int(self.defaults['alloc_rate']))
-            if self.defaults['lock_files']:
-                if self.defaults['lock_while_reading']:
-                    self.locking_data.SetSelection(2)
-                else:
-                    self.locking_data.SetSelection(1)
-            else:
-                self.locking_data.SetSelection(0)
-            if self.defaults['double_check']:
-                if self.defaults['triple_check']:
-                    self.doublecheck_data.SetSelection(2)
-                else:
-                    self.doublecheck_data.SetSelection(1)
-            else:
-                self.doublecheck_data.SetSelection(0)
-            setval = self.defaults['max_files_open']
-            if setval == 0:
-                setval = 'no limit '
-            else:
-                setval = str(setval)
-            if not setval in self.maxfilesopen_choices:
-                setval = self.maxfilesopen_choices[0]
-            self.maxfilesopen_data.SetStringSelection(setval)
-            setval = self.defaults['max_connections']
-            if setval == 0:
-                setval = 'no limit '
-            else:
-                setval = str(setval)
-            if not setval in self.maxconnections_choices:
-                setval = self.maxconnections_choices[0]
-            self.maxconnections_data.SetStringSelection(setval)
-            self.superseeder_data.SetSelection(int(self.defaults['super_seeder']))
-            setval = self.defaults['expire_cache_data']
-            if setval == 0:
-                setval = 'never '
-            else:
-                setval = str(setval)
-            if not setval in self.expirecache_choices:
-                setval = self.expirecache_choices[0]
-            self.expirecache_data.SetStringSelection(setval)
-          except:
-            self.parent.exception()
-
-        def saveConfigs(evt, self = self):
-          try:
-            self.advancedConfig['ip'] = self.ip_data.GetValue()
-            self.advancedConfig['bind'] = self.bind_data.GetValue()
-            if sys.version_info >= (2,3) and socket.has_ipv6:
-                self.advancedConfig['ipv6_binds_v4'] = self.ipv6bindsv4_data.GetSelection()
-            self.advancedConfig['min_peers'] = self.minpeers_data.GetValue()
-            self.advancedConfig['display_interval'] = float(self.displayinterval_data.GetValue())/1000
-            self.advancedConfig['alloc_type'] = self.alloctype_data.GetStringSelection()
-            self.advancedConfig['alloc_rate'] = float(self.allocrate_data.GetValue())
-            self.advancedConfig['lock_files'] = int(self.locking_data.GetSelection() >= 1)
-            self.advancedConfig['lock_while_reading'] = int(self.locking_data.GetSelection() > 1)
-            self.advancedConfig['double_check'] = int(self.doublecheck_data.GetSelection() >= 1)
-            self.advancedConfig['triple_check'] = int(self.doublecheck_data.GetSelection() > 1)
-            try:
-                self.advancedConfig['max_files_open'] = int(self.maxfilesopen_data.GetStringSelection())
-            except:       # if it ain't a number, it must be "no limit"
-                self.advancedConfig['max_files_open'] = 0
-            try:
-                self.advancedConfig['max_connections'] = int(self.maxconnections_data.GetStringSelection())
-                self.advancedConfig['max_initiate'] = min(
-                    2*self.advancedConfig['min_peers'], self.advancedConfig['max_connections'])
-            except:       # if it ain't a number, it must be "no limit"
-                self.advancedConfig['max_connections'] = 0
-                self.advancedConfig['max_initiate'] = 2*self.advancedConfig['min_peers']
-            self.advancedConfig['super_seeder']=int(self.superseeder_data.GetSelection())
-            try:
-                self.advancedConfig['expire_cache_data'] = int(self.expirecache_data.GetStringSelection())
-            except:
-                self.advancedConfig['expire_cache_data'] = 0
-            self.advancedMenuBox.Close()
-          except:
-            self.parent.exception()
-
-        def cancelConfigs(evt, self = self):            
-            self.advancedMenuBox.Close()
-
-        def ip_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\nThe IP reported to the tracker.\n' +
-                                  'unless the tracker is on the\n' +
-                                  'same intranet as this client,\n' +
-                                  'the tracker will autodetect the\n' +
-                                  "client's IP and ignore this\n" +
-                                  "value.")
-
-        def bind_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\nThe IP the client will bind to.\n' +
-                                  'Only useful if your machine is\n' +
-                                  'directly handling multiple IPs.\n' +
-                                  "If you don't know what this is,\n" +
-                                  "leave it blank.")
-
-        def ipv6bindsv4_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\nCertain operating systems will\n' +
-                                  'open IPv4 protocol connections on\n' +
-                                  'an IPv6 socket; others require you\n' +
-                                  "to open two sockets on the same\n" +
-                                  "port, one IPv4 and one IPv6.")
-
-        def minpeers_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\nThe minimum number of peers the\n' +
-                                  'client tries to stay connected\n' +
-                                  'with.  Do not set this higher\n' +
-                                  'unless you have a very fast\n' +
-                                  "connection and a lot of system\n" +
-                                  "resources.")
-
-        def displayinterval_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\nHow often to update the\n' +
-                                  'graphical display, in 1/1000s\n' +
-                                  'of a second. Setting this too low\n' +
-                                  "will strain your computer's\n" +
-                                  "processor and video access.")
-
-        def alloctype_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\nHow to allocate disk space.\n' +
-                                  'normal allocates space as data is\n' +
-                                  'received, background also adds\n' +
-                                  "space in the background, pre-\n" +
-                                  "allocate reserves up front, and\n" +
-                                  'sparse is only for filesystems\n' +
-                                  'that support it by default.')
-
-        def allocrate_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\nAt what rate to allocate disk\n' +
-                                  'space when allocating in the\n' +
-                                  'background.  Set this too high on a\n' +
-                                  "slow filesystem and your download\n" +
-                                  "will slow to a crawl.")
-
-        def locking_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\n\nFile locking prevents other\n' +
-                                  'programs (including other instances\n' +
-                                  'of BitTorrent) from accessing files\n' +
-                                  "you are downloading.")
-
-        def doublecheck_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\nHow much extra checking to do\n' +
-                                  'making sure no data is corrupted.\n' +
-                                  'Double-check mode uses more CPU,\n' +
-                                  "while triple-check mode increases\n" +
-                                  "disk accesses.")
-
-        def maxfilesopen_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\n\nThe maximum number of files to\n' +
-                                  'keep open at the same time.  Zero\n' +
-                                  'means no limit.  Please note that\n' +
-                                  "if this option is in effect,\n" +
-                                  "files are not guaranteed to be\n" +
-                                  "locked.")
-
-        def maxconnections_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\nSome operating systems, most\n' +
-                                  'notably Windows 9x/ME combined\n' +
-                                  'with certain network drivers,\n' +
-                                  "cannot handle more than a certain\n" +
-                                  "number of open ports.  If the\n" +
-                                  "client freezes, try setting this\n" +
-                                  "to 60 or below.")
-
-        def superseeder_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\nThe "super-seed" method allows\n' +
-                                  'a single source to more efficiently\n' +
-                                  'seed a large torrent, but is not\n' +
-                                  "necessary in a well-seeded torrent,\n" +
-                                  "and causes problems with statistics.\n" +
-                                  "Unless you routinely seed torrents\n" +
-                                  "you can enable this by selecting\n" +
-                                  '"SUPER-SEED" for connection type.\n' +
-                                  '(once enabled it does not turn off.)')
-
-        def expirecache_hint(evt, self = self):
-            self.hinttext.SetLabel('\n\nThe client stores temporary data\n' +
-                                  'in order to handle downloading only\n' +
-                                  'specific files from the torrent and\n' +
-                                  "so it can resume downloads more\n" +
-                                  "quickly.  This sets how long the\n" +
-                                  "client will keep this data before\n" +
-                                  "deleting it to free disk space.")
-
-        EVT_BUTTON(self.advancedMenuBox, okButton.GetId(), saveConfigs)
-        EVT_BUTTON(self.advancedMenuBox, cancelButton.GetId(), cancelConfigs)
-        EVT_BUTTON(self.advancedMenuBox, defaultsButton.GetId(), setDefaults)
-        EVT_ENTER_WINDOW(self.ip_data, ip_hint)
-        EVT_ENTER_WINDOW(self.bind_data, bind_hint)
-        if sys.version_info >= (2,3) and socket.has_ipv6:
-            EVT_ENTER_WINDOW(self.ipv6bindsv4_data, ipv6bindsv4_hint)
-        EVT_ENTER_WINDOW(self.minpeers_data, minpeers_hint)
-        EVT_ENTER_WINDOW(self.displayinterval_data, displayinterval_hint)
-        EVT_ENTER_WINDOW(self.alloctype_data, alloctype_hint)
-        EVT_ENTER_WINDOW(self.allocrate_data, allocrate_hint)
-        EVT_ENTER_WINDOW(self.locking_data, locking_hint)
-        EVT_ENTER_WINDOW(self.doublecheck_data, doublecheck_hint)
-        EVT_ENTER_WINDOW(self.maxfilesopen_data, maxfilesopen_hint)
-        EVT_ENTER_WINDOW(self.maxconnections_data, maxconnections_hint)
-        EVT_ENTER_WINDOW(self.superseeder_data, superseeder_hint)
-        EVT_ENTER_WINDOW(self.expirecache_data, expirecache_hint)
-
-        self.advancedMenuBox.Show ()
-        border.Fit(panel)
-        self.advancedMenuBox.Fit()
-      except:
-        self.parent.exception()
-
-
-    def CloseAdvanced(self):
-        if self.advancedMenuBox is not None:
-            try:
-                self.advancedMenuBox.Close()
-            except wxPyDeadObjectError, e:
-                self.advancedMenuBox = None
-
diff --git a/www/pages/torrent/client/ConnChoice.py b/www/pages/torrent/client/ConnChoice.py
deleted file mode 100644 (file)
index 8d07396..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-connChoices=(
-    {'name':'automatic',
-     'rate':{'min':0, 'max':5000, 'def': 0},
-     'conn':{'min':0, 'max':100,  'def': 0},
-     'automatic':1},
-    {'name':'unlimited',
-     'rate':{'min':0, 'max':5000, 'def': 0, 'div': 50},
-     'conn':{'min':4, 'max':100,  'def': 4}},
-    {'name':'dialup/isdn',
-     'rate':{'min':3,   'max':   8, 'def':  5},
-     'conn':{'min':2, 'max':  3, 'def': 2},
-     'initiate': 12},
-    {'name':'dsl/cable slow',
-     'rate':{'min':10,  'max':  48, 'def': 13},
-     'conn':{'min':4, 'max': 20, 'def': 4}},
-    {'name':'dsl/cable fast',
-     'rate':{'min':20,  'max': 100, 'def': 40},
-     'conn':{'min':4, 'max': 30, 'def': 6}},
-    {'name':'T1',
-     'rate':{'min':100, 'max': 300, 'def':150},
-     'conn':{'min':4, 'max': 40, 'def':10}},
-    {'name':'T3+',
-     'rate':{'min':400, 'max':2000, 'def':500},
-     'conn':{'min':4, 'max':100, 'def':20}},
-    {'name':'seeder',
-     'rate':{'min':0, 'max':5000, 'def':0, 'div': 50},
-     'conn':{'min':1, 'max':100, 'def':1}},
-    {'name':'SUPER-SEED', 'super-seed':1}
-     )
-
-connChoiceList = map(lambda x:x['name'], connChoices)
diff --git a/www/pages/torrent/client/CreateIcons.py b/www/pages/torrent/client/CreateIcons.py
deleted file mode 100644 (file)
index 72e0241..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-# Generated from bt_MakeCreateIcons - 05/10/04 22:15:33
-# T-0.3.0 (BitTornado)
-
-from binascii import a2b_base64
-from zlib import decompress
-from os.path import join
-
-icons = {
-    "icon_bt.ico":
-        "eJyt1K+OFEEQx/FaQTh5GDRZhSQpiUHwCrxCBYXFrjyJLXeXEARPsZqUPMm+" +
-        "AlmP+PGtngoLDji69zMz2zt/qqtr1mxHv7621d4+MnvK/jl66Bl2drV+e7Wz" +
-        "S/v12A7rY4fDtuvOwfF4tOPXo52/fLLz+WwpWd6nqRXHKXux39sTrtnjNd7g" +
-        "PW7wGSd860f880kffjvJ2QYS1Zcw4AjcoaA5yRFIFDQXOgKJguZmjkCioB4T" +
-        "Y2CqxpTXA7sHEgVNEC8RSBQ0gfk7xtknCupgk3EEEgXlNgFHIFHQTMoRSBQ0" +
-        "E+1ouicKmsk7AomCJiGOQKKgSZIjkChoEucIJAqaZDoCiYImwb4iydULmqQ7" +
-        "AomC1kLcEQ/jSBQ0i+MIJAqaBXMEElVdi9siOgKJgmZhfWWlVjTddXW/FtsR" +
-        "SBQ0BeAIJAqaonAEEgVNoTgCiYKmeByBREHaqiVWRtSRrAJzBBIFTdE5AomC" +
-        "phBPpxPP57dVkDfrTl063nUVnWe383fZx9tb3uN+o7U+BLDtuvcQm8d/27Y/" +
-        "jO3o5/ay+YPv/+f6y30e1OyB7QcsGWFj",
-    "icon_done.ico":
-        "eJyt1K2OVEEQhuEaQbJyMWgyCklSEoPgFvYWKigsduRKbLndhCC4itGk5Erm" +
-        "Fsh4xMdbfSoMOGDpnuf89Jyf6uqaMdvRr69ttbdPzJ6xf4Eeeo6dXa3vXu/s" +
-        "0n49tsP62OGw7bpzcDwe7fj1aOcvn+x8PltKlg9pasVxyl7u9/aUe/Z4gxu8" +
-        "xy0+44Rv/Yp/vujDbxc520Ci+hYGHIF7FDQXOQKJguZGRyBR0DzMEUgU1GNi" +
-        "DEzVmPJ6YfdAoqAJ4hUCiYImMH/HOPtEQR1sMo5AoqDcJuAIJAqaSTkCiYJm" +
-        "oh1N90RBM3lHIFHQJMQRSBQ0SXIEEgVN4hyBREGTTEcgUdAk2FckuXpBk3RH" +
-        "IFHQWoh74mEciYJmcRyBREGzYI5AoqprcVtERyBR0Cysr6zUiqa7rh7WYjsC" +
-        "iYKmAByBREFTFI5AoqApFEcgUdAUjyOQKEhbtcTKiDqSVWCOQKKgKTpHIFHQ" +
-        "FOLpdOL9fLcK8nY9qUvHu66i8+x2/i77eHfH77h/0VofAth23Xuoz/+2bX8Y" +
-        "29HP7WXzB+f/5/7Lcx7V7JHtB9dPG3I=",
-    "black.ico":
-        "eJzt1zsOgkAYReFLLCztjJ2UlpLY485kOS7DpbgESwqTcQZDghjxZwAfyfl0" +
-        "LIieGzUWSom/pan840rHnbSUtPHHX9Je9+tAh2ybNe8TZZ/vk8ajJ4zl6JVJ" +
-        "+xFx+0R03Djx1/2B8bcT9L/bt0+4Wq+4se8e/VTfMvGqb4n3nYiIGz+lvt9s" +
-        "9EpE2T4xJN4xNFYWU6t+JWXuXDFzTom7SodSyi/S+iwtwjlJ80KaNY/C34rW" +
-        "aT8nvK5uhF7ohn7Yqfb87kffLAAAAAAAAAAAAAAAAAAAGMUNy7dADg==",
-    "blue.ico":
-        "eJzt10EOwUAYhuGv6cLSTux06QD2dTM9jmM4iiNYdiEZ81cIFTWddtDkfbQW" +
-        "De8XogtS5h9FIf+81H4jLSSt/ekvaavrdaCDez4SZV+PpPHoicBy9ErSfkQ8" +
-        "fCI6Hjgx6f7A+McJ+r/t95i46xMP7bf8Uz9o4k0/XMT338voP5shK0MkjXcM" +
-        "YSqam6Qunatyf7Nk7iztaqk8SaujNLfzIM0qKX88ZX8rWmf7Nfa+W8N61rW+" +
-        "7TR7fverHxYAAAAAAAAAAAAAAAAAAIziApVZ444=",
-    "green.ico":
-        "eJzt1zEOgjAAheFHGBzdjJuMHsAdbybxNB7Do3gERwaT2mJIBCOWlqok/yc4" +
-        "EP1fNDIoZfZRFLLPa5120krS1p72kvZ6XAeGHLtHouzrkTQePOFZDl5J2g+I" +
-        "+08Exz0nZt2PjH+coP/bvveEaY2L+/VN13/1PSbe9v0FfP+jTP6ziVmJkTQ+" +
-        "MISZaO6SujSmyu3dkpmbdKil8iptLtLSnWdpUUn58yn3t6J39l/j3tc2XM91" +
-        "Xd/tNHt296sfFgAAAAAAAAAAAAAAAAAATOIOVLEoDg==",
-    "red.ico":
-        "eJzt10EOwUAYhuGv6cLSTux06QD2dTOO4xiO4giWXUjG/BVCRTuddtDkfbQW" +
-        "De8XogtS5h9FIf+81GEjLSSt/ekvaavbdaCVez0SZd+PpPHoicBy9ErSfkQ8" +
-        "fCI6Hjgx6f7AeOcE/d/2QyceesaD+g1/1u+e+NwPF/H99zL6z2bIyhBJ4y1D" +
-        "mIb6LqlK5/a5v1syd5F2lVSepdVJmtt5lGZ7KX8+ZX8rGmfzNfa+e8N61rW+" +
-        "7dR7fverHxYAAAAAAAAAAAAAAAAAAIziCpgs444=",
-    "white.ico":
-        "eJzt1zsOgkAYReFLKCztjJ2ULsAed6bLcRnuwYTaJVhSmIwzGBLEiD8D+EjO" +
-        "p2NB9NyosVBK/C3L5B+XOmykhaS1P/6StrpfBzoUp6J5nyj7fJ80Hj1hLEev" +
-        "TNqPiNsnouPGib/uD4y/naD/3b59wtV6xY199+in+paJV31LvO9ERNz4KfX9" +
-        "ZqNXIsr2iSHxjqGxspha9Sspc+f2qXNK3FXalVJ+kVZnaR7OUZrtpbR5FP5W" +
-        "tE77OeF1dSP0Qjf0w06153c/+mYBAAAAAAAAAAAAAAAAAMAobj//I7s=",
-    "yellow.ico":
-        "eJzt1zsOgkAYReFLKCztjJ2ULsAedybLcRkuxSVYUpiM82M0ihGHgVFJzidY" +
-        "ED03vgqlzN+KQv5+qf1GWkha+9Nf0lbX60AX556ORNnXI2k8eiKwHL2StB8R" +
-        "D5+IjgdOTLo/MP5xgv5v+8ETd/3iYf2W/+oHTLzth4t4/3sZ/WszZGWIpPGO" +
-        "IUxE8yupS+eq3H9smTtLu1oqT9LqKM3tPEizSsofT9nfitbZfow979awnnWt" +
-        "bzvNnt/96osFAAAAAAAAAAAAAAAAAACjuABhjmIs",
-    "black1.ico":
-        "eJzt0zEOgkAUANEhFpZSGTstTWzkVt5Cj8ZROAIHMNGPWBCFDYgxMZkHn2Iz" +
-        "G5YCyOLKc+K54XSANbCPiSV2tOt/qjgW3XtSnN41FH/Qv29Jx/P7qefp7W8P" +
-        "4z85HQ+9JRG/7BpTft31DPUKyiVcFjEZzQ/TTtdzrWnKmCr6evv780qSJEmS" +
-        "JEmSJEmSJEmSpPnunVFDcA==",
-    "green1.ico":
-        "eJzt0zEKwkAQRuEXLCyTSuy0DHgxb6F4shzFI+QAgpkkFoombowIwvt2Z4vh" +
-        "X5gtFrJYRUGca/Y7WAFlVLTY0vf/1elxTwqP3xoKf5B/vjIenp+fOs+r/LWT" +
-        "/uQ34aGpUqQnv+1ygDqHagnHRVRG+2H6unfrtZkq6hz5evP7eSVJkiRJkiRJ" +
-        "kiRJkiRJ0nwNoWQ+AA==",
-    "yellow1.ico":
-        "eJzt0zEKwkAQRuEXLCxNJXZaCl7MW8Sj5SgeIQcQ4oS1UDTJxkhAeN/ubDH8" +
-        "C7PFQhGrLIlzx/kEW+AYFS0OpP6/atuXPSk8fKsv/EX+/cpweH5+6jyf8kn+" +
-        "k0fCfVPlyE/+2q2CZgP1Gi6rqILuw6R69uh1mTrqGvlmv/y8kiRJkiRJkiRJ" +
-        "kiRJkiRpvjsp9L8k",
-    "alloc.gif":
-        "eJxz93SzsEw0YRBh+M4ABi0MS3ue///P8H8UjIIRBhR/sjAyMDAx6IAyAihP" +
-        "MHAcYWDlkPHYsOBgM4ewVsyJDQsPNzEoebF8CHjo0smjH3dmRsDjI33C7Dw3" +
-        "MiYuOtjNyDShRSNwyemJguJJKhaGS32nGka61Vg2NJyYKRd+bY+nwtMzjbqV" +
-        "Qh84gxMCJgnlL4vJuqJyaa5NfFLNLsNVV2a7syacfVWkHd4bv7RN1ltM7ejm" +
-        "tMtNZ19Oyb02p8C3aqr3dr2GbXl/7fZyOej5rW653WZ7MzzHZV+v7O2/EZM+" +
-        "Pt45kbX6ScWHNWfOilo3n5thucXv8org1XF3DRQYrAEWiVY3"
-}
-
-def GetIcons():
-    return icons.keys()
-
-def CreateIcon(icon, savedir):
-    try:
-        f = open(join(savedir,icon),"wb")
-        f.write(decompress(a2b_base64(icons[icon])))
-        success = 1
-    except:
-        success = 0
-    try:
-        f.close()
-    except:
-        pass
-    return success
diff --git a/www/pages/torrent/client/CurrentRateMeasure.py b/www/pages/torrent/client/CurrentRateMeasure.py
deleted file mode 100644 (file)
index a363565..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-# Written by Bram Cohen
-# see LICENSE.txt for license information
-
-from clock import clock
-
-class Measure:
-    def __init__(self, max_rate_period, fudge = 1):
-        self.max_rate_period = max_rate_period
-        self.ratesince = clock() - fudge
-        self.last = self.ratesince
-        self.rate = 0.0
-        self.total = 0l
-
-    def update_rate(self, amount):
-        self.total += amount
-        t = clock()
-        self.rate = (self.rate * (self.last - self.ratesince) + 
-            amount) / (t - self.ratesince + 0.0001)
-        self.last = t
-        if self.ratesince < t - self.max_rate_period:
-            self.ratesince = t - self.max_rate_period
-
-    def get_rate(self):
-        self.update_rate(0)
-        return self.rate
-
-    def get_rate_noupdate(self):
-        return self.rate
-
-    def time_until_rate(self, newrate):
-        if self.rate <= newrate:
-            return 0
-        t = clock() - self.ratesince
-        return ((self.rate * t) / newrate) - t
-
-    def get_total(self):
-        return self.total
\ No newline at end of file
diff --git a/www/pages/torrent/client/HTTPHandler.py b/www/pages/torrent/client/HTTPHandler.py
deleted file mode 100644 (file)
index b8146e5..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-# Written by Bram Cohen
-# see LICENSE.txt for license information
-
-from cStringIO import StringIO
-from sys import stdout
-import time
-from clock import clock
-from gzip import GzipFile
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-DEBUG = False
-
-weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-
-months = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
-    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-
-class HTTPConnection:
-    def __init__(self, handler, connection):
-        self.handler = handler
-        self.connection = connection
-        self.buf = ''
-        self.closed = False
-        self.done = False
-        self.donereading = False
-        self.next_func = self.read_type
-
-    def get_ip(self):
-        return self.connection.get_ip()
-
-    def data_came_in(self, data):
-        if self.donereading or self.next_func is None:
-            return True
-        self.buf += data
-        while True:
-            try:
-                i = self.buf.index('\n')
-            except ValueError:
-                return True
-            val = self.buf[:i]
-            self.buf = self.buf[i+1:]
-            self.next_func = self.next_func(val)
-            if self.donereading:
-                return True
-            if self.next_func is None or self.closed:
-                return False
-
-    def read_type(self, data):
-        self.header = data.strip()
-        words = data.split()
-        if len(words) == 3:
-            self.command, self.path, garbage = words
-            self.pre1 = False
-        elif len(words) == 2:
-            self.command, self.path = words
-            self.pre1 = True
-            if self.command != 'GET':
-                return None
-        else:
-            return None
-        if self.command not in ('HEAD', 'GET'):
-            return None
-        self.headers = {}
-        return self.read_header
-
-    def read_header(self, data):
-        data = data.strip()
-        if data == '':
-            self.donereading = True
-            if self.headers.get('accept-encoding','').find('gzip') > -1:
-                self.encoding = 'gzip'
-            else:
-                self.encoding = 'identity'
-            r = self.handler.getfunc(self, self.path, self.headers)
-            if r is not None:
-                self.answer(r)
-            return None
-        try:
-            i = data.index(':')
-        except ValueError:
-            return None
-        self.headers[data[:i].strip().lower()] = data[i+1:].strip()
-        if DEBUG:
-            print data[:i].strip() + ": " + data[i+1:].strip()
-        return self.read_header
-
-    def answer(self, (responsecode, responsestring, headers, data)):
-        if self.closed:
-            return
-        if self.encoding == 'gzip':
-            compressed = StringIO()
-            gz = GzipFile(fileobj = compressed, mode = 'wb', compresslevel = 9)
-            gz.write(data)
-            gz.close()
-            cdata = compressed.getvalue()
-            if len(cdata) >= len(data):
-                self.encoding = 'identity'
-            else:
-                if DEBUG:
-                   print "Compressed: %i  Uncompressed: %i\n" % (len(cdata),len(data))
-                data = cdata
-                headers['Content-Encoding'] = 'gzip'
-
-        # i'm abusing the identd field here, but this should be ok
-        if self.encoding == 'identity':
-            ident = '-'
-        else:
-            ident = self.encoding
-        self.handler.log( self.connection.get_ip(), ident, '-',
-                          self.header, responsecode, len(data),
-                          self.headers.get('referer','-'),
-                          self.headers.get('user-agent','-') )
-        self.done = True
-        r = StringIO()
-        r.write('HTTP/1.0 ' + str(responsecode) + ' ' + 
-            responsestring + '\r\n')
-        if not self.pre1:
-            headers['Content-Length'] = len(data)
-            for key, value in headers.items():
-                r.write(key + ': ' + str(value) + '\r\n')
-            r.write('\r\n')
-        if self.command != 'HEAD':
-            r.write(data)
-        self.connection.write(r.getvalue())
-        if self.connection.is_flushed():
-            self.connection.shutdown(1)
-
-class HTTPHandler:
-    def __init__(self, getfunc, minflush):
-        self.connections = {}
-        self.getfunc = getfunc
-        self.minflush = minflush
-        self.lastflush = clock()
-
-    def external_connection_made(self, connection):
-        self.connections[connection] = HTTPConnection(self, connection)
-
-    def connection_flushed(self, connection):
-        if self.connections[connection].done:
-            connection.shutdown(1)
-
-    def connection_lost(self, connection):
-        ec = self.connections[connection]
-        ec.closed = True
-        del ec.connection
-        del ec.next_func
-        del self.connections[connection]
-
-    def data_came_in(self, connection, data):
-        c = self.connections[connection]
-        if not c.data_came_in(data) and not c.closed:
-            c.connection.shutdown(1)
-
-    def log(self, ip, ident, username, header,
-            responsecode, length, referrer, useragent):
-        year, month, day, hour, minute, second, a, b, c = time.localtime(time.time())
-        print '%s %s %s [%02d/%3s/%04d:%02d:%02d:%02d] "%s" %i %i "%s" "%s"' % (
-            ip, ident, username, day, months[month], year, hour,
-            minute, second, header, responsecode, length, referrer, useragent)
-        t = clock()
-        if t - self.lastflush > self.minflush:
-            self.lastflush = t
-            stdout.flush()
diff --git a/www/pages/torrent/client/PSYCO.py b/www/pages/torrent/client/PSYCO.py
deleted file mode 100644 (file)
index e5e7dae..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# edit this file to enable/disable Psyco
-# psyco = 1 -- enabled
-# psyco = 0 -- disabled
-
-psyco = 0
diff --git a/www/pages/torrent/client/RateLimiter.py b/www/pages/torrent/client/RateLimiter.py
deleted file mode 100644 (file)
index 4e64966..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-# Written by Bram Cohen
-# see LICENSE.txt for license information
-
-from traceback import print_exc
-from binascii import b2a_hex
-from clock import clock
-from CurrentRateMeasure import Measure
-from cStringIO import StringIO
-from math import sqrt
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-try:
-    sum([1])
-except:
-    sum = lambda a: reduce(lambda x,y: x+y, a, 0)
-
-DEBUG = False
-
-MAX_RATE_PERIOD = 20.0
-MAX_RATE = 10e10
-PING_BOUNDARY = 1.2
-PING_SAMPLES = 7
-PING_DISCARDS = 1
-PING_THRESHHOLD = 5
-PING_DELAY = 5  # cycles 'til first upward adjustment
-PING_DELAY_NEXT = 2  # 'til next
-ADJUST_UP = 1.05
-ADJUST_DOWN = 0.95
-UP_DELAY_FIRST = 5
-UP_DELAY_NEXT = 2
-SLOTS_STARTING = 6
-SLOTS_FACTOR = 1.66/1000
-
-class RateLimiter:
-    def __init__(self, sched, unitsize, slotsfunc = lambda x: None):
-        self.sched = sched
-        self.last = None
-        self.unitsize = unitsize
-        self.slotsfunc = slotsfunc
-        self.measure = Measure(MAX_RATE_PERIOD)
-        self.autoadjust = False
-        self.upload_rate = MAX_RATE * 1000
-        self.slots = SLOTS_STARTING    # garbage if not automatic
-
-    def set_upload_rate(self, rate):
-        # rate = -1 # test automatic
-        if rate < 0:
-            if self.autoadjust:
-                return
-            self.autoadjust = True
-            self.autoadjustup = 0
-            self.pings = []
-            rate = MAX_RATE
-            self.slots = SLOTS_STARTING
-            self.slotsfunc(self.slots)
-        else:
-            self.autoadjust = False
-        if not rate:
-            rate = MAX_RATE
-        self.upload_rate = rate * 1000
-        self.lasttime = clock()
-        self.bytes_sent = 0
-
-    def queue(self, conn):
-        assert conn.next_upload is None
-        if self.last is None:
-            self.last = conn
-            conn.next_upload = conn
-            self.try_send(True)
-        else:
-            conn.next_upload = self.last.next_upload
-            self.last.next_upload = conn
-            self.last = conn
-
-    def try_send(self, check_time = False):
-        t = clock()
-        self.bytes_sent -= (t - self.lasttime) * self.upload_rate
-        self.lasttime = t
-        if check_time:
-            self.bytes_sent = max(self.bytes_sent, 0)
-        cur = self.last.next_upload
-        while self.bytes_sent <= 0:
-            bytes = cur.send_partial(self.unitsize)
-            self.bytes_sent += bytes
-            self.measure.update_rate(bytes)
-            if bytes == 0 or cur.backlogged():
-                if self.last is cur:
-                    self.last = None
-                    cur.next_upload = None
-                    break
-                else:
-                    self.last.next_upload = cur.next_upload
-                    cur.next_upload = None
-                    cur = self.last.next_upload
-            else:
-                self.last = cur
-                cur = cur.next_upload
-        else:
-            self.sched(self.try_send, self.bytes_sent / self.upload_rate)
-
-    def adjust_sent(self, bytes):
-        self.bytes_sent = min(self.bytes_sent+bytes, self.upload_rate*3)
-        self.measure.update_rate(bytes)
-
-
-    def ping(self, delay):
-        if DEBUG:
-            print delay
-        if not self.autoadjust:
-            return
-        self.pings.append(delay > PING_BOUNDARY)
-        if len(self.pings) < PING_SAMPLES+PING_DISCARDS:
-            return
-        if DEBUG:
-            print 'cycle'
-        pings = sum(self.pings[PING_DISCARDS:])
-        del self.pings[:]
-        if pings >= PING_THRESHHOLD:   # assume flooded
-            if self.upload_rate == MAX_RATE:
-                self.upload_rate = self.measure.get_rate()*ADJUST_DOWN
-            else:
-                self.upload_rate = min(self.upload_rate,
-                                       self.measure.get_rate()*1.1)
-            self.upload_rate = max(int(self.upload_rate*ADJUST_DOWN),2)
-            self.slots = int(sqrt(self.upload_rate*SLOTS_FACTOR))
-            self.slotsfunc(self.slots)
-            if DEBUG:
-                print 'adjust down to '+str(self.upload_rate)
-            self.lasttime = clock()
-            self.bytes_sent = 0
-            self.autoadjustup = UP_DELAY_FIRST
-        else:   # not flooded
-            if self.upload_rate == MAX_RATE:
-                return
-            self.autoadjustup -= 1
-            if self.autoadjustup:
-                return
-            self.upload_rate = int(self.upload_rate*ADJUST_UP)
-            self.slots = int(sqrt(self.upload_rate*SLOTS_FACTOR))
-            self.slotsfunc(self.slots)
-            if DEBUG:
-                print 'adjust up to '+str(self.upload_rate)
-            self.lasttime = clock()
-            self.bytes_sent = 0
-            self.autoadjustup = UP_DELAY_NEXT
-
-
-
-
diff --git a/www/pages/torrent/client/RateMeasure.py b/www/pages/torrent/client/RateMeasure.py
deleted file mode 100644 (file)
index 7b7310a..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-# Written by Bram Cohen
-# see LICENSE.txt for license information
-
-from clock import clock
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-FACTOR = 0.999
-
-class RateMeasure:
-    def __init__(self):
-        self.last = None
-        self.time = 1.0
-        self.got = 0.0
-        self.remaining = None
-        self.broke = False
-        self.got_anything = False
-        self.last_checked = None
-        self.rate = 0
-        self.lastten = False
-
-    def data_came_in(self, amount):
-        if not self.got_anything:
-            self.got_anything = True
-            self.last = clock()
-            return
-        self.update(amount)
-
-    def data_rejected(self, amount):
-        pass
-
-    def get_time_left(self, left):
-        t = clock()
-        if not self.got_anything:
-            return None
-        if t - self.last > 15:
-            self.update(0)
-        try:
-            remaining = left/self.rate
-            if not self.lastten and remaining <= 10:
-                self.lastten = True
-            if self.lastten:
-                return remaining
-            delta = max(remaining/20,2)
-            if self.remaining is None:
-                self.remaining = remaining
-            elif abs(self.remaining-remaining) > delta:
-                self.remaining = remaining
-            else:
-                self.remaining -= t - self.last_checked
-        except ZeroDivisionError:
-            self.remaining = None
-        if self.remaining is not None and self.remaining < 0.1:
-            self.remaining = 0.1
-        self.last_checked = t
-        return self.remaining
-
-    def update(self, amount):
-        t = clock()
-        t1 = int(t)
-        l1 = int(self.last)
-        for i in xrange(l1,t1):
-            self.time *= FACTOR
-            self.got *= FACTOR
-        self.got += amount
-        if t - self.last < 20:
-            self.time += t - self.last
-        self.last = t
-        try:
-            self.rate = self.got / self.time
-        except ZeroDivisionError:
-            pass
diff --git a/www/pages/torrent/client/RawServer.py b/www/pages/torrent/client/RawServer.py
deleted file mode 100644 (file)
index 1274934..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-# Written by Bram Cohen
-# see LICENSE.txt for license information
-
-from bisect import insort
-from SocketHandler import SocketHandler, UPnP_ERROR
-import socket
-from cStringIO import StringIO
-from traceback import print_exc
-from select import error
-from threading import Thread, Event
-from time import sleep
-from clock import clock
-import sys
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-
-def autodetect_ipv6():
-    try:
-        assert sys.version_info >= (2,3)
-        assert socket.has_ipv6
-        socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
-    except:
-        return 0
-    return 1
-
-def autodetect_socket_style():
-       if sys.platform.find('linux') < 0:
-               return 1
-       else:
-               try:
-                       f = open('/proc/sys/net/ipv6/bindv6only','r')
-                       dual_socket_style = int(f.read())
-                       f.close()
-                       return int(not dual_socket_style)
-               except:
-                       return 0
-
-
-READSIZE = 100000
-
-class RawServer:
-    def __init__(self, doneflag, timeout_check_interval, timeout, noisy = True,
-                 ipv6_enable = True, failfunc = lambda x: None, errorfunc = None,
-                 sockethandler = None, excflag = Event()):
-        self.timeout_check_interval = timeout_check_interval
-        self.timeout = timeout
-        self.servers = {}
-        self.single_sockets = {}
-        self.dead_from_write = []
-        self.doneflag = doneflag
-        self.noisy = noisy
-        self.failfunc = failfunc
-        self.errorfunc = errorfunc
-        self.exccount = 0
-        self.funcs = []
-        self.externally_added = []
-        self.finished = Event()
-        self.tasks_to_kill = []
-        self.excflag = excflag
-        
-        if sockethandler is None:
-            sockethandler = SocketHandler(timeout, ipv6_enable, READSIZE)
-        self.sockethandler = sockethandler
-        self.add_task(self.scan_for_timeouts, timeout_check_interval)
-
-    def get_exception_flag(self):
-        return self.excflag
-
-    def _add_task(self, func, delay, id = None):
-        assert float(delay) >= 0
-        insort(self.funcs, (clock() + delay, func, id))
-
-    def add_task(self, func, delay = 0, id = None):
-        assert float(delay) >= 0
-        self.externally_added.append((func, delay, id))
-
-    def scan_for_timeouts(self):
-        self.add_task(self.scan_for_timeouts, self.timeout_check_interval)
-        self.sockethandler.scan_for_timeouts()
-
-    def bind(self, port, bind = '', reuse = False,
-                        ipv6_socket_style = 1, upnp = False):
-        self.sockethandler.bind(port, bind, reuse, ipv6_socket_style, upnp)
-
-    def find_and_bind(self, minport, maxport, bind = '', reuse = False,
-                      ipv6_socket_style = 1, upnp = 0, randomizer = False):
-        return self.sockethandler.find_and_bind(minport, maxport, bind, reuse,
-                                 ipv6_socket_style, upnp, randomizer)
-
-    def start_connection_raw(self, dns, socktype, handler = None):
-        return self.sockethandler.start_connection_raw(dns, socktype, handler)
-
-    def start_connection(self, dns, handler = None, randomize = False):
-        return self.sockethandler.start_connection(dns, handler, randomize)
-
-    def get_stats(self):
-        return self.sockethandler.get_stats()
-
-    def pop_external(self):
-        while self.externally_added:
-            (a, b, c) = self.externally_added.pop(0)
-            self._add_task(a, b, c)
-
-
-    def listen_forever(self, handler):
-        self.sockethandler.set_handler(handler)
-        try:
-            while not self.doneflag.isSet():
-                try:
-                    self.pop_external()
-                    self._kill_tasks()
-                    if self.funcs:
-                        period = self.funcs[0][0] + 0.001 - clock()
-                    else:
-                        period = 2 ** 30
-                    if period < 0:
-                        period = 0
-                    events = self.sockethandler.do_poll(period)
-                    if self.doneflag.isSet():
-                        return
-                    while self.funcs and self.funcs[0][0] <= clock():
-                        garbage1, func, id = self.funcs.pop(0)
-                        if id in self.tasks_to_kill:
-                            pass
-                        try:
-#                            print func.func_name
-                            func()
-                        except (SystemError, MemoryError), e:
-                            self.failfunc(str(e))
-                            return
-                        except KeyboardInterrupt:
-#                            self.exception(True)
-                            return
-                        except:
-                            if self.noisy:
-                                self.exception()
-                    self.sockethandler.close_dead()
-                    self.sockethandler.handle_events(events)
-                    if self.doneflag.isSet():
-                        return
-                    self.sockethandler.close_dead()
-                except (SystemError, MemoryError), e:
-                    self.failfunc(str(e))
-                    return
-                except error:
-                    if self.doneflag.isSet():
-                        return
-                except KeyboardInterrupt:
-#                    self.exception(True)
-                    return
-                except:
-                    self.exception()
-                if self.exccount > 10:
-                    return
-        finally:
-#            self.sockethandler.shutdown()
-            self.finished.set()
-
-    def is_finished(self):
-        return self.finished.isSet()
-
-    def wait_until_finished(self):
-        self.finished.wait()
-
-    def _kill_tasks(self):
-        if self.tasks_to_kill:
-            new_funcs = []
-            for (t, func, id) in self.funcs:
-                if id not in self.tasks_to_kill:
-                    new_funcs.append((t, func, id))
-            self.funcs = new_funcs
-            self.tasks_to_kill = []
-
-    def kill_tasks(self, id):
-        self.tasks_to_kill.append(id)
-
-    def exception(self, kbint = False):
-        if not kbint:
-            self.excflag.set()
-        self.exccount += 1
-        if self.errorfunc is None:
-            print_exc()
-        else:
-            data = StringIO()
-            print_exc(file = data)
-#            print data.getvalue()   # report exception here too
-            if not kbint:           # don't report here if it's a keyboard interrupt
-                self.errorfunc(data.getvalue())
-
-    def shutdown(self):
-        self.sockethandler.shutdown()
diff --git a/www/pages/torrent/client/ServerPortHandler.py b/www/pages/torrent/client/ServerPortHandler.py
deleted file mode 100644 (file)
index 63df089..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-from cStringIO import StringIO
-#from RawServer import RawServer
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-from BT1.Encrypter import protocol_name
-
-default_task_id = []
-
-class SingleRawServer:
-    def __init__(self, info_hash, multihandler, doneflag, protocol):
-        self.info_hash = info_hash
-        self.doneflag = doneflag
-        self.protocol = protocol
-        self.multihandler = multihandler
-        self.rawserver = multihandler.rawserver
-        self.finished = False
-        self.running = False
-        self.handler = None
-        self.taskqueue = []
-
-    def shutdown(self):
-        if not self.finished:
-            self.multihandler.shutdown_torrent(self.info_hash)
-
-    def _shutdown(self):
-        if not self.finished:
-            self.finished = True
-            self.running = False
-            self.rawserver.kill_tasks(self.info_hash)
-            if self.handler:
-                self.handler.close_all()
-
-    def _external_connection_made(self, c, options, already_read):
-        if self.running:
-            c.set_handler(self.handler)
-            self.handler.externally_handshaked_connection_made(
-                c, options, already_read)
-
-    ### RawServer functions ###
-
-    def add_task(self, func, delay=0, id = default_task_id):
-        if id is default_task_id:
-            id = self.info_hash
-        if not self.finished:
-            self.rawserver.add_task(func, delay, id)
-
-#    def bind(self, port, bind = '', reuse = False):
-#        pass    # not handled here
-        
-    def start_connection(self, dns, handler = None):
-        if not handler:
-            handler = self.handler
-        c = self.rawserver.start_connection(dns, handler)
-        return c
-
-#    def listen_forever(self, handler):
-#        pass    # don't call with this
-    
-    def start_listening(self, handler):
-        self.handler = handler
-        self.running = True
-        return self.shutdown    # obviously, doesn't listen forever
-
-    def is_finished(self):
-        return self.finished
-
-    def get_exception_flag(self):
-        return self.rawserver.get_exception_flag()
-
-
-class NewSocketHandler:     # hand a new socket off where it belongs
-    def __init__(self, multihandler, connection):
-        self.multihandler = multihandler
-        self.connection = connection
-        connection.set_handler(self)
-        self.closed = False
-        self.buffer = StringIO()
-        self.complete = False
-        self.next_len, self.next_func = 1, self.read_header_len
-        self.multihandler.rawserver.add_task(self._auto_close, 15)
-
-    def _auto_close(self):
-        if not self.complete:
-            self.close()
-        
-    def close(self):
-        if not self.closed:
-            self.connection.close()
-            self.closed = True
-
-        
-#   header format:
-#        connection.write(chr(len(protocol_name)) + protocol_name + 
-#            (chr(0) * 8) + self.encrypter.download_id + self.encrypter.my_id)
-
-    # copied from Encrypter and modified
-    
-    def read_header_len(self, s):
-        l = ord(s)
-        return l, self.read_header
-
-    def read_header(self, s):
-        self.protocol = s
-        return 8, self.read_reserved
-
-    def read_reserved(self, s):
-        self.options = s
-        return 20, self.read_download_id
-
-    def read_download_id(self, s):
-        if self.multihandler.singlerawservers.has_key(s):
-            if self.multihandler.singlerawservers[s].protocol == self.protocol:
-                return True
-        return None
-
-    def read_dead(self, s):
-        return None
-
-    def data_came_in(self, garbage, s):
-        while True:
-            if self.closed:
-                return
-            i = self.next_len - self.buffer.tell()
-            if i > len(s):
-                self.buffer.write(s)
-                return
-            self.buffer.write(s[:i])
-            s = s[i:]
-            m = self.buffer.getvalue()
-            self.buffer.reset()
-            self.buffer.truncate()
-            try:
-                x = self.next_func(m)
-            except:
-                self.next_len, self.next_func = 1, self.read_dead
-                raise
-            if x is None:
-                self.close()
-                return
-            if x == True:       # ready to process
-                self.multihandler.singlerawservers[m]._external_connection_made(
-                        self.connection, self.options, s)
-                self.complete = True
-                return
-            self.next_len, self.next_func = x
-
-    def connection_flushed(self, ss):
-        pass
-
-    def connection_lost(self, ss):
-        self.closed = True
-
-class MultiHandler:
-    def __init__(self, rawserver, doneflag):
-        self.rawserver = rawserver
-        self.masterdoneflag = doneflag
-        self.singlerawservers = {}
-        self.connections = {}
-        self.taskqueues = {}
-
-    def newRawServer(self, info_hash, doneflag, protocol=protocol_name):
-        new = SingleRawServer(info_hash, self, doneflag, protocol)
-        self.singlerawservers[info_hash] = new
-        return new
-
-    def shutdown_torrent(self, info_hash):
-        self.singlerawservers[info_hash]._shutdown()
-        del self.singlerawservers[info_hash]
-
-    def listen_forever(self):
-        self.rawserver.listen_forever(self)
-        for srs in self.singlerawservers.values():
-            srs.finished = True
-            srs.running = False
-            srs.doneflag.set()
-        
-    ### RawServer handler functions ###
-    # be wary of name collisions
-
-    def external_connection_made(self, ss):
-        NewSocketHandler(self, ss)
diff --git a/www/pages/torrent/client/SocketHandler.py b/www/pages/torrent/client/SocketHandler.py
deleted file mode 100644 (file)
index 7676830..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-# Written by Bram Cohen
-# see LICENSE.txt for license information
-
-import socket
-from errno import EWOULDBLOCK, ECONNREFUSED, EHOSTUNREACH
-try:
-    from select import poll, error, POLLIN, POLLOUT, POLLERR, POLLHUP
-    timemult = 1000
-except ImportError:
-    from selectpoll import poll, error, POLLIN, POLLOUT, POLLERR, POLLHUP
-    timemult = 1
-from time import sleep
-from clock import clock
-import sys
-from random import shuffle, randrange
-from natpunch import UPnP_open_port, UPnP_close_port
-# from BT1.StreamCheck import StreamCheck
-# import inspect
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-all = POLLIN | POLLOUT
-
-UPnP_ERROR = "unable to forward port via UPnP"
-
-class SingleSocket:
-    def __init__(self, socket_handler, sock, handler, ip = None):
-        self.socket_handler = socket_handler
-        self.socket = sock
-        self.handler = handler
-        self.buffer = []
-        self.last_hit = clock()
-        self.fileno = sock.fileno()
-        self.connected = False
-        self.skipped = 0
-#        self.check = StreamCheck()
-        try:
-            self.ip = self.socket.getpeername()[0]
-        except:
-            if ip is None:
-                self.ip = 'unknown'
-            else:
-                self.ip = ip
-        
-    def get_ip(self, real=False):
-        if real:
-            try:
-                self.ip = self.socket.getpeername()[0]
-            except:
-                pass
-        return self.ip
-        
-    def close(self):
-        '''
-        for x in xrange(5,0,-1):
-            try:
-                f = inspect.currentframe(x).f_code
-                print (f.co_filename,f.co_firstlineno,f.co_name)
-                del f
-            except:
-                pass
-        print ''
-        '''
-        assert self.socket
-        self.connected = False
-        sock = self.socket
-        self.socket = None
-        self.buffer = []
-        del self.socket_handler.single_sockets[self.fileno]
-        self.socket_handler.poll.unregister(sock)
-        sock.close()
-
-    def shutdown(self, val):
-        self.socket.shutdown(val)
-
-    def is_flushed(self):
-        return not self.buffer
-
-    def write(self, s):
-#        self.check.write(s)
-        assert self.socket is not None
-        self.buffer.append(s)
-        if len(self.buffer) == 1:
-            self.try_write()
-
-    def try_write(self):
-        if self.connected:
-            dead = False
-            try:
-                while self.buffer:
-                    buf = self.buffer[0]
-                    amount = self.socket.send(buf)
-                    if amount == 0:
-                        self.skipped += 1
-                        break
-                    self.skipped = 0
-                    if amount != len(buf):
-                        self.buffer[0] = buf[amount:]
-                        break
-                    del self.buffer[0]
-            except socket.error, e:
-                try:
-                    dead = e[0] != EWOULDBLOCK
-                except:
-                    dead = True
-                self.skipped += 1
-            if self.skipped >= 3:
-                dead = True
-            if dead:
-                self.socket_handler.dead_from_write.append(self)
-                return
-        if self.buffer:
-            self.socket_handler.poll.register(self.socket, all)
-        else:
-            self.socket_handler.poll.register(self.socket, POLLIN)
-
-    def set_handler(self, handler):
-        self.handler = handler
-
-class SocketHandler:
-    def __init__(self, timeout, ipv6_enable, readsize = 100000):
-        self.timeout = timeout
-        self.ipv6_enable = ipv6_enable
-        self.readsize = readsize
-        self.poll = poll()
-        # {socket: SingleSocket}
-        self.single_sockets = {}
-        self.dead_from_write = []
-        self.max_connects = 1000
-        self.port_forwarded = None
-        self.servers = {}
-
-    def scan_for_timeouts(self):
-        t = clock() - self.timeout
-        tokill = []
-        for s in self.single_sockets.values():
-            if s.last_hit < t:
-                tokill.append(s)
-        for k in tokill:
-            if k.socket is not None:
-                self._close_socket(k)
-
-    def bind(self, port, bind = '', reuse = False, ipv6_socket_style = 1, upnp = 0):
-        port = int(port)
-        addrinfos = []
-        self.servers = {}
-        self.interfaces = []
-        # if bind != "" thread it as a comma seperated list and bind to all
-        # addresses (can be ips or hostnames) else bind to default ipv6 and
-        # ipv4 address
-        if bind:
-            if self.ipv6_enable:
-                socktype = socket.AF_UNSPEC
-            else:
-                socktype = socket.AF_INET
-            bind = bind.split(',')
-            for addr in bind:
-                if sys.version_info < (2,2):
-                    addrinfos.append((socket.AF_INET, None, None, None, (addr, port)))
-                else:
-                    addrinfos.extend(socket.getaddrinfo(addr, port,
-                                               socktype, socket.SOCK_STREAM))
-        else:
-            if self.ipv6_enable:
-                addrinfos.append([socket.AF_INET6, None, None, None, ('', port)])
-            if not addrinfos or ipv6_socket_style != 0:
-                addrinfos.append([socket.AF_INET, None, None, None, ('', port)])
-        for addrinfo in addrinfos:
-            try:
-                server = socket.socket(addrinfo[0], socket.SOCK_STREAM)
-                if reuse:
-                    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-                server.setblocking(0)
-                server.bind(addrinfo[4])
-                self.servers[server.fileno()] = server
-                if bind:
-                    self.interfaces.append(server.getsockname()[0])
-                server.listen(64)
-                self.poll.register(server, POLLIN)
-            except socket.error, e:
-                for server in self.servers.values():
-                    try:
-                        server.close()
-                    except:
-                        pass
-                if self.ipv6_enable and ipv6_socket_style == 0 and self.servers:
-                    raise socket.error('blocked port (may require ipv6_binds_v4 to be set)')
-                raise socket.error(str(e))
-        if not self.servers:
-            raise socket.error('unable to open server port')
-        if upnp:
-            if not UPnP_open_port(port):
-                for server in self.servers.values():
-                    try:
-                        server.close()
-                    except:
-                        pass
-                    self.servers = None
-                    self.interfaces = None
-                raise socket.error(UPnP_ERROR)
-            self.port_forwarded = port
-        self.port = port
-
-    def find_and_bind(self, minport, maxport, bind = '', reuse = False,
-                      ipv6_socket_style = 1, upnp = 0, randomizer = False):
-        e = 'maxport less than minport - no ports to check'
-        if maxport-minport < 50 or not randomizer:
-            portrange = range(minport, maxport+1)
-            if randomizer:
-                shuffle(portrange)
-                portrange = portrange[:20]  # check a maximum of 20 ports
-        else:
-            portrange = []
-            while len(portrange) < 20:
-                listen_port = randrange(minport, maxport+1)
-                if not listen_port in portrange:
-                    portrange.append(listen_port)
-        for listen_port in portrange:
-            try:
-                self.bind(listen_port, bind,
-                               ipv6_socket_style = ipv6_socket_style, upnp = upnp)
-                return listen_port
-            except socket.error, e:
-                pass
-        raise socket.error(str(e))
-
-
-    def set_handler(self, handler):
-        self.handler = handler
-
-
-    def start_connection_raw(self, dns, socktype = socket.AF_INET, handler = None):
-        if handler is None:
-            handler = self.handler
-        sock = socket.socket(socktype, socket.SOCK_STREAM)
-        sock.setblocking(0)
-        try:
-            sock.connect_ex(dns)
-        except socket.error:
-            raise
-        except Exception, e:
-            raise socket.error(str(e))
-        self.poll.register(sock, POLLIN)
-        s = SingleSocket(self, sock, handler, dns[0])
-        self.single_sockets[sock.fileno()] = s
-        return s
-
-
-    def start_connection(self, dns, handler = None, randomize = False):
-        if handler is None:
-            handler = self.handler
-        if sys.version_info < (2,2):
-            s = self.start_connection_raw(dns,socket.AF_INET,handler)
-        else:
-            if self.ipv6_enable:
-                socktype = socket.AF_UNSPEC
-            else:
-                socktype = socket.AF_INET
-            try:
-                addrinfos = socket.getaddrinfo(dns[0], int(dns[1]),
-                                               socktype, socket.SOCK_STREAM)
-            except socket.error, e:
-                raise
-            except Exception, e:
-                raise socket.error(str(e))
-            if randomize:
-                shuffle(addrinfos)
-            for addrinfo in addrinfos:
-                try:
-                    s = self.start_connection_raw(addrinfo[4],addrinfo[0],handler)
-                    break
-                except:
-                    pass
-            else:
-                raise socket.error('unable to connect')
-        return s
-
-
-    def _sleep(self):
-        sleep(1)
-        
-    def handle_events(self, events):
-        for sock, event in events:
-            s = self.servers.get(sock)
-            if s:
-                if event & (POLLHUP | POLLERR) != 0:
-                    self.poll.unregister(s)
-                    s.close()
-                    del self.servers[sock]
-                    print "lost server socket"
-                elif len(self.single_sockets) < self.max_connects:
-                    try:
-                        newsock, addr = s.accept()
-                        newsock.setblocking(0)
-                        nss = SingleSocket(self, newsock, self.handler)
-                        self.single_sockets[newsock.fileno()] = nss
-                        self.poll.register(newsock, POLLIN)
-                        self.handler.external_connection_made(nss)
-                    except socket.error:
-                        self._sleep()
-            else:
-                s = self.single_sockets.get(sock)
-                if not s:
-                    continue
-                s.connected = True
-                if (event & (POLLHUP | POLLERR)):
-                    self._close_socket(s)
-                    continue
-                if (event & POLLIN):
-                    try:
-                        s.last_hit = clock()
-                        data = s.socket.recv(100000)
-                        if not data:
-                            self._close_socket(s)
-                        else:
-                            s.handler.data_came_in(s, data)
-                    except socket.error, e:
-                        code, msg = e
-                        if code != EWOULDBLOCK:
-                            self._close_socket(s)
-                            continue
-                if (event & POLLOUT) and s.socket and not s.is_flushed():
-                    s.try_write()
-                    if s.is_flushed():
-                        s.handler.connection_flushed(s)
-
-    def close_dead(self):
-        while self.dead_from_write:
-            old = self.dead_from_write
-            self.dead_from_write = []
-            for s in old:
-                if s.socket:
-                    self._close_socket(s)
-
-    def _close_socket(self, s):
-        s.close()
-        s.handler.connection_lost(s)
-
-    def do_poll(self, t):
-        r = self.poll.poll(t*timemult)
-        if r is None:
-            connects = len(self.single_sockets)
-            to_close = int(connects*0.05)+1 # close 5% of sockets
-            self.max_connects = connects-to_close
-            closelist = self.single_sockets.values()
-            shuffle(closelist)
-            closelist = closelist[:to_close]
-            for sock in closelist:
-                self._close_socket(sock)
-            return []
-        return r     
-
-    def get_stats(self):
-        return { 'interfaces': self.interfaces,
-                 'port': self.port,
-                 'upnp': self.port_forwarded is not None }
-
-
-    def shutdown(self):
-        for ss in self.single_sockets.values():
-            try:
-                ss.close()
-            except:
-                pass
-        for server in self.servers.values():
-            try:
-                server.close()
-            except:
-                pass
-        if self.port_forwarded is not None:
-            UPnP_close_port(self.port_forwarded)
-
diff --git a/www/pages/torrent/client/__init__.py b/www/pages/torrent/client/__init__.py
deleted file mode 100644 (file)
index 20a831b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-product_name = 'BitTornado'
-version_short = 'T-0.3.17'
-
-version = version_short+' ('+product_name+')'
-report_email = version_short+'@degreez.net'
-
-from types import StringType
-from sha import sha
-from time import time, clock
-try:
-    from os import getpid
-except ImportError:
-    def getpid():
-        return 1
-
-mapbase64 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-'
-
-_idprefix = version_short[0]
-for subver in version_short[2:].split('.'):
-    try:
-        subver = int(subver)
-    except:
-        subver = 0
-    _idprefix += mapbase64[subver]
-_idprefix += ('-' * (6-len(_idprefix)))
-_idrandom = [None]
-
-def resetPeerIDs():
-    try:
-        f = open('/dev/urandom','rb')
-        x = f.read(20)
-        f.close()
-    except:
-        x = ''
-
-    l1 = 0
-    t = clock()
-    while t == clock():
-        l1 += 1
-    l2 = 0
-    t = long(time()*100)
-    while t == long(time()*100):
-        l2 += 1
-    l3 = 0
-    if l2 < 1000:
-        t = long(time()*10)
-        while t == long(clock()*10):
-            l3 += 1
-    x += ( repr(time()) + '/' + str(time()) + '/'
-           + str(l1) + '/' + str(l2) + '/' + str(l3) + '/'
-           + str(getpid()) )
-
-    s = ''
-    for i in sha(x).digest()[-11:]:
-        s += mapbase64[ord(i) & 0x3F]
-    _idrandom[0] = s
-        
-resetPeerIDs()
-
-def createPeerID(ins = '---'):
-    assert type(ins) is StringType
-    assert len(ins) == 3
-    return _idprefix + ins + _idrandom[0]
diff --git a/www/pages/torrent/client/bencode.py b/www/pages/torrent/client/bencode.py
deleted file mode 100644 (file)
index 1ff0736..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-# Written by Petru Paler, Uoti Urpala, Ross Cohen and John Hoffman
-# see LICENSE.txt for license information
-
-from types import IntType, LongType, StringType, ListType, TupleType, DictType
-try:
-    from types import BooleanType
-except ImportError:
-    BooleanType = None
-try:
-    from types import UnicodeType
-except ImportError:
-    UnicodeType = None
-from cStringIO import StringIO
-
-def decode_int(x, f):
-    f += 1
-    newf = x.index('e', f)
-    try:
-        n = int(x[f:newf])
-    except:
-        n = long(x[f:newf])
-    if x[f] == '-':
-        if x[f + 1] == '0':
-            raise ValueError
-    elif x[f] == '0' and newf != f+1:
-        raise ValueError
-    return (n, newf+1)
-  
-def decode_string(x, f):
-    colon = x.index(':', f)
-    try:
-        n = int(x[f:colon])
-    except (OverflowError, ValueError):
-        n = long(x[f:colon])
-    if x[f] == '0' and colon != f+1:
-        raise ValueError
-    colon += 1
-    return (x[colon:colon+n], colon+n)
-
-def decode_unicode(x, f):
-    s, f = decode_string(x, f+1)
-    return (s.decode('UTF-8'),f)
-
-def decode_list(x, f):
-    r, f = [], f+1
-    while x[f] != 'e':
-        v, f = decode_func[x[f]](x, f)
-        r.append(v)
-    return (r, f + 1)
-
-def decode_dict(x, f):
-    r, f = {}, f+1
-    lastkey = None
-    while x[f] != 'e':
-        k, f = decode_string(x, f)
-        if lastkey >= k:
-            raise ValueError
-        lastkey = k
-        r[k], f = decode_func[x[f]](x, f)
-    return (r, f + 1)
-
-decode_func = {}
-decode_func['l'] = decode_list
-decode_func['d'] = decode_dict
-decode_func['i'] = decode_int
-decode_func['0'] = decode_string
-decode_func['1'] = decode_string
-decode_func['2'] = decode_string
-decode_func['3'] = decode_string
-decode_func['4'] = decode_string
-decode_func['5'] = decode_string
-decode_func['6'] = decode_string
-decode_func['7'] = decode_string
-decode_func['8'] = decode_string
-decode_func['9'] = decode_string
-#decode_func['u'] = decode_unicode
-  
-def bdecode(x, sloppy = 0):
-    try:
-        r, l = decode_func[x[0]](x, 0)
-#    except (IndexError, KeyError):
-    except (IndexError, KeyError, ValueError):
-        raise ValueError, "bad bencoded data"
-    if not sloppy and l != len(x):
-        raise ValueError, "bad bencoded data"
-    return r
-
-def test_bdecode():
-    try:
-        bdecode('0:0:')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('ie')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('i341foo382e')
-        assert 0
-    except ValueError:
-        pass
-    assert bdecode('i4e') == 4L
-    assert bdecode('i0e') == 0L
-    assert bdecode('i123456789e') == 123456789L
-    assert bdecode('i-10e') == -10L
-    try:
-        bdecode('i-0e')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('i123')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('i6easd')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('35208734823ljdahflajhdf')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('2:abfdjslhfld')
-        assert 0
-    except ValueError:
-        pass
-    assert bdecode('0:') == ''
-    assert bdecode('3:abc') == 'abc'
-    assert bdecode('10:1234567890') == '1234567890'
-    try:
-        bdecode('02:xy')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('l')
-        assert 0
-    except ValueError:
-        pass
-    assert bdecode('le') == []
-    try:
-        bdecode('leanfdldjfh')
-        assert 0
-    except ValueError:
-        pass
-    assert bdecode('l0:0:0:e') == ['', '', '']
-    try:
-        bdecode('relwjhrlewjh')
-        assert 0
-    except ValueError:
-        pass
-    assert bdecode('li1ei2ei3ee') == [1, 2, 3]
-    assert bdecode('l3:asd2:xye') == ['asd', 'xy']
-    assert bdecode('ll5:Alice3:Bobeli2ei3eee') == [['Alice', 'Bob'], [2, 3]]
-    try:
-        bdecode('d')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('defoobar')
-        assert 0
-    except ValueError:
-        pass
-    assert bdecode('de') == {}
-    assert bdecode('d3:agei25e4:eyes4:bluee') == {'age': 25, 'eyes': 'blue'}
-    assert bdecode('d8:spam.mp3d6:author5:Alice6:lengthi100000eee') == {'spam.mp3': {'author': 'Alice', 'length': 100000}}
-    try:
-        bdecode('d3:fooe')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('di1e0:e')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('d1:b0:1:a0:e')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('d1:a0:1:a0:e')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('i03e')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('l01:ae')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('9999:x')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('l0:')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('d0:0:')
-        assert 0
-    except ValueError:
-        pass
-    try:
-        bdecode('d0:')
-        assert 0
-    except ValueError:
-        pass
-
-bencached_marker = []
-
-class Bencached:
-    def __init__(self, s):
-        self.marker = bencached_marker
-        self.bencoded = s
-
-BencachedType = type(Bencached('')) # insufficient, but good as a filter
-
-def encode_bencached(x,r):
-    assert x.marker == bencached_marker
-    r.append(x.bencoded)
-
-def encode_int(x,r):
-    r.extend(('i',str(x),'e'))
-
-def encode_bool(x,r):
-    encode_int(int(x),r)
-
-def encode_string(x,r):    
-    r.extend((str(len(x)),':',x))
-
-def encode_unicode(x,r):
-    #r.append('u')
-    encode_string(x.encode('UTF-8'),r)
-
-def encode_list(x,r):
-        r.append('l')
-        for e in x:
-            encode_func[type(e)](e, r)
-        r.append('e')
-
-def encode_dict(x,r):
-    r.append('d')
-    ilist = x.items()
-    ilist.sort()
-    for k,v in ilist:
-        r.extend((str(len(k)),':',k))
-        encode_func[type(v)](v, r)
-    r.append('e')
-
-encode_func = {}
-encode_func[BencachedType] = encode_bencached
-encode_func[IntType] = encode_int
-encode_func[LongType] = encode_int
-encode_func[StringType] = encode_string
-encode_func[ListType] = encode_list
-encode_func[TupleType] = encode_list
-encode_func[DictType] = encode_dict
-if BooleanType:
-    encode_func[BooleanType] = encode_bool
-if UnicodeType:
-    encode_func[UnicodeType] = encode_unicode
-    
-def bencode(x):
-    r = []
-    try:
-        encode_func[type(x)](x, r)
-    except:
-        print "*** error *** could not encode type %s (value: %s)" % (type(x), x)
-        assert 0
-    return ''.join(r)
-
-def test_bencode():
-    assert bencode(4) == 'i4e'
-    assert bencode(0) == 'i0e'
-    assert bencode(-10) == 'i-10e'
-    assert bencode(12345678901234567890L) == 'i12345678901234567890e'
-    assert bencode('') == '0:'
-    assert bencode('abc') == '3:abc'
-    assert bencode('1234567890') == '10:1234567890'
-    assert bencode([]) == 'le'
-    assert bencode([1, 2, 3]) == 'li1ei2ei3ee'
-    assert bencode([['Alice', 'Bob'], [2, 3]]) == 'll5:Alice3:Bobeli2ei3eee'
-    assert bencode({}) == 'de'
-    assert bencode({'age': 25, 'eyes': 'blue'}) == 'd3:agei25e4:eyes4:bluee'
-    assert bencode({'spam.mp3': {'author': 'Alice', 'length': 100000}}) == 'd8:spam.mp3d6:author5:Alice6:lengthi100000eee'
-    try:
-        bencode({1: 'foo'})
-        assert 0
-    except AssertionError:
-        pass
-
-  
-try:
-    import psyco
-    psyco.bind(bdecode)
-    psyco.bind(bencode)
-except ImportError:
-    pass
diff --git a/www/pages/torrent/client/bitfield.py b/www/pages/torrent/client/bitfield.py
deleted file mode 100644 (file)
index 3d532e3..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-# Written by Bram Cohen, Uoti Urpala, and John Hoffman
-# see LICENSE.txt for license information
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-    bool = lambda x: not not x
-
-try:
-    sum([1])
-    negsum = lambda a: len(a)-sum(a)
-except:
-    negsum = lambda a: reduce(lambda x,y: x+(not y), a, 0)
-    
-def _int_to_booleans(x):
-    r = []
-    for i in range(8):
-        r.append(bool(x & 0x80))
-        x <<= 1
-    return tuple(r)
-
-lookup_table = []
-reverse_lookup_table = {}
-for i in xrange(256):
-    x = _int_to_booleans(i)
-    lookup_table.append(x)
-    reverse_lookup_table[x] = chr(i)
-
-
-class Bitfield:
-    def __init__(self, length = None, bitstring = None, copyfrom = None):
-        if copyfrom is not None:
-            self.length = copyfrom.length
-            self.array = copyfrom.array[:]
-            self.numfalse = copyfrom.numfalse
-            return
-        if length is None:
-            raise ValueError, "length must be provided unless copying from another array"
-        self.length = length
-        if bitstring is not None:
-            extra = len(bitstring) * 8 - length
-            if extra < 0 or extra >= 8:
-                raise ValueError
-            t = lookup_table
-            r = []
-            for c in bitstring:
-                r.extend(t[ord(c)])
-            if extra > 0:
-                if r[-extra:] != [0] * extra:
-                    raise ValueError
-                del r[-extra:]
-            self.array = r
-            self.numfalse = negsum(r)
-        else:
-            self.array = [False] * length
-            self.numfalse = length
-
-    def __setitem__(self, index, val):
-        val = bool(val)
-        self.numfalse += self.array[index]-val
-        self.array[index] = val
-
-    def __getitem__(self, index):
-        return self.array[index]
-
-    def __len__(self):
-        return self.length
-
-    def tostring(self):
-        booleans = self.array
-        t = reverse_lookup_table
-        s = len(booleans) % 8
-        r = [ t[tuple(booleans[x:x+8])] for x in xrange(0, len(booleans)-s, 8) ]
-        if s:
-            r += t[tuple(booleans[-s:] + ([0] * (8-s)))]
-        return ''.join(r)
-
-    def complete(self):
-        return not self.numfalse
-
-
-def test_bitfield():
-    try:
-        x = Bitfield(7, 'ab')
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(7, 'ab')
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(9, 'abc')
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(0, 'a')
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(1, '')
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(7, '')
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(8, '')
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(9, 'a')
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(7, chr(1))
-        assert False
-    except ValueError:
-        pass
-    try:
-        x = Bitfield(9, chr(0) + chr(0x40))
-        assert False
-    except ValueError:
-        pass
-    assert Bitfield(0, '').tostring() == ''
-    assert Bitfield(1, chr(0x80)).tostring() == chr(0x80)
-    assert Bitfield(7, chr(0x02)).tostring() == chr(0x02)
-    assert Bitfield(8, chr(0xFF)).tostring() == chr(0xFF)
-    assert Bitfield(9, chr(0) + chr(0x80)).tostring() == chr(0) + chr(0x80)
-    x = Bitfield(1)
-    assert x.numfalse == 1
-    x[0] = 1
-    assert x.numfalse == 0
-    x[0] = 1
-    assert x.numfalse == 0
-    assert x.tostring() == chr(0x80)
-    x = Bitfield(7)
-    assert len(x) == 7
-    x[6] = 1
-    assert x.numfalse == 6
-    assert x.tostring() == chr(0x02)
-    x = Bitfield(8)
-    x[7] = 1
-    assert x.tostring() == chr(1)
-    x = Bitfield(9)
-    x[8] = 1
-    assert x.numfalse == 8
-    assert x.tostring() == chr(0) + chr(0x80)
-    x = Bitfield(8, chr(0xC4))
-    assert len(x) == 8
-    assert x.numfalse == 5
-    assert x.tostring() == chr(0xC4)
diff --git a/www/pages/torrent/client/clock.py b/www/pages/torrent/client/clock.py
deleted file mode 100644 (file)
index e42c59b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-from time import *
-import sys
-
-_MAXFORWARD = 100
-_FUDGE = 1
-
-class RelativeTime:
-    def __init__(self):
-        self.time = time()
-        self.offset = 0
-
-    def get_time(self):        
-        t = time() + self.offset
-        if t < self.time or t > self.time + _MAXFORWARD:
-            self.time += _FUDGE
-            self.offset += self.time - t
-            return self.time
-        self.time = t
-        return t
-
-if sys.platform != 'win32':
-    _RTIME = RelativeTime()
-    def clock():
-        return _RTIME.get_time()
\ No newline at end of file
diff --git a/www/pages/torrent/client/download_bt1.py b/www/pages/torrent/client/download_bt1.py
deleted file mode 100644 (file)
index f4aef0c..0000000
+++ /dev/null
@@ -1,882 +0,0 @@
-# Written by Bram Cohen
-# see LICENSE.txt for license information
-
-from zurllib import urlopen
-from urlparse import urlparse
-from BT1.btformats import check_message
-from BT1.Choker import Choker
-from BT1.Storage import Storage
-from BT1.StorageWrapper import StorageWrapper
-from BT1.FileSelector import FileSelector
-from BT1.Uploader import Upload
-from BT1.Downloader import Downloader
-from BT1.HTTPDownloader import HTTPDownloader
-from BT1.Connecter import Connecter
-from RateLimiter import RateLimiter
-from BT1.Encrypter import Encoder
-from RawServer import RawServer, autodetect_ipv6, autodetect_socket_style
-from BT1.Rerequester import Rerequester
-from BT1.DownloaderFeedback import DownloaderFeedback
-from RateMeasure import RateMeasure
-from CurrentRateMeasure import Measure
-from BT1.PiecePicker import PiecePicker
-from BT1.Statistics import Statistics
-from ConfigDir import ConfigDir
-from bencode import bencode, bdecode
-from natpunch import UPnP_test
-from sha import sha
-from os import path, makedirs, listdir
-from parseargs import parseargs, formatDefinitions, defaultargs
-from socket import error as socketerror
-from random import seed
-from threading import Thread, Event
-from clock import clock
-from __init__ import createPeerID
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-defaults = [
-    ('max_uploads', 7,
-        "the maximum number of uploads to allow at once."),
-    ('keepalive_interval', 120.0,
-        'number of seconds to pause between sending keepalives'),
-    ('download_slice_size', 2 ** 14,
-        "How many bytes to query for per request."),
-    ('upload_unit_size', 1460,
-        "when limiting upload rate, how many bytes to send at a time"),
-    ('request_backlog', 10,
-        "maximum number of requests to keep in a single pipe at once."),
-    ('max_message_length', 2 ** 23,
-        "maximum length prefix encoding you'll accept over the wire - larger values get the connection dropped."),
-    ('ip', '',
-        "ip to report you have to the tracker."),
-    ('minport', 10000, 'minimum port to listen on, counts up if unavailable'),
-    ('maxport', 60000, 'maximum port to listen on'),
-    ('random_port', 1, 'whether to choose randomly inside the port range ' +
-        'instead of counting up linearly'),
-    ('responsefile', '',
-        'file the server response was stored in, alternative to url'),
-    ('url', '',
-        'url to get file from, alternative to responsefile'),
-    ('selector_enabled', 1,
-        'whether to enable the file selector and fast resume function'),
-    ('expire_cache_data', 10,
-        'the number of days after which you wish to expire old cache data ' +
-        '(0 = disabled)'),
-    ('priority', '',
-        'a list of file priorities separated by commas, must be one per file, ' +
-        '0 = highest, 1 = normal, 2 = lowest, -1 = download disabled'),
-    ('saveas', '',
-        'local file name to save the file as, null indicates query user'),
-    ('timeout', 300.0,
-        'time to wait between closing sockets which nothing has been received on'),
-    ('timeout_check_interval', 60.0,
-        'time to wait between checking if any connections have timed out'),
-    ('max_slice_length', 2 ** 17,
-        "maximum length slice to send to peers, larger requests are ignored"),
-    ('max_rate_period', 20.0,
-        "maximum amount of time to guess the current rate estimate represents"),
-    ('bind', '', 
-        'comma-separated list of ips/hostnames to bind to locally'),
-#    ('ipv6_enabled', autodetect_ipv6(),
-    ('ipv6_enabled', 0,
-         'allow the client to connect to peers via IPv6'),
-    ('ipv6_binds_v4', autodetect_socket_style(),
-        "set if an IPv6 server socket won't also field IPv4 connections"),
-    ('upnp_nat_access', 1,
-        'attempt to autoconfigure a UPnP router to forward a server port ' +
-        '(0 = disabled, 1 = mode 1 [fast], 2 = mode 2 [slow])'),
-    ('upload_rate_fudge', 5.0, 
-        'time equivalent of writing to kernel-level TCP buffer, for rate adjustment'),
-    ('tcp_ack_fudge', 0.03,
-        'how much TCP ACK download overhead to add to upload rate calculations ' +
-        '(0 = disabled)'),
-    ('display_interval', .5,
-        'time between updates of displayed information'),
-    ('rerequest_interval', 5 * 60,
-        'time to wait between requesting more peers'),
-    ('min_peers', 20, 
-        'minimum number of peers to not do rerequesting'),
-    ('http_timeout', 60, 
-        'number of seconds to wait before assuming that an http connection has timed out'),
-    ('max_initiate', 40,
-        'number of peers at which to stop initiating new connections'),
-    ('check_hashes', 1,
-        'whether to check hashes on disk'),
-    ('max_upload_rate', 0,
-        'maximum kB/s to upload at (0 = no limit, -1 = automatic)'),
-    ('max_download_rate', 0,
-        'maximum kB/s to download at (0 = no limit)'),
-    ('alloc_type', 'normal',
-        'allocation type (may be normal, background, pre-allocate or sparse)'),
-    ('alloc_rate', 2.0,
-        'rate (in MiB/s) to allocate space at using background allocation'),
-    ('buffer_reads', 1,
-        'whether to buffer disk reads'),
-    ('write_buffer_size', 4,
-        'the maximum amount of space to use for buffering disk writes ' +
-        '(in megabytes, 0 = disabled)'),
-    ('breakup_seed_bitfield', 1,
-        'sends an incomplete bitfield and then fills with have messages, '
-        'in order to get around stupid ISP manipulation'),
-    ('snub_time', 30.0,
-        "seconds to wait for data to come in over a connection before assuming it's semi-permanently choked"),
-    ('spew', 0,
-        "whether to display diagnostic info to stdout"),
-    ('rarest_first_cutoff', 2,
-        "number of downloads at which to switch from random to rarest first"),
-    ('rarest_first_priority_cutoff', 5,
-        'the number of peers which need to have a piece before other partials take priority over rarest first'),
-    ('min_uploads', 4,
-        "the number of uploads to fill out to with extra optimistic unchokes"),
-    ('max_files_open', 50,
-        'the maximum number of files to keep open at a time, 0 means no limit'),
-    ('round_robin_period', 30,
-        "the number of seconds between the client's switching upload targets"),
-    ('super_seeder', 0,
-        "whether to use special upload-efficiency-maximizing routines (only for dedicated seeds)"),
-    ('security', 1,
-        "whether to enable extra security features intended to prevent abuse"),
-    ('max_connections', 0,
-        "the absolute maximum number of peers to connect with (0 = no limit)"),
-    ('auto_kick', 1,
-        "whether to allow the client to automatically kick/ban peers that send bad data"),
-    ('double_check', 1,
-        "whether to double-check data being written to the disk for errors (may increase CPU load)"),
-    ('triple_check', 0,
-        "whether to thoroughly check data being written to the disk (may slow disk access)"),
-    ('lock_files', 1,
-        "whether to lock files the client is working with"),
-    ('lock_while_reading', 0,
-        "whether to lock access to files being read"),
-    ('auto_flush', 0,
-        "minutes between automatic flushes to disk (0 = disabled)"),
-    ('dedicated_seed_id', '',
-        "code to send to tracker identifying as a dedicated seed"),
-    ]
-
-argslistheader = 'Arguments are:\n\n'
-
-
-def _failfunc(x):
-    print x
-
-# old-style downloader
-def download(params, filefunc, statusfunc, finfunc, errorfunc, doneflag, cols,
-             pathFunc = None, presets = {}, exchandler = None,
-             failed = _failfunc, paramfunc = None):
-
-    try:
-        config = parse_params(params, presets)
-    except ValueError, e:
-        failed('error: ' + str(e) + '\nrun with no args for parameter explanations')
-        return
-    if not config:
-        errorfunc(get_usage())
-        return
-    
-    myid = createPeerID()
-    seed(myid)
-
-    rawserver = RawServer(doneflag, config['timeout_check_interval'],
-                          config['timeout'], ipv6_enable = config['ipv6_enabled'],
-                          failfunc = failed, errorfunc = exchandler)
-
-    upnp_type = UPnP_test(config['upnp_nat_access'])
-    try:
-        listen_port = rawserver.find_and_bind(config['minport'], config['maxport'],
-                        config['bind'], ipv6_socket_style = config['ipv6_binds_v4'],
-                        upnp = upnp_type, randomizer = config['random_port'])
-    except socketerror, e:
-        failed("Couldn't listen - " + str(e))
-        return
-
-    response = get_response(config['responsefile'], config['url'], failed)
-    if not response:
-        return
-
-    infohash = sha(bencode(response['info'])).digest()
-
-    d = BT1Download(statusfunc, finfunc, errorfunc, exchandler, doneflag,
-                    config, response, infohash, myid, rawserver, listen_port)
-
-    if not d.saveAs(filefunc):
-        return
-
-    if pathFunc:
-        pathFunc(d.getFilename())
-
-    hashcheck = d.initFiles(old_style = True)
-    if not hashcheck:
-        return
-    if not hashcheck():
-        return
-    if not d.startEngine():
-        return
-    d.startRerequester()
-    d.autoStats()
-
-    statusfunc(activity = 'connecting to peers')
-
-    if paramfunc:
-        paramfunc({ 'max_upload_rate' : d.setUploadRate,  # change_max_upload_rate(<int KiB/sec>)
-                    'max_uploads': d.setConns, # change_max_uploads(<int max uploads>)
-                    'listen_port' : listen_port, # int
-                    'peer_id' : myid, # string
-                    'info_hash' : infohash, # string
-                    'start_connection' : d._startConnection, # start_connection((<string ip>, <int port>), <peer id>)
-                    })
-        
-    rawserver.listen_forever(d.getPortHandler())
-    
-    d.shutdown()
-
-
-def parse_params(params, presets = {}):
-    if len(params) == 0:
-        return None
-    config, args = parseargs(params, defaults, 0, 1, presets = presets)
-    if args:
-        if config['responsefile'] or config['url']:
-            raise ValueError,'must have responsefile or url as arg or parameter, not both'
-        if path.isfile(args[0]):
-            config['responsefile'] = args[0]
-        else:
-            try:
-                urlparse(args[0])
-            except:
-                raise ValueError, 'bad filename or url'
-            config['url'] = args[0]
-    elif (config['responsefile'] == '') == (config['url'] == ''):
-        raise ValueError, 'need responsefile or url, must have one, cannot have both'
-    return config
-
-
-def get_usage(defaults = defaults, cols = 100, presets = {}):
-    return (argslistheader + formatDefinitions(defaults, cols, presets))
-
-
-def get_response(file, url, errorfunc):
-    try:
-        if file:
-            h = open(file, 'rb')
-            try:
-                line = h.read(10)   # quick test to see if responsefile contains a dict
-                front,garbage = line.split(':',1)
-                assert front[0] == 'd'
-                int(front[1:])
-            except:
-                errorfunc(file+' is not a valid responsefile')
-                return None
-            try:
-                h.seek(0)
-            except:
-                try:
-                    h.close()
-                except:
-                    pass
-                h = open(file, 'rb')
-        else:
-            try:
-                h = urlopen(url)
-            except:
-                errorfunc(url+' bad url')
-                return None
-        response = h.read()
-    
-    except IOError, e:
-        errorfunc('problem getting response info - ' + str(e))
-        return None
-    try:    
-        h.close()
-    except:
-        pass
-    try:
-        try:
-            response = bdecode(response)
-        except:
-            errorfunc("warning: bad data in responsefile")
-            response = bdecode(response, sloppy=1)
-        check_message(response)
-    except ValueError, e:
-        errorfunc("got bad file info - " + str(e))
-        return None
-
-    return response
-
-
-class BT1Download:    
-    def __init__(self, statusfunc, finfunc, errorfunc, excfunc, doneflag,
-                 config, response, infohash, id, rawserver, port,
-                 appdataobj = None):
-        self.statusfunc = statusfunc
-        self.finfunc = finfunc
-        self.errorfunc = errorfunc
-        self.excfunc = excfunc
-        self.doneflag = doneflag
-        self.config = config
-        self.response = response
-        self.infohash = infohash
-        self.myid = id
-        self.rawserver = rawserver
-        self.port = port
-        
-        self.info = self.response['info']
-        self.pieces = [self.info['pieces'][x:x+20]
-                       for x in xrange(0, len(self.info['pieces']), 20)]
-        self.len_pieces = len(self.pieces)
-        self.argslistheader = argslistheader
-        self.unpauseflag = Event()
-        self.unpauseflag.set()
-        self.downloader = None
-        self.storagewrapper = None
-        self.fileselector = None
-        self.super_seeding_active = False
-        self.filedatflag = Event()
-        self.spewflag = Event()
-        self.superseedflag = Event()
-        self.whenpaused = None
-        self.finflag = Event()
-        self.rerequest = None
-        self.tcp_ack_fudge = config['tcp_ack_fudge']
-        
-        self.selector_enabled = config['selector_enabled']
-        if appdataobj:
-            self.appdataobj = appdataobj
-        elif self.selector_enabled:
-            self.appdataobj = ConfigDir()
-            self.appdataobj.deleteOldCacheData( config['expire_cache_data'],
-                                                [self.infohash] )
-
-        self.excflag = self.rawserver.get_exception_flag()
-        self.failed = False
-        self.checking = False
-        self.started = False
-
-        self.picker = PiecePicker(self.len_pieces, config['rarest_first_cutoff'],
-                             config['rarest_first_priority_cutoff'])
-        self.choker = Choker(config, rawserver.add_task,
-                             self.picker, self.finflag.isSet)
-
-
-    def checkSaveLocation(self, loc):
-        if self.info.has_key('length'):
-            return path.exists(loc)
-        for x in self.info['files']:
-            if path.exists(path.join(loc, x['path'][0])):
-                return True
-        return False
-                
-
-    def saveAs(self, filefunc, pathfunc = None):
-        try:
-            def make(f, forcedir = False):
-                if not forcedir:
-                    f = path.split(f)[0]
-                if f != '' and not path.exists(f):
-                    makedirs(f)
-
-            if self.info.has_key('length'):
-                file_length = self.info['length']
-                file = filefunc(self.info['name'], file_length,
-                                self.config['saveas'], False)
-                if file is None:
-                    return None
-                make(file)
-                files = [(file, file_length)]
-            else:
-                file_length = 0L
-                for x in self.info['files']:
-                    file_length += x['length']
-                file = filefunc(self.info['name'], file_length,
-                                self.config['saveas'], True)
-                if file is None:
-                    return None
-
-                # if this path exists, and no files from the info dict exist, we assume it's a new download and 
-                # the user wants to create a new directory with the default name
-                existing = 0
-                if path.exists(file):
-                    if not path.isdir(file):
-                        self.errorfunc(file + 'is not a dir')
-                        return None
-                    if len(listdir(file)) > 0:  # if it's not empty
-                        for x in self.info['files']:
-                            if path.exists(path.join(file, x['path'][0])):
-                                existing = 1
-                        if not existing:
-                            file = path.join(file, self.info['name'])
-                            if path.exists(file) and not path.isdir(file):
-                                if file[-8:] == '.torrent':
-                                    file = file[:-8]
-                                if path.exists(file) and not path.isdir(file):
-                                    self.errorfunc("Can't create dir - " + self.info['name'])
-                                    return None
-                make(file, True)
-
-                # alert the UI to any possible change in path
-                if pathfunc != None:
-                    pathfunc(file)
-
-                files = []
-                for x in self.info['files']:
-                    n = file
-                    for i in x['path']:
-                        n = path.join(n, i)
-                    files.append((n, x['length']))
-                    make(n)
-        except OSError, e:
-            self.errorfunc("Couldn't allocate dir - " + str(e))
-            return None
-
-        self.filename = file
-        self.files = files
-        self.datalength = file_length
-
-        return file
-    
-
-    def getFilename(self):
-        return self.filename
-
-
-    def _finished(self):
-        self.finflag.set()
-        try:
-            self.storage.set_readonly()
-        except (IOError, OSError), e:
-            self.errorfunc('trouble setting readonly at end - ' + str(e))
-        if self.superseedflag.isSet():
-            self._set_super_seed()
-        self.choker.set_round_robin_period(
-            max( self.config['round_robin_period'],
-                 self.config['round_robin_period'] *
-                                     self.info['piece length'] / 200000 ) )
-        self.rerequest_complete()
-        self.finfunc()
-
-    def _data_flunked(self, amount, index):
-        self.ratemeasure_datarejected(amount)
-        if not self.doneflag.isSet():
-            self.errorfunc('piece %d failed hash check, re-downloading it' % index)
-
-    def _failed(self, reason):
-        self.failed = True
-        self.doneflag.set()
-        if reason is not None:
-            self.errorfunc(reason)
-        
-
-    def initFiles(self, old_style = False, statusfunc = None):
-        if self.doneflag.isSet():
-            return None
-        if not statusfunc:
-            statusfunc = self.statusfunc
-
-        disabled_files = None
-        if self.selector_enabled:
-            self.priority = self.config['priority']
-            if self.priority:
-                try:
-                    self.priority = self.priority.split(',')
-                    assert len(self.priority) == len(self.files)
-                    self.priority = [int(p) for p in self.priority]
-                    for p in self.priority:
-                        assert p >= -1
-                        assert p <= 2
-                except:
-                    self.errorfunc('bad priority list given, ignored')
-                    self.priority = None
-
-            data = self.appdataobj.getTorrentData(self.infohash)
-            try:
-                d = data['resume data']['priority']
-                assert len(d) == len(self.files)
-                disabled_files = [x == -1 for x in d]
-            except:
-                try:
-                    disabled_files = [x == -1 for x in self.priority]
-                except:
-                    pass
-
-        try:
-            try:
-                self.storage = Storage(self.files, self.info['piece length'],
-                                       self.doneflag, self.config, disabled_files)
-            except IOError, e:
-                self.errorfunc('trouble accessing files - ' + str(e))
-                return None
-            if self.doneflag.isSet():
-                return None
-
-            self.storagewrapper = StorageWrapper(self.storage, self.config['download_slice_size'],
-                self.pieces, self.info['piece length'], self._finished, self._failed,
-                statusfunc, self.doneflag, self.config['check_hashes'],
-                self._data_flunked, self.rawserver.add_task,
-                self.config, self.unpauseflag)
-            
-        except ValueError, e:
-            self._failed('bad data - ' + str(e))
-        except IOError, e:
-            self._failed('IOError - ' + str(e))
-        if self.doneflag.isSet():
-            return None
-
-        if self.selector_enabled:
-            self.fileselector = FileSelector(self.files, self.info['piece length'],
-                                             self.appdataobj.getPieceDir(self.infohash),
-                                             self.storage, self.storagewrapper,
-                                             self.rawserver.add_task,
-                                             self._failed)
-            if data:
-                data = data.get('resume data')
-                if data:
-                    self.fileselector.unpickle(data)
-                
-        self.checking = True
-        if old_style:
-            return self.storagewrapper.old_style_init()
-        return self.storagewrapper.initialize
-
-
-    def getCachedTorrentData(self):
-        return self.appdataobj.getTorrentData(self.infohash)
-
-
-    def _make_upload(self, connection, ratelimiter, totalup):
-        return Upload(connection, ratelimiter, totalup,
-                      self.choker, self.storagewrapper, self.picker,
-                      self.config)
-
-    def _kick_peer(self, connection):
-        def k(connection = connection):
-            connection.close()
-        self.rawserver.add_task(k,0)
-
-    def _ban_peer(self, ip):
-        self.encoder_ban(ip)
-
-    def _received_raw_data(self, x):
-        if self.tcp_ack_fudge:
-            x = int(x*self.tcp_ack_fudge)
-            self.ratelimiter.adjust_sent(x)
-#            self.upmeasure.update_rate(x)
-
-    def _received_data(self, x):
-        self.downmeasure.update_rate(x)
-        self.ratemeasure.data_came_in(x)
-
-    def _received_http_data(self, x):
-        self.downmeasure.update_rate(x)
-        self.ratemeasure.data_came_in(x)
-        self.downloader.external_data_received(x)
-
-    def _cancelfunc(self, pieces):
-        self.downloader.cancel_piece_download(pieces)
-        self.httpdownloader.cancel_piece_download(pieces)
-    def _reqmorefunc(self, pieces):
-        self.downloader.requeue_piece_download(pieces)
-
-    def startEngine(self, ratelimiter = None, statusfunc = None):
-        if self.doneflag.isSet():
-            return False
-        if not statusfunc:
-            statusfunc = self.statusfunc
-
-        self.checking = False
-
-        for i in xrange(self.len_pieces):
-            if self.storagewrapper.do_I_have(i):
-                self.picker.complete(i)
-        self.upmeasure = Measure(self.config['max_rate_period'],
-                            self.config['upload_rate_fudge'])
-        self.downmeasure = Measure(self.config['max_rate_period'])
-
-        if ratelimiter:
-            self.ratelimiter = ratelimiter
-        else:
-            self.ratelimiter = RateLimiter(self.rawserver.add_task,
-                                           self.config['upload_unit_size'],
-                                           self.setConns)
-            self.ratelimiter.set_upload_rate(self.config['max_upload_rate'])
-        
-        self.ratemeasure = RateMeasure()
-        self.ratemeasure_datarejected = self.ratemeasure.data_rejected
-
-        self.downloader = Downloader(self.storagewrapper, self.picker,
-            self.config['request_backlog'], self.config['max_rate_period'],
-            self.len_pieces, self.config['download_slice_size'],
-            self._received_data, self.config['snub_time'], self.config['auto_kick'],
-            self._kick_peer, self._ban_peer)
-        self.downloader.set_download_rate(self.config['max_download_rate'])
-        self.connecter = Connecter(self._make_upload, self.downloader, self.choker,
-                            self.len_pieces, self.upmeasure, self.config,
-                            self.ratelimiter, self.rawserver.add_task)
-        self.encoder = Encoder(self.connecter, self.rawserver,
-            self.myid, self.config['max_message_length'], self.rawserver.add_task,
-            self.config['keepalive_interval'], self.infohash,
-            self._received_raw_data, self.config)
-        self.encoder_ban = self.encoder.ban
-
-        self.httpdownloader = HTTPDownloader(self.storagewrapper, self.picker,
-            self.rawserver, self.finflag, self.errorfunc, self.downloader,
-            self.config['max_rate_period'], self.infohash, self._received_http_data,
-            self.connecter.got_piece)
-        if self.response.has_key('httpseeds') and not self.finflag.isSet():
-            for u in self.response['httpseeds']:
-                self.httpdownloader.make_download(u)
-
-        if self.selector_enabled:
-            self.fileselector.tie_in(self.picker, self._cancelfunc,
-                    self._reqmorefunc, self.rerequest_ondownloadmore)
-            if self.priority:
-                self.fileselector.set_priorities_now(self.priority)
-            self.appdataobj.deleteTorrentData(self.infohash)
-                                # erase old data once you've started modifying it
-
-        if self.config['super_seeder']:
-            self.set_super_seed()
-
-        self.started = True
-        return True
-
-
-    def rerequest_complete(self):
-        if self.rerequest:
-            self.rerequest.announce(1)
-
-    def rerequest_stopped(self):
-        if self.rerequest:
-            self.rerequest.announce(2)
-
-    def rerequest_lastfailed(self):
-        if self.rerequest:
-            return self.rerequest.last_failed
-        return False
-
-    def rerequest_ondownloadmore(self):
-        if self.rerequest:
-            self.rerequest.hit()
-
-    def startRerequester(self, seededfunc = None, force_rapid_update = False):
-        if self.response.has_key('announce-list'):
-            trackerlist = self.response['announce-list']
-        else:
-            trackerlist = [[self.response['announce']]]
-
-        self.rerequest = Rerequester(trackerlist, self.config['rerequest_interval'], 
-            self.rawserver.add_task, self.connecter.how_many_connections, 
-            self.config['min_peers'], self.encoder.start_connections,
-            self.rawserver.add_task, self.storagewrapper.get_amount_left, 
-            self.upmeasure.get_total, self.downmeasure.get_total, self.port, self.config['ip'],
-            self.myid, self.infohash, self.config['http_timeout'],
-            self.errorfunc, self.excfunc, self.config['max_initiate'],
-            self.doneflag, self.upmeasure.get_rate, self.downmeasure.get_rate,
-            self.unpauseflag, self.config['dedicated_seed_id'],
-            seededfunc, force_rapid_update )
-
-        self.rerequest.start()
-
-
-    def _init_stats(self):
-        self.statistics = Statistics(self.upmeasure, self.downmeasure,
-                    self.connecter, self.httpdownloader, self.ratelimiter,
-                    self.rerequest_lastfailed, self.filedatflag)
-        if self.info.has_key('files'):
-            self.statistics.set_dirstats(self.files, self.info['piece length'])
-        if self.config['spew']:
-            self.spewflag.set()
-
-    def autoStats(self, displayfunc = None):
-        if not displayfunc:
-            displayfunc = self.statusfunc
-
-        self._init_stats()
-        DownloaderFeedback(self.choker, self.httpdownloader, self.rawserver.add_task,
-            self.upmeasure.get_rate, self.downmeasure.get_rate,
-            self.ratemeasure, self.storagewrapper.get_stats,
-            self.datalength, self.finflag, self.spewflag, self.statistics,
-            displayfunc, self.config['display_interval'])
-
-    def startStats(self):
-        self._init_stats()
-        d = DownloaderFeedback(self.choker, self.httpdownloader, self.rawserver.add_task,
-            self.upmeasure.get_rate, self.downmeasure.get_rate,
-            self.ratemeasure, self.storagewrapper.get_stats,
-            self.datalength, self.finflag, self.spewflag, self.statistics)
-        return d.gather
-
-
-    def getPortHandler(self):
-        return self.encoder
-
-
-    def shutdown(self, torrentdata = {}):
-        if self.checking or self.started:
-            self.storagewrapper.sync()
-            self.storage.close()
-            self.rerequest_stopped()
-        if self.fileselector and self.started:
-            if not self.failed:
-                self.fileselector.finish()
-                torrentdata['resume data'] = self.fileselector.pickle()
-            try:
-                self.appdataobj.writeTorrentData(self.infohash,torrentdata)
-            except:
-                self.appdataobj.deleteTorrentData(self.infohash) # clear it
-        return not self.failed and not self.excflag.isSet()
-        # if returns false, you may wish to auto-restart the torrent
-
-
-    def setUploadRate(self, rate):
-        try:
-            def s(self = self, rate = rate):
-                self.config['max_upload_rate'] = rate
-                self.ratelimiter.set_upload_rate(rate)
-            self.rawserver.add_task(s)
-        except AttributeError:
-            pass
-
-    def setConns(self, conns, conns2 = None):
-        if not conns2:
-            conns2 = conns
-        try:
-            def s(self = self, conns = conns, conns2 = conns2):
-                self.config['min_uploads'] = conns
-                self.config['max_uploads'] = conns2
-                if (conns > 30):
-                    self.config['max_initiate'] = conns + 10
-            self.rawserver.add_task(s)
-        except AttributeError:
-            pass
-        
-    def setDownloadRate(self, rate):
-        try:
-            def s(self = self, rate = rate):
-                self.config['max_download_rate'] = rate
-                self.downloader.set_download_rate(rate)
-            self.rawserver.add_task(s)
-        except AttributeError:
-            pass
-
-    def startConnection(self, ip, port, id):
-        self.encoder._start_connection((ip, port), id)
-      
-    def _startConnection(self, ipandport, id):
-        self.encoder._start_connection(ipandport, id)
-        
-    def setInitiate(self, initiate):
-        try:
-            def s(self = self, initiate = initiate):
-                self.config['max_initiate'] = initiate
-            self.rawserver.add_task(s)
-        except AttributeError:
-            pass
-
-    def getConfig(self):
-        return self.config
-
-    def getDefaults(self):
-        return defaultargs(defaults)
-
-    def getUsageText(self):
-        return self.argslistheader
-
-    def reannounce(self, special = None):
-        try:
-            def r(self = self, special = special):
-                if special is None:
-                    self.rerequest.announce()
-                else:
-                    self.rerequest.announce(specialurl = special)
-            self.rawserver.add_task(r)
-        except AttributeError:
-            pass
-
-    def getResponse(self):
-        try:
-            return self.response
-        except:
-            return None
-
-#    def Pause(self):
-#        try:
-#            if self.storagewrapper:
-#                self.rawserver.add_task(self._pausemaker, 0)
-#        except:
-#            return False
-#        self.unpauseflag.clear()
-#        return True
-#
-#    def _pausemaker(self):
-#        self.whenpaused = clock()
-#        self.unpauseflag.wait()   # sticks a monkey wrench in the main thread
-#
-#    def Unpause(self):
-#        self.unpauseflag.set()
-#        if self.whenpaused and clock()-self.whenpaused > 60:
-#            def r(self = self):
-#                self.rerequest.announce(3)      # rerequest automatically if paused for >60 seconds
-#            self.rawserver.add_task(r)
-
-    def Pause(self):
-        if not self.storagewrapper:
-            return False
-        self.unpauseflag.clear()
-        self.rawserver.add_task(self.onPause)
-        return True
-
-    def onPause(self):
-        self.whenpaused = clock()
-        if not self.downloader:
-            return
-        self.downloader.pause(True)
-        self.encoder.pause(True)
-        self.choker.pause(True)
-    
-    def Unpause(self):
-        self.unpauseflag.set()
-        self.rawserver.add_task(self.onUnpause)
-
-    def onUnpause(self):
-        if not self.downloader:
-            return
-        self.downloader.pause(False)
-        self.encoder.pause(False)
-        self.choker.pause(False)
-        if self.rerequest and self.whenpaused and clock()-self.whenpaused > 60:
-            self.rerequest.announce(3)      # rerequest automatically if paused for >60 seconds
-
-    def set_super_seed(self):
-        try:
-            self.superseedflag.set()
-            def s(self = self):
-                if self.finflag.isSet():
-                    self._set_super_seed()
-            self.rawserver.add_task(s)
-        except AttributeError:
-            pass
-
-    def _set_super_seed(self):
-        if not self.super_seeding_active:
-            self.super_seeding_active = True
-            self.errorfunc('        ** SUPER-SEED OPERATION ACTIVE **\n' +
-                           '  please set Max uploads so each peer gets 6-8 kB/s')
-            def s(self = self):
-                self.downloader.set_super_seed()
-                self.choker.set_super_seed()
-            self.rawserver.add_task(s)
-            if self.finflag.isSet():        # mode started when already finished
-                def r(self = self):
-                    self.rerequest.announce(3)  # so after kicking everyone off, reannounce
-                self.rawserver.add_task(r)
-
-    def am_I_finished(self):
-        return self.finflag.isSet()
-
-    def get_transfer_stats(self):
-        return self.upmeasure.get_total(), self.downmeasure.get_total()
diff --git a/www/pages/torrent/client/inifile.py b/www/pages/torrent/client/inifile.py
deleted file mode 100644 (file)
index 032d339..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-'''
-reads/writes a Windows-style INI file
-format:
-
-  aa = "bb"
-  cc = 11
-
-  [eee]
-  ff = "gg"
-
-decodes to:
-d = { '': {'aa':'bb','cc':'11'}, 'eee': {'ff':'gg'} }
-
-the encoder can also take this as input:
-
-d = { 'aa': 'bb, 'cc': 11, 'eee': {'ff':'gg'} }
-
-though it will only decode in the above format.  Keywords must be strings.
-Values that are strings are written surrounded by quotes, and the decoding
-routine automatically strips any.
-Booleans are written as integers.  Anything else aside from string/int/float
-may have unpredictable results.
-'''
-
-from cStringIO import StringIO
-from traceback import print_exc
-from types import DictType, StringType
-try:
-    from types import BooleanType
-except ImportError:
-    BooleanType = None
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-DEBUG = False
-
-def ini_write(f, d, comment=''):
-    try:
-        a = {'':{}}
-        for k,v in d.items():
-            assert type(k) == StringType
-            k = k.lower()
-            if type(v) == DictType:
-                if DEBUG:
-                    print 'new section:' +k
-                if k:
-                    assert not a.has_key(k)
-                    a[k] = {}
-                aa = a[k]
-                for kk,vv in v:
-                    assert type(kk) == StringType
-                    kk = kk.lower()
-                    assert not aa.has_key(kk)
-                    if type(vv) == BooleanType:
-                        vv = int(vv)
-                    if type(vv) == StringType:
-                        vv = '"'+vv+'"'
-                    aa[kk] = str(vv)
-                    if DEBUG:
-                        print 'a['+k+']['+kk+'] = '+str(vv)
-            else:
-                aa = a['']
-                assert not aa.has_key(k)
-                if type(v) == BooleanType:
-                    v = int(v)
-                if type(v) == StringType:
-                    v = '"'+v+'"'
-                aa[k] = str(v)
-                if DEBUG:
-                    print 'a[\'\']['+k+'] = '+str(v)
-        r = open(f,'w')
-        if comment:
-            for c in comment.split('\n'):
-                r.write('# '+c+'\n')
-            r.write('\n')
-        l = a.keys()
-        l.sort()
-        for k in l:
-            if k:
-                r.write('\n['+k+']\n')
-            aa = a[k]
-            ll = aa.keys()
-            ll.sort()
-            for kk in ll:
-                r.write(kk+' = '+aa[kk]+'\n')
-        success = True
-    except:
-        if DEBUG:
-            print_exc()
-        success = False
-    try:
-        r.close()
-    except:
-        pass
-    return success
-
-
-if DEBUG:
-    def errfunc(lineno, line, err):
-        print '('+str(lineno)+') '+err+': '+line
-else:
-    errfunc = lambda lineno, line, err: None
-
-def ini_read(f, errfunc = errfunc):
-    try:
-        r = open(f,'r')
-        ll = r.readlines()
-        d = {}
-        dd = {'':d}
-        for i in xrange(len(ll)):
-            l = ll[i]
-            l = l.strip()
-            if not l:
-                continue
-            if l[0] == '#':
-                continue
-            if l[0] == '[':
-                if l[-1] != ']':
-                    errfunc(i,l,'syntax error')
-                    continue
-                l1 = l[1:-1].strip().lower()
-                if not l1:
-                    errfunc(i,l,'syntax error')
-                    continue
-                if dd.has_key(l1):
-                    errfunc(i,l,'duplicate section')
-                    d = dd[l1]
-                    continue
-                d = {}
-                dd[l1] = d
-                continue
-            try:
-                k,v = l.split('=',1)
-            except:
-                try:
-                    k,v = l.split(':',1)
-                except:
-                    errfunc(i,l,'syntax error')
-                    continue
-            k = k.strip().lower()
-            v = v.strip()
-            if len(v) > 1 and ( (v[0] == '"' and v[-1] == '"') or
-                                (v[0] == "'" and v[-1] == "'") ):
-                v = v[1:-1]
-            if not k:
-                errfunc(i,l,'syntax error')
-                continue
-            if d.has_key(k):
-                errfunc(i,l,'duplicate entry')
-                continue
-            d[k] = v
-        if DEBUG:
-            print dd
-    except:
-        if DEBUG:
-            print_exc()
-        dd = None
-    try:
-        r.close()
-    except:
-        pass
-    return dd
diff --git a/www/pages/torrent/client/iprangeparse.py b/www/pages/torrent/client/iprangeparse.py
deleted file mode 100644 (file)
index 52f140e..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-from bisect import bisect, insort
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-    bool = lambda x: not not x
-
-
-def to_long_ipv4(ip):
-    ip = ip.split('.')
-    if len(ip) != 4:
-        raise ValueError, "bad address"
-    b = 0L
-    for n in ip:
-        b *= 256
-        b += int(n)
-    return b
-
-
-def to_long_ipv6(ip):
-    if ip == '':
-        raise ValueError, "bad address"
-    if ip == '::':      # boundary handling
-        ip = ''
-    elif ip[:2] == '::':
-        ip = ip[1:]
-    elif ip[0] == ':':
-        raise ValueError, "bad address"
-    elif ip[-2:] == '::':
-        ip = ip[:-1]
-    elif ip[-1] == ':':
-        raise ValueError, "bad address"
-
-    b = []
-    doublecolon = False
-    for n in ip.split(':'):
-        if n == '':     # double-colon
-            if doublecolon:
-                raise ValueError, "bad address"
-            doublecolon = True
-            b.append(None)
-            continue
-        if n.find('.') >= 0: # IPv4
-            n = n.split('.')
-            if len(n) != 4:
-                raise ValueError, "bad address"
-            for i in n:
-                b.append(int(i))
-            continue
-        n = ('0'*(4-len(n))) + n
-        b.append(int(n[:2],16))
-        b.append(int(n[2:],16))
-    bb = 0L
-    for n in b:
-        if n is None:
-            for i in xrange(17-len(b)):
-                bb *= 256
-            continue
-        bb *= 256
-        bb += n
-    return bb
-
-ipv4addrmask = 65535L*256*256*256*256
-
-class IP_List:
-    def __init__(self):
-        self.ipv4list = []  # starts of ranges
-        self.ipv4dict = {}  # start: end of ranges
-        self.ipv6list = []  # "
-        self.ipv6dict = {}  # "
-
-    def __nonzero__(self):
-        return bool(self.ipv4list or self.ipv6list)
-
-
-    def append(self, ip_beg, ip_end = None):
-        if ip_end is None:
-            ip_end = ip_beg
-        else:
-            assert ip_beg <= ip_end
-        if ip_beg.find(':') < 0:        # IPv4
-            ip_beg = to_long_ipv4(ip_beg)
-            ip_end = to_long_ipv4(ip_end)
-            l = self.ipv4list
-            d = self.ipv4dict
-        else:
-            ip_beg = to_long_ipv6(ip_beg)
-            ip_end = to_long_ipv6(ip_end)
-            bb = ip_beg % (256*256*256*256)
-            if bb == ipv4addrmask:
-                ip_beg -= bb
-                ip_end -= bb
-                l = self.ipv4list
-                d = self.ipv4dict
-            else:
-                l = self.ipv6list
-                d = self.ipv6dict
-
-        pos = bisect(l,ip_beg)-1
-        done = pos < 0
-        while not done:
-            p = pos
-            while p < len(l):
-                range_beg = l[p]
-                if range_beg > ip_end+1:
-                    done = True
-                    break
-                range_end = d[range_beg]
-                if range_end < ip_beg-1:
-                    p += 1
-                    if p == len(l):
-                        done = True
-                        break
-                    continue
-                # if neither of the above conditions is true, the ranges overlap
-                ip_beg = min(ip_beg, range_beg)
-                ip_end = max(ip_end, range_end)
-                del l[p]
-                del d[range_beg]
-                break
-
-        insort(l,ip_beg)
-        d[ip_beg] = ip_end
-
-
-    def includes(self, ip):
-        if not (self.ipv4list or self.ipv6list):
-            return False
-        if ip.find(':') < 0:        # IPv4
-            ip = to_long_ipv4(ip)
-            l = self.ipv4list
-            d = self.ipv4dict
-        else:
-            ip = to_long_ipv6(ip)
-            bb = ip % (256*256*256*256)
-            if bb == ipv4addrmask:
-                ip -= bb
-                l = self.ipv4list
-                d = self.ipv4dict
-            else:
-                l = self.ipv6list
-                d = self.ipv6dict
-        for ip_beg in l[bisect(l,ip)-1:]:
-            if ip == ip_beg:
-                return True
-            ip_end = d[ip_beg]
-            if ip > ip_beg and ip <= ip_end:
-                return True
-        return False
-
-
-    # reads a list from a file in the format 'whatever:whatever:ip-ip'
-    # (not IPv6 compatible at all)
-    def read_rangelist(self, file):
-        f = open(file, 'r')
-        while True:
-            line = f.readline()
-            if not line:
-                break
-            line = line.strip()
-            if not line or line[0] == '#':
-                continue
-            line = line.split(':')[-1]
-            try:
-                ip1,ip2 = line.split('-')
-            except:
-                ip1 = line
-                ip2 = line
-            try:
-                self.append(ip1.strip(),ip2.strip())
-            except:
-                print '*** WARNING *** could not parse IP range: '+line
-        f.close()
-
-def is_ipv4(ip):
-    return ip.find(':') < 0
-
-def is_valid_ip(ip):
-    try:
-        if is_ipv4(ip):
-            a = ip.split('.')
-            assert len(a) == 4
-            for i in a:
-                chr(int(i))
-            return True
-        to_long_ipv6(ip)
-        return True
-    except:
-        return False
diff --git a/www/pages/torrent/client/launchmanycore.py b/www/pages/torrent/client/launchmanycore.py
deleted file mode 100644 (file)
index 8dbb59c..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-#!/usr/bin/env python
-
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-from BitTornado import PSYCO
-if PSYCO.psyco:
-    try:
-        import psyco
-        assert psyco.__version__ >= 0x010100f0
-        psyco.full()
-    except:
-        pass
-
-from download_bt1 import BT1Download
-from RawServer import RawServer, UPnP_ERROR
-from RateLimiter import RateLimiter
-from ServerPortHandler import MultiHandler
-from parsedir import parsedir
-from natpunch import UPnP_test
-from random import seed
-from socket import error as socketerror
-from threading import Event
-from sys import argv, exit
-import sys, os
-from clock import clock
-from __init__ import createPeerID, mapbase64, version
-from cStringIO import StringIO
-from traceback import print_exc
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-
-def fmttime(n):
-    try:
-        n = int(n)  # n may be None or too large
-        assert n < 5184000  # 60 days
-    except:
-        return 'downloading'
-    m, s = divmod(n, 60)
-    h, m = divmod(m, 60)
-    return '%d:%02d:%02d' % (h, m, s)
-
-class SingleDownload:
-    def __init__(self, controller, hash, response, config, myid):
-        self.controller = controller
-        self.hash = hash
-        self.response = response
-        self.config = config
-        
-        self.doneflag = Event()
-        self.waiting = True
-        self.checking = False
-        self.working = False
-        self.seed = False
-        self.closed = False
-
-        self.status_msg = ''
-        self.status_err = ['']
-        self.status_errtime = 0
-        self.status_done = 0.0
-
-        self.rawserver = controller.handler.newRawServer(hash, self.doneflag)
-
-        d = BT1Download(self.display, self.finished, self.error,
-                        controller.exchandler, self.doneflag, config, response,
-                        hash, myid, self.rawserver, controller.listen_port)
-        self.d = d
-
-    def start(self):
-        if not self.d.saveAs(self.saveAs):
-            self._shutdown()
-            return
-        self._hashcheckfunc = self.d.initFiles()
-        if not self._hashcheckfunc:
-            self._shutdown()
-            return
-        self.controller.hashchecksched(self.hash)
-
-
-    def saveAs(self, name, length, saveas, isdir):
-        return self.controller.saveAs(self.hash, name, saveas, isdir)
-
-    def hashcheck_start(self, donefunc):
-        if self.is_dead():
-            self._shutdown()
-            return
-        self.waiting = False
-        self.checking = True
-        self._hashcheckfunc(donefunc)
-
-    def hashcheck_callback(self):
-        self.checking = False
-        if self.is_dead():
-            self._shutdown()
-            return
-        if not self.d.startEngine(ratelimiter = self.controller.ratelimiter):
-            self._shutdown()
-            return
-        self.d.startRerequester()
-        self.statsfunc = self.d.startStats()
-        self.rawserver.start_listening(self.d.getPortHandler())
-        self.working = True
-
-    def is_dead(self):
-        return self.doneflag.isSet()
-
-    def _shutdown(self):
-        self.shutdown(False)
-
-    def shutdown(self, quiet=True):
-        if self.closed:
-            return
-        self.doneflag.set()
-        self.rawserver.shutdown()
-        if self.checking or self.working:
-            self.d.shutdown()
-        self.waiting = False
-        self.checking = False
-        self.working = False
-        self.closed = True
-        self.controller.was_stopped(self.hash)
-        if not quiet:
-            self.controller.died(self.hash)
-            
-
-    def display(self, activity = None, fractionDone = None):
-        # really only used by StorageWrapper now
-        if activity:
-            self.status_msg = activity
-        if fractionDone is not None:
-            self.status_done = float(fractionDone)
-
-    def finished(self):
-        self.seed = True
-
-    def error(self, msg):
-        if self.doneflag.isSet():
-            self._shutdown()
-        self.status_err.append(msg)
-        self.status_errtime = clock()
-
-
-class LaunchMany:
-    def __init__(self, config, Output):
-        try:
-            self.config = config
-            self.Output = Output
-
-            self.torrent_dir = config['torrent_dir']
-            self.torrent_cache = {}
-            self.file_cache = {}
-            self.blocked_files = {}
-            self.scan_period = config['parse_dir_interval']
-            self.stats_period = config['display_interval']
-
-            self.torrent_list = []
-            self.downloads = {}
-            self.counter = 0
-            self.doneflag = Event()
-
-            self.hashcheck_queue = []
-            self.hashcheck_current = None
-            
-            self.rawserver = RawServer(self.doneflag, config['timeout_check_interval'],
-                              config['timeout'], ipv6_enable = config['ipv6_enabled'],
-                              failfunc = self.failed, errorfunc = self.exchandler)
-            upnp_type = UPnP_test(config['upnp_nat_access'])
-            while True:
-                try:
-                    self.listen_port = self.rawserver.find_and_bind(
-                                    config['minport'], config['maxport'], config['bind'],
-                                    ipv6_socket_style = config['ipv6_binds_v4'],
-                                    upnp = upnp_type, randomizer = config['random_port'])
-                    break
-                except socketerror, e:
-                    if upnp_type and e == UPnP_ERROR:
-                        self.Output.message('WARNING: COULD NOT FORWARD VIA UPnP')
-                        upnp_type = 0
-                        continue
-                    self.failed("Couldn't listen - " + str(e))
-                    return
-
-            self.ratelimiter = RateLimiter(self.rawserver.add_task,
-                                           config['upload_unit_size'])
-            self.ratelimiter.set_upload_rate(config['max_upload_rate'])
-
-            self.handler = MultiHandler(self.rawserver, self.doneflag)
-            seed(createPeerID())
-            self.rawserver.add_task(self.scan, 0)
-            self.rawserver.add_task(self.stats, 0)
-
-            self.handler.listen_forever()
-
-            self.Output.message('shutting down')
-            self.hashcheck_queue = []
-            for hash in self.torrent_list:
-                self.Output.message('dropped "'+self.torrent_cache[hash]['path']+'"')
-                self.downloads[hash].shutdown()
-            self.rawserver.shutdown()
-
-        except:
-            data = StringIO()
-            print_exc(file = data)
-            Output.exception(data.getvalue())
-
-
-    def scan(self):
-        self.rawserver.add_task(self.scan, self.scan_period)
-                                
-        r = parsedir(self.torrent_dir, self.torrent_cache,
-                     self.file_cache, self.blocked_files,
-                     return_metainfo = True, errfunc = self.Output.message)
-
-        ( self.torrent_cache, self.file_cache, self.blocked_files,
-            added, removed ) = r
-
-        for hash, data in removed.items():
-            self.Output.message('dropped "'+data['path']+'"')
-            self.remove(hash)
-        for hash, data in added.items():
-            self.Output.message('added "'+data['path']+'"')
-            self.add(hash, data)
-
-    def stats(self):            
-        self.rawserver.add_task(self.stats, self.stats_period)
-        data = []
-        for hash in self.torrent_list:
-            cache = self.torrent_cache[hash]
-            if self.config['display_path']:
-                name = cache['path']
-            else:
-                name = cache['name']
-            size = cache['length']
-            d = self.downloads[hash]
-            progress = '0.0%'
-            peers = 0
-            seeds = 0
-            seedsmsg = "S"
-            dist = 0.0
-            uprate = 0.0
-            dnrate = 0.0
-            upamt = 0
-            dnamt = 0
-            t = 0
-            if d.is_dead():
-                status = 'stopped'
-            elif d.waiting:
-                status = 'waiting for hash check'
-            elif d.checking:
-                status = d.status_msg
-                progress = '%.1f%%' % (d.status_done*100)
-            else:
-                stats = d.statsfunc()
-                s = stats['stats']
-                if d.seed:
-                    status = 'seeding'
-                    progress = '100.0%'
-                    seeds = s.numOldSeeds
-                    seedsmsg = "s"
-                    dist = s.numCopies
-                else:
-                    if s.numSeeds + s.numPeers:
-                        t = stats['time']
-                        if t == 0:  # unlikely
-                            t = 0.01
-                        status = fmttime(t)
-                    else:
-                        t = -1
-                        status = 'connecting to peers'
-                    progress = '%.1f%%' % (int(stats['frac']*1000)/10.0)
-                    seeds = s.numSeeds
-                    dist = s.numCopies2
-                    dnrate = stats['down']
-                peers = s.numPeers
-                uprate = stats['up']
-                upamt = s.upTotal
-                dnamt = s.downTotal
-                   
-            if d.is_dead() or d.status_errtime+300 > clock():
-                msg = d.status_err[-1]
-            else:
-                msg = ''
-
-            data.append(( name, status, progress, peers, seeds, seedsmsg, dist,
-                          uprate, dnrate, upamt, dnamt, size, t, msg ))
-        stop = self.Output.display(data)
-        if stop:
-            self.doneflag.set()
-
-    def remove(self, hash):
-        self.torrent_list.remove(hash)
-        self.downloads[hash].shutdown()
-        del self.downloads[hash]
-        
-    def add(self, hash, data):
-        c = self.counter
-        self.counter += 1
-        x = ''
-        for i in xrange(3):
-            x = mapbase64[c & 0x3F]+x
-            c >>= 6
-        peer_id = createPeerID(x)
-        d = SingleDownload(self, hash, data['metainfo'], self.config, peer_id)
-        self.torrent_list.append(hash)
-        self.downloads[hash] = d
-        d.start()
-
-
-    def saveAs(self, hash, name, saveas, isdir):
-        x = self.torrent_cache[hash]
-        style = self.config['saveas_style']
-        if style == 1 or style == 3:
-            if saveas:
-                saveas = os.path.join(saveas,x['file'][:-1-len(x['type'])])
-            else:
-                saveas = x['path'][:-1-len(x['type'])]
-            if style == 3:
-                if not os.path.isdir(saveas):
-                    try:
-                        os.mkdir(saveas)
-                    except:
-                        raise OSError("couldn't create directory for "+x['path']
-                                      +" ("+saveas+")")
-                if not isdir:
-                    saveas = os.path.join(saveas, name)
-        else:
-            if saveas:
-                saveas = os.path.join(saveas, name)
-            else:
-                saveas = os.path.join(os.path.split(x['path'])[0], name)
-                
-        if isdir and not os.path.isdir(saveas):
-            try:
-                os.mkdir(saveas)
-            except:
-                raise OSError("couldn't create directory for "+x['path']
-                                      +" ("+saveas+")")
-        return saveas
-
-
-    def hashchecksched(self, hash = None):
-        if hash:
-            self.hashcheck_queue.append(hash)
-        if not self.hashcheck_current:
-            self._hashcheck_start()
-
-    def _hashcheck_start(self):
-        self.hashcheck_current = self.hashcheck_queue.pop(0)
-        self.downloads[self.hashcheck_current].hashcheck_start(self.hashcheck_callback)
-
-    def hashcheck_callback(self):
-        self.downloads[self.hashcheck_current].hashcheck_callback()
-        if self.hashcheck_queue:
-            self._hashcheck_start()
-        else:
-            self.hashcheck_current = None
-
-    def died(self, hash):
-        if self.torrent_cache.has_key(hash):
-            self.Output.message('DIED: "'+self.torrent_cache[hash]['path']+'"')
-        
-    def was_stopped(self, hash):
-        try:
-            self.hashcheck_queue.remove(hash)
-        except:
-            pass
-        if self.hashcheck_current == hash:
-            self.hashcheck_current = None
-            if self.hashcheck_queue:
-                self._hashcheck_start()
-
-    def failed(self, s):
-        self.Output.message('FAILURE: '+s)
-
-    def exchandler(self, s):
-        self.Output.exception(s)
diff --git a/www/pages/torrent/client/natpunch.py b/www/pages/torrent/client/natpunch.py
deleted file mode 100644 (file)
index 896827b..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-# Written by John Hoffman
-# derived from NATPortMapping.py by Yejun Yang
-# and from example code by Myers Carpenter
-# see LICENSE.txt for license information
-
-import socket
-from traceback import print_exc
-from subnetparse import IP_List
-from clock import clock
-from __init__ import createPeerID
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-DEBUG = False
-
-EXPIRE_CACHE = 30 # seconds
-ID = "BT-"+createPeerID()[-4:]
-
-try:
-    import pythoncom, win32com.client
-    _supported = 1
-except ImportError:
-    _supported = 0
-
-
-
-class _UPnP1:   # derived from Myers Carpenter's code
-                # seems to use the machine's local UPnP
-                # system for its operation.  Runs fairly fast
-
-    def __init__(self):
-        self.map = None
-        self.last_got_map = -10e10
-
-    def _get_map(self):
-        if self.last_got_map + EXPIRE_CACHE < clock():
-            try:
-                dispatcher = win32com.client.Dispatch("HNetCfg.NATUPnP")
-                self.map = dispatcher.StaticPortMappingCollection
-                self.last_got_map = clock()
-            except:
-                self.map = None
-        return self.map
-
-    def test(self):
-        try:
-            assert self._get_map()     # make sure a map was found
-            success = True
-        except:
-            success = False
-        return success
-
-
-    def open(self, ip, p):
-        map = self._get_map()
-        try:
-            map.Add(p,'TCP',p,ip,True,ID)
-            if DEBUG:
-                print 'port opened: '+ip+':'+str(p)
-            success = True
-        except:
-            if DEBUG:
-                print "COULDN'T OPEN "+str(p)
-                print_exc()
-            success = False
-        return success
-
-
-    def close(self, p):
-        map = self._get_map()
-        try:
-            map.Remove(p,'TCP')
-            success = True
-            if DEBUG:
-                print 'port closed: '+str(p)
-        except:
-            if DEBUG:
-                print 'ERROR CLOSING '+str(p)
-                print_exc()
-            success = False
-        return success
-
-
-    def clean(self, retry = False):
-        if not _supported:
-            return
-        try:
-            map = self._get_map()
-            ports_in_use = []
-            for i in xrange(len(map)):
-                try:
-                    mapping = map[i]
-                    port = mapping.ExternalPort
-                    prot = str(mapping.Protocol).lower()
-                    desc = str(mapping.Description).lower()
-                except:
-                    port = None
-                if port and prot == 'tcp' and desc[:3] == 'bt-':
-                    ports_in_use.append(port)
-            success = True
-            for port in ports_in_use:
-                try:
-                    map.Remove(port,'TCP')
-                except:
-                    success = False
-            if not success and not retry:
-                self.clean(retry = True)
-        except:
-            pass
-
-
-class _UPnP2:   # derived from Yejun Yang's code
-                # apparently does a direct search for UPnP hardware
-                # may work in some cases where _UPnP1 won't, but is slow
-                # still need to implement "clean" method
-
-    def __init__(self):
-        self.services = None
-        self.last_got_services = -10e10
-                           
-    def _get_services(self):
-        if not self.services or self.last_got_services + EXPIRE_CACHE < clock():
-            self.services = []
-            try:
-                f=win32com.client.Dispatch("UPnP.UPnPDeviceFinder")
-                for t in ( "urn:schemas-upnp-org:service:WANIPConnection:1",
-                           "urn:schemas-upnp-org:service:WANPPPConnection:1" ):
-                    try:
-                        conns = f.FindByType(t,0)
-                        for c in xrange(len(conns)):
-                            try:
-                                svcs = conns[c].Services
-                                for s in xrange(len(svcs)):
-                                    try:
-                                        self.services.append(svcs[s])
-                                    except:
-                                        pass
-                            except:
-                                pass
-                    except:
-                        pass
-            except:
-                pass
-            self.last_got_services = clock()
-        return self.services
-
-    def test(self):
-        try:
-            assert self._get_services()    # make sure some services can be found
-            success = True
-        except:
-            success = False
-        return success
-
-
-    def open(self, ip, p):
-        svcs = self._get_services()
-        success = False
-        for s in svcs:
-            try:
-                s.InvokeAction('AddPortMapping',['',p,'TCP',p,ip,True,ID,0],'')
-                success = True
-            except:
-                pass
-        if DEBUG and not success:
-            print "COULDN'T OPEN "+str(p)
-            print_exc()
-        return success
-
-
-    def close(self, p):
-        svcs = self._get_services()
-        success = False
-        for s in svcs:
-            try:
-                s.InvokeAction('DeletePortMapping', ['',p,'TCP'], '')
-                success = True
-            except:
-                pass
-        if DEBUG and not success:
-            print "COULDN'T OPEN "+str(p)
-            print_exc()
-        return success
-
-
-class _UPnP:    # master holding class
-    def __init__(self):
-        self.upnp1 = _UPnP1()
-        self.upnp2 = _UPnP2()
-        self.upnplist = (None, self.upnp1, self.upnp2)
-        self.upnp = None
-        self.local_ip = None
-        self.last_got_ip = -10e10
-        
-    def get_ip(self):
-        if self.last_got_ip + EXPIRE_CACHE < clock():
-            local_ips = IP_List()
-            local_ips.set_intranet_addresses()
-            try:
-                for info in socket.getaddrinfo(socket.gethostname(),0,socket.AF_INET):
-                            # exception if socket library isn't recent
-                    self.local_ip = info[4][0]
-                    if local_ips.includes(self.local_ip):
-                        self.last_got_ip = clock()
-                        if DEBUG:
-                            print 'Local IP found: '+self.local_ip
-                        break
-                else:
-                    raise ValueError('couldn\'t find intranet IP')
-            except:
-                self.local_ip = None
-                if DEBUG:
-                    print 'Error finding local IP'
-                    print_exc()
-        return self.local_ip
-
-    def test(self, upnp_type):
-        if DEBUG:
-            print 'testing UPnP type '+str(upnp_type)
-        if not upnp_type or not _supported or self.get_ip() is None:
-            if DEBUG:
-                print 'not supported'
-            return 0
-        pythoncom.CoInitialize()                # leave initialized
-        self.upnp = self.upnplist[upnp_type]    # cache this
-        if self.upnp.test():
-            if DEBUG:
-                print 'ok'
-            return upnp_type
-        if DEBUG:
-            print 'tested bad'
-        return 0
-
-    def open(self, p):
-        assert self.upnp, "must run UPnP_test() with the desired UPnP access type first"
-        return self.upnp.open(self.get_ip(), p)
-
-    def close(self, p):
-        assert self.upnp, "must run UPnP_test() with the desired UPnP access type first"
-        return self.upnp.close(p)
-
-    def clean(self):
-        return self.upnp1.clean()
-
-_upnp_ = _UPnP()
-
-UPnP_test = _upnp_.test
-UPnP_open_port = _upnp_.open
-UPnP_close_port = _upnp_.close
-UPnP_reset = _upnp_.clean
-
diff --git a/www/pages/torrent/client/parseargs.py b/www/pages/torrent/client/parseargs.py
deleted file mode 100644 (file)
index 646af10..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-# Written by Bill Bumgarner and Bram Cohen
-# see LICENSE.txt for license information
-
-from types import *
-from cStringIO import StringIO
-
-
-def splitLine(line, COLS=80, indent=10):
-    indent = " " * indent
-    width = COLS - (len(indent) + 1)
-    if indent and width < 15:
-        width = COLS - 2
-        indent = " "
-    s = StringIO()
-    i = 0
-    for word in line.split():
-        if i == 0:
-            s.write(indent+word)
-            i = len(word)
-            continue
-        if i + len(word) >= width:
-            s.write('\n'+indent+word)
-            i = len(word)
-            continue
-        s.write(' '+word)
-        i += len(word) + 1
-    return s.getvalue()
-
-def formatDefinitions(options, COLS, presets = {}):
-    s = StringIO()
-    for (longname, default, doc) in options:
-        s.write('--' + longname + ' <arg>\n')
-        default = presets.get(longname, default)
-        if type(default) in (IntType, LongType):
-            try:
-                default = int(default)
-            except:
-                pass
-        if default is not None:
-            doc += ' (defaults to ' + repr(default) + ')'
-        s.write(splitLine(doc,COLS,10))
-        s.write('\n\n')
-    return s.getvalue()
-
-
-def usage(str):
-    raise ValueError(str)
-
-
-def defaultargs(options):
-    l = {}
-    for (longname, default, doc) in options:
-        if default is not None:
-            l[longname] = default
-    return l
-        
-
-def parseargs(argv, options, minargs = None, maxargs = None, presets = {}):
-    config = {}
-    longkeyed = {}
-    for option in options:
-        longname, default, doc = option
-        longkeyed[longname] = option
-        config[longname] = default
-    for longname in presets.keys():        # presets after defaults but before arguments
-        config[longname] = presets[longname]
-    options = []
-    args = []
-    pos = 0
-    while pos < len(argv):
-        if argv[pos][:2] != '--':
-            args.append(argv[pos])
-            pos += 1
-        else:
-            if pos == len(argv) - 1:
-                usage('parameter passed in at end with no value')
-            key, value = argv[pos][2:], argv[pos+1]
-            pos += 2
-            if not longkeyed.has_key(key):
-                usage('unknown key --' + key)
-            longname, default, doc = longkeyed[key]
-            try:
-                t = type(config[longname])
-                if t is NoneType or t is StringType:
-                    config[longname] = value
-                elif t in (IntType, LongType):
-                    config[longname] = long(value)
-                elif t is FloatType:
-                    config[longname] = float(value)
-                else:
-                    assert 0
-            except ValueError, e:
-                usage('wrong format of --%s - %s' % (key, str(e)))
-    for key, value in config.items():
-        if value is None:
-            usage("Option --%s is required." % key)
-    if minargs is not None and len(args) < minargs:
-        usage("Must supply at least %d args." % minargs)
-    if maxargs is not None and len(args) > maxargs:
-        usage("Too many args - %d max." % maxargs)
-    return (config, args)
-
-def test_parseargs():
-    assert parseargs(('d', '--a', 'pq', 'e', '--b', '3', '--c', '4.5', 'f'), (('a', 'x', ''), ('b', 1, ''), ('c', 2.3, ''))) == ({'a': 'pq', 'b': 3, 'c': 4.5}, ['d', 'e', 'f'])
-    assert parseargs([], [('a', 'x', '')]) == ({'a': 'x'}, [])
-    assert parseargs(['--a', 'x', '--a', 'y'], [('a', '', '')]) == ({'a': 'y'}, [])
-    try:
-        parseargs([], [('a', 'x', '')])
-    except ValueError:
-        pass
-    try:
-        parseargs(['--a', 'x'], [])
-    except ValueError:
-        pass
-    try:
-        parseargs(['--a'], [('a', 'x', '')])
-    except ValueError:
-        pass
-    try:
-        parseargs([], [], 1, 2)
-    except ValueError:
-        pass
-    assert parseargs(['x'], [], 1, 2) == ({}, ['x'])
-    assert parseargs(['x', 'y'], [], 1, 2) == ({}, ['x', 'y'])
-    try:
-        parseargs(['x', 'y', 'z'], [], 1, 2)
-    except ValueError:
-        pass
-    try:
-        parseargs(['--a', '2.0'], [('a', 3, '')])
-    except ValueError:
-        pass
-    try:
-        parseargs(['--a', 'z'], [('a', 2.1, '')])
-    except ValueError:
-        pass
-
diff --git a/www/pages/torrent/client/parsedir.py b/www/pages/torrent/client/parsedir.py
deleted file mode 100644 (file)
index 51613ce..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-# Written by John Hoffman and Uoti Urpala
-# see LICENSE.txt for license information
-from bencode import bencode, bdecode
-from BT1.btformats import check_info
-from os.path import exists, isfile
-from sha import sha
-import sys, os
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-NOISY = False
-
-def _errfunc(x):
-    print ":: "+x
-
-def parsedir(directory, parsed, files, blocked,
-             exts = ['.torrent'], return_metainfo = False, errfunc = _errfunc):
-    if NOISY:
-        errfunc('checking dir')
-    dirs_to_check = [directory]
-    new_files = {}
-    new_blocked = {}
-    torrent_type = {}
-    while dirs_to_check:    # first, recurse directories and gather torrents
-        directory = dirs_to_check.pop()
-        newtorrents = False
-        for f in os.listdir(directory):
-            newtorrent = None
-            for ext in exts:
-                if f.endswith(ext):
-                    newtorrent = ext[1:]
-                    break
-            if newtorrent:
-                newtorrents = True
-                p = os.path.join(directory, f)
-                new_files[p] = [(os.path.getmtime(p), os.path.getsize(p)), 0]
-                torrent_type[p] = newtorrent
-        if not newtorrents:
-            for f in os.listdir(directory):
-                p = os.path.join(directory, f)
-                if os.path.isdir(p):
-                    dirs_to_check.append(p)
-
-    new_parsed = {}
-    to_add = []
-    added = {}
-    removed = {}
-    # files[path] = [(modification_time, size), hash], hash is 0 if the file
-    # has not been successfully parsed
-    for p,v in new_files.items():   # re-add old items and check for changes
-        oldval = files.get(p)
-        if not oldval:          # new file
-            to_add.append(p)
-            continue
-        h = oldval[1]
-        if oldval[0] == v[0]:   # file is unchanged from last parse
-            if h:
-                if blocked.has_key(p):  # parseable + blocked means duplicate
-                    to_add.append(p)    # other duplicate may have gone away
-                else:
-                    new_parsed[h] = parsed[h]
-                new_files[p] = oldval
-            else:
-                new_blocked[p] = 1  # same broken unparseable file
-            continue
-        if parsed.has_key(h) and not blocked.has_key(p):
-            if NOISY:
-                errfunc('removing '+p+' (will re-add)')
-            removed[h] = parsed[h]
-        to_add.append(p)
-
-    to_add.sort()
-    for p in to_add:                # then, parse new and changed torrents
-        new_file = new_files[p]
-        v,h = new_file
-        if new_parsed.has_key(h): # duplicate
-            if not blocked.has_key(p) or files[p][0] != v:
-                errfunc('**warning** '+
-                    p +' is a duplicate torrent for '+new_parsed[h]['path'])
-            new_blocked[p] = 1
-            continue
-                
-        if NOISY:
-            errfunc('adding '+p)
-        try:
-            ff = open(p, 'rb')
-            d = bdecode(ff.read())
-            check_info(d['info'])
-            h = sha(bencode(d['info'])).digest()
-            new_file[1] = h
-            if new_parsed.has_key(h):
-                errfunc('**warning** '+
-                    p +' is a duplicate torrent for '+new_parsed[h]['path'])
-                new_blocked[p] = 1
-                continue
-
-            a = {}
-            a['path'] = p
-            f = os.path.basename(p)
-            a['file'] = f
-            a['type'] = torrent_type[p]
-            i = d['info']
-            l = 0
-            nf = 0
-            if i.has_key('length'):
-                l = i.get('length',0)
-                nf = 1
-            elif i.has_key('files'):
-                for li in i['files']:
-                    nf += 1
-                    if li.has_key('length'):
-                        l += li['length']
-            a['numfiles'] = nf
-            a['length'] = l
-            a['name'] = i.get('name', f)
-            def setkey(k, d = d, a = a):
-                if d.has_key(k):
-                    a[k] = d[k]
-            setkey('failure reason')
-            setkey('warning message')
-            setkey('announce-list')
-            if return_metainfo:
-                a['metainfo'] = d
-        except:
-            errfunc('**warning** '+p+' has errors')
-            new_blocked[p] = 1
-            continue
-        try:
-            ff.close()
-        except:
-            pass
-        if NOISY:
-            errfunc('... successful')
-        new_parsed[h] = a
-        added[h] = a
-
-    for p,v in files.items():       # and finally, mark removed torrents
-        if not new_files.has_key(p) and not blocked.has_key(p):
-            if NOISY:
-                errfunc('removing '+p)
-            removed[v[1]] = parsed[v[1]]
-
-    if NOISY:
-        errfunc('done checking')
-    return (new_parsed, new_files, new_blocked, added, removed)
-
diff --git a/www/pages/torrent/client/piecebuffer.py b/www/pages/torrent/client/piecebuffer.py
deleted file mode 100644 (file)
index 96cc918..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-from array import array
-from threading import Lock
-# import inspect
-try:
-    True
-except:
-    True = 1
-    False = 0
-    
-DEBUG = False
-
-class SingleBuffer:
-    def __init__(self, pool):
-        self.pool = pool
-        self.buf = array('c')
-
-    def init(self):
-        if DEBUG:
-            print self.count
-            '''
-            for x in xrange(6,1,-1):
-                try:
-                    f = inspect.currentframe(x).f_code
-                    print (f.co_filename,f.co_firstlineno,f.co_name)
-                    del f
-                except:
-                    pass
-            print ''
-            '''
-        self.length = 0
-
-    def append(self, s):
-        l = self.length+len(s)
-        self.buf[self.length:l] = array('c',s)
-        self.length = l
-
-    def __len__(self):
-        return self.length
-
-    def __getslice__(self, a, b):
-        if b > self.length:
-            b = self.length
-        if b < 0:
-            b += self.length
-        if a == 0 and b == self.length and len(self.buf) == b:
-            return self.buf  # optimization
-        return self.buf[a:b]
-
-    def getarray(self):
-        return self.buf[:self.length]
-
-    def release(self):
-        if DEBUG:
-            print -self.count
-        self.pool.release(self)
-
-
-class BufferPool:
-    def __init__(self):
-        self.pool = []
-        self.lock = Lock()
-        if DEBUG:
-            self.count = 0
-
-    def new(self):
-        self.lock.acquire()
-        if self.pool:
-            x = self.pool.pop()
-        else:
-            x = SingleBuffer(self)
-            if DEBUG:
-                self.count += 1
-                x.count = self.count
-        x.init()
-        self.lock.release()
-        return x
-
-    def release(self, x):
-        self.pool.append(x)
-
-
-_pool = BufferPool()
-PieceBuffer = _pool.new
diff --git a/www/pages/torrent/client/selectpoll.py b/www/pages/torrent/client/selectpoll.py
deleted file mode 100644 (file)
index c9d694d..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-# Written by Bram Cohen
-# see LICENSE.txt for license information
-
-from select import select, error
-from time import sleep
-from types import IntType
-from bisect import bisect
-POLLIN = 1
-POLLOUT = 2
-POLLERR = 8
-POLLHUP = 16
-
-class poll:
-    def __init__(self):
-        self.rlist = []
-        self.wlist = []
-        
-    def register(self, f, t):
-        if type(f) != IntType:
-            f = f.fileno()
-        if (t & POLLIN):
-            insert(self.rlist, f)
-        else:
-            remove(self.rlist, f)
-        if (t & POLLOUT):
-            insert(self.wlist, f)
-        else:
-            remove(self.wlist, f)
-
-    def unregister(self, f):
-        if type(f) != IntType:
-            f = f.fileno()
-        remove(self.rlist, f)
-        remove(self.wlist, f)
-
-    def poll(self, timeout = None):
-        if self.rlist or self.wlist:
-            try:
-                r, w, e = select(self.rlist, self.wlist, [], timeout)
-            except ValueError:
-                return None
-        else:
-            sleep(timeout)
-            return []
-        result = []
-        for s in r:
-            result.append((s, POLLIN))
-        for s in w:
-            result.append((s, POLLOUT))
-        return result
-
-def remove(list, item):
-    i = bisect(list, item)
-    if i > 0 and list[i-1] == item:
-        del list[i-1]
-
-def insert(list, item):
-    i = bisect(list, item)
-    if i == 0 or list[i-1] != item:
-        list.insert(i, item)
-
-def test_remove():
-    x = [2, 4, 6]
-    remove(x, 2)
-    assert x == [4, 6]
-    x = [2, 4, 6]
-    remove(x, 4)
-    assert x == [2, 6]
-    x = [2, 4, 6]
-    remove(x, 6)
-    assert x == [2, 4]
-    x = [2, 4, 6]
-    remove(x, 5)
-    assert x == [2, 4, 6]
-    x = [2, 4, 6]
-    remove(x, 1)
-    assert x == [2, 4, 6]
-    x = [2, 4, 6]
-    remove(x, 7)
-    assert x == [2, 4, 6]
-    x = [2, 4, 6]
-    remove(x, 5)
-    assert x == [2, 4, 6]
-    x = []
-    remove(x, 3)
-    assert x == []
-
-def test_insert():
-    x = [2, 4]
-    insert(x, 1)
-    assert x == [1, 2, 4]
-    x = [2, 4]
-    insert(x, 3)
-    assert x == [2, 3, 4]
-    x = [2, 4]
-    insert(x, 5)
-    assert x == [2, 4, 5]
-    x = [2, 4]
-    insert(x, 2)
-    assert x == [2, 4]
-    x = [2, 4]
-    insert(x, 4)
-    assert x == [2, 4]
-    x = [2, 3, 4]
-    insert(x, 3)
-    assert x == [2, 3, 4]
-    x = []
-    insert(x, 3)
-    assert x == [3]
diff --git a/www/pages/torrent/client/subnetparse.py b/www/pages/torrent/client/subnetparse.py
deleted file mode 100644 (file)
index 55b46dc..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-from bisect import bisect, insort
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-    bool = lambda x: not not x
-
-hexbinmap = {
-    '0': '0000',
-    '1': '0001',
-    '2': '0010',
-    '3': '0011',
-    '4': '0100',
-    '5': '0101',
-    '6': '0110',
-    '7': '0111',
-    '8': '1000',
-    '9': '1001',
-    'a': '1010',
-    'b': '1011',
-    'c': '1100',
-    'd': '1101',
-    'e': '1110',
-    'f': '1111',
-    'x': '0000',
-}
-
-chrbinmap = {}
-for n in xrange(256):
-    b = []
-    nn = n
-    for i in xrange(8):
-        if nn & 0x80:
-            b.append('1')
-        else:
-            b.append('0')
-        nn <<= 1
-    chrbinmap[n] = ''.join(b)
-
-
-def to_bitfield_ipv4(ip):
-    ip = ip.split('.')
-    if len(ip) != 4:
-        raise ValueError, "bad address"
-    b = []
-    for i in ip:
-        b.append(chrbinmap[int(i)])
-    return ''.join(b)
-
-def to_bitfield_ipv6(ip):
-    b = ''
-    doublecolon = False
-
-    if ip == '':
-        raise ValueError, "bad address"
-    if ip == '::':      # boundary handling
-        ip = ''
-    elif ip[:2] == '::':
-        ip = ip[1:]
-    elif ip[0] == ':':
-        raise ValueError, "bad address"
-    elif ip[-2:] == '::':
-        ip = ip[:-1]
-    elif ip[-1] == ':':
-        raise ValueError, "bad address"
-    for n in ip.split(':'):
-        if n == '':     # double-colon
-            if doublecolon:
-                raise ValueError, "bad address"
-            doublecolon = True
-            b += ':'
-            continue
-        if n.find('.') >= 0: # IPv4
-            n = to_bitfield_ipv4(n)
-            b += n + '0'*(32-len(n))
-            continue
-        n = ('x'*(4-len(n))) + n
-        for i in n:
-            b += hexbinmap[i]
-    if doublecolon:
-        pos = b.find(':')
-        b = b[:pos]+('0'*(129-len(b)))+b[pos+1:]
-    if len(b) != 128:   # always check size
-        raise ValueError, "bad address"
-    return b
-
-ipv4addrmask = to_bitfield_ipv6('::ffff:0:0')[:96]
-
-class IP_List:
-    def __init__(self):
-        self.ipv4list = []
-        self.ipv6list = []
-
-    def __nonzero__(self):
-        return bool(self.ipv4list or self.ipv6list)
-
-
-    def append(self, ip, depth = 256):
-        if ip.find(':') < 0:        # IPv4
-            insort(self.ipv4list,to_bitfield_ipv4(ip)[:depth])
-        else:
-            b = to_bitfield_ipv6(ip)
-            if b.startswith(ipv4addrmask):
-                insort(self.ipv4list,b[96:][:depth-96])
-            else:
-                insort(self.ipv6list,b[:depth])
-
-
-    def includes(self, ip):
-        if not (self.ipv4list or self.ipv6list):
-            return False
-        if ip.find(':') < 0:        # IPv4
-            b = to_bitfield_ipv4(ip)
-        else:
-            b = to_bitfield_ipv6(ip)
-            if b.startswith(ipv4addrmask):
-                b = b[96:]
-        if len(b) > 32:
-            l = self.ipv6list
-        else:
-            l = self.ipv4list
-        for map in l[bisect(l,b)-1:]:
-            if b.startswith(map):
-                return True
-            if map > b:
-                return False
-        return False
-
-
-    def read_fieldlist(self, file):   # reads a list from a file in the format 'ip/len <whatever>'
-        f = open(file, 'r')
-        while True:
-            line = f.readline()
-            if not line:
-                break
-            line = line.strip().expandtabs()
-            if not line or line[0] == '#':
-                continue
-            try:
-                line, garbage = line.split(' ',1)
-            except:
-                pass
-            try:
-                line, garbage = line.split('#',1)
-            except:
-                pass
-            try:
-                ip, depth = line.split('/')
-            except:
-                ip = line
-                depth = None
-            try:
-                if depth is not None:                
-                    depth = int(depth)
-                self.append(ip,depth)
-            except:
-                print '*** WARNING *** could not parse IP range: '+line
-        f.close()
-
-
-    def set_intranet_addresses(self):
-        self.append('127.0.0.1',8)
-        self.append('10.0.0.0',8)
-        self.append('172.16.0.0',12)
-        self.append('192.168.0.0',16)
-        self.append('169.254.0.0',16)
-        self.append('::1')
-        self.append('fe80::',16)
-        self.append('fec0::',16)
-
-    def set_ipv4_addresses(self):
-        self.append('::ffff:0:0',96)
-
-def ipv6_to_ipv4(ip):
-    ip = to_bitfield_ipv6(ip)
-    if not ip.startswith(ipv4addrmask):
-        raise ValueError, "not convertible to IPv4"
-    ip = ip[-32:]
-    x = ''
-    for i in range(4):
-        x += str(int(ip[:8],2))
-        if i < 3:
-            x += '.'
-        ip = ip[8:]
-    return x
-
-def to_ipv4(ip):
-    if is_ipv4(ip):
-        _valid_ipv4(ip)
-        return ip
-    return ipv6_to_ipv4(ip)
-
-def is_ipv4(ip):
-    return ip.find(':') < 0
-
-def _valid_ipv4(ip):
-    ip = ip.split('.')
-    if len(ip) != 4:
-        raise ValueError
-    for i in ip:
-        chr(int(i))
-
-def is_valid_ip(ip):
-    try:
-        if not ip:
-            return False
-        if is_ipv4(ip):
-            _valid_ipv4(ip)
-            return True
-        to_bitfield_ipv6(ip)
-        return True
-    except:
-        return False
diff --git a/www/pages/torrent/client/torrentlistparse.py b/www/pages/torrent/client/torrentlistparse.py
deleted file mode 100644 (file)
index 5ed464b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-from binascii import unhexlify
-
-try:
-    True
-except:
-    True = 1
-    False = 0
-
-
-# parses a list of torrent hashes, in the format of one hash per line in hex format
-
-def parsetorrentlist(filename, parsed):
-    new_parsed = {}
-    added = {}
-    removed = parsed
-    f = open(filename, 'r')
-    while True:
-        l = f.readline()
-        if not l:
-            break
-        l = l.strip()
-        try:
-            if len(l) != 40:
-                raise ValueError, 'bad line'
-            h = unhexlify(l)
-        except:
-            print '*** WARNING *** could not parse line in torrent list: '+l
-        if parsed.has_key(h):
-            del removed[h]
-        else:
-            added[h] = True
-        new_parsed[h] = True
-    f.close()
-    return (new_parsed, added, removed)
-
diff --git a/www/pages/torrent/client/zurllib.py b/www/pages/torrent/client/zurllib.py
deleted file mode 100644 (file)
index 2af4032..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-# Written by John Hoffman
-# see LICENSE.txt for license information
-
-from httplib import HTTPConnection, HTTPSConnection, HTTPException
-from urlparse import urlparse
-from bencode import bdecode
-import socket
-from gzip import GzipFile
-from StringIO import StringIO
-from urllib import quote, unquote
-from __init__ import product_name, version_short
-
-VERSION = product_name+'/'+version_short
-MAX_REDIRECTS = 10
-
-
-class btHTTPcon(HTTPConnection): # attempt to add automatic connection timeout
-    def connect(self):
-        HTTPConnection.connect(self)
-        try:
-            self.sock.settimeout(30)
-        except:
-            pass
-
-class btHTTPScon(HTTPSConnection): # attempt to add automatic connection timeout
-    def connect(self):
-        HTTPSConnection.connect(self)
-        try:
-            self.sock.settimeout(30)
-        except:
-            pass 
-
-class urlopen:
-    def __init__(self, url):
-        self.tries = 0
-        self._open(url.strip())
-        self.error_return = None
-
-    def _open(self, url):
-        self.tries += 1
-        if self.tries > MAX_REDIRECTS:
-            raise IOError, ('http error', 500,
-                            "Internal Server Error: Redirect Recursion")
-        (scheme, netloc, path, pars, query, fragment) = urlparse(url)
-        if scheme != 'http' and scheme != 'https':
-            raise IOError, ('url error', 'unknown url type', scheme, url)
-        url = path
-        if pars:
-            url += ';'+pars
-        if query:
-            url += '?'+query
-#        if fragment:
-        try:
-            if scheme == 'http':
-                self.connection = btHTTPcon(netloc)
-            else:
-                self.connection = btHTTPScon(netloc)
-            self.connection.request('GET', url, None,
-                                { 'User-Agent': VERSION,
-                                  'Accept-Encoding': 'gzip' } )
-            self.response = self.connection.getresponse()
-        except HTTPException, e:
-            raise IOError, ('http error', str(e))
-        status = self.response.status
-        if status in (301,302):
-            try:
-                self.connection.close()
-            except:
-                pass
-            self._open(self.response.getheader('Location'))
-            return
-        if status != 200:
-            try:
-                data = self._read()
-                d = bdecode(data)
-                if d.has_key('failure reason'):
-                    self.error_return = data
-                    return
-            except:
-                pass
-            raise IOError, ('http error', status, self.response.reason)
-
-    def read(self):
-        if self.error_return:
-            return self.error_return
-        return self._read()
-
-    def _read(self):
-        data = self.response.read()
-        if self.response.getheader('Content-Encoding','').find('gzip') >= 0:
-            try:
-                compressed = StringIO(data)
-                f = GzipFile(fileobj = compressed)
-                data = f.read()
-            except:
-                raise IOError, ('http error', 'got corrupt response')
-        return data
-
-    def close(self):
-        self.connection.close()
diff --git a/www/pages/translate/__init__.py b/www/pages/translate/__init__.py
deleted file mode 100644 (file)
index 5c126b7..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/python
-
-import os
-
-import web
-import web.elements
-from web.javascript import Javascript
-
-BASE="/srv/checkout"
-
-projects = []
-
-class Po(object):
-       code2lang = {
-               "da" : "Dansk (Dansk)",
-               "de" : "Deutsch (German)",
-               "fr" : "Français (French)",
-       }
-
-       def __init__(self, path):
-               self.path = path
-               
-               p = os.popen("msgfmt -v --statistics %s 2>&1" % self.path)
-               self.line = p.readlines()[0]
-
-       def __cmp__(self, other):
-               return cmp(self.lang, other.lang)
-
-       @property
-       def code(self):
-               return os.path.basename(self.path)[:-3]
-
-       @property
-       def lang(self):
-               return self.code2lang.get(self.code, "Unknown (%s)" % self.code)
-
-       @property
-       def translated(self):
-               return int(self.line.split()[0])
-
-       @property
-       def untranslated(self):
-               l = self.line.split()
-               if len(l) == 6:
-                       return int(l[3])
-               elif len(l) == 9:
-                       return int(l[6])
-               return 0
-
-       @property
-       def fuzzy(self):
-               l = self.line.split()
-               if len(l) == 9:
-                       return l[3]
-               return 0
-
-
-class Project(object):
-       def __init__(self, id, path, **kwargs):
-               self.id = id
-               self.path = path
-               self._name = kwargs.pop("name")
-               self.desc = kwargs.pop("desc")
-
-               self._translations = []
-               self.pot = None
-               self.find_pot()
-
-       @property
-       def name(self):
-               if self._name:
-                       return self._name
-               return self.id
-
-       @property
-       def translations(self):
-               if not self._translations:
-                       for path in os.listdir(self.path):
-                               if path.endswith(".po"):
-                                       self._translations.append(Po(os.path.join(self.path, path)))
-               return self._translations
-
-       def find_pot(self):
-               for path in os.listdir(self.path):
-                       if path.endswith(".pot"):
-                               self.pot = Po(os.path.join(self.path, path))
-                               break
-
-
-projects.append(Project("pomona", BASE + "/ipfire-3.x/src/pomona/po", name="Pomona", desc="The pomona installer for ipfire."))
-
-class Content(web.Content):
-       def __init__(self):
-               web.Content.__init__(self)
-               self.projects = projects
-               
-       def __call__(self, lang):
-               ret = """<h3>IPFire Translation Status</h3>
-                                       <div id="tabs"><ul>"""
-               
-               for project in self.projects:
-                       ret += """<li><a href="#%s">%s</a></li>""" % (project.id, project.name)
-               
-               ret += "</ul>"
-               
-               for project in self.projects:
-                       ret += """<div id="%s">
-                               <p><strong>Description:</strong> %s</p>
-                               <br />
-                               <table class="translate">
-                                       <tr>
-                                               <th>Language</th>
-                                               <th>Translated</th>
-                                               <th>Untranslated</th>
-                                               <th>Fuzzy</th>
-                                               <th>Status</th>
-                                       </tr>""" % (project.id, project.desc)
-
-                       total = 0
-                       if project.pot:
-                               total = project.pot.untranslated
-
-                       for t in sorted(project.translations):
-                               if total:
-                                       percent = "%3.1f%%" % (t.translated * 100 / total)
-                               else:
-                                       percent = "---.-%"
-
-                               ret += """\
-                                       <tr>
-                                               <td class="lang"><img src="/images/flags/%s.png" alt="%s" />%s</td>
-                                               <td>%s</td>
-                                               <td>%s</td>
-                                               <td>%s</td>
-                                               <td>%s</td>
-                                       </tr>""" % \
-                                       (t.code, t.code, t.lang, t.translated, t.untranslated, t.fuzzy, percent)
-
-                       ret += "</table>"
-
-                       if project.pot:
-                               ret += """\
-                                       <p>
-                                               <br />
-                                               <strong>Template</strong> - %s strings
-                                       </p>""" % project.pot.untranslated
-
-                       ret += "</div>"
-
-               ret += "</div>"
-               return ret
-
-page = web.Page()
-page.content = Content()
-page.sidebar = web.elements.DevelopmentSidebar()
-page.javascript = Javascript(1, 1)
-page.javascript.write("""
-       <script type="text/javascript">
-               $(function() {
-                       $("#tabs").tabs();
-               });
-       </script>
-""")
diff --git a/www/releases.json b/www/releases.json
new file mode 100644 (file)
index 0000000..ba939f9
--- /dev/null
@@ -0,0 +1,109 @@
+[
+       { "name" : "IPFire 2.5 - Core 34",
+         "status"    : "stable",
+         "online"    : 1,
+         "files" : [
+               {
+                 "type" : "alix",
+                 "name" : "ipfire-2.5.1gb-ext2-scon.i586-full-core34.img.gz",
+                 "sha1" : "7f1fbea61842ff89197aede66da29a5e436543c3"
+               },
+               {
+                 "type" : "flash",
+                 "name" : "ipfire-2.5.1gb-ext2.i586-full-core34.img.gz",
+                 "sha1" : "26e60ee522b8a006f9c3e26e0077446d444cf27a"
+               },
+               {
+                 "type" : "iso",
+                 "name" : "ipfire-2.5.i586-full-core34.iso",
+                 "sha1" : "91ad4fb774bf14b4eb2e13c26caf066438b281aa"
+               },
+               {
+                 "type" : "torrent",
+                 "name" : "ipfire-2.5.i586-full-core34.iso.torrent",
+                 "hash" : "50DC8E935D63ACAC02E5A3C21477EE59D7F1A06D"
+               },
+               {
+                 "type" : "usbfdd",
+                 "name" : "ipfire-2.5-install-usb-fdd.i586-full-core34.img.gz",
+                 "sha1" : "a038d5af7e6e052f5df0199c729316e19ce202d1"
+               },
+               {
+                 "type" : "usbhdd",
+                 "name" : "ipfire-2.5-install-usb-hdd.i586-full-core34.img.gz",
+                 "sha1" : "5a53677b757fa5515ecb686ac4b22739e11da7c1"
+               },
+               {
+                 "type" : "xen",
+                 "name" : "ipfire-2.5.xen.i586-full-core34.tar.bz2",
+                 "sha1" : "05f062b1c0499a0d949127f7d048dda959feb9ac"
+               }
+         ]
+       },
+
+       { "name" : "IPFire 2.5 - Core 33",
+         "status"    : "stable",
+         "online"    : 1,
+         "files" : [
+               {
+                 "type" : "alix",
+                 "name" : "ipfire-2.5.1gb-ext2-scon.i586-full-core33.img.gz",
+                 "sha1" : "04e0634ce5e0445c77a8278e254ca7084f68e30a"
+               },
+               {
+                 "type" : "flash",
+                 "name" : "ipfire-2.5.1gb-ext2.i586-full-core33.img.gz",
+                 "sha1" : "1e3a8b0594fe92bb237bfabe10a8a10d687773f2"
+               },
+               {
+                 "type" : "iso",
+                 "name" : "ipfire-2.5.i586-full-core33.iso",
+                 "sha1" : "c60c7bbe625044e96790c4ee3a30eaffb89aa379"
+               },
+               {
+                 "type" : "torrent",
+                 "name" : "ipfire-2.5.i586-full-core33.iso.torrent",
+                 "hash" : "D9992ED673EC9D92774452962F4445993ECA730E"
+               },
+               {
+                 "type" : "usbfdd",
+                 "name" : "ipfire-2.5-install-usb-fdd.i586-full-core33.img.gz",
+                 "sha1" : "5e8888afb035881f07ef318fc75dda7a3ab16840"
+               },
+               {
+                 "type" : "usbhdd",
+                 "name" : "ipfire-2.5-install-usb-hdd.i586-full-core33.img.gz",
+                 "sha1" : "6b1e702d5cf2f317ff52371ecd7e68828b56f262"
+               },
+               {
+                 "type" : "xen",
+                 "name" : "ipfire-2.5.xen.i586-full-core33.tar.bz2",
+                 "sha1" : "04e0634ce5e0445c77a8278e254ca7084f68e30a"
+               }
+         ]
+       },
+
+       { "name" : "IPFire 3.0 alpha 1",
+         "status"    : "development",
+         "online"    : 1,
+         "files" : [
+               {
+                 "type" : "iso",
+                 "name" : "ipfire-3.0-alpha1.i686.iso",
+                 "sha1" : "e5d6c236a8997de8f1718f1c44f5a9d8f7d90af6"
+               }
+         ]
+       },
+
+       { "name" : "IPFire 1.4.9 - FINAL",
+         "status"    : "stable",
+         "online"    : 1,
+         "files" : [
+               {
+                 "type" : "iso",
+                 "name" : "IPFire-1.4.9-FINAL.iso",
+                 "sha1" : "ba40ca010f6c3069f110f6b7d99e3524bd81d367"
+               }
+         ]
+       }
+]
diff --git a/www/rpc.py b/www/rpc.py
deleted file mode 100644 (file)
index 407b228..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/python
-
-import cgi
-import simplejson as json
-
-from rpc_functions import *
-
-form = cgi.FieldStorage()
-method = form.getfirst("method")
-id     = form.getfirst("id")
-
-params = None
-param_string = form.getfirst("params")
-if param_string:
-       params = json.loads(param_string)
-
-methods = { "cluster_get_info" : cluster_get_info,
-                       "uriel_send_info"  : uriel_send_info, }
-
-if method and methods.has_key(method):
-       print json.dumps({ "version": "1.1",
-                                          "id": id or "null",
-                                          "result" : methods[method](params),
-                                          "error" : "null", },
-                                        sort_keys=True, indent=4)
diff --git a/www/rpc_functions.py b/www/rpc_functions.py
deleted file mode 100644 (file)
index 02f87f7..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/python
-
-import time
-
-import web.info
-
-info = web.info.Info()
-
-def cluster_get_info(params):
-       import web.cluster
-       cluster = web.cluster.Cluster(info["hosting"]["cluster"])
-       return cluster.json
-
-def uriel_send_info(params):
-       import web.urieldb
-       db = web.urieldb.Urieldb()
-       
-       id = None
-       items = {}
-       for (item, value) in params.items():
-               if item == "id":
-                       id = value
-               if item not in web.urieldb.allowed_items:
-                       continue
-               items[item] = value
-
-       # We need an id
-       if not id:
-               return
-
-       for item, value in items.items():
-               db.set(id, item, value)
-
-       # Save date of last modification
-       db.set(id, "date", "%s" % int(time.time()))
diff --git a/www/rss.inc b/www/rss.inc
deleted file mode 100644 (file)
index 3c899b5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<rss version="2.0">
-       <channel>
-               <title>IPFire.org - News</title>
-               <link>http://www.ipfire.org/</link>
-               <description>IPFire News Feed</description>
-               <language>%(lang)s</language>
-               <copyright>IPFire-Team</copyright>
-               <pubDate>Thu, 8 Nov 2007 00:00:00 +0200</pubDate>
-               %(content)s
-       </channel>
-</rss>
similarity index 100%
rename from www/include/ie6.css
rename to www/static/css/ie6.css
similarity index 79%
rename from www/include/style.css
rename to www/static/css/style.css
index 508f990665e9da4a2ac6714f406b4736b55a8e45..11f6fda399ba8353ee7947bbf0408e43fdaf2e70 100644 (file)
@@ -33,7 +33,7 @@ body
 {
   font-family: "Verdana", "Deja-Vu Sans", "Bitstream Vera Sans", sans-serif;
   font-size: 0.9em;
-  background: #880400; /* url(/images/bg.png) repeat;*/
+  background: #880400; /* url(../images/bg.png) repeat;*/
   color: #585858;
 }
 
@@ -131,13 +131,17 @@ p
 line-height: 1.5em;
 }
 
+p.right {
+       float: right;
+}
+
 /* Header */
 
 #header
 {
 width:100%;
 height:102px;
-background: url('/images/bg-menu99.png') repeat-x;
+background: url('../images/bg-menu99.png') repeat-x;
 }
 
 #header_inner
@@ -236,7 +240,7 @@ float: left;
 #menu li
 {
 vertical-align: middle;
-background: #333 url('/images/btn-break.png') center;
+background: #333 url('../images/btn-break.png') center;
 }
 #menu li a
 {
@@ -245,7 +249,7 @@ margin-right: 1px;
 display: block;
 padding: 10px 5px 0 8px;
 height: 26px;
-background: #333 url('/images/btn-empty.png') repeat-x center;
+background: #333 url('../images/btn-empty.png') repeat-x center;
 color: #ddd;
 font-weight: bolder;
 vertical-align: middle;
@@ -255,13 +259,13 @@ text-decoration: none;
 
 #menu li a.active
 {
-background: #CA2F2F url('/images/btn-red2.png') repeat-x center;
+background: #CA2F2F url('../images/btn-red2.png') repeat-x center;
 color: #ddd;
 }
 
 #menu li a:hover
 {
-background: #333 url('/images/btn-red2.png') repeat-x center;
+background: #333 url('../images/btn-red2.png') repeat-x center;
 color: #fff;
 }
 
@@ -269,7 +273,7 @@ color: #fff;
 
 #main
 {
-/* background: #fff url('images/n2.gif') 0px 1px repeat-x; */
+/* background: #fff url('../images/n2.gif') 0px 1px repeat-x; */
 }
 
 #main_inner p
@@ -366,12 +370,12 @@ padding-left: 15px;
 
 #main_inner .post ul.post_info li.date
 {
-background-image: url('images/n5.gif');
+background-image: url('../images/n5.gif');
 }
 
 #main_inner .post ul.post_info li.comments
 {
-background-image: url('images/n6.gif');
+background-image: url('../images/n6.gif');
 margin-left: 1.1em;
 }
 
@@ -390,28 +394,28 @@ table {
   font-size: 0.9em;
 }
 #sh-tl {
-  background: url(/images/sh-tl.png) no-repeat right bottom;
+  background: url("../images/sh-tl.png") no-repeat right bottom;
 }
 #sh-top {
-  background: url(/images/sh-top.png) repeat-x bottom;
+  background: url("../images/sh-top.png") repeat-x bottom;
 }
 #sh-tr {
-  background: url(/images/sh-tr.png) no-repeat left bottom;
+  background: url("../images/sh-tr.png") no-repeat left bottom;
 }
 #sh-lft {
-  background: url(/images/sh-lft.png) repeat-y right;
+  background: url("../images/sh-lft.png") repeat-y right;
 }
 #sh-rgt {
-  background: url(/images/sh-rgt.png) repeat-y left;
+  background: url("../images/sh-rgt.png") repeat-y left;
 }
 #sh-bl {
-  background: url(/images/sh-bl.png) no-repeat right top;
+  background: url("../images/sh-bl.png") no-repeat right top;
 }
 #sh-btn {
-  background: url(/images/sh-btn.png) repeat-x top;
+  background: url("../images/sh-btn.png") repeat-x top;
 }
 #sh-br {
-  background: url(/images/sh-br.png) no-repeat left top;
+  background: url("../images/sh-br.png") no-repeat left top;
 }
 #no-sh {
   background-color: #f5f5f5;
@@ -481,7 +485,7 @@ clear: both;
 height: 26px;
 color: #ddd;
 text-align: center;
-background: url(/images/ft.png) left top;
+background: url("../images/ft.png") left top;
 margin-top: 0em;
 margin-bottom: 0em;
 padding-top: 0.5em;
@@ -493,7 +497,7 @@ text-transform: lowercase;
 
 input.button
 {
-background: #CA2F2F url('images/n3.gif') repeat-x;
+background: #CA2F2F url("../images/n3.gif") repeat-x;
 color: #fff;
 border: solid 1px #A94B4B;
 font-weight: bold;
@@ -545,7 +549,7 @@ z-index: 50;
 
 .thumbnail span{ /*CSS for enlarged image*/
 position: absolute;
-background-color: lightyellow;
+background-color: #ffffe0; /*lightyellow;*/
 padding: 5px;
 left: -1000px;
 border: 1px dashed gray;
@@ -569,7 +573,7 @@ left: 60px; /*position where enlarged image should offset horizontally */
 .feed {
   margin-left: 3px;
   padding: 0 0 0 19px;
-  background: url("/images/feed.png") no-repeat 0 50%;
+  background: url("../images/feed.png") no-repeat 0 50%;
 }
 
 /* LAYOUT - 3 COLUMNS */
@@ -764,7 +768,7 @@ table.translate td.lang {
 /* Component containers */
 .ui-widget-content {
     border: 1px solid #999/*{borderColorContent}*/;
-       background: #F5F5F5/*{bgColorContent}*/ 50%/*{bgContentXPos}*/ url(/images/ui-bg_flat_75_f5f5f5_40x100.png)/*{bgImgUrlDefault}*/50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/;
+       background: #F5F5F5/*{bgColorContent}*/ 50%/*{bgContentXPos}*/ url(../images/ui-bg_flat_75_f5f5f5_40x100.png)/*{bgImgUrlDefault}*/50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/;
        color: #222222/*{fcContent}*/;
 }
 .ui-widget-content a {
@@ -772,7 +776,7 @@ table.translate td.lang {
 }
 .ui-widget-header {
        border: 1px solid #aaaaaa/*{borderColorHeader}*/;
-       background: #cccccc/*{bgColorHeader}*/ url(/images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/;
+       background: #cccccc/*{bgColorHeader}*/ url(/../images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/;
        color: #222222/*{fcHeader}*/;
        font-weight: bold;
 }
@@ -782,7 +786,7 @@ table.translate td.lang {
 /* Interaction states */
 .ui-state-default, .ui-widget-content .ui-state-default {
        border: 1px solid #d3d3d3/*{borderColorDefault}*/;
-       background: #e6e6e6/*{bgColorDefault}*/ url(/images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/;
+       background: #e6e6e6/*{bgColorDefault}*/ url(../images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/;
        font-weight: normal/*{fwDefault}*/;
        color: #555555/*{fcDefault}*/;
        outline: none;
@@ -794,7 +798,7 @@ table.translate td.lang {
 }
 .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus {
        border: 1px solid #999999/*{borderColorHover}*/;
-       background: #dadada/*{bgColorHover}*/ url(/images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/;
+       background: #dadada/*{bgColorHover}*/ url(../images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/;
        font-weight: normal/*{fwDefault}*/;
        color: #212121/*{fcHover}*/;
        outline: none;
@@ -963,7 +967,7 @@ table.translate td.lang {
 
 /* IPFire Download Button */
 .button {
-    background: url(/images/buttons/download_core_96x320.png);
+    background: url(../images/buttons/download_core_96x320.png);
     background-repeat: no-repeat;
     background-position: right;
     width: 700px;
@@ -985,7 +989,7 @@ table.translate td.lang {
 
 /* CeBIT Button */
 .cebit_button {
-    background: url(/images/buttons/cebit_96x320.png);
+    background: url(../images/buttons/cebit_96x320.png);
     background-repeat: no-repeat;
     background-position: right;
     width: 700px;
@@ -1002,5 +1006,108 @@ table.translate td.lang {
        color:#333; 
        font-size: 20px !important;
        text-shadow: #666 1px 2px 2px;
-    padding: 51px 0px 0px 472px;
+    padding: 51px 0px 0px 465px;
+}
+
+/* Public Relations linklists */
+.pr_li {
+    padding: 0px 0px 0px 20px;
+       line-height: 1.2em;  
+}
+
+div.bigdownload {
+       margin-top: 50px;
+       margin-left: 100px;
+       padding-top: 15px;
+       background: url(../images/download_button.png) no-repeat;
+       height: 84px;
+       width: 255px;
+       text-align: center;
+}
+
+div.bigdownload a {
+       color: white;
+       font-size: 1.3em;
+       font-weight: bold;
+       text-decoration: none;
+}
+
+div.bigdownload a:hover {
+       text-decoration: underline;
+}
+
+table.download {
+       width: 660px;
+       margin-left: 75px;
+}
+
+table.download td.icon {
+       width: 50px;
+}
+
+table.download td.link {
+       width: 180px;
+}
+
+table.download-torrents {
+       margin-bottom: 25px;
+       margin-left: 50px;
+       margin-top: 25px;
+       width: 600px;
+}
+
+table.download-torrents tr {
+       height: 24px;
+}
+
+table.download-torrents td {
+       text-align: center;
+}
+
+table.download-torrents th.seeds, th.peers, td.seeds, td.peers {
+       text-align: right;
+}
+
+table.download-torrents th.peers,td.peers {
+       padding-left: 5px;
+}
+
+table.download-mirrors {
+       margin-bottom: 25px;
+       margin-left: 15px;
+       margin-top: 25px;
+       width: 700px;
+}
+
+table.download-mirrors tr {
+       height: 32px;
+}
+
+table.download-mirrors tr.legend {
+       text-align: right;
+}
+
+table.download-mirrors td {
+       padding-left: 10px;
+       padding-right: 10px;
+}
+
+table.download-mirrors tr.unreachable, td.unreachable {
+       border: 1px solid #f55;
+       background-color: #f99;
+}
+
+table.download-mirrors tr.reachable, td.reachable {
+       border: 1px solid #5f5;
+       background-color: #9f9;
+}
+
+table.download-mirrors td.latency {
+       width: 70px;
+       text-align: right;
+}
+
+ul.sources li {
+       font-family: courier;
+       list-style-type: none;
 }
diff --git a/www/static/favicon.ico b/www/static/favicon.ico
new file mode 100644 (file)
index 0000000..565ba7b
Binary files /dev/null and b/www/static/favicon.ico differ
diff --git a/www/static/images/aktinet_logo.jpg b/www/static/images/aktinet_logo.jpg
new file mode 100644 (file)
index 0000000..2ff187f
Binary files /dev/null and b/www/static/images/aktinet_logo.jpg differ
similarity index 100%
rename from www/images/bg.png
rename to www/static/images/bg.png
similarity index 100%
rename from www/images/bg1.png
rename to www/static/images/bg1.png
diff --git a/www/static/images/bittorrent.png b/www/static/images/bittorrent.png
new file mode 100644 (file)
index 0000000..1d48dae
Binary files /dev/null and b/www/static/images/bittorrent.png differ
diff --git a/www/static/images/buttons/cebit_96x320.png b/www/static/images/buttons/cebit_96x320.png
new file mode 100644 (file)
index 0000000..89384d1
Binary files /dev/null and b/www/static/images/buttons/cebit_96x320.png differ
diff --git a/www/static/images/buttons/download_core_96x320.png b/www/static/images/buttons/download_core_96x320.png
new file mode 100644 (file)
index 0000000..49ecea8
Binary files /dev/null and b/www/static/images/buttons/download_core_96x320.png differ
similarity index 100%
rename from www/images/de.gif
rename to www/static/images/de.gif
diff --git a/www/static/images/download_button.png b/www/static/images/download_button.png
new file mode 100644 (file)
index 0000000..7971ec4
Binary files /dev/null and b/www/static/images/download_button.png differ
diff --git a/www/static/images/download_type_alix.png b/www/static/images/download_type_alix.png
new file mode 100644 (file)
index 0000000..4b0e05d
Binary files /dev/null and b/www/static/images/download_type_alix.png differ
diff --git a/www/static/images/download_type_flash.png b/www/static/images/download_type_flash.png
new file mode 100644 (file)
index 0000000..3337f71
Binary files /dev/null and b/www/static/images/download_type_flash.png differ
diff --git a/www/static/images/download_type_iso.png b/www/static/images/download_type_iso.png
new file mode 100644 (file)
index 0000000..f3e679c
Binary files /dev/null and b/www/static/images/download_type_iso.png differ
diff --git a/www/static/images/download_type_torrent.png b/www/static/images/download_type_torrent.png
new file mode 100644 (file)
index 0000000..a70def0
Binary files /dev/null and b/www/static/images/download_type_torrent.png differ
diff --git a/www/static/images/download_type_usbfdd.png b/www/static/images/download_type_usbfdd.png
new file mode 100644 (file)
index 0000000..32632c3
Binary files /dev/null and b/www/static/images/download_type_usbfdd.png differ
diff --git a/www/static/images/download_type_usbhdd.png b/www/static/images/download_type_usbhdd.png
new file mode 100644 (file)
index 0000000..196f8c7
Binary files /dev/null and b/www/static/images/download_type_usbhdd.png differ
diff --git a/www/static/images/download_type_xen.png b/www/static/images/download_type_xen.png
new file mode 100644 (file)
index 0000000..394a8ac
Binary files /dev/null and b/www/static/images/download_type_xen.png differ
similarity index 100%
rename from www/images/en.gif
rename to www/static/images/en.gif
similarity index 100%
rename from www/images/ft.png
rename to www/static/images/ft.png
diff --git a/www/static/images/ipfire_download.png b/www/static/images/ipfire_download.png
new file mode 100644 (file)
index 0000000..de645e6
Binary files /dev/null and b/www/static/images/ipfire_download.png differ
similarity index 100%
rename from www/images/lf1.png
rename to www/static/images/lf1.png
similarity index 100%
rename from www/images/lf2.png
rename to www/static/images/lf2.png
similarity index 100%
rename from www/images/lf3.png
rename to www/static/images/lf3.png
similarity index 100%
rename from www/images/n1.gif
rename to www/static/images/n1.gif
similarity index 100%
rename from www/images/n2.gif
rename to www/static/images/n2.gif
similarity index 100%
rename from www/images/n3.gif
rename to www/static/images/n3.gif
similarity index 100%
rename from www/images/n4.gif
rename to www/static/images/n4.gif
similarity index 100%
rename from www/images/n5.gif
rename to www/static/images/n5.gif
similarity index 100%
rename from www/images/n6.gif
rename to www/static/images/n6.gif
diff --git a/www/static/images/page_icons/development.png b/www/static/images/page_icons/development.png
new file mode 100644 (file)
index 0000000..5417ad1
Binary files /dev/null and b/www/static/images/page_icons/development.png differ
diff --git a/www/static/images/page_icons/donation.png b/www/static/images/page_icons/donation.png
new file mode 100644 (file)
index 0000000..5f7717c
Binary files /dev/null and b/www/static/images/page_icons/donation.png differ
diff --git a/www/static/images/page_icons/download-all.png b/www/static/images/page_icons/download-all.png
new file mode 100644 (file)
index 0000000..496a6f7
Binary files /dev/null and b/www/static/images/page_icons/download-all.png differ
diff --git a/www/static/images/page_icons/download-developmemt.png b/www/static/images/page_icons/download-developmemt.png
new file mode 100644 (file)
index 0000000..cb58eae
Binary files /dev/null and b/www/static/images/page_icons/download-developmemt.png differ
diff --git a/www/static/images/page_icons/download-mirrors.png b/www/static/images/page_icons/download-mirrors.png
new file mode 100644 (file)
index 0000000..39fc17f
Binary files /dev/null and b/www/static/images/page_icons/download-mirrors.png differ
diff --git a/www/static/images/page_icons/download-mirrors_16.png b/www/static/images/page_icons/download-mirrors_16.png
new file mode 100644 (file)
index 0000000..7055ddc
Binary files /dev/null and b/www/static/images/page_icons/download-mirrors_16.png differ
diff --git a/www/static/images/page_icons/download-torrents.png b/www/static/images/page_icons/download-torrents.png
new file mode 100644 (file)
index 0000000..885e20f
Binary files /dev/null and b/www/static/images/page_icons/download-torrents.png differ
diff --git a/www/static/images/page_icons/download-torrents_orginal.png b/www/static/images/page_icons/download-torrents_orginal.png
new file mode 100644 (file)
index 0000000..88a18db
Binary files /dev/null and b/www/static/images/page_icons/download-torrents_orginal.png differ
diff --git a/www/static/images/page_icons/downloads_torrents.png b/www/static/images/page_icons/downloads_torrents.png
new file mode 100644 (file)
index 0000000..65315ee
Binary files /dev/null and b/www/static/images/page_icons/downloads_torrents.png differ
diff --git a/www/static/images/page_icons/imprint.png b/www/static/images/page_icons/imprint.png
new file mode 100644 (file)
index 0000000..09e078f
Binary files /dev/null and b/www/static/images/page_icons/imprint.png differ
diff --git a/www/static/images/page_icons/news.png b/www/static/images/page_icons/news.png
new file mode 100644 (file)
index 0000000..f6a539e
Binary files /dev/null and b/www/static/images/page_icons/news.png differ
diff --git a/www/static/images/page_icons/pr.png b/www/static/images/page_icons/pr.png
new file mode 100644 (file)
index 0000000..2608d27
Binary files /dev/null and b/www/static/images/page_icons/pr.png differ
diff --git a/www/static/images/page_icons/screenshots.png b/www/static/images/page_icons/screenshots.png
new file mode 100644 (file)
index 0000000..054929d
Binary files /dev/null and b/www/static/images/page_icons/screenshots.png differ
diff --git a/www/static/images/page_icons/screenshots_orginal.png b/www/static/images/page_icons/screenshots_orginal.png
new file mode 100644 (file)
index 0000000..c5b0b46
Binary files /dev/null and b/www/static/images/page_icons/screenshots_orginal.png differ
similarity index 100%
rename from www/images/pic.gif
rename to www/static/images/pic.gif
similarity index 100%
rename from www/images/pxe.png
rename to www/static/images/pxe.png
similarity index 100%
rename from www/images/tux.png
rename to www/static/images/tux.png
diff --git a/www/static/images/tux/ipfire_tux_128x128.png b/www/static/images/tux/ipfire_tux_128x128.png
new file mode 100644 (file)
index 0000000..eb7819e
Binary files /dev/null and b/www/static/images/tux/ipfire_tux_128x128.png differ
diff --git a/www/static/images/tux/ipfire_tux_16x16.png b/www/static/images/tux/ipfire_tux_16x16.png
new file mode 100644 (file)
index 0000000..0aa4f60
Binary files /dev/null and b/www/static/images/tux/ipfire_tux_16x16.png differ
diff --git a/www/static/images/tux/ipfire_tux_256x256.png b/www/static/images/tux/ipfire_tux_256x256.png
new file mode 100644 (file)
index 0000000..b0d6a6f
Binary files /dev/null and b/www/static/images/tux/ipfire_tux_256x256.png differ
diff --git a/www/static/images/tux/ipfire_tux_32x32.png b/www/static/images/tux/ipfire_tux_32x32.png
new file mode 100644 (file)
index 0000000..e632f9f
Binary files /dev/null and b/www/static/images/tux/ipfire_tux_32x32.png differ
diff --git a/www/static/images/tux/ipfire_tux_48x48.png b/www/static/images/tux/ipfire_tux_48x48.png
new file mode 100644 (file)
index 0000000..264c544
Binary files /dev/null and b/www/static/images/tux/ipfire_tux_48x48.png differ
diff --git a/www/static/images/tux/ipfire_tux_512x512.png b/www/static/images/tux/ipfire_tux_512x512.png
new file mode 100644 (file)
index 0000000..ec2bab2
Binary files /dev/null and b/www/static/images/tux/ipfire_tux_512x512.png differ
diff --git a/www/static/images/tux/ipfire_tux_64x64.png b/www/static/images/tux/ipfire_tux_64x64.png
new file mode 100644 (file)
index 0000000..cd84ad5
Binary files /dev/null and b/www/static/images/tux/ipfire_tux_64x64.png differ
diff --git a/www/static/images/tux_menu_99x100.png b/www/static/images/tux_menu_99x100.png
new file mode 100644 (file)
index 0000000..d6acb5c
Binary files /dev/null and b/www/static/images/tux_menu_99x100.png differ
diff --git a/www/static/js/cluster.js b/www/static/js/cluster.js
new file mode 100644 (file)
index 0000000..8aaee75
--- /dev/null
@@ -0,0 +1,65 @@
+nodes = new Array();
+id = 0;
+busy = false;
+
+update = function() {
+       $.getJSON("/api/cluster_info", { id : id++ },
+               function(data) {
+                       // If we are already busy then exit
+                       if (busy == true) return;
+
+                       var count = 0;
+
+                       if (data.error != "null") return;
+                       
+                       busy = true;
+
+                       $.each(data.result.nodes, function(i, node) {
+                               var nodeid = node.hostname.replace(/\./g, "");
+                               count++;
+
+                               nodes[nodeid] = true;
+
+                               if ($("#" + nodeid).length) {
+                                       $("#" + nodeid + "_speed").html(node.speed);
+                               } else {
+                                       row  = "<tr id=\"" + nodeid + "\" class=\"node\">";
+                                       row += "  <td id=\"" + nodeid + "_hostname\"></td>";
+                                       row += "  <td id=\"" + nodeid + "_arch\">" + node.arch + "</td>";
+                                       row += "  <td><span id=\"" + nodeid + "_loadbar\"></span></td>";
+                                       row += "  <td><span id=\"" + nodeid + "_jobs\"></span></td>";
+                                       row += "  <td id=\"" + nodeid + "_speed\">" + node.speed + "</td>";
+                                       row += "</tr>";
+                                       $("#nodes").append(row);
+                               }
+                               $("#" + nodeid + "_loadbar").progressBar(node.load, {showText: false});
+                               $("#" + nodeid + "_jobs").progressBar(node.jobcount.split("/")[0], { max: node.jobcount.split("/")[1], textFormat: 'fraction'});
+                               if (node.installing == true) {
+                                       $("#" + nodeid + "_hostname").html(node.hostname + " *");
+                               } else {
+                                       $("#" + nodeid + "_hostname").html(node.hostname);
+                               }
+                       });
+
+                       $("#loadbar").progressBar(data.result.cluster.load);
+                       $("#jobbar").progressBar(data.result.cluster.jobcount.split("/")[0], { max: data.result.cluster.jobcount.split("/")[1], textFormat: 'fraction'});
+                       for (var nodeid in nodes) {
+                               if (nodes[nodeid] == false) {
+                                       $("#" + nodeid).remove();
+                                       nodes.pop(nodeid);
+                               } else {
+                                       nodes[nodeid] = false;
+                               }
+                       }
+                       $("#count").html(count);
+                       busy = false;
+       });
+}
+
+$(document).ready(function(){
+       // Init loadbar
+       $("#loadbar").progressBar();
+
+       update();
+       setInterval("update()", 2000);
+})
similarity index 94%
rename from www/include/jquery.lightbox.min.js
rename to www/static/js/jquery.lightbox.min.js
index ad15574fb5d276be558195bbcd753bcef8896943..8b4a4ac58e6318a6080554410691f620f8a0bead 100644 (file)
@@ -11,7 +11,7 @@
  * @license CC Attribution-No Derivative Works 2.5 Brazil - http://creativecommons.org/licenses/by-nd/2.5/br/deed.en_US
  * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin
  */
-(function($){$.fn.lightBox=function(settings){settings=jQuery.extend({overlayBgColor:'#000',overlayOpacity:0.8,fixedNavigation:false,imageLoading:'/images/lightbox/lightbox-ico-loading.gif',imageBtnPrev:'/images/lightbox/lightbox-btn-prev.gif',imageBtnNext:'/images/lightbox/lightbox-btn-next.gif',imageBtnClose:'/images/lightbox/lightbox-btn-close.gif',imageBlank:'/images/lightbox/lightbox-blank.gif',containerBorderSize:10,containerResizeSpeed:400,txtImage:'Image',txtOf:'of',keyToClose:'c',keyToPrev:'p',keyToNext:'n',imageArray:[],activeImage:0},settings);var jQueryMatchedObj=this;function _initialize(){_start(this,jQueryMatchedObj);return false;}
+(function($){$.fn.lightBox=function(settings){settings=jQuery.extend({overlayBgColor:'#000',overlayOpacity:0.8,fixedNavigation:false,imageLoading:'/static/images/lightbox/lightbox-ico-loading.gif',imageBtnPrev:'/static/images/lightbox/lightbox-btn-prev.gif',imageBtnNext:'/static/images/lightbox/lightbox-btn-next.gif',imageBtnClose:'/static/images/lightbox/lightbox-btn-close.gif',imageBlank:'/static/images/lightbox/lightbox-blank.gif',containerBorderSize:10,containerResizeSpeed:400,txtImage:'Image',txtOf:'of',keyToClose:'c',keyToPrev:'p',keyToNext:'n',imageArray:[],activeImage:0},settings);var jQueryMatchedObj=this;function _initialize(){_start(this,jQueryMatchedObj);return false;}
 function _start(objClicked,jQueryMatchedObj){$('embed, object, select').css({'visibility':'hidden'});_set_interface();settings.imageArray.length=0;settings.activeImage=0;if(jQueryMatchedObj.length==1){settings.imageArray.push(new Array(objClicked.getAttribute('href'),objClicked.getAttribute('title')));}else{for(var i=0;i<jQueryMatchedObj.length;i++){settings.imageArray.push(new Array(jQueryMatchedObj[i].getAttribute('href'),jQueryMatchedObj[i].getAttribute('title')));}}
 while(settings.imageArray[settings.activeImage][0]!=objClicked.getAttribute('href')){settings.activeImage++;}
 _set_image_to_view();}
similarity index 87%
rename from www/include/jquery.progressbar.min.js
rename to www/static/js/jquery.progressbar.js
index af1b87bfa89c0770ba424930dc21c50fc46cb696..54229d2179854c06cd76fda36e61b18156abdc00 100644 (file)
@@ -1,5 +1,5 @@
 
-(function($){$.extend({progressBar:new function(){this.defaults={steps:20,step_duration:20,max:100,showText:true,textFormat:'percentage',width:120,height:12,callback:null,boxImage:'/images/progressbar.gif',barImage:{0:'/images/progressbg_green.gif',30:'/images/progressbg_orange.gif',70:'/images/progressbg_red.gif'},running_value:0,value:0,image:null};this.construct=function(arg1,arg2){var argvalue=null;var argconfig=null;if(arg1!=null){if(!isNaN(arg1)){argvalue=arg1;if(arg2!=null){argconfig=arg2;}}else{argconfig=arg1;}}
+(function($){$.extend({progressBar:new function(){this.defaults={steps:20,step_duration:20,max:100,showText:true,textFormat:'percentage',width:120,height:12,callback:null,boxImage:'/static/images/progressbar.gif',barImage:{0:'/static/images/progressbg_green.gif',30:'/static/images/progressbg_orange.gif',70:'/static/images/progressbg_red.gif'},running_value:0,value:0,image:null};this.construct=function(arg1,arg2){var argvalue=null;var argconfig=null;if(arg1!=null){if(!isNaN(arg1)){argvalue=arg1;if(arg2!=null){argconfig=arg2;}}else{argconfig=arg1;}}
 return this.each(function(child){var pb=this;var config=this.config;if(argvalue!=null&&this.bar!=null&&this.config!=null){this.config.value=argvalue
 if(argconfig!=null)
 pb.config=$.extend(this.config,argconfig);config=pb.config;}else{var $this=$(this);var config=$.extend({},$.progressBar.defaults,argconfig);config.id=$this.attr('id')?$this.attr('id'):Math.ceil(Math.random()*100000);if(argvalue==null)
similarity index 55%
rename from www/template.inc
rename to www/templates/base.html
index 96684ac4905721f623ad24a9bce52c74d12edc04..e02eee52ed90c8e5a345fc07bd8ce9b4f2a322f2 100644 (file)
@@ -4,35 +4,44 @@
        <head>
                <meta http-equiv="content-type" content="text/html; charset=utf-8" />
                <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
-               <title>%(title)s</title>
+               <title>{% block title %}{{ title }}{% end block %}</title>
                <meta name="keywords" content="Linux, Firewall, IPFire, Security" />
                <meta name="description" content="" />
                <meta name="verify-v1" content="2LEf3W8naILGWVy2dhedSVEHPXTpp2xFNVsHXZMH1JI=" />
-               <link rel="stylesheet" type="text/css" href="/include/style.css" />
-               <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.ipfire.org/%(lang)s/news.rss" />
-       <!--[if lt IE 7]>
-               <link rel="stylesheet" type="text/css" href="/include/ie6.css" />
-               <script src="/include/correctpng.js" type="text/javascript"></script>
-       <![endif]-->
-               %(javascript)s
+               <link rel="stylesheet" type="text/css" href="{{ static_url("css/style.css") }}" />
+               <script type="text/javascript" src="{{ static_url("js/jquery.js") }}"></script>
+               <script type="text/javascript" src="{{ static_url("js/jquery-ui.js") }}"></script>
+               <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.ipfire.org/{{ lang }}/news.rss" />
+               <!--[if lt IE 7]>
+                       <link rel="stylesheet" type="text/css" href="{{ static_url("css/ie6.css") }}" />
+                       <script src="{{ static_url("js/correctpng.js") }}" type="text/javascript"></script>
+               <![endif]-->
        </head>
        <body>
                <div id="header">
                        <div id="header_inner" class="fixed">
                                <div id="logo">
-                                       <a href="/" accesskey="h" title="[ALT+H]"><img src="/images/tux_menu_99x100.png" width="100px" height="99px" class="symbol" alt="IPFire" /></a>
+                                       <a href="{{ link("") }}">
+                                               <img src="{{ static_url("images/tux_menu_99x100.png") }}" class="symbol" alt="IPFire" />
+                                       </a>
                                </div>
                                <div id="line1">
-                                       %(menu)s
+                                       {% block menu %}
+                                               {{ modules.Menu() }}
+                                       {% end block %}
                                        <div id="lang">
-                                               %(languages)s
+                                               {% block languages %}
+                                                       {% for lng in langs %}
+                                                               <a href="{{ lang_link(lng) }}"><img src="{{ static_url("images/%s.gif" % lng) }}" alt="{{ lng }}" /></a>
+                                                       {% end %}
+                                               {% end block %}
                                        </div>
                                </div>
                                <div id="line2">
-                                       <h1>%(server)s</h1>
+                                       <h1>{{ server }}</h1>
                                </div>
                                <div id="line3">
-                                       <h2>%(slogan)s</h2>
+                                       <h2>{{ _("Security gone easy!") }}</h2>
                                </div>
                                
                        </div>
                                                <td id="no-sh">
                                                        <div id="primaryContent_2columns">
                                                                <div id="columnA_2columns">
-                                                                       %(content)s
+                                                                       {% block content %}
+                                                                       {% end block %}
                                                                        <br class="clear" />
                                                                </div>
                                                        </div>
                                                        <div id="secondaryContent_2columns">
                                                                <div id="columnC_2columns">
-                                                                       %(sidebar)s
+                                                                       {% block sidebar %}
+                                                                               {{ modules.SidebarBanner(banner) }}
+                                                                       {% end block %}
                                                                        <br class="clear" />
                                                                </div>
                                                        </div>
@@ -67,7 +79,7 @@
                                        <tr>
                                                <td id="sh-lft"></td>
                                                <td id="footer" class="fixed2">
-                                                       Copyright &copy; %(year)s IPFire.org. All rights reserved. <a href="/%(lang)s/imprint">Imprint</a>
+                                                       Copyright &copy; {{ year }} IPFire.org. All rights reserved. <a href="{{ link("imprint") }}">{{ _("imprint") }}</a>
                                                </td>
                                                <td id="sh-rgt"></td>
                                        </tr>
@@ -80,5 +92,6 @@
                                </table>
                        </div>
                </div>
+       {% block javascript %}{% end block %}
        </body>
 </html>
diff --git a/www/templates/builds.html b/www/templates/builds.html
new file mode 100644 (file)
index 0000000..d3934c3
--- /dev/null
@@ -0,0 +1,44 @@
+{% extends "base.html" %}
+
+{% block title %}{{ _("Builds") }}{% end block %}
+
+{% block content %}
+       <h3>{{ _("Nightly builds") }}</h3>
+
+       <table id="builds">
+               <tbody>
+                       {% if builds["<12h"] %}
+                               <tr class="headline">
+                                       <td colspan="3">
+                                               {{ _("Less than 12 hours ago") }}
+                                       </td>
+                               </tr>
+                               {% for build in builds["<12h"] %}
+                                       {{ modules.Build(build) }}
+                               {% end %}
+                       {% end %}
+                       
+                       {% if builds[">12h"] %}
+                               <tr class="headline">
+                                       <td colspan="3">
+                                               {{ _("More than 12 hours ago") }}
+                                       </td>
+                               </tr>
+                               {% for build in builds[">12h"] %}
+                                       {{ modules.Build(build) }}
+                               {% end %}
+                       {% end %}
+                       
+                       {% if builds[">24h"] %}
+                               <tr class="headline">
+                                       <td colspan="3">
+                                               {{ _("More than a day ago") }}
+                                       </td>
+                               </tr>
+                               {% for build in builds[">24h"] %}
+                                       {{ modules.Build(build) }}
+                               {% end %}
+                       {% end %}
+               </tbody>
+       </table>
+{% end block %}
diff --git a/www/templates/downloads-all.html b/www/templates/downloads-all.html
new file mode 100644 (file)
index 0000000..257e404
--- /dev/null
@@ -0,0 +1,23 @@
+{% extends "base.html" %}
+
+{% block content %}
+       <div class="post">
+               <h3>{{ _("Download IPFire") }}</h3>
+               <img src="{{ static_url("images/page_icons/download-all.png") }}" class="floatTR" border="0" alt="{{ _("Download IPFire") }}" />
+               <p>
+                       {{ _("These are the ancient downloads of IPFire. They are just saved for historical reasons and should not be used in a productive environment.") }}
+               </p>
+               
+               <p>
+                       <a href="{{ link("downloads") }}">{{ _("Get back to latest stable downloads.") }}</a>
+               </p>
+
+               <br class="clear" />
+       </div>
+       
+       {% for release in releases.stable %}
+               {% if not release == releases.latest %}
+                       {{ modules.ReleaseItem(release) }}
+               {% end %}
+       {% end %}
+{% end block %}
diff --git a/www/templates/downloads-development.html b/www/templates/downloads-development.html
new file mode 100644 (file)
index 0000000..2ae3ae3
--- /dev/null
@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+
+{% block content %}
+       <div class="post">
+               <h3>{{ _("Development Downloads") }}</h3>
+               <img src="{{ static_url("images/page_icons/download-developmemt.png") }}"
+                       class="floatTR" border="0" alt="{{ _("Development Downloads") }}" />
+               
+               {% if lang == "de" %}
+                       <p>
+                               In regelmäßigen Abständen wird aus dem aktuellen Quellcode der
+                               Entwicklungsversion ein installationsfähiges Image als
+                               technologische Vorschau erstellt.<br />
+                               Diese Versionen dienen dazu einen stabilen Stand einer größeren
+                               Menge an Testern zukommen zu lassen und sind <strong>nicht</strong>
+                               für den Produktiveinsatz bestimmt.
+                       </p>
+        {% else %}
+               <p>
+                       The developers do create a snapshort version from the current 
+                               development sources to get this distributed to a higher number
+                               of testers.<br />
+                               These versions are <strong>not</strong> intended to be used in a
+                               productive environment.
+               {% end %}               
+
+               <p>
+                       <a href="{{ link("downloads") }}">{{ _("Get back to latest stable downloads.") }}</a>
+               </p>
+       </div>
+
+       {% for release in releases.development %}
+               {{ modules.ReleaseItem(release) }}
+       {% end %}
+{% end block %}
diff --git a/www/templates/downloads-mirrors.html b/www/templates/downloads-mirrors.html
new file mode 100644 (file)
index 0000000..46a2a20
--- /dev/null
@@ -0,0 +1,77 @@
+{% extends "base.html" %}
+
+{% block content %}
+       <div class="post">
+               <a name="latest"></a>
+               <h3>{{ _("IPFire Mirrors") }}</h3>
+               <img src="{{ static_url("images/page_icons/download-mirrors.png") }}" class="floatTR" border="0" alt="{{ _("IPFire Torrent Tracker") }}" />
+               
+               {% if lang == "de" %}
+                       <p>
+                               Diese Seite zeigt eine Liste der Mirror-Server des IPFire-Projektes.
+                       </p>
+
+                       <p>
+                               Bei einem Download wird einer der Server zufällig aus der Liste
+                               gewählt und der User umgeleitet.
+                       </p>
+                       
+                       <ul>
+                               <li>
+                                       <a href="http://wiki.ipfire.org/{{ lang }}/project/web"
+                                               target="_blank">Wie stelle ich selbst einen Mirror-Server bereit?</a>
+                               </li>
+                       </ul>
+               {% else %}
+                       <p>
+                               This page is an overview about our mirror servers.
+                       </p>
+
+                       <p>
+                               When a user downloads a file, one of the servers is arbitrarily
+                               choosen und the user gets reditected.
+                       </p>
+                       
+                       <ul>
+                               <li>
+                                       <a href="http://wiki.ipfire.org/{{ lang }}/project/web"
+                                               target="_blank">How do I contribute a mirror server?</a>
+                               </li>
+                       </ul>
+               {% end %}
+               <br class="clear" />
+               
+               <table class="download-mirrors">
+                       <tr>
+                               <th>{{ _("Owner (Hostname)") }}</th>
+                               <th>{{ _("Location") }}</th>
+                               <th>{{ _("Latency") }}</th>
+                       </tr>
+                       {% for mirror in mirrors.all %}
+                               <tr class="{% if not mirror.reachable %}un{% end %}reachable">
+                                       <td>{{ mirror.name }} ({{ mirror.hostname }})</td>
+                                       <td>
+                                               <img src="{{ static_url("images/flags/%s.png" % mirror.location["country_code"]) }}"
+                                                        align="absmiddle" alt="{{ mirror.location["country_code"] }}" />
+                                               {{ mirror.location["country"] }}, {{ mirror.location["city"] }}
+                                       </td>
+                                       <td class="latency">{{ mirror.latency }} ms</td>
+                               </tr>
+                       {% end %}
+                       <tr class="legend">
+                               <td colspan="3">&nbsp;</td>
+                       </tr>
+                       <tr class="legend">
+                               <td><strong>{{ _("Legend") }}:</strong></td>
+                               <td colspan="2" class="reachable">{{ _("Server is reachable") }}</td>
+                       </tr>
+                       <tr class="legend">
+                               <td>&nbsp;</td>
+                               <td colspan="2" class="unreachable">{{ _("Server is unreachable") }}</td>
+                       </tr>
+               </table>
+
+               <br class="clear" />
+       </div>
+
+{% end block %}
diff --git a/www/templates/downloads-torrents.html b/www/templates/downloads-torrents.html
new file mode 100644 (file)
index 0000000..b0ad9c8
--- /dev/null
@@ -0,0 +1,73 @@
+{% extends "base.html" %}
+
+{% block content %}
+       <div class="post">
+               <a name="latest"></a>
+               <h3>{{ _("IPFire Torrent Tracker") }}</h3>
+
+               <img src="{{ static_url("images/page_icons/download-torrents.png") }}"
+                       class="floatTR" border="0" alt="{{ _("IPFire Torrent Tracker") }}" />
+
+               {% if lang == "de" %}
+                       <p>
+                               Auf dieser Seite findet man eine Liste fast aller Dateien, die
+                               Ã¼ber den IPFire-Torrent-Tracker verteilt werden.
+                       <p>
+                       <p>
+                               Das Torrentnetz ist ein Netzwerk, welches Dateien durch verteilte
+                               Downloads schnell verbreitet. IPFire nutzt dieses System um
+                               Downloads der Distributionsimages bereitzustellen.
+                       </p>
+                       <p>
+                               Mehr Informationen zu Torrent-Netzwerken gibt es in der
+                               <a href="http://de.wikipedia.org/wiki/BitTorrent"
+                               target="_blank">Wikipedia</a>.
+                       </p>
+               {% else %}
+                       <p>
+                               This page displays a list of files that are tracked by the
+                               IPFire torrent tracker.
+                       <p>
+                       <p>
+                               The bittorrent protocol transfers large files by a distributed
+                               technology. IPFire uses this system to spread the distribution's
+                               files.
+                       </p>
+                       <p>
+                               Get more information on the bittorrent protocol on
+                               <a href="http://en.wikipedia.org/wiki/BitTorrent_(protocol)"
+                               target="_blank">Wikipedia</a>.
+                       </p>
+               {% end %}
+               
+                               <br class="clear" />
+
+               
+               <table class="download-torrents">
+                       <tr>
+                               <th>{{ _("Release") }}</th>
+                               <th>{{ _("File") }}</th>
+                               <th class="seeds">S</th>
+                               <th class="peers">P</th>
+                               <th>&nbsp;</th>
+                       </tr>
+                       {% for release in releases %}
+                               <tr>
+                                       <td>{{ release.name }}</td>
+                                       <td>{{ release.torrent.file[:-8] }}</td>
+                                       <td class="seeds">{{ hashes[release.torrent.hash]["seeds"] }}</td>
+                                       <td class="peers">{{ hashes[release.torrent.hash]["peers"] }}</td>
+                                       <td class="download">
+                                               <a href="{{ release.torrent.url }}">{{ _("Download file") }}</a>
+                                       </td>
+                               </tr>
+                       {% end %}
+               </table>
+               
+               <p class="right">
+                       {{ _("Got that information from <em>%s</em> within %.2f second(s).") % (tracker, request_time) }}
+               </p>
+
+               <br class="clear" />
+       </div>
+{% end block %}
diff --git a/www/templates/downloads.html b/www/templates/downloads.html
new file mode 100644 (file)
index 0000000..42a7608
--- /dev/null
@@ -0,0 +1,89 @@
+{% extends "base.html" %}
+
+{% block title %}{{ _("Downloads") }}{% end block %}
+
+{% block content %}
+       <div class="post">
+               <a name="latest"></a>
+               <h3>{{ _("Download IPFire") }}</h3>
+
+               <img src="{{ static_url("images/box_ipfire.png") }}" alt="{{ _("CD-Box") }}" class="floatTR" />
+
+               {% if lang == "de" %}
+                       <p>
+                               Auf dieser Seite können Sie <strong>kostenlos</strong> die neueste
+                               Version von IPFire herunterladen. Ã„ltere Versionen oder
+                               andere Downloadoptionen finden Sie weiter unten auf der Seite.
+                       </p>
+
+                       <p>
+                               IPFire ist innerhalb von 15 bis 20 Minuten eingerichtet.
+                               Eine <a href="http://wiki.ipfire.org/{{ lang }}/installation/start"
+                               target="_blank">Installationsanleitung</a>
+                               ist in unserem Wiki zu finden.
+                       </p>
+
+                       <p>
+                               Sollte Ihnen diese Software gefallen, würden sich die Betreiber
+                               Ã¼ber ein kleines Dankeschön freuen.
+                       </p>
+               {% else %}
+                       <p>
+                               On this page one can download the latest version of IPFire
+                               <strong>for free</strong>. Older versions and other downloads
+                               can be retrieved on the linked pages below.
+                       </p>
+
+                       <p>
+                               IPFire can be installed within 15 to 20 minutes. An
+                               <a href="http://wiki.ipfire.org/{{ lang }}/installation/start"
+                               target="_blank">installation guide</a> can be found on our wiki.
+                       </p>
+
+                       <p>
+                               If you like this piece of software, developers appreciate your
+                               donations.
+                       </p>
+               {% end %}
+
+               <div class="bigdownload">
+                       <a href="{{ release.iso.url }}">
+                               {{ _("Begin download") }}<br />
+                               {{ release.name }}
+                       </a>
+               </div>
+
+               <table class="download">
+                       {% for download in release.downloads %}
+                               <tr class="{{ download.type }}">
+                                       <td class="icon">
+                                               <img src="{{ static_url("images/download_type_%s.png" % download.type) }}"
+                                                       alt="{{ download.type }}" />
+                                       </td>
+                                       <td class="link">
+                                               <a href="{{ download.url }}">{{ _(download.desc) }}</a>
+                                       </td>
+                                       <td>
+                                               {{ _(download.rem) }}
+                                       </td>
+                               </tr>
+                       {% end %}
+               </table>
+
+               <br class="clear" />
+       </div>
+
+       <div class="post">
+               <a name="other"></a>
+               <h3>{{ _("Other download options") }}</h3>
+               <div class=pr_li>
+                       <ul>
+                               <li><a href="{{ link("downloads/all") }}">{{ _("See older downloads...") }}</a></li>
+                               <li><a href="{{ link("downloads/development") }}">{{ _("See development releases...") }}</a></li>
+                               <li><a href="{{ link("downloads/torrents") }}">{{ _("See all torrents...") }}</a></li>
+                               <li><a href="{{ link("downloads/mirrors") }}">{{ _("See a list of mirrors...") }}</a></li>
+                       </ul>
+               </div>
+               <br class="clear" />
+       </div>
+{% end block %}
diff --git a/www/templates/error-404.html b/www/templates/error-404.html
new file mode 100644 (file)
index 0000000..0535c63
--- /dev/null
@@ -0,0 +1 @@
+{% extends "error.html" %}
diff --git a/www/templates/error-500.html b/www/templates/error-500.html
new file mode 100644 (file)
index 0000000..be9f5d4
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends "error.html" %}
+
+{% block explanation %}
+       <br class="clear" />
+
+       <h4>{{ _("Detailed information") }}</h4>
+       <p>
+               {% if lang == "de" %}
+                       Bei der Verarbeitung der Anfrage kam es zu einem internen Problem
+                       des Webservers.<br />Sollten nähere Informationen verfügbar sein, so
+                       sind diese untenstehend angehangen.
+               {% else %}
+                       While processing the request, there was an internal problem
+                       of the web server. <br /> If there are more information available,
+                       they would be appended below.
+               {% end %}
+       </p>
+{% end block %}
diff --git a/www/templates/error.html b/www/templates/error.html
new file mode 100644 (file)
index 0000000..bc587d1
--- /dev/null
@@ -0,0 +1,41 @@
+{% extends "base.html" %}
+
+{% block title %}{{ _("Error") }} {{ code }}{% end block %}
+
+{% block content %}
+<div class=post>
+       <h3>{{ code }} - {{ message }}</h3>
+       <img class="floatTL" src="{{ static_url("images/error/%s.png" % code) }}"
+               alt="{{ _("Error") }} {{ code }}" />
+       <p>
+               {% if lang == "de" %}
+                       Leider ist ein unerwarteter Fehler beim Laden der Seite aufgetreten.
+                       <br /><br />
+                       Das ist erstmal kein Grund zur Panik.
+                       <br /><br />
+                       Sollte dies das erstmalige Auftreten des Fehlers sein, so bitten wir
+                       einige Zeit abzuwarten. Sollte der Fehler jedoch an dieser Stelle
+                       regelmäßig auftreten, so würden sich die Webmaster Ã¼ber eine kleine
+                       Benachrichtigung freuen.
+               {% else %}
+                       Unfortunately, an unexpected error has occurred during page load.
+                       <br /><br />
+                       At first this is no reason to panic.
+                       <br /><br />
+                       If this is the first occurrence of the error, please wait a little bit
+                       and try again. If the error occurres anyway the webmaster would be happy
+                       to get a notification about this.
+               {% end %}
+       </p>
+</div>
+<div class=post>
+       {% block explanation %}{% end block %}
+</div>
+       {% if exception %}
+               <div class=post>
+                       <p>
+                               <pre>{{ exception }}</pre>
+                       </p>
+               </div>
+       {% end %}
+{% end block %}
diff --git a/www/templates/index.html b/www/templates/index.html
new file mode 100644 (file)
index 0000000..025ee21
--- /dev/null
@@ -0,0 +1,77 @@
+{% extends "base.html" %}
+
+{% block title %}{{ _("Home") }}{% end block %}
+
+{% block content %}
+       <div class=post>
+               <h3>{{ _("More security for your network") }}</h3>
+               <p>
+                       {% if lang == "de" %}
+                               Das <strong>IPFire</strong>-System ist eine Linux-Distribution, mit der Zielsetzung ein einfach zu 
+                               installierendes Grundsystem zu bieten und dabei ein <strong>hohes Sicherheitsniveau</strong> zu gewährleisten.
+                               <strong>IPFire</strong> ist komplett Ã¼ber sein intuitiv zu bedienendes Webinterface zu konfigurieren 
+                               und bietet sowohl <strong>Anfängern</strong>, als auch erfahrenen <strong>Administratoren</strong> eine Fülle von 
+                               Einstellungsmöglichkeiten. Einen <strong>Schwerpunkt</strong> bei der Weiterentwicklung legen die erfahrenen Entwickler 
+                               auf regelmäßige System- und vor allem <strong>Sicherheitsupdates</strong>.<br /><br />                         
+                               Durch den integrierten Paketmanager <strong>Pakfire</strong> lässt sich der <strong>IPFire</strong> mit diversen 
+                               <a href="http://wiki.ipfire.org/de/addons/start" target="_blank">Addons</a>, 
+                               zu einem Server-System erweitern.
+                       {% else %}
+                               <strong>IPFire</strong> is a linux-distribution that focusses on easy setup, good handling and a 
+                               <strong>high niveau of security</strong>.<br /> It is operable via an intuitive webinterface, which offers a
+                               lot of playground for <strong>beginners</strong> and even experienced <strong>administrators</strong>.
+                               <strong>IPFire</strong> is maintained by experienced developers, who are really concerned about security and regulary 
+                               updates to <strong>keep it secure</strong>.<br /><br />                  
+                               <strong>IPFire</strong> ships with a custom built paket-manager called <strong>Pakfire</strong>, so the system can be 
+                               expanded with various <a href="http://wiki.ipfire.org/en/addons/start" target="_blank">addons</a>.                               
+                       {% end %}
+               </p>
+               <div class="cebit_button">
+                       <div class="cebit_button_text">                                         
+                               <a href="cebit">{{ _("CeBIT-Donation") }}</a>
+                       </div>
+               </div>  
+               <!-- 
+               <div class="button">
+                       <div class="button_text">
+                                       <a href="download">Download&nbsp;&nbsp;IPFire 2.5</a>
+                       </div>
+               </div>
+               -->             
+               <img src="{{ static_url("images/Network-1.png") }}") }}" alt="IPFire Network" />        
+       </div>
+       
+       <div class=post>
+               <h3>{{ _("News") }}</h3>
+       
+               {% for item in news.get(2) %}
+                       {{ modules.NewsItem(item) }}
+               {% end %}
+       </div>
+       <p class="right">
+               <a href="{{ link("news") }}">{{ _("Previous posts >>") }}</a>
+       </p>
+{% end block %}
+
+{% block sidebar %}
+       {{ modules.SidebarRelease() }}
+       
+       <h4><span>Internet Relay</span> Chat</h4>
+       <p>
+               Server: irc.freenode.net<br />
+               Channel: #ipfire<br />
+               <a href="http://webchat.freenode.net/?channels=ipfire" target="_blank">Web-Chat</a>
+       </p>
+       
+       {{ modules.SidebarBanner(banner) }}
+       
+       <h4><span>RSS</span> feed</h4>
+       <p>
+               {% if lang == "de" %}
+                       <a class="feed" href="news.rss">IPFire - News</a><br />
+               {% else %}              
+                       <a class="feed" href="news.rss">IPFire - News</a><br />
+               {% end %}
+       </p>
+
+{% end block %}
diff --git a/www/templates/modules/builds.html b/www/templates/modules/builds.html
new file mode 100644 (file)
index 0000000..5b24269
--- /dev/null
@@ -0,0 +1,15 @@
+<tr>
+       <td>
+               <img src="{{ static_url("images/icons/ipfire.png") }}" alt="IPFire" />
+       </td>
+       <td>
+               &nbsp;<br />
+               <strong>{{ build.release }}</strong> ({{ build.arch }})<br />
+               {{ build.date }}
+       </td>
+       <td>
+               &nbsp;<br />
+               <a href="#">{{ build.iso }}</a> | {{ build.size }}<br />
+               {{ build.pxe }}&nbsp;
+       </td>
+</tr>
diff --git a/www/templates/modules/menu-item.html b/www/templates/modules/menu-item.html
new file mode 100644 (file)
index 0000000..f3833a2
--- /dev/null
@@ -0,0 +1,3 @@
+<li>
+       <a href="{{ item.uri }}"{% if item.active %} class="active"{% end %}>{{ item.name }}</a>
+</li>
diff --git a/www/templates/modules/menu.html b/www/templates/modules/menu.html
new file mode 100644 (file)
index 0000000..5ca3982
--- /dev/null
@@ -0,0 +1,7 @@
+<div id="menu">
+       <ul>
+               {% for item in menuitems %}
+                       {{ modules.MenuItem(item) }}
+               {% end %}
+       </ul>
+</div>
diff --git a/www/templates/modules/news-item.html b/www/templates/modules/news-item.html
new file mode 100644 (file)
index 0000000..0cd5add
--- /dev/null
@@ -0,0 +1,6 @@
+<div class="post">
+       <a name="{{ item.subject }}"></a>
+       <h3>{{ item.subject }}</h3>
+       <div class="post_info">{{ item.date }} - {{ _("by") }} {{ item.author }}</div>
+       {{ item.content }}
+</div>
diff --git a/www/templates/modules/release-item.html b/www/templates/modules/release-item.html
new file mode 100644 (file)
index 0000000..3d7dedf
--- /dev/null
@@ -0,0 +1,14 @@
+<div class="post">
+       <h3>{{ item.name }}</h3>
+       <p>     
+               {{ _("Here you will find the downloads for the version") }} {{ item.name }}:
+       </p>
+
+       <div align="right">
+               {% for download in item.downloads %}
+                       <a class="{{ download.type }}" href="{{ download.url }}">{{ _(download.desc) }}</a><br />
+               {% end %}
+       </div>
+
+       <br class="clear" />
+</div>
diff --git a/www/templates/modules/sidebar-banner.html b/www/templates/modules/sidebar-banner.html
new file mode 100644 (file)
index 0000000..7a10b3b
--- /dev/null
@@ -0,0 +1,5 @@
+<h4>{{ item.title }}</h4>
+
+<a href="{{ item.link }}" {% if item.link.startswith("http://") %}target="_blank" {% end %}>
+       <img src="{{ static_url(item.uri) }}" border="0" alt="{{ _("Banner") }}" />
+</a>
diff --git a/www/templates/modules/sidebar-item.html b/www/templates/modules/sidebar-item.html
new file mode 100644 (file)
index 0000000..7ebff07
--- /dev/null
@@ -0,0 +1,2 @@
+<h4>{% block heading %}{{ item.heading }}{% end block %}</h4>
+{% block body %}{{ item.body }}{% end block %}
diff --git a/www/templates/modules/sidebar-release.html b/www/templates/modules/sidebar-release.html
new file mode 100644 (file)
index 0000000..0483673
--- /dev/null
@@ -0,0 +1,23 @@
+{% extends "sidebar-item.html" %}
+
+{% block heading %}{{ _("release information") }}{% end block %}
+
+{% block body %}
+       <p>
+               <img src="{{ static_url("images/ipfire_download.png") }}" alt="Tux Logo" />
+       </p>
+
+       <p>
+               <strong>{{ _("Current version") }}</strong>:
+               <br />
+               <a href="{{ link("downloads") }}">{{ releases.latest.name }}</a>
+       </p>
+
+       {% if releases.latest_devel %}
+       <p>
+               <strong>{{ _("Current unstable") }}</strong>:
+               <br />
+               <a href="{{ link("downloads/development") }}">{{ releases.latest_devel.name }}</a>
+       </p>
+       {% end %}
+{% end block %}
diff --git a/www/templates/news.html b/www/templates/news.html
new file mode 100644 (file)
index 0000000..e6b98d0
--- /dev/null
@@ -0,0 +1,7 @@
+{% extends "base.html" %}
+
+{% block content %}
+       {% for item in news.get() %}
+               {{ modules.NewsItem(item) }}
+       {% end %}
+{% end block %}
diff --git a/www/templates/sources.html b/www/templates/sources.html
new file mode 100644 (file)
index 0000000..6189966
--- /dev/null
@@ -0,0 +1,23 @@
+{% extends "base.html" %}
+
+{% block title %}{{ _("Sources") }}{% end block %}
+
+{% block content %}
+       <h3>{{ _("Source Code") }}</h3>
+
+       <p>
+               {{ _("There are %s source files on the server.") % len(files) }}
+       </p>
+
+       <br class="clear" />
+
+       <ul class="sources">
+               {% for file in files %}
+                       <li>
+                               {{ file["hash"] }} |
+                               <a href="/{{ file["dir"] }}/{{ file["name"] }}">{{ file["name"] }}</a>
+                               ({{ file["size"] }})
+                       </li>
+               {% end %}
+       </ul>
+{% end block %}
diff --git a/www/templates/static/cebit.html b/www/templates/static/cebit.html
new file mode 100644 (file)
index 0000000..5235405
--- /dev/null
@@ -0,0 +1,173 @@
+{% extends "../base.html" %}
+               
+{% block title %}CeBIT-Special{% end block %}
+
+{% block content %}
+
+       <div class=post>                
+       {% if lang == "de" %}
+               <h3>IPFire auf der CeBIT 2010</h3>
+               <img src="{{ static_url("images/cebit-177px_schatten.png") }}" class="floatTR" border="0" alt="CeBIT" />
+               <p>
+                       Vom <em>2. bis 6. März 2010</em> findet die <strong>CeBIT</strong> in Hannover statt.
+                       Das Besondere in diesem Jahr: <strong>IPFire</strong> wird mit einem
+                       kleinen Stand in der <strong>Open Source Project Lounge</strong> auf der Messe vertreten sein.
+               </p>
+               <p>
+                       Zuallererst gebührt unser Dank der
+                       <a href="http://www.linuxnewmedia.de/Produkte/Events" target="_blank">Linux New Media AG</a>
+                       und der <a href="http://www.cebit.de/opensource_d" target="_blank">Messegesellschaft</a>,
+                       welche für ausgewählte OpenSource-Projekte einige kostenlose Stände zur Verfügung stellen.
+                       Die <strong>CeBIT</strong> die weltgrößte Computer- und Telekommunikationsmesse,
+                       und diese Präsentationsmöglichkeit ist natürlich eine riesige Chance, das Projekt bekannter
+                       zu machen, mehr Nutzer und Entwickler zu erreichen, bzw. Kontakte zu knüpfen und Allianzen
+                       zu schmieden. 
+               </p>
+               <p>
+                       Ebenfalls erhaltet ihr die einmalige Chance, die Entwickler einmal persönlich kennen zu lernen,
+                       Ideen auszutauschen, und und und...
+               </p>    
+       {% else %}
+               <h3>IPFire on CeBIT 2010</h3>
+               <img src="{{ static_url("images/cebit-177px_schatten.png") }}"class="floatTR" alt="CeBIT" />
+               <p>
+                       <strong>CeBIT</strong> 2010 will be here soon, beginning March 2nd and lasting until
+                       March 6th in Hannover, Germany. This year will prove to be a special
+                       one, as <strong>IPFire</strong> will be represented by its very own booth in
+                       the <strong>Open Source Project Lounge</strong>.
+               </p>            
+               <p>
+                       First of all, our very special thanks go out to
+                       <a href="http://www.linuxnewmedia.de/Produkte/Events" target="_blank">Linux New Media AG</a> and
+                       <a href="http://www.cebit.de/opensource_d" target="_blank">Messegesellschaft</a>,
+                       who offer free booths to selected Open Source
+                       projects. <strong>CeBIT</strong> (a German acronym for the Center for Office and
+                       Information Technology) is the biggest computer and telecommunications
+                       exhibition in the world. This an excellent chance for IPFire to gain
+                       recognition, get in touch with users and developers, and possibly find
+                       sponsors and forge alliances. 
+               </p>
+               <p>
+                       And, it is also a chance for all of you to meet the members of the
+                       <strong>IPFire</strong> community in person.
+               </p>    
+       {% end %}
+       </div>
+
+
+       <div class=post>
+       {% if lang == "de" %}
+               <h3>Spendenaufruf</h3>
+               <img src="{{ static_url("images/paypal-folder.png") }}" class="floatTL" alt="Paypal" /> 
+               <p>
+                       Dieses Projekt wird von Freiwilligen in ihrer Freizeit betrieben und betreut, was auch
+                       für den Stand zutrifft. Man glaubt es kaum, aber selbst wenn man einen kostenlosen
+                       Stand zur Verfügung gestellt bekommt, entstehen hohe Kosten für Flyer, CDs, Poster und
+                       sonstige Merchandise-Artikel.
+               </p>
+               <p>
+                       Wir möchten jedoch <strong>IPFire</strong> so professionell wie möglich präsentieren, daher ergeht
+                       an Sie Alle ein <strong>Spenden- und Mitmachaufruf</strong>.<br />
+                       Wir möchten diese einmalige Chance nutzen und <strong>IPFire</strong> noch bekannter machen.
+               </p>
+               <p>
+                       Spenden müssen nicht unbedingt finanzieller Natur sein. Es wird auch folgendes benötigt:
+               </p>
+
+               <p>
+                       <ul>
+                               <li>Poster</li>
+                               <li>Flyer</li>
+                               <li>CD-ROMs (bedruckt) in großer Auflage</li>
+                               <li>Textilien mit Aufdruck</li>
+                       </ul>
+               </p>
+               <p>
+                       Wegen des einfachen Ablaufs der Spende bevorzugen wir <strong>PayPal</strong>.
+                       Auf <a href="mailto:&#x6d;&#x69;&#x63;&#x68;&#x61;&#x65;&#x6c;&#x2e;&#x74;&#x72;&#x65;&#x6d;&#x65;&#x72;&#x40;&#x69;&#x70;&#x66;&#x69;&#x72;&#x65;&#x2e;&#x6f;&#x72;&#x67;" class="mail JSnocheck" title="&#x6d;&#x69;&#x63;&#x68;&#x61;&#x65;&#x6c;&#x2e;&#x74;&#x72;&#x65;&#x6d;&#x65;&#x72;&#x40;&#x69;&#x70;&#x66;&#x69;&#x72;&#x65;&#x2e;&#x6f;&#x72;&#x67;">Anfrage</a>
+                       kann eine Ãœberweisung auch per Kontonummer erfolgen.
+               </p>
+               <div align="center">
+               <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
+                       <input type="hidden" name="cmd" value="_s-xclick">
+                       <input type="hidden" name="hosted_button_id" value="10718640">
+                       <input type="image" src="https://www.paypal.com/de_DE/DE/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
+                       <img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
+               </form>
+               </div>
+       {% else %}
+               <h3>Your Donations are Needed!</h3>
+               <p>
+                       This project is driven and maintained by volunteers in their free time.
+                       The same goes to the booth. Even though it is being donated there are
+                       still many costs associated with running a booth, such as flyers, CDs,
+                       posters and other merchandise.
+               </p>
+               <p>
+                       As we strive to represent <strong>IPFire</strong> as professionally,
+                       we are asking for some extra help to take advantage of this opportunity.
+                       All we ask is a small donation, as every little bit helps. This is a unique
+                       opportunity to gain international recognition for the project, so your
+                       money will be well spent.
+               </p>
+               <p>
+                       Materials we will be purchasing:
+               </p>
+               <p>
+                       <ul>
+                               <li>Posters</li>
+                               <li>Flyers</li>
+                               <li>Discs (pressed)</li>
+                               <li>T-Shirts, etc.</li>
+                       </ul>
+               </p>            
+               <p>
+                       Our favorite way for a donation is <strong>PayPal</strong> because
+                       it is fast and easy. If you prefer a bank donation, please send
+                       us a short <a href="mailto:&#x6d;&#x69;&#x63;&#x68;&#x61;&#x65;&#x6c;&#x2e;&#x74;&#x72;&#x65;&#x6d;&#x65;&#x72;&#x40;&#x69;&#x70;&#x66;&#x69;&#x72;&#x65;&#x2e;&#x6f;&#x72;&#x67;" class="mail JSnocheck" title="&#x6d;&#x69;&#x63;&#x68;&#x61;&#x65;&#x6c;&#x2e;&#x74;&#x72;&#x65;&#x6d;&#x65;&#x72;&#x40;&#x69;&#x70;&#x66;&#x69;&#x72;&#x65;&#x2e;&#x6f;&#x72;&#x67;">request</a>
+                       for our bank account number.
+               </p>
+               <div align="center">
+               <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
+                       <input type="hidden" name="cmd" value="_s-xclick">
+                       <input type="hidden" name="hosted_button_id" value="10718640">
+                       <input type="image" src="https://www.paypal.com/en_US/GB/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
+                       <img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
+               </form>
+               </div>  
+       {% end %}
+       </div>
+       
+       
+       <div class=post>
+       {% if lang == "de" %}
+               <h3>Sponsoren</h3>
+       {% else %}
+               <h3>Sponsors</h3>
+       {% end %}
+       <a href="http://www.linuxnewmedia.de/" target="_blank" border"0"><img src="{{ static_url("images/linux_new_media_ag.jpg") }} alt="Linux New Media AG" /></a>
+       <a href="http://www.aktinet.de/" target="_blank" border="0"><img src="{{ static_url("images/aktinet_logo.jpg") }} alt="Aktinet IT-Services" /></a>
+       </div>
+       
+               
+{% end block %}
+
+{% block sidebar %}
+       <h4><span>Ce</span>BIT</h4>
+       {% if lang == "de" %}
+               <ul class="links">              
+                       <li class="first"><a href="#IPFire auf der CeBIT 2010">CeBIT 2010</a></li>
+                       <li><a href="#Spendenaufruf">Spenden!</a></li>
+                       <li><a href="#Sponsoren">Sponsoren</a></li>
+               </ul>
+       {% else %}
+               <ul class="links">              
+                       <li class="first"><a href="#IPFire on CeBIT 2010:">CeBIT 2010</a></li>
+                       <li><a href="#Your Donations are Needed!">Donation!</a></li>
+                       <li><a href="#Sponsors">Sponsors</a></li>
+               </ul>
+       {% end %}
+
+{{ modules.SidebarBanner(banner) }}
+
+{% end block %}
diff --git a/www/templates/static/cluster.html b/www/templates/static/cluster.html
new file mode 100644 (file)
index 0000000..b5d4cea
--- /dev/null
@@ -0,0 +1,35 @@
+{% extends "../base.html" %}
+
+{% block title %}{{ _("Cluster") }}{% end block %}
+
+{% block content %}
+       <h3>{{ _("Icecream Cluster Monitoring") }}</h3>
+
+       <p>{{ _("Cluster's CPU load") }}:
+               <span id="loadbar"></span>
+               - {{ _("Job load") }}:
+               <span id="jobbar"></span>
+       </p>
+
+       <table id="nodes">
+               <thead>
+                       <tr>
+                               <th class="hostname">{{ _("Name") }}</th>
+                               <th class="arch">{{ _("Arch") }}</th>
+                               <th class="load">{{ _("CPU-Load") }}</th>
+                               <th class="jobs">{{ _("Jobs") }}</th>
+                               <th class="speed">{{ _("Speed") }}</th>
+                       </tr>
+               </thead>
+               <tbody>
+               </tbody>
+       </table>
+
+       <p class="right">&nbsp;<br />{{ _("Number of nodes") }}: <span id="count">-</span></p>
+
+{% end block %}
+
+{% block javascript %}
+       <script type="text/javascript" src="{{ static_url("js/jquery.progressbar.js") }}"></script>
+       <script type="text/javascript" src="{{ static_url("js/cluster.js") }}"></script>
+{% end block %}
diff --git a/www/templates/static/development.html b/www/templates/static/development.html
new file mode 100644 (file)
index 0000000..885e157
--- /dev/null
@@ -0,0 +1,159 @@
+{% extends "../base.html" %}
+               
+{% block title %}{{ _("Development") }}{% end block %}
+
+{% block content %}
+       
+       
+       <div class=post>
+               <h3>{{ _("Development") }}</h3>
+               <img src="{{ static_url("images/page_icons/development.png") }}" class="floatTR" border="0" alt="{{ _("Development") }}" />
+               <p>
+                       {% if lang == "de" %}
+                               Willkommen im Entwicklungsbereich des IPFire-Projekts.<br />
+                               Hier gibt es Zugriff auf alle Ressourcen für die Entwicklung.<br />
+                       {% else %}
+                               Welcome to the development area of the ipfire project.<br />
+                               These are the development ressources.
+                       {% end %}
+               </p>
+       </div>
+       <br class="clear" />    
+
+       <div class=post>
+               <h3>{{ _("git") }}</h3>
+               <img src="      http://git.ipfire.org/git-logo.png" class="floatTL" alt="{{ _("git") }}" />
+               <p>
+                       {% if lang == "de" %}
+                               Das Quellcode-Repository wird durch
+                               <a href="http://git.or.cz" target="_blank">Git</a>
+                               verwaltet. Ein Howto zum Arbeiten mit Git findet man
+                               in unserem <a href="http://wiki.ipfire.org/de/development/git" target="_blank">Wiki</a>.
+                               <br />
+                               Den Source-Code findet man unter: <a href="http://git.ipfire.org/" target="_blank">http://git.ipfire.org/</a>
+                       {% else %}      
+                               Our source code repository is managed by
+                               <a href="http://git.or.cz" target="_blank">git</a>.
+                               Your will find a howto to work with git in our
+                               <a href="http://wiki.ipfire.org/en/development/git" target="_blank">wiki</a>.
+                               <br />
+                               You may find our source code on: <a href="http://git.ipfire.org/" target="_blank">http://git.ipfire.org/</a>
+                       {% end %}
+               </p>
+       </div>
+       <br class="clear" />
+
+
+       <div class=post>
+               <h3>{{ _("source-code") }}</h3>
+               <p>
+                       {% if lang == "de" %}
+                               Die Sourcecode-Tarballs der im IPFire verwendeten Tools findet man unter
+                               <a href="http://source.ipfire.org/" target="_target">http://source.ipfire.org/</a><br />
+                               Alle Patches, die in der Distribution Verwendung finden, werden in einem
+                               Git-Repository verwaltet (Siehe oben).
+                       {% else %}      
+                               The source code tarballs of the tools used in IPFire are available on
+                               <a href="http://source.ipfire.org/" target="_target">http://source.ipfire.org/</a>.<br />
+                               All patches that are used in our distribution are stored in a git repository (see above).
+                       {% end %}                       
+               </p>
+       </div>
+       
+       
+       <div class=post>
+               <h3>{{ _("bugtracker") }}</h3>
+               <img src="http://bugtracker.ipfire.org/images/mantis_logo.gif" class="floatTL" width="80" alt="{{ _("bugtracker") }}" />
+               <p>
+                       {% if lang == "de" %}
+                                       Im <a href="http://bugtracker.ipfire.org" target="_blank">Bugtracker</a> findet man bekannte Fehler.<br />
+                                       Solltet ihr also einen Fehler oder auch Funktionsvorschlag haben so könnt ihr uns Ã¼ber den Bugtracker 
+                                       dies mitteilen. Für die Entwicklung ist es wichtig, dass es ausführliche Bug-Reports gibt,
+                                       die dann rasch bearbeitet werden können. 
+                       {% else %}      
+                                       We manage all issues in our <a href="http://bugtracker.ipfire.org" target="_blank">bugtracker</a>.<br />
+                                       Should you have a bug or feature proposal you can tell us about it by posting 
+                                       to the bugtracker. It is important for development to create a detailed bug reports so that
+                                       we can fix them fastly. 
+                       {% end %}               
+               </p>
+       </div>
+       <br class="clear" />
+       
+       
+       <div class=post>
+               <h3>{{ _("HowTos") }}</h3>
+               <p>
+               {% if lang == "de" %}
+                       Im Wiki befinden sich viele weitere Howtos hier einmal die wichtigsten rund ums Entwickeln.
+                       <div class=pr_li>
+                               <ul>
+                                       <li><a href="http://wiki.ipfire.org/de/development/build" target="_blank">Building IPFire</a></li>
+                                       <li><a href="http://wiki.ipfire.org/de/development/addon" target="_blank">Building Addon</a></li>
+                                       <li><a href="http://wiki.ipfire.org/de/development/language" target="_blank">Creating language file</a></li>
+                               </ul>
+                       </div>
+               {% else %}      
+                       In the wiki there are many other howtos here folowing the important ons for development.
+                       <div class=pr_li>
+                               <ul>
+                                       <li><a href="http://wiki.ipfire.org/en/development/build" target="_blank">Building IPFire</a></li>
+                                       <li><a href="http://wiki.ipfire.org/en/development/addon" target="_blank">Building Addon</a></li>
+                                       <li><a href="http://wiki.ipfire.org/en/development/language" target="_blank">Creating language file</a></li>
+                               </ul>
+                       </div>
+               {% end %}
+               </p>
+       </div>
+       
+       
+       <div class=post>
+               <h3>{{ _("IPFire 3.x") }}</h3>
+               <p>
+               {% if lang == "de" %}
+                       Unser nächstes Ziel ist die Entwicklung einer völlig neuen und komplett redesignten IPFire Version 3.<br />
+                       In der <a href="downloads/development" target="_blank">Download-Sektion</a> 
+                       gibt es aktuelle Entwicklungsversionen zum herunterladen.
+                       <div class=pr_li>
+                               <ul>
+                                       <li><a href="http://wiki.ipfire.org/de/development/3.0" target="_blank">Roadmap von IPFire 3.x</a></li>
+                               </ul>
+                       </div>
+               {% else %}      
+                       Our next goal is to develop a completely new and redesigned IPFire version 3.<br />
+                       In the <a href="downloads/development" target="_blank">download section</a> 
+                       you can get a curent development version.
+                       <div class=pr_li>
+                               <ul>
+                                       <li><a href="http://wiki.ipfire.org/en/development/3.0" target="_blank">Roadmap of IPFire 3.x</a></li>
+                               </ul>
+                       </div>
+               {% end %}
+       </div>
+       
+                       
+{% end block %}
+
+{% block sidebar %}
+               <h4>{{ _("Development Area") }}</h4>
+               <ul class="links">              
+                       <li class="first"><a href="#{{ _("git") }}">{{ _("git") }}</a></li>
+                       <li><a href="#{{ _("source-code") }}">{{ _("source-code") }}</a></li>
+                       <li><a href="#{{ _("bugtracker") }}">{{ _("bugtracker") }}</a></li>
+                       <li><a href="#{{ _("IPFire 3.x") }}">{{ _("IPFire 3.x") }}</a></li>     
+                       <li>
+                               <a href="http://www.ohloh.net/projects/compare?metric=Activity&amp;project_0=IPFire&amp;project_1=Smoothwall&amp;project_2=IPCop+Firewall" target="_blank">             
+                               {% if lang == "de" %}
+                                       IPFire im Vergleich mit IPCop und Smoothwall auf ohloh.net
+                               {% else %}      
+                                       Comparison of IPFire to IPCop and Smoothwall on ohloh.net
+                               {% end %}
+                               </a>
+                       </li>
+               </ul>
+
+               
+       
+ {{ modules.SidebarBanner(banner) }}
+
+{% end block %}
diff --git a/www/templates/static/donation.html b/www/templates/static/donation.html
new file mode 100644 (file)
index 0000000..b3abada
--- /dev/null
@@ -0,0 +1,22 @@
+{% extends "../base.html" %}
+               
+{% block title %}{{ _("Donation") }}{% end block %}
+
+{% block content %}
+       
+       
+       <div class=post>
+               <h3>{{ _("Donation") }}</h3>
+               <img src="{{ static_url("images/page_icons/donation.png") }}") }}" class="floatTR" border="0" alt="{{ _("Donation") }}" />
+               <p>
+                       {% if lang == "de" %}
+                       Mit jeder Spende und sei sie noch so klein unterstützen sie dieses Projekt sehr.
+                       {% else %}
+                       With each donation, and if with small ones you support this project.    
+                       {% end %}
+               </p>
+       </div>
+       <br class="clear" />
+
+       {% end block %}
diff --git a/www/templates/static/imprint.html b/www/templates/static/imprint.html
new file mode 100644 (file)
index 0000000..8d0356c
--- /dev/null
@@ -0,0 +1,116 @@
+{% extends "../base.html" %}
+
+{% block title %}{{ _("Imprint") }}{% end block %}
+
+{% block content %}
+
+       <div class=post>
+       <h3>{{ _("Imprint") }}</h3>
+       <img src="{{ static_url("images/page_icons/imprint.png") }}" class="floatTR" border="0" alt="{{ _("Imprint") }}" />
+
+       {% if lang == "de" %}
+               <p>
+                       Dieses Projekt ist ein Open-Source-Projekt und verfolgt keine kommerziellen Ziele.
+               </p>
+               
+               <p>
+                       <strong>Verantwortliche im Sinne von Â§ 5 TMG, Â§ 55 RfStV:</strong>
+                       <br />
+
+                       Michael Tremer (<a href="mailto:michael@ipfire.org">michael@ipfire.org</a>)<br />
+                       Gerhardstrasse 8<br />
+                       45711 Datteln<br /><br />
+               
+                       Christian Schmidt (<a href="mailto:maniacikarus@ipfire.org">maniacikarus@ipfire.org</a>)<br />
+                       Mathildenstr. 25<br />
+                       90489 Nürnberg<br /><br />
+
+               </p>
+               
+               <h4>Haftungsausschluss</h4>
+               <p>
+                       <b>1. Inhalt des Onlineangebotes</b><br />
+                       Der Autor Ã¼bernimmt keinerlei Gewähr für die Aktualität, Korrektheit, Vollständigkeit 
+                       oder Qualität der bereitgestellten Informationen. Haftungsansprüche gegen den Autor, 
+                       welche sich auf Schäden materieller oder ideeller Art beziehen, die durch die Nutzung 
+                       oder Nichtnutzung der dargebotenen Informationen bzw. durch die Nutzung fehlerhafter 
+                       und unvollständiger Informationen verursacht wurden, sind grundsätzlich ausgeschlossen, 
+                       sofern seitens des Autors kein nachweislich vorsätzliches oder grob fahrlässiges 
+                       Verschulden vorliegt.<br />
+                       Alle Angebote sind freibleibend und unverbindlich. Der Autor behält es sich ausdrücklich vor, 
+                       Teile der Seiten oder das gesamte Angebot ohne gesonderte Ankündigung zu verändern, 
+                       zu ergänzen, zu löschen oder die Veröffentlichung zeitweise oder endgültig einzustellen.
+               </p>
+       
+               <p>
+                       <b>2. Verweise und Links</b><br />
+                       Bei direkten oder indirekten Verweisen auf fremde Internetseiten ("Links"), 
+                       die außerhalb des Verantwortungsbereiches des Autors liegen, würde eine 
+                       Haftungsverpflichtung ausschließlich in dem Fall in Kraft treten, in dem der 
+                       Autor von den Inhalten Kenntnis hat und es ihm technisch möglich und zumutbar wäre, 
+                       die Nutzung im Falle rechtswidriger Inhalte zu verhindern. <br />
+                       Der Autor erklärt hiermit ausdrücklich, dass zum Zeitpunkt der Linksetzung keine 
+                       illegalen Inhalte auf den zu verlinkenden Seiten erkennbar waren. 
+                       Auf die aktuelle und zukünftige Gestaltung, die Inhalte oder die Urheberschaft 
+                       der gelinkten/verknüpften Seiten hat der Autor keinerlei Einfluss. Deshalb distanziert 
+                       er sich hiermit ausdrücklich von allen Inhalten aller gelinkten /verknüpften Seiten, 
+                       die nach der Linksetzung verändert wurden. Diese Feststellung gilt für alle innerhalb 
+                       des eigenen Internetangebotes gesetzten Links und Verweise sowie für Fremdeinträge 
+                       in vom Autor eingerichteten Gästebüchern, Diskussionsforen und Mailinglisten. 
+                       Für illegale, fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, 
+                       die aus der Nutzung oder Nichtnutzung solcherart dargebotener Informationen entstehen, 
+                       haftet allein der Anbieter der Seite, auf welche verwiesen wurde, nicht derjenige, 
+                       der Ã¼ber Links auf die jeweilige Veröffentlichung lediglich verweist.
+               </p>
+
+               <p>
+                       <b>3. Urheber- und Kennzeichenrecht </b><br />
+                       Der Autor ist bestrebt, in allen Publikationen die Urheberrechte der verwendeten Grafiken, 
+                       Tondokumente, Videosequenzen und Texte zu beachten, von ihm selbst erstellte Grafiken, 
+                       Tondokumente, Videosequenzen und Texte zu nutzen oder auf lizenzfreie Grafiken, Tondokumente, 
+                       Videosequenzen und Texte zurückzugreifen. <br />
+                       Alle innerhalb des Internetangebotes genannten und ggf. durch Dritte geschützten Marken- 
+                       und Warenzeichen unterliegen uneingeschränkt den Bestimmungen des jeweils gültigen Kennzeichenrechts 
+                       und den Besitzrechten der jeweiligen eingetragenen Eigentümer. Allein aufgrund der bloßen Nennung 
+                       ist nicht der Schluss zu ziehen, dass Markenzeichen nicht durch Rechte Dritter geschützt sind! <br />
+                       Das Copyright für veröffentlichte, vom Autor selbst erstellte Objekte bleibt allein beim Autor der Seiten. 
+                       Eine Vervielfältigung oder Verwendung solcher Grafiken, Tondokumente, Videosequenzen und Texte in 
+                       anderen elektronischen oder gedruckten Publikationen ist ohne ausdrückliche Zustimmung des Autors nicht gestattet.
+               </p>
+       
+               <p>
+                       <b>4. Datenschutz </b><br />
+                       Sofern innerhalb des Internetangebotes die Möglichkeit zur Eingabe persönlicher oder geschäftlicher Daten 
+                       (Emailadressen, Namen, Anschriften) besteht, so erfolgt die Preisgabe dieser Daten seitens 
+                       des Nutzers auf ausdrücklich freiwilliger Basis. Die Inanspruchnahme und Bezahlung aller 
+                       angebotenen Dienste ist - soweit technisch möglich und zumutbar - auch ohne Angabe solcher Daten 
+                       bzw. unter Angabe anonymisierter Daten oder eines Pseudonyms gestattet. Die Nutzung der im Rahmen 
+                       des Impressums oder vergleichbarer Angaben veröffentlichten Kontaktdaten wie Postanschriften, 
+                       Telefon- und Faxnummern sowie Emailadressen durch Dritte zur Ãœbersendung von nicht ausdrücklich 
+                       angeforderten Informationen ist nicht gestattet. Rechtliche Schritte gegen die Versender von 
+                       sogenannten Spam- Mails bei Verstössen gegen dieses Verbot sind ausdrücklich vorbehalten.
+               </p>
+
+               <p>
+                       <b>5. Rechtswirksamkeit dieses Haftungsausschlusses </b><br />
+                       Dieser Haftungsausschluss ist als Teil des Internetangebotes zu betrachten, von dem aus auf diese 
+                       Seite verwiesen wurde. Sofern Teile oder einzelne Formulierungen dieses Textes der geltenden 
+                       Rechtslage nicht, nicht mehr oder nicht vollständig entsprechen sollten, bleiben die Ã¼brigen 
+                       Teile des Dokumentes in ihrem Inhalt und ihrer Gültigkeit davon unberührt.
+               </p>
+               
+               <p>
+                       Dieses Impressum gilt für alle mit dem IPFire-Projekt verbundenen Webseiten.
+               </p>
+               
+       {% else %}
+               <p>
+                       Because of the fact that the people who started this project are living
+                       in Germany and the German law demands it. This side is only available in german language, 
+                       so please have a look at the <a href="{{ lang_link("de") }}">german legal notes</a>.
+               </p>
+       {% end %}
+       </div>
+       <br class="clear" />
+
+{% end block %}
diff --git a/www/templates/static/pr.html b/www/templates/static/pr.html
new file mode 100644 (file)
index 0000000..ac9ebae
--- /dev/null
@@ -0,0 +1,224 @@
+{% extends "../base.html" %}
+               
+{% block title %}{{ _("Public Relations") }}{% end block %}
+
+{% block content %}
+       
+       
+       <div class=post>
+               <h3>{{ _("Public Relations") }}</h3>
+               <img src="{{ static_url("images/page_icons/pr.png") }}") }}" class="floatTR" border="0" alt="{{ _("Public Relations") }}" />
+               <p>
+                       {% if lang == "de" %}
+                       Euer Ansprechpartner für die Bereiche Presse, allgemeine Ã–ffentlichkeitsarbeit und Sponsoring:
+                       {% else %}
+                       Your contact person for the fields press, general public relations and sponsorship:
+                       {% end %}
+                       <br /><br />
+                       Markus Krüger
+                        <img src="http://wiki.ipfire.org/lib/tpl/ipfire3-1/images/mail_icon.gif"  align="absmiddle"/><a href="mailto:&#109;&#97;&#114;&#107;&#117;&#115;&#46;&#107;&#114;&#117;&#101;&#103;&#101;&#114;&#64;&#105;&#112;&#102;&#105;&#114;&#101;&#46;&#111;&#114;&#103;">&#101;&#77;&#97;&#105;&#108;</a><br />
+                       Kollegstraße 2 / 432<br />
+                       44801 Bochum<br />
+                       {% if lang != "de" %}
+                       West Germany
+                       {% end %}
+               </p>
+       </div>
+       <br class="clear" />
+
+       <div class=post>
+               <h3>{{ _("Press") }}</h3>
+               <p>
+                       <h4>{{ _("Press kit") }}</h4>
+
+                       {% if lang == "de" %}
+                       <p>
+                               Hier findet hier eine groß\9fe Auswahl an Informationen rund um das Projekt IPFire.
+                       </p>
+                       {% else %}
+                       <p>
+                               Here you will find a large selection of information about the project IPFire.
+                       </p>
+                       {% end %}
+                       <br />
+                       
+                       <h4>{{ _("Logos and print artworks") }}</h4>
+                       <p>
+                               <div class=pr_li>
+                               <ul>
+                                       <li>{{ _("<strong>Print</strong> media") }}:</li>
+                                               <ul>
+                                                       {% if lang == "de" %}
+                                                       <p>
+                                                               <em>Bilder von Tim -  hier rein</em>
+                                                       </p>
+                                                       {% else %}
+                                                       <p>
+                                                               <em>Picture made by Tim - put in here</em>
+                                                       </p>
+                                                       {% end %}
+                                               </ul>
+                                       <li>{{ _("<strong>Online</strong> media") }}:</li>
+                                       <ul>
+                                                <li><img src="{{ static_url("images/tux/ipfire_tux_16x16.png") }}" align="bottom" border= "0"/>
+                                                <img src="{{ static_url("images/tux/ipfire_tux_32x32.png") }}" align="bottom" border= "0"/>
+                                                <img src="{{ static_url("images/tux/ipfire_tux_64x64.png") }}" align="bottom" border= "0"/>
+                                                <img src="{{ static_url("images/tux/ipfire_tux_128x128.png") }}" align="bottom" border= "0"/>
+                                                <br /><a href="{{ static_url("images/tux/ipfire_tux_16x16.png") }}") }}" target="_blank" border="0">
+                                                ipfire.png (16 x 16)</a>
+                                                <br /><a href="{{ static_url("images/tux/ipfire_tux_32x32.png") }}") }}" target="_blank" border="0">
+                                                ipfire.png (32 x 32)</a>
+                                                <br /><a href="{{ static_url("images/tux/ipfire_tux_64x64.png") }}") }}" target="_blank" border="0">
+                                                ipfire.png (64 x 64)</a>
+                                                <br /><a href="{{ static_url("images/tux/ipfire_tux_128x128.png") }}") }}" target="_blank" border="0">
+                                                ipfire.png (128 x 128)</a>
+                                                <br /><a href="{{ static_url("images/tux/ipfire_tux_256x256.png") }}") }}" target="_blank" border="0">
+                                                ipfire.png (256 x 256)</a>
+                                                <br /><a href="{{ static_url("images/tux/ipfire_tux_512x512.png") }}") }}" target="_blank" border="0">
+                                                ipfire.png (512 x 512)</a></li>
+                                       </ul>
+                               </ul>
+                               </div>
+                       </p>
+               </p>
+       </div>
+       
+       <div class=post>
+               <h3>{{ _("IPFire in the press") }}</h3>
+               <p>
+                       {% if lang == "de" %}
+                       Hier findet ihr einige Artikel Ã¼ber IPFire in der internationalen Presse.<br />
+                       Wenn ihr neue Artikel Ã¼ber IPFire kennt die hier noch nicht aufgelistet sind, sendet uns diese an die oben angegeben Adresse, 
+                       damit diese hinzugefügt werden können.
+                       {% else %}
+                       Below are recent articles about IPFire in the international press.<br />
+                       If you know of any news stories featuring IPFire that we have not listed here, please send details to the contact given above 
+                       so that we can include them.
+                       {% end %}
+               </p>
+               <br />
+               <div class=pr_li>
+                       <ul>
+                               <li>{{ _("Press") }}:</li>
+                               <ul>
+                                       <li>www.pro-linux.de: <a href="http://www.pro-linux.de/NB3/artikel/2/613/ipfire.html" target="_blank">
+                                       Vorstellung von IPFire</a>,
+                                       &nbsp;<a href="http://www.pro-linux.de/NB3/news/1/14360/1,ipfire-25-freigegeben.html" target="_blank">
+                                       IPFire 2.5 freigegeben</a>,
+                                       &nbsp;<a href="http://www.pro-linux.de/NB3/news/1/13436/1,ipfire-23-freigegeben.html" target="_blank">
+                                       IPFire 2.3 freigegeben</a></li>                         
+                                       <li>www.heise.de: <a href="http://www.heise.de/software/download/ipfire/47736a" target="_blank">
+                                       Artikel aus c't 20/2009</a></li>
+                                       <li>www.securebase.at: <a href="http://www.securebase.at/software/application-gateways/ipfire-schutz-gegen-jegliche-art-von-spyware-malware-und-sonstigen-hacker-aktivitaten" target="_blank">Schutz gegen jegliche Art von Spyware, Malware...</a></li>
+                                       <li>www.techmonkey.de: <a href="http://www.techmonkey.de/2008/09/15/ipfire-der-nachste-star-am-soho-himmel/" target="_blank">
+                                       Der nächste Star am SOHO Himmel?</a>,
+                                       &nbsp;<a href="http://www.techmonkey.de/2009/06/24/endlich-ipfire-2-5-erschien" target="_blank">Endlich! 
+                                       IPFire 2.5 erschienen</a>
+                                       <li>www.pcwelt.de: <a href="http://www.pcwelt.de/start/sicherheit/firewall/news/187759/ipfire_auf_version_23_aktualisiert/"
+                                        target="_blank">IPFire auf Version 2.3 aktualisiert</a></li>
+                                       <li>www.lintelligence.de: <a href="http://www.lintelligence.de/news/1026" target="_blank">IPFire 2.1</a></li>
+                                       <li>www.h-online.com: <a href="http://www.h-online.com/newsticker/news/item/IPFire-the-Lean-Linux-firewall-738055.html"
+                                       target="_blank">IPFire, the Lean Linux firewall</a></li>
+                                       <li>www.4reackt.net: <a href="http://www.4reackt.net/programas-linux-rpms/5303-ipfire-v2-1-a.html"
+                                       target="_blank">IPFire v2.1</a></li>
+                               </ul>
+                               <li>Blogs:</li>
+                               <ul>
+                                       <li>linuxmini.blogspot.com: <a href="http://linuxmini.blogspot.com/2007/10/ipfire-free-firewall-for-your-home-or.html"
+                                        target="_blank">Free firewall for your home or SOHO</a></li>
+                                       <li>www.ffoutpost.net: <a href="http://www.ffoutpost.net/2009/09/01/ipfire-initial-setup" target="_blank">
+                                       IPFire Initial Setup</a>,
+                                       &nbsp;<a href="http://www.ffoutpost.net/2009/09/15/ipfire-wireless-blue-access-setup" target="_blank">IPFire 
+                                       Wireless (Blue Access) Setup</a></li>
+                               </ul>   
+                       <ul>
+               </div>          
+       </div>
+
+       <div class=post>
+               <h3>{{ _("Sponsoring") }}</h3>
+               {% if lang == "de" %}
+               <p>
+                       Da das Projekt mittlerweile auf eine stattliche Größe angewachsen ist,
+                       sind wir in vielen Bereichen auf Eure Hilfe angewiesen.
+                       Allen voran ist die (Server-)Infrastuktur für das Aufrechterhalten der
+                       Webseite inklusive des Wikis und der Foren zu nennen.
+                       Auch für genügend Platz und Bandbreite zum erstellen, 'konservieren' und
+                       verteilen der Nightly-builds muss gesorgt werden.
+               </p><br />
+               <p>
+                       Falls ihr das Projekt also unterstützen möchtet und zufällig einen
+                       Bladeserver 'übrig' habt und/oder einen freien Platz für's Server-Housing
+                       mit entsprechender Bandbreite kostenlos zur Verfügung stellen wollt,
+                       werden wir gerne auf Eure Angebote eingehen.
+                       (Unsere Entwickler freuen sich auch immer Ã¼ber neue Hardware auf der
+                       ausgiebig getestet werden kann.)
+               </p><br />
+               <p>                             
+                       Abgesehen von der Hardware sind wir auch immer auf der Suche nach
+                       helfenden Händen für die IPFire-Community.
+                       Besonders gefragt sind Personen, die sich mit Linux auskennen und die
+                       neuesten Funktionen und Addons testen und Fehler melden,
+                       aktive Forenmoderatoren, Wiki-Dokumentatoren sowie Web- und Grafikdesigner.
+               </p><br />
+               <p>                             
+                       Um die IPFire-Community zu unterstützen, melden Sie sich einfach im <a href="http://forum.ipfire.org">Forum</a>
+                       oder im IRC-Channel <a href="http://webchat.freenode.net/?channels=ipfire" target="_blank">#ipfire</a> 
+                       auf irc.freenode.net.
+               </p><br />
+               <p>
+                       Momentan besonders dringend benötigt werden:
+               <div class="li_pr">
+                       <ul>
+                               <li>Neuer Server mit ausreichend Platz</li>
+                               <li>und Hosting/Housingpartner mit hoher Bandbreite</li>
+               <br />
+                               <li>Spenden für die <a href="cebit">CeBIT 2010</a></li>
+                       </ul>
+               </div>
+               </p>
+               {% else %}
+               <p>
+                       <em>General information about sponsorshop and partners - need to be translated </em>
+               </p>
+               {% end %}
+               <br />
+               
+               <h4>{{ _("friends of ipfire") }}</h4>
+                       <p>
+                               {% if lang == "de" %}
+                                       Die folgenden User ermöglichen dem Projekt die Nutzung ihrer persönlichen Server (<a href="downloads/mirrors">Mirror</a>,
+                                        Build und Root Server).
+                                       An dieser Stelle möchten wir uns bei Allen für ihre Unterstützung bedanken. (Liste in alphabetischer Reihenfolge.)
+                               {% else %}
+                                       The following users are supporting the project by sharing their personal server (<a href="downloads/mirrors">mirror</a>,
+                                        build, and root servers).
+                                       At this point we would like to thank all for their help. (List in alphabetical order.)
+                               {% end %}
+                               <div class=pr_li>
+                               <ul>
+                                       <li>Kim Barthel: <a href="http://www.kbarthel.de" target="_blank">www.kbarthel.de</a></li>
+                                       <li>Peter Schaelchli: <a href="http://www.scp-systems.ch" target="_blank">www.scp-systems.ch</a></li>
+                                       <li>Ronald Wiesinger: <a href="http://www.rowie.at" target="_blank">www.rowie.at</a></li>
+                                       <li>Sebastian Winter</li>
+                                </ul>
+                                </div>
+                        </p>           
+       </div>
+
+
+
+{% end block %}
+
+{% block sidebar %}
+               <h4>Public <span>relations</span></h4>
+               <ul class="links">              
+                       <li class="first"><a href="#{{ _("Press") }}">{{ _("Press") }}</a></li>
+                               <li><a href="#{{ _("Press kit") }}">{{ _("Press kit") }}</a></li>
+                               <li><a href="#{{ _("Logos and print artworks") }}">{{ _("Logos and print artworks") }}</a></li>
+                       <li class="first"><a href="#{{ _("IPFire in the press") }}">{{ _("IPFire in the press") }}</a></li>
+                       <li><a href="#{{ _("Sponsoring") }}">{{ _("Sponsoring") }}</a></li>
+                               <li><a href="#{{ _("friends of ipfire") }}">{{ _("friends of ipfire") }}</a></li>
+               </ul>
+{% end block %}
diff --git a/www/templates/static/screenshots.html b/www/templates/static/screenshots.html
new file mode 100644 (file)
index 0000000..c0dd9e4
--- /dev/null
@@ -0,0 +1,118 @@
+{% extends "../base.html" %}
+               
+{% block title %}{{ _("Screenshots") }}{% end block %}
+
+{% block content %}
+       
+       
+       <div class=post>
+               <h3>{{ _("Sceenshots") }}</h3>
+               <img src="{{ static_url("images/page_icons/screenshots.png") }}" class="floatTR" border="0" alt="{{ _("Sceenshots") }}" />
+               <p>
+                       {% if lang == "de" %}
+                               Hier findet ihr einen Einblick in das IPFire Webinterface.      
+                       {% else %}
+                               Here you will find an insight into the IPFire webinterface.
+                       {% end %}
+               </p>
+       </div>
+       
+       <br class="clear" />
+       <div class=post>
+               <h3>{{ _("System") }}</h3>
+               <div id="screenshots">
+                       &nbsp;&nbsp;&nbsp;
+                       <a href="{{ static_url("images/screenshots/index_%s.png" % lang) }}" title="{{ _("Home") }}"><img src="{{ static_url("images/screenshots/index_%s_tn.png" % lang) }}" border="0" alt="{{ _("Home") }}" /></a>
+                       &nbsp;&nbsp;&nbsp;
+                       <a href="{{ static_url("images/screenshots/backup_%s.png" % lang) }}" title="{{ _("Backup") }}"><img src="{{ static_url("images/screenshots/backup_%s_tn.png" % lang) }}" border="0" alt="{{ _("Backup") }}" /></a>
+               </div>
+       </div>
+       
+       <div class=post>
+               <h3>{{ _("Status") }}</h3>
+               <div id="screenshots">
+                       &nbsp;&nbsp;&nbsp;                              
+                       <a href={{ static_url("images/screenshots/services_%s.png" % lang) }}" title="{{ _("Services") }}"><img src={{ static_url("images/screenshots/services_%s_tn.png" % lang) }}" border="0" alt="{{ _("Services") }}"></a>
+                       &nbsp;&nbsp;&nbsp;
+                       <a href={{ static_url("images/screenshots/networkother_%s.png" % lang) }}" title="{{ _("Network (other)") }}"><img src={{ static_url("images/screenshots/networkother_%s_tn.png" % lang) }}" border="0" alt="Network (other)"></a>
+                       &nbsp;&nbsp;&nbsp;
+                       <a href={{ static_url("images/screenshots/connections_%s.png" % lang) }}" title="{{ _("Connections") }}"><img src={{ static_url("images/screenshots/connections_%s_tn.png" % lang) }}" border="0" alt="{{ _("Connections") }}"></a>
+               </div>
+       </div>          
+
+
+       <div class=post>
+               <h3>{{ _("Network") }}</h3>
+               <div id="screenshots">
+                       &nbsp;&nbsp;&nbsp;                              
+                       <a href={{ static_url("images/screenshots/dhcp_%s.png" % lang) }}" title="{{ _("DHCP Server") }}"><img src={{ static_url("images/screenshots/dhcp_%s_tn.png" % lang) }}" border="0" alt="{{ _("DHCP Server") }}"></a>
+               </div>          
+       </div>
+
+       
+       <div class=post>
+               <h3>{{ _("Services") }}</h3>
+               <div id="screenshots">
+                       &nbsp;&nbsp;&nbsp;                      
+                       <a href={{ static_url("images/screenshots/ipsec_%s.png" % lang) }}" title="{{ _("IPSec") }}"><img src={{ static_url("images/screenshots/ipsec_%s_tn.png" % lang) }}" border="0" alt="{{ _("IPSec") }}"></a>
+                       &nbsp;&nbsp;&nbsp;
+                       <a href={{ static_url("images/screenshots/qos_%s.png" % lang) }}" title="{{ _("Quality of Service") }}"><img src={{ static_url("images/screenshots/qos_%s_tn.png" % lang) }}" border="0" alt="{{ _("Quality of Service") }}"></a>
+               </div>  
+       </div>
+
+
+       <div class=post>
+               <h3>{{ _("Firewall") }}</h3>
+               <div id="screenshots">
+                       &nbsp;&nbsp;&nbsp;                              
+                       <a href={{ static_url("images/screenshots/outgoing_fw_%s.png" % lang) }}" title="{{ _("Outgoing Firewall") }}"><img src={{ static_url("images/screenshots/outgoing_fw_%s_tn.png" % lang) }}" border="0" alt="{{ _("Outgoing Firewall") }}"></a>
+               </div>                  
+       </div>
+
+
+       <div class=post>
+               <h3>{{ _("IPFire") }}</h3>
+               <div id="screenshots">
+                       &nbsp;&nbsp;&nbsp;                              
+                       <a href={{ static_url("images/screenshots/pakfire_%s.png" % lang) }}" title="{{ _("Pakfire") }}"><img src={{ static_url("images/screenshots/pakfire_%s_tn.png" % lang) }}" border="0" alt="{{ _("Pakfire") }}"></a>                                                             
+                       &nbsp;&nbsp;&nbsp;
+                       <a href={{ static_url("images/screenshots/samba_%s.png" % lang) }}" title="{{ _("Samba") }}"><img src={{ static_url("images/screenshots/samba_%s_tn.png" % lang) }}" border="0" alt="{{ _("Samba") }}"></a>
+               </div>  
+       </div>
+
+
+       <div class=post>
+               <h3>{{ _("Logs") }}</h3>
+               <div id="screenshots">
+                       &nbsp;&nbsp;&nbsp;                      
+                       <a href={{ static_url("images/screenshots/fwlog_ip_%s.png" % lang) }}" title="{{ _("Fw-Logdgraphs (IP)") }}"><img src={{ static_url("images/screenshots/fwlog_ip_%s_tn.png" % lang) }}" border="0" alt="{{ _("Fw-Logdgraphs (IP)") }}"></a>
+                       &nbsp;&nbsp;&nbsp;
+                       <a href={{ static_url("images/screenshots/proxy_%s.png" % lang) }}" title="{{ _("Proxy Reports") }}"><img src={{ static_url("images/screenshots/proxy_%s_tn.png" % lang) }}" border="0" alt="{{ _("Proxy Reports") }}"></a>
+               </div>
+       </div>
+       
+{% end block %}
+
+{% block sidebar %}
+               <h4><span>{{ _("Screenshot") }}</span> list</h4>
+               <ul class="links">              
+                       <li class="first"><a href="#{{ _("System") }}">{{ _("System") }}</a></li>
+                       <li><a href="#{{ _("Status") }}">{{ _("Status") }}</a></li>
+                       <li><a href="#{{ _("Network") }}">{{ _("Network") }}</a></li>
+                       <li><a href="#{{ _("Services") }}">{{ _("Services") }}</a></li>
+                       <li><a href="#{{ _("Firewall") }}">{{ _("Firewall") }}</a></li>
+                       <li><a href="#{{ _("IPFire") }}">{{ _("IPFire") }}</a></li>
+                       <li><a href="#{{ _("Logs") }}">{{ _("Logs") }}</a></li>
+               </ul>
+ {{ modules.SidebarBanner(banner) }}
+
+{% end block %}
+
+{% block javascript %}
+       <script type="text/javascript" src="{{ static_url("js/jquery.lightbox.min.js") }}"></script>
+       <script type="text/javascript">
+               $(function() {
+                       $("#screenshots a").lightBox();
+               });
+       </script>
+{% end block %}
diff --git a/www/templates/translations.html b/www/templates/translations.html
new file mode 100644 (file)
index 0000000..549abb5
--- /dev/null
@@ -0,0 +1,55 @@
+{% extends "base.html" %}
+
+{% block title %}{{ _("Translations") }}{% end block %}
+
+{% block content %}
+       <h3>IPFire {{ _("Translation Status") }}</h3>
+       
+       <div id="tabs">
+               <ul>
+                       {% for project in projects %}
+                               <li>
+                                       <a href="#{{ project.id }}">{{ project.name }}</a>
+                               </li>
+                       {% end %}
+               </ul>
+       </div>
+       
+       {% for project in projects %}
+               <div id="{{ project.id }}">
+                       <p><strong>{{ _("Description") }}:</strong> {{ project.desc }}</p>
+                       <br />
+                       <table class="translate">
+                               <tr>
+                                       <th>{{ _("Language") }}</th>
+                                       <th>{{ _("Translated") }}</th>
+                                       <th>{{ _("Untranslated") }}</th>
+                                       <th>{{ _("Fuzzy") }}</th>
+                                       <th>{{ _("Status") }}</th>
+                               </tr>
+
+                               {% for translation in project.translations %}
+                                       <tr>
+                                               <td class="lang"><img src="{{ static_url("images/flags/%s.png" % translation.code) }}"
+                                                       alt="{{ translation.code }}" />{{ translation.lang }}</td>
+                                               <td>{{ translation.translated }}</td>
+                                               <td>{{ translation.untranslated }}</td>
+                                               <td>{{ translation.fuzzy }}</td>
+                                               <td>{{ translation.percent }}</td>
+                                       </tr>
+                               {% end %}
+                       </table>
+       {% end %}
+
+       <p class="right">
+               <strong>{{ _("Template") }}</strong> - {{ project.total_strings }} strings
+       </p>
+{% end block %}
+
+{% block javascript %}
+       <script type="text/javascript">
+               $(function() {
+                       $("#tabs").tabs();
+               });
+       </script>
+{% end block %}
diff --git a/www/translations/de_DE.csv b/www/translations/de_DE.csv
new file mode 100644 (file)
index 0000000..d466214
--- /dev/null
@@ -0,0 +1,84 @@
+"Alix image","Alix-Image"
+"An image that is meant to run on embedded devices.","Fertiges Image für Embedded-Geräte."
+"Arch","Arch"
+"Area","Bereich"
+"A ready-to-run image for Xen.","Schlüsselfertiges Xen-Image."
+"Begin download","Download starten"
+"by","von"
+"CeBIT-Donation","CeBIT-Spende"
+"Cluster's CPU load","Prozessorauslastung des Clusters"
+"Connections","Verbindungen"
+"CPU-Load","CPU-Auslastung"
+"Current unstable","Entwicklungsversion"
+"Current version","Aktuelle Version"
+"Description","Beschreibung"
+"Development","Entwicklung"
+"DHCP Server","DHCP-Server"
+"Download file","Datei herunterladen"
+"Download the CD image from the torrent network.","Laden Sie das CD-Image Ã¼ber das Torrent Netzwerk."
+"File","Datei"
+"Firewall","Firewall"
+"Fuzzy","Fuzzy"
+"Fw-Logdgraphs (IP)","Fw-Logdgraphs (IP)"
+"Got that information from <em>%s</em> within %.2f second(s).","Dauer der Abfrage von <em>%s</em>: %.2f Sekunde(n)."
+"Home","Startseite"
+"If the floppy image doesn't work, use this image instead.","USB-Stick-Image als Harddisk formatiert."
+"imprint","Impressum"
+"Installable CD image","Bootbares CD-Image"
+"Install IPFire from a floppy-formated USB key.","Installationsimage für USB-Sticks als Floppy formatiert."
+"IPFire in the press","IPFire in der Presse"
+"IPSec","IPSec"
+"Job load","Job-Auslastung"
+"Jobs","Jobs"
+"Language","Sprache"
+"Logos and print artworks","Logos und Druckvorlagen"
+"More security for your network","mehr sicherheit für Ihr netzwerk"
+"Name","Name"
+"Network","Netzwerk"
+"Network (other)","Netzwerk (sonstige)"
+"Number of nodes","Anzahl der Knoten"
+"Other download options","Weitere Downloadoptionen"
+"Outgoing Firewall","Ausgehende Firewall"
+"Pakfire","Pakfire"
+"Pregenerated Xen image","Xen-Image"
+"Press kit","Pressemappe"
+"Press","Presse"
+"Previous posts >>","Vorherige Einträge >>"
+"Proxy Reports","Proxyberichte"
+"Public Relations","Public Relations"
+"Quality of Service","Quality of Service"
+"<strong>release</strong> information","<strong>Release</strong>informationen"
+"Release","Release"
+"Samba","Samba"
+"See all torrents...","Alle Torrent-Downloads anzeigen..."
+"See development releases...","Entwicklungsversionen anzeigen..."
+"See older downloads...","Ältere Downloads anzeigen..."
+"Services","Dienste"
+"Sponsoring","Sponsoring"
+"Status","Status"
+"<strong>Online</strong> media","<strong>Online</strong>medien"
+"<strong>Print</strong> media","<strong>Print</strong>medien"
+"System","System"
+"Template","Vorlage"
+"Torrent file","Torrent-Download"
+"Translated","Ãœbersetzt"
+"Translation Status","Ãœbersetzungsüberblick"
+"Untranslated","Nicht Ã¼bersetzt"
+"USB FDD image","USB-Floppy-Image"
+"USB HDD image","USB-Harddisk-Image"
+"Use this image to burn a CD and install IPFire from it.","Brennen Sie dieses Image und booten Sie die Installation davon."
+"Owner (Hostname)","Eigentümer (Hostname)"
+"Priority","Priorität"
+"Location","Standort"
+"Latency","Latenz"
+"Legend","Legende"
+"Server is reachable","Server ist erreichbar"
+"Server is unreachable","Server ist nicht erreichbar"
+"Get back to latest stable downloads.","Zurück zur aktuellen Version."
+"Here you will find the downloads for the version","Hier findet ihr die Downloads für die Version"
+"These are the ancient downloads of IPFire. They are just saved for historical reasons and should not be used in a productive environment.","Dies sind veraltete Downloads von IPFire. Sie sind nur aus historischen Gründen gespeichert und sollten nicht mehr in einer produktiven Umgebung eingesetzt werden."
+"Donation","Spende"
+"Development Area","Entwicklungsbereich"
+"See a list of mirrors...","Liste der Mirror-Server anzeigen..."
+"Flash image where a serial console is enabled by default.","Flash-Image mit eingeschalteter serieller Konsole."
+"Flash image","Flash-Image"
diff --git a/www/web/__init__.py b/www/web/__init__.py
deleted file mode 100644 (file)
index e137f5f..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-import os
-import cgi
-import time
-
-try:
-       import cStringIO as StringIO
-except ImportError:
-       import StringIO
-
-from http import HTTPResponse, WebError
-
-import info
-import lang
-import menu
-
-class Data:
-       def __init__(self):
-               self.output = ""
-       
-       def w(self, s):
-               self.output += "%s\n" % s
-       
-       write = w
-               
-       def __call__(self):
-               return self.output
-
-
-class Page(object):
-       def __init__(self):
-               self.io = StringIO.StringIO()
-
-               self.info = info.Info()
-               self.langs = lang.Languages()
-               self.menu = menu.Menu(self.langs.current)
-               self.site = self.title = cgi.FieldStorage().getfirst("site", default="index")
-
-               self.content = None
-               self.javascript = None
-               self.sidebar = None
-
-       @property
-       def data(self):
-               ret = { "content" : "",
-                                "javascript": "",
-                                "lang"   : self.langs.current,
-                                "languages" : self.langs.menu(self.site),
-                                "menu"   : self.menu(),
-                                "name"   : self.info["name"],
-                                "server" : os.environ["SERVER_NAME"].replace("ipfire", "<span>ipfire</span>"),
-                                "sidebar" : "",
-                                "slogan" : self.info["slogan"],
-                                "sname"  : self.info["sname"],
-                                "title"  : "%s - %s" % (os.environ["SERVER_NAME"], self.title,),                                
-                                "year"   : time.strftime("%Y"),}
-
-               if self.content:
-                       ret["content"] = self.content(self.langs.current)
-               if self.javascript:
-                       ret["javascript"] = self.javascript(self.langs.current)
-               if self.sidebar:
-                       ret["sidebar"] = self.sidebar(self.langs.current)
-
-               return ret
-                       
-       def include(self, file):
-               f = open(file)
-               output = f.read()
-               f.close()
-               self.io.write(output % self.data)
-
-       def __call__(self):
-               type = "text/html"
-               try:
-                       if self.title.endswith(".rss"):
-                               self.include("rss.inc")
-                               type = "application/rss+xml"
-                       else:
-                               self.include("template.inc")
-                       code = 200
-               except WebError:
-                       code = 500
-               h = HTTPResponse(code, type=type)
-               h.execute(self.io.getvalue())
-
-               
-class Content(Data):
-       def __init__(self):
-               Data.__init__(self)
-
-       def content(self):
-               self.w("""<h3>Test Page</h3>
-                       <p>Lorem ipsum dolor sit amet, consectetuer sadipscing elitr,
-                       sed diam nonumy eirmod tempor invidunt ut labore et dolore magna
-                       aliquyam erat, sed diam voluptua. At vero eos et accusam et justo
-                       duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
-                       sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
-                       consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt
-                       ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero
-                       eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
-                       gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
-                       Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
-                       nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
-                       sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
-                       rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem
-                       ipsum dolor sit amet.</p>""")
-               
-               b = Box("Test box one", "Subtitle of box")
-               b.write("""<p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit
-                       esse molestie consequat, vel illum dolore eu feugiat nulla facilisis
-                       at vero eros et accumsan et iusto odio dignissim qui blandit praesent
-                       luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
-                       Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam
-                       nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat
-                       volutpat.</p>""")
-               self.w(b())
-
-               b = Box("Test box two", "Subtitle of box")
-               b.write("""<p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
-                       suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem
-                       vel eum iriure dolor in hendrerit in vulputate velit esse molestie
-                       consequat, vel illum dolore eu feugiat nulla facilisis at vero eros
-                       et accumsan et iusto odio dignissim qui blandit praesent luptatum
-                       zzril delenit augue duis dolore te feugait nulla facilisi.</p>""")
-               self.w(b())
-
-       def __call__(self, lang="en"):
-               self.content()
-               return Data.__call__(self)
diff --git a/www/web/banners.py b/www/web/banners.py
deleted file mode 100644 (file)
index 60172d5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/python
-
-import random
-
-from json import Json
-
-class Banners(Json):
-       def __init__(self, lang="en"):
-               self.lang = lang
-               Json.__init__(self, "banners.json")
-
-       def random(self):
-               banner = random.choice(self.json.values())
-               return banner
-
diff --git a/www/web/elements.py b/www/web/elements.py
deleted file mode 100644 (file)
index e1adbfb..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/python
-
-from web import Data
-from banners import Banners
-from info import Info
-
-class Box(Data):
-       def __init__(self, headline, subtitle=""):
-               Data.__init__(self)
-               self.w("""<div class="post"><a name="%s"></a><h3>%s</h3>""" % (headline,headline,))
-               if subtitle:
-                       self.w("""<div class="post_info">%s</div>""" % (subtitle,))
-
-       def __call__(self):
-               self.w("""<br class="clear" /></div>""")
-               return Data.__call__(self)
-
-class Sidebar(Data):
-       def __init__(self):
-               Data.__init__(self)
-
-       def content(self, lang):
-               banners = Banners()
-               self.w("""<h4>%(title)s</h4><a href="%(link)s" target="_blank">
-                       <img class="banner" src="%(uri)s" /></a>""" % banners.random())
-
-       def __call__(self, lang):
-               self.content(lang)
-               return Data.__call__(self)
-
-class Releases(Data):
-       def __init__(self):
-               Data.__init__(self)
-       
-       def content(self, lang):
-               info = Info()
-               if lang == "de":
-                       self.write("""<h4><span>release</span> informationen</h4>
-                               <p><strong>Aktuelle Version</strong>:<br />%(stable)s</p>
-                               <p><strong>Testversionen</strong>:<br />%(testing)s</p>
-                       """ % info["releases"])
-               else:
-                       self.write("""<h4><span>info</span>rmation</h4>
-                               <p><strong>Current version</strong>:<br />%(stable)s</p>
-                               <p><strong>Current unstables</strong>:<br />%(testing)s</p>
-                       """ % info["releases"])
-       
-       def __call__(self, lang):
-               self.content(lang)
-               return Data.__call__(self)
-
-class DevelopmentSidebar(Sidebar):
-       def __init__(self):
-               Sidebar.__init__(self)
-
-       def __call__(self, lang):
-               return Sidebar.__call__(self, lang)
-
-       def content(self, lang):
-               self.w("""<h4>Development Ressources</h4>
-                               <p> - <a href="cluster">Cluster</a> Monitoring<br />
-                                       - Nightly <a href="builds">Builds</a><br />
-                                       - <a href="source">Source</a> Code<br />
-                                       - Pakfire <a href="pakfire3">Repositories</a><br />
-                                       - <a href="translate">Localization</a> Status</p>
-               """)
diff --git a/www/web/http.py b/www/web/http.py
deleted file mode 100644 (file)
index 76f547a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-code2msg = { 200 : "OK",
-                        302 : "Temporarily Moved",
-                        404 : "Not found",
-                        500 : "Internal Server Error", }
-
-class HTTPResponse:
-       def __init__(self, code, header=None, type="text/html"):
-               self.code = code
-
-               print "Status: %s - %s" % (self.code, code2msg[self.code],)
-               if self.code == 302:
-                       print "Pragma: no-cache"
-               if type:
-                       print "Content-type: " + type
-               if header:
-                       for (key, value,) in header:
-                               print "%s: %s" % (key, value,)
-               print
-
-       def execute(self, content=""):
-               if self.code == 200:
-                       print content
-
-class WebError(Exception):
-       pass
diff --git a/www/web/info.py b/www/web/info.py
deleted file mode 100644 (file)
index 2baf722..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/python
-
-from json import Json
-
-class Info(Json):
-       def __init__(self):
-               Json.__init__(self, "info.json")
-
-       def get(self, key):
-               if not self.json.has_key(key):
-                       raise KeyError
-               return self.json[key]
-       
-       __getitem__ = get
diff --git a/www/web/javascript.py b/www/web/javascript.py
deleted file mode 100644 (file)
index 8c703ca..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/python
-
-try:
-       import cStringIO as StringIO
-except ImportError:
-       import StringIO
-
-class Javascript(object):
-       def __init__(self, jquery=0, jqueryui=0):
-               self.io = StringIO.StringIO()
-
-               if jquery:
-                       self.io.write("""<script src="/include/jquery.min.js" type="text/javascript"></script>""")
-               
-               if jqueryui:
-                       self.io.write("""<script src="/include/jquery-ui.min.js" type="text/javascript"></script>""")
-       
-       def __call__(self, lang="en"):
-               return self.io.getvalue()
-
-       def jquery_plugin(self, plugin):
-               self.io.write("""<script src="/include/jquery.%s.min.js" type="text/javascript"></script>""" % plugin)
-
-       def write(self, s):
-               self.io.write(s)
diff --git a/www/web/json.py b/www/web/json.py
deleted file mode 100644 (file)
index ef0a85d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/python
-
-import simplejson as json
-
-class Json:
-       def __init__(self, file):
-               f = open(file)
-               data = f.read()
-               data = data.replace('\n', '') # Remove all \n
-               data = data.replace('\t', ' ') # Remove all \t
-               self.json = json.loads(data)
-               f.close()
diff --git a/www/web/lang.py b/www/web/lang.py
deleted file mode 100644 (file)
index 973d7dc..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/python
-
-import locale
-import cgi
-
-lang2locale = { "de" : "de_DE.utf8",
-                               "en" : "en_US.utf8", }
-
-class Languages:
-       def __init__(self, doc=""):
-               self.available = []
-
-               for lang in ("de", "en",):
-                       self.append(lang,)
-               
-               self.current = cgi.FieldStorage().getfirst("lang") or "en"
-               if lang2locale.has_key(self.current):
-                       locale.setlocale(locale.LC_ALL, lang2locale[self.current])
-
-       def append(self, lang):
-               self.available.append(lang)
-
-       def menu(self, doc):
-               s = ""
-               for lang in self.available:
-                       s += """<a href="/%(lang)s/%(doc)s"><img src="/images/%(lang)s.gif" alt="%(lang)s" /></a>""" % \
-                               { "lang" : lang, "doc" : doc, }
-               return s
diff --git a/www/web/menu.py b/www/web/menu.py
deleted file mode 100644 (file)
index c02b78c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/python
-
-import os
-
-from json import Json
-
-class Menu(Json):
-       def __init__(self, lang):
-               self.lang = lang
-               Json.__init__(self, "menu.json")
-
-       def __call__(self):
-               s = """<div id="menu"><ul>\n"""
-               for item in self.json.values():
-                       item["active"] = ""
-
-                       # Grab language
-                       if type(item["name"]) == type({}):
-                               item["name"] = item["name"][self.lang]
-
-                       # Add language attribute to local uris
-                       if item["uri"].startswith("/"):
-                               item["uri"] = "/%s%s" % (self.lang, item["uri"],)
-
-                       if os.environ["REQUEST_URI"].endswith(item["uri"]):
-                               item["active"] = "class=\"active\""
-
-                       s += """<li><a href="%(uri)s" %(active)s>%(name)s</a></li>\n""" % item
-               s += "</ul></div>"
-               return s
diff --git a/www/web/news.py b/www/web/news.py
deleted file mode 100644 (file)
index 5daf057..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/python
-
-from elements import Box
-from json import Json
-
-class News(Json):
-       def __init__(self, limit=3):
-               Json.__init__(self, "news.json")
-               self.news = []
-               for key in sorted(self.json.keys()):
-                       self.news.insert(0, self.json[key])
-               if limit:
-                       self.news = self.news[:limit]
-
-       def html(self, lang="en"):
-               s = ""
-               for item in self.news:
-                       for i in ("content", "subject",):
-                               if type(item[i]) == type({}):
-                                       item[i] = item[i][lang]
-                       b = Box(item["subject"], "%(date)s - by %(author)s" % item)
-                       b.w(item["content"])
-                       if item["link"]:
-                               if lang == "en":
-                                       b.w("""<p><a href="%(link)s" target="_blank">Read more.</a></p>""" % item)
-                               elif lang == "de":
-                                       b.w("""<p><a href="%(link)s" target="_blank">Mehr Informationen.</a></p>""" % item)
-                       s += b()
-               return s
-
-       __call__ = html
-
-       def headlines(self, lang="en"):
-               headlines = []
-               for item in self.news:
-                       if type(item["subject"]) == type({}):
-                               item["subject"] = item["subject"][lang]
-                       headlines.append((item["subject"],))
-               return headlines
-
-       def items(self):
-               return self.news
diff --git a/www/webapp.py b/www/webapp.py
new file mode 100755 (executable)
index 0000000..eae4848
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/python2.6
+
+import tornado.httpserver
+import tornado.ioloop
+
+from webapp import Application
+application = Application()
+
+if __name__ == "__main__":
+       http_server = tornado.httpserver.HTTPServer(application, xheaders=True)
+       http_server.listen(8001)
+
+       try:
+               tornado.ioloop.IOLoop.instance().start()
+       except KeyboardInterrupt:
+               # Shutdown mirror monitoring
+               from webapp.mirrors import mirrors
+               mirrors.shutdown()
+
+               raise
diff --git a/www/webapp/__init__.py b/www/webapp/__init__.py
new file mode 100644 (file)
index 0000000..a8e34c5
--- /dev/null
@@ -0,0 +1,110 @@
+#/usr/bin/python
+
+import os.path
+import simplejson
+
+simplejson._default_decoder = simplejson.JSONDecoder(encoding="latin-1")
+
+import tornado.locale
+import tornado.options
+import tornado.web
+
+from db import HashDatabase
+from handlers import *
+from ui_modules import *
+
+BASEDIR = os.path.join(os.path.dirname(__file__), "..")
+
+tornado.locale.load_translations(os.path.join(BASEDIR, "translations"))
+tornado.options.enable_pretty_logging()
+
+class Application(tornado.web.Application):
+       def __init__(self):
+               settings = dict(
+                       cookie_secret = "aXBmaXJlY29va2llc2VjcmV0Cg==",
+                       #debug = True,
+                       gzip = True,
+                       template_path = os.path.join(BASEDIR, "templates"),
+                       ui_modules = {
+                               "Build"          : BuildModule,
+                               "Menu"           : MenuModule,
+                               "MenuItem"       : MenuItemModule,
+                               "NewsItem"       : NewsItemModule,
+                               "ReleaseItem"    : ReleaseItemModule,
+                               "SidebarBanner"  : SidebarBannerModule,
+                               "SidebarItem"    : SidebarItemModule,
+                               "SidebarRelease" : SidebarReleaseModule,
+                       },
+                       xsrf_cookies = True,
+               )
+
+               tornado.web.Application.__init__(self, **settings)
+
+               # Initialize database connections
+               self.hash_db = HashDatabase()
+
+               self.settings["static_path"] = static_path = os.path.join(BASEDIR, "static")
+               static_handlers = [
+                       (r"/static/(.*)", tornado.web.StaticFileHandler, dict(path = static_path)),
+                       (r"/(favicon\.ico)", tornado.web.StaticFileHandler, dict(path = static_path)),
+                       (r"/(robots\.txt)", tornado.web.StaticFileHandler, dict(path = static_path)),
+               ]
+
+               self.add_handlers(r"(dev|www)\.ipfire\.(at|org)", [
+                       # Entry sites that lead the user to index
+                       (r"/", MainHandler),
+                       (r"/[A-Za-z]{2}/?", MainHandler),
+                       #
+                       (r"/[A-Za-z]{2}/index", IndexHandler),
+                       (r"/[A-Za-z]{2}/news", NewsHandler),
+                       (r"/[A-Za-z]{2}/builds", BuildHandler),
+                       (r"/[A-Za-z]{2}/translations?", TranslationHandler),
+                       # Download sites
+                       (r"/[A-Za-z]{2}/downloads?", DownloadHandler),
+                       (r"/[A-Za-z]{2}/downloads?/all", DownloadAllHandler),
+                       (r"/[A-Za-z]{2}/downloads?/development", DownloadDevelopmentHandler),
+                       (r"/[A-Za-z]{2}/downloads?/mirrors", DownloadMirrorHandler),
+                       (r"/[A-Za-z]{2}/downloads?/torrents", DownloadTorrentHandler),
+                       # API
+                       (r"/api/cluster_info", ApiClusterInfoHandler),
+                       # Always the last rule
+                       (r"/[A-Za-z]{2}/(.*)", StaticHandler),
+               ] + static_handlers)
+
+               # download.ipfire.org
+               self.add_handlers(r"download\.ipfire\.org", [
+                       (r"/", tornado.web.RedirectHandler, { "url" : "http://www.ipfire.org/" }),
+                       (r"/(favicon\.ico)", tornado.web.StaticFileHandler, dict(path = static_path)),
+                       (r"/(.*)", DownloadFileHandler),
+               ])
+
+               # source.ipfire.org
+               self.add_handlers(r"source\.ipfire\.org", [
+                       (r"/", MainHandler),
+                       (r"/[A-Za-z]{2}/?", MainHandler),
+                       (r"/[A-Za-z]{2}/index", SourceHandler),
+                       (r"(/source.*)", SourceDownloadHandler),
+               ] + static_handlers)
+
+               # torrent.ipfire.org
+               self.add_handlers(r"torrent\.ipfire\.org", [
+                       (r"/", MainHandler),
+                       (r"/[A-Za-z]{2}/?", MainHandler),
+                       (r"/[A-Za-z]{2}/index", DownloadTorrentHandler),
+               ] + static_handlers)
+
+               # tracker.ipfire.org
+               self.add_handlers(r"tracker\.ipfire\.org", [
+                       (r"/", MainHandler),
+                       (r"/[A-Za-z]{2}/?", MainHandler),
+                       (r"/[A-Za-z]{2}/index", DownloadTorrentHandler),
+               ] + static_handlers)
+
+               # ipfire.org
+               self.add_handlers(r".*", [
+                       (r".*", tornado.web.RedirectHandler, { "url" : "http://www.ipfire.org" })
+               ])
+
+       def __del__(self):
+               from mirrors import mirrors
+               mirrors.stop()
diff --git a/www/webapp/banners.py b/www/webapp/banners.py
new file mode 100644 (file)
index 0000000..ba21ab9
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+
+import random
+
+from helpers import Item, _stringify, json_loads
+
+class Banners(object):
+       def __init__(self, filename=None):
+               self.items = []
+
+               if filename:
+                       self.load(filename)
+
+       def load(self, filename):
+               f = open(filename)
+               data = f.read()
+               f.close()
+               
+               for item in json_loads(data):
+                       self.items.append(Item(**_stringify(item)))
+
+       def get(self):
+               return random.choice(self.items)
+
+
+banners = Banners("banners.json")
diff --git a/www/webapp/builds.py b/www/webapp/builds.py
new file mode 100644 (file)
index 0000000..49dbace
--- /dev/null
@@ -0,0 +1,89 @@
+#!/usr/bin/python
+
+import os
+import time
+
+from helpers import size
+from info import info
+
+def find():
+       ret = []
+       for item in info["nightly_builds"]:
+               path = item.get("path", None)
+               if not path or not os.path.exists(path):
+                       continue
+
+               for host in os.listdir(path):
+                       for build in os.listdir(os.path.join(path, host)):
+                               ret.append(Build(os.path.join(path, host, build)))
+
+       return ret
+
+class Build(object):
+       def __init__(self, path):
+               self.path = path
+
+               self.__buildinfo = None
+       
+       @property
+       def buildinfo(self):
+               if not self.__buildinfo:
+                       f = open(os.path.join(self.path, ".buildinfo"))
+                       self.__buildinfo = f.readlines()
+                       f.close()
+               return self.__buildinfo
+
+       def get(self, key):
+               key = key.upper() + "="
+               for line in self.buildinfo:
+                       if line.startswith(key):
+                               return line[len(key):].strip("\n")
+
+       @property
+       def build_host(self):
+               return self.get("hostname")
+
+       @property
+       def release(self):
+               return self.get("release")
+
+       @property
+       def time(self):
+               return time.localtime(float(self.get("date")))
+
+       @property
+       def date(self):
+               return time.strftime("%a, %Y-%m-%d %H:%M", self.time)
+
+       @property
+       def arch(self):
+               return self.get("arch")
+
+       @property
+       def iso(self):
+               return self.get("iso")
+
+       @property
+       def size(self):
+               return size(os.path.getsize(os.path.join(self.path, self.iso)))
+
+       @property
+       def packages(self):
+               path = "%s/packages_%s" % (self.path, self.arch,)
+               if not os.path.exists(path):
+                       return []
+               return os.listdir(path)
+
+       @property
+       def pxe(self):
+               dir = "/srv/www/ipfire.org/pxe"
+               if not os.path.isdir(dir):
+                       return ""
+
+               for iso in os.listdir(dir):
+                       # Skip non-iso files
+                       if not iso.endswith(".iso"):
+                               continue
+                       if os.readlink(os.path.join(dir, iso)) == os.path.join(self.path, self.iso):
+                               return "[PXE]"
+               return ""
similarity index 97%
rename from www/web/cluster.py
rename to www/webapp/cluster.py
index bddf3fe4b2aa2d038b2950e9a030194e2c70cbcf..7afc2977e1ac993e126743da0ce4fddfcaf79667 100644 (file)
@@ -3,8 +3,6 @@
 import os
 import telnetlib
 
-import simplejson as json
-
 class Node(object):
        def __init__(self, hostname, address, arch, speed, jobcount, load, installing):
                self.hostname = hostname
@@ -28,6 +26,9 @@ class Node(object):
        def __repr__(self):
                return "<Node %s>" % self.hostname
 
+       def __cmp__(self, other):
+               return cmp(self.hostname, other.hostname)
+
        def print_node(self):
                print "Hostname : %s" % self.hostname
                print "  Address: %s" % self.address
@@ -111,7 +112,7 @@ class Cluster(object):
                                node = Node(hostname, address, arch, speed, jobcount, load, installing)
                                ret.append(node)
                        
-               self._nodes = ret
+               self._nodes = sorted(ret)
                return ret
 
        @property
diff --git a/www/webapp/db.py b/www/webapp/db.py
new file mode 100644 (file)
index 0000000..8d81614
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+import hashlib
+import sqlite3
+import os.path
+
+
+class HashDatabase(object):
+       def __init__(self):
+               self.conn = sqlite3.connect("/srv/www/ipfire.org/source/hashes.db")
+
+       def __del__(self):
+               self.conn.close()
+
+       def prepare(self):
+               c = self.conn.cursor()
+               c.execute("CREATE TABLE IF NOT EXISTS hashes(file, sha1)")
+               c.close()
+
+       def _save_hash(self, path, hash):
+               c = self.conn.cursor()
+               c.execute("INSERT INTO hashes VALUES('%s', '%s')" % (os.path.basename(path), hash))
+               c.close()
+
+       def get_hash(self, path):
+               c = self.conn.cursor()
+               c.execute("SELECT sha1 FROM hashes WHERE file = '%s'" % os.path.basename(path))
+
+               hash = c.fetchone()
+               c.close()
+
+               if not hash:
+                       hash = self._calc_hash(path)
+                       self._save_hash(path, hash)
+
+               if hash:
+                       return "%s" % hash
+
+       def _calc_hash(self, path):
+               if not os.path.exists(path):
+                       return
+
+               m = hashlib.sha1()
+               f = open(path)
+               m.update(f.read())
+               f.close()
+
+               return m.hexdigest()
diff --git a/www/webapp/handlers.py b/www/webapp/handlers.py
new file mode 100644 (file)
index 0000000..58f1a0f
--- /dev/null
@@ -0,0 +1,296 @@
+#!/usr/bin/python
+
+import datetime
+import httplib
+import mimetypes
+import operator
+import os
+import simplejson
+import stat
+import sqlite3
+import time
+import urlparse
+
+import tornado.httpclient
+import tornado.locale
+import tornado.web
+
+from banners import banners
+from helpers import size
+from info import info
+from mirrors import mirrors
+from news import news
+from releases import releases
+
+import builds
+import cluster
+import menu
+import translations
+#import uriel
+
+class BaseHandler(tornado.web.RequestHandler):
+       def get_user_locale(self):
+               uri = self.request.uri.split("/")
+               if len(uri) > 1:
+                       for lang in tornado.locale.get_supported_locales(None):
+                               if lang[:2] == uri[1]:
+                                       return tornado.locale.get(lang)
+
+       @property
+       def render_args(self):
+               return {
+                       "banner"    : banners.get(),
+                       "lang"      : self.locale.code[:2],
+                       "langs"     : [l[:2] for l in tornado.locale.get_supported_locales(None)],
+                       "lang_link" : self.lang_link,
+                       "link"      : self.link,
+                       "title"     : "no title given",
+                       "server"    : self.request.host.replace("ipfire", "<span>ipfire</span>"),
+                       "uri"       : self.request.uri,
+                       "year"      : time.strftime("%Y"),
+               }
+
+       def render(self, *args, **kwargs):
+               nargs = self.render_args
+               nargs.update(kwargs)
+               nargs["title"] = "%s - %s" % (self.request.host, nargs["title"])
+               tornado.web.RequestHandler.render(self, *args, **nargs)
+
+       def link(self, s):
+               return "/%s/%s" % (self.locale.code[:2], s)
+       
+       def lang_link(self, lang):
+               return "/%s/%s" % (lang, self.request.uri[4:])
+       
+       def get_error_html(self, status_code, **kwargs):
+               if status_code in (404, 500):
+                       render_args = self.render_args
+                       render_args.update({
+                               "code"      : status_code,
+                               "exception" : kwargs.get("exception", None),
+                               "message"   : httplib.responses[status_code],
+                       })
+                       return self.render_string("error-%s.html" % status_code, **render_args)
+               else:
+                       return tornado.web.RequestHandler.get_error_html(self, status_code, **kwargs)
+
+       @property
+       def hash_db(self):
+               return self.application.hash_db
+
+class MainHandler(BaseHandler):
+       def get(self):
+               lang = self.locale.code[:2]
+               self.redirect("/%s/index" % (lang))
+
+
+class DownloadHandler(BaseHandler):
+       def get(self):
+               self.render("downloads.html", release=releases.latest)
+
+
+class DownloadAllHandler(BaseHandler):
+       def get(self):
+               self.render("downloads-all.html", releases=releases)
+
+
+class DownloadDevelopmentHandler(BaseHandler):
+       def get(self):
+               self.render("downloads-development.html", releases=releases)
+
+
+class DownloadTorrentHandler(BaseHandler):
+       tracker_url = "http://tracker.ipfire.org:6969/stats?format=txt&mode=tpbs"
+
+       @tornado.web.asynchronous
+       def get(self):
+               http = tornado.httpclient.AsyncHTTPClient()
+               http.fetch(self.tracker_url, callback=self.async_callback(self.on_response))
+
+       def on_response(self, response):
+               torrents = releases.torrents
+               hashes = {}
+               if response.code == 200:
+                       for line in response.body.split("\n"):
+                               if not line: continue
+                               hash, seeds, peers = line.split(":")
+                               hash.lower()
+                               hashes[hash] = {
+                                       "peers" : peers,
+                                       "seeds" : seeds,
+                               }
+
+               self.render("downloads-torrents.html",
+                       hashes=hashes,
+                       releases=torrents,
+                       request_time=response.request_time,
+                       tracker=urlparse.urlparse(response.request.url).netloc)
+
+
+class DownloadMirrorHandler(BaseHandler):
+       def get(self):
+               self.render("downloads-mirrors.html", mirrors=mirrors)
+
+
+class StaticHandler(BaseHandler):
+       @property
+       def static_path(self):
+               return os.path.join(self.application.settings["template_path"], "static")
+
+       @property
+       def static_files(self):
+               ret = []
+               for filename in os.listdir(self.static_path):
+                       if filename.endswith(".html"):
+                               ret.append(filename)
+               return ret
+
+       def get(self, name=None):
+               name = "%s.html" % name
+
+               if not name in self.static_files:
+                       raise tornado.web.HTTPError(404)
+
+               self.render("static/%s" % name)
+
+
+class IndexHandler(BaseHandler):
+       def get(self):
+               self.render("index.html", news=news)
+
+
+class NewsHandler(BaseHandler):
+       def get(self):
+               self.render("news.html", news=news)
+
+
+class BuildHandler(BaseHandler):
+       def prepare(self):
+               self.builds = {
+                       "<12h" : [],
+                       ">12h" : [],
+                       ">24h" : [],
+               }
+
+               for build in builds.find():
+                       if (time.time() - float(build.get("date"))) < 12*60*60:
+                               self.builds["<12h"].append(build)
+                       elif (time.time() - float(build.get("date"))) < 24*60*60:
+                               self.builds[">12h"].append(build)
+                       else:
+                               self.builds[">24h"].append(build)
+
+               for l in self.builds.values():
+                       l.sort()
+
+       def get(self):
+               self.render("builds.html", builds=self.builds)
+
+
+class UrielBaseHandler(BaseHandler):
+       #db = uriel.Database()
+       pass
+
+class UrielHandler(UrielBaseHandler):
+       def get(self):
+               pass
+
+
+class ApiClusterInfoHandler(BaseHandler):
+       def get(self):
+               id = self.get_argument("id", "null")
+
+               c = cluster.Cluster(info["cluster"]["hostname"])
+
+               self.write(simplejson.dumps({
+                       "version": "1.1",
+                       "id": id,
+                       "result" : c.json,
+                       "error" : "null", }))
+               self.finish()
+
+
+class TranslationHandler(BaseHandler):
+       def get(self):
+               self.render("translations.html", projects=translations.projects)
+
+
+class SourceHandler(BaseHandler):
+       def get(self):
+               source_path = "/srv/sources"
+               fileobjects = []
+
+               for dir, subdirs, files in os.walk(source_path):
+                       if not files:
+                               continue
+                       for file in files:
+                               if file in [f["name"] for f in fileobjects]:
+                                       continue
+
+                               hash = self.hash_db.get_hash(file)
+
+                               if not hash:
+                                       hash = "0000000000000000000000000000000000000000"
+
+                               fileobjects.append({
+                                       "dir"  : dir[len(source_path)+1:],
+                                       "name" : file,
+                                       "hash" : hash,
+                                       "size" : size(os.path.getsize(os.path.join(source_path, dir, file))),
+                               })
+
+               fileobjects.sort(key=operator.itemgetter("name"))
+
+               self.render("sources.html", files=fileobjects)
+
+
+class SourceDownloadHandler(BaseHandler):
+       def head(self, path):
+               self.get(path, include_body=False)
+
+       def get(self, path, include_body=True):
+               source_path = "/srv/sources"
+
+               path = os.path.abspath(os.path.join(source_path, path[1:]))
+
+               if not path.startswith(source_path):
+                       raise tornado.web.HTTPError(403)
+               if not os.path.exists(path):
+                       raise tornado.web.HTTPError(404)
+
+               stat_result = os.stat(path)
+               modified = datetime.datetime.fromtimestamp(stat_result[stat.ST_MTIME])
+
+               self.set_header("Last-Modified", modified)
+               self.set_header("Content-Length", stat_result[stat.ST_SIZE])
+
+               mime_type, encoding = mimetypes.guess_type(path)
+               if mime_type:
+                       self.set_header("Content-Type", mime_type)
+
+               hash = self.hash_db.get_hash(path)
+               if hash:
+                       self.set_header("X-Hash-Sha1", "%s" % hash)
+
+               if not include_body:
+                       return
+               file = open(path, "r")
+               try:
+                       self.write(file.read())
+               finally:
+                       file.close()
+
+
+class DownloadFileHandler(BaseHandler):
+       def get(self, path):
+               for mirror in mirrors.with_file(path):
+                       if not mirror.reachable:
+                               continue
+
+                       self.redirect(mirror.url + path)
+                       return
+
+               raise tornado.web.HTTPError(404)
+
+       def get_error_html(self, status_code, **kwargs):
+               return tornado.web.RequestHandler.get_error_html(self, status_code, **kwargs)
diff --git a/www/webapp/helpers.py b/www/webapp/helpers.py
new file mode 100644 (file)
index 0000000..d634fcb
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+
+import simplejson
+import subprocess
+
+class Item(object):
+       def __init__(self, **args):
+               self.args = args
+       
+       def __getattr__(self, key):
+               return self.args[key]
+
+       def __getitem__(self, key):
+               return self.args[key]
+               
+       def __setitem__(self, key, val):
+               self.args[key] = val
+
+def size(s):
+       suffixes = ["B", "K", "M", "G", "T",]
+       
+       idx = 0
+       while s >= 1024 and idx < len(suffixes):
+               s /= 1024
+               idx += 1
+
+       return "%.0f%s" % (s, suffixes[idx])
+
+def json_loads(s):
+       return simplejson.loads(s.decode("utf-8"))
+
+def _stringify(d):
+       ret = {}
+       for key in d.keys():
+               ret[str(key)] = d[key]
+       return ret
+
+def ping(host, count=5, wait=10):
+       cmd = subprocess.Popen(
+               ["ping", "-c%d" % count, "-w%d" % wait, host],
+               stdout = subprocess.PIPE,
+               stderr = subprocess.PIPE,
+       )
+
+       latency = None
+
+       out, error = cmd.communicate()
+
+       for line in out.split("\n"):
+               if not line.startswith("rtt"):
+                       continue
+
+               line = line.split()
+               if len(line) < 4:
+                       break
+
+               rtts = line[3].split("/")
+               if len(rtts) < 4:
+                       break
+
+               latency = "%.1f" % float(rtts[1])
+
+       return latency
+
+
+if __name__ == "__main__":
+       print ping("www.ipfire.org")
+       print ping("www.rowie.at")
diff --git a/www/webapp/info.py b/www/webapp/info.py
new file mode 100644 (file)
index 0000000..3ea75b0
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/python
+
+from helpers import json_loads
+
+class Info(dict):
+       def __init__(self, filename):
+               self.load(filename)
+               
+       def load(self, filename):
+               f = open(filename)
+               for key, val in json_loads(f.read()).items():
+                       self[key] = val
+               f.close()
+
+
+info = Info("info.json")
diff --git a/www/webapp/menu.py b/www/webapp/menu.py
new file mode 100644 (file)
index 0000000..d998fd3
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+
+import simplejson
+
+from helpers import Item, _stringify
+
+class Menu(object):
+       def __init__(self, filename=None):
+               self.items = []
+
+               if filename:
+                       self.load(filename)
+
+       def load(self, filename):
+               f = open(filename)
+               data = f.read()
+               f.close()
+               
+               for item in simplejson.loads(data):
+                       self.items.append(MenuItem(**_stringify(item)))
+
+
+class MenuItem(Item):
+       def __init__(self, **args):
+               Item.__init__(self, **args)
+               self.active = False
+               
+               # Parse submenu
+               if self.args.has_key("subs"):
+                       self.args["items"] = []
+                       for sub in self.args["subs"]:
+                               self.args["items"].append(MenuItem(**_stringify(sub)))
+                       del self.args["subs"]
+
+
+if __name__ == "__main__":
+       m = Menu("menu.json")
+       print [i.args for i in m.items]
diff --git a/www/webapp/mirrors.py b/www/webapp/mirrors.py
new file mode 100644 (file)
index 0000000..df19627
--- /dev/null
@@ -0,0 +1,196 @@
+#!/usr/bin/python
+
+import tornado.httpclient
+
+import random
+import threading
+import time
+
+from helpers import Item, _stringify, ping, json_loads
+
+class Mirrors(threading.Thread):
+       def __init__(self, filename):
+               threading.Thread.__init__(self, name="Mirror Monitor")
+
+               self.items = []
+               self.load(filename)
+
+               self.__running = True
+
+               self.start()
+
+       def load(self, filename):
+               f = open(filename)
+               data = f.read()
+               f.close()
+               
+               for item in json_loads(data):
+                       self.items.append(MirrorItem(**_stringify(item)))
+
+       @property
+       def all(self):
+               return sorted(self.items)
+
+       @property
+       def random(self):
+               # Doesnt work :(
+               #return random.shuffle(self.items)
+               ret = []
+               items = self.items[:]
+               while items:
+                       rnd = random.randint(0, len(items)-1)
+                       ret.append(items.pop(rnd))
+               return ret
+
+       @property
+       def reachable(self):
+               ret = []
+               for mirror in self.items:
+                       if not mirror.reachable:
+                               continue
+                       ret.append(mirror)
+               return ret
+
+       @property
+       def unreachable(self):
+               ret = []
+               for mirror in self.all:
+                       if mirror in self.reachable:
+                               continue
+                       ret.append(mirror)
+               return ret
+
+       def pickone(self, reachable=False):
+               mirrors = self.items
+               if reachable:
+                       mirrors = self.reachable
+               if not mirrors:
+                       return None
+               return random.choice(mirrors)
+
+       def with_file(self, path):
+               ret = []
+               for mirror in self.random:
+                       if not mirror["serves"]["isos"]:
+                               continue
+                       if path in mirror.files:
+                               ret.append(mirror)
+               return ret
+
+       def shutdown(self):
+               self.__running = False
+
+       def run(self):
+               for mirror in self.random:
+                       if not self.__running:
+                               return
+                       mirror.update()
+
+               count = 0
+               while self.__running:
+                       if not count:
+                               count = 300 # 30 secs
+                               mirror = self.pickone()
+                               if mirror:
+                                       mirror.update()
+
+                       time.sleep(0.1)
+                       count -= 1
+
+
+class MirrorItem(Item):
+       def __init__(self, *args, **kwargs):
+               Item.__init__(self, *args, **kwargs)
+
+               self.filelist = MirrorFilelist(self)
+               self.latency = "N/A"
+
+       def __cmp__(self, other):
+               return cmp(self.name, other.name)
+
+       def update(self):
+               self.latency = ping(self.hostname) or "N/A"
+               if self.filelist.outdated:
+                       self.filelist.update()
+
+       @property
+       def reachable(self):
+               return not self.latency == "N/A"
+
+       @property
+       def url(self):
+               ret = "http://" + self.hostname
+               if not self.path.startswith("/"):
+                       ret += "/"
+               ret += self.path
+               if not ret.endswith("/"):
+                       ret += "/"
+               return ret
+
+       @property
+       def files(self):
+               return self.filelist.files
+
+       def has_file(self, path):
+               return path in self.files
+
+
+class MirrorFilelist(object):
+       def __init__(self, mirror):
+               self.mirror = mirror
+
+               self.__files = []
+               self.__time = 0
+
+               #self.update(now=True)
+
+       def update(self, now=False):
+               args = {}
+               
+               if now:
+                       while not self.mirror.reachable:
+                               time.sleep(10)
+
+               http = tornado.httpclient.HTTPClient()
+
+               if not now:
+                       http = tornado.httpclient.AsyncHTTPClient()
+                       args["callback"] = self.on_response
+
+               try:
+                       reponse = http.fetch(self.mirror.url + ".filelist", **args)
+               except tornado.httpclient.HTTPError:
+                       self.__time = time.time()
+                       return
+
+               if now:
+                       self.on_response(reponse)
+
+       def on_response(self, response):
+               self.__files = []
+               self.__time = time.time()
+
+               if not response.code == 200:
+                       return
+
+               # If invalid html content...
+               if response.body.startswith("<!"):
+                       return
+
+               for line in response.body.split("\n"):
+                       if not line:
+                               continue
+                       self.__files.append(line)
+
+       @property
+       def outdated(self):
+               return (time.time() - self.__time) > 60*60
+
+       @property
+       def files(self):
+               #if self.outdated:
+               #       self.update()
+               return self.__files
+
+
+mirrors = Mirrors("mirrors.json")
diff --git a/www/webapp/news.py b/www/webapp/news.py
new file mode 100644 (file)
index 0000000..9d170db
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+from helpers import Item, _stringify, json_loads
+
+class News(object):
+       def __init__(self, filename=None):
+               self.items = []
+
+               if filename:
+                       self.load(filename)
+
+       def load(self, filename):
+               f = open(filename)
+               data = f.read()
+               f.close()
+
+               data = data.replace("\n", "").replace("\t", " ")
+
+               json = json_loads(data)
+               for key in sorted(json.keys()):
+                       self.items.append(NewsItem(**_stringify(json[key])))
+
+       def get(self, limit=None):
+               ret = self.items[:]
+               ret.reverse()
+               if limit:
+                       ret = ret[:limit]
+               return ret
+
+
+NewsItem = Item
+
+news = News("news.json")
diff --git a/www/webapp/releases.py b/www/webapp/releases.py
new file mode 100644 (file)
index 0000000..e065296
--- /dev/null
@@ -0,0 +1,185 @@
+#!/usr/bin/python
+
+from helpers import Item, _stringify, json_loads
+
+class ReleaseItem(Item):
+       options = {
+               "iso" : {
+                       "prio" : 10,
+                       "desc" : "Installable CD image",
+                       "url"  : "http://download.ipfire.org/iso/",
+                       "rem"  : "Use this image to burn a CD and install IPFire from it.",
+               },
+               "torrent" : {
+                       "prio" : 20,
+                       "desc" : "Torrent file",
+                       "url"  : "http://download.ipfire.org/torrent/",
+                       "rem"  : "Download the CD image from the torrent network.",
+               },
+               "flash" : {
+                       "prio" : 40,
+                       "desc" : "Flash image",
+                       "url"  : "http://download.ipfire.org/iso/",
+                       "rem"  : "An image that is meant to run on embedded devices.",
+               },
+               "alix" : {
+                       "prio" : 41,
+                       "desc" : "Alix image",
+                       "url"  : "http://download.ipfire.org/iso/",
+                       "rem"  : "Flash image where a serial console is enabled by default.",
+               },
+               "usbfdd" : {
+                       "prio" : 30,
+                       "desc" : "USB FDD image",
+                       "url"  : "http://download.ipfire.org/iso/",
+                       "rem"  : "Install IPFire from a floppy-formated USB key.",
+               },
+               "usbhdd" : {
+                       "prio" : 30,
+                       "desc" : "USB HDD image",
+                       "url"  : "http://download.ipfire.org/iso/",
+                       "rem"  : "If the floppy image doesn't work, use this image instead.",
+               },
+               "xen" : {
+                       "prio" : 50,
+                       "desc" : "Pregenerated Xen image",
+                       "url"  : "http://download.ipfire.org/iso/",
+                       "rem"  : "A ready-to-run image for Xen.",
+               },
+       }
+
+       @property
+       def downloads(self):
+               ret = []
+               for fileitem in self.args["files"]:
+                       filetype = fileitem["type"]
+                       ret.append(Item(
+                               desc = self.options[filetype]["desc"],
+                               file = fileitem["name"],
+                               hash = fileitem.get("hash", None),
+                               prio = self.options[filetype]["prio"],
+                               rem  = self.options[filetype]["rem"],
+                               sha1 = fileitem.get("sha1", None),
+                               type = filetype,
+                               url  = self.options[filetype]["url"] + fileitem["name"],
+                       ))
+
+               ret.sort(lambda a, b: cmp(a.prio, b.prio))
+               return ret
+               
+               for option in self.options.keys():
+                       if not self.args["files"].has_key(option):
+                               continue
+
+                       ret.append(Item(
+                               desc = self.options[option]["desc"],
+                               file = self.args["files"][option],
+                               prio = self.options[option]["prio"],
+                               type = option,
+                               url = self.options[option]["url"] + self.args["files"][option],
+                       ))
+
+               ret.sort(lambda a, b: cmp(a.prio, b.prio))
+               return ret
+
+       @property
+       def iso(self):
+               for download in self.downloads:
+                       if download.type == "iso":
+                               return download
+
+       @property
+       def torrent(self):
+               for download in self.downloads:
+                       if download.type == "torrent":
+                               return download
+
+       @property
+       def stable(self):
+               return self.status == "stable"
+
+       @property
+       def development(self):
+               return self.status == "development"
+
+
+class Releases(object):
+       def __init__(self, filename="releases.json"):
+               self.items = []
+
+               if filename:
+                       self.load(filename)
+       
+       def load(self, filename):
+               f = open(filename)
+               data = f.read()
+               f.close()
+               
+               for item in json_loads(data):
+                       self.items.append(ReleaseItem(**_stringify(item)))
+
+       @property
+       def all(self):
+               return self.items
+
+       @property
+       def online(self):
+               ret = []
+               for item in self.all:
+                       if item.online:
+                               ret.append(item)
+               return ret
+
+       @property
+       def offline(self):
+               ret = []
+               for item in self.all:
+                       if not item.online:
+                               ret.append(item)
+               return ret
+
+       @property
+       def latest(self):
+               if self.stable:
+                       return self.stable[0]
+
+       @property
+       def latest_devel(self):
+               if self.development:
+                       return self.development[0]
+
+       @property
+       def stable(self):
+               ret = []
+               for item in self.online:
+                       if item.stable:
+                               ret.append(item)
+               return ret
+
+       @property
+       def development(self):
+               ret = []
+               for item in self.online:
+                       if item.development:
+                               ret.append(item)
+               return ret
+
+       @property
+       def torrents(self):
+               ret = []
+               for item in self.online:
+                       if item.torrent:
+                               ret.append(item)
+               return ret
+
+
+releases = Releases("releases.json")
+
+if __name__ == "__main__":
+       r = Releases()
+
+       print r.stable
+       print r.development
+       print r.latest
+       print r.online
+       print r.offline
diff --git a/www/webapp/translations.py b/www/webapp/translations.py
new file mode 100644 (file)
index 0000000..af44823
--- /dev/null
@@ -0,0 +1,102 @@
+#!/usr/bin/python
+
+import os
+
+import tornado.locale
+
+class Po(object):
+       def __init__(self, path, project):
+               self.path = path
+               self.project = project
+               
+               p = os.popen("msgfmt -v --statistics %s 2>&1" % self.path)
+               self.line = p.readlines()[0]
+
+       def __cmp__(self, other):
+               return cmp(self.lang, other.lang)
+
+       @property
+       def code2lang(self):
+               ret = {}
+               for lang in tornado.locale.LOCALE_NAMES.keys():
+                       ret[lang[:2]] = "%(name)s (%(name_en)s)" % tornado.locale.LOCALE_NAMES[lang]
+               return ret
+
+       @property
+       def code(self):
+               return os.path.basename(self.path)[:-3]
+
+       @property
+       def lang(self):
+               return self.code2lang.get(self.code, "Unknown (%s)" % self.code)
+
+       @property
+       def translated(self):
+               return int(self.line.split()[0])
+
+       @property
+       def untranslated(self):
+               l = self.line.split()
+               if len(l) == 6:
+                       return int(l[3])
+               elif len(l) == 9:
+                       return int(l[6])
+               return 0
+
+       @property
+       def fuzzy(self):
+               l = self.line.split()
+               if len(l) == 9:
+                       return l[3]
+               return 0
+
+       @property
+       def percent(self):
+               if not self.project.total_strings:
+                       return "---.-- %"
+               
+               return "%3.1f%%" % (self.translated * 100 / self.project.total_strings)
+
+
+class Project(object):
+       def __init__(self, id, path, **kwargs):
+               self.id = id
+               self.path = path
+               self._name = kwargs.pop("name")
+               self.desc = kwargs.pop("desc")
+
+               self._translations = []
+               self.pot = None
+               self.find_pot()
+
+       @property
+       def name(self):
+               if self._name:
+                       return self._name
+               return self.id
+
+       @property
+       def translations(self):
+               if not self._translations:
+                       for path in os.listdir(self.path):
+                               if path.endswith(".po"):
+                                       self._translations.append(Po(os.path.join(self.path, path), self))
+                       self._translations.sort()
+               return self._translations
+
+       def find_pot(self):
+               for path in os.listdir(self.path):
+                       if path.endswith(".pot"):
+                               self.pot = Po(os.path.join(self.path, path), self)
+                               break
+
+       @property
+       def total_strings(self):
+               if not self.pot:
+                       return 0
+               return self.pot.untranslated
+
+projects = [
+       Project("pomona", "/srv/checkout/ipfire-3.x/src/pomona/po",
+               name="Pomona", desc="The pomona installer for ipfire."),
+]
diff --git a/www/webapp/ui_modules.py b/www/webapp/ui_modules.py
new file mode 100644 (file)
index 0000000..aa89f80
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+
+import tornado.web
+
+import menu
+import releases
+
+from helpers import Item
+
+class UIModule(tornado.web.UIModule):
+       def render_string(self, *args, **kwargs):
+               kwargs.update({
+                       "link" : self.handler.link,
+               })
+               return tornado.web.UIModule.render_string(self, *args, **kwargs)
+
+
+class MenuItemModule(UIModule):
+       def render(self, item):
+               if self.request.uri.endswith(item.uri):
+                       item.active = True
+
+               if not item.uri.startswith("http://"):
+                       item.uri = "/%s%s" % (self.locale.code[:2], item.uri,)
+
+               if type(item.name) == type({}):
+                       item.name = item.name[self.locale.code[:2]]
+
+               return self.render_string("modules/menu-item.html", item=item)
+
+
+class MenuModule(UIModule):
+       def render(self, menuclass=None):
+               if not menuclass:
+                       menuclass = menu.Menu("menu.json")
+               return self.render_string("modules/menu.html", menuitems=menuclass.items)
+
+
+class NewsItemModule(UIModule):
+       def render(self, item):
+               item = Item(**item.args.copy())
+               for attr in ("subject", "content"):
+                       if type(item[attr]) != type({}):
+                               continue
+                       item[attr] = item[attr][self.locale.code[:2]]
+
+               return self.render_string("modules/news-item.html", item=item)
+
+
+#class SidebarModule(UIModule):
+#      def render(self, sidebar):
+#              return self.render_string("modules/sidebar.html", items=sidebar.items)
+
+
+class SidebarItemModule(UIModule):
+       def render(self):
+               return self.render_string("modules/sidebar-item.html")
+
+
+class SidebarReleaseModule(UIModule):
+       releases = releases.Releases()
+
+       def render(self):
+               return self.render_string("modules/sidebar-release.html",
+                       releases=self.releases)
+
+
+class ReleaseItemModule(UIModule):
+       def render(self, item):
+               return self.render_string("modules/release-item.html", item=item)
+
+
+class SidebarBannerModule(UIModule):
+       def render(self, item):
+               return self.render_string("modules/sidebar-banner.html", item=item)
+
+
+class BuildModule(UIModule):
+       def render(self, build):
+               return self.render_string("modules/builds.html", build=build)
similarity index 98%
rename from www/web/urieldb.py
rename to www/webapp/uriel.py
index d44d5b51729c20e50d9412eada497ebfb1c98ce6..bf1f10401a0196898a8aedd899765eec4dceb146 100644 (file)
@@ -6,7 +6,7 @@ import MySQLdb as sql
 allowed_items = [ "cpu_mhz", "cpu_model", "formfactor", "lang", "model",
                                  "ram_mb", "storage_mb", "system", "vendor", ]
 
-class Urieldb(object):
+class Database(object):
        _name = "uriel"
        _table = "hosts"