当前位置: 首页>>代码示例>>C#>>正文


C# BoardMapping类代码示例

本文整理汇总了C#中BoardMapping的典型用法代码示例。如果您正苦于以下问题:C# BoardMapping类的具体用法?C# BoardMapping怎么用?C# BoardMapping使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


BoardMapping类属于命名空间,在下文中一共展示了BoardMapping类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: CalculateLeanKitCardType

		public static CardType CalculateLeanKitCardType(BoardMapping project, GitHubIssues.Issue issue) 
		{
			// NOTE: GitHub does not use types for issues. It uses labels. 
			// Default labels are: bug, duplicate, enhancement, invalid, question, wont fix
			// of those bug and enhancement are the ones that fit a type the best. 
			// bug could be mapped to bug/issue in LeanKit and enhancement mapped to improvement/feature in LeanKit

			var defaultCardType = project.ValidCardTypes.FirstOrDefault(x => x.IsDefault);

			if (issue != null && issue.Labels != null && issue.Labels.Any()) {
				foreach (var label in issue.Labels) {
					var mappedWorkType = project.Types.FirstOrDefault(x => x.Target.ToLowerInvariant() == label.Name.ToLowerInvariant());
					if (mappedWorkType != null) {
						var definedVal = project.ValidCardTypes.FirstOrDefault(x => x.Name.ToLowerInvariant() == mappedWorkType.LeanKit.ToLowerInvariant());
						if (definedVal != null) {
							return definedVal;
						}
					}
					var implicitVal = project.ValidCardTypes.FirstOrDefault(x => x.Name.ToLowerInvariant() == label.Name.ToLowerInvariant());
					if (implicitVal != null) {
						return implicitVal;
					}
				}
			}
			return defaultCardType;
		}
开发者ID:clickless,项目名称:LeanKit.IntegrationService,代码行数:26,代码来源:ConversionExtensions.cs

示例2: CalculateLeanKitCardType

		public static CardType CalculateLeanKitCardType(BoardMapping project, string issueTypeName) 
		{
			if (string.IsNullOrEmpty(issueTypeName)) return project.ValidCardTypes.FirstOrDefault(x => x.IsDefault);

			var mappedWorkType = project.Types.FirstOrDefault(x => x.Target.Equals(issueTypeName, StringComparison.InvariantCultureIgnoreCase));
			if (mappedWorkType != null) 
			{
				var definedVal = project.ValidCardTypes.FirstOrDefault(x => x.Name.Equals(mappedWorkType.LeanKit, StringComparison.InvariantCultureIgnoreCase));
				if (definedVal != null)  return definedVal;
			}
			var implicitVal = project.ValidCardTypes.FirstOrDefault(x => x.Name.Equals(issueTypeName, StringComparison.InvariantCultureIgnoreCase));
			return implicitVal ?? project.ValidCardTypes.FirstOrDefault(x => x.IsDefault);
		}
开发者ID:JanKinable,项目名称:LeanKit.IntegrationService,代码行数:13,代码来源:ConversionExtensions.cs

