134 lines
5.5 KiB
Python
134 lines
5.5 KiB
Python
|
# Copyright (C) 2014 SUSE Linux Products GmbH
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation; either version 2 of the License, or
|
||
|
# (at your option) any later version.
|
||
|
#
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
#
|
||
|
# You should have received a copy of the GNU General Public License along
|
||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
from datetime import datetime
|
||
|
import re
|
||
|
from xml.etree import cElementTree as ET
|
||
|
|
||
|
from osc.core import http_DELETE
|
||
|
from osc.core import http_GET
|
||
|
from osc.core import http_POST
|
||
|
from osc.core import makeurl
|
||
|
|
||
|
|
||
|
class CommentAPI(object):
|
||
|
def __init__(self, apiurl):
|
||
|
self.apiurl = apiurl
|
||
|
|
||
|
def _prepare_url(self, request_id=None, project_name=None,
|
||
|
package_name=None):
|
||
|
"""Prepare the URL to get/put comments in OBS.
|
||
|
|
||
|
:param request_id: Request where to refer the comment.
|
||
|
:param project_name: Project name where to refer comment.
|
||
|
:param package_name: Package name where to refer the comment.
|
||
|
:returns: Formated URL for the request.
|
||
|
"""
|
||
|
url = None
|
||
|
if request_id:
|
||
|
url = makeurl(self.apiurl, ['comments', 'request', request_id])
|
||
|
elif project_name and package_name:
|
||
|
url = makeurl(self.apiurl, ['comments', 'package', project_name,
|
||
|
package_name])
|
||
|
elif project_name:
|
||
|
url = makeurl(self.apiurl, ['comments', 'project', project_name])
|
||
|
else:
|
||
|
raise ValueError('Please, set request_id, project_name or / and package_name to add a comment.')
|
||
|
return url
|
||
|
|
||
|
def _comment_as_dict(self, comment_element):
|
||
|
"""Convert an XML element comment into a dictionary.
|
||
|
:param comment_element: XML element that store a comment.
|
||
|
:returns: A Python dictionary object.
|
||
|
"""
|
||
|
comment = {
|
||
|
'who': comment_element.get('who'),
|
||
|
'when': datetime.strptime(comment_element.get('when'), '%Y-%m-%d %H:%M:%S %Z'),
|
||
|
'id': comment_element.get('id'),
|
||
|
'comment': comment_element.text,
|
||
|
}
|
||
|
try:
|
||
|
comment['parent'] = comment_element['parent']
|
||
|
except:
|
||
|
pass
|
||
|
return comment
|
||
|
|
||
|
def get_comments(self, request_id=None, project_name=None,
|
||
|
package_name=None):
|
||
|
"""Get the list of comments of an object in OBS.
|
||
|
|
||
|
:param request_id: Request where to get comments.
|
||
|
:param project_name: Project name where to get comments.
|
||
|
:param package_name: Package name where to get comments.
|
||
|
:returns: A list of comments (as a dictionary).
|
||
|
"""
|
||
|
url = self._prepare_url(request_id, project_name, package_name)
|
||
|
root = root = ET.parse(http_GET(url)).getroot()
|
||
|
comments = [self._comment_as_dict(c) for c in root.findall('comment')]
|
||
|
return comments
|
||
|
|
||
|
def add_comment(self, request_id=None, project_name=None,
|
||
|
package_name=None, comment=None):
|
||
|
"""Add a comment in an object in OBS.
|
||
|
|
||
|
:param request_id: Request where to write a comment.
|
||
|
:param project_name: Project name where to write a comment.
|
||
|
:param package_name: Package name where to write a comment.
|
||
|
:param comment: Comment to be published.
|
||
|
:return: Comment id.
|
||
|
"""
|
||
|
if not comment:
|
||
|
raise ValueError('Empty comment.')
|
||
|
|
||
|
url = self._prepare_url(request_id, project_name, package_name)
|
||
|
return http_POST(url, data=comment)
|
||
|
|
||
|
def delete(self, comment_id):
|
||
|
"""Remove a comment object.
|
||
|
:param comment_id: Id of the comment object.
|
||
|
"""
|
||
|
url = makeurl(self.apiurl, ['comments', comment_id])
|
||
|
return http_DELETE(url)
|
||
|
|
||
|
def delete_from(self, request_id=None, project_name=None,
|
||
|
package_name=None):
|
||
|
"""Remove the comments related with a request, project or package.
|
||
|
:param request_id: Request where to remove comments.
|
||
|
:param project_name: Project name where to remove comments.
|
||
|
:param package_name: Package name where to remove comments.
|
||
|
:return: Number of comments removed.
|
||
|
"""
|
||
|
comments = self.get_comments(request_id, project_name, package_name)
|
||
|
for comment in comments:
|
||
|
self.delete(comment['id'])
|
||
|
return len(comments)
|
||
|
|
||
|
def delete_from_where_user(self, user, request_id=None, project_name=None,
|
||
|
package_name=None):
|
||
|
"""Remove comments where @user is mentioned.
|
||
|
|
||
|
This method is used to remove notifications when a request is
|
||
|
removed or moved to another project.
|
||
|
:param user: User name where the comment will be removed.
|
||
|
:param request_id: Request where to remove comments.
|
||
|
:param project_name: Project name where to remove comments.
|
||
|
:param package_name: Package name where to remove comments.
|
||
|
:return: Number of comments removed.
|
||
|
"""
|
||
|
user_re = re.compile(r'@%s\b')
|
||
|
for comment in self.comments(request_id, project_name, package_name):
|
||
|
if user_re.match(comment['comment']):
|
||
|
self.delete(comment['id'])
|