chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package checker
|
||||
|
||||
import (
|
||||
"github.com/apache/answer/internal/base/constant"
|
||||
"github.com/apache/answer/pkg/obj"
|
||||
"github.com/apache/answer/pkg/uid"
|
||||
)
|
||||
|
||||
const (
|
||||
QuestionLinkTypeURL = 1
|
||||
QuestionLinkTypeID = 2
|
||||
)
|
||||
|
||||
type QuestionLink struct {
|
||||
LinkType int
|
||||
QuestionID string
|
||||
AnswerID string
|
||||
}
|
||||
|
||||
func GetQuestionLink(content string) []QuestionLink {
|
||||
uniqueIDs := make(map[string]struct{})
|
||||
var questionLinks []QuestionLink
|
||||
|
||||
// use two pointer to find the link
|
||||
left, right := 0, 0
|
||||
for right < len(content) {
|
||||
// find "/questions/" or "#"
|
||||
switch {
|
||||
case right+11 < len(content) && content[right:right+11] == "/questions/":
|
||||
left = right
|
||||
right += 11
|
||||
processURL(content, &left, &right, uniqueIDs, &questionLinks)
|
||||
case content[right] == '#':
|
||||
left = right + 1
|
||||
right = left
|
||||
processID(content, &left, &right, uniqueIDs, &questionLinks)
|
||||
default:
|
||||
right++
|
||||
}
|
||||
}
|
||||
|
||||
return questionLinks
|
||||
}
|
||||
|
||||
func processURL(content string, left, right *int, uniqueIDs map[string]struct{}, questionLinks *[]QuestionLink) {
|
||||
for *right < len(content) && (isDigit(content[*right]) || isLetter(content[*right])) {
|
||||
*right++
|
||||
}
|
||||
questionID := content[*left+len("/questions/") : *right]
|
||||
|
||||
answerID := ""
|
||||
if *right < len(content) && content[*right] == '/' {
|
||||
*left = *right + 1
|
||||
*right = *left
|
||||
for *right < len(content) && (isDigit(content[*right]) || isLetter(content[*right])) {
|
||||
*right++
|
||||
}
|
||||
answerID = content[*left:*right]
|
||||
}
|
||||
|
||||
addUniqueID(questionID, answerID, QuestionLinkTypeURL, uniqueIDs, questionLinks)
|
||||
}
|
||||
|
||||
func processID(content string, left, right *int, uniqueIDs map[string]struct{}, questionLinks *[]QuestionLink) {
|
||||
for *right < len(content) && (isDigit(content[*right]) || isLetter(content[*right])) {
|
||||
*right++
|
||||
}
|
||||
id := content[*left:*right]
|
||||
addUniqueID(id, "", QuestionLinkTypeID, uniqueIDs, questionLinks)
|
||||
}
|
||||
|
||||
func isDigit(c byte) bool {
|
||||
return c >= '0' && c <= '9'
|
||||
}
|
||||
|
||||
func isLetter(c byte) bool {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|
||||
}
|
||||
|
||||
func addUniqueID(questionID, answerID string, linkType int, uniqueIDs map[string]struct{}, questionLinks *[]QuestionLink) {
|
||||
isAdd := false
|
||||
if answerID != "" {
|
||||
objectType, err := obj.GetObjectTypeStrByObjectID(uid.DeShortID(answerID))
|
||||
if err != nil {
|
||||
answerID = ""
|
||||
} else if objectType == constant.AnswerObjectType {
|
||||
if _, ok := uniqueIDs[answerID]; !ok {
|
||||
uniqueIDs[answerID] = struct{}{}
|
||||
isAdd = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if objectType, err := obj.GetObjectTypeStrByObjectID(uid.DeShortID(questionID)); err == nil {
|
||||
if _, ok := uniqueIDs[questionID]; !ok {
|
||||
uniqueIDs[questionID] = struct{}{}
|
||||
isAdd = true
|
||||
if objectType == constant.AnswerObjectType {
|
||||
answerID = questionID
|
||||
questionID = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isAdd {
|
||||
*questionLinks = append(*questionLinks, QuestionLink{
|
||||
LinkType: linkType,
|
||||
QuestionID: questionID,
|
||||
AnswerID: answerID,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user