示例3: WorkItemUpdated

        private void WorkItemUpdated(WorkItem workItem, Card card, BoardMapping project)
        {
            Log.Info("WorkItem [{0}] updated, comparing to corresponding card...", workItem.Id);

	        var boardId = project.Identity.LeanKit;

            // sync and save those items that are different (of title, description, priority)
            var saveCard = false;
            if (workItem.Title != card.Title)
            {
                card.Title = workItem.Title;
                saveCard = true;
            }

            var description = workItem.LeanKitDescription(GetTfsVersion());
            if (description != card.Description)
            {
                card.Description = description;
                saveCard = true;
            }

            var priority = workItem.LeanKitPriority();
            if(priority!= card.Priority)
            {
                card.Priority = priority;
                saveCard = true;
            }
            
            if(workItem.Fields!=null && 
				workItem.Fields.Contains("Tags") && 
				workItem.Fields["Tags"] != null && 
				workItem.Fields["Tags"].Value.ToString() != card.Tags)
            {
	            var tfsTags = workItem.Fields["Tags"].Value.ToString();
				// since we cannot set the tags in TFS we cannot blindly overwrite the LK tags 
				// with what is in TFS. Instead we can only add TFS tags to LK
				if (!string.IsNullOrEmpty(tfsTags))
				{
					var tfsTagsArr = tfsTags.Contains(',') ? tfsTags.Split(',') : tfsTags.Split(';');
					foreach (var tag in tfsTagsArr)
					{
						if (card.Tags != null && card.Tags.ToLowerInvariant().Contains(tag.ToLowerInvariant())) continue;
						if (string.IsNullOrEmpty(card.Tags))
							card.Tags = tag;
						else
							card.Tags += "," + tag;
						saveCard = true;
					}
				}
            }

			if (workItem.Fields != null && (workItem.Fields.Contains("Original Estimate") || workItem.Fields.Contains("Story Points"))) 
			{
				if (workItem.Fields.Contains("Original Estimate") && workItem.Fields["Original Estimate"] != null && workItem.Fields["Original Estimate"].Value != null) 
				{
					double cardSize;
					var isNumber = Double.TryParse(workItem.Fields["Original Estimate"].Value.ToString(), out cardSize);
					if (isNumber)
					{
						var size = (int) cardSize;
						if (card.Size != size)
						{
							card.Size = size;
							saveCard = true;
						}
					}
				} 
				else if (workItem.Fields.Contains("Story Points") && workItem.Fields["Story Points"] != null && workItem.Fields["Story Points"].Value != null) 
				{
					double cardSize;
					var isNumber = Double.TryParse(workItem.Fields["Story Points"].Value.ToString(), out cardSize);
					if (isNumber)
					{
						var size = (int)cardSize;
						if (card.Size != size) 
						{
							card.Size = size;
							saveCard = true;
						}
					}
				}
			}

			if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName) 
			{
				if (string.IsNullOrEmpty(card.Tags))
					card.Tags = ServiceName;
				else
					card.Tags += "," + ServiceName;
				saveCard = true;
			}

            if(saveCard)
            {
                Log.Info("Updating card [{0}]", card.Id);
                LeanKit.UpdateCard(boardId, card);
            }

			// check the state of the work item
			// if we have the state mapped to a lane then check to see if the card is in that lane
//.........这里部分代码省略.........
开发者ID:ERPDevelopment,项目名称:LeanKit.IntegrationService,代码行数:101,代码来源:Tfs.cs

示例4: CreateCardFromItem

		private void CreateCardFromItem(BoardMapping project, Issue issue)
		{
			if (issue == null) return;

			var boardId = project.Identity.LeanKit;

			var mappedCardType = issue.LeanKitCardType(project);

			var validLanes = project.LanesFromState(issue.Fields.Status.Name);
			var laneId = validLanes.Any() ? validLanes.First() : project.DefaultCardCreationLaneId;

			var card = new Card
			{
				Active = true,
				Title = issue.Fields.Summary,
				Description = issue.Fields.Description.SanitizeCardDescription().JiraPlainTextToLeanKitHtml(),
				Priority = issue.LeanKitPriority(),
				TypeId = mappedCardType.Id,
				TypeName = mappedCardType.Name,
				LaneId = laneId,
				ExternalCardID = issue.Key,
				ExternalSystemName = ServiceName,
				ExternalSystemUrl = string.Format(_externalUrlTemplate, issue.Key)
			};

			var assignedUserId = issue.LeanKitAssignedUserId(boardId, LeanKit);
			if (assignedUserId != null)
				card.AssignedUserIds = new[] {assignedUserId.Value};

			if (issue.Fields != null && issue.Fields.DueDate != null && CurrentUser != null)
			{
				var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy";
				card.DueDate = issue.Fields.DueDate.Value.ToString(dateFormat, CultureInfo.InvariantCulture);
			}

			if (issue.Fields != null && issue.Fields.Labels != null && issue.Fields.Labels.Any())
			{
				card.Tags = string.Join(",", issue.Fields.Labels);
			}

			if ((card.Tags == null || !card.Tags.Contains(ServiceName)) && project.TagCardsWithTargetSystemName)
			{
				if (string.IsNullOrEmpty(card.Tags))
					card.Tags = ServiceName;
				else
					card.Tags += "," + ServiceName;
			}

			// TODO: Add size from the custom story points field.

			Log.Info("Creating a card of type [{0}] for issue [{1}] on Board [{2}] on Lane [{3}]", mappedCardType.Name,
				issue.Key, boardId, laneId);

			CardAddResult cardAddResult = null;

			int tries = 0;
			bool success = false;
			while (tries < 10 && !success)
			{
				if (tries > 0)
				{
					Log.Error(string.Format("Attempting to create card for work item [{0}] attempt number [{1}]",
						issue.Key, tries));
					// wait 5 seconds before trying again
					Thread.Sleep(new TimeSpan(0, 0, 5));
				}

				try
				{
					cardAddResult = LeanKit.AddCard(boardId, card, "New Card From Jira Issue");
					success = true;
				}
				catch (Exception ex)
				{
					Log.Error(string.Format("An error occurred: {0} - {1} - {2}", ex.GetType(), ex.Message,
						ex.StackTrace));
				}
				tries++;
			}
			card.Id = cardAddResult.CardId;

			Log.Info("Created a card [{0}] of type [{1}] for work item [{2}] on Board [{3}] on Lane [{4}]", card.Id,
				mappedCardType.Name, issue.Key, boardId, laneId);
		}
