kopia lustrzana https://github.com/jaseg/gerbolyze
rodzic
a006deb188
commit
874adce8f4
|
@ -0,0 +1,474 @@
|
|||
##
|
||||
## Arch Linux repository mirrorlist
|
||||
## Generated on 2017-06-06
|
||||
##
|
||||
|
||||
## Worldwide
|
||||
#Server = https://archlinux.surlyjake.com/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.evowise.com/archlinux/$repo/os/$arch
|
||||
Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
|
||||
|
||||
## Australia
|
||||
#Server = https://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.mirror.digitalpacific.com.au/$repo/os/$arch
|
||||
#Server = http://ftp.iinet.net.au/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.internode.on.net/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.swin.edu.au/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.uberglobalmirror.com/$repo/os/$arch
|
||||
|
||||
## Austria
|
||||
#Server = http://mirror.digitalnova.at/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.easyname.at/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror1.htu.tugraz.at/archlinux/$repo/os/$arch
|
||||
|
||||
## Belarus
|
||||
#Server = http://ftp.byfly.by/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.datacenter.by/pub/archlinux/$repo/os/$arch
|
||||
|
||||
## Belgium
|
||||
#Server = http://archlinux.cu.be/$repo/os/$arch
|
||||
#Server = http://archlinux.mirror.kangaroot.net/$repo/os/$arch
|
||||
|
||||
## Bosnia and Herzegovina
|
||||
#Server = http://burek.archlinux.ba/$repo/os/$arch
|
||||
#Server = http://archlinux.mirror.ba/$repo/os/$arch
|
||||
|
||||
## Brazil
|
||||
#Server = http://br.mirror.archlinux-br.org/$repo/os/$arch
|
||||
#Server = http://archlinux.c3sl.ufpr.br/$repo/os/$arch
|
||||
#Server = http://linorg.usp.br/archlinux/$repo/os/$arch
|
||||
#Server = http://pet.inf.ufsc.br/mirrors/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.pop-es.rnp.br/$repo/os/$arch
|
||||
|
||||
## Bulgaria
|
||||
#Server = http://mirror.host.ag/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.netix.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.telepoint.bg/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.uni-plovdiv.net/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.uni-plovdiv.net/archlinux/$repo/os/$arch
|
||||
|
||||
## Canada
|
||||
#Server = http://mirror.cedille.club/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.mirror.colo-serv.net/$repo/os/$arch
|
||||
#Server = http://mirror.csclub.uwaterloo.ca/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.csclub.uwaterloo.ca/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.frgl.pw/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.frgl.pw/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.its.dal.ca/archlinux/$repo/os/$arch
|
||||
#Server = http://muug.ca/mirror/archlinux/$repo/os/$arch
|
||||
#Server = https://muug.ca/mirror/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.mirror.rafal.ca/$repo/os/$arch
|
||||
|
||||
## Chile
|
||||
#Server = http://mirror.archlinux.cl/$repo/os/$arch
|
||||
|
||||
## China
|
||||
#Server = http://mirrors.163.com/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.lzu.edu.cn/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.neusoft.edu.cn/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.skyshe.cn/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.xjtu.edu.cn/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.xjtu.edu.cn/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.zju.edu.cn/archlinux/$repo/os/$arch
|
||||
|
||||
## Colombia
|
||||
#Server = http://mirror.edatel.net.co/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.upb.edu.co/archlinux/$repo/os/$arch
|
||||
|
||||
## Croatia
|
||||
#Server = http://archlinux.iskon.hr/$repo/os/$arch
|
||||
|
||||
## Czech Republic
|
||||
#Server = http://mirror.dkm.cz/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.dkm.cz/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.fi.muni.cz/pub/linux/arch/$repo/os/$arch
|
||||
#Server = http://ftp.linux.cz/pub/linux/arch/$repo/os/$arch
|
||||
#Server = http://gluttony.sin.cvut.cz/arch/$repo/os/$arch
|
||||
#Server = https://gluttony.sin.cvut.cz/arch/$repo/os/$arch
|
||||
#Server = http://mirrors.nic.cz/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.sh.cvut.cz/arch/$repo/os/$arch
|
||||
#Server = https://ftp.sh.cvut.cz/arch/$repo/os/$arch
|
||||
#Server = http://mirror.vpsfree.cz/archlinux/$repo/os/$arch
|
||||
|
||||
## Denmark
|
||||
#Server = http://mirrors.dotsrc.org/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.dotsrc.org/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.klid.dk/ftp/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.one.com/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.one.com/archlinux/$repo/os/$arch
|
||||
|
||||
## Ecuador
|
||||
#Server = http://mirror.cedia.org.ec/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.espoch.edu.ec/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.uta.edu.ec/archlinux/$repo/os/$arch
|
||||
|
||||
## Finland
|
||||
#Server = http://arch.mirror.far.fi/$repo/os/$arch
|
||||
|
||||
## France
|
||||
#Server = http://archlinux.de-labrusse.fr/$repo/os/$arch
|
||||
#Server = http://mirror.archlinux.ikoula.com/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.vi-di.fr/$repo/os/$arch
|
||||
#Server = https://archlinux.vi-di.fr/$repo/os/$arch
|
||||
#Server = http://mirror.armbrust.me/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.armbrust.me/archlinux/$repo/os/$arch
|
||||
#Server = https://archlinux.ec-tech.fr/$repo/os/$arch
|
||||
#Server = http://fooo.biz/archlinux/$repo/os/$arch
|
||||
#Server = https://fooo.biz/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.gerhard.re/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.ibcp.fr/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.lastmikoi.net/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.mailtunnel.eu/$repo/os/$arch
|
||||
#Server = https://www.mailtunnel.eu/archlinux/$repo/os/$arch
|
||||
#Server = http://mir.archlinux.fr/$repo/os/$arch
|
||||
#Server = http://archlinux.mirrors.ovh.net/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.mirror.pkern.at/$repo/os/$arch
|
||||
#Server = https://archlinux.mirror.pkern.at/$repo/os/$arch
|
||||
#Server = http://archlinux.polymorf.fr/$repo/os/$arch
|
||||
#Server = http://mirrors.standaloneinstaller.com/archlinux/$repo/os/$arch
|
||||
#Server = http://arch.tamcore.eu/$repo/os/$arch
|
||||
#Server = http://mirror.tyborek.pl/arch/$repo/os/$arch
|
||||
#Server = https://mirror.tyborek.pl/arch/$repo/os/$arch
|
||||
#Server = http://ftp.u-strasbg.fr/linux/distributions/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.wormhole.eu/archlinux/$repo/os/$arch
|
||||
#Server = http://arch.yourlabs.org/$repo/os/$arch
|
||||
|
||||
## Germany
|
||||
#Server = http://mirror.23media.de/archlinux/$repo/os/$arch
|
||||
#Server = https://arch.32g.eu/$repo/os/$arch
|
||||
#Server = http://artfiles.org/archlinux.org/$repo/os/$arch
|
||||
#Server = https://fabric-mirror.vps.hosteurope.de/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.bethselamin.de/$repo/os/$arch
|
||||
#Server = http://mirror.euserv.net/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.f4st.host/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.f4st.host/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.fau.de/archlinux/$repo/os/$arch
|
||||
#Server = https://ftp.fau.de/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.fluxent.de/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.fluxent.de/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.gnomus.de/$repo/os/$arch
|
||||
#Server = http://www.gutscheindrache.com/mirror/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.gwdg.de/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.hactar.xyz/$repo/os/$arch
|
||||
#Server = https://mirror.hactar.xyz/$repo/os/$arch
|
||||
#Server = http://archlinux.honkgong.info/$repo/os/$arch
|
||||
#Server = http://ftp.hosteurope.de/mirror/ftp.archlinux.org/$repo/os/$arch
|
||||
#Server = http://ftp-stud.hs-esslingen.de/pub/Mirrors/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.mirror.iphh.net/$repo/os/$arch
|
||||
#Server = http://repo.itmettke.de/archlinux/$repo/os/$arch
|
||||
#Server = https://repo.itmettke.de/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.jankoppe.de/archlinux/$repo/os/$arch
|
||||
#Server = http://arch.jensgutermuth.de/$repo/os/$arch
|
||||
#Server = https://arch.jensgutermuth.de/$repo/os/$arch
|
||||
#Server = http://mirror.js-webcoding.de/pub/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.js-webcoding.de/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://k42.ch/mirror/archlinux/$repo/os/$arch
|
||||
#Server = https://k42.ch/mirror/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.de.leaseweb.net/archlinux/$repo/os/$arch
|
||||
Server = https://mirror.de.leaseweb.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.loli.forsale/arch/$repo/os/$arch
|
||||
#Server = https://mirror.loli.forsale/arch/$repo/os/$arch
|
||||
#Server = http://mirror.metalgamer.eu/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.metalgamer.eu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.michael-eckert.net/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.michael-eckert.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.n-ix.net/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.n-ix.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.netcologne.de/archlinux/$repo/os/$arch
|
||||
Server = https://mirror.netcologne.de/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.niyawe.de/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.niyawe.de/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.nullpointer.io/$repo/os/$arch
|
||||
#Server = https://archlinux.nullpointer.io/$repo/os/$arch
|
||||
#Server = http://mirror.pseudoform.org/$repo/os/$arch
|
||||
#Server = https://mirror.pseudoform.org/$repo/os/$arch
|
||||
#Server = https://www.ratenzahlung.de/mirror/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.halifax.rwth-aachen.de/archlinux/$repo/os/$arch
|
||||
#Server = http://linux.rz.rub.de/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.selfnet.de/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.spline.inf.fu-berlin.de/mirrors/archlinux/$repo/os/$arch
|
||||
#Server = https://ftp.spline.inf.fu-berlin.de/mirrors/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.thaller.ws/$repo/os/$arch
|
||||
#Server = https://archlinux.thaller.ws/$repo/os/$arch
|
||||
#Server = http://archlinux.thelinuxnetworx.rocks/$repo/os/$arch
|
||||
#Server = https://archlinux.thelinuxnetworx.rocks/$repo/os/$arch
|
||||
#Server = http://archmirror.tomforb.es/$repo/os/$arch
|
||||
#Server = https://archmirror.tomforb.es/$repo/os/$arch
|
||||
#Server = http://ftp.tu-chemnitz.de/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.ubrco.de/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.ubrco.de/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.uni-bayreuth.de/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.uni-hannover.de/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.uni-kl.de/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.united-gameserver.de/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.vfn-nrw.de/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.vfn-nrw.de/archlinux/$repo/os/$arch
|
||||
|
||||
## Greece
|
||||
#Server = http://ftp.cc.uoc.gr/mirrors/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://foss.aueb.gr/mirrors/linux/archlinux/$repo/os/$arch
|
||||
#Server = https://foss.aueb.gr/mirrors/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.myaegean.gr/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.ntua.gr/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.otenet.gr/linux/archlinux/$repo/os/$arch
|
||||
|
||||
## Hong Kong
|
||||
#Server = http://arch-mirror.wtako.net/$repo/os/$arch
|
||||
#Server = https://arch-mirror.wtako.net/$repo/os/$arch
|
||||
|
||||
## Hungary
|
||||
#Server = http://ftp.energia.mta.hu/pub/mirrors/ftp.archlinux.org/$repo/os/$arch
|
||||
#Server = http://archmirror.hbit.sztaki.hu/archlinux/$repo/os/$arch
|
||||
|
||||
## Iceland
|
||||
#Server = http://mirror.system.is/arch/$repo/os/$arch
|
||||
#Server = https://mirror.system.is/arch/$repo/os/$arch
|
||||
|
||||
## India
|
||||
#Server = http://mirror.cse.iitk.ac.in/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.iitm.ac.in/archlinux/$repo/os/$arch
|
||||
|
||||
## Indonesia
|
||||
#Server = http://mirror.devilzc0de.org/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.poliwangi.ac.id/archlinux/$repo/os/$arch
|
||||
#Server = http://suro.ubaya.ac.id/archlinux/$repo/os/$arch
|
||||
|
||||
## Iran
|
||||
#Server = http://repo.sadjad.ac.ir/arch/$repo/os/$arch
|
||||
#Server = https://repo.sadjad.ac.ir/arch/$repo/os/$arch
|
||||
|
||||
## Ireland
|
||||
#Server = http://ftp.heanet.ie/mirrors/ftp.archlinux.org/$repo/os/$arch
|
||||
#Server = https://ftp.heanet.ie/mirrors/ftp.archlinux.org/$repo/os/$arch
|
||||
|
||||
## Israel
|
||||
#Server = http://mirror.isoc.org.il/pub/archlinux/$repo/os/$arch
|
||||
|
||||
## Italy
|
||||
#Server = http://archlinux.prometeolibero.eu/archlinux/$repo/os/$arch
|
||||
#Server = https://archlinux.prometeolibero.eu/archlinux/$repo/os/$arch
|
||||
#Server = https://archlinux.beccacervello.it/archlinux/$repo/os/$arch
|
||||
#Server = http://mi.mirror.garr.it/mirrors/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.prometeus.net/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.students.cs.unibo.it/$repo/os/$arch
|
||||
|
||||
## Japan
|
||||
#Server = http://ftp.tsukuba.wide.ad.jp/Linux/archlinux/$repo/os/$arch
|
||||
Server = http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/$repo/os/$arch
|
||||
|
||||
## Kazakhstan
|
||||
#Server = http://mirror.neolabs.kz/archlinux/$repo/os/$arch
|
||||
|
||||
## Latvia
|
||||
#Server = http://archlinux.koyanet.lv/archlinux/$repo/os/$arch
|
||||
|
||||
## Lithuania
|
||||
#Server = http://mirrors.atviras.lt/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.atviras.lt/archlinux/$repo/os/$arch
|
||||
|
||||
## Luxembourg
|
||||
#Server = http://archlinux.mirror.root.lu/$repo/os/$arch
|
||||
|
||||
## Macedonia
|
||||
#Server = http://arch.softver.org.mk/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.t-home.mk/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.t-home.mk/archlinux/$repo/os/$arch
|
||||
|
||||
## Netherlands
|
||||
#Server = http://arch.apt-get.eu/$repo/os/$arch
|
||||
#Server = http://mirror.i3d.net/pub/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.i3d.net/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.nl.leaseweb.net/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.nl.leaseweb.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.netrouting.net/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.nluug.nl/os/Linux/distr/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.snt.utwente.nl/pub/os/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.mirror.wearetriple.com/$repo/os/$arch
|
||||
#Server = https://archlinux.mirror.wearetriple.com/$repo/os/$arch
|
||||
|
||||
## New Caledonia
|
||||
#Server = http://mirror.lagoon.nc/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.nautile.nc/archlinux/$repo/os/$arch
|
||||
|
||||
## New Zealand
|
||||
#Server = https://mirror.smith.geek.nz/archlinux/$repo/os/$arch
|
||||
|
||||
## Norway
|
||||
#Server = http://mirror.archlinux.no/$repo/os/$arch
|
||||
#Server = http://archlinux.uib.no/$repo/os/$arch
|
||||
#Server = http://mirror.neuf.no/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.neuf.no/archlinux/$repo/os/$arch
|
||||
|
||||
## Philippines
|
||||
#Server = http://mirror.rise.ph/archlinux/$repo/os/$arch
|
||||
|
||||
## Poland
|
||||
#Server = http://mirror.chmuri.net/archmirror/$repo/os/$arch
|
||||
#Server = http://arch.midov.pl/arch/$repo/os/$arch
|
||||
#Server = http://mirror.onet.pl/pub/mirrors/archlinux/$repo/os/$arch
|
||||
#Server = http://piotrkosoft.net/pub/mirrors/ftp.archlinux.org/$repo/os/$arch
|
||||
#Server = http://ftp.vectranet.pl/archlinux/$repo/os/$arch
|
||||
|
||||
## Portugal
|
||||
#Server = http://glua.ua.pt/pub/archlinux/$repo/os/$arch
|
||||
#Server = https://glua.ua.pt/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.rnl.tecnico.ulisboa.pt/pub/archlinux/$repo/os/$arch
|
||||
|
||||
## Qatar
|
||||
#Server = http://mirror.qnren.qa/archlinux/$repo/os/$arch
|
||||
|
||||
## Romania
|
||||
#Server = http://mirror.archlinux.ro/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.mirrors.linux.ro/$repo/os/$arch
|
||||
#Server = http://mirrors.m247.ro/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.pidginhost.com/arch/$repo/os/$arch
|
||||
|
||||
## Russia
|
||||
#Server = http://mirror.aur.rocks/$repo/os/$arch
|
||||
#Server = https://mirror.aur.rocks/$repo/os/$arch
|
||||
#Server = http://mirror.rol.ru/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.rol.ru/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.yandex.ru/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.yandex.ru/archlinux/$repo/os/$arch
|
||||
|
||||
## Serbia
|
||||
#Server = http://mirror.pmf.kg.ac.rs/archlinux/$repo/os/$arch
|
||||
|
||||
## Singapore
|
||||
#Server = http://mirror.0x.sg/archlinux/$repo/os/$arch
|
||||
#Server = http://download.nus.edu.sg/mirror/arch/$repo/os/$arch
|
||||
|
||||
## Slovakia
|
||||
#Server = http://mirror.lnx.sk/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.lnx.sk/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://tux.rainside.sk/archlinux/$repo/os/$arch
|
||||
|
||||
## Slovenia
|
||||
#Server = http://archimonde.ts.si/archlinux/$repo/os/$arch
|
||||
#Server = https://archimonde.ts.si/archlinux/$repo/os/$arch
|
||||
|
||||
## South Africa
|
||||
#Server = http://za.mirror.archlinux-br.org/$repo/os/$arch
|
||||
#Server = http://ftp.wa.co.za/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.is.co.za/mirror/archlinux.org/$repo/os/$arch
|
||||
#Server = http://mirror.wbs.co.za/archlinux/$repo/os/$arch
|
||||
|
||||
## South Korea
|
||||
#Server = http://ftp.kaist.ac.kr/ArchLinux/$repo/os/$arch
|
||||
#Server = http://mirror.premi.st/archlinux/$repo/os/$arch
|
||||
|
||||
## Spain
|
||||
#Server = http://osl.ugr.es/archlinux/$repo/os/$arch
|
||||
#Server = http://sunsite.rediris.es/mirror/archlinux/$repo/os/$arch
|
||||
|
||||
## Sweden
|
||||
#Server = http://ftp.acc.umu.se/mirror/archlinux/$repo/os/$arch
|
||||
#Server = https://ftp.acc.umu.se/mirror/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.dynamict.se/$repo/os/$arch
|
||||
#Server = https://archlinux.dynamict.se/$repo/os/$arch
|
||||
#Server = http://ftp.lysator.liu.se/pub/archlinux/$repo/os/$arch
|
||||
#Server = https://ftp.lysator.liu.se/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.myrveln.se/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = https://ftp.myrveln.se/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.osbeck.com/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.portlane.com/pub/os/linux/archlinux/$repo/os/$arch
|
||||
|
||||
## Switzerland
|
||||
#Server = http://pkg.adfinis-sygroup.ch/archlinux/$repo/os/$arch
|
||||
#Server = https://pkg.adfinis-sygroup.ch/archlinux/$repo/os/$arch
|
||||
#Server = http://archlinux.puzzle.ch/$repo/os/$arch
|
||||
|
||||
## Taiwan
|
||||
#Server = http://archlinux.cs.nctu.edu.tw/$repo/os/$arch
|
||||
#Server = http://shadow.ind.ntou.edu.tw/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.tku.edu.tw/Linux/ArchLinux/$repo/os/$arch
|
||||
#Server = http://ftp.yzu.edu.tw/Linux/archlinux/$repo/os/$arch
|
||||
|
||||
## Thailand
|
||||
#Server = http://mirror.adminbannok.com/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.kku.ac.th/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.kku.ac.th/archlinux/$repo/os/$arch
|
||||
|
||||
## Turkey
|
||||
#Server = http://ftp.linux.org.tr/archlinux/$repo/os/$arch
|
||||
|
||||
## Ukraine
|
||||
#Server = http://archlinux.ip-connect.vn.ua/$repo/os/$arch
|
||||
#Server = https://archlinux.ip-connect.vn.ua/$repo/os/$arch
|
||||
#Server = http://mirrors.nix.org.ua/linux/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.nix.org.ua/linux/archlinux/$repo/os/$arch
|
||||
|
||||
## United Kingdom
|
||||
#Server = http://mirror.bytemark.co.uk/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.manchester.m247.com/arch-linux/$repo/os/$arch
|
||||
#Server = http://www.mirrorservice.org/sites/ftp.archlinux.org/$repo/os/$arch
|
||||
#Server = http://arch.serverspace.co.uk/arch/$repo/os/$arch
|
||||
#Server = http://archlinux.mirrors.uk2.net/$repo/os/$arch
|
||||
|
||||
## United States
|
||||
#Server = http://mirrors.acm.wpi.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.advancedhosters.com/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.aggregate.org/archlinux/$repo/os/$arch
|
||||
#Server = http://ca.us.mirror.archlinux-br.org/$repo/os/$arch
|
||||
#Server = http://il.us.mirror.archlinux-br.org/$repo/os/$arch
|
||||
#Server = http://archlinux.surlyjake.com/archlinux/$repo/os/$arch
|
||||
#Server = http://arlm.tyzoid.com/$repo/os/$arch
|
||||
#Server = http://mirror.as65535.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.cat.pdx.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.cc.columbia.edu/pub/linux/archlinux/$repo/os/$arch
|
||||
#Server = http://arch.mirror.constant.com/$repo/os/$arch
|
||||
#Server = https://arch.mirror.constant.com/$repo/os/$arch
|
||||
#Server = http://cosmos.cites.illinois.edu/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.cs.pitt.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.cs.vt.edu/pub/ArchLinux/$repo/os/$arch
|
||||
#Server = http://mirror.epiphyte.network/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.epiphyte.network/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.es.its.nyu.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.gigenet.com/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.grig.io/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.grig.io/archlinux/$repo/os/$arch
|
||||
#Server = http://www.gtlib.gatech.edu/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror1.hackingand.coffee/arch/$repo/os/$arch
|
||||
#Server = http://mirror2.hackingand.coffee/arch/$repo/os/$arch
|
||||
#Server = http://mirror3.hackingand.coffee/arch/$repo/os/$arch
|
||||
#Server = http://mirror.htnshost.com/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.jmu.edu/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.kernel.org/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.kernel.org/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.us.leaseweb.net/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.us.leaseweb.net/archlinux/$repo/os/$arch
|
||||
#Server = http://il.mirrors.linaxe.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.liquidweb.com/archlinux/$repo/os/$arch
|
||||
#Server = http://arch.localmsp.org/arch/$repo/os/$arch
|
||||
#Server = https://arch.localmsp.org/arch/$repo/os/$arch
|
||||
#Server = http://mirror.lty.me/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.lty.me/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.lug.mtu.edu/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.lug.mtu.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.math.princeton.edu/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.metrocast.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.kaminski.io/archlinux/$repo/os/$arch
|
||||
#Server = https://mirror.kaminski.io/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.nexcess.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.ocf.berkeley.edu/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.ocf.berkeley.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://ftp.osuosl.org/pub/archlinux/$repo/os/$arch
|
||||
#Server = http://arch.mirrors.pair.com/$repo/os/$arch
|
||||
#Server = http://mirrors.rit.edu/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.rit.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.rutgers.edu/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.rutgers.edu/archlinux/$repo/os/$arch
|
||||
#Server = https://mirrors.tuxns.net/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.umd.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch
|
||||
#Server = http://mirrors.xmission.com/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror.yellowfiber.net/archlinux/$repo/os/$arch
|
||||
|
||||
## Vietnam
|
||||
#Server = http://f.archlinuxvn.org/archlinux/$repo/os/$arch
|
||||
#Server = http://mirror-fpt-telecom.fpt.net/archlinux/$repo/os/$arch
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
- name: Gerbolyze container setup playbook
|
||||
hosts: localhost
|
||||
connection: local
|
||||
tasks:
|
||||
- name: Download arch bootstrap image
|
||||
get_url:
|
||||
url: http://mirror.rackspace.com/archlinux/iso/2019.03.01/archlinux-bootstrap-2019.03.01-x86_64.tar.gz
|
||||
dest: /tmp/arch-bootstrap.tar.xz
|
||||
checksum: sha256:865c8a25312b663e724923eecf0dfc626f4cd621e2cfcb19eafc69a4fc666756
|
||||
|
||||
- name: Install host requisites
|
||||
become: yes
|
||||
dnf:
|
||||
name: btrfs-progs,arch-install-scripts
|
||||
state: latest
|
||||
|
||||
- name: Create container image file
|
||||
become: yes
|
||||
shell: truncate -s 4G /var/cache/gerbolyze_container.img
|
||||
args:
|
||||
creates: /var/cache/gerbolyze_container.img
|
||||
|
||||
- name: Create container image filesystem
|
||||
become: yes
|
||||
filesystem:
|
||||
dev: /var/cache/gerbolyze_container.img
|
||||
fstype: btrfs
|
||||
|
||||
- name: Create container image fstab entry
|
||||
become: yes
|
||||
mount:
|
||||
src: /var/cache/gerbolyze_container.img
|
||||
path: /var/cache/gerbolyze_container
|
||||
state: mounted
|
||||
fstype: btrfs
|
||||
opts: loop
|
||||
|
||||
- name: Unpack bootstrap image
|
||||
become: yes
|
||||
unarchive:
|
||||
remote_src: yes
|
||||
src: /tmp/arch-bootstrap.tar.xz
|
||||
dest: /var/cache/gerbolyze_container
|
||||
extra_opts: --strip-components=1
|
||||
creates: /var/cache/gerbolyze_container/etc
|
||||
|
||||
- name: Copy mirrorlist into container
|
||||
become: yes
|
||||
copy:
|
||||
src: mirrorlist
|
||||
dest: /var/cache/gerbolyze_container/etc/pacman.d/mirrorlist
|
||||
|
||||
- name: Copy render script
|
||||
become: yes
|
||||
copy:
|
||||
src: render.sh
|
||||
dest: /usr/local/sbin/gerbolyze_render.sh
|
||||
mode: ug+x
|
||||
|
||||
- name: Copy vector script
|
||||
become: yes
|
||||
copy:
|
||||
src: vector.sh
|
||||
dest: /usr/local/sbin/gerbolyze_vector.sh
|
||||
mode: ug+x
|
||||
|
||||
- name: Initialize container pacman keyring
|
||||
become: yes
|
||||
shell: arch-chroot /var/cache/gerbolyze_container pacman-key --init && arch-chroot /var/cache/gerbolyze_container pacman-key --populate archlinux
|
||||
args:
|
||||
creates: /var/cache/gerbolyze_container/etc/pacman.d/gnupg
|
||||
|
||||
- name: Fixup pacman.conf for pacman to work in chroot without its own root fs
|
||||
become: yes
|
||||
lineinfile:
|
||||
path: /var/cache/gerbolyze_container/etc/pacman.conf
|
||||
regexp: '^CheckSpace'
|
||||
line: '#CheckSpace'
|
||||
|
||||
- name: Update container and install software
|
||||
become: yes
|
||||
shell: arch-chroot /var/cache/gerbolyze_container pacman -Syu --noconfirm python3 opencv hdf5 gtk3 python-numpy python-pip imagemagick unzip zip
|
||||
|
||||
# TODO maybe install directly from local git checkout?
|
||||
- name: Install gerbolyze
|
||||
become: yes
|
||||
shell: arch-chroot /var/cache/gerbolyze_container pip install -U --upgrade-strategy=eager gerbolyze
|
||||
|
||||
# - name: Cleanup bootstrap image
|
||||
# file:
|
||||
# path: /tmp/arch-bootstrap.tar.xz
|
||||
# state: absent
|
||||
|
||||
- name: Create app cache directory
|
||||
file:
|
||||
path: /var/cache/gerboweb
|
||||
owner: user # FIXME debug
|
||||
group: user # FIXME debug
|
||||
mode: 0770
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
|
||||
[ $# != 1 ] && exit 1
|
||||
ID=$1
|
||||
egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2
|
||||
|
||||
systemd-nspawn \
|
||||
-D /var/cache/gerbolyze_container \
|
||||
-x --bind=/var/cache/gerboweb/upload/$ID:/mnt \
|
||||
/bin/sh -c "set -euo pipefail
|
||||
unzip -j -d /tmp/gerber /mnt/gerber.zip
|
||||
rm -f /mnt/render_top.png /mnt/render_bottom.png /mnt/render_top.small.png /mnt/render_bottom.small.png
|
||||
date; echo 'Rendering bottom layer'
|
||||
gerbolyze render top /tmp/gerber /mnt/render_top.png
|
||||
date; echo 'Scaling down'
|
||||
convert /mnt/render_top.png -resize 500x500 /mnt/render_top.small.png
|
||||
date; echo 'Rendering top layer'
|
||||
gerbolyze render bottom /tmp/gerber /mnt/render_bottom.png
|
||||
date; echo 'Scaling down'
|
||||
convert /mnt/render_bottom.png -resize 500x500 /mnt/render_bottom.small.png"
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
|
||||
[ $# != 2 ] && exit 1
|
||||
ID=$1
|
||||
egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2
|
||||
LAYER=$2
|
||||
egrep -x -q '^(top|bottom)$'<<<"$LAYER" || exit 2
|
||||
|
||||
systemd-nspawn \
|
||||
-D /var/cache/gerbolyze_container \
|
||||
-x --bind=/var/cache/gerboweb/upload/$ID:/mnt \
|
||||
/bin/sh -c "set -euo pipefail
|
||||
cd /tmp
|
||||
unzip -j -d gerber_in /mnt/gerber.zip
|
||||
gerbolyze vectorize $LAYER gerber_in gerber /mnt/overlay.png
|
||||
rm -f /mnt/gerber_out.zip
|
||||
zip -r /mnt/gerber_out.zip gerber"
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
MAX_CONTENT_LENGTH=10000000
|
||||
SECRET_KEY="FIXME: CHANGE THIS KEY"
|
||||
UPLOAD_PATH="/var/cache/gerboweb/upload"
|
||||
JOB_QUEUE_DB="/var/cache/gerboweb/job_queue.sqlite3"
|
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# TODO create systemd unit file
|
||||
# TODO create systemd tmpfiles.d config
|
||||
# TODO setup ansible deployment
|
||||
# TODO setup webserver user disk quota
|
||||
|
||||
import tempfile
|
||||
import uuid
|
||||
from functools import wraps
|
||||
from os import path
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
from flask import Flask, url_for, redirect, session, make_response, render_template, request, send_file, abort
|
||||
from flask_wtf import FlaskForm
|
||||
from flask_wtf.file import FileField
|
||||
from wtforms.fields import RadioField
|
||||
from wtforms.validators import DataRequired
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
from job_queue import JobQueue
|
||||
|
||||
app = Flask(__name__, static_url_path='/static')
|
||||
app.config.from_envvar('GERBOWEB_SETTINGS')
|
||||
|
||||
class UploadForm(FlaskForm):
|
||||
upload_file = FileField(validators=[DataRequired()])
|
||||
|
||||
class OverlayForm(UploadForm):
|
||||
upload_file = FileField(validators=[DataRequired()])
|
||||
side = RadioField('Side', choices=[('top', 'Top'), ('bottom', 'Bottom')])
|
||||
|
||||
class ResetForm(FlaskForm):
|
||||
pass
|
||||
|
||||
job_queue = JobQueue(app.config['JOB_QUEUE_DB'])
|
||||
|
||||
def tempfile_path(namespace):
|
||||
""" Return a path for a per-session temporary file identified by the given namespace. Create the session tempfile
|
||||
dir if necessary. The application tempfile dir is controlled via the upload_path config value and not managed by
|
||||
this function. """
|
||||
if not path.isdir(app.config['UPLOAD_PATH']):
|
||||
os.mkdir(app.config['UPLOAD_PATH'])
|
||||
sess_tmp = path.join(app.config['UPLOAD_PATH'], session['session_id'])
|
||||
if not path.isdir(sess_tmp):
|
||||
os.mkdir(sess_tmp)
|
||||
|
||||
return path.join(sess_tmp, namespace)
|
||||
|
||||
def require_session_id(fun):
|
||||
@wraps(fun)
|
||||
def wrapper(*args, **kwargs):
|
||||
if 'session_id' not in session:
|
||||
session['session_id'] = str(uuid.uuid4())
|
||||
return fun(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
@app.route('/')
|
||||
@require_session_id
|
||||
def index():
|
||||
forms = {
|
||||
'gerber_form': UploadForm(),
|
||||
'overlay_form': OverlayForm(),
|
||||
'reset_form': ResetForm() }
|
||||
|
||||
for job in ('vector_job', 'render_job'):
|
||||
if job in session and job_queue[session[job]].finished:
|
||||
del session[job]
|
||||
|
||||
r = make_response(render_template('index.html',
|
||||
has_renders = path.isfile(tempfile_path('gerber.zip')),
|
||||
has_output = path.isfile(tempfile_path('overlay.png')),
|
||||
**forms))
|
||||
if 'vector_job' in session or 'render_job' in session:
|
||||
r.headers.set('refresh', '10')
|
||||
return r
|
||||
|
||||
# NOTES about the gerber and overlay file upload routines
|
||||
# * The maximum upload size is limited by the MAX_CONTENT_LENGTH config setting.
|
||||
# * The uploaded files are deleted after a while by systemd tmpfiles.d
|
||||
# TODO: validate this setting applies *after* gzip transport compression
|
||||
|
||||
@app.route('/upload/<namespace>', methods=['POST'])
|
||||
@require_session_id
|
||||
def upload(namespace):
|
||||
if namespace not in ('gerber', 'overlay'):
|
||||
return abort(400, 'Invalid upload type')
|
||||
|
||||
upload_form = UploadForm() if namespace == 'gerber' else OverlayForm()
|
||||
if upload_form.validate_on_submit():
|
||||
f = upload_form.upload_file.data
|
||||
|
||||
if namespace == 'gerber':
|
||||
f.save(tempfile_path('gerber.zip'))
|
||||
session['filename'] = secure_filename(f.filename) # Cache filename for later download
|
||||
if 'render_job' in session:
|
||||
job_queue.drop(session['render_job'])
|
||||
session['render_job'] = job_queue.enqueue('render',
|
||||
session_id=session['session_id'],
|
||||
client=request.remote_addr)
|
||||
else: # namespace == 'vector'
|
||||
f.save(tempfile_path('overlay.png'))
|
||||
|
||||
# Re-vectorize if either file has changed
|
||||
if path.isfile(tempfile_path('gerber.zip')) and path.isfile(tempfile_path('overlay.png')):
|
||||
if 'vector_job' in session:
|
||||
job_queue.drop(session['vector_job'])
|
||||
session['vector_job'] = job_queue.enqueue('vector',
|
||||
client=request.remote_addr,
|
||||
session_id=session['session_id'],
|
||||
side=upload_form.side.data)
|
||||
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route('/render/preview/<side>')
|
||||
def render_preview(side):
|
||||
if not side in ('top', 'bottom'):
|
||||
return abort(400, 'side must be either "top" or "bottom"')
|
||||
return send_file(tempfile_path(f'render_{side}.small.png'))
|
||||
|
||||
@app.route('/render/download/<side>')
|
||||
def render_download(side):
|
||||
if not side in ('top', 'bottom'):
|
||||
return abort(400, 'side must be either "top" or "bottom"')
|
||||
return send_file(tempfile_path(f'render_{side}.png'),
|
||||
mimetype='image/png',
|
||||
as_attachment=True,
|
||||
attachment_filename=f'{path.splitext(session["filename"])[0]}_render.png')
|
||||
|
||||
@app.route('/output/download')
|
||||
def output_download():
|
||||
return send_file(tempfile_path('gerber_out.zip'),
|
||||
mimetype='application/zip',
|
||||
as_attachment=True,
|
||||
attachment_filename=f'{path.splitext(session["filename"])[0]}_with_artwork.zip')
|
||||
|
||||
@app.route('/session_reset', methods=['POST'])
|
||||
@require_session_id
|
||||
def session_reset():
|
||||
if 'render_job' in session:
|
||||
session['render_job'].abort()
|
||||
if 'vector_job' in session:
|
||||
session['vector_job'].abort()
|
||||
session.clear()
|
||||
return redirect(url_for('index'))
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
import signal
|
||||
import subprocess
|
||||
import logging
|
||||
import itertools
|
||||
|
||||
from job_queue import JobQueue
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('queue', help='job queue sqlite3 database file')
|
||||
parser.add_argument('--loglevel', '-l', default='info')
|
||||
args = parser.parse_args()
|
||||
|
||||
numeric_level = getattr(logging, args.loglevel.upper(), None)
|
||||
if not isinstance(numeric_level, int):
|
||||
raise ValueError('Invalid log level: %s' % loglevel)
|
||||
logging.basicConfig(level=numeric_level)
|
||||
|
||||
job_queue = JobQueue(args.queue)
|
||||
|
||||
signal.signal(signal.SIGALRM, lambda *args: None) # Ignore incoming alarm signals while processing jobs
|
||||
signal.setitimer(signal.ITIMER_REAL, 0.001, 1)
|
||||
while signal.sigwait([signal.SIGALRM, signal.SIGINT]) == signal.SIGALRM:
|
||||
logging.debug('Checking for jobs')
|
||||
for job in job_queue.job_iter('render'):
|
||||
logging.info(f'Processing {job.type} job {job.id} session {job["session_id"]} from {job.client} submitted {job.created}')
|
||||
with job:
|
||||
job.result = subprocess.call(['sudo', '/usr/local/sbin/gerbolyze_render.sh', job['session_id']])
|
||||
logging.info(f'Finishied processing {job.type} job {job.id}')
|
||||
|
||||
for job in job_queue.job_iter('vector'):
|
||||
logging.info(f'Processing {job.type} job {job.id} session {job["session_id"]} from {job.client} submitted {job.created}')
|
||||
with job:
|
||||
job.result = subprocess.call(['sudo', '/usr/local/sbin/gerbolyze_vector.sh', job['session_id'], job['side']])
|
||||
logging.info(f'Finishied processing {job.type} job {job.id}')
|
||||
logging.info('Caught SIGINT. Exiting.')
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
import json
|
||||
import sqlite3
|
||||
|
||||
class JobQueue:
|
||||
def __init__(self, dbfile):
|
||||
self.dbfile = dbfile
|
||||
self.db = sqlite3.connect(dbfile, check_same_thread=False)
|
||||
self.db.row_factory = sqlite3.Row
|
||||
with self.db as conn:
|
||||
conn.execute('''CREATE TABLE IF NOT EXISTS jobs
|
||||
(id INTEGER PRIMARY KEY,
|
||||
type TEXT,
|
||||
params TEXT,
|
||||
client TEXT,
|
||||
result TEXT DEFAULT NULL,
|
||||
created DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
consumed DATETIME DEFAULT NULL,
|
||||
aborted DATETIME DEFAULT NULL,
|
||||
finished DATETIME DEFAULT NULL);''')
|
||||
|
||||
def enqueue(self, task_type:str, client, **params):
|
||||
""" Enqueue a job of the given type with the given params. Returns the new job ID. """
|
||||
with self.db as conn:
|
||||
return conn.execute('INSERT INTO jobs(type, client, params) VALUES (?, ?, ?)',
|
||||
(task_type, client, json.dumps(params))).lastrowid
|
||||
|
||||
def check_result(slef, job_id):
|
||||
with self.db as conn:
|
||||
job = conn.execute('SELECT * FROM jobs WHERE id=?', (job_id,)).fetchone()
|
||||
if job is None:
|
||||
raise IndexError('Job id not found')
|
||||
return job.result
|
||||
|
||||
def drop(self, job_id):
|
||||
with self.db as conn:
|
||||
return conn.execute('DELETE FROM jobs WHERE id=?', (job_id,)).rowcount > 0
|
||||
|
||||
def pop(self, task_type):
|
||||
""" Fetch the next job of the given type. Returns a sqlite3.Row object of the job or None if no jobs of the given
|
||||
type are queued. """
|
||||
with self.db as conn:
|
||||
job = conn.execute('SELECT * FROM jobs WHERE type=? AND consumed IS NULL ORDER BY created ASC LIMIT 1',
|
||||
(task_type,)).fetchone()
|
||||
if job is None:
|
||||
return None
|
||||
|
||||
# Atomically commit to this job
|
||||
conn.execute('UPDATE jobs SET consumed=datetime("now") WHERE id=?', (job['id'],))
|
||||
|
||||
return Job(self.db, job)
|
||||
|
||||
def job_iter(self, task_type):
|
||||
return iter(lambda: self.pop(task_type), None)
|
||||
|
||||
def __getitem__(self, key):
|
||||
""" Return the job with the given ID, or raise a KeyError if the key cannot be found. """
|
||||
with self.db as conn:
|
||||
job = conn.execute('SELECT * FROM jobs WHERE id=?', (key,)).fetchone()
|
||||
if job is None:
|
||||
raise KeyError(f'Unknown job ID "{key}"')
|
||||
|
||||
return Job(self.db, job)
|
||||
|
||||
class Job(dict):
|
||||
def __init__(self, db, row):
|
||||
super().__init__(json.loads(row['params']))
|
||||
self._db = db
|
||||
self._row = row
|
||||
self.id = row['id']
|
||||
self.type = row['type']
|
||||
self.client = row['client']
|
||||
self.created = row['created']
|
||||
self.consumed = row['consumed']
|
||||
self.finished = row['finished']
|
||||
self.result = None
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, _exc_type, _exc_val, _exc_tb):
|
||||
with self._db as conn:
|
||||
conn.execute('UPDATE jobs SET finished=datetime("now"), result=? WHERE id=?', (self.result, self.id,))
|
||||
|
||||
def abort(self):
|
||||
with self._db as conn:
|
||||
conn.execute('UPDATE jobs SET aborted=datetime("now") WHERE id=?', (self.id,))
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Gerbolyze Raster image to PCB renderer</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="desc">
|
||||
<h1>Raster image to PCB converter</h1>
|
||||
<p>
|
||||
Gerbolyze is a tool for rendering black and white raster (PNG) images directly onto gerber layers. You can
|
||||
use this to put art on a PCB's silkscreen, solder mask or copper layers. The input is a black-and-white PNG
|
||||
image that is vectorized and rendered into an existing gerber file. Gerbolyze works with gerber files
|
||||
produced with any EDA toolchain and has been tested to work with both Altium and KiCAD.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="step" id="step1">
|
||||
<h2>Step 1: Upload zipped gerber files</h2>
|
||||
<p>
|
||||
First, upload a zip file containing all your gerber files. The default file names used by KiCAD, Eagle
|
||||
and Altium are supported.
|
||||
</p>
|
||||
|
||||
<form method="POST" action="{{url_for('upload', namespace='gerber')}}" enctype="multipart/form-data">
|
||||
{{gerber_form.csrf_token}}
|
||||
{{gerber_form.upload_file.label}} {{gerber_form.upload_file(size=20)}}
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if 'render_job' in session or has_renders %}
|
||||
<div class="step" id="step2">
|
||||
<h2>Step 2: Download the target side's preview image</h2>
|
||||
<p>
|
||||
Second, download either the top or bottom preview image and use it to align and scale your own artwork
|
||||
in an image editing program such as Gimp. Then upload your overlay image below.
|
||||
|
||||
Note that you will have to convert grayscale images into binary images yourself. Gerbolyze can't do this
|
||||
for you since there are lots of variables involved. Our <a href="{{url_for('static',
|
||||
filename='image_processing_guide.html')}}">Guideline on image processing</a> gives an overview on
|
||||
<i>one</i> way to produce agreeable binary images from grayscale source material.
|
||||
</p>
|
||||
{% if 'render_job' in session %}
|
||||
<strong>Processing...</strong> (this may take several minutes!)
|
||||
{% else %}
|
||||
<img src="{{url_for('render_preview', side='top')}}"> <a href="{{url_for('render_download', side='top')}}">Download</a>
|
||||
<img src="{{url_for('render_preview', side='bottom')}}"> <a href="{{url_for('render_download', side='bottom')}}">Download</a>
|
||||
{% endif %}
|
||||
<form method="POST" action="{{url_for('session_reset')}}">
|
||||
{{reset_form.csrf_token}}
|
||||
<input type="submit" value="Start over">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="step" id="step3">
|
||||
<h2>Step 3: Upload overlay image</h2>
|
||||
<p>
|
||||
Now, upload your binary overlay image as a PNG and let gerbolyze render it onto the target layer. The PNG
|
||||
file should be a black and white binary file with details generally above about 10px size. <b>Antialiased
|
||||
edges are supported.</b>
|
||||
</p>
|
||||
<form method="POST" action="{{url_for('upload', namespace='overlay')}}" enctype="multipart/form-data">
|
||||
{{overlay_form.csrf_token}}
|
||||
{{overlay_form.upload_file.label}} {{overlay_form.upload_file(size=20)}}
|
||||
{{overlay_form.side.label}} {{overlay_form.side()}}
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if 'vector_job' in session or has_output %}
|
||||
<div class="step" id="step4">
|
||||
<h2> Step 4: Download the processed gerber files</h2>
|
||||
{% if 'vector_job' in session %}
|
||||
<strong>Processing...</strong> (this may take several minutes!)
|
||||
{% else %}
|
||||
<a href="{{url_for('output_download')}}">Download</a>
|
||||
{% endif %}
|
||||
<form method="POST" action="{{url_for('session_reset')}}">
|
||||
{{reset_form.csrf_token}}
|
||||
<input type="submit" value="Start over">
|
||||
</form>
|
||||
</div>
|
||||
{% endif %} {# vector job #}
|
||||
{% endif %} {# render job #}
|
||||
</body>
|
||||
</html>
|
Ładowanie…
Reference in New Issue