PopufareAPI.py 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394
  1. #!/usr/bin/python3
  2. #
  3. # Copyright (c) 2019 Clementine Computing LLC.
  4. #
  5. # This file is part of PopuFare.
  6. #
  7. # PopuFare is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # PopuFare is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
  19. #
  20. ## WORK IN PROGRESS
  21. import json
  22. import mysql.connector
  23. import time
  24. import datetime
  25. import copy
  26. import hashlib
  27. import sys
  28. import getopt
  29. POPUFARE_API_VERSION = "2.0.0"
  30. #conn = mysql.connector.connect(user='bus', password='bus', host='localhost', database='busdb', port=3306)
  31. _USER = 'busapi'
  32. _PASSWORD = 'bus'
  33. _HOST = 'localhost'
  34. _DATABASE = 'busdb'
  35. _PORT = 5506
  36. Function = [
  37. "User",
  38. "Card",
  39. "Pass",
  40. "Log",
  41. "PricePoints",
  42. "AdminGetCard", "AdminGetCards", "AdminGetPass", "AdminGetUser",
  43. "AdminGetAdmin", "AdminGetPassesOnCard", "AdminGetPendingQueue", "AdminProcessPendingQueue",
  44. "AdminRemovePendingQueue", "AdminCreateCardBlock", "AdminCreateCard", "AdminSetUser",
  45. "AdminSetAdmin", "AdminAddPass", "AdminAddCard", "AdminAddUser",
  46. "AdminAddAdmin", "AdminRemovePass", "AdminRemovePasses", "AdminRemoveCard",
  47. "AdminRemoveUser", "AdminRemoveAdmin", "AdminTransferCard", "AdminTransferPass",
  48. "AdminGetPassOptions", "AdminAddCardToUser", "AdminRemoveCardFromUser", "AdminGetAdminPermissions",
  49. "AdminAddAdminPermissions", "AdminRemoveAdminPermissions", "AdminAddAdminApiPermissions", "AdminRemoveAdminApiPermissions",
  50. "AdminSetAdminApiPermissions", "AdminGetCustomCard", "AdminGetAdmins", "AdminSearchCards",
  51. "AdminSearchUsers", "AdminSearchAdmins"]
  52. PASS_FIELDS = ["logical_card_id", "issued", "activated", "deactivated", "firstused", "lastused",
  53. "nrides_orig", "nrides_remain", "nday_orig", "nday_expiration",
  54. "active", "expired", "queue_order",
  55. "rule", "comment", "paytype" ]
  56. CARD_FIELDS = ["mag_token", "rfid_token", "comment", "userid", "issued", "deactivated", "lastused",
  57. "firstused", "group_id", "issuetype"]
  58. USER_FIELDS = ["username", "comment", "first_name", "last_name", "phone",
  59. "email", "address", "city", "state", "zip", "passwordhash",
  60. "shipping_address", "shipping_city", "shipping_state", "shipping_zip",
  61. "shipping_name", "shipping_country_code", "shipping_country_name"]
  62. GROUP_FIELDS = ["id", "group_id", "group_name"]
  63. RULECLASS_FIELDS = ["id", "group_id", "group_name"]
  64. def Request(ctx, db_info = { "user":_USER, "pass":_PASSWORD, "host":_HOST, "db":_DATABASE, "port":_PORT}):
  65. #_conn = mysql.connector.connect(user=_USER, password=_PASSWORD, host=_HOST, database=_DATABASE, port=_PORT)
  66. _conn = mysql.connector.connect(user=db_info["user"], password=db_info["pass"], host=db_info["host"], database=db_info["db"], port=db_info["port"])
  67. res = {}
  68. if "function" in ctx:
  69. if ctx["function"] == "CardInfo":
  70. res = CardInfo(_conn, ctx)
  71. elif ctx["function"] == "UserInfo":
  72. res = UserInfo(_conn, ctx)
  73. elif ctx["function"] == "User":
  74. res = User(_conn, ctx)
  75. elif ctx["function"] == "Card":
  76. res = Card(_conn, ctx)
  77. elif ctx["function"] == "Pass":
  78. res = Pass(_conn, ctx)
  79. elif ctx["function"] == "Group":
  80. res = Group(_conn, ctx)
  81. elif ctx["function"] == "Ruleclass":
  82. res = Ruleclass(_conn, ctx)
  83. elif ctx["function"] == "Reissue":
  84. res = Reissue(_conn, ctx)
  85. elif ctx["function"] == "RecycleCard":
  86. res = RecycleCard(_conn, ctx)
  87. elif ctx["function"] == "AddCardBlock":
  88. res = AddCardBlock(_conn, ctx)
  89. elif ctx["function"] == "Search":
  90. res = Search(_conn, ctx)
  91. elif ctx["function"] == "Pending":
  92. res = Pending(_conn, ctx)
  93. elif ctx["function"] == "ping":
  94. res["result"] = "success"
  95. res["data"] = "pong"
  96. _conn.close()
  97. return res
  98. ## _ _ __
  99. ## ___ __ _ _ __ __| (_)_ __ / _| ___
  100. ## / __/ _` | '__/ _` | | '_ \| |_ / _ \
  101. ## | (_| (_| | | | (_| | | | | | _| (_) |
  102. ## \___\__,_|_| \__,_|_|_| |_|_| \___/
  103. ##
  104. def CardInfo(db, ctx):
  105. card_res = {}
  106. action = "get"
  107. if "action" in ctx:
  108. action = ctx["action"]
  109. if action == "get":
  110. print("CardInfo:", ctx)
  111. cardid = -1
  112. if "logical_card_id" in ctx:
  113. cardid = ctx["logical_card_id"]
  114. card_res["logical_card_id"] = cardid
  115. card_res = Card(db, {"action":"get", "logical_card_id": cardid})
  116. card_res["pass"] = []
  117. if card_res["result"] == "success":
  118. ## through each of the passes on the card
  119. ##
  120. pass_query = "select user_pass_id from user_pass where logical_card_id = %s and expired = 0 order by queue_order asc"
  121. pass_cursor = db.cursor()
  122. pass_cursor.execute(pass_query, [card_res["logical_card_id"]])
  123. pass_rows = pass_cursor.fetchall()
  124. for pass_row in pass_rows:
  125. pass_res = Pass(db, {"action":"get", "user_pass_id":pass_row[0]})
  126. card_res["pass"].append(pass_res)
  127. card_res["user"] = {}
  128. if ((card_res["userid"] is not None) and (int(card_res["userid"]) >= 0)):
  129. card_res["user"] = User(db, {"action":"get", "userid": card_res["userid"] })
  130. elif action == "search":
  131. card_res["cards"] = []
  132. res_cardid = Card(db, ctx)
  133. for cid in res_cardid["logical_card_ids"]:
  134. _c = CardInfo(db, {"action":"get", "logical_card_id":cid})
  135. card_res["cards"].append(_c)
  136. card_res["result"] = "success"
  137. return card_res
  138. ## _ __
  139. ## _ _ ___ ___ _ __(_)_ __ / _| ___
  140. ## | | | / __|/ _ \ '__| | '_ \| |_ / _ \
  141. ## | |_| \__ \ __/ | | | | | | _| (_) |
  142. ## \__,_|___/\___|_| |_|_| |_|_| \___/
  143. ##
  144. def UserInfo(db, ctx):
  145. res = {}
  146. res["result"] = "fail"
  147. userid = -1
  148. if ("userid" in ctx):
  149. userid = ctx["userid"]
  150. pass_fields = PASS_FIELDS.copy()
  151. card_fields = CARD_FIELDS.copy()
  152. user_fields = USER_FIELDS.copy()
  153. res["userid"] = userid
  154. cursor = db.cursor()
  155. ## fill in user data
  156. ##
  157. res["user"] = {}
  158. fields = USER_FIELDS.copy()
  159. query = "select " + ",".join(fields) + " from users where userid = %s"
  160. cursor.execute(query, [userid])
  161. row = cursor.fetchone()
  162. if row is None:
  163. res["api_comment"] = "user not found"
  164. return res
  165. res["user"]["userid"] = userid
  166. for idx,f in enumerate(user_fields):
  167. res["user"][f] = row[idx]
  168. ## go through each card and fill in card data and pass data
  169. ##
  170. res["card"] = []
  171. query = "select logical_card_id from user_card where userid = %s and active = 1 order by logical_card_id asc"
  172. card_cursor = db.cursor()
  173. card_cursor.execute(query, [userid])
  174. rows = card_cursor.fetchall()
  175. for row in rows:
  176. card_res = CardInfo(db, {"logical_card_id":row[0]})
  177. res["card"].append(card_res)
  178. res["result"] = "success"
  179. return res
  180. def _update_pass_bits(cursor, passid):
  181. q = "select logical_card_id from user_pass where user_pass_id = %s"
  182. cursor.execute(q, [passid])
  183. rows = cursor.fetchall()
  184. print("\n\nupdating pass bits", passid, "\n\n")
  185. cardid = -1
  186. for row in rows:
  187. cardid = row[0]
  188. break
  189. print("\n\nupdating pass bits cardid:", cardid, "\n\n")
  190. if cardid < 0: return
  191. q = "update user_pass set active = 0 where logical_card_id = %s"
  192. cursor.execute(q, [cardid])
  193. q = "update user_pass set active = 1 where logical_card_id = %s and expired = 0 and queue_order = " + \
  194. "( select min(x.queue_order) from user_pass x where x.logical_card_id = %s and x.expired = 0 )"
  195. cursor.execute(q, [cardid,cardid])
  196. ## _ _
  197. ## _ __ _ _| | ___ ___| | __ _ ___ ___
  198. ## | '__| | | | |/ _ \/ __| |/ _` / __/ __|
  199. ## | | | |_| | | __/ (__| | (_| \__ \__ \
  200. ## |_| \__,_|_|\___|\___|_|\__,_|___/___/
  201. ##
  202. def Ruleclass(db, ctx):
  203. res = {}
  204. ruleclass_fields = RULECLASS_FIELDS.copy()
  205. cursor = db.cursor()
  206. fields = ruleclass_fields.copy()
  207. field_vals = []
  208. if ctx["action"] == "search":
  209. query = "select id, rulename, ruleclass from rule_class"
  210. cursor.execute(query)
  211. rows = cursor.fetchall()
  212. res["ruleclass"] = []
  213. for row in rows:
  214. res["ruleclass"].append({"id":row[0], "rulename":row[1], "ruleclass":row[2]})
  215. db.commit()
  216. return res
  217. ##
  218. ## _ __ __ _ ___ ___
  219. ## | '_ \ / _` / __/ __|
  220. ## | |_) | (_| \__ \__ \
  221. ## | .__/ \__,_|___/___/
  222. ## |_|
  223. def Pass(db, ctx):
  224. res = {}
  225. passid = -1
  226. if ("user_pass_id" in ctx):
  227. passid = ctx["user_pass_id"]
  228. pass_fields = PASS_FIELDS.copy()
  229. cursor = db.cursor()
  230. fields = pass_fields.copy()
  231. field_vals = []
  232. if (ctx["action"] == "get"):
  233. query = "select " + ",".join(pass_fields) + " from user_pass where user_pass_id = %s"
  234. cursor.execute(query, [passid])
  235. row = cursor.fetchone()
  236. if row is not None:
  237. res["result"] = "success"
  238. res["user_pass_id"] = passid
  239. for idx,f in enumerate(pass_fields):
  240. if isinstance(row[idx], datetime.datetime):
  241. res[f] = row[idx].strftime("%Y-%m-%d %H:%M:%S")
  242. else:
  243. res[f] = row[idx]
  244. else:
  245. res["result"] = "fail"
  246. res["api_comment"] = "pass not found"
  247. elif (ctx["action"] == "add"):
  248. if (not "logical_card_id" in ctx) or (ctx["logical_card_id"] == ''):
  249. res["result"] = "fail"
  250. res["api_comment"] = "must have logical_card_id to add pass"
  251. else:
  252. ## fill in some default values
  253. ##
  254. dt = time.strftime('%Y-%m-%d %H:%M:%S')
  255. if "issued" not in ctx: ctx["issued"] = dt
  256. if "expired" not in ctx: ctx["expired"] = 0
  257. if "active" not in ctx: ctx["active"] = 0
  258. if "logical_card_id" in ctx:
  259. cardid = ctx["logical_card_id"]
  260. _q = "select queue_order from user_pass where logical_card_id = %s and expired = 0 order by queue_order desc limit 1"
  261. _c = db.cursor()
  262. _c.execute(_q, [cardid])
  263. _r = _c.fetchone()
  264. if _r is not None:
  265. ctx["queue_order"] = int(_r[0])+1
  266. else:
  267. ctx["active"] = 1
  268. ctx["queue_order"] = 0
  269. else:
  270. ctx["queue_order"] = 0
  271. for f in pass_fields:
  272. if f in ctx: field_vals.append(ctx[f])
  273. else: field_vals.append(None)
  274. query = "insert into user_pass (" + ",".join(fields) + ") values (" + ",".join(["%s"]*len(fields)) + ")"
  275. print(query)
  276. print(fields, field_vals)
  277. cursor.execute(query, field_vals)
  278. res["user_pass_id"] = cursor.lastrowid
  279. res["result"] = "success"
  280. _update_pass_bits(cursor, passid);
  281. elif (ctx["action"] == "update"):
  282. update_field = []
  283. update_val = []
  284. for f in pass_fields:
  285. if f in ctx:
  286. update_field.append(f + "= %s")
  287. update_val.append(ctx[f])
  288. update_val.append(passid)
  289. query = "update user_pass set " + ",".join(update_field) + " where user_pass_id = %s"
  290. cursor.execute(query, update_val)
  291. res["user_pass_id"] = passid
  292. res["result"] = "success"
  293. _update_pass_bits(cursor, passid);
  294. elif (ctx["action"] == "deactivate"):
  295. update_field = []
  296. update_val = []
  297. for f in pass_fields:
  298. if f in ctx:
  299. update_field.append(f + "= %s")
  300. update_val.append(ctx[f])
  301. update_val.append(passid)
  302. query = "update user_pass set active = 0, expired = 1 where user_pass_id = %s"
  303. cursor.execute(query, [passid])
  304. _update_pass_bits(cursor, passid);
  305. res["user_pass_id"] = passid
  306. res["result"] = "success"
  307. elif (ctx["action"] == "delete"):
  308. query = "delete from user_pass where user_pass_id = %s"
  309. cursor.execute(query, [passid])
  310. _update_pass_bits(cursor, passid);
  311. res["result"] = "success"
  312. db.commit()
  313. return res
  314. ## _
  315. ## ___ __ _ _ __ __| |
  316. ## / __/ _` | '__/ _` |
  317. ## | (_| (_| | | | (_| |
  318. ## \___\__,_|_| \__,_|
  319. ##
  320. def Card(db, ctx):
  321. card_fields = CARD_FIELDS.copy()
  322. res = {}
  323. cardid = -1
  324. if ("logical_card_id" in ctx):
  325. cardid = ctx["logical_card_id"]
  326. cursor = db.cursor()
  327. fields = card_fields.copy()
  328. field_vals = []
  329. if (ctx["action"] == "get"):
  330. query = "select " + ",".join(card_fields) + " from user_card where logical_card_id = %s"
  331. cursor.execute(query, [cardid])
  332. row = cursor.fetchone()
  333. if row is not None:
  334. res["logical_card_id"] = cardid
  335. for idx,f in enumerate(card_fields):
  336. if isinstance(row[idx], datetime.datetime):
  337. res[f] = row[idx].strftime("%Y-%m-%d %H:%M:%S")
  338. else:
  339. res[f] = row[idx]
  340. res["result"] = "success"
  341. else:
  342. res["result"] = "fail"
  343. res["api_comment"] = "card not found"
  344. elif (ctx["action"] == "add"):
  345. fields.append("active")
  346. for f in card_fields:
  347. if f in ctx: field_vals.append(ctx[f])
  348. else: field_vals.append(None)
  349. field_vals.append(1)
  350. query = "insert into user_card (" + ",".join(fields) + ") values (" + ",".join(["%s"]*len(fields)) + ")"
  351. cursor.execute(query, field_vals)
  352. res["logical_card_id"] = cursor.lastrowid
  353. res["result"] = "success"
  354. elif (ctx["action"] == "update"):
  355. if not "logical_card_id" in ctx:
  356. res["result"] = "fail"
  357. res["api_comment"] = "must supply a logical_card_id"
  358. else:
  359. update_field = []
  360. update_val = []
  361. query_card_id = ctx["logical_card_id"]
  362. cursor.execute("select logical_card_id from user_card where logical_card_id = %s", [query_card_id])
  363. rows = cursor.fetchall()
  364. if len(rows) == 0:
  365. res["result"] = "fail"
  366. res["api_comment"] = "card not found"
  367. else:
  368. print(">>>>", len(rows))
  369. for row in rows:
  370. logical_card_id = row[0]
  371. for f in card_fields:
  372. if f in ctx:
  373. update_field.append(f + "= %s")
  374. update_val.append(ctx[f])
  375. update_val.append(cardid)
  376. query = "update user_card set " + ",".join(update_field) + " where logical_card_id = %s"
  377. cursor.execute(query, update_val)
  378. res["logical_card_id"] = cardid
  379. res["result"] = "success"
  380. elif (ctx["action"] == "delete"):
  381. query = "delete from user_card where logical_card_id = %s"
  382. cursor.execute(query, [cardid])
  383. res["result"] = "success"
  384. elif (ctx["action"] == "search"):
  385. query = "select logical_card_id from user_card where "
  386. n_search = 0
  387. if "logical_card_id" in ctx:
  388. query += " logical_card_id = %s"
  389. field_vals.append( ctx["logical_card_id"])
  390. n_search += 1
  391. if "mag_token" in ctx:
  392. query += " mag_token like %s "
  393. field_vals.append( '%' + ctx["mag_token"] + '%')
  394. n_search += 1
  395. if "rfid_token" in ctx:
  396. if len(field_vals)>0: query += " and "
  397. query += " rfid_token like %s "
  398. field_vals.append( '%' + ctx["rfid_token"] + '%')
  399. n_search += 1
  400. query_limit = " "
  401. if "limit" in ctx:
  402. query_limit = " limit %s "
  403. search_vals.append(ctx["limit"])
  404. query += query_limit
  405. res["logical_card_ids"] = []
  406. if n_search > 0:
  407. cursor.execute(query, field_vals)
  408. rows = cursor.fetchall()
  409. for row in rows:
  410. res["logical_card_ids"].append(row[0])
  411. res["result"] = "success"
  412. db.commit()
  413. return res
  414. ##
  415. ## __ _ _ __ ___ _ _ _ __
  416. ## / _` | '__/ _ \| | | | '_ \
  417. ## | (_| | | | (_) | |_| | |_) |
  418. ## \__, |_| \___/ \__,_| .__/
  419. ## |___/ |_|
  420. def Group(db,ctx):
  421. group_res = { "result":"fail"}
  422. action = "get"
  423. if "action" in ctx:
  424. action = ctx["action"]
  425. cursor = db.cursor()
  426. if action == "get":
  427. group_res["group"] = []
  428. query = "select group_id, group_name from groups order by group_id asc"
  429. cursor.execute(query)
  430. rows = cursor.fetchall()
  431. for row in rows:
  432. group_res["group"].append({"group_id":row[0], "group_name":row[1]})
  433. group_res["result"] = "success"
  434. elif action == "add":
  435. if "group_name" not in ctx:
  436. group_res["result"] = "fail"
  437. group_res["api_comment"] = "must provide group name to add"
  438. return res
  439. group_name = ctx["group_name"]
  440. group_id = -1
  441. cursor.execute("select max(group_id) from groups")
  442. x = cursor.fetchone()
  443. if x[0] is None:
  444. group_id = 1
  445. else:
  446. group_id = int(x[0]) + 1
  447. cursor.execute("insert into groups (group_id, group_name) values (%s, %s)", [group_id, group_name])
  448. group_res["result"] = "success"
  449. group_res["group_id"] = group_id
  450. group_res["group_name"] = group_name
  451. elif action == "getone":
  452. group_res["group"] = []
  453. query = "select group_id, group_name from groups where group_name = %s "
  454. cursor.execute(query, [ctx["group"]])
  455. row = cursor.fetchone()
  456. if not row:
  457. group_res["result"] = "fail"
  458. group_res["api_comment"] = "invalid group"
  459. else:
  460. group_res["result"] = "success"
  461. group_res["group_id"] = row[0]
  462. elif action == "default":
  463. return Group(db, {"action":"getone", "group":"TEST-ORG"})
  464. db.commit()
  465. return group_res
  466. ##
  467. ## _ _ ___ ___ _ __
  468. ## | | | / __|/ _ \ '__|
  469. ## | |_| \__ \ __/ |
  470. ## \__,_|___/\___|_|
  471. ##
  472. def User(db, ctx):
  473. user_fields = USER_FIELDS.copy()
  474. res = {}
  475. cursor = db.cursor()
  476. fields = user_fields.copy()
  477. user_vals = []
  478. userid = -1
  479. if "userid" in ctx: userid = ctx["userid"]
  480. print("cp.user")
  481. ## USER GET
  482. ##
  483. if (ctx["action"] == "get"):
  484. query = "select " + ",".join(user_fields) + " from users where userid = %s"
  485. cursor.execute(query, [userid])
  486. row = cursor.fetchone()
  487. if row is not None:
  488. res["userid"] = userid
  489. for idx,f in enumerate(user_fields):
  490. if isinstance(row[idx], datetime.datetime):
  491. res[f] = row[idx].strftime("%Y-%m-%d %H:%M:%S")
  492. else:
  493. res[f] = row[idx]
  494. res["result"] = "success"
  495. else:
  496. res["result"] = "fail"
  497. res["api_comment"] = "user not found"
  498. ## USER ADD
  499. ##
  500. elif (ctx["action"] == "add"):
  501. if ((not "password" in ctx) or
  502. (not "username" in ctx) ):
  503. res["api_comment"] = "invalid parameters, need username and password to create account"
  504. res["result"] = "fail"
  505. else:
  506. uname = ctx["username"]
  507. pword = ctx["password"]
  508. fields.append("active")
  509. fields.append("created")
  510. for f in user_fields:
  511. if f in ctx: user_vals.append(ctx[f])
  512. elif f == "passwordhash":
  513. ha = hashlib.sha256()
  514. ha.update(str.encode(uname))
  515. ha.update(str.encode(pword))
  516. user_vals.append(ha.hexdigest())
  517. else: user_vals.append(None)
  518. user_vals.append(1)
  519. user_vals.append(time.strftime('%Y-%m-%d %H:%M:%S'))
  520. query = "insert into users (" + ",".join(fields) + ") values (" + ",".join(["%s"]*len(fields)) + ")"
  521. cursor.execute(query, user_vals)
  522. res["userid"] = cursor.lastrowid
  523. res["result"] = "success"
  524. ## USER UPDATE
  525. ##
  526. elif (ctx["action"] == "update"):
  527. if not "userid" in ctx:
  528. res["result"] = "fail"
  529. res["api_comment"] = "no userid specified"
  530. else:
  531. uname = ''
  532. query = "select username from users where userid = %s";
  533. cursor.execute(query, [userid])
  534. rows = cursor.fetchall()
  535. for row in rows:
  536. uname = row[0]
  537. if uname == '':
  538. res["result"] = "fail"
  539. res["api_comment"] = "could not find username"
  540. else:
  541. update_field = []
  542. update_val = []
  543. print("user_field:", user_fields)
  544. print("ctx:", ctx)
  545. for f in user_fields:
  546. if (f == "passwordhash") and ("password" in ctx):
  547. update_field.append(" passwordhash = %s ")
  548. ha = hashlib.sha256()
  549. ha.update(str.encode(uname))
  550. ha.update(str.encode(ctx["password"]))
  551. update_val.append(ha.hexdigest())
  552. elif f in ctx:
  553. update_field.append(f + "= %s")
  554. update_val.append(ctx[f])
  555. else:
  556. pass
  557. #update_val.append(None)
  558. update_val.append(userid)
  559. if len(update_field) == 0:
  560. print("NOPE")
  561. print("manage_user.update>>>", userid, ":".join(update_field), ":".join(update_val), len(update_field))
  562. query = "update users set " + ",".join(update_field) + " where userid = %s"
  563. print("WTFFF???", query)
  564. cursor.execute(query, update_val)
  565. res["userid"] = userid
  566. res["result"] = "success"
  567. ## USER DELETE
  568. ##
  569. elif (ctx["action"] == "delete"):
  570. query = "delete from users where userid = %s"
  571. cursor.execute(query, [userid])
  572. ## USER SEARCH
  573. ##
  574. elif (ctx["action"] == "search"):
  575. res["userids"] = []
  576. res["userid"] = userid
  577. res["result"] = "success"
  578. search_field = []
  579. search_val = []
  580. for f in user_fields:
  581. if f in ctx:
  582. search_field.append(f + " like %s")
  583. search_val.append('%' + ctx[f] + '%')
  584. query_limit = " "
  585. if "limit" in ctx:
  586. query_limit = " limit %s "
  587. search_val.append(ctx["limit"])
  588. query = "select userid from users where " + " and ".join(search_field) + query_limit
  589. cursor.execute(query, search_val)
  590. rows = cursor.fetchall()
  591. for row in rows:
  592. res["userids"].append(row[0])
  593. db.commit()
  594. return res
  595. ## _
  596. ## _ __ ___(_)___ ___ _ _ ___
  597. ## | '__/ _ \ / __/ __| | | |/ _ \
  598. ## | | | __/ \__ \__ \ |_| | __/
  599. ## |_| \___|_|___/___/\__,_|\___|
  600. ##
  601. def _fixup_card_pass_state(cursor, cid):
  602. num_active_query = "select count(active) from user_pass " + \
  603. " where logiacl_card_id = %s and expired = 0"
  604. cursor.execute(num_active_query, [cid])
  605. num_res = int(cursor.fetchone()[0])
  606. # nothing to do
  607. #
  608. if num_res == 1:
  609. return
  610. min_queue_query = "select min(queue_order) from user_pass " + \
  611. " where logical_card_id = %s and expired = 0 "
  612. cursor.execute(min_queue_query, [cid])
  613. minq = int(cursor.fetchone()[0])
  614. set_active_query = "update user_pass set active = 1 " + \
  615. " where logical_card_id = %s and expired = 0 and queue_order = %s "
  616. cursor.execute(set_active_query, [cid, minq])
  617. def Reissue(db, ctx):
  618. res = {"result":"fail"}
  619. cursor = db.cursor()
  620. fields = [ "src_logical_card_id", "dst_logical_card_id" ]
  621. val = {}
  622. for f in fields:
  623. if f in ctx:
  624. if ctx[f] and len(ctx[f]) > 0:
  625. val[f] = ctx[f]
  626. if not ("src_logical_card_id" in val):
  627. return res
  628. if not ("dst_logical_card_id" in val):
  629. return res
  630. cursor.execute("select max(queue_order) from user_pass where logiacl_card_id = %s", [val["src_logical_card_id"]])
  631. cursor.execute("select count(queue_order) from user_pass where expired = 0 logiacl_card_id = %s", [val["src_logical_card_id"]])
  632. src_query = "select user_pass_id, active, expired, queue_order " + \
  633. " from user_pass where logical_card_id = %s " + \
  634. " order by queue_order asc "
  635. cursor.execute(src_query, [val["src_logical_card_id"]]);
  636. src_rows = cursor.fetchall()
  637. dst_card_order_queue = 0
  638. cursor.execute("select count(queue_order) from user_pass where logical_card_id = %s", [val["dst_logical_card_id"]])
  639. dst_pass_count = cursor.fetchone()[0];
  640. if int(dst_pass_count) > 0:
  641. dst_query = "select max(queue_order) from user_pass where logical_card_id = %s"
  642. cursor.execute(dst_query, [val["dst_logical_card_id"]])
  643. dst_card_order_queue = int(cursor.fetchone()[0]);
  644. for src_row in src_rows:
  645. if (src_row[2] == 1): continue
  646. dst_card_order_queue += 1
  647. xfer_query = "update user_pass set active = 0, logical_card_id = %s, queue_order = %s where user_pass_id = %s"
  648. cursor.execute(xfer_query, [val["dst_logiacl_card_id"], dst_card_order_queue, src_row[0]] )
  649. _fixup_card_pass_state(val["dst_logical_card_id"])
  650. res["result"] = "success"
  651. return res
  652. ## _ _
  653. ## _ __ ___ ___ _ _ ___| | ___ ___ __ _ _ __ __| |
  654. ## | '__/ _ \/ __| | | |/ __| |/ _ \ / __/ _` | '__/ _` |
  655. ## | | | __/ (__| |_| | (__| | __/ | (_| (_| | | | (_| |
  656. ## |_| \___|\___|\__, |\___|_|\___| \___\__,_|_| \__,_|
  657. ## |___/
  658. def RecycleCard(db, ctx):
  659. res = {"result":"fail"}
  660. cursor = db.cursor()
  661. fields = ["logical_card_id", "rfid_token", "mag_token", "group",
  662. "userid",
  663. "rule", "pass_class", "nrides_remain", "nrides_orig", "nday_orig" ]
  664. val = {}
  665. for f in fields:
  666. if f in ctx:
  667. if ctx[f] and len(ctx[f]) > 0:
  668. val[f] = ctx[f]
  669. if ((not ("logical_card_id" in val)) and
  670. (not ("rfid_token" in val)) and
  671. (not ("mag_token" in val))):
  672. return res
  673. logical_card_id = -1
  674. if not ("logical_card_id" in val):
  675. if "mag_token" in val:
  676. query = "select logical_card_id from user_card where mag_token = %s and active = 1"
  677. cursor.execute(query, [val["mag_token"]])
  678. cid = cursor.fetchone()
  679. if cid is not None:
  680. val["logical_card_id"] = cid[0]
  681. else:
  682. return res
  683. elif "rfid_token" in val:
  684. query = "select logical_card_id from user_card where rfid_token = %s and active = 1"
  685. cursor.execute(query, [val["rfid_token"]])
  686. cid = cursor.fetchone()
  687. if cid is not None:
  688. val["logical_card_id"] = cid[0]
  689. else:
  690. return res
  691. group_info = Group(db, {"action":"default"})
  692. if "group" in val:
  693. group_info = Group(db, {"action":"getone", "group":val["group"]})
  694. if group_info["result"] != "success":
  695. res["api_comment"] = "invalid group"
  696. return res
  697. query = "update user_card set active = 0 where logical_card_id = %s"
  698. cursor.execute(query, [val["logical_card_id"]])
  699. card_info = {"action":"add", "group_id":group_info["group_id"], "active":1}
  700. if "mag_token" in val: card_info["mag_token"] = val["mag_token"]
  701. if "rfid_token" in val: card_info["rfid_token"] = val["rfid_token"]
  702. card_res = Card(db, card_info)
  703. if card_res["result"] != "success":
  704. res["result"] = "fail"
  705. res["api_comment"] = "failed to find card"
  706. return res
  707. res["logical_card_id"] = card_res["logical_card_id"]
  708. if "pass_class" in val:
  709. pass_opt = {"action":"add", "logical_card_id": res["logical_card_id"] }
  710. if val["pass_class"] == "OTHER":
  711. pass_opt["rule"] = val["rule"]
  712. Pass(db, pass_opt)
  713. elif val["pass_class"] == "NRIDE":
  714. pass_opt["rule"] = val["rule"]
  715. pass_opt["nrides_orig"] = val["nrides_orig"]
  716. pass_opt["nrides_remain"] = val["nrides_remain"]
  717. Pass(db, pass_opt)
  718. elif val["pass_class"] == "NDAY":
  719. pass_opt["rule"] = val["rule"]
  720. pass_opt["nday_orig"] = val["nday_orig"]
  721. Pass(db, pass_opt)
  722. return res
  723. ## _
  724. ## ___ ___ __ _ _ __ ___| |__
  725. ## / __|/ _ \/ _` | '__/ __| '_ \
  726. ## \__ \ __/ (_| | | | (__| | | |
  727. ## |___/\___|\__,_|_| \___|_| |_|
  728. ##
  729. def Search(db, ctx):
  730. res = {"result":"fail"}
  731. cursor = db.cursor()
  732. fields = ["search_type", "search_string", "start", "count"]
  733. start = "0"
  734. count = "100"
  735. val = {}
  736. for f in fields:
  737. if f in ctx:
  738. if ctx[f] and len(ctx[f]) > 0:
  739. val[f] = ctx[f]
  740. if "start" in val: start = val["start"]
  741. if "count" in val: count = val["count"]
  742. if val["search_type"] == "card":
  743. t = val["search_string"]
  744. p = '%' + t + '%'
  745. query = "select logical_card_id, mag_token, rfid_token, userid, issued, firstused, lastused, group_id, issuetype"
  746. query += " from user_card where mag_token like %s "
  747. query += " or rfid_token like %s "
  748. query += " or comment like %s "
  749. query += " or issuetype like %s "
  750. query += " and active = 1 "
  751. query += " order by logical_card_id desc"
  752. query += " limit %s,%s "
  753. _v = [p,p, p, p, int(start), int(start) + int(count)]
  754. #cursor.execute(query, [p, p, p, p])
  755. cursor.execute(query, _v)
  756. rows = cursor.fetchall()
  757. res["data"] = []
  758. for row in rows:
  759. _d = {
  760. "iscard": 1,
  761. "logical_card_id": row[0],
  762. "mag_token": row[1],
  763. "rfid_token": row[2],
  764. "userid": row[3],
  765. "issued": row[4],
  766. "firstused": row[5],
  767. "lastused": row[6],
  768. "group_id": row[7],
  769. "issuetype": row[8]
  770. }
  771. res["data"].append( _d )
  772. res["result"] = "success"
  773. elif val["search_type"] == "user":
  774. t = val["search_string"]
  775. p = '%' + t + '%'
  776. fields = [ "username", "first_name", "last_name", "phone", "email", "address", "city","state", "zip", "created",
  777. "shipping_address", "shipping_city", "shipping_state", "shipping_zip", "shipping_name",
  778. "shipping_country_code", "shipping_country_name" ]
  779. query = "select userid, " + ", ".join(fields)
  780. query += " from users "
  781. query += " where " + " like %s or ".join(fields) + " like %s "
  782. query += " and active = 1 "
  783. query += " order by userid desc"
  784. query += " limit %s,%s "
  785. print("user query:", query)
  786. _v = [p]*len(fields)
  787. _v.append(int(start))
  788. _v.append(int(start) + int(count))
  789. #cursor.execute(query, [p]*len(fields))
  790. cursor.execute(query, _v)
  791. rows = cursor.fetchall()
  792. res["data"] = []
  793. for row in rows:
  794. _d = { "userid": row[0], "isuser": 1 }
  795. for idx,f in enumerate(fields):
  796. _d[f] = row[idx+1]
  797. res["data"].append( _d )
  798. res["result"] = "success"
  799. elif val["search_type"] == "admin":
  800. t = val["search_string"]
  801. p = '%' + t + '%'
  802. fields = [ "username", "comment" ]
  803. query = "select userid, group_id, " + ", ".join(fields)
  804. query += " from admins "
  805. query += " where " + " like %s or ".join(fields) + " like %s "
  806. query += " and active = 1 "
  807. query += " order by userid desc"
  808. query += " limit %s,%s "
  809. print("user query:", query)
  810. _v = [p]*len(fields)
  811. _v.append(int(start))
  812. _v.append(int(start) + int(count))
  813. cursor.execute(query, _v)
  814. rows = cursor.fetchall()
  815. res["data"] = []
  816. for row in rows:
  817. _d = { "userid": row[0], "group_id": row[1], "isadmin": 1 }
  818. for idx,f in enumerate(fields):
  819. _d[f] = row[idx+2]
  820. res["data"].append( _d )
  821. res["result"] = "success"
  822. return res
  823. ## _ _ _ _ _ _
  824. ## __ _ __| | __| | ___ __ _ _ __ __| | | |__ | | ___ ___| | __
  825. ## / _` |/ _` |/ _` | / __/ _` | '__/ _` | | '_ \| |/ _ \ / __| |/ /
  826. ## | (_| | (_| | (_| | | (_| (_| | | | (_| | | |_) | | (_) | (__| <
  827. ## \__,_|\__,_|\__,_| \___\__,_|_| \__,_| |_.__/|_|\___/ \___|_|\_\
  828. ##
  829. def AddCardBlock(db, ctx):
  830. res = {"result":"fail"}
  831. cursor = db.cursor()
  832. fields = ["mag_token", "rfid_token", "group_id",
  833. "rule", "nday_orig", "nrides_remain", "nrides_orig",
  834. "count",
  835. "pass_rule", "pass_nrides_remain", "pass_nrides_orig",
  836. "pass_nday_orig", "pass_class"]
  837. val = {}
  838. for f in fields:
  839. if f in ctx:
  840. if ctx[f] and len(ctx[f]) > 0:
  841. val[f] = ctx[f]
  842. if not ("count" in val):
  843. res["result"] = "fail"
  844. res["api_comment"] = "count must be positive"
  845. return res
  846. if ((not ("mag_token" in val)) and
  847. (not ("rfid_token" in val))):
  848. res["result"] = "fail"
  849. res["api_comment"] = "mag_token and/or rfid_token must be specified"
  850. return res
  851. use_mag = False
  852. use_rfid = False
  853. if "mag_token" in val:
  854. use_mag = True
  855. pfx_mag_cred = val["mag_token"].split(":")[0]
  856. base_mag_cred = int(val["mag_token"].split(":")[-1])
  857. if "rfid_token" in val:
  858. use_rfid = True
  859. pfx_rfid_cred = ":".join(val["rfid_token"].split(":")[0:2])
  860. base_rfid_cred = int(val["rfid_token"].split(":")[-1])
  861. logical_card_ids = []
  862. for idx in range(int(val["count"])):
  863. card_info = {"action":"add", "group_id":val["group_id"], "active":1}
  864. if "mag_token" in val: card_info["mag_token"] = val["mag_token"]
  865. if "rfid_token" in val: card_info["rfid_token"] = val["rfid_token"]
  866. if use_mag:
  867. card_info["mag_token"] = pfx_mag_cred + ":" + str(base_mag_cred + idx)
  868. if use_rfid:
  869. card_info["rfid_token"] = pfx_rfid_cred + ":" + str(base_rfid_cred + idx)
  870. card_res = Card(db, card_info)
  871. if card_res["result"] != "success":
  872. res["result"] = "fail"
  873. res["api_comment"] = "failed to add card"
  874. return res
  875. logical_card_id = card_res["logical_card_id"]
  876. if "pass_rule" in val:
  877. pass_info = {"action":"add", "logical_card_id":logical_card_id, "active":1,
  878. "rule" : val["pass_rule"] }
  879. if val["pass_class"] == "OTHER":
  880. pass
  881. elif val["pass_class"] == "NRIDE":
  882. pass_info["nrides_remain"] = val["pass_nrides_remain"]
  883. pass_info["nrides_orig"] = val["pass_nrides_orig"]
  884. elif val["pass_class"] == "NDAY":
  885. pass_info["nday_orig"] = val["pass_nday_orig"]
  886. pass_res = Pass(db, pass_info)
  887. logical_card_ids.append(logical_card_id)
  888. res["result"] = "success"
  889. res["logical_card_ids"] = logical_card_ids
  890. return res
  891. ## ____ _ _
  892. ## | _ \ ___ _ __ __| (_)_ __ __ _
  893. ## | |_) / _ \ '_ \ / _` | | '_ \ / _` |
  894. ## | __/ __/ | | | (_| | | | | | (_| |
  895. ## |_| \___|_| |_|\__,_|_|_| |_|\__, |
  896. ## |___/
  897. def Pending(db, ctx):
  898. res = {"result":"fail"}
  899. cursor = db.cursor()
  900. fields = ["org_card_order_queue_id", "userid", "logical_card_id", "created", "processed", "comment" ]
  901. val = {}
  902. for f in fields:
  903. if f in ctx:
  904. if (type(ctx[f]) == int) or (ctx[f] and ((type(ctx[f]) != int) and (len(ctx[f]) > 0))):
  905. val[f] = ctx[f]
  906. if not "comment" in val:
  907. val["comment"] = ''
  908. if (ctx["action"] == "getall"):
  909. query = "select org_card_order_queue_id, userid, logical_card_id, "
  910. query += " date_format(created, '%Y-%m-%d %H:%i:%S'), "
  911. query += " date_format(processed,'%Y-%m-%d %H:%i:%S'), comment, pending "
  912. query += " from org_card_order_queue "
  913. query += " where pending = 1 "
  914. query += " order by org_card_order_queue_id asc"
  915. cursor.execute(query)
  916. rows = cursor.fetchall()
  917. res["data"] = []
  918. for row in rows:
  919. _c = Card(db, {"action":"get", "logical_card_id":row[2]})
  920. mag_token = ""
  921. if "mag_token" in _c: mag_token = _c["mag_token"]
  922. rfid_token = ""
  923. if "rfid_token" in _c: rfid_token = _c["rfid_token"]
  924. _r = {"org_card_order_queue_id":row[0], "userid":row[1], "logical_card_id":row[2], "created": row[3],
  925. "processed":row[4], "comment":row[5], "pending":row[6],
  926. "mag_token":mag_token, "rfid_token":rfid_token}
  927. res["data"].append(_r)
  928. res["result"] = "success"
  929. if (ctx["action"] == "get"):
  930. query = "select org_card_order_queue_id, userid, logical_card_id, "
  931. query += " date_format(created, '%Y-%m-%d %H:%i:%S'), "
  932. query += " date_format(processed,'%Y-%m-%d %H:%i:%S'), comment, pending "
  933. query += " from org_card_order_queue "
  934. query += " where pending = 1 and org_card_order_queue_id = %s"
  935. cursor.execute(query, [val["org_card_order_queue_id"]])
  936. row = cursor.fetchone()
  937. if row is None:
  938. res["api_comment"] = "pending card not found"
  939. return res
  940. cols = ["org_card_order_queue_id", "userid", "logical_card_id", "created", "processed", "comment", "pending" ]
  941. res["pending_card"] = {}
  942. for idx,f in enumerate(cols):
  943. res["pending_card"][f] = row[idx]
  944. cid = res["pending_card"]["logical_card_id"]
  945. _r = CardInfo(db, {"action":"get", "logical_card_id":cid})
  946. if _r["result"] == "fail":
  947. return _r
  948. res["cardinfo"] = _r
  949. res["result"] = "success"
  950. elif (ctx["action"] == "add"):
  951. query = "insert into org_card_order_queue (userid, logical_card_id, comment, pending, created) values (%s,%s,%s,1,now())"
  952. cursor.execute(query, [val["userid"], val["logical_card_id"], val["comment"]])
  953. res["org_card_order_queue_id"] = cursor.lastrowid
  954. res["result"] = "success"
  955. elif (ctx["action"] == "process"):
  956. query = "update org_card_order_queue set pending = 0, processed = now() where org_card_order_queue_id = %s"
  957. cursor.execute(query, [val["org_card_order_queue_id"]])
  958. res["result"] = "success"
  959. db.commit()
  960. return res
  961. ## _
  962. ## _ __ ___ __ _(_)_ __
  963. ## | '_ ` _ \ / _` | | '_ \
  964. ## | | | | | | (_| | | | | |
  965. ## |_| |_| |_|\__,_|_|_| |_|
  966. ##
  967. def __test(db):
  968. print("main")
  969. print("---------")
  970. print("---------")
  971. print("---------")
  972. res = User(db, {"action":"add", "username":"abe" })
  973. print("user.add:", res)
  974. res = User(db, {"action":"update", "username":"abeabe", "userid":res["userid"]})
  975. print("user.update:", res)
  976. res = User(db, {"action":"get", "userid":res["userid"]})
  977. print("user.get:", res)
  978. res = User(db, {"action":"delete", "userid": res["userid"]})
  979. print("user.delete:", res)
  980. print("---------")
  981. print("---------")
  982. print("---------")
  983. res = Card(db, {"action":"get", "logical_card_id":1})
  984. print("card.get:", res)
  985. res = Card(db, {"action":"add", "mag_token":"2:1234", "rfid_token":"26:20:415", "comment":"testing api", "userid":1})
  986. print("card.add:", res)
  987. res = Card(db, {"action":"update", "mag_token":"2:9234", "logical_card_id":res["logical_card_id"]})
  988. print("card.update:", res)
  989. res = Card(db, {"action":"delete", "logical_card_id":res["logical_card_id"]})
  990. print("card.delete:", res)
  991. print("---------")
  992. print("---------")
  993. print("---------")
  994. res = Pass(db, {"action":"get", "user_pass_id":11})
  995. print("pass.get:", res)
  996. res = Pass(db, {"action":"add", "logical_card_id":1, "queue_order":9, "rule":"TEST-ORG-NDAY", "nday_orig":3})
  997. print("pass.add:", res)
  998. res = Pass(db, {"action":"update", "user_pass_id":res["user_pass_id"], "queue_order":10, "rule":"TEST-ORG-NDAY", "nday_orig":5})
  999. print("pass.update:", res)
  1000. res = Pass(db, {"action":"delete", "user_pass_id":res["user_pass_id"]})
  1001. print("pass.delete:", res)
  1002. print("---------")
  1003. print("---------")
  1004. print("---------")
  1005. res = UserInfo(db, {"userid":348})
  1006. print("userinfo:", json.dumps(res, indent=2))
  1007. print("---------")
  1008. print("---------")
  1009. print("---------")
  1010. res = Request({"function":"CardInfo", "action":"search", "logical_card_id":1})
  1011. print("request.card.search:", res)
  1012. def show_version(ofp):
  1013. ofp.write("PopufareAPI version " + POPUFARE_API_VERSION + "\n")
  1014. ofp.flush()
  1015. def show_help(ofp):
  1016. show_version(ofp)
  1017. ofp.write("\nusage:\n")
  1018. ofp.write("\n")
  1019. ofp.write(" PopufareAPI [-h] [-v] [-c config] [-u dbuser] [-p dbpass] [-H dbhost] [-D db] [-P dbport] <json_data>\n")
  1020. ofp.write("\n")
  1021. ofp.write(" -c config file\n")
  1022. ofp.write(" -u db user\n")
  1023. ofp.write(" -p db pass\n")
  1024. ofp.write(" -H db host\n")
  1025. ofp.write(" -D db name\n")
  1026. ofp.write(" -P db port\n")
  1027. ofp.write(" -h help (this screen)\n")
  1028. ofp.write(" -v show version\n")
  1029. ofp.write("\n")
  1030. ofp.write("example:\n")
  1031. ofp.write("\n")
  1032. ofp.write(" PopufareAPI -d '{\"function\":\"ping\"}\n")
  1033. ofp.write("\n")
  1034. ofp.flush()
  1035. if __name__ == "__main__":
  1036. api_opt = {
  1037. "db_info": {
  1038. "user":"busapi",
  1039. "pass":"bus",
  1040. "host":"localhost",
  1041. "db":"busdb",
  1042. "port":5506
  1043. },
  1044. "config":"",
  1045. "data":""
  1046. }
  1047. data = {}
  1048. opts,args = getopt.getopt(sys.argv[1:], "hd:u:p:H:D:P:c:")
  1049. for o,a in opts:
  1050. if o == "-h":
  1051. show_help(sys.stdout)
  1052. sys.exit(0)
  1053. elif o == "-c":
  1054. api_opt["config"] = a
  1055. elif o == "-u":
  1056. api_opt["db_info"]["user"] = a
  1057. elif o == "-p":
  1058. api_opt["db_info"]["pass"] = a
  1059. elif o == "-H":
  1060. api_opt["db_info"]["host"] = a
  1061. elif o == "-D":
  1062. api_opt["db_info"]["db"] = a
  1063. elif o == "-P":
  1064. api_opt["db_info"]["port"] = int(a)
  1065. #elif o == "-d":
  1066. # api_opt["data"] = json.loads(a)
  1067. else:
  1068. show_help(sys.stderr)
  1069. sys.exit(-1)
  1070. if len(args) < 1:
  1071. sys.stderr.write("no data request\n")
  1072. show_help(sys.stderr)
  1073. sys.exit(-1)
  1074. api_opt["data"] = json.loads(args[0])
  1075. res = Request(api_opt["data"], api_opt["db_info"])
  1076. print(json.dumps(res,indent=2))
  1077. #conn = mysql.connector.connect(user=_USER, password=_PASSWORD, host=_HOST, database=_DATABASE, port=_PORT)
  1078. #conn = mysql.connector.connect(user=api_opt["dbuser"], password=api_opt["dbpass"], host=api_opt["dbhost"], database=api_opt["db"], port=api_opt["dbport"])
  1079. #main(conn)
  1080. #conn.close()