From de28393d61564ff860f28ce84f4a052f7585ee97 Mon Sep 17 00:00:00 2001 From: Ryan Backman Date: Thu, 24 May 2012 14:36:24 -0700 Subject: [PATCH 1/2] Copied ticket.py to user.py and modified to work with user objects --- pyrt/__init__.py | 145 ++++++++++++++++++++-------------------- pyrt/user.py | 171 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 71 deletions(-) create mode 100644 pyrt/user.py diff --git a/pyrt/__init__.py b/pyrt/__init__.py index a16cbb2..e1eef22 100644 --- a/pyrt/__init__.py +++ b/pyrt/__init__.py @@ -22,7 +22,7 @@ >>> search = and_([rt.ticket.c.created > '2008-02-20',rt.ticket.c.owner=='justin']) >>> tickets = rt.ticket.search(search) >>> for t in tickets: -... print t +... print t ... #searches for ('created' > '2008-02-20' AND 'owner' = 'justin') ['1644', 'blah blah'] @@ -39,7 +39,7 @@ Tue Feb 26 13:26:29 2008 >>> for t in rt.ticket.search(rt.ticket.c.cf.building=='Biology'): -... print t +... print t ... #searches for 'CF.{building}' = 'Biology' ['292', 'blah'] @@ -47,8 +47,6 @@ ['943', 'blah'] """ - - import urllib, urllib2, urlparse import os @@ -56,76 +54,81 @@ REST_VERSION = "1.0" from ticket import * +from user import * class RTError(Exception): - pass + pass COOKIEFILE = os.path.expanduser('~/.rt_cookies.txt') class RTClient: - def __init__(self, url, username, password): - self.url = url - self.username = username - self.password = password - - self.cj = cookielib.LWPCookieJar(COOKIEFILE) - self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj)) - - try: - self.cj.load(ignore_discard=True, ignore_expires=True) - except IOError: - pass - - self.logging_in = False - #self.login() - - def _make_url(self, action): - return "%s/REST/%s/%s" % (self.url, REST_VERSION, action) - - def _do(self, action, data=None, **args): - """Call url with args as query args and return the result""" - - for k,v in args.items(): - if k.endswith("_"): - del args[k] - args[k[:-1]]=v - - url = self._make_url(action) - if not data: - data = urllib.urlencode(args) - raw = self.opener.open(url, data).read() - res = self.split_res(raw) - - if 'Credentials required' in raw: - if not self.logging_in: - self.logging_in = True - self.login() - return self._do(action, data=data, **args) - raise RTError("Credentials required") - if 'Your username or password is incorrect' in res: - raise RTError("Your username or password is incorrect") - if 'Invalid query' in res: - raise RTError("Invalid query %s" % args) - #if 'does not exist.' in res: - # raise RTError("Ticket does not exist") - #if 'You are not allowed to display ticket ' in res: - # raise RTError("You are not allowed to display this ticket") - #print res - out = forms.parse(res) - #if 'rt_comments' in out[0]: - # raise RTError(''.join(out[0]['rt_comments'])) - return out - - def split_res(self, res): - ret = res.split("\n") - return '\n'.join(ret[2:]) - - def login(self): - #self._do('/') #need this to start the session first? O.o - res = self._do('/search/ticket', query='id=1', user=self.username, pass_=self.password) - self.cj.save(COOKIEFILE, ignore_discard=True, ignore_expires=True) - return res - - def _get_ticket(self): - return Ticket(self) - ticket = property(_get_ticket) + def __init__(self, url, username, password): + self.url = url + self.username = username + self.password = password + + self.cj = cookielib.LWPCookieJar(COOKIEFILE) + self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj)) + + try: + self.cj.load(ignore_discard=True, ignore_expires=True) + except IOError: + pass + + self.logging_in = False + #self.login() + + def _make_url(self, action): + return "%s/REST/%s/%s" % (self.url, REST_VERSION, action) + + def _do(self, action, data=None, **args): + """Call url with args as query args and return the result""" + + for k,v in args.items(): + if k.endswith("_"): + del args[k] + args[k[:-1]]=v + + url = self._make_url(action) + if not data: + data = urllib.urlencode(args) + raw = self.opener.open(url, data).read() + res = self.split_res(raw) + + if 'Credentials required' in raw: + if not self.logging_in: + self.logging_in = True + self.login() + return self._do(action, data=data, **args) + raise RTError("Credentials required") + if 'Your username or password is incorrect' in res: + raise RTError("Your username or password is incorrect") + if 'Invalid query' in res: + raise RTError("Invalid query %s" % args) + #if 'does not exist.' in res: + # raise RTError("Ticket does not exist") + #if 'You are not allowed to display ticket ' in res: + # raise RTError("You are not allowed to display this ticket") + #print res + out = forms.parse(res) + #if 'rt_comments' in out[0]: + # raise RTError(''.join(out[0]['rt_comments'])) + return out + + def split_res(self, res): + ret = res.split("\n") + return '\n'.join(ret[2:]) + + def login(self): + #self._do('/') #need this to start the session first? O.o + res = self._do('/search/ticket', query='id=1', user=self.username, pass_=self.password) + self.cj.save(COOKIEFILE, ignore_discard=True, ignore_expires=True) + return res + + def _get_ticket(self): + return Ticket(self) + ticket = property(_get_ticket) + + def _get_user(self): + return User(self) + user = property(_get_user) diff --git a/pyrt/user.py b/pyrt/user.py new file mode 100644 index 0000000..3ac8866 --- /dev/null +++ b/pyrt/user.py @@ -0,0 +1,171 @@ +# pyrt/user.py +# Copyright (C) 2007, 2008 Justin Azoff JAzoff@uamail.albany.edu +# +# This module is released under the MIT License: +# http://www.opensource.org/licenses/mit-license.php + +import re +import forms + +def and_(crit): + return '(' + ' AND '.join(crit) + ')' +def or_(crit): + return '(' + ' OR '.join(crit) + ')' + +class Field: + def __init__(self, name): + self.name=name + + def __eq__(self, other): + return self._compare(self.name, other, '=') + def __ne__(self, other): + return self._compare(self.name, other, '!=') + def __gt__(self, other): + return self._compare(self.name, other, '>') + def __lt__(self, other): + return self._compare(self.name, other, '<') + + def __ge__(self, other): + return self._compare(self.name, other, '>=') + def __le__(self, other): + return self._compare(self.name, other, '<=') + + def like(self, other): + return self._compare(self.name, other, 'LIKE') + contains = like + + + def _compare(self, name, other, op): + nullops = {'=': 'IS', '!=': 'IS NOT'} + if other is None: + other = 'NULL' + op = nullops[op] + t = "'%s' %s '%s'" + return t % (name, op, other) + +class FieldWrapper: + def __init__(self, custom=False): + self.custom=custom + self.cf = None + def __getattr__(self, attr): + if self.custom: + return Field('CF.{%s}' % attr) + else: + return Field(attr) + + __call__ = __getattr__ + +class User(object): + def __init__(self, rtclient, id=None, fields=None): + self.id=id + self._fields = fields + self.rt = rtclient + self.c = FieldWrapper() + self.c.cf = FieldWrapper(custom=True) + + self._dirty_fields = {} + if fields: + self.id = fields['id'] + if id: + self._user_initialized = True + + def __repr__(self): + return "[pyrt.user %s]" % self.id + + def get(self, id): + """Fetch a user""" + if 'user/' in str(id): + id = int(id.replace('user/','')) + new_user = User(self.rt, id) + return new_user + + def show(self, force=False): + """Return all the fields for this user""" + + if not force and self._fields: + return self._fields + + fields = self.rt._do('user/show', id=self.id) + self._fields = fields[0] + return fields[0] + cache = show + + def create(self, **fields): + """Create a new user + >>> rt.user.new(id='rbackman', email='rbackman@georgefox.edu', + cf={ + 'building': building_name, + 'room': room_number, + }) + """ + + self.id = 'new' + out = self.edit(**fields) + msg = out[0]['rt_comments'][0] + match = re.search("User (\d+) created",msg) + if match: + id = match.groups()[0] + self.id = id + self._user_initialized = True + return self + raise Exception("Error creating user %s" % out) + + def edit(self, **fields): + """Edit an existing user + >>> t = rt.user.get('rbackman') + >>> t.edit(email='email@somewhere.com') + """ + fields['id'] = self.id + content = forms.generate(fields) + page = self.rt._do('user/%s/edit' % self.id, content=content) + return page + + def save(self): + if not self._dirty_fields: + return + fields = {} + fields['id'] = self.id + fields.update(self._dirty_fields) + ret = self.edit(**fields) + self._dirty_fields = {} + return ret + + def __getattr__(self, attr): + if not self.id: + raise AttributeError, "'User' object has no attribute '%s'" % attr + self.cache() + f = self._fields + + if attr in f: + return f[attr] + + a = attr.replace("_","-") + if a in f: + return f[a] + + raise AttributeError, "'User' object has no attribute '%s'" % attr + + def __getitem__(self, attr): + f = self._fields + return f[attr] + + def __setattr__(self, attr, val): + if not self.__dict__.has_key('_user_initialized') or attr.startswith("_"): + # this test allows attributes to be set in the __init__ method + return dict.__setattr__(self, attr, val) + self.cache() + f = self._fields + if attr in f: + self._dirty_fields[attr] = val + f[attr] = val + return + + a = attr.replace("_","-") + if a in f: + self._dirty_fields[a] = val + f[a] = val + return + + raise AttributeError, "'User' object has no attribute '%s'" % attr + +__all__ = ["User","and_","or_"] From 6f887c9c768b2765e549bfa63c08c141f2e72bd7 Mon Sep 17 00:00:00 2001 From: Ryan Backman Date: Wed, 6 Jun 2012 09:53:19 -0700 Subject: [PATCH 2/2] Tabs to spaces --- pyrt/__init__.py | 146 +++++++++++------------ pyrt/user.py | 302 +++++++++++++++++++++++------------------------ 2 files changed, 224 insertions(+), 224 deletions(-) diff --git a/pyrt/__init__.py b/pyrt/__init__.py index e1eef22..f228535 100644 --- a/pyrt/__init__.py +++ b/pyrt/__init__.py @@ -22,7 +22,7 @@ >>> search = and_([rt.ticket.c.created > '2008-02-20',rt.ticket.c.owner=='justin']) >>> tickets = rt.ticket.search(search) >>> for t in tickets: -... print t +... print t ... #searches for ('created' > '2008-02-20' AND 'owner' = 'justin') ['1644', 'blah blah'] @@ -39,7 +39,7 @@ Tue Feb 26 13:26:29 2008 >>> for t in rt.ticket.search(rt.ticket.c.cf.building=='Biology'): -... print t +... print t ... #searches for 'CF.{building}' = 'Biology' ['292', 'blah'] @@ -57,78 +57,78 @@ from user import * class RTError(Exception): - pass + pass COOKIEFILE = os.path.expanduser('~/.rt_cookies.txt') class RTClient: - def __init__(self, url, username, password): - self.url = url - self.username = username - self.password = password - - self.cj = cookielib.LWPCookieJar(COOKIEFILE) - self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj)) - - try: - self.cj.load(ignore_discard=True, ignore_expires=True) - except IOError: - pass - - self.logging_in = False - #self.login() - - def _make_url(self, action): - return "%s/REST/%s/%s" % (self.url, REST_VERSION, action) - - def _do(self, action, data=None, **args): - """Call url with args as query args and return the result""" - - for k,v in args.items(): - if k.endswith("_"): - del args[k] - args[k[:-1]]=v - - url = self._make_url(action) - if not data: - data = urllib.urlencode(args) - raw = self.opener.open(url, data).read() - res = self.split_res(raw) - - if 'Credentials required' in raw: - if not self.logging_in: - self.logging_in = True - self.login() - return self._do(action, data=data, **args) - raise RTError("Credentials required") - if 'Your username or password is incorrect' in res: - raise RTError("Your username or password is incorrect") - if 'Invalid query' in res: - raise RTError("Invalid query %s" % args) - #if 'does not exist.' in res: - # raise RTError("Ticket does not exist") - #if 'You are not allowed to display ticket ' in res: - # raise RTError("You are not allowed to display this ticket") - #print res - out = forms.parse(res) - #if 'rt_comments' in out[0]: - # raise RTError(''.join(out[0]['rt_comments'])) - return out - - def split_res(self, res): - ret = res.split("\n") - return '\n'.join(ret[2:]) - - def login(self): - #self._do('/') #need this to start the session first? O.o - res = self._do('/search/ticket', query='id=1', user=self.username, pass_=self.password) - self.cj.save(COOKIEFILE, ignore_discard=True, ignore_expires=True) - return res - - def _get_ticket(self): - return Ticket(self) - ticket = property(_get_ticket) - - def _get_user(self): - return User(self) - user = property(_get_user) + def __init__(self, url, username, password): + self.url = url + self.username = username + self.password = password + + self.cj = cookielib.LWPCookieJar(COOKIEFILE) + self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj)) + + try: + self.cj.load(ignore_discard=True, ignore_expires=True) + except IOError: + pass + + self.logging_in = False + #self.login() + + def _make_url(self, action): + return "%s/REST/%s/%s" % (self.url, REST_VERSION, action) + + def _do(self, action, data=None, **args): + """Call url with args as query args and return the result""" + + for k,v in args.items(): + if k.endswith("_"): + del args[k] + args[k[:-1]]=v + + url = self._make_url(action) + if not data: + data = urllib.urlencode(args) + raw = self.opener.open(url, data).read() + res = self.split_res(raw) + + if 'Credentials required' in raw: + if not self.logging_in: + self.logging_in = True + self.login() + return self._do(action, data=data, **args) + raise RTError("Credentials required") + if 'Your username or password is incorrect' in res: + raise RTError("Your username or password is incorrect") + if 'Invalid query' in res: + raise RTError("Invalid query %s" % args) + #if 'does not exist.' in res: + # raise RTError("Ticket does not exist") + #if 'You are not allowed to display ticket ' in res: + # raise RTError("You are not allowed to display this ticket") + #print res + out = forms.parse(res) + #if 'rt_comments' in out[0]: + # raise RTError(''.join(out[0]['rt_comments'])) + return out + + def split_res(self, res): + ret = res.split("\n") + return '\n'.join(ret[2:]) + + def login(self): + #self._do('/') #need this to start the session first? O.o + res = self._do('/search/ticket', query='id=1', user=self.username, pass_=self.password) + self.cj.save(COOKIEFILE, ignore_discard=True, ignore_expires=True) + return res + + def _get_ticket(self): + return Ticket(self) + ticket = property(_get_ticket) + + def _get_user(self): + return User(self) + user = property(_get_user) diff --git a/pyrt/user.py b/pyrt/user.py index 3ac8866..c9cc07d 100644 --- a/pyrt/user.py +++ b/pyrt/user.py @@ -8,164 +8,164 @@ import forms def and_(crit): - return '(' + ' AND '.join(crit) + ')' + return '(' + ' AND '.join(crit) + ')' def or_(crit): - return '(' + ' OR '.join(crit) + ')' + return '(' + ' OR '.join(crit) + ')' class Field: - def __init__(self, name): - self.name=name - - def __eq__(self, other): - return self._compare(self.name, other, '=') - def __ne__(self, other): - return self._compare(self.name, other, '!=') - def __gt__(self, other): - return self._compare(self.name, other, '>') - def __lt__(self, other): - return self._compare(self.name, other, '<') - - def __ge__(self, other): - return self._compare(self.name, other, '>=') - def __le__(self, other): - return self._compare(self.name, other, '<=') - - def like(self, other): - return self._compare(self.name, other, 'LIKE') - contains = like - - - def _compare(self, name, other, op): - nullops = {'=': 'IS', '!=': 'IS NOT'} - if other is None: - other = 'NULL' - op = nullops[op] - t = "'%s' %s '%s'" - return t % (name, op, other) + def __init__(self, name): + self.name=name + + def __eq__(self, other): + return self._compare(self.name, other, '=') + def __ne__(self, other): + return self._compare(self.name, other, '!=') + def __gt__(self, other): + return self._compare(self.name, other, '>') + def __lt__(self, other): + return self._compare(self.name, other, '<') + + def __ge__(self, other): + return self._compare(self.name, other, '>=') + def __le__(self, other): + return self._compare(self.name, other, '<=') + + def like(self, other): + return self._compare(self.name, other, 'LIKE') + contains = like + + + def _compare(self, name, other, op): + nullops = {'=': 'IS', '!=': 'IS NOT'} + if other is None: + other = 'NULL' + op = nullops[op] + t = "'%s' %s '%s'" + return t % (name, op, other) class FieldWrapper: - def __init__(self, custom=False): - self.custom=custom - self.cf = None - def __getattr__(self, attr): - if self.custom: - return Field('CF.{%s}' % attr) - else: - return Field(attr) + def __init__(self, custom=False): + self.custom=custom + self.cf = None + def __getattr__(self, attr): + if self.custom: + return Field('CF.{%s}' % attr) + else: + return Field(attr) - __call__ = __getattr__ + __call__ = __getattr__ class User(object): - def __init__(self, rtclient, id=None, fields=None): - self.id=id - self._fields = fields - self.rt = rtclient - self.c = FieldWrapper() - self.c.cf = FieldWrapper(custom=True) - - self._dirty_fields = {} - if fields: - self.id = fields['id'] - if id: - self._user_initialized = True - - def __repr__(self): - return "[pyrt.user %s]" % self.id - - def get(self, id): - """Fetch a user""" - if 'user/' in str(id): - id = int(id.replace('user/','')) - new_user = User(self.rt, id) - return new_user - - def show(self, force=False): - """Return all the fields for this user""" - - if not force and self._fields: - return self._fields - - fields = self.rt._do('user/show', id=self.id) - self._fields = fields[0] - return fields[0] - cache = show - - def create(self, **fields): - """Create a new user - >>> rt.user.new(id='rbackman', email='rbackman@georgefox.edu', - cf={ - 'building': building_name, - 'room': room_number, - }) - """ - - self.id = 'new' - out = self.edit(**fields) - msg = out[0]['rt_comments'][0] - match = re.search("User (\d+) created",msg) - if match: - id = match.groups()[0] - self.id = id - self._user_initialized = True - return self - raise Exception("Error creating user %s" % out) - - def edit(self, **fields): - """Edit an existing user - >>> t = rt.user.get('rbackman') - >>> t.edit(email='email@somewhere.com') - """ - fields['id'] = self.id - content = forms.generate(fields) - page = self.rt._do('user/%s/edit' % self.id, content=content) - return page - - def save(self): - if not self._dirty_fields: - return - fields = {} - fields['id'] = self.id - fields.update(self._dirty_fields) - ret = self.edit(**fields) - self._dirty_fields = {} - return ret - - def __getattr__(self, attr): - if not self.id: - raise AttributeError, "'User' object has no attribute '%s'" % attr - self.cache() - f = self._fields - - if attr in f: - return f[attr] - - a = attr.replace("_","-") - if a in f: - return f[a] - - raise AttributeError, "'User' object has no attribute '%s'" % attr - - def __getitem__(self, attr): - f = self._fields - return f[attr] - - def __setattr__(self, attr, val): - if not self.__dict__.has_key('_user_initialized') or attr.startswith("_"): - # this test allows attributes to be set in the __init__ method - return dict.__setattr__(self, attr, val) - self.cache() - f = self._fields - if attr in f: - self._dirty_fields[attr] = val - f[attr] = val - return - - a = attr.replace("_","-") - if a in f: - self._dirty_fields[a] = val - f[a] = val - return - - raise AttributeError, "'User' object has no attribute '%s'" % attr + def __init__(self, rtclient, id=None, fields=None): + self.id=id + self._fields = fields + self.rt = rtclient + self.c = FieldWrapper() + self.c.cf = FieldWrapper(custom=True) + + self._dirty_fields = {} + if fields: + self.id = fields['id'] + if id: + self._user_initialized = True + + def __repr__(self): + return "[pyrt.user %s]" % self.id + + def get(self, id): + """Fetch a user""" + if 'user/' in str(id): + id = int(id.replace('user/','')) + new_user = User(self.rt, id) + return new_user + + def show(self, force=False): + """Return all the fields for this user""" + + if not force and self._fields: + return self._fields + + fields = self.rt._do('user/show', id=self.id) + self._fields = fields[0] + return fields[0] + cache = show + + def create(self, **fields): + """Create a new user + >>> rt.user.new(id='rbackman', email='rbackman@georgefox.edu', + cf={ + 'building': building_name, + 'room': room_number, + }) + """ + + self.id = 'new' + out = self.edit(**fields) + msg = out[0]['rt_comments'][0] + match = re.search("User (\d+) created",msg) + if match: + id = match.groups()[0] + self.id = id + self._user_initialized = True + return self + raise Exception("Error creating user %s" % out) + + def edit(self, **fields): + """Edit an existing user + >>> t = rt.user.get('rbackman') + >>> t.edit(email='email@somewhere.com') + """ + fields['id'] = self.id + content = forms.generate(fields) + page = self.rt._do('user/%s/edit' % self.id, content=content) + return page + + def save(self): + if not self._dirty_fields: + return + fields = {} + fields['id'] = self.id + fields.update(self._dirty_fields) + ret = self.edit(**fields) + self._dirty_fields = {} + return ret + + def __getattr__(self, attr): + if not self.id: + raise AttributeError, "'User' object has no attribute '%s'" % attr + self.cache() + f = self._fields + + if attr in f: + return f[attr] + + a = attr.replace("_","-") + if a in f: + return f[a] + + raise AttributeError, "'User' object has no attribute '%s'" % attr + + def __getitem__(self, attr): + f = self._fields + return f[attr] + + def __setattr__(self, attr, val): + if not self.__dict__.has_key('_user_initialized') or attr.startswith("_"): + # this test allows attributes to be set in the __init__ method + return dict.__setattr__(self, attr, val) + self.cache() + f = self._fields + if attr in f: + self._dirty_fields[attr] = val + f[attr] = val + return + + a = attr.replace("_","-") + if a in f: + self._dirty_fields[a] = val + f[a] = val + return + + raise AttributeError, "'User' object has no attribute '%s'" % attr __all__ = ["User","and_","or_"]