forked from twitter/the-algorithm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tweetypie is the core Tweet service that handles the reading and writing of Tweet data.
- Loading branch information
twitter-team
committed
May 19, 2023
1 parent
90d7ea3
commit 01dbfee
Showing
591 changed files
with
68,352 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
tweetypie/common/src/scala/com/twitter/tweetypie/additionalfields/AdditionalFields.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package com.twitter.tweetypie.additionalfields | ||
|
||
import com.twitter.tweetypie.thriftscala.Tweet | ||
import com.twitter.scrooge.TFieldBlob | ||
import com.twitter.scrooge.ThriftStructField | ||
|
||
object AdditionalFields { | ||
type FieldId = Short | ||
|
||
/** additional fields really start at 100, be we are ignoring conversation id for now */ | ||
val StartAdditionalId = 101 | ||
|
||
/** all known [[Tweet]] field IDs */ | ||
val CompiledFieldIds: Seq[FieldId] = Tweet.metaData.fields.map(_.id) | ||
|
||
/** all known [[Tweet]] fields in the "additional-field" range (excludes id) */ | ||
val CompiledAdditionalFieldMetaDatas: Seq[ThriftStructField[Tweet]] = | ||
Tweet.metaData.fields.filter(f => isAdditionalFieldId(f.id)) | ||
|
||
val CompiledAdditionalFieldsMap: Map[Short, ThriftStructField[Tweet]] = | ||
CompiledAdditionalFieldMetaDatas.map(field => (field.id, field)).toMap | ||
|
||
/** all known [[Tweet]] field IDs in the "additional-field" range */ | ||
val CompiledAdditionalFieldIds: Seq[FieldId] = | ||
CompiledAdditionalFieldsMap.keys.toSeq | ||
|
||
/** all [[Tweet]] field IDs which should be rejected when set as additional | ||
* fields on via PostTweetRequest.additionalFields or RetweetRequest.additionalFields */ | ||
val RejectedFieldIds: Seq[FieldId] = Seq( | ||
// Should be provided via PostTweetRequest.conversationControl field. go/convocontrolsbackend | ||
Tweet.ConversationControlField.id, | ||
// This field should only be set based on whether the client sets the right community | ||
// tweet annotation. | ||
Tweet.CommunitiesField.id, | ||
// This field should not be set by clients and should opt for | ||
// [[PostTweetRequest.ExclusiveTweetControlOptions]]. | ||
// The exclusiveTweetControl field requires the userId to be set | ||
// and we shouldn't trust the client to provide the right one. | ||
Tweet.ExclusiveTweetControlField.id, | ||
// This field should not be set by clients and should opt for | ||
// [[PostTweetRequest.TrustedFriendsControlOptions]]. | ||
// The trustedFriendsControl field requires the trustedFriendsListId to be | ||
// set and we shouldn't trust the client to provide the right one. | ||
Tweet.TrustedFriendsControlField.id, | ||
// This field should not be set by clients and should opt for | ||
// [[PostTweetRequest.CollabControlOptions]]. | ||
// The collabControl field requires a list of Collaborators to be | ||
// set and we shouldn't trust the client to provide the right one. | ||
Tweet.CollabControlField.id | ||
) | ||
|
||
def isAdditionalFieldId(fieldId: FieldId): Boolean = | ||
fieldId >= StartAdditionalId | ||
|
||
/** | ||
* Provides a list of all additional field IDs on the tweet, which include all | ||
* the compiled additional fields and all the provided passthrough fields. This includes | ||
* compiled additional fields where the value is None. | ||
*/ | ||
def allAdditionalFieldIds(tweet: Tweet): Seq[FieldId] = | ||
CompiledAdditionalFieldIds ++ tweet._passthroughFields.keys | ||
|
||
/** | ||
* Provides a list of all field IDs that have a value on the tweet which are not known compiled | ||
* additional fields (excludes [[Tweet.id]]). | ||
*/ | ||
def unsettableAdditionalFieldIds(tweet: Tweet): Seq[FieldId] = | ||
CompiledFieldIds | ||
.filter { id => | ||
!isAdditionalFieldId(id) && id != Tweet.IdField.id && tweet.getFieldBlob(id).isDefined | ||
} ++ | ||
tweet._passthroughFields.keys | ||
|
||
/** | ||
* Provides a list of all field IDs that have a value on the tweet which are explicitly disallowed | ||
* from being set via PostTweetRequest.additionalFields and RetweetRequest.additionalFields | ||
*/ | ||
def rejectedAdditionalFieldIds(tweet: Tweet): Seq[FieldId] = | ||
RejectedFieldIds | ||
.filter { id => tweet.getFieldBlob(id).isDefined } | ||
|
||
def unsettableAdditionalFieldIdsErrorMessage(unsettableFieldIds: Seq[FieldId]): String = | ||
s"request may not contain fields: [${unsettableFieldIds.sorted.mkString(", ")}]" | ||
|
||
/** | ||
* Provides a list of all additional field IDs that have a value on the tweet, | ||
* compiled and passthrough (excludes Tweet.id). | ||
*/ | ||
def nonEmptyAdditionalFieldIds(tweet: Tweet): Seq[FieldId] = | ||
CompiledAdditionalFieldMetaDatas.collect { | ||
case f if f.getValue(tweet) != None => f.id | ||
} ++ tweet._passthroughFields.keys | ||
|
||
def additionalFields(tweet: Tweet): Seq[TFieldBlob] = | ||
(tweet.getFieldBlobs(CompiledAdditionalFieldIds) ++ tweet._passthroughFields).values.toSeq | ||
|
||
/** | ||
* Merge base tweet with additional fields. | ||
* Non-additional fields in the additional tweet are ignored. | ||
* @param base: a tweet that contains basic fields | ||
* @param additional: a tweet object that carries additional fields | ||
*/ | ||
def setAdditionalFields(base: Tweet, additional: Tweet): Tweet = | ||
setAdditionalFields(base, additionalFields(additional)) | ||
|
||
def setAdditionalFields(base: Tweet, additional: Option[Tweet]): Tweet = | ||
additional.map(setAdditionalFields(base, _)).getOrElse(base) | ||
|
||
def setAdditionalFields(base: Tweet, additional: Traversable[TFieldBlob]): Tweet = | ||
additional.foldLeft(base) { case (t, f) => t.setField(f) } | ||
|
||
/** | ||
* Unsets the specified fields on the given tweet. | ||
*/ | ||
def unsetFields(tweet: Tweet, fieldIds: Iterable[FieldId]): Tweet = { | ||
tweet.unsetFields(fieldIds.toSet) | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
tweetypie/common/src/scala/com/twitter/tweetypie/additionalfields/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
scala_library( | ||
sources = ["*.scala"], | ||
compiler_option_sets = ["fatal_warnings"], | ||
platform = "java8", | ||
strict_deps = True, | ||
tags = ["bazel-compatible"], | ||
dependencies = [ | ||
"3rdparty/jvm/org/apache/thrift:libthrift", | ||
"mediaservices/commons/src/main/thrift:thrift-scala", | ||
"scrooge/scrooge-core", | ||
"src/thrift/com/twitter/escherbird:media-annotation-structs-scala", | ||
"src/thrift/com/twitter/spam/rtf:safety-label-scala", | ||
"tweetypie/common/src/thrift/com/twitter/tweetypie:tweet-scala", | ||
], | ||
) |
15 changes: 15 additions & 0 deletions
15
tweetypie/common/src/scala/com/twitter/tweetypie/caching/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
scala_library( | ||
compiler_option_sets = ["fatal_warnings"], | ||
strict_deps = True, | ||
tags = ["bazel-compatible"], | ||
dependencies = [ | ||
"finagle/finagle-memcached/src/main/scala", | ||
"scrooge/scrooge-serializer", | ||
"stitch/stitch-core", | ||
"util/util-core", | ||
"util/util-logging", | ||
# CachedValue struct | ||
"tweetypie/servo/repo/src/main/thrift:thrift-scala", | ||
"util/util-slf4j-api/src/main/scala/com/twitter/util/logging", | ||
], | ||
) |
Oops, something went wrong.