开发者ID:clickless,项目名称:LeanKit.IntegrationService,代码行数:84,代码来源:JiraSubsystem.cs

示例5: LeanKitCardType

 public static CardType LeanKitCardType(this Jira.Issue issue, BoardMapping project)
 {
     return CalculateLeanKitCardType(project, issue.Fields.IssueType.Name);
 }
开发者ID:JanKinable,项目名称:LeanKit.IntegrationService,代码行数:4,代码来源:ConversionExtensions.cs

示例6: Synchronize

	    protected abstract void Synchronize(BoardMapping boardMapping);
开发者ID:ERPDevelopment,项目名称:LeanKit.IntegrationService,代码行数:1,代码来源:TargetBase.cs

示例7: CardUpdated

 protected abstract void CardUpdated(Card card, List<string> updatedItems, BoardMapping boardMapping);
开发者ID:ERPDevelopment,项目名称:LeanKit.IntegrationService,代码行数:1,代码来源:TargetBase.cs

示例8: CheckForMissedCardMoves

	    private void CheckForMissedCardMoves(BoardMapping mapping)
	    {
			if (!mapping.UpdateTargetItems)
			{
				Log.Info("Skipped check for missed card moves because 'UpdateTargetItems' is disabled.");
				return;
			}

			// if we have local storage, we have saved board versions and we have one for this board			
			var boardId = mapping.Identity.LeanKit;
		    if (AppSettings == null || AppSettings.BoardVersions == null || !AppSettings.BoardVersions.Any() ||
		        !AppSettings.BoardVersions.ContainsKey(boardId)) return;

		    var version = AppSettings.BoardVersions[boardId];
		    Log.Debug(string.Format("Checking for any cards moved to mapped lanes on board [{0}] since service last ran, version [{1}].", boardId, version));
		    try
		    {
			    var events = LeanKit.GetBoardHistorySince(boardId, version);
			    var board = LeanKit.GetBoard(boardId);
			    if (board == null || events == null) return;

			    foreach (var ev in events)
			    {
				    // check for created cards
				    if (ev.EventType == "CardCreation")
				    {
					    var card = LeanKit.GetCard(board.Id, ev.CardId);
					    if (card != null && string.IsNullOrEmpty(card.ExternalCardID))
					    {
						    try
						    {
							    CreateNewItem(card.ToCard(), mapping);
						    }
						    catch (Exception e)
						    {
							    Log.Error("Exception for CreateNewItem: " + e.Message);
						    }
					    }
				    }
				    // only look for moved cards
				    else if (ev.ToLaneId != 0)
				    {
					    var lane = board.GetLaneById(ev.ToLaneId);
					    if (lane != null)
					    {
						    if (lane.Id.HasValue && mapping.LaneToStatesMap.Any() && mapping.LaneToStatesMap.ContainsKey(lane.Id.Value))
						    {
							    if (mapping.LaneToStatesMap[lane.Id.Value] != null && mapping.LaneToStatesMap[lane.Id.Value].Count > 0)
							    {
								    // board.GetCard() only seems to get cards in active lanes
								    // using LeanKitApi.GetCard() instead because it will get 
								    // cards in archive lanes
								    var card = LeanKit.GetCard(board.Id, ev.CardId);
								    if (card != null && !string.IsNullOrEmpty(card.ExternalCardID))
								    {
									    try {
										    UpdateStateOfExternalItem(card.ToCard(), mapping.LaneToStatesMap[lane.Id.Value], mapping);
									    } catch (Exception e) {
										    Log.Error("Exception for UpdateStateOfExternalItem: " + e.Message);
									    }
								    }
							    }
						    }
					    }
				    }					    
			    }
			    UpdateBoardVersion(board.Id, board.Version);
		    }
		    catch (Exception ex)
		    {
			    Log.Error(string.Format("An error occured: {0} - {1} - {2}", ex.GetType(), ex.Message, ex.StackTrace));
		    }
	    }
