Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
List overview
Download
copr-commits
September 2015
----- 2024 -----
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
copr-commits@lists.fedorahosted.org
4 participants
116 discussions
Start a n
N
ew thread
[copr] python_copr_apiv2: [python][api_v2] refactored inderect handlers calls; moved ListResource creation code to the classmethods (9c63bcb)
by vgologuz@fedoraproject.org
30 Sep '15
30 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : python_copr_apiv2 >--------------------------------------------------------------- commit 9c63bcbb8fc3d2d5a9b1e8dd205e0641af83d14b Author: Valentin Gologuzov <vgologuz(a)redhat.com> Date: Wed Sep 30 16:48:55 2015 +0200 [python][api_v2] refactored inderect handlers calls; moved ListResource creation code to the classmethods >--------------------------------------------------------------- python/copr/client_v2/handlers.py | 94 ++++------------------------------- python/copr/client_v2/resources.py | 75 +++++++++++++++++++++++++++- python/run_tmp.py | 12 ++++- 3 files changed, 92 insertions(+), 89 deletions(-) diff --git a/python/copr/client_v2/handlers.py b/python/copr/client_v2/handlers.py index 03eb7c3..c7b7434 100644 --- a/python/copr/client_v2/handlers.py +++ b/python/copr/client_v2/handlers.py @@ -68,23 +68,7 @@ class BuildHandle(AbstractHandle): } response = self.nc.request(self.get_base_url(), query_params=options) - data_dict = response.json - result = BuildList( - self, - response=response, - links=Link.from_dict(data_dict["_links"], { - "self": EntityTypes.BUILD, - }), - individuals=[ - Build.from_response( - handle=self, - response=None, - data_dict=dict_part, - ) - for dict_part in data_dict["builds"] - ] - ) - return result + return BuildList.from_response(self, response, options) def cancel(self, build_entity): """ @@ -221,24 +205,7 @@ class ProjectHandle(AbstractHandle): } response = self.nc.request(self.get_base_url(), query_params=options) - data_dict = response.json - result = ProjectsList( - self, - response=response, - links=Link.from_dict(data_dict["_links"], { - "self": EntityTypes.PROJECT, - }), - individuals=[ - Project.from_response( - handle=self, - response=None, - data_dict=dict_part, - ) - for dict_part in data_dict["projects"] - ], - options=None - ) - return result + return ProjectsList.from_response(self, response, options) def get_one(self, project_id, show_builds=False, show_chroots=False): """ @@ -273,44 +240,18 @@ class ProjectHandle(AbstractHandle): response = self.nc.request(url, method="delete", do_auth=True) return OperationResult(self, response) - def get_project_chroot(self, project, name): - """ - :type project: copr.client_v2.resources.Project - :param str name: chroot name - :rtype: copr.client_v2.resources.ProjectChroot - """ - return self.client.project_chroots.get_one(project, name) - - def get_project_chroot_list(self, project): - """ - :type project: copr.client_v2.resources.Project - """ - return self.client.project_chroots.get_list(project) - - def enable_chroot(self, project, *args, **kwargs): - """ - :type project: copr.client_v2.resources.Project - """ - return self.client.project_chroots.enable(project, *args, **kwargs) - - # def create_build_from_file(self, project, *args, **kwargs): - # """ - # See additional options `:py:method:BuildHandle.create_from_file:` - # """ - # return self.client.builds.create_from_file(project.id, *args, **kwargs) - # - # def create_build_from_url(self, project, *args, **kwargs): - # """ - # See additional options `:py:method:BuildHandle.create_from_url:` - # """ - # return self.client.builds.create_from_url(project.id, *args, **kwargs) - def get_builds_handle(self): """ :rtype: BuildHandle """ return self.client.builds + def get_project_chroots_handle(self): + """ + :rtype: ProjectChrootHandle + """ + return self.client.project_chroots + class ProjectChrootHandle(AbstractHandle): @@ -341,23 +282,10 @@ class ProjectChrootHandle(AbstractHandle): :type project: copr.client_v2.resources.Project """ response = self.nc.request(self.get_base_url(project)) - data_dict = response.json - return ProjectChrootList( - self, - project=project, + return ProjectChrootList.from_response( + handle=self, response=response, - links=Link.from_dict(data_dict["_links"], { - "self": EntityTypes.PROJECT_CHROOT, - }), - individuals=[ - ProjectChroot.from_response( - handle=self, - response=None, - data_dict=dict_part, - project=project - ) - for dict_part in data_dict["chroots"] - ] + project=project ) def disable(self, project, name): diff --git a/python/copr/client_v2/resources.py b/python/copr/client_v2/resources.py index fa40551..e8f258b 100644 --- a/python/copr/client_v2/resources.py +++ b/python/copr/client_v2/resources.py @@ -129,13 +129,16 @@ class Project(IndividualResource): return self._handle.get_one(self.id, **self._options) def get_project_chroot(self, name): - return self._handle.get_project_chroot(self, name) + handle = self._handle.get_project_chroots_handle() + return handle.get_one(self, name) def get_project_chroot_list(self): - return self._handle.get_project_chroot_list(self) + handle = self._handle.get_project_chroots_handle() + return handle.get_list(self) def enable_project_chroot(self, *args, **kwargs): - return self._handle.enable_chroot(self, *args, **kwargs) + handle = self._handle.get_project_chroots_handle() + return handle.enable(self, *args, **kwargs) # TODO: remove proxy methods on the handle classes def create_build_from_file(self, *args, **kwargs): @@ -279,6 +282,10 @@ class CollectionResource(Iterable, UnicodeMixin): """ return iter(self._individuals) + @classmethod + def from_response(cls, handle, response, options): + raise NotImplementedError + # todo: add classmethod from response @@ -295,6 +302,27 @@ class ProjectsList(CollectionResource): def projects(self): return self._individuals + @classmethod + def from_response(cls, handle, response, options): + data_dict = response.json + result = ProjectsList( + handle, + response=response, + links=Link.from_dict(data_dict["_links"], { + "self": EntityTypes.PROJECT, + }), + individuals=[ + Project.from_response( + handle=handle, + response=None, + data_dict=dict_part, + ) + for dict_part in data_dict["projects"] + ], + options=None + ) + return result + class BuildList(CollectionResource): """ @@ -308,6 +336,26 @@ class BuildList(CollectionResource): def builds(self): return self._individuals + @classmethod + def from_response(cls, handle, response, options): + data_dict = response.json + result = BuildList( + handle, + response=response, + links=Link.from_dict(data_dict["_links"], { + "self": EntityTypes.BUILD, + }), + individuals=[ + Build.from_response( + handle=handle, + response=None, + data_dict=dict_part, + ) + for dict_part in data_dict["builds"] + ] + ) + return result + class ProjectChrootList(CollectionResource): """ @@ -326,6 +374,27 @@ class ProjectChrootList(CollectionResource): def enable(self, name): return self._handle.enable(self._project, name) + @classmethod + def from_response(cls, handle, response, project): + data_dict = response.json + return ProjectChrootList( + handle, + project=project, + response=response, + links=Link.from_dict(data_dict["_links"], { + "self": EntityTypes.PROJECT_CHROOT, + }), + individuals=[ + ProjectChroot.from_response( + handle=handle, + response=None, + data_dict=dict_part, + project=project + ) + for dict_part in data_dict["chroots"] + ] + ) + class MockChrootList(CollectionResource): """ diff --git a/python/run_tmp.py b/python/run_tmp.py index cc630b1..780db44 100644 --- a/python/run_tmp.py +++ b/python/run_tmp.py @@ -70,6 +70,8 @@ def main(): for pc in project.get_project_chroot_list(): print(pc) + t4() + def t5(): build = client.builds.get_one(117578) #build._handle.cancel(build._entity) @@ -82,7 +84,7 @@ def main(): def t6(): - project = client.projects.get_one("4642") + project = client.projects.get_one(3554) print(project) # new_c = project.get_project_chroot("epel-5-x86_64") @@ -92,12 +94,13 @@ def main(): for pc in project.get_project_chroot_list(): print(pc) - pc.disable() + # pc.disable() x = 2 + t6() # def t7(): @@ -132,7 +135,10 @@ def main(): for mc in mcl: print(mc) - t9() + # t9() + + def t10(): + pass if __name__ == "__main__": try:
1
0
0
0
[copr] python_copr_apiv2: [python][api_v2] added support for MockChroot resource (e0ca760)
by vgologuz@fedoraproject.org
30 Sep '15
30 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : python_copr_apiv2 >--------------------------------------------------------------- commit e0ca7601cb06ba17cfa11d8739cef20e8bab60ad Author: Valentin Gologuzov <vgologuz(a)redhat.com> Date: Wed Sep 30 14:35:20 2015 +0200 [python][api_v2] added support for MockChroot resource >--------------------------------------------------------------- python/copr/client_v2/client.py | 22 +++++++- python/copr/client_v2/common.py | 13 +++++ python/copr/client_v2/entities.py | 73 ++++++++++++++++++------- python/copr/client_v2/handlers.py | 45 +++++++++++++++- python/copr/client_v2/net_client.py | 4 +- python/copr/client_v2/resources.py | 45 ++++++++++++++- python/copr/client_v2/schemas.py | 16 +----- python/copr/test/client_v2/test_net_client.py | 1 + python/run_tmp.py | 9 +++- 9 files changed, 185 insertions(+), 43 deletions(-) diff --git a/python/copr/client_v2/client.py b/python/copr/client_v2/client.py index be05dae..9035d5e 100644 --- a/python/copr/client_v2/client.py +++ b/python/copr/client_v2/client.py @@ -20,7 +20,7 @@ from six.moves import configparser # from requests_toolbelt.multipart.encoder import MultipartEncoder from .resources import Root -from .handlers import ProjectHandle, ProjectChrootHandle, BuildHandle +from .handlers import ProjectHandle, ProjectChrootHandle, BuildHandle, MockChrootHandle from .common import EntityTypes from .net_client import NetClient @@ -68,6 +68,14 @@ class HandlersProvider(with_metaclass(ABCMeta)): # def build_tasks(self): # pass + @abstractproperty + def mock_chroots(self): + """ + :rtype: MockChrootHandle + """ + pass + + class CoprClient(UnicodeMixin, HandlersProvider): """ Main interface to the copr service @@ -100,6 +108,7 @@ class CoprClient(UnicodeMixin, HandlersProvider): self._projects = None self._project_chroots = None self._builds = None + self._mock_chroots = None def _check_client_init(self): if not self._post_init_done: @@ -121,6 +130,11 @@ class CoprClient(UnicodeMixin, HandlersProvider): self._check_client_init() return self._builds + @property + def mock_chroots(self): + self._check_client_init() + return self._mock_chroots + def __unicode__(self): return ( u"<Copr client. api root url: {}, config provided: {}, net client: {}>" @@ -203,9 +217,15 @@ class CoprClient(UnicodeMixin, HandlersProvider): projects_href=self.root.get_href_by_name(u"projects"),) self._project_chroots = ProjectChrootHandle( weakref.proxy(self), self.nc, root_url=self.root_url) + self._builds = BuildHandle( weakref.proxy(self), self.nc, root_url=self.root_url, builds_href=self.root.get_href_by_name(u"builds"),) + # self._build_chroots = BuildTaskHandle() + self._mock_chroots = MockChrootHandle( + weakref.proxy(self), self.nc, root_url=self.root_url, + href=self.root.get_href_by_name(u"mock_chroots") + ) self._post_init_done = True diff --git a/python/copr/client_v2/common.py b/python/copr/client_v2/common.py index 4e96bf5..8f64195 100644 --- a/python/copr/client_v2/common.py +++ b/python/copr/client_v2/common.py @@ -1,4 +1,7 @@ # coding: utf-8 +from copr.util import UnicodeMixin + + class EntityTypes(object): ROOT = "root" PROJECT = "project" @@ -6,3 +9,13 @@ class EntityTypes(object): BUILD = "build" BUILD_TASK = "build_task" MOCK_CHROOT = "mock_chroot" + + +class BuiltPackage(UnicodeMixin): + + def __init__(self, name, version): + self.name = name + self.version = version + + def __unicode__(self): + return u"{} {}".format(self.name, self.version) diff --git a/python/copr/client_v2/entities.py b/python/copr/client_v2/entities.py index 6789872..b39aa12 100644 --- a/python/copr/client_v2/entities.py +++ b/python/copr/client_v2/entities.py @@ -1,11 +1,10 @@ # coding: utf-8 from ..util import UnicodeMixin -from .schemas import ProjectSchema, EmptySchema, ProjectChrootSchema, BuildSchema, BuildTaskSchema +from .schemas import ProjectSchema, EmptySchema, ProjectChrootSchema, BuildSchema, BuildTaskSchema, MockChrootSchema class Link(UnicodeMixin): - def __init__(self, role, href, target_type): self.role = role self.href = href @@ -44,9 +43,12 @@ class Link(UnicodeMixin): class Entity(UnicodeMixin): - _schema = EmptySchema() + def __init__(self, **kwargs): + for field in self._schema.fields.keys(): + setattr(self, field, kwargs.get(field)) + def to_dict(self): return self._schema.dump(self).data @@ -54,52 +56,83 @@ class Entity(UnicodeMixin): return self._schema.dumps(self).data @classmethod - def constructor(cls, **kwargs): - return cls.from_dict(kwargs) - - @classmethod def from_dict(cls, raw_dict): parsed = cls._schema.load(raw_dict) - obj = cls() - for field, value in parsed.data.items(): - setattr(obj, field, value) - return obj + return cls(**parsed.data) class ProjectEntity(Entity): - _schema = ProjectSchema(strict=True) + # def __init__(self, **kwargs): + # self.id = kwargs["id"] + # self.name = kwargs["name"] + # + # self.owner = kwargs["owner"] + # self.description = kwargs.get("description") + # self.instructions = kwargs.get("instructions") + # self.homepage = kwargs.get("homepage") + # self.contact = kwargs.get("contact") + # + # self.disable_createrepo = kwargs.get("disable_createrepo") + # self.build_enable_net = kwargs.get("build_enable_net") + # self.last_modified = kwargs.get("last_modified") + # + # self.repos = kwargs.get("repos", list()) + def __unicode__(self): return "<Project #{}: {}/{}>".format(self.id, self.owner, self.name) class ProjectChrootEntity(Entity): - _schema = ProjectChrootSchema(strict=True) + # def __init__(self, **kwargs): + # self.name = kwargs["name"] + # self.buildroot_pkgs = kwargs.get("buildroot_pkgs", list()) + # + # self.comps = kwargs.get("comps") + # self.comps_name = kwargs.get("comps_name") + # self.comps_len = kwargs.get("comps_len") + def __unicode__(self): return "<Project chroot: {}, additional " \ - "packages: {}, comps size if any: {}>".format( - self.name, - self.buildroot_pkgs, - self.comps_len, - ) + "packages: {}, comps size if any: {}>"\ + .format(self.name, self.buildroot_pkgs, self.comps_len,) class BuildEntity(Entity): - _schema = BuildSchema(strict=True) + # def __init__(self, **kwargs): + # + # self.id = kwargs["id"] + # self.state = kwargs["state"] + # + # self.submitter = kwargs["submitter"] + # + # self.built_packages = kwargs["built_packages"] + # + # + def __unicode__(self): return "<Build #{} state: {}>".format(self.id, self.state) class BuildTaskEntity(Entity): - _schema = BuildTaskSchema(strict=True) def __unicode__(self): return "<Build task #{}-{}, state: {}>".format( self.build_id, self.chroot_name, self.state ) + + +class MockChrootEntity(Entity): + + _schema = MockChrootSchema(strict=True) + + def __unicode__(self): + return "<Mock chroot: {} is active: {}>".format( + self.name, self.is_active + ) diff --git a/python/copr/client_v2/handlers.py b/python/copr/client_v2/handlers.py index d590f75..03eb7c3 100644 --- a/python/copr/client_v2/handlers.py +++ b/python/copr/client_v2/handlers.py @@ -6,7 +6,8 @@ import os from .common import EntityTypes from copr.client_v2.net_client import RequestError, MultiPartTuple from .entities import Link, ProjectChrootEntity -from .resources import Project, OperationResult, ProjectsList, ProjectChroot, ProjectChrootList, Build, BuildList +from .resources import Project, OperationResult, ProjectsList, ProjectChroot, ProjectChrootList, Build, BuildList, \ + MockChroot, MockChrootList class AbstractHandle(object): @@ -373,7 +374,7 @@ class ProjectChrootHandle(AbstractHandle): :type project: copr.client_v2.resources.Project """ - new_entity = ProjectChrootEntity.constructor( + new_entity = ProjectChrootEntity( name=name, buildroot_pkgs=buildroot_pkgs or list() ) @@ -398,3 +399,43 @@ class ProjectChrootHandle(AbstractHandle): do_auth=True ) return OperationResult(self, response) + + +class MockChrootHandle(AbstractHandle): + + def __init__(self, client, nc, root_url, href): + super(MockChrootHandle, self).__init__(client, nc, root_url) + self._href = href + self._base_url = "{}{}".format(self.root_url, href) + + def get_base_url(self): + return self._base_url + + def get_one(self, name): + url = "{}/{}".format(self.get_base_url(), name) + response = self.nc.get(url) + return MockChroot.from_response(self, response, response.json) + + def get_list(self, active_only=True): + options = dict(active_only=active_only) + + response = self.nc.get( + self.get_base_url(), + query_params=options + ) + data_dict = response.json + return MockChrootList( + self, + response=response, + links=Link.from_dict(data_dict["_links"], { + "self": EntityTypes.MOCK_CHROOT, + }), + individuals=[ + MockChroot.from_response( + handle=self, + response=None, + data_dict=dict_part, + ) + for dict_part in data_dict["chroots"] + ] + ) diff --git a/python/copr/client_v2/net_client.py b/python/copr/client_v2/net_client.py index 676d4f6..74b66b0 100644 --- a/python/copr/client_v2/net_client.py +++ b/python/copr/client_v2/net_client.py @@ -24,9 +24,9 @@ class RequestError(Exception, UnicodeMixin): @property def response_json(self): - if self.response.headers["content-type"] == "application/json": - if self.response is None: + if self.response is None: raise ValueError("No response") + if self.response.headers["content-type"] == "application/json": try: result = json.loads(self.response.text) except (ValueError, AttributeError): diff --git a/python/copr/client_v2/resources.py b/python/copr/client_v2/resources.py index ac0537d..fa40551 100644 --- a/python/copr/client_v2/resources.py +++ b/python/copr/client_v2/resources.py @@ -4,7 +4,7 @@ from collections import Iterable from ..util import UnicodeMixin from .common import EntityTypes -from .entities import Link, ProjectEntity, ProjectChrootEntity, BuildEntity +from .entities import Link, ProjectEntity, ProjectChrootEntity, BuildEntity, MockChrootEntity from .schemas import EmptySchema @@ -143,7 +143,7 @@ class Project(IndividualResource): See additional options `:py:method:BuildHandle.create_from_file:` """ builds = self._handle.get_builds_handle() - builds.create_from_file(self.id, *args, **kwargs) + return builds.create_from_file(self.id, *args, **kwargs) @classmethod def from_response(cls, handle, response, data_dict, options=None): @@ -186,6 +186,29 @@ class ProjectChroot(IndividualResource): return self._handle.update(self._project, self._entity) +class MockChroot(IndividualResource): + """ + :type entity: copr.client_v2.entities.MockChrootEntity + :type handle: copr.client_v2.handlers.MockChrootHandle + """ + + def __init__(self, entity, handle, **kwargs): + super(MockChroot, self).__init__( + entity=entity, + handle=handle, + **kwargs + ) + + @classmethod + def from_response(cls, handle, response, data_dict, options=None): + links = Link.from_dict(data_dict["_links"], { + "self": EntityTypes.MOCK_CHROOT, + }) + entity = MockChrootEntity.from_dict(data_dict["chroot"]) + return cls(entity=entity, handle=handle, + response=response, links=links, options=options) + + class OperationResult(IndividualResource): # TODO: app param expected_status=200 and method is_successful() which would compare @@ -256,6 +279,8 @@ class CollectionResource(Iterable, UnicodeMixin): """ return iter(self._individuals) + # todo: add classmethod from response + class ProjectsList(CollectionResource): """ @@ -286,7 +311,7 @@ class BuildList(CollectionResource): class ProjectChrootList(CollectionResource): """ - :type handle: coprclient_v2.handlers.ProjectChrootHandle + :type handle: copr.client_v2.handlers.ProjectChrootHandle """ def __init__(self, handle, project, **kwargs): @@ -300,3 +325,17 @@ class ProjectChrootList(CollectionResource): def enable(self, name): return self._handle.enable(self._project, name) + + +class MockChrootList(CollectionResource): + """ + :type handle: copr.client_v2.handlers.MockChrootHandle + """ + + def __init__(self, handle, **kwargs): + super(MockChrootList, self).__init__(**kwargs) + self._handle = handle + + @property + def chroots(self): + return self._individuals diff --git a/python/copr/client_v2/schemas.py b/python/copr/client_v2/schemas.py index c4c780c..68ca2b4 100644 --- a/python/copr/client_v2/schemas.py +++ b/python/copr/client_v2/schemas.py @@ -1,14 +1,12 @@ # coding: utf-8 -from collections import Iterable -from marshmallow import Schema, fields, post_load -from marshmallow import Schema, fields, validates_schema, ValidationError, validate +from marshmallow import Schema, fields # todo: maybe define schemas for Link sets in each indvidual/collection # class LinkSchema(Schema): # href = fields.Str() # -from copr.util import UnicodeMixin +from .common import BuiltPackage class EmptySchema(Schema): @@ -43,16 +41,6 @@ class ProjectChrootSchema(Schema): comps_len = fields.Int(load_only=True, allow_none=True) -class BuiltPackage(UnicodeMixin): - - def __init__(self, name, version): - self.name = name - self.version = version - - def __unicode__(self): - return u"{} {}".format(self.name, self.version) - - class BuiltPackageSchema(Schema): name = fields.Str() diff --git a/python/copr/test/client_v2/test_net_client.py b/python/copr/test/client_v2/test_net_client.py index ba9113f..7cca53a 100644 --- a/python/copr/test/client_v2/test_net_client.py +++ b/python/copr/test/client_v2/test_net_client.py @@ -66,4 +66,5 @@ class TestNetClient(object): # some coverage for Request error s = str(exc_info.value) with pytest.raises(ValueError): + # import ipdb; ipdb.set_trace() x = exc_info.value.response_json diff --git a/python/run_tmp.py b/python/run_tmp.py index 6347eb8..cc630b1 100644 --- a/python/run_tmp.py +++ b/python/run_tmp.py @@ -124,8 +124,15 @@ def main(): b = b.get_self() print(b) - t8() + # t8() + def t9(): + + mcl = client.mock_chroots.get_list(active_only=False) + for mc in mcl: + print(mc) + + t9() if __name__ == "__main__": try:
1
0
0
0
[copr] frontend-python3: [frontend] more py2/py3 compatibile strings magic (cea2c35)
by frostyx@fedoraproject.org
30 Sep '15
30 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : frontend-python3 >--------------------------------------------------------------- commit cea2c3532e4613c3aae1c60c127caa0290f94cbc Author: Jakub Kadlčík <jkadlcik(a)redhat.com> Date: Wed Sep 30 12:32:15 2015 +0200 [frontend] more py2/py3 compatibile strings magic >--------------------------------------------------------------- frontend/coprs_frontend/coprs/models.py | 2 +- frontend/coprs_frontend/coprs/rest_api/common.py | 2 +- frontend/coprs_frontend/coprs/rest_api/schemas.py | 3 ++- .../tests/test_api/test_project_chroot_r.py | 4 ++-- .../test_views/test_coprs_ns/test_coprs_general.py | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py index 63ef2bd..5f04a6e 100644 --- a/frontend/coprs_frontend/coprs/models.py +++ b/frontend/coprs_frontend/coprs/models.py @@ -646,7 +646,7 @@ class CoprChroot(db.Model, helpers.Serializer): comps_name = db.Column(db.String(127), nullable=True) def update_comps(self, comps_xml): - self.comps_zlib = zlib.compress(comps_xml) + self.comps_zlib = zlib.compress(comps_xml.encode("utf-8")) @property def buildroot_pkgs_list(self): diff --git a/frontend/coprs_frontend/coprs/rest_api/common.py b/frontend/coprs_frontend/coprs/rest_api/common.py index 6be90b2..d554369 100644 --- a/frontend/coprs_frontend/coprs/rest_api/common.py +++ b/frontend/coprs_frontend/coprs/rest_api/common.py @@ -91,7 +91,7 @@ def rest_api_auth_required(f): base64string = flask.request.headers["Authorization"] base64string = base64string.split()[1].strip() userstring = base64.b64decode(base64string) - (api_login, token) = userstring.split(b":") + (api_login, token) = userstring.decode("utf-8").split(":") except Exception: log.exception("Failed to get auth token from headers") api_login = token = None diff --git a/frontend/coprs_frontend/coprs/rest_api/schemas.py b/frontend/coprs_frontend/coprs/rest_api/schemas.py index 2144b54..05cc5be 100644 --- a/frontend/coprs_frontend/coprs/rest_api/schemas.py +++ b/frontend/coprs_frontend/coprs/rest_api/schemas.py @@ -3,6 +3,7 @@ from collections import Iterable from marshmallow import Schema, fields from marshmallow import Schema, fields, validates_schema, ValidationError, validate +from six import string_types def validate_any(fn_list): @@ -37,7 +38,7 @@ class SpaceSeparatedList(fields.Field): def _deserialize(self, value): if value is None: return "" - elif not isinstance(value, Iterable) or isinstance(value, basestring): + elif not isinstance(value, Iterable) or isinstance(value, string_types): raise ValidationError("Value `{}` is not a list of strings" .format(value)) else: diff --git a/frontend/coprs_frontend/tests/test_api/test_project_chroot_r.py b/frontend/coprs_frontend/tests/test_api/test_project_chroot_r.py index 054b37f..0562737 100644 --- a/frontend/coprs_frontend/tests/test_api/test_project_chroot_r.py +++ b/frontend/coprs_frontend/tests/test_api/test_project_chroot_r.py @@ -93,7 +93,7 @@ class TestProjectChrootResource(CoprsTestCase): for k, v in data.items(): assert response_data.get(k) == v - assert_content(json.loads(r2.data)["chroot"]) + assert_content(json.loads(r2.data.decode("utf-8"))["chroot"]) # test idempotency self.request_rest_api_with_auth( @@ -103,7 +103,7 @@ class TestProjectChrootResource(CoprsTestCase): ) r3 = self.tc.get("/api_2/projects/1/chroots/{}".format(chroot_name)) assert r3.status_code == 200 - assert_content(json.loads(r3.data)["chroot"]) + assert_content(json.loads(r3.data.decode("utf-8"))["chroot"]) # test put with excessive name field data["name"] = chroot_name diff --git a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py index e34e971..64c6bb2 100644 --- a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py +++ b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py @@ -501,7 +501,7 @@ class TestCoprUpdatePermissions(CoprsTestCase): '<option selected value="2">approved</option>' '</select>' ) - assert check_string not in r.data + assert check_string.encode("utf-8") not in r.data @TransactionDecorator("u2") def test_update_more_permissions(self, f_users, f_coprs,
1
0
0
0
[copr] frontend-python3: [frontend] sort by argument 'key' instead of 'cmp' (6d7747b)
by frostyx@fedoraproject.org
30 Sep '15
30 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : frontend-python3 >--------------------------------------------------------------- commit 6d7747b1f68aa62bc4834a73453c031e026bb1bc Author: Jakub Kadlčík <jkadlcik(a)redhat.com> Date: Tue Sep 29 12:46:13 2015 +0200 [frontend] sort by argument 'key' instead of 'cmp' >--------------------------------------------------------------- .../coprs/views/coprs_ns/coprs_general.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py index bf37527..c6a5d18 100644 --- a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py +++ b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py @@ -453,7 +453,7 @@ def copr_update_permissions(username, coprname): # if admin is changing his permissions, his must be changed last # so that we don't get InsufficientRightsException permissions.sort( - cmp=lambda x, y: -1 if y.user_id == flask.g.user.id else 1) + key=lambda x: -1 if x.user_id == flask.g.user.id else 1) for perm in permissions: old_builder = perm.copr_builder old_admin = perm.copr_admin
1
0
0
0
[copr] frontend-python3: [frontend] more py2/py3 compatibile strings magic (c8822b8)
by frostyx@fedoraproject.org
30 Sep '15
30 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : frontend-python3 >--------------------------------------------------------------- commit c8822b855fb6947d3b095294b8bad34f794a7d44 Author: Jakub Kadlčík <jkadlcik(a)redhat.com> Date: Tue Sep 29 12:29:26 2015 +0200 [frontend] more py2/py3 compatibile strings magic >--------------------------------------------------------------- .../test_views/test_coprs_ns/test_coprs_builds.py | 4 ++-- .../test_views/test_coprs_ns/test_coprs_general.py | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py index 2fa1290..02ef73a 100644 --- a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py +++ b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py @@ -236,7 +236,7 @@ class TestCoprRepeatBuild(CoprsTestCase): assert r.status_code == 200 # no longer using URL #assert self.b_few_chroots.pkgs in r.data - assert b"Resubmit build {}".format(self.b_few_chroots.id) in r.data + assert "Resubmit build {}".format(self.b_few_chroots.id).encode("utf-8") in r.data # TODO: maybe test, that only failed chroots are selected @@ -264,7 +264,7 @@ class TestCoprRepeatBuild(CoprsTestCase): data={}, follow_redirects=True) - assert b"Resubmit build {}".format(self.b1.id) in r.data + assert "Resubmit build {}".format(self.b1.id).encode("utf-8") in r.data assert r.status_code == 200 # assert "Build was resubmitted" in r.data # assert len(self.models.Build.query diff --git a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py index ca0ab85..e34e971 100644 --- a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py +++ b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py @@ -100,7 +100,7 @@ class TestCoprNew(CoprsTestCase): assert self.models.Copr.query.filter( self.models.Copr.name == "foo").first() - assert self.success_string in r.data + assert self.success_string.encode("utf-8") in r.data # make sure no initial build was submitted assert self.models.Build.query.first() is None @@ -124,7 +124,7 @@ class TestCoprNew(CoprsTestCase): assert len(self.models.Copr.query.filter( self.models.Copr.name == self.c1.name).all()) == foocoprs + 1 - assert self.success_string in r.data + assert self.success_string.encode("utf-8") in r.data @TransactionDecorator("u1") def test_copr_new_exists_for_this_user(self, f_users, f_coprs, @@ -159,7 +159,7 @@ class TestCoprNew(CoprsTestCase): copr = self.models.Copr.query.filter( self.models.Copr.name == "foo").first() assert copr - assert self.success_string in r.data + assert self.success_string.encode("utf-8") in r.data assert self.models.Build.query.first().copr == copr assert self.models.Build.query.first().enable_net is True @@ -181,7 +181,7 @@ class TestCoprNew(CoprsTestCase): copr = self.models.Copr.query.filter( self.models.Copr.name == "foo").first() assert copr - assert self.success_string in r.data + assert self.success_string.encode("utf-8") in r.data assert self.models.Build.query.first().copr == copr assert self.models.Build.query.first().enable_net is False @@ -210,7 +210,7 @@ class TestCoprNew(CoprsTestCase): self.c1.name) .filter(self.models.Copr.owner == self.u1) .all()) == 2 - assert self.success_string in r.data + assert self.success_string.encode("utf-8") in r.data class TestCoprDetail(CoprsTestCase): @@ -292,8 +292,8 @@ class TestCoprEdit(CoprsTestCase): # TODO: use some kind of html parsing library to look # for the hidden input, this ties us # to the precise format of the tag - assert (b'<input hidden id="id" name="id" type="hidden" value="{0}">' - .format(self.c1.id) in r.data) + assert ('<input hidden id="id" name="id" type="hidden" value="{0}">' + .format(self.c1.id).encode("utf-8") in r.data) class TestCoprUpdate(CoprsTestCase):
1
0
0
0
[copr] frontend-python3: [frontend] explicitly cast map results to list On python3, the result of a map function is an iterator, not list (df35612)
by frostyx@fedoraproject.org
30 Sep '15
30 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : frontend-python3 >--------------------------------------------------------------- commit df35612db1f517f0f72abf52d721006d3cbd1861 Author: Jakub Kadlčík <jkadlcik(a)redhat.com> Date: Tue Sep 29 12:21:37 2015 +0200 [frontend] explicitly cast map results to list On python3, the result of a map function is an iterator, not list >--------------------------------------------------------------- frontend/coprs_frontend/coprs/forms.py | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/coprs_frontend/coprs/forms.py b/frontend/coprs_frontend/coprs/forms.py index 9e9feda..b42d05a 100644 --- a/frontend/coprs_frontend/coprs/forms.py +++ b/frontend/coprs_frontend/coprs/forms.py @@ -227,10 +227,10 @@ class CoprFormFactory(object): have_any = True return have_any - F.chroots_list = map(lambda x: x.name, + F.chroots_list = list(map(lambda x: x.name, models.MockChroot.query.filter( models.MockChroot.is_active == True - ).all()) + ).all())) F.chroots_list.sort() # sets of chroots according to how we should print them in columns F.chroots_sets = {} @@ -300,7 +300,7 @@ class BuildFormFactory(object): enable_net = wtforms.BooleanField() - F.chroots_list = map(lambda x: x.name, active_chroots) + F.chroots_list = list(map(lambda x: x.name, active_chroots)) F.chroots_list.sort() F.chroots_sets = {} for ch in F.chroots_list: @@ -392,7 +392,7 @@ class BuildFormRebuildFactory(object): enable_net = wtforms.BooleanField() - F.chroots_list = map(lambda x: x.name, active_chroots) + F.chroots_list = list(map(lambda x: x.name, active_chroots)) F.chroots_list.sort() F.chroots_sets = {} for ch in F.chroots_list:
1
0
0
0
[copr] master: [frontend][groups support] fix html (0f03dba)
by vgologuz@fedoraproject.org
30 Sep '15
30 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : master >--------------------------------------------------------------- commit 0f03dba8aabaa9910bd358a5b9da94fda23c4cd9 Author: Valentin Gologuzov <vgologuz(a)redhat.com> Date: Wed Sep 30 11:26:16 2015 +0200 [frontend][groups support] fix html >--------------------------------------------------------------- .../coprs/templates/coprs/detail/overview.html | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/overview.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/overview.html index c4f69e9..d055f0e 100644 --- a/frontend/coprs_frontend/coprs/templates/coprs/detail/overview.html +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/overview.html @@ -169,7 +169,7 @@ <h3 class="panel-title"> Other Actions </h3> </div> <div class="panel-body"> - {% if user.can_edit(copr) and not copr.is_a_group_project %} + {% if user and user.can_edit(copr) and not copr.is_a_group_project %} <a href="{{ url_for('coprs_ns.copr_group_managed', username = copr.owner.name, coprname = copr.name) }}"> Change to a group project </a>
1
0
0
0
[copr] master: [frontend][rhbz: #1266750] Unable to view second, third, ��� page of search results: " Search string must have at least 3 characters " (cf27a99)
by vgologuz@fedoraproject.org
30 Sep '15
30 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : master >--------------------------------------------------------------- commit cf27a994b3885aac31cd2f2f816a0e541bc66fb8 Author: Valentin Gologuzov <vgologuz(a)redhat.com> Date: Wed Sep 30 11:21:27 2015 +0200 [frontend][rhbz: #1266750] Unable to view second, third, … page of search results: " Search string must have at least 3 characters " >--------------------------------------------------------------- frontend/coprs_frontend/coprs/helpers.py | 6 +++++- .../coprs/views/coprs_ns/coprs_general.py | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/coprs_frontend/coprs/helpers.py b/frontend/coprs_frontend/coprs/helpers.py index f3406b4..ef1a504 100644 --- a/frontend/coprs_frontend/coprs/helpers.py +++ b/frontend/coprs_frontend/coprs/helpers.py @@ -110,13 +110,16 @@ class FailTypeEnum(object): class Paginator(object): def __init__(self, query, total_count, page=1, - per_page_override=None, urls_count_override=None): + per_page_override=None, urls_count_override=None, + additional_params=None): self.query = query self.total_count = total_count self.page = page self.per_page = per_page_override or constants.ITEMS_PER_PAGE self.urls_count = urls_count_override or constants.PAGES_URLS_COUNT + self.additional_params = additional_params or dict() + self._sliced_query = None def page_slice(self, page): @@ -155,6 +158,7 @@ class Paginator(object): def url_for_other_page(self, request, page): args = request.view_args.copy() args["page"] = page + args.update(self.additional_params) return flask.url_for(request.endpoint, **args) diff --git a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py index 2891ca8..6c14138 100644 --- a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py +++ b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py @@ -123,7 +123,8 @@ def coprs_fulltext_search(page=1): return flask.redirect(flask.request.referrer or flask.url_for("coprs_ns.coprs_show")) - paginator = helpers.Paginator(query, query.count(), page) + paginator = helpers.Paginator(query, query.count(), page, + additional_params={"fulltext": fulltext}) coprs = paginator.sliced_query return render_template("coprs/show/fulltext.html", coprs=coprs, @@ -358,6 +359,7 @@ def _check_rpmfusion(repos): message = flask.Markup('Using rpmfusion as dependency is nearly always wrong. Please see <a href="
https://fedorahosted.org/copr/wiki/UserDocs#WhatIcanbuildinCopr
">What I can build in Copr</a>.') flask.flash(message, "error") + @coprs_ns.route("/<username>/<coprname>/update/", methods=["POST"]) @login_required def copr_update(username, coprname):
1
0
0
0
[copr] master: [frontend] Support group projects, Work In progress (f990384)
by vgologuz@fedoraproject.org
29 Sep '15
29 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : master >--------------------------------------------------------------- commit f990384a5f964780edb71557007b963713e1e4aa Author: Valentin Gologuzov <vgologuz(a)redhat.com> Date: Tue Sep 29 17:29:19 2015 +0200 [frontend] Support group projects, Work In progress >--------------------------------------------------------------- frontend/coprs_frontend/coprs/forms.py | 14 ++++ frontend/coprs_frontend/coprs/logic/coprs_logic.py | 46 +++++++++++-- frontend/coprs_frontend/coprs/logic/users_logic.py | 33 +++++++++- frontend/coprs_frontend/coprs/models.py | 25 ++++++- frontend/coprs_frontend/coprs/redis_session.py | 1 + .../templates/coprs/detail/make_group_project.html | 35 ++++++++++ .../coprs/templates/coprs/detail/overview.html | 16 +++++ .../coprs/views/coprs_ns/coprs_general.py | 68 ++++++++++++++++++-- frontend/coprs_frontend/coprs/views/misc.py | 2 +- 9 files changed, 221 insertions(+), 19 deletions(-) diff --git a/frontend/coprs_frontend/coprs/forms.py b/frontend/coprs_frontend/coprs/forms.py index 7ffe436..ea8f795 100644 --- a/frontend/coprs_frontend/coprs/forms.py +++ b/frontend/coprs_frontend/coprs/forms.py @@ -506,3 +506,17 @@ class AdminPlaygroundForm(wtf.Form): class AdminPlaygroundSearchForm(wtf.Form): project = wtforms.TextField("Project") + + +def group_managed_form_fabric(available_fas_groups): + """ + :type available_fas_groups: list of str + """ + choices = [(x, x) for x in available_fas_groups] + + class GroupManagedForm(wtf.Form): + + name = wtforms.StringField() + fas_name = wtforms.SelectField(choices=choices) + + return GroupManagedForm() diff --git a/frontend/coprs_frontend/coprs/logic/coprs_logic.py b/frontend/coprs_frontend/coprs/logic/coprs_logic.py index ec56f0a..03ed0a2 100644 --- a/frontend/coprs_frontend/coprs/logic/coprs_logic.py +++ b/frontend/coprs_frontend/coprs/logic/coprs_logic.py @@ -39,6 +39,22 @@ class CoprsLogic(object): return cls.get_all().filter(models.Copr.id == copr_id) @classmethod + def _attach_build(cls, query): + query = (query.outerjoin(models.Copr.builds) + .options(db.contains_eager(models.Copr.builds)) + .order_by(models.Build.submitted_on.desc())) + return query + + @classmethod + def _attach_mock_chroots(cls, query): + query = (query.outerjoin(*models.Copr.mock_chroots.attr) + .options(db.contains_eager(*models.Copr.mock_chroots.attr)) + .order_by(models.MockChroot.os_release.asc()) + .order_by(models.MockChroot.os_version.asc()) + .order_by(models.MockChroot.arch.asc())) + return query + + @classmethod def get(cls, username, coprname, **kwargs): with_builds = kwargs.get("with_builds", False) with_mock_chroots = kwargs.get("with_mock_chroots", False) @@ -50,19 +66,33 @@ class CoprsLogic(object): ) if with_builds: - query = (query.outerjoin(models.Copr.builds) - .options(db.contains_eager(models.Copr.builds)) - .order_by(models.Build.submitted_on.desc())) + query = cls._attach_build(query) + + if with_mock_chroots: + query = cls._attach_mock_chroots(query) + + return query + + @classmethod + def get_by_group_id(cls, group_id, coprname, **kwargs): + with_builds = kwargs.get("with_builds", False) + with_mock_chroots = kwargs.get("with_mock_chroots", False) + + query = ( + cls.get_all() + .filter(models.Copr.group_id == group_id) + .filter(models.Copr.name == coprname) + ) + + if with_builds: + query = cls._attach_build(query) if with_mock_chroots: - query = (query.outerjoin(*models.Copr.mock_chroots.attr) - .options(db.contains_eager(*models.Copr.mock_chroots.attr)) - .order_by(models.MockChroot.os_release.asc()) - .order_by(models.MockChroot.os_version.asc()) - .order_by(models.MockChroot.arch.asc())) + query = cls._attach_mock_chroots(query) return query + @classmethod def get_multiple(cls, include_deleted=False): query = ( diff --git a/frontend/coprs_frontend/coprs/logic/users_logic.py b/frontend/coprs_frontend/coprs/logic/users_logic.py index 3d494e8..68092a4 100644 --- a/frontend/coprs_frontend/coprs/logic/users_logic.py +++ b/frontend/coprs_frontend/coprs/logic/users_logic.py @@ -1,6 +1,7 @@ from coprs import exceptions -from coprs.models import User +from coprs import db +from coprs.models import User, Group class UsersLogic(object): @@ -34,3 +35,33 @@ class UsersLogic(object): if not user.can_build_in(copr): raise exceptions.InsufficientRightsException(message) + + @classmethod + def get_group_by_alias(cls, name): + return Group.query.filter(Group.name == name) + + @classmethod + def get_group_by_fas_name(cls, fas_name): + return Group.query.filter(Group.fas_name == fas_name) + + @classmethod + def create_group_by_fas_name(cls, fas_name, alias=None): + if alias is None: + alias = fas_name + + group = Group( + fas_name=fas_name, + name=alias, + ) + db.session.add(group) + return group + + @classmethod + def get_group_by_fas_name_or_create(cls, fas_name, alias=None): + mb_group = cls.get_group_by_fas_name(fas_name).first() + if mb_group is not None: + return mb_group + + group = cls.create_group_by_fas_name(fas_name, alias) + db.session.flush() + return group diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py index dac42fd..2a6db9b 100644 --- a/frontend/coprs_frontend/coprs/models.py +++ b/frontend/coprs_frontend/coprs/models.py @@ -2,6 +2,7 @@ import copy import datetime import json import os +import flask from sqlalchemy.ext.associationproxy import association_proxy from libravatar import libravatar_url @@ -87,6 +88,11 @@ class User(db.Model, helpers.Serializer): can_build = True + # a bit dirty code, here we access flask.session object + if copr.group is not None and \ + copr.group.fas_name in flask.session.get("teams", []): + return True + return can_build def can_edit(self, copr): @@ -94,16 +100,20 @@ class User(db.Model, helpers.Serializer): Determine if this user can edit the given copr. """ - can_edit = False if copr.owner == self or self.admin: - can_edit = True + return True if (self.permissions_for_copr(copr) and self.permissions_for_copr(copr).copr_admin == helpers.PermissionEnum("approved")): - can_edit = True + return True - return can_edit + # a bit dirty code, here we access flask.session object + if copr.group is not None and \ + copr.group.fas_name in flask.session.get("teams", []): + return True + + return False @property def serializable_attributes(self): @@ -173,6 +183,10 @@ class Copr(db.Model, helpers.Serializer): } @property + def is_a_group_project(self): + return self.group_id is not None + + @property def owner_name(self): return self.owner.name @@ -855,12 +869,15 @@ class CounterStat(db.Model, helpers.Serializer): counter = db.Column(db.Integer, default=0, server_default="0") + class Group(db.Model, helpers.Serializer): """ Represents FAS groups and their aliases in Copr """ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(127)) + + # TODO: add unique=True fas_name = db.Column(db.String(127)) def __str__(self): diff --git a/frontend/coprs_frontend/coprs/redis_session.py b/frontend/coprs_frontend/coprs/redis_session.py index d345777..5ec89b6 100644 --- a/frontend/coprs_frontend/coprs/redis_session.py +++ b/frontend/coprs_frontend/coprs/redis_session.py @@ -54,6 +54,7 @@ class RedisSessionInterface(SessionInterface): return self.session_class(sid=sid, new=True) def save_session(self, app, session, response): + # print("String session: {}".format(session)) domain = self.get_cookie_domain(app) if not session: self.redis.delete(self.prefix + session.sid) diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/make_group_project.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/make_group_project.html new file mode 100644 index 0000000..e1fb714 --- /dev/null +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/make_group_project.html @@ -0,0 +1,35 @@ +{% extends "coprs/detail.html" %} + +{% from "_helpers.html" import render_field, render_form_errors %} + +{% block title %} + Change project {{ copr.owner.name }}/{{ copr.name }} into a group managed one/ + +{% endblock %} +{%block project_breadcrumb %} +{# +<!--<li>--> + <!--<a href="{{ url_for('coprs_ns.copr_builds', username=copr.owner.name, coprname=copr.name) }}">Packages</a>--> +<!--</li>--> +#} +<li class="active"> + +</li> +{%endblock%} + +{% block detail_body %} + <h3> + Select Fas project to bound project + </h3> + <form class="form-horizontal" + action="{{ url_for('coprs_ns.copr_group_managed', username=copr.owner.name, coprname=copr.name) }}" + method="post" enctype="multipart/form-data"> + {{ form.csrf_token }} + + {{ render_field(form.name, label="Group alias to use in the Copr") }} + {{ render_field(form.fas_name) }} + + <input class="btn btn-primary" type="submit" value="Submit"> + </form> + +{% endblock %} diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/overview.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/overview.html index d5254cc..c4f69e9 100644 --- a/frontend/coprs_frontend/coprs/templates/coprs/detail/overview.html +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/overview.html @@ -25,6 +25,13 @@ The following unofficial repositories are provided as-is by owner of this project. Contact the owner directly for bugs or issues (IE: not bugzilla). </p> + + <p> + {% if copr.is_a_group_project %} + This project is managed by FAS group {{ copr.group.fas_name }} + {% endif %} + </p> + <table class="table table-striped table-bordered"> <thead> <tr> @@ -162,9 +169,18 @@ <h3 class="panel-title"> Other Actions </h3> </div> <div class="panel-body"> + {% if user.can_edit(copr) and not copr.is_a_group_project %} + <a href="{{ url_for('coprs_ns.copr_group_managed', username = copr.owner.name, coprname = copr.name) }}"> + Change to a group project + </a> + {% endif %} + + <a href="{{ url_for('coprs_ns.copr_report_abuse', username = copr.owner.name, coprname = copr.name) }}"> <small class="pficon pficon-warning-triangle-o"> Report Abuse </small></a> + </div> + </div> </div> </div> diff --git a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py index 7d90c0b..2891ca8 100644 --- a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py +++ b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py @@ -19,8 +19,10 @@ from coprs import exceptions from coprs import forms from coprs import helpers from coprs import models +from coprs.forms import group_managed_form_fabric from coprs.logic.coprs_logic import CoprsLogic from coprs.logic.stat_logic import CounterStatLogic +from coprs.logic.users_logic import UsersLogic from coprs.rmodels import TimedStatEvents from coprs.logic.complex_logic import ComplexLogic @@ -215,18 +217,40 @@ def copr_report_abuse(username, coprname): form=form) +(a)coprs_ns.route("/g/<groupname>/<coprname>/") +def group_copr_detail(groupname, coprname): + + try: + group = UsersLogic.get_group_by_alias(groupname).one() + except sqlalchemy.orm.exc.NoResultFound: + return page_not_found( + "Group {} does not exist.".format(groupname)) + + try: + copr = CoprsLogic.get_by_group_id(group.id, coprname).one() + except sqlalchemy.orm.exc.NoResultFound: + return page_not_found( + "Project {0} does not exist.".format(coprname)) + + return render_copr_detail(copr) + + @coprs_ns.route("/<username>/<coprname>/") def copr_detail(username, coprname): query = coprs_logic.CoprsLogic.get(username, coprname, with_mock_chroots=True) - form = forms.CoprLegalFlagForm() + try: copr = query.one() except sqlalchemy.orm.exc.NoResultFound: return page_not_found( "Project {0} does not exist.".format(coprname)) - repo_dl_stat = CounterStatLogic.get_copr_repo_dl_stat(copr) + return render_copr_detail(copr) + +def render_copr_detail(copr): + repo_dl_stat = CounterStatLogic.get_copr_repo_dl_stat(copr) + form = forms.CoprLegalFlagForm() repos_info = {} for chroot in copr.active_chroots: # chroot_rpms_dl_stat_key = CHROOT_REPO_MD_DL_STAT_FMT.format( @@ -260,14 +284,12 @@ def copr_detail(username, coprname): else: repos_info[chroot.name_release]["arch_list"].append(chroot.arch) repos_info[chroot.name_release]["rpm_dl_stat"][chroot.arch] = chroot_rpms_dl_stat - repos_info_list = sorted(repos_info.values(), key=lambda rec: rec["name_release"]) - builds = builds_logic.BuildsLogic.get_multiple_by_copr(copr=copr).limit(1).all() - return flask.render_template( "coprs/detail/overview.html", copr=copr, + user=flask.g.user, form=form, repo_dl_stat=repo_dl_stat, repos_info_list=repos_info_list, @@ -706,3 +728,39 @@ def copr_build_monitor_detailed(username, coprname): monitor=monitor, oses=oses_grouped, archs=archs) + + +(a)coprs_ns.route("/<username>/<coprname>/group_managed", methods=["GET", "POST"]) +def copr_group_managed(username, coprname): + try: + copr = coprs_logic.CoprsLogic.get(username, coprname, with_mock_chroots=True).one() + except sqlalchemy.orm.exc.NoResultFound: + return page_not_found( + "Project {0} does not exist.".format(coprname)) + + form = group_managed_form_fabric(flask.session.get("teams")) + + if form.validate_on_submit(): + group = UsersLogic.get_group_by_fas_name_or_create( + form.fas_name.data, form.name.data) + + copr.group_id = group.id + db.session.add(copr) + db.session.commit() + + flask.flash( + "Project is now managed by {} FAS group, " + "main url to the project: {}" + .format( + form.fas_name.data, + "group url todo:" + ) + ) + return flask.redirect(flask.url_for( + "coprs_ns.copr_detail", username=username, coprname=coprname)) + + else: + return flask.render_template( + "coprs/detail/make_group_project.html", + copr=copr, form=form, + ) diff --git a/frontend/coprs_frontend/coprs/views/misc.py b/frontend/coprs_frontend/coprs/views/misc.py index f0eb45c..440f051 100644 --- a/frontend/coprs_frontend/coprs/views/misc.py +++ b/frontend/coprs_frontend/coprs/views/misc.py @@ -149,7 +149,7 @@ def login(): return flask.redirect(oid.get_next_url()) else: # todo: ask puiterwijk to enable "magic" group - team_req = TeamsRequest(["fi-apprentice", "_FAS_ALL_GROUPS_"]) + team_req = TeamsRequest(["fi-apprentice", "packager", "_FAS_ALL_GROUPS_"]) return oid.try_login("
https://id.fedoraproject.org/
", ask_for=["email", "timezone"], extensions=[team_req])
1
0
0
0
[copr] master: minor fix in Vagrantfile (2885f1e)
by asamalik@fedoraproject.org
29 Sep '15
29 Sep '15
Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : master >--------------------------------------------------------------- commit 2885f1e66954d8e3262bf77f42dfdd58cd192178 Author: Adam Samalik <asamalik(a)redhat.com> Date: Tue Sep 29 15:17:00 2015 +0200 minor fix in Vagrantfile >--------------------------------------------------------------- Vagrantfile | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index 52212e1..0adc8b9 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -53,7 +53,8 @@ Vagrant.configure(2) do |config| # .. config.vm.provision "shell", - inline: "sudo systemctl start postgresql" + inline: "sudo systemctl start postgresql", + run: "always" # .. config.vm.provision "shell",
1
0
0
0
← Newer
1
2
3
4
...
12
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
Results per page:
10
25
50
100
200