Skip to content

Commit

Permalink
handle hashtags
Browse files Browse the repository at this point in the history
  • Loading branch information
ilGianfri committed Nov 23, 2024
1 parent 6bc2bce commit f2bb39d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 6 deletions.
15 changes: 13 additions & 2 deletions src/TwitterSky/Models/TweetArchiveModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Text.Json.Serialization;

#nullable disable

namespace TwitterSky.Models
{
public partial class TweetArchiveModel
Expand All @@ -15,7 +17,7 @@ public partial class Tweet
public bool Retweeted { get; set; }

[JsonPropertyName("entities")]
public Entities? Entities { get; set; }
public Entities Entities { get; set; }

[JsonPropertyName("id")]
public string Id { get; set; }
Expand All @@ -39,7 +41,7 @@ public partial class Tweet
public partial class Entities
{
[JsonPropertyName("hashtags")]
public List<object> Hashtags { get; set; }
public List<Hashtag> Hashtags { get; set; }

[JsonPropertyName("user_mentions")]
public List<object> UserMentions { get; set; }
Expand All @@ -48,6 +50,15 @@ public partial class Entities
public List<Url> Urls { get; set; }
}

public partial class Hashtag
{
[JsonPropertyName("text")]
public string Text { get; set; }

[JsonPropertyName("indices")]
public List<string> Indices { get; set; }
}

public partial class ExtendedEntities
{
[JsonPropertyName("media")]
Expand Down
51 changes: 47 additions & 4 deletions src/TwitterSky/TweetImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,46 @@ private static (string, List<Facet>) ReplaceUrls(string tweetContent, List<Url>
return (tweetContent, facets);
}

/// <summary>
/// Gets the hashtags from the tweet content and creates facets for them.
/// </summary>
/// <param name="tweetContent">The content of the tweet.</param>
/// <param name="hashtags">List of hashtags to replace</param>
/// <returns>A list of facets</returns>
private static List<Facet> GetHashtags(string tweetContent, List<Hashtag>? hashtags)
{
if (hashtags == null || hashtags.Count == 0)
{
return [];
}

List<Facet> facets = [];
if (hashtags.Count > 0)
{
foreach (Hashtag hashtag in hashtags)
{
FacetIndex index;
if (hashtag.Indices.Count == 2)
{
index = new(Convert.ToInt32(hashtag.Indices[0]), Convert.ToInt32(hashtag.Indices[1]));
}
else
{
// If the indices are not present, we need to find the start and end of the hashtag text.
// This is done as a "ByteSlice."
int promptStart = tweetContent.IndexOf(hashtag.Text, StringComparison.InvariantCulture);
int promptEnd = promptStart + Encoding.Default.GetBytes(hashtag.Text).Length;
index = new(promptStart, promptEnd);
}

FacetFeature tag = FacetFeature.CreateHashtag(hashtag.Text);
facets.Add(new Facet(index, tag));
}
}

return facets;
}

/// <summary>
/// Requests the cancellation of the import operation.
/// </summary>
Expand Down Expand Up @@ -244,7 +284,10 @@ public async Task ImportTweetAsync()
parentPostId = value;
}

await PostToBskyAsync(tweet.Tweet.Id, content, imageUrls, DateTime.ParseExact(tweet.Tweet.CreatedAt, TW_DATE_FORMAT, CultureInfo.InvariantCulture), facets, parentPostId);
// Get the hashtags from the tweet content
facets.AddRange(GetHashtags(content, tweet.Tweet?.Entities?.Hashtags));

await PostToBskyAsync(tweet.Tweet!.Id, content, imageUrls, DateTime.ParseExact(tweet.Tweet.CreatedAt, TW_DATE_FORMAT, CultureInfo.InvariantCulture), facets, parentPostId);

await SaveLastParsedTweet(tweet.Tweet.Id);

Expand All @@ -271,7 +314,7 @@ public async Task ImportTweetAsync()
/// <param name="createdAt">The creation date of the tweet.</param>
/// <param name="facets">The list of facets for the tweet.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
private async Task PostToBskyAsync(string tweetId, string textContent, List<string> imageUrls, DateTime createdAt, List<Facet> facets, CreatePostResponse inReplyTo)
private async Task PostToBskyAsync(string tweetId, string textContent, List<string> imageUrls, DateTime createdAt, List<Facet> facets, CreatePostResponse? inReplyTo)
{
Reply? reply = null;
if (inReplyTo != null)
Expand Down Expand Up @@ -309,7 +352,7 @@ await blobResult.SwitchAsync(
// Blob is uploaded.
Console.WriteLine($"Uploading image...");
// Converts the blob to an image.
FishyFlip.Models.Image? image = success.Blob.ToImage();
Image? image = success.Blob.ToImage();
bskyImages.Add(image);
},
async error =>

Check warning on line 358 in src/TwitterSky/TweetImporter.cs

View workflow job for this annotation

GitHub Actions / build-releases

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 358 in src/TwitterSky/TweetImporter.cs

View workflow job for this annotation

GitHub Actions / build-releases

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 358 in src/TwitterSky/TweetImporter.cs

View workflow job for this annotation

GitHub Actions / build-releases

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 358 in src/TwitterSky/TweetImporter.cs

View workflow job for this annotation

GitHub Actions / build-releases

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
Expand All @@ -327,7 +370,7 @@ await blobResult.SwitchAsync(
postResult = await _bskyProtocol.Repo.CreatePostAsync(textContent, facets: [.. facets], createdAt: createdAt, reply: reply);
}

if (_tweetIdToBskyId.ContainsKey(tweetId) && postResult.Value is CreatePostResponse postResponse)
if (_tweetIdToBskyId.ContainsKey(tweetId) && postResult?.Value is CreatePostResponse postResponse)
{
_tweetIdToBskyId[tweetId] = postResponse;
}
Expand Down

0 comments on commit f2bb39d

Please sign in to comment.