OLD | NEW |
(Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is govered by a BSD-style |
| 3 # license that can be found in the LICENSE file or at |
| 4 # https://developers.google.com/open-source/licenses/bsd |
| 5 |
| 6 """Protocol buffers for Monorail projects.""" |
| 7 |
| 8 from protorpc import messages |
| 9 |
| 10 # Project state affects permissions in that project, and project deletion. |
| 11 # It is edited on the project admin page. If it is anything other that LIVE |
| 12 # it triggers a notice at the top of every project page. |
| 13 # For more info, see the "Project deletion in Monorail" design doc. |
| 14 class ProjectState(messages.Enum): |
| 15 """Enum for states in the project lifecycle.""" |
| 16 # Project is visible and indexed. This is the typical state. |
| 17 # |
| 18 # If moved_to is set, this project is live but has been moved |
| 19 # to another location, so redirects will be used or links shown. |
| 20 LIVE = 1 |
| 21 |
| 22 # Project owner has requested the project be archived. Project is |
| 23 # read-only to members only, off-limits to non-members. Issues |
| 24 # can be searched when in the project, but should not appear in |
| 25 # site-wide searches. The project name is still in-use by this |
| 26 # project. |
| 27 # |
| 28 # If a delete_time is set, then the project is doomed: (1) the |
| 29 # state can only be changed by a site admin, and (2) the project |
| 30 # will automatically transition to DELETABLE after that time is |
| 31 # reached. |
| 32 ARCHIVED = 2 |
| 33 |
| 34 # Project can be deleted at any time. The project name should |
| 35 # have already been changed to a generated string, so it's |
| 36 # impossible to navigate to this project, and the original name |
| 37 # can be reused by a new project. |
| 38 DELETABLE = 3 |
| 39 |
| 40 |
| 41 # Project access affects permissions in that project. |
| 42 # It is edited on the project admin page. |
| 43 class ProjectAccess(messages.Enum): |
| 44 """Enum for possible project access levels.""" |
| 45 # Anyone may view this project, even anonymous users. |
| 46 ANYONE = 1 |
| 47 |
| 48 # Only project members may view the project. |
| 49 MEMBERS_ONLY = 3 |
| 50 |
| 51 |
| 52 # A Project PB represents a project in Monorail, which is a workspace for |
| 53 # project members to collaborate on issues. |
| 54 # A project is created on the project creation page, searched on the project |
| 55 # list page, and edited on the project admin page. |
| 56 class Project(messages.Message): |
| 57 """This protocol buffer holds all the metadata associated with a project.""" |
| 58 state = messages.EnumField(ProjectState, 1, required=True) |
| 59 access = messages.EnumField(ProjectAccess, 18, default=ProjectAccess.ANYONE) |
| 60 |
| 61 # The short identifier for this project. This value is lower-cased, |
| 62 # and must be between 3 and 20 characters (inclusive). Alphanumeric |
| 63 # and dashes are allowed, and it must start with an alpha character. |
| 64 # Project names must be unique. |
| 65 project_name = messages.StringField(2, required=True) |
| 66 |
| 67 # A numeric identifier for this project. |
| 68 project_id = messages.IntegerField(3, required=True) |
| 69 |
| 70 # A one-line summary (human-readable) name of the project. |
| 71 summary = messages.StringField(4, default='') |
| 72 |
| 73 # A detailed description of the project. |
| 74 description = messages.StringField(5, default='') |
| 75 |
| 76 # Description of why this project has the state set as it is. |
| 77 # This is used for administrative purposes to notify Owners that we |
| 78 # are going to delete their project unless they can provide a good |
| 79 # reason to not do so. |
| 80 state_reason = messages.StringField(9) |
| 81 |
| 82 # Time (in seconds) at which an ARCHIVED project may automatically |
| 83 # be changed to state DELETABLE. The state change is done by a |
| 84 # cron job. |
| 85 delete_time = messages.IntegerField(10) |
| 86 |
| 87 # Note that these lists are disjoint (a user ID will not appear twice). |
| 88 owner_ids = messages.IntegerField(11, repeated=True) |
| 89 committer_ids = messages.IntegerField(12, repeated=True) |
| 90 contributor_ids = messages.IntegerField(15, repeated=True) |
| 91 |
| 92 class ExtraPerms(messages.Message): |
| 93 """Nested message for each member's extra permissions in a project.""" |
| 94 member_id = messages.IntegerField(1, required=True) |
| 95 # Each custom perm is a single word [a-zA-Z0-9]. |
| 96 perms = messages.StringField(2, repeated=True) |
| 97 |
| 98 extra_perms = messages.MessageField(ExtraPerms, 16, repeated=True) |
| 99 |
| 100 # Project owners may choose to have ALL issue change notifications go to a |
| 101 # mailing list (in addition to going directly to the users interested |
| 102 # in that issue). |
| 103 issue_notify_address = messages.StringField(14) |
| 104 |
| 105 # These fields keep track of the cumulative size of all issue attachments |
| 106 # in a given project. Normally, the number of bytes used is compared |
| 107 # to a constant defined in the web application. However, if a custom |
| 108 # quota is specified here, it will be used instead. An issue attachment |
| 109 # will fail if its size would put the project over its quota. Not all |
| 110 # projects have these fields: they are only set when the first attachment |
| 111 # is uploaded. |
| 112 attachment_bytes_used = messages.IntegerField(38, default=0) |
| 113 # If quota is not set, default from tracker_constants.py is used. |
| 114 attachment_quota = messages.IntegerField(39) |
| 115 |
| 116 # NOTE: open slots 40, 41 |
| 117 |
| 118 # Recent_activity is a timestamp (in seconds since the Epoch) of the |
| 119 # last time that an issue was entered, updated, or commented on. |
| 120 recent_activity = messages.IntegerField(42, default=0) |
| 121 |
| 122 # NOTE: open slots 43... |
| 123 |
| 124 # Timestamp (in seconds since the Epoch) of the most recent change |
| 125 # to this project that would invalidate cached content. It is set |
| 126 # whenever project membership is edited, or any component config PB |
| 127 # is edited. HTTP requests for auto-complete feeds include this |
| 128 # value in the URL. |
| 129 cached_content_timestamp = messages.IntegerField(53, default=0) |
| 130 |
| 131 # If set, this project has been moved elsewhere. This can |
| 132 # be an absolute URL, the name of another project on the same site. |
| 133 moved_to = messages.StringField(60) |
| 134 |
| 135 # Enable inbound email processing for issues. |
| 136 process_inbound_email = messages.BooleanField(63, default=False) |
| 137 |
| 138 # Limit removal of Restrict-* labels to project owners. |
| 139 only_owners_remove_restrictions = messages.BooleanField(64, default=False) |
| 140 |
| 141 # A per-project read-only lock. This lock (1) is meant to be |
| 142 # long-lived (lasting as long as migration operations, project |
| 143 # deletion, or anything else might take and (2) is meant to only |
| 144 # limit user mutations; whether or not it limits automated actions |
| 145 # that would change project data (such as workflow items) is |
| 146 # determined based on the action. |
| 147 # |
| 148 # This lock is implemented as a user-visible string describing the |
| 149 # reason for the project being in a read-only state. An absent or empty |
| 150 # value indicates that the project is read-write; a present and |
| 151 # non-empty value indicates that the project is read-only for the |
| 152 # reason described. |
| 153 read_only_reason = messages.StringField(65) |
| 154 |
| 155 # This option is rarely used, but it makes sense for projects that aim for |
| 156 # hub-and-spoke collaboration bewtween a vendor organization (like Google) |
| 157 # and representatives of partner companies who are not supposed to know |
| 158 # about each other. |
| 159 # When true, it prevents project committers, contributors, and visitors |
| 160 # from seeing the list of project members on the project summary page, |
| 161 # on the People list page, and in autocomplete for issue owner and Cc. |
| 162 # Project owners can always see the complete list of project members. |
| 163 only_owners_see_contributors = messages.BooleanField(66, default=False) |
| 164 |
| 165 # This configures the URLs generated when autolinking revision numbers. |
| 166 # E.g., gitiles, viewvc, or crrev.com. |
| 167 revision_url_format = messages.StringField(67) |
| 168 |
| 169 # The home page of the Project. |
| 170 home_page = messages.StringField(68) |
| 171 # The url to redirect to for wiki/documentation links. |
| 172 docs_url = messages.StringField(71) |
| 173 # The GCS object ID of the Project's logo. |
| 174 logo_gcs_id = messages.StringField(69) |
| 175 # The uploaded file name of the Project's logo. |
| 176 logo_file_name = messages.StringField(70) |
| 177 |
| 178 |
| 179 # This PB documents some of the duties of some of the members |
| 180 # in a given project. This info is displayed on the project People page. |
| 181 class ProjectCommitments(messages.Message): |
| 182 project_id = messages.IntegerField(50) |
| 183 |
| 184 # TODO(agable): Does it still make sense to call it a 'Commitment' when |
| 185 # it doesn't contain duties anymore? |
| 186 class MemberCommitment(messages.Message): |
| 187 member_id = messages.IntegerField(11, required=True) |
| 188 notes = messages.StringField(13) |
| 189 |
| 190 commitments = messages.MessageField(MemberCommitment, 2, repeated=True) |
| 191 |
| 192 |
| 193 def MakeProject( |
| 194 project_name, project_id=None, state=ProjectState.LIVE, |
| 195 access=ProjectAccess.ANYONE, summary=None, description=None, |
| 196 moved_to=None, cached_content_timestamp=None, |
| 197 owner_ids=None, committer_ids=None, contributor_ids=None, |
| 198 read_only=None, home_page=None, docs_url=None, |
| 199 logo_gcs_id=None, logo_file_name=None): |
| 200 """Returns a project protocol buffer with the given attributes.""" |
| 201 project = Project( |
| 202 project_name=project_name, access=access, state=state) |
| 203 if project_id: |
| 204 project.project_id = project_id |
| 205 if moved_to: |
| 206 project.moved_to = moved_to |
| 207 if cached_content_timestamp: |
| 208 project.cached_content_timestamp = cached_content_timestamp |
| 209 if summary: |
| 210 project.summary = summary |
| 211 if description: |
| 212 project.description = description |
| 213 if home_page: |
| 214 project.home_page = home_page |
| 215 if docs_url: |
| 216 project.docs_url = docs_url |
| 217 if logo_gcs_id: |
| 218 project.logo_gcs_id = logo_gcs_id |
| 219 if logo_file_name: |
| 220 project.logo_file_name = logo_file_name |
| 221 |
| 222 project.owner_ids.extend(owner_ids or []) |
| 223 project.committer_ids.extend(committer_ids or []) |
| 224 project.contributor_ids.extend(contributor_ids or []) |
| 225 |
| 226 if read_only is not None: |
| 227 project.read_only = read_only |
| 228 |
| 229 return project |
OLD | NEW |