开发者ID:ERPDevelopment,项目名称:LeanKit.IntegrationService,代码行数:73,代码来源:TargetBase.cs

示例9: GetTfsWorkItemType

		private Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemType GetTfsWorkItemType(BoardMapping boardMapping, WorkItemTypeCollection workItemTypes, long cardTypeId)
		{			
			if (boardMapping != null && 
				boardMapping.Types != null && 
				boardMapping.ValidCardTypes != null && 
				boardMapping.Types.Any() && 
				boardMapping.ValidCardTypes.Any() )
			{				
				var lkType = boardMapping.ValidCardTypes.FirstOrDefault(x => x.Id == cardTypeId);
				if (lkType != null)
				{
					// first check for mapped type
					var mappedType = boardMapping.Types.FirstOrDefault(x => x.LeanKit.ToLowerInvariant() == lkType.Name.ToLowerInvariant());
					if (mappedType != null) 
					{
						if (workItemTypes.Contains(mappedType.Target))
							return workItemTypes[mappedType.Target];
					}
					// now check for implicit type
					if (workItemTypes.Contains(lkType.Name))
						return workItemTypes[lkType.Name];
				}

			}
			// else just return the first type from list of types from TFS
			return workItemTypes[0];
		}
开发者ID:ERPDevelopment,项目名称:LeanKit.IntegrationService,代码行数:27,代码来源:Tfs.cs

示例10: TestUpdateStateOfExternalItem

			public void TestUpdateStateOfExternalItem(Card card, List<string> laneStateMap, BoardMapping boardConfig)
			{
				base.UpdateStateOfExternalItem(card, laneStateMap, boardConfig, true);
			}
开发者ID:clickless,项目名称:LeanKit.IntegrationService,代码行数:4,代码来源:GitHubPullsSpec.cs

示例11: TestCardUpdated

			public void TestCardUpdated(Card card, List<string> updatedItems, BoardMapping boardMapping)
			{
				base.CardUpdated(card, updatedItems, boardMapping);
			}
开发者ID:clickless,项目名称:LeanKit.IntegrationService,代码行数:4,代码来源:GitHubPullsSpec.cs

示例12: OnStartFixture

		protected override void OnStartFixture()
		{
			_testBoard = Test<Board>.Item;
			int ctr = 0;
			foreach (var boardUser in _testBoard.BoardUsers)
			{
				if (ctr == 0)
				{
					boardUser.UserName = "jcash";
					boardUser.FullName = "Johnny Cash";
					boardUser.EmailAddress = "[email protected]";
					boardUser.Id = 101;
				}
				ctr++;
			}
			_mapping = Test<BoardMapping>.Item;
			_mapping.Identity.LeanKit = _testBoard.Id;
			TestConfig = Test<Configuration>.Item;
			TestConfig.Mappings = new List<BoardMapping> {_mapping};
		}
开发者ID:clickless,项目名称:LeanKit.IntegrationService,代码行数:20,代码来源:GitHubPullsSpec.cs

