(fO_N~<22md@0Qbu7X+ZFK2cZpXpMj+v_1lT1CwNW1#AItM_P7s=-$L{hh@RcE=zqGsJnw|C+}_a+E{{AsS};8bq0+N6==EL?b|9nsI@z&yJh=c*(;*D-Jh0S+`o)6
zp7i@4AjhJ#JmVicB?*oDNrER_s=~%cI!n5xaf_szKBZh2HKxUyiraRsqXl}gOtsF6
zjgsg^HQJdyL|O`zh5f{aUi7+#v{
zwMT1dUuQVP(39L3|_F#*b0p3l@mAf(?@7^OLdWuZxQGa
z*muU3um)7uY4^phNWF`_-{33le*(PeH2Ja<^1;GP=9y2vAT{|eIg#xX-p2&IGvZj2
z+yeOzxo%IOmeAVW^@hmgsKNejWr*xGa*#Klx1-MLpaJLA=rZ4g&u$=)D8gISs7?_(
zYe*G6WGb`vw2JVZ%+=dKOay<2j(8M3rH#0jYekQ0Q~ELJM^)r69pCNA9rZEYd{HH)
z0yE$E?AGny126SgmK*M$?crx^*Fx2o#YdYjU#oG
z9;4Pzoh0xH0n)#^N#Hpbc1De=qJE6bSP}?C;Ni~?oM0yiEv|J)S&3_#TKC&%Hu2w%
zB9~O30vM6?6q-0@YTG)?%eI9!@k~+x|By_vU_7Mi0Hap
z$sghO(7C1JFHkY#UC@E>%HvskKHj|dcrfU_`||DmqlmHZ?A8+KKgVsKpixY5!!|tU
zoczc{n>dey9~+U2S4;_&+%T2scpvA9if3$;{=iH&;y#->SZyy}zd`@#MPc>n`T5&3
zeN}7gPK&KF8m4oK{k;%N)B7Phn&n)vJW^amH!P1;tOTCePo;P!s)M~UpPrSq(=g|4
z5jv^POWbyd=7L=_iF2UEdYBVUJsO`@(yXlWF-V61h1F*9l|dI%emsFH<;l(Tq7{
zE}-Mnk?^7_+|nnZnHLUf?UO}etR8X5FgKuVOpksCXby0Ubn|2$4dsn4X`78@<4?@75SRc*-cOLi=Q$RovW
znLr4QNTLKnGMXh4NI?XD1DyXB2En
Mhd%G~j1P~00Zm=G_W%F@
literal 0
HcmV?d00001
diff --git a/src/__pycache__/route.cpython-38.pyc b/src/__pycache__/route.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fe030591107aa8efe298955df39b657f65cafac8
GIT binary patch
literal 868
zcmZ`%yKWOf6rI3Ryg6HFxgJ+{c-7_RYaTm*IH(`P;jPg0b(k*&PZu$2i?1G=>?T
zvo%jSCtu`ZEmK+hGFPd3!HhD|4KtCI*D{TaoU&p312fr>hh*wuxjBFN3jL#JnX@Nn
zXRlA~Wo4Z|$u=gpFqu*8?m$dU{|D$;mU6>VVYm@DER{wYg)8ToLw=E??H<-F;7eanh=*dUpgNoXn)ItayFmeG9Z?I-XAZDwH-SP
z7nK`-wC~FT{Mf;44AgN{ehM9}mm9Bjhx){57?1JW_8Uy2_WJ+Wjxgnlt(fN*G4#Ed
zGLJ0Q2>E2Ff+{n=2vOZIC=Znl(LBo$Q-YZ_&c^K1wvUFK7D|^ZvF)``>Jonei7>h*
z=^i>B3GztMN_>%D*)_k5ljN@H+TMXiyb;WoxqZBc=%NxOM)I5o#7M_Mfz1p`-f5%%
zfEf1544l;!5L}Fq)XhHtIoDAcTXuZkSR_oB!dR>?*C%>olWtHX44fHU*el`%3
zJIzQzs7axJnxv^oNqC}?80ZW;h-CqUAnY%^FGtAg2MZwSM6F!0spI}tG$c\n'
+class Handler(BaseHTTPRequestHandler):
+
+ def r_403(self):
+ self.send_response(403)
+ self.end_headers()
+ print(self.client_address)
+
+ def r_404(self):
+ self.send_response(404)
+ self.end_headers()
+ print(self.client_address)
+
+ def route(self):
+ if self.path in route:
+ return true
+ else:
+ return false
+
+ def parse_url(self):
+ pass
+
+ def do_GET(self):
+ self.r_t =""
+ #print(Router.parse_url(self))
+ #print("data:\t" + self.rfile.read())
+ #request = Router.parse_url(self).decode('utf-8')
+ if self.client_address[0] == '127.0.0.1' or self.client_address[0].startswith('10.0'):
+ self.send_response(200)
+ self.end_headers()
+ if self.path =="/":
+ #content_len = int(self.headers(['Content-Length']))
+ #post_body = self.rfile.read('content_len')
+ #data = json.loads(post_body)
+ #print(data)
+ with open('./views/index.html', 'tr') as f:
+ self.r_t=f.read()
+ print(self.client_address)
+
+ elif self.path == '/main':
+ print(self.rfile/read())
+ with open("./README.txt", 'r') as f:
+ self.r_t = str(f.read())
+
+ elif self.path == '/ovelays':
+ overlays = get_list_overlays()
+ #print(ovls)
+ if overlays: # == "":
+ overlays ="Error"
+
+ self.r_t=json.dumps({"repositories": overlays})
+
+ elif self.path == "/favicon.ico":
+ with open('./favicon.png', 'rb') as f:
+ self.r_t = f.read()
+
+ elif self.path == '/logo.png':
+ pass
+
+ elif self.path.startswith( "/static/"):
+ self.r_static()
+ self.send_response(200)
+ #print(self.r_t)
+
+ elif self.path == '/get_dump_list':
+ try:
+ with open('./pkgs.json', 'r') as fn:
+ data = fn.read()
+ pkg_list = json.load
+ s(data)
+ print(pkg_list)
+ except Exception (e):
+ print(str(e))
+ self.r_t = json.dumps({"dump_portage": pkg_list})
+
+ elif self.path.startswith("/?st_app="):
+ #config = load_config()
+ #param = self.path.replace("/?st_app=", "")
+ #list_param = param.split(',')
+ #print(list_param)
+ for i in list_param:
+ if i.startswith('port'):
+ port = int(i.split('=')[1])
+ elif i.startswith('Lang'):
+ Lang = i.split('=')[1]
+
+ write_config(port, Lang)
+ print(config)
+ print(param)
+
+ elif self.path == 'find':
+ param = request['params']['name']
+ pk_list = []
+ search_result = {}
+ #if len(param.split('/')) == 2:
+ # param = param.split('/')[1]
+ #p_list = on_find(param)
+ #print(p_list)
+ #if len(p_list) == 0:
+ # print("Never Found")
+ # self.r_t = str(json.dumps({"Package_result": p_list}))
+ #else:
+ #for p in p_list:
+ #print(p)
+ if len(param.split("/")) == 2:
+ pk_list.append(Package().search(param.split("/")[1]))
+ else:
+ pk_list.append(Package().search(param))
+ #print(pk)
+ search_result = {"Package_result": pk_list}
+ self.r_t = str(json.dumps(search_result))
+
+ elif self.path == "get_settings_app":
+
+ self.r_t = str(json.dumps(load_config()))
+
+ elif self.path == 'get_portage':
+
+ #self.r_t = str(sort_inatll_pkg())
+ self.r_t = str(json.dumps(scan_config_portage()))
+
+ elif '.py?' in self.path:
+ print("loading")
+ self.path = "/static/app" + str(self.path.split('?')[0])
+ print(self.path)
+ self.r_static()
+
+ else:
+ self.send_response(404)
+
+ self.end_headers()
+ print(str(self.client_address[0]) +"\t" + str(404))
+
+ # Send the html message
+ #self.wfile.write(bytes(self.r_t, "utf-8"))
+ try:
+ return self.wfile.write(self.r_t)
+ except TypeError:
+ #print("TypeError")
+ return self.wfile.write(bytes(self.r_t, 'utf-8'))
+ else:
+ self.r_403()
+
+ def r_static(self):
+ if os.path.exists('./views/' + self.path):
+ #self.send_response(200)
+ #self.end_headers()
+ with open('./views/' + self.path, 'tr') as f:
+ self.r_t=f.read()
+
+ else:
+ self.send_response(404)
+ self.end_headers()
+ def do_POST(self):
+ self._set_headers()
+ content_len = int(self.headers.getheader('content-length', 0))
+ post_body = self.rfile.read(content_len)
+ data = json.loads(post_body)
+ print(data)
diff --git a/src/route.py b/src/route.py
new file mode 100644
index 0000000..07652f5
--- /dev/null
+++ b/src/route.py
@@ -0,0 +1,29 @@
+# -*- codding: utf-8 -*-
+#!/usr/bin/env python3
+from io import StringIO ## for Python 3
+from http.server import BaseHTTPRequestHandler
+import json
+class Router(BaseHTTPRequestHandler):
+ def __int__(self):
+ self.p_list = []
+ self.r_t = ""
+ pass
+ def route(self):
+ if self.path in route:
+ return true
+ else:
+ return false
+
+ def parse_url(request):
+
+ print("request.rfile:\t" + str(request.rfile.read()))
+ #return json.loads(str(request.rfile.read()))
+
+
+"""
+ def do_GET(self):
+ pass
+
+ def do_POST(self):
+ pass
+"""
\ No newline at end of file
diff --git a/start b/start
new file mode 100755
index 0000000..8b02299
--- /dev/null
+++ b/start
@@ -0,0 +1,6 @@
+#/bin/bash
+#rm ./gpo-repositories.xml
+#wget http://gpo.zugaina.org/lst/gpo-repositories.xml &&
+python3 server.py
+
+#python client.py
diff --git a/test.db b/test.db
new file mode 100644
index 0000000..e69de29
diff --git a/utils/__pycache__/utils.cpython-36.pyc b/utils/__pycache__/utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2f0a09352526dfb8ae5f30212e7febe338bf4bf8
GIT binary patch
literal 3169
zcmZuzTW=gm6|U;bbkBI~b)1`%4PvwyDYGEYie1DKMT^76C_vWi#loS*?$DlU+db*&
zo>bLr9IIP`OeA=L4w_S7R3_!MR856i1SZ)v?MNwi;%n|E{V(Nm&K~M
zg8rPiDqcpvBHRyH_bXAe-;XD{ko|ttP>H-hQBR>J+v;)?$mGE!QF=gvlb-|TZ8X&e
z(QL@4_D0yt*^(Txu49}+nP5NB$s`qjV$z4yk}tm2J19m;uRf>uFxed!Quii0%~Va-
z$B#^qs=h1=-K10KIL2iFI-uR@=b^RGtQvQ~q^#nk%Frp>(?d3Jl*pk3NBiA8@<c?Es`>Y}pxY`-Ir8D%VxO|0c
zRX$n+EjY|dZ|Dmc;5Pg4qbe-JVMBORJ`5_~^1kI8kCyFM!+r%jEMN7Q4)3?*6VB)_
zf-3kK%bj~nH%q^4l!(UPx)sblY|YKPvBUI&Zj%GZtR+9;fU3
zNv?}xy^#C8;^RbS@gvof$+%D{LNQI$`r#;xJdzmCT6IArY9Q0GPK(@x6h-5BKbd?R
z2ATb_GvA{#`^W4r$B#R+KhOR-`}^$EJ6?KWk`7t!$loBd9yK@WYr}G(d>QIQjo2ER
zGD~UWj^eR7k4Wh!^-g_V^l1Zm1(S_WjvE_S$NNZ7kLE;vnjG{$s>nC7<^<%r
z;Gb@M6{(s-F6l_)S)nH;qjA><
z5(2j6ItC(NAHa#mqqUN7>iL_tAIelGbHMu%Ca4gEIZMF1OI*@D1|*;#B_QFQwdNWa
z4YU&u?zCJnJ%{&-pSh8Zs;&Q1ULw6oZ}}PsqNRvM*QwQeoy26ynpjL;ID^UWVMvjb
zLBR`Leh1vCg5+va(ke))1K71ia0n+%xmwlk6!DNZG(fn5d+M6Kx9E+G(ydu(FRK)eYuV^kJOcHz9ygJxuk1yoQyDJLI8W1np5_{E=
zw;(yS7y&fRu@?Im7+A}`DNtq|Dy(Q8nt%9vYeAGYSnM$@*rUl;KJM
literal 0
HcmV?d00001
diff --git a/utils/__pycache__/utils.cpython-38.pyc b/utils/__pycache__/utils.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3ac42db1359937271801b65d844237b157410120
GIT binary patch
literal 3174
zcmZuz&5s;M6|d^=nVsF(yZ%@w0Y)ZB83Q|3L{KnRSYt0D$XOD{5Yr+VdZ&7Kd)?DL
zuBwUcRW|}V5?oL&969WY6Bm?2kOBgZoM&&SuAKZY_yWIIJ?rc)ZmFtXy{fKypTAc>
znV)Yne1CZG?++()jQxiuM?V*nRW$W`bb<+f*WpY!!p&LSj6CLc?!*p8FLy^??9KN0
zqrhRDjlwtr#}~oJEN+QVL>SwmCE6J0#GL40?1*`>fN@^DEEdJm$2?vTXT(`>UJ&QR
zd5ovTvbccpw0KdxgmF>0@3G#O;?`i0Omry+gE&yBygN}(AS_$&aTCh)-Xv9eNQ|SO
zgUNL?)j_A(9^bdR;XG$ua`1YNaY|*vtyHIzO#F#SA6(l#{c3-^9Hsr{uKxXWV_Ztz
zpXe-CO}{dJXu?blWLfGK-9pzfE<^M~I{onTK+py&$_)@1tGQ-7e9x)aK9_H3w_=a^
zC(E@{IXBn`o!Zr2~;1oyT$IXBGR7V#1+h{uzUKQL~nO9)h$Zh{Xsb?
zM9-JxOyiBQVuJKRrnE9%IZg}Xk7ZWqo@b)XEKiGMl!BGWWMufJ@$#%lztCO=bV^62
zi5LvaVl&%P^Wa!RGVbvXZ}W(sbL1&-kJ+6ReWvW6F%i5*43WZnyyE-3cD7heCUCX0
z=T^?1w+|!KP_6dS0<^I5_I%;)^Be4g59_Fk_5$JU^PRBvE$v%6*ga)uft`i#vtrp}
zI=b7Ik2vBHW(w=@XRL7UFx{&BDyR^XzjJFCd#_#LbeQ)|J*PWld@^fAW^Jt-wtIP7
z>#@4h?#?(ZR2#pJMv?
z!EdI2n||JNBz5g~yN%(#e-Udu#>+8P)4m`J8-Tox*g!`T9^
zLFk{5E%t}oSuRe7(rKjFAV)L~4o_XiRq9oA6i*)FiTVYXdW^i|bX ?g|05UNmpf~ah`U`db|EAnRd6e+Ncie
zMe-$x69$Y^PtF?~S0`IYQjhi+KP!-yadddF
z-Fd>c@@x3}3Ywy1WKNqe!fqb&lbT&UW;KE)YSwCmO%_i0x;?hX;}8;xL?R&>!Azw;YS{Nh6vxnguGPo$`PEhQQOM$*!g6!
zhQELaZsqNx{(J#^6;%Llz2_S5ogd%2ZM>UFu@(Ebf4KJc+SB=!egjY|B%0y(d!Dtu
zq>^Vm%k;!#H17F8ML@XhV{Po?r{zr-I
zi;e#H?$&O&l5R{0rB36%xRVu111ASqQoV3iLGLH|T@wKm)%{Fw%a^f}UK-;(8K#Yw
zd-WJqW-S6}YSvo+0s%|e_XJ9;Lq!$ML-TF9MPY@#ehKRZby!CPid8TxcCgoZ23U-+
zBd%L`alm5dS=BmEZ;{oyUA6c8eFi(C+*UsQ*_2@sT)>XQy;s@Em7}S9@5a500Ac%<
z5n<(L7Mewbe*n{T6Ur`msI|V^>8EDYlQBWIDn%DY4XndMFFMY?~TF8T&_-z3IT
z6L+q9sG9H!P<8Wcqbc=g0lq7#mT9^&D?_(I$G&C7b4PgcEFDRYQ2RKuRnry$d5L%g
zTsD7gCfWeA0v$mZ0_^4i7+oEeVv?tCx?rgn(M5b2rFqebyl5`Eh~~G$$dB4l`+tbv
B*g^mR
literal 0
HcmV?d00001
diff --git a/utils/get_icon.py b/utils/get_icon.py
new file mode 100755
index 0000000..b1a71e4
--- /dev/null
+++ b/utils/get_icon.py
@@ -0,0 +1,13 @@
+# -*- codding: UFT-8 -*-
+#/usr/bin/env python3
+import requests
+from PIL import Image
+from io import StringIO
+#req = requests.get('https://api.github.com/events')
+payload = {'s': '16'}
+req = requests.get('https://iconbird.com/png/download.php?id=15895', params=payload)
+#print(r.content)
+
+i = Image.open(StringIO(req.content))
+
+i.save('image')
diff --git a/utils/utils.py b/utils/utils.py
new file mode 100755
index 0000000..2d70011
--- /dev/null
+++ b/utils/utils.py
@@ -0,0 +1,124 @@
+# -*- coding: UTF-8 -*-
+#!/usr/bin/env python3
+'__autor__'== 'serkus'
+import os, sys, json
+from urllib import request
+#import xml
+import xml.etree.ElementTree as ET
+#Проверяем пользователь ROOT или нет
+def is_root():
+ return os.geteuid() == 0
+
+#Читаем Файл посторочно
+def read_configs(filename):
+ param = {}
+ if os.path.exists(filename):
+ with open(filename) as f:
+ for line in f:
+ print(line)
+ else:
+ print("Path is not Found")
+
+#получаем список оверлеев
+
+def get_list_overlays():
+ overlays =""
+ url = "https://api.gentoo.org/overlays/repositories.xml"
+ response = request.urlopen(url)
+ overlays = []
+ overlay = {}
+ root = ET.fromstring(response.read())
+ #print(root.tag)
+ #print(root.attrib)
+ name = ""
+ description = ""
+ homepage = ""
+ for child in root.findall('repo'):
+ name = child.find('name').text
+ #try:
+ description = child.find('description').text
+ #except AttributeError:
+ # description = "У overlay нет описания"
+ try:
+ homepage = child.find('homepage').text
+ except AttributeError:
+ homepage = "У overlay нет домашней странички"
+ overlay = dict(name=name, description=description, homepage=homepage)
+
+ overlays.append(overlay)
+ #print(str(overlays))
+ print(len(overlays))
+ #f=open('./overlays.json', 'a')
+ #f.write(json.dumps({"repositories": overlays}))
+ #f.close()
+
+ return overlays
+
+
+def xml_element_to_dict(elem):
+ "Convert XML Element to a simple dict"
+ inner = dict(elem.attrib)
+ children = list(map(xml_element_to_dict, list(elem)))
+ text = elem.text and elem.text.strip()
+ if text:
+ inner['@text'] = text
+ if children:
+ inner['@children'] = children
+ return {elem.tag: inner}
+
+def xml2json(xmldata):
+ pass
+ #doc = ET.parse(xmldata)
+ #root = root = ET.fromstring(xmldata)
+
+def write_config(port=8000, Lang='ru', theme="default"):
+
+ conf = dict(PORT=port, Lang=Lang, THEME=theme)
+ with open('./config.json', 'w') as f:
+ json.dump(conf, f)
+ return conf
+
+def read_config():
+ with open('./config.json', 'r') as f:
+ conf = json.load(f)
+ return conf
+
+def load_config():
+ conf = {}
+ if not os.path.exists("./config.json"):
+ write_config()
+ else:
+ conf = read_config()
+ return conf
+
+#SORT IN INTALL PAKAGES
+#'/var/db/pkg/'
+def sort_inatll_pkg():
+ INSTALL = []
+ path = '/var/db/pkg'
+ for d, dirs, files in os.walk(path):
+ for f in files:
+ if f.endswith('.ebuild'):
+ INSTALL.append(f.replace('.ebuild', ""))
+ #print(str(len(INSTALL)))
+ return json.dumps({'install_pkgs':INSTALL})
+
+def scan_config_portage():
+ dir_root ="/etc/portage"
+ config = {}
+ i = 0
+ dr = {}
+ data = {}
+ pf={}
+ for d, dirs, files in os.walk(dir_root):
+ print(str(d))
+ i=i+1
+ for fl in files:
+
+ with open(d + "/" +fl) as f:
+ pf[str(d.split('/')[-1]) + "/"+ fl]= f.read().split('\n')
+ str(d.split('/')[-1])
+ print(dr)
+ config = {'portage': pf}
+ print("config:\t" + str(config))
+ return config
\ No newline at end of file
diff --git a/view/static/js b/view/static/js
new file mode 160000
index 0000000..8ec0464
--- /dev/null
+++ b/view/static/js
@@ -0,0 +1 @@
+Subproject commit 8ec046485ccdcfcee73c114fc9e3186882ed6ccf
diff --git a/views/404.html b/views/404.html
new file mode 100755
index 0000000..d77f3ca
--- /dev/null
+++ b/views/404.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Page is not Found
+
+
+
+ 404 page is NOT Found
+
+
+
\ No newline at end of file
diff --git a/views/README.txt b/views/README.txt
new file mode 100755
index 0000000..5ff8ea2
--- /dev/null
+++ b/views/README.txt
@@ -0,0 +1,23 @@
+ GRUSS ALLE
+
+ЧТО ЭТО ТАКОЕ:
+Это проект Web GUI для пакетного менеджера Portage(Gentoo, Calcukate-linux).
+Этот продукт предстовляет из себя клиент-серверное приложение.
+Цели:
+Предоставить удобный Гуй portage, для таких утройств как Планшеты, смартфоны.
+Предоставить удаленный доступ к portagу на клиентской машине.
+Снизить порог вхождения для новых пользователей на дистрибутивах имеющих в свой основе пакетный менеджер portageю
+
+
+
+КАК СОБРАТЬ И ЗАПУСТИТЬ:
+
+1.Нужен диструтив использущий дистрибутив использующий portage.
+2.Скачайте дистрибутив проекта.
+3.Введите в терминале:
+ cd web_pоrt &&
+ git clone https://github.com/brython-dev/brython.git ./view/static/js/brython
+ скачайте Brython и распакуйте его в ./view/static/js/brython
+
+4.Запустите ./start
+5.Откройте в браузере localhost:8080
\ No newline at end of file
diff --git a/views/blank.html b/views/blank.html
new file mode 100755
index 0000000..2977648
--- /dev/null
+++ b/views/blank.html
@@ -0,0 +1,559 @@
+
+
+
+
+
+
+
+
+
+
+ Ample Admin Template - The Ultimate Multipurpose admin template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/views/index.html b/views/index.html
new file mode 100755
index 0000000..3f03fe9
--- /dev/null
+++ b/views/index.html
@@ -0,0 +1,70 @@
+
+
+
+
+ UI portage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Идёт Обработка
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/views/index.html.old b/views/index.html.old
new file mode 100755
index 0000000..07f3253
--- /dev/null
+++ b/views/index.html.old
@@ -0,0 +1,140 @@
+
+
+
+
+
UI portage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Загрузка
+
+
+
+
+
+
+
Идёт загрузка ......
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/views/license.txt b/views/license.txt
new file mode 100755
index 0000000..a3857f7
--- /dev/null
+++ b/views/license.txt
@@ -0,0 +1,12 @@
+
+
+
diff --git a/views/navigation-bar-by-jan-kadera.zip b/views/navigation-bar-by-jan-kadera.zip
new file mode 100755
index 0000000000000000000000000000000000000000..72d7c5f97d383da83bc5881d1a298b7344ad4430
GIT binary patch
literal 3352
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
literal 0
HcmV?d00001
diff --git a/views/profile.html b/views/profile.html
new file mode 100755
index 0000000..2eb7ce0
--- /dev/null
+++ b/views/profile.html
@@ -0,0 +1,773 @@
+
+
+
+
+
+
+
+
+
+
+ Ample Admin Template - The Ultimate Multipurpose admin template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
User Name
+
info@myadmin.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
John Doe 5 minutes ago
+
+
+
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa
Design weblayout
+
+
+
+
+
+
+
+
John Doe 5 minutes ago
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper
+
+
+
+
+
+
+
+
+
Full Name
+
+
Johnathan Deo
+
+
Mobile
+
+
(123) 456 7890
+
+
Email
+
+
johnathan@admin.com
+
+
+
+
+
Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt.Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.
+
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries
+
It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
+
Skill Set
+
+
Wordpress 80%
+
+
HTML 5 90%
+
+
jQuery 50%
+
+
Photoshop 70%
+
+
+
+
+
+
+
+
John Doe 5 minutes ago
+
+
+
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa
Design weblayout
+
+
+
+
+
+
+
+
+
+
+
John Doe 5 minutes ago
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/views/vertical-css-menus201017.zip b/views/vertical-css-menus201017.zip
new file mode 100755
index 0000000000000000000000000000000000000000..6b07fbe72fd809b7cda3030093ddccc0b1b39ef2
GIT binary patch
literal 18955
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
F{sxPcz{3Cl
literal 0
HcmV?d00001
diff --git a/xml2json.py b/xml2json.py
new file mode 100644
index 0000000..0f82253
--- /dev/null
+++ b/xml2json.py
@@ -0,0 +1,43 @@
+#! /usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+import json
+import sys
+import argparse
+
+parser = argparse.ArgumentParser(description='Convert an XML file to JSON.')
+parser.add_argument('--unsafe', action='store_true',
+ help='do not use defusedxml: only for known-safe XML!')
+parser.add_argument('infile', nargs='?', type=argparse.FileType('rt'),
+ default=sys.stdin)
+
+
+def xml_element_to_dict(elem):
+ "Convert XML Element to a simple dict"
+ inner = dict(elem.attrib)
+ children = list(map(xml_element_to_dict, list(elem)))
+ text = elem.text and elem.text.strip()
+ if text:
+ inner['@text'] = text
+ if children:
+ inner['@children'] = children
+
+ return {elem.tag: inner}
+
+
+def main(args):
+ "Dump JSON-from-parsed-XML to stdout"
+ if args.unsafe:
+ import xml.etree.ElementTree as ElementTree
+# import defusedxml.ElementTree as ElementTree
+
+ xml_parser = ElementTree.parse(args.infile)
+ root = xml_parser.getroot()
+
+ json.dump(xml_element_to_dict(root), sys.stdout, indent=2)
+ print()
+
+
+if __name__ == '__main__':
+ args = parser.parse_args()
+main(args)