00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 import os, sys, string, time, re
00040
00041 import urllib2, cookielib
00042
00043 import mimetypes
00044 import mimetools
00045
00046 import neo_cgi, neo_util
00047 import simple_hdfhelp as hdfhelp
00048 import attachment_help
00049
00050
00051 def _is_serial_valid(reference):
00052 if len(reference) != 12:
00053 return False
00054
00055 if not reference.startswith('680'):
00056 return False
00057
00058 return True
00059
00060
00061
00062
00063
00064
00065 class Invent(object):
00066
00067
00068 def __init__(self, username, password, debug=False):
00069 self.username = username
00070 self.password = password
00071
00072 self.debug = debug
00073
00074 self.cj = cookielib.CookieJar()
00075 self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
00076
00077 self.loggedin = False
00078 self._logged_time = 0
00079
00080 self.site = "http://invent.willowgarage.com/invent/"
00081 if debug:
00082 self.site = "http://cmi.willowgarage.com/invent/"
00083
00084
00085 def login(self):
00086 dt = time.time() - self._logged_time
00087 if self.loggedin==False or dt > 3600:
00088 return self._login()
00089 return True
00090
00091
00092
00093 def _login(self):
00094 username = self.username
00095 password = self.password
00096 url = self.site + "login/signin0.py?Action.Login=1&username=%(username)s&password=%(password)s" % locals()
00097
00098 fp = self.opener.open(url)
00099 body = fp.read()
00100 fp.close()
00101
00102 self.loggedin = False
00103 self._logged_time = 0
00104 if body.find("Invalid Login") != -1:
00105 return False
00106
00107 self.loggedin = True
00108 self._logged_time = time.time()
00109 return True
00110
00111
00112
00113
00114 def reload_pr2scds_bom(self):
00115 self.login()
00116
00117 url = self.site + "invent/api.py?Action.reloadBom=1&"
00118 fp = self.opener.open(url)
00119 body = fp.read()
00120 fp.close()
00121
00122 hdf = neo_util.HDF()
00123 try:
00124 hdf.readString(body)
00125 except Exception, e:
00126 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00127 return False
00128
00129 val = hdf.getValue("CGI.out", "")
00130 return val.lower() == "true"
00131
00132
00133
00134
00135 def check_serial_valid(self, serial):
00136 if not _is_serial_valid(serial):
00137 return False
00138
00139 self.login()
00140
00141 url = self.site + "invent/api.py?Action.isItemValid=1&reference=%s" % (serial,)
00142 fp = self.opener.open(url)
00143 body = fp.read()
00144 fp.close()
00145
00146 i = string.find(body, "\n<!--")
00147 value = string.strip(body[:i])
00148
00149 return value.lower() == "true"
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 def check_assembled(self, serial, recursive = False):
00160 self.login()
00161
00162 url = self.site + "invent/api.py?Action.checkAssembled=1&reference=%s" % (serial,)
00163 fp = self.opener.open(url)
00164 body = fp.read()
00165 fp.close()
00166
00167 hdf = neo_util.HDF()
00168 try:
00169 hdf.readString(body)
00170 except Exception, e:
00171 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00172 return False
00173
00174 val = hdf.getValue("CGI.out", "")
00175
00176 if not recursive:
00177 return val.lower() == "true"
00178
00179
00180 if not val.lower() == "true":
00181 return False
00182
00183 subs = self.get_sub_items(serial)
00184
00185 for sub in subs:
00186 if not self.check_assembled(sub, recursive):
00187 return False
00188
00189 return True
00190
00191
00192
00193
00194
00195
00196
00197
00198 def lookup_by_reference(self, ref):
00199 self.login()
00200
00201 url = self.site + "invent/api.py?Action.lookupByReference=1&reference=%s" % (ref,)
00202 fp = self.opener.open(url)
00203 body = fp.read()
00204 fp.close()
00205
00206 hdf = neo_util.HDF()
00207 try:
00208 hdf.readString(body)
00209 except Exception, e:
00210 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00211 return []
00212
00213 rv = []
00214 for k,o in hdfhelp.hdf_ko_iterator(hdf.getObj("CGI.cur.items")):
00215 rv.append(o.getValue("reference", ""))
00216
00217 return rv
00218
00219 def getItemReferences(self, key):
00220 import warnings
00221 warnings.warn('Using deprecated getItemRefences in wg_invent_client/Invent', DeprecationWarning, stacklevel = 2)
00222 return self.get_item_references(key)
00223
00224
00225
00226
00227
00228 def get_item_references(self, key):
00229 self.login()
00230
00231 key = key.strip()
00232
00233 url = self.site + "invent/api.py?Action.getItemReferences=1&key=%s" % (key,)
00234 fp = self.opener.open(url)
00235 body = fp.read()
00236 fp.close()
00237
00238 hdf = neo_util.HDF()
00239 try:
00240 hdf.readString(body)
00241 except Exception, e:
00242 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00243 return {}
00244
00245 ret = {}
00246 for k,o in hdfhelp.hdf_ko_iterator(hdf.getObj("CGI.cur.refs")):
00247 ret[o.getValue("name", "")] = o.getValue("reference", "")
00248
00249 return ret
00250
00251
00252
00253
00254
00255
00256 def remove_item_reference(self, key, name):
00257 self.login()
00258
00259 key = key.strip()
00260
00261 url = self.site + "invent/api.py?Action.removeItemReference=1&key=%s&name=%s" % (key,urllib2.quote(name))
00262 fp = self.opener.open(url)
00263 body = fp.read()
00264 fp.close()
00265
00266 hdf = neo_util.HDF()
00267 try:
00268 hdf.readString(body)
00269 except Exception, e:
00270 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00271 return False
00272
00273 val = hdf.getValue("CGI.out", "")
00274 return val.lower() == "true"
00275
00276 return True
00277
00278
00279
00280
00281
00282
00283
00284 def addItemReference(self, key, name, reference):
00285 self.login()
00286
00287 key = key.strip()
00288
00289 url = self.site + "invent/api.py?Action.addItemReference=1&key=%s&name=%s&reference=%s" % (key,urllib2.quote(name),urllib2.quote(reference))
00290 fp = self.opener.open(url)
00291 body = fp.read()
00292 fp.close()
00293
00294 hdf = neo_util.HDF()
00295 try:
00296 hdf.readString(body)
00297 except Exception, e:
00298 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00299 return False
00300
00301 val = hdf.getValue("CGI.out", "")
00302 return val.lower() == "true"
00303
00304 return True
00305
00306
00307
00308
00309
00310
00311 def generateWGMacaddr(self, key, name):
00312 self.login()
00313
00314 key = key.strip()
00315
00316 url = self.site + "invent/api.py?Action.generateWGMacaddr=1&key=%s&name=%s" % (key,urllib2.quote(name))
00317 fp = self.opener.open(url)
00318 body = fp.read()
00319 fp.close()
00320
00321
00322
00323
00324
00325
00326
00327
00328 def setNote(self, reference, note, noteid = None):
00329 self.login()
00330
00331 url = self.site + "invent/api.py?Action.AddNoteToItem=1&reference=%s¬e=%s" % (reference, urllib2.quote(note))
00332 if noteid:
00333 url = url + "¬eid=%s" % noteid
00334
00335 fp = self.opener.open(url)
00336 body = fp.read()
00337 fp.close()
00338
00339 pat = re.compile("rowid=([0-9]+)")
00340 m = pat.search(body)
00341 if m:
00342 noteid = int(m.group(1))
00343 return noteid
00344 return None
00345
00346
00347
00348
00349
00350
00351 def get_item_notes(self, reference, deleted = False):
00352 self.login()
00353
00354 url = self.site + "invent/api.py?Action.GetItemNotes=1&reference=%s" % (reference)
00355 if deleted:
00356 url += "&deleted=1"
00357
00358 fp = self.opener.open(url)
00359 body = fp.read()
00360 fp.close()
00361
00362 hdf = neo_util.HDF()
00363 try:
00364 hdf.readString(body)
00365 except Exception, e:
00366 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00367 return {}
00368
00369 ret = {}
00370 for k,o in hdfhelp.hdf_ko_iterator(hdf.getObj("CGI.cur.notes")):
00371 ret[o.getValue("noteid", "")] = o.getValue("note", "")
00372
00373 return ret
00374
00375
00376
00377
00378
00379
00380 def delete_note(self, noteid):
00381 self.login()
00382
00383 url = self.site + "invent/api.py?Action.DeleteNote=1¬eid=%s" % (noteid)
00384
00385 fp = self.opener.open(url)
00386 body = fp.read()
00387 fp.close()
00388
00389 hdf = neo_util.HDF()
00390 try:
00391 hdf.readString(body)
00392 except Exception, e:
00393 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00394 return False
00395
00396 val = hdf.getValue("CGI.out", "")
00397 return val.lower() == "true"
00398
00399
00400
00401
00402
00403
00404 def restore_note(self, noteid):
00405 self.login()
00406
00407 url = self.site + "invent/api.py?Action.restoreNote=1¬eid=%s" % (noteid)
00408
00409 fp = self.opener.open(url)
00410 body = fp.read()
00411 fp.close()
00412
00413 hdf = neo_util.HDF()
00414 try:
00415 hdf.readString(body)
00416 except Exception, e:
00417 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00418 return False
00419
00420 val = hdf.getValue("CGI.out", "")
00421 return val.lower() == "true"
00422
00423
00424
00425
00426
00427
00428
00429 def get_note(self, noteid):
00430 self.login()
00431
00432 url = self.site + "invent/api.py?Action.GetNote=1¬eid=%s" % (noteid)
00433
00434 fp = self.opener.open(url)
00435 body = fp.read()
00436 fp.close()
00437
00438 hdf = neo_util.HDF()
00439 try:
00440 hdf.readString(body)
00441 except Exception, e:
00442 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00443 return ('', '', '', '', '')
00444
00445 ref = hdf.getValue("CGI.cur.item.reference", "")
00446 note = hdf.getValue("CGI.cur.note.note", "")
00447 user = hdf.getValue("CGI.cur.note.whom", "")
00448 date = hdf.getValue("CGI.cur.note.date", "")
00449 deleted = hdf.getValue("CGI.cur.note.deleted", "")
00450
00451 return (ref, note, user, date, deleted)
00452
00453
00454
00455
00456
00457
00458
00459
00460 def setKV(self, reference, key, value):
00461 self.login()
00462
00463 key = key.strip()
00464 value = value.strip()
00465
00466 if not key:
00467 print >> sys.stderr, "Unable to set empty key into inventory system. Reference: %s, Value: %s" % (reference, value)
00468 return False
00469
00470 if not value:
00471 print >> sys.stderr, "Unable to set empty value into inventory system. Reference: %s, Key: %s" % (reference, key)
00472 return False
00473
00474 url = self.site + "invent/api.py?Action.setKeyValue=1&reference=%s&key=%s&value=%s" % (reference, urllib2.quote(key), urllib2.quote(value))
00475
00476 fp = self.opener.open(url)
00477 fp.read()
00478 fp.close()
00479
00480 return True
00481
00482
00483
00484
00485
00486
00487
00488 def deleteKV(self, reference, key):
00489 self.login()
00490
00491 key = key.strip()
00492
00493 if not key:
00494 print >> sys.stderr, "Unable to set empty key into inventory system. Reference: %s" % (reference)
00495 return False
00496
00497 url = self.site + "invent/api.py?Action.deleteKeyValue=1&reference=%s&key=%s" % (reference, urllib2.quote(key))
00498
00499 fp = self.opener.open(url)
00500 body = fp.read()
00501 fp.close()
00502
00503 hdf = neo_util.HDF()
00504 try:
00505 hdf.readString(body)
00506 except Exception, e:
00507 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00508 return False
00509
00510 val = hdf.getValue("CGI.cur.out", "")
00511
00512 return val.lower() == "true"
00513
00514
00515 def get_test_status(self, reference):
00516 return self.getKV(reference, 'Test Status') == 'PASS'
00517
00518
00519
00520
00521
00522
00523 def getKV(self, reference, key):
00524 self.login()
00525
00526 key = key.strip()
00527
00528 if not key:
00529 raise ValueError, "the key is blank"
00530
00531 url = self.site + "invent/api.py?Action.getKeyValue=1&reference=%s&key=%s" % (reference, urllib2.quote(key))
00532
00533 fp = self.opener.open(url)
00534 value = fp.read()
00535 fp.close()
00536
00537 i = string.find(value, "\n<!--")
00538 value = string.strip(value[:i])
00539
00540 return value
00541
00542
00543
00544
00545
00546 def listKVs(self, reference):
00547 self.login()
00548
00549 url = self.site + "invent/api.py?Action.listKeyValues=1&reference=%s" % (reference)
00550
00551 fp = self.opener.open(url)
00552 body = fp.read()
00553 fp.close()
00554
00555 hdf = neo_util.HDF()
00556 try:
00557 hdf.readString(body)
00558 except Exception, e:
00559 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00560 return {}
00561
00562 ret = {}
00563 for k,o in hdfhelp.hdf_ko_iterator(hdf.getObj("CGI.cur.kvs")):
00564 ret[o.getValue("key", "")] = o.getValue("value", "")
00565
00566 return ret
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 def add_attachment(self, reference, name, mimetype, attachment, note = None, aid=None):
00581 self.login()
00582
00583 if not name:
00584 raise ValueError, "the name is blank"
00585
00586 theURL = self.site + "invent/api.py"
00587
00588 fields = []
00589 fields.append(('Action.addAttachment', "1"))
00590 fields.append(('reference', reference))
00591 fields.append(('mimetype', mimetype))
00592 fields.append(('name', name))
00593 if note is not None:
00594 fields.append(('note', note))
00595 if aid is not None:
00596 fields.append(('aid', aid))
00597
00598 files = []
00599 files.append(("attach", name, attachment))
00600
00601 input = attachment_help.build_request(theURL, fields, files)
00602
00603 response = self.opener.open(input).read()
00604
00605 pat = re.compile("rowid=([0-9]+)")
00606 m = pat.search(response)
00607 if m is not None:
00608 aid = int(m.group(1))
00609 return aid
00610 return None
00611
00612
00613
00614
00615 def list_attachments(self, key):
00616 self.login()
00617
00618 key = key.strip()
00619
00620 url = self.site + "invent/api.py?Action.getAttachments=1&key=%s" % (key,)
00621 fp = self.opener.open(url)
00622 body = fp.read()
00623 fp.close()
00624
00625 hdf = neo_util.HDF()
00626 try:
00627 hdf.readString(body)
00628 except Exception, e:
00629 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00630 return {}
00631
00632 ret = {}
00633 for k,o in hdfhelp.hdf_ko_iterator(hdf.getObj("CGI.cur.attachments")):
00634 ret[o.getValue("aid", "")] = o.getValue("name", "")
00635
00636 return ret
00637
00638
00639
00640
00641
00642 def get_attachment_info(self, aid):
00643 self.login()
00644
00645 aid = aid.strip()
00646
00647 url = self.site + "invent/api.py?Action.getAttachmentInfo=1&aid=%s" % (aid,)
00648 fp = self.opener.open(url)
00649 body = fp.read()
00650 fp.close()
00651
00652 hdf = neo_util.HDF()
00653 try:
00654 hdf.readString(body)
00655 except Exception, e:
00656 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00657 return ('', '', '', '')
00658
00659 ref = hdf.getValue("CGI.cur.reference", "")
00660 docname = hdf.getValue("CGI.cur.attachment.name", "")
00661 user = hdf.getValue("CGI.cur.attachment.whom", "")
00662 note = hdf.getValue("CGI.cur.attachment.note", "")
00663 date = hdf.getValue("CGI.cur.attachment.date", "")
00664
00665 return (ref, docname, user, note, date)
00666
00667
00668
00669
00670
00671 def get_attachment(self, aid):
00672 self.login()
00673
00674 aid = aid.strip()
00675
00676 url = self.site + "invent/api.py?Action.getAttachmentInfo=1&aid=%s" % (aid,)
00677 fp = self.opener.open(url)
00678 body = fp.read()
00679 fp.close()
00680
00681 hdf = neo_util.HDF()
00682 try:
00683 hdf.readString(body)
00684 except Exception, e:
00685 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00686 return ('', '', '', '')
00687
00688 docname = hdf.getValue("CGI.cur.attachment.name", "")
00689 docref = hdf.getValue("CGI.cur.attachment.docref", "")
00690
00691 url = self.site + "documents/show.py?reference=%s&name=%s" % (docref, docname)
00692 fp = self.opener.open(url)
00693 doc = fp.read()
00694 fp.close()
00695
00696 return doc
00697
00698
00699
00700
00701
00702
00703 def delete_attachment(self, aid):
00704 self.login()
00705
00706 url = self.site + "invent/api.py?Action.deleteAttachment=1&aid=%s" % (aid)
00707
00708 fp = self.opener.open(url)
00709 body = fp.read()
00710 fp.close()
00711
00712 hdf = neo_util.HDF()
00713 try:
00714 hdf.readString(body)
00715 except Exception, e:
00716 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00717 return False
00718
00719 val = hdf.getValue("CGI.out", "")
00720 return val.lower() == "true"
00721
00722
00723
00724
00725
00726
00727
00728 def get_sub_items(self, reference, recursive = False):
00729 self.login()
00730
00731 reference = reference.strip()
00732
00733 url = self.site + "invent/api.py?Action.getSubparts=1&reference=%s" % (reference)
00734 if recursive:
00735 url += "&recursive=1"
00736
00737 fp = self.opener.open(url)
00738 body = fp.read()
00739 fp.close()
00740
00741 hdf = neo_util.HDF()
00742 try:
00743 hdf.readString(body)
00744 except Exception, e:
00745 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00746 return {}
00747
00748 ret = []
00749 for k,o in hdfhelp.hdf_ko_iterator(hdf.getObj("CGI.cur.items")):
00750 ret.append(o.getValue("reference", ""))
00751
00752 return ret
00753
00754
00755
00756
00757
00758
00759 def get_parent_item(self, reference):
00760 self.login()
00761
00762 url = self.site + "invent/api.py?Action.getParentItem=1&reference=%s" % (reference)
00763 fp = self.opener.open(url)
00764 body = fp.read()
00765 fp.close()
00766
00767 hdf = neo_util.HDF()
00768 try:
00769 hdf.readString(body)
00770 except Exception, e:
00771 print >> sys.stderr, 'Unable to parse HDF output from inventory system. Output:\n%s' % body
00772 return None
00773
00774 parent = hdf.getValue("CGI.cur.parent", "")
00775 if not parent:
00776 return None
00777
00778 return parent
00779
00780
00781
00782
00783
00784