示例13: OnStartFixture

		protected override void OnStartFixture() 
		{
			_testBoard = Test<Board>.Item;
			foreach (var cardType in _testBoard.CardTypes)
				cardType.IsDefault = false;
			_testBoard.CardTypes.Add(new CardType() { Id = 999, Name = "Willy", IsDefault = false });
			_testBoard.CardTypes.Last().IsDefault = true;
			_mapping = Test<BoardMapping>.Item;
			_mapping.Identity.LeanKit = _testBoard.Id;
			_mapping.Types = new List<WorkItemType>() { new WorkItemType() { LeanKit = "Willy", Target = "Roger"}};
			TestConfig = Test<Configuration>.Item;
			TestConfig.Mappings = new List<BoardMapping> { _mapping };
		}
开发者ID:JanKinable,项目名称:LeanKit.IntegrationService,代码行数:13,代码来源:UnfuddleSpec.cs

示例14: CreateNewItem

		protected override void CreateNewItem(Card card, BoardMapping boardMapping)
		{
			var jiraIssueType = GetJiraIssueType(boardMapping, card.TypeId);

			string json = "{ \"fields\": { ";
			json += "\"project\":  { \"key\": \"" + boardMapping.Identity.Target + "\" }";
			json += ", \"summary\": \"" + card.Title.Replace("\"", "\\\"") + "\" ";
			json += ", \"description\": \"" + card.Description.LeanKitHtmlToJiraPlainText() + "\" ";
			json += ", \"issuetype\": { \"name\": \"" + jiraIssueType + "\" }";
			json += ", \"priority\": { \"name\": \"" + GetPriority(card.Priority) + "\" }";

			if (jiraIssueType.ToLowerInvariant() == "epic")
			{
				if (CustomFields.Any())
				{
					var epicNameField = CustomFields.FirstOrDefault(x => x.Name == "Epic Name");
					if (epicNameField != null)
					{
						json += ", \"" + epicNameField.Id + "\": \"" + card.Title.Replace("\"", "\\\"") + "\"";
					}
				}
			}

			if (!string.IsNullOrEmpty(card.DueDate) && CurrentUser != null)
			{
				try
				{
					var dateFormat = CurrentUser.DateFormat ?? "MM/dd/yyyy";
					var parsed = DateTime.ParseExact(card.DueDate, dateFormat, CultureInfo.InvariantCulture);

					json += ", \"duedate\": \"" + parsed.ToString("o") + "\"";
				}
				catch (Exception ex)
				{
					Log.Warn(ex, "Could not parse due date: {0}", card.DueDate);
				}
			}

			if (!string.IsNullOrEmpty(card.Tags))
			{
				var newLabels = card.Tags.Split(',');
				string updateLabels = "";
				int ctr = 0;
				foreach (string newLabel in newLabels)
				{
					if (ctr > 0)
						updateLabels += ", ";

					updateLabels += "\"" + newLabel.Trim() + "\"";

					ctr++;
				}
				json += ", \"labels\": [" + updateLabels + "]";
			}

			json += "}}";

			Issue newIssue = null;
			try
			{
				//https://yoursite.atlassian.net/rest/api/latest/issue
				var createRequest = CreateRequest("rest/api/latest/issue", Method.POST);
				createRequest.AddParameter("application/json", json, ParameterType.RequestBody);
				var resp = ExecuteRequest(createRequest);

				if (resp.StatusCode != HttpStatusCode.OK && resp.StatusCode != HttpStatusCode.Created)
				{
					Log.Error(string.Format("Unable to create Issue from card [{0}], Description: {1}, Message: {2}",
						card.ExternalCardID, resp.StatusDescription, resp.Content));
				}
				else
				{
					newIssue = new JsonSerializer<Issue>().DeserializeFromString(resp.Content);
					Log.Debug(String.Format("Created Issue [{0}]", newIssue.Key));
				}
			}
			catch (Exception ex)
			{
				Log.Error(string.Format("Unable to create Issue from Card [{0}], Exception: {1}", card.ExternalCardID,
					ex.Message));
			}

			if (newIssue != null)
			{
				try
				{
					card.ExternalCardID = newIssue.Key;
					card.ExternalSystemName = ServiceName;
					card.ExternalSystemUrl = string.Format(_externalUrlTemplate, newIssue.Key);

					// now that we've created the work item let's try to set it to any matching state defined by lane
					var states = boardMapping.LaneToStatesMap[card.LaneId];
					if (states != null)
					{
						UpdateStateOfExternalItem(card, states, boardMapping, true);
					}

					LeanKit.UpdateCard(boardMapping.Identity.LeanKit, card);
				}
				catch (Exception ex)
//.........这里部分代码省略.........
开发者ID:clickless,项目名称:LeanKit.IntegrationService,代码行数:101,代码来源:JiraSubsystem.cs

示例15: UpdateStateOfExternalItem

		protected void UpdateStateOfExternalItem(Card card, List<string> states, BoardMapping mapping, bool runOnlyOnce)
		{
			if (string.IsNullOrEmpty(card.ExternalSystemName) ||
			    !card.ExternalSystemName.Equals(ServiceName, StringComparison.OrdinalIgnoreCase))
				return;

			if (string.IsNullOrEmpty(card.ExternalCardID))
			{
				Log.Debug("Ignoring card [{0}] with missing external id value.", card.Id);
				return;
			}


			if (states == null || states.Count == 0)
				return;

			int tries = 0;
			bool success = false;
			while (tries < 10 && !success && (!runOnlyOnce || tries == 0))
			{
				if (tries > 0)
				{
					Log.Warn(string.Format("Attempting to update external work item [{0}] attempt number [{1}]",
						card.ExternalCardID,
						tries));
					// wait 5 seconds before trying again
					Thread.Sleep(new TimeSpan(0, 0, 5));
				}

				//https://yoursite.atlassian.net/rest/api/latest/issue/{issueIdOrKey}
				var request = CreateRequest(string.Format("rest/api/latest/issue/{0}", card.ExternalCardID), Method.GET);
				var jiraResp = ExecuteRequest(request);

				if (jiraResp.StatusCode != HttpStatusCode.OK)
				{
					var serializer = new JsonSerializer<ErrorMessage>();
					var errorMessage = serializer.DeserializeFromString(jiraResp.Content);
					Log.Error(
						string.Format(
							"Unable to get issues from Jira, Error: {0}. Check your board/repo mapping configuration.",
							errorMessage.Message));
				}
				else
				{
					var issueToUpdate = new JsonSerializer<Issue>().DeserializeFromString(jiraResp.Content);

					// Check for a workflow mapping to the closed state
					if (states != null && states.Count > 0 && states[0].Contains(">"))
					{
						var workflowStates = states[0].Split('>');

						// check to see if the workitem is already in one of the workflow states
						var alreadyInState =
							workflowStates.FirstOrDefault(
								x => x.Trim().ToLowerInvariant() == issueToUpdate.Fields.Status.Name.ToLowerInvariant());
						if (!string.IsNullOrEmpty(alreadyInState))
						{
							// change workflowStates to only use the states after the currently set state
							var currentIndex = Array.IndexOf(workflowStates, alreadyInState);
							if (currentIndex < workflowStates.Length - 1)
							{
								var updatedWorkflowStates = new List<string>();
								for (int i = currentIndex + 1; i < workflowStates.Length; i++)
								{
									updatedWorkflowStates.Add(workflowStates[i]);
								}
								workflowStates = updatedWorkflowStates.ToArray();
							}
						}
						if (workflowStates.Length > 0)
						{
							foreach (string workflowState in workflowStates)
							{
								UpdateStateOfExternalItem(card, new List<string> {workflowState.Trim()}, mapping,
									runOnlyOnce);
							}
							return;
						}
					}

					foreach (var state in states)
					{
						if (issueToUpdate.Fields.Status.Name.ToLowerInvariant() == state.ToLowerInvariant())
						{
							Log.Debug(string.Format("Issue [{0}] is already in state [{1}]", issueToUpdate.Key, state));
							return;
						}
					}

					try
					{
						// first get a list of available transitions
						var transitionsRequest =
							CreateRequest(
								string.Format("rest/api/2/issue/{0}/transitions?expand=transitions.fields",
									card.ExternalCardID), Method.GET);
						var transitionsResponse = ExecuteRequest(transitionsRequest);

						if (transitionsResponse.StatusCode != HttpStatusCode.OK)
						{
//.........这里部分代码省略.........
开发者ID:clickless,项目名称:LeanKit.IntegrationService,代码行数:101,代码来源:JiraSubsystem.cs


注:本文中的BoardMapping类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。