talimat.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. #!/usr/bin/python2
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Copyright (c) 2017 Mahmut Şamil Avar - milisarge
  5. #
  6. # Permission is hereby granted, free of charge, to any person obtaining a copy
  7. # of this software and associated documentation files (the "Software"), to
  8. # deal in the Software without restriction, including without limitation the
  9. # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. # sell copies of the Software, and to permit persons to whom the Software is
  11. # furnished to do so, subject to the following conditions:
  12. #
  13. # The above copyright notice and this permission notice shall be included in
  14. # all copies or substantial portions of the Software.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. # IN THE SOFTWARE.
  23. """
  24. Milis Linux Python Talimat Kütüphanesi - talimat.py
  25. """
  26. import sys
  27. import re
  28. import os
  29. import shlex
  30. import urllib2
  31. from requests.exceptions import HTTPError
  32. # Milis linux talimat sınıfı
  33. class Talimat():
  34. talimatname="/sources/milis.git/talimatname/"
  35. def __init__(self):
  36. self.tanim=""
  37. self.url=""
  38. self.paketci=""
  39. self.gerekler=[]
  40. self.isim=""
  41. self._isim=""
  42. self.surum=""
  43. self.devir=""
  44. self.kaynaklar=[]
  45. self.derleme="build() {"+"\n"
  46. def ice_aktar(self,dosya,tip):
  47. if tip=="arch":
  48. pkgbuild=PKGBUILD(dosya)
  49. self.tanim=pkgbuild.description
  50. self.url=pkgbuild.url
  51. self.paketci="milisarge"
  52. if hasattr(pkgbuild, 'makedepends'):
  53. for mgerek in pkgbuild.makedepends:
  54. if mgerek not in self.gerekler:
  55. self.gerekler.append(mgerek)
  56. if hasattr(pkgbuild, 'depends'):
  57. for gerek in pkgbuild.depends:
  58. if gerek not in self.gerekler:
  59. self.gerekler.append(gerek)
  60. self.isim=pkgbuild.name
  61. if hasattr(pkgbuild, '_name'):
  62. self._isim=pkgbuild._name
  63. self.surum=pkgbuild.version
  64. self.devir=pkgbuild.release
  65. self.kaynaklar=pkgbuild.sources
  66. self._ice_aktar_bloklar(dosya,tip)
  67. return "tanımlar için gecersiz tip!"
  68. def _gerekler(self):
  69. gerekstr=""
  70. for gerek in self.gerekler:
  71. if os.path.exists(self.talimatname+"temel-ek/"+gerek) is False and os.path.exists(self.talimatname+"temel/"+gerek) is False:
  72. gerekstr+=gerek+" "
  73. if os.path.exists(self.talimatname+"genel/"+gerek) is False:
  74. print renk.uyari+gerek+" talimatı yapılmalı!"+renk.son
  75. return gerekstr
  76. def _kaynaklar(self):
  77. kaynakstr=""
  78. for kaynak in self.kaynaklar:
  79. kaynakstr+=kaynak+"\n"
  80. return kaynakstr
  81. def _ice_aktar_bloklar(self,dosya,tip):
  82. if tip=="arch":
  83. #bu sekilde de satirlar cekilebilir.
  84. #lines = [line.rstrip('\n') for line in open(dosya)]
  85. with open(dosya) as f:
  86. satirlar = f.readlines()
  87. blok=False
  88. onblok=False
  89. for satir in satirlar:
  90. if "md5sums=(" in satir or "sha256sums=('" in satir:
  91. onblok=True
  92. if onblok is True and "')" in satir:
  93. blok=True
  94. continue
  95. if blok and satir.rstrip()!="" and satir.rstrip()!="}":
  96. if (satir not in self.derleme) and ("pkgver()" not in satir) and ("prepare()" not in satir) and ("build()" not in satir) and ("package()" not in satir) and ("check()" not in satir):
  97. satir=satir.replace("pkgdir","PKG")
  98. satir=satir.replace("srcdir","SRC")
  99. satir=satir.replace("pkgname","name")
  100. satir=satir.replace("pkgver","version")
  101. satir=satir.replace("pkgrel","release")
  102. self.derleme+=satir+"\n"
  103. else:
  104. return "blok için gecersiz tip!"
  105. def olustur(self):
  106. if self.isim:
  107. print renk.tamamb+self.isim+" talimatı hazırlanıyor..."+renk.son
  108. os.system("mkdir -p "+self.isim)
  109. open(self.isim+"/talimat","w").write(self.icerik())
  110. def icerik(self):
  111. icerikstr=""
  112. icerikstr+="# Description: "+self.tanim+"\n"
  113. icerikstr+="# URL: "+self.url+"\n"
  114. icerikstr+="# Packager: "+self.paketci+"\n"
  115. icerikstr+="# Depends on: "+self._gerekler()
  116. icerikstr+="\n"+"\n"
  117. icerikstr+="name="+self.isim+"\n"
  118. if self._isim !="":
  119. icerikstr+="_name="+self._isim+"\n"
  120. icerikstr+="version="+str(self.surum)+"\n"
  121. icerikstr+="release="+str(self.devir)+"\n"
  122. icerikstr+="source=("+self._kaynaklar()+")"
  123. icerikstr+="\n"+"\n"
  124. icerikstr+=self.derleme
  125. icerikstr+="}"
  126. return icerikstr
  127. def cevir(self,dosya,tip="arch"):
  128. self.ice_aktar(dosya,tip)
  129. self.olustur()
  130. print renk.tamamy+talimat.isim+" talimatı hazır."+renk.son
  131. # archlinux pkgbuild sınıfı
  132. #Copyright (c) 2009 Sebastian Nowicki (parched.py)
  133. class PKGBUILD():
  134. _symbol_regex = re.compile(r"\$(?P<name>{[\w\d_]+}|[\w\d]+)")
  135. def __init__(self, name=None, fileobj=None):
  136. self.install = ""
  137. self.checksums = {
  138. 'md5': [],
  139. 'sha1': [],
  140. 'sha256': [],
  141. 'sha384': [],
  142. 'sha512': [],
  143. }
  144. self.noextract = []
  145. self.sources = []
  146. self.makedepends = []
  147. # Symbol lookup table
  148. self._var_map = {
  149. 'pkgname': 'name',
  150. '_pkgname': '_name',
  151. 'pkgver': 'version',
  152. 'pkgdesc': 'description',
  153. 'pkgrel': 'release',
  154. 'source': 'sources',
  155. 'arch': 'architectures',
  156. 'license': 'licenses',
  157. }
  158. self._checksum_fields = (
  159. 'md5sums',
  160. 'sha1sums',
  161. 'sha256sums',
  162. 'sha384sums',
  163. 'sha512sums',
  164. )
  165. # Symbol table
  166. self._symbols = {}
  167. if not name and not fileobj:
  168. raise ValueError("nothing to open")
  169. should_close = False
  170. if not fileobj:
  171. fileobj = open(name, "r")
  172. should_close = True
  173. self._parse(fileobj)
  174. if should_close:
  175. fileobj.close()
  176. def _handle_assign(self, token):
  177. var, equals, value = token.strip().partition('=')
  178. # Is it an array?
  179. if value[0] == '(' and value[-1] == ')':
  180. self._symbols[var] = self._clean_array(value)
  181. else:
  182. self._symbols[var] = self._clean(value)
  183. def _parse(self, fileobj):
  184. """Parse PKGBUILD"""
  185. if hasattr(fileobj, "seek"):
  186. fileobj.seek(0)
  187. parser = shlex.shlex(fileobj, posix=True)
  188. parser.whitespace_split = True
  189. in_function = False
  190. while 1:
  191. token = parser.get_token()
  192. if token is None or token == '':
  193. break
  194. # Skip escaped newlines and functions
  195. if token == '\n' or in_function:
  196. continue
  197. # Special case:
  198. # Array elements are dispersed among tokens, we have to join
  199. # them first
  200. if token.find("=(") >= 0 and not token.rfind(")") >= 0:
  201. in_array = True
  202. elements = []
  203. while in_array:
  204. _token = parser.get_token()
  205. if _token == '\n':
  206. continue
  207. if _token[-1] == ')':
  208. _token = '"%s")' % _token.strip(')')
  209. token = token.replace('=(', '=("', 1) + '"'
  210. token = " ".join((token, " ".join(elements), _token))
  211. in_array = False
  212. else:
  213. elements.append('"%s"' % _token.strip())
  214. # Assignment
  215. if re.match(r"^[\w\d_]+=", token):
  216. self._handle_assign(token)
  217. # Function definitions
  218. elif token == '{':
  219. in_function = True
  220. elif token == '}' and in_function:
  221. in_function = False
  222. self._substitute()
  223. self._assign_local()
  224. if self.release:
  225. self.release = float(self.release)
  226. def _clean(self, value):
  227. """Pythonize a bash string"""
  228. return " ".join(shlex.split(value))
  229. def _clean_array(self, value):
  230. """Pythonize a bash array"""
  231. return shlex.split(value.strip('()'))
  232. def _replace_symbol(self, matchobj):
  233. """Replace a regex-matched variable with its value"""
  234. symbol = matchobj.group('name').strip("{}")
  235. # If the symbol isn't found fallback to an empty string, like bash
  236. try:
  237. value = self._symbols[symbol]
  238. except KeyError:
  239. value = ''
  240. # BUG: Might result in an infinite loop, oops!
  241. return self._symbol_regex.sub(self._replace_symbol, value)
  242. def _substitute(self):
  243. """Substitute all bash variables within values with their values"""
  244. for symbol in self._symbols:
  245. value = self._symbols[symbol]
  246. # FIXME: This is icky
  247. if isinstance(value, str):
  248. result = self._symbol_regex.sub(self._replace_symbol, value)
  249. else:
  250. result = [self._symbol_regex.sub(self._replace_symbol, x)
  251. for x in value]
  252. self._symbols[symbol] = result
  253. def _assign_local(self):
  254. """Assign values from _symbols to PKGBUILD variables"""
  255. for var in self._symbols:
  256. value = self._symbols[var]
  257. if var in self._checksum_fields:
  258. key = var.replace('sums', '')
  259. self.checksums[key] = value
  260. else:
  261. if var in self._var_map:
  262. var = self._var_map[var]
  263. setattr(self, var, value)
  264. class renk:
  265. baslik = '\033[95m'
  266. tamamb = '\033[94m'
  267. tamamy = '\033[92m'
  268. uyari = '\033[93m'
  269. hata = '\033[91m'
  270. son = '\033[0m'
  271. kalin = '\033[1m'
  272. altcizgili = '\033[4m'
  273. class Arge:
  274. def indir(self,link):
  275. if "packages/" in link:
  276. paket=link.split("?h=packages/")[1]
  277. else:
  278. paket=link.split("?h=")[1]
  279. print renk.tamamb+paket+" indiriliyor..."+renk.son
  280. try:
  281. veri = urllib2.urlopen(link)
  282. open(paket+"_pkgbuild","w").write(veri.read())
  283. return paket+"_pkgbuild"
  284. except urllib2.HTTPError, e:
  285. if e.code == 404:
  286. print renk.hata+link+" bulunamadı!"+renk.son
  287. return None
  288. def aur_link(self,paket):
  289. link="https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h="+paket
  290. return link
  291. def arch2_link(self,paket):
  292. link="https://git.archlinux.org/svntogit/community.git/plain/trunk/PKGBUILD?h=packages/"+paket
  293. return link
  294. def arch_link(self,paket):
  295. link="https://git.archlinux.org/svntogit/packages.git/plain/trunk/PKGBUILD?h=packages/"+paket
  296. return link
  297. if __name__ == '__main__':
  298. if len(sys.argv) > 1:
  299. dosya=sys.argv[1]
  300. talimat=Talimat()
  301. arge=Arge()
  302. if os.path.exists(dosya):
  303. talimat.cevir(dosya)
  304. elif "https" in dosya or "http" in dosya:
  305. Pdosya=arge.indir(dosya)
  306. talimat.cevir(Pdosya)
  307. elif dosya == "-a":
  308. if len(sys.argv) > 2:
  309. paket=sys.argv[2]
  310. paket=str(paket)
  311. link=arge.aur_link(paket)
  312. dosya=arge.indir(link)
  313. if dosya is None:
  314. link=arge.arch_link(paket)
  315. dosya=arge.indir(link)
  316. if dosya is None:
  317. link=arge.arch2_link(paket)
  318. dosya=arge.indir(link)
  319. if link and dosya:
  320. talimat.cevir(dosya)
  321. else:
  322. print renk.hata+dosya+" paremetre bulunamadı!"+renk.son