138
137
PackagePublishingStatus,
140
139
from lp.soyuz.interfaces.archive import (
140
ArchiveDependencyError,
143
143
IArchiveEditDependenciesForm,
146
validate_external_dependencies,
147
148
from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
148
149
from lp.soyuz.interfaces.archivesubscriber import IArchiveSubscriberSet
1357
1358
def do_copy(self, sources_field_name, source_pubs, dest_archive,
1358
1359
dest_series, dest_pocket, include_binaries,
1359
1360
dest_url=None, dest_display_name=None, person=None,
1360
check_permissions=True):
1361
check_permissions=True, force_async=False):
1361
1362
"""Copy packages and add appropriate feedback to the browser page.
1363
1364
This may either copy synchronously, if there are few enough
1381
1382
:param person: The person requesting the copy.
1382
1383
:param: check_permissions: boolean indicating whether or not the
1383
1384
requester's permissions to copy should be checked.
1385
:param force_async: Force the copy to create package copy jobs and
1386
perform the copy asynchronously.
1385
1388
:return: True if the copying worked, False otherwise.
1388
if self.canCopySynchronously(source_pubs):
1391
if (force_async == False and
1392
self.canCopySynchronously(source_pubs)):
1389
1393
notification = copy_synchronously(
1390
1394
source_pubs, dest_archive, dest_series, dest_pocket,
1391
1395
include_binaries, dest_url=dest_url,
1861
1865
self._messages.append(structured(
1862
1866
'<p>Primary dependency added: %s</p>', primary_dependency.title))
1864
def validate(self, data):
1865
"""Validate dependency configuration changes.
1867
Skip checks if no dependency candidate was sent in the form.
1869
Validate if the requested PPA dependency is sane (different than
1870
the context PPA and not yet registered).
1872
Also check if the dependency candidate is private, if so, it can
1873
only be set if the user has 'launchpad.View' permission on it and
1874
the context PPA is also private (this way P3A credentials will be
1875
sanitized from buildlogs).
1877
dependency_candidate = data.get('dependency_candidate')
1879
if dependency_candidate is None:
1882
if dependency_candidate == self.context:
1883
self.setFieldError('dependency_candidate',
1884
"An archive should not depend on itself.")
1887
if self.context.getArchiveDependency(dependency_candidate):
1888
self.setFieldError('dependency_candidate',
1889
"This dependency is already registered.")
1892
if not check_permission('launchpad.View', dependency_candidate):
1894
'dependency_candidate',
1895
"You don't have permission to use this dependency.")
1898
if dependency_candidate.private and not self.context.private:
1900
'dependency_candidate',
1901
"Public PPAs cannot depend on private ones.")
1903
1868
@action(_("Save"), name="save")
1904
1869
def save_action(self, action, data):
1905
1870
"""Save dependency configuration changes.
1911
1876
refreshing. And render a page notification with the summary of the
1914
# Redirect after POST.
1915
self.next_url = self.request.URL
1917
1879
# Process the form.
1918
1880
self._add_primary_dependencies(data)
1919
self._add_ppa_dependencies(data)
1882
self._add_ppa_dependencies(data)
1883
except ArchiveDependencyError as e:
1884
self.setFieldError('dependency_candidate', str(e))
1920
1886
self._remove_dependencies(data)
1922
1888
# Issue a notification if anything was changed.
1923
1889
if len(self.messages) > 0:
1924
1890
self.request.response.addNotification(
1925
1891
structured(self.messages))
1892
# Redirect after POST.
1893
self.next_url = self.request.URL
1928
1896
class ArchiveActivateView(LaunchpadFormView):
2125
2093
# Check the external_dependencies field.
2126
2094
ext_deps = data.get('external_dependencies')
2127
2095
if ext_deps is not None:
2128
errors = self.validate_external_dependencies(ext_deps)
2096
errors = validate_external_dependencies(ext_deps)
2129
2097
if len(errors) != 0:
2130
2098
error_text = "\n".join(errors)
2131
2099
self.setFieldError('external_dependencies', error_text)
2136
2104
'Can only set commericial for private archives.')
2138
def validate_external_dependencies(self, ext_deps):
2139
"""Validate the external_dependencies field.
2141
:param ext_deps: The dependencies form field to check.
2144
# The field can consist of multiple entries separated by
2145
# newlines, so process each in turn.
2146
for dep in ext_deps.splitlines():
2148
deb, url, suite, components = dep.split(" ", 3)
2151
"'%s' is not a complete and valid sources.list entry"
2156
errors.append("%s: Must start with 'deb'" % dep)
2157
url_components = urlparse(url)
2158
if not url_components[0] or not url_components[1]:
2159
errors.append("%s: Invalid URL" % dep)
2164
2107
def owner_is_private_team(self):
2165
2108
"""Is the owner a private team?