From 451d0190d0ce291115e5b32b35a3d3a830f65a2d Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Sun, 16 Apr 2017 20:01:57 +0300 Subject: [PATCH 01/15] added like, unlike, follow, unfollow, comment, delete comment possibilities; improved tests and examples --- .../{InstaSharperExamples.cs => Basics.cs} | 48 +- .../InstaSharper.Examples.csproj | 3 +- .../Utils/StringExtensions.cs | 16 + InstaSharper.Tests/Endpoints/FollowersTest.cs | 16 +- InstaSharper.Tests/Endpoints/LikesTest.cs | 34 +- InstaSharper.Tests/Endpoints/MediaTest.cs | 28 +- InstaSharper.Tests/Endpoints/UserInfoTest.cs | 21 + InstaSharper.Tests/project.json | 2 +- InstaSharper/API/IInstaApi.cs | 71 ++- InstaSharper/API/InstaApi.cs | 435 +++++++++++++----- InstaSharper/API/InstaApiConstants.cs | 14 +- .../Android/DeviceInfo/ApiRequestMessage.cs | 2 +- InstaSharper/Classes/Models/Images.cs | 6 +- InstaSharper/Classes/Models/InstaCarousel.cs | 11 + .../Classes/Models/InstaCarouselItem.cs | 21 + .../Classes/Models/InstaFriendshipStatus.cs | 5 +- InstaSharper/Classes/Models/InstaMedia.cs | 6 +- .../Classes/Models/InstaRecipients.cs | 2 +- .../Models/{Image.cs => MediaImage.cs} | 4 +- InstaSharper/Classes/ResponseType.cs | 10 + .../ResponseWrappers/BadStatusResponse.cs | 4 +- .../BaseResponse/BaseLoadableResponse.cs | 2 +- .../BaseResponse/BaseStatusResponse.cs | 20 + .../ResponseWrappers/FollowedByResponse.cs | 2 +- .../ResponseWrappers/ImageResponse.cs | 2 +- .../ResponseWrappers/ImagesResponse.cs | 2 +- .../ResponseWrappers/InstaCaptionResponse.cs | 4 +- .../InstaCarouselItemResponse.cs | 29 ++ .../ResponseWrappers/InstaCarouselResponse.cs | 8 + .../InstaCommentListResponse.cs | 4 +- .../ResponseWrappers/InstaCommentResponse.cs | 2 +- .../InstaCurrentUserResponse.cs | 4 +- .../InstaDirectInboxContainerResponse.cs | 4 +- .../InstaDirectInboxItemResponse.cs | 4 +- .../InstaDirectInboxResponse.cs | 2 +- .../InstaDirectInboxSubscriptionResponse.cs | 2 +- .../InstaDirectInboxThreadResponse.cs | 4 +- .../ResponseWrappers/InstaFeedResponse.cs | 4 +- .../InstaFollowersResponse.cs | 4 +- .../InstaFriendshipStatusResponse.cs | 26 ++ .../InstaImageCandidatesResponse.cs | 2 +- .../InstaInlineFollowResponse.cs | 2 +- .../ResponseWrappers/InstaLinkResponse.cs | 2 +- .../ResponseWrappers/InstaLoginResponse.cs | 2 +- .../InstaMediaItemResponse.cs | 5 +- .../InstaMediaLikersResponse.cs | 2 +- .../InstaMediaListResponse.cs | 4 +- .../InstaRecentActivityFeedResponse.cs | 2 +- .../InstaRecentActivityResponse.cs | 4 +- .../InstaRecentActivityStoryItemResponse.cs | 2 +- .../InstaRecipientsResponse.cs | 4 +- .../InstaSearchUserResponse.cs | 2 +- .../ResponseWrappers/InstaStoryResponse.cs | 2 +- .../ResponseWrappers/InstaTagFeedResponse.cs | 2 +- .../ResponseWrappers/InstaUserResponse.cs | 4 +- .../InstaUserTagListResponse.cs | 2 +- .../ResponseWrappers/InstaUserTagResponse.cs | 2 +- InstaSharper/Classes/Result.cs | 32 -- InstaSharper/Classes/ResultInfo.cs | 28 ++ InstaSharper/Converters/ConvertersFabric.cs | 14 +- .../Converters/InstaCaptionConverter.cs | 2 +- .../Converters/InstaCarouselConverter.cs | 23 + .../Converters/InstaCarouselItemConverter.cs | 25 + .../Converters/InstaCommentConverter.cs | 2 +- .../Converters/InstaCommentListConverter.cs | 2 +- .../Converters/InstaDirectInboxConverter.cs | 2 +- .../InstaDirectInboxSubscriptionConverter.cs | 2 +- .../Converters/InstaDirectThreadConverter.cs | 2 +- .../InstaDirectThreadItemConverter.cs | 2 +- InstaSharper/Converters/InstaFeedConverter.cs | 2 +- .../InstaFriendshipStatusConverter.cs | 14 +- .../Converters/InstaMediaConverter.cs | 6 +- .../Converters/InstaMediaListConverter.cs | 2 +- .../InstaRecentActivityConverter.cs | 2 +- .../Converters/InstaRecipientsConverter.cs | 2 +- .../Converters/InstaStoryConverter.cs | 2 +- .../Converters/InstaUserTagConverter.cs | 2 +- .../Converters/InstaUsersConverter.cs | 2 +- .../Json/InstaCommentDataConverter.cs | 30 ++ .../Json/InstaFeedResponseDataConverter.cs | 2 +- .../Json/InstaFriendShipDataConverter.cs | 33 ++ .../Json/InstaMediaListDataConverter.cs | 2 +- .../Json/InstaRecentActivityConverter.cs | 2 +- .../Json/InstaRecipientsDataConverter.cs | 2 +- .../Json/InstaThreadDataConverter.cs | 2 +- InstaSharper/Helpers/CryptoHelper.cs | 42 +- InstaSharper/Helpers/DateTimeHelper.cs | 17 +- InstaSharper/Helpers/HttpHelper.cs | 22 + InstaSharper/Helpers/UriCreator.cs | 62 +++ .../BaseResponse/BaseStatusResponse.cs | 10 - .../InstaFriendshipStatusResponse.cs | 19 - InstaSharper/project.json | 2 +- 92 files changed, 1020 insertions(+), 330 deletions(-) rename InstaSharper.Examples/{InstaSharperExamples.cs => Basics.cs} (60%) create mode 100644 InstaSharper.Examples/Utils/StringExtensions.cs create mode 100644 InstaSharper/Classes/Models/InstaCarousel.cs create mode 100644 InstaSharper/Classes/Models/InstaCarouselItem.cs rename InstaSharper/Classes/Models/{Image.cs => MediaImage.cs} (74%) create mode 100644 InstaSharper/Classes/ResponseType.cs rename InstaSharper/{ => Classes}/ResponseWrappers/BadStatusResponse.cs (76%) rename InstaSharper/{ => Classes}/ResponseWrappers/BaseResponse/BaseLoadableResponse.cs (90%) create mode 100644 InstaSharper/Classes/ResponseWrappers/BaseResponse/BaseStatusResponse.cs rename InstaSharper/{ => Classes}/ResponseWrappers/FollowedByResponse.cs (75%) rename InstaSharper/{ => Classes}/ResponseWrappers/ImageResponse.cs (86%) rename InstaSharper/{ => Classes}/ResponseWrappers/ImagesResponse.cs (88%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaCaptionResponse.cs (87%) create mode 100644 InstaSharper/Classes/ResponseWrappers/InstaCarouselItemResponse.cs create mode 100644 InstaSharper/Classes/ResponseWrappers/InstaCarouselResponse.cs rename InstaSharper/{ => Classes}/ResponseWrappers/InstaCommentListResponse.cs (89%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaCommentResponse.cs (95%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaCurrentUserResponse.cs (63%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaDirectInboxContainerResponse.cs (86%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaDirectInboxItemResponse.cs (86%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaDirectInboxResponse.cs (90%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaDirectInboxSubscriptionResponse.cs (89%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaDirectInboxThreadResponse.cs (93%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaFeedResponse.cs (79%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaFollowersResponse.cs (84%) create mode 100644 InstaSharper/Classes/ResponseWrappers/InstaFriendshipStatusResponse.cs rename InstaSharper/{ => Classes}/ResponseWrappers/InstaImageCandidatesResponse.cs (82%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaInlineFollowResponse.cs (88%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaLinkResponse.cs (88%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaLoginResponse.cs (83%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaMediaItemResponse.cs (93%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaMediaLikersResponse.cs (86%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaMediaListResponse.cs (77%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaRecentActivityFeedResponse.cs (87%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaRecentActivityResponse.cs (77%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaRecentActivityStoryItemResponse.cs (93%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaRecipientsResponse.cs (75%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaSearchUserResponse.cs (88%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaStoryResponse.cs (94%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaTagFeedResponse.cs (82%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaUserResponse.cs (92%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaUserTagListResponse.cs (83%) rename InstaSharper/{ => Classes}/ResponseWrappers/InstaUserTagResponse.cs (87%) create mode 100644 InstaSharper/Classes/ResultInfo.cs create mode 100644 InstaSharper/Converters/InstaCarouselConverter.cs create mode 100644 InstaSharper/Converters/InstaCarouselItemConverter.cs create mode 100644 InstaSharper/Converters/Json/InstaCommentDataConverter.cs create mode 100644 InstaSharper/Converters/Json/InstaFriendShipDataConverter.cs delete mode 100644 InstaSharper/ResponseWrappers/BaseResponse/BaseStatusResponse.cs delete mode 100644 InstaSharper/ResponseWrappers/InstaFriendshipStatusResponse.cs diff --git a/InstaSharper.Examples/InstaSharperExamples.cs b/InstaSharper.Examples/Basics.cs similarity index 60% rename from InstaSharper.Examples/InstaSharperExamples.cs rename to InstaSharper.Examples/Basics.cs index dff2c68a..82e39647 100644 --- a/InstaSharper.Examples/InstaSharperExamples.cs +++ b/InstaSharper.Examples/Basics.cs @@ -3,13 +3,24 @@ using InstaSharper.API; using InstaSharper.API.Builder; using InstaSharper.Classes; +using InstaSharper.Classes.Models; +using InstaSharper.Examples.Utils; namespace InstaSharper.Examples { - internal class InstaSharperExamples + internal class Basics { + /// + /// Api instance (one instance per Instagram user) + /// private static IInstaApi _instaApi; + /// + /// Config values + /// + private static int _maxDescriptionLength = 20; + + private static void Main(string[] args) { // create user session data and provide login details @@ -30,35 +41,50 @@ private static void Main(string[] args) // get currently logged in user var currentUser = _instaApi.GetCurrentUser().Value; Console.WriteLine($"Logged in: username - {currentUser.UserName}, full name - {currentUser.FullName}"); - // get followers + + // get self followers var followers = _instaApi.GetUserFollowersAsync(currentUser.UserName, 5).Result.Value; Console.WriteLine($"Count of followers [{currentUser.UserName}]:{followers.Count}"); - // get user's media + + // get self user's media, latest 5 pages var currentUserMedia = _instaApi.GetUserMedia(currentUser.UserName, 5); if (currentUserMedia.Succeeded) { Console.WriteLine($"Media count [{currentUser.UserName}]: {currentUserMedia.Value.Count}"); - foreach (var media in currentUserMedia.Value) Console.WriteLine($"Media [{currentUser.UserName}]: {media.Caption.Text}, {media.Code}, likes: {media.LikesCount}, image link: {media.Images.LastOrDefault()?.Url}"); + foreach (var media in currentUserMedia.Value) PrintMedia("Self media", media); } - //get user feed, first 5 pages - var userFeed = _instaApi.GetExploreFeed(5); + //get user time line feed, latest 5 pages + var userFeed = _instaApi.GetUserTimelineFeed(5); if (userFeed.Succeeded) { Console.WriteLine($"Feed items (in {userFeed.Value.Pages} pages) [{currentUser.UserName}]: {userFeed.Value.Medias.Count}"); - foreach (var media in userFeed.Value.Medias) Console.WriteLine($"Feed item - code:{media.Code}, likes: {media.LikesCount}"); + foreach (var media in userFeed.Value.Medias) PrintMedia("Feed media", media); + //like first 10 medias from user timeline feed + foreach (var media in userFeed.Value.Medias.Take(10)) + { + var likeResult = _instaApi.LikeMedia(media.InstaIdentifier); + var resultString = likeResult.Value ? "liked" : "not like"; + Console.WriteLine($"Media {media.Code} {resultString}"); + } } - // get tag feed, first 5 pages - var tagFeed = _instaApi.GetTagFeed("gm", 5); - if (userFeed.Succeeded) + + // get tag feed, latest 5 pages + var tagFeed = _instaApi.GetTagFeed("quadcopter", 5); + if (tagFeed.Succeeded) { Console.WriteLine($"Tag feed items (in {tagFeed.Value.Pages} pages) [{currentUser.UserName}]: {tagFeed.Value.Medias.Count}"); - foreach (var media in tagFeed.Value.Medias) Console.WriteLine($"Tag feed item - code: {media.Code}, likes: {media.LikesCount}"); + foreach (var media in tagFeed.Value.Medias) PrintMedia("Tag feed", media); } var logoutResult = _instaApi.Logout(); if (logoutResult.Value) Console.WriteLine("Logout succeed"); } Console.ReadKey(); } + + private static void PrintMedia(string header, InstaMedia media) + { + Console.WriteLine($"{header} [{media.User.UserName}]: {media.Caption?.Text.Truncate(_maxDescriptionLength)}, {media.Code}, likes: {media.LikesCount}, multipost: {media.IsMultiPost}"); + } } } \ No newline at end of file diff --git a/InstaSharper.Examples/InstaSharper.Examples.csproj b/InstaSharper.Examples/InstaSharper.Examples.csproj index efe30f26..e1ae411e 100644 --- a/InstaSharper.Examples/InstaSharper.Examples.csproj +++ b/InstaSharper.Examples/InstaSharper.Examples.csproj @@ -46,8 +46,9 @@ - + + diff --git a/InstaSharper.Examples/Utils/StringExtensions.cs b/InstaSharper.Examples/Utils/StringExtensions.cs new file mode 100644 index 00000000..5b757da7 --- /dev/null +++ b/InstaSharper.Examples/Utils/StringExtensions.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace InstaSharper.Examples.Utils +{ + public static class StringExtensions + { + public static string Truncate(this string value, int maxChars) + { + return value.Length <= maxChars ? value : value.Substring(0, maxChars) + "..."; + } + } +} diff --git a/InstaSharper.Tests/Endpoints/FollowersTest.cs b/InstaSharper.Tests/Endpoints/FollowersTest.cs index 75994640..f1201f79 100644 --- a/InstaSharper.Tests/Endpoints/FollowersTest.cs +++ b/InstaSharper.Tests/Endpoints/FollowersTest.cs @@ -50,7 +50,6 @@ public async void GetCurrentUserFollwersTest() Password = password }); if (!TestHelpers.Login(apiInstance, _output)) return; - if (!TestHelpers.Login(apiInstance, _output)) return; var result = await apiInstance.GetCurrentUserFollowersAsync(); var followers = result.Value; //assert @@ -60,7 +59,7 @@ public async void GetCurrentUserFollwersTest() [RunnableInDebugOnlyTheory] [InlineData(196754384)] - public async void FollowUserTest(long userId) + public async void FollowUnfollowUserTest(long userId) { var currentUsername = "alex_codegarage"; var password = Environment.GetEnvironmentVariable("instaapiuserpassword"); @@ -69,12 +68,15 @@ public async void FollowUserTest(long userId) UserName = currentUsername, Password = password }); - if (!TestHelpers.Login(apiInstance, _output)) return; - var result = await apiInstance.FollowUserAsync(userId); - var followers = result.Value; + if (!TestHelpers.Login(apiInstance, _output)) throw new Exception("Not logged in"); + var followResult = await apiInstance.FollowUserAsync(userId); + var unFollowResult = await apiInstance.UnFollowUserAsync(userId); //assert - Assert.True(result.Succeeded); - Assert.NotNull(followers); + Assert.True(followResult.Succeeded); + Assert.True(unFollowResult.Succeeded); + + Assert.True(followResult.Value.Following); + Assert.False(unFollowResult.Value.Following); } } } \ No newline at end of file diff --git a/InstaSharper.Tests/Endpoints/LikesTest.cs b/InstaSharper.Tests/Endpoints/LikesTest.cs index e54a68b6..8dc02223 100644 --- a/InstaSharper.Tests/Endpoints/LikesTest.cs +++ b/InstaSharper.Tests/Endpoints/LikesTest.cs @@ -20,7 +20,7 @@ public LikesTest(ITestOutputHelper output) [RunnableInDebugOnlyTheory] [InlineData("1484832969772514291_196754384")] - public async void LikeTest(string mediaId) + public async void LikeUnlikeTest(string mediaId) { //arrange var apiInstance = @@ -29,35 +29,13 @@ public async void LikeTest(string mediaId) UserName = _username, Password = _password }); + if (!TestHelpers.Login(apiInstance, _output)) throw new Exception("Not logged in"); //act - var loginSucceed = TestHelpers.Login(apiInstance, _output); - Assert.True(loginSucceed); - var result = await apiInstance.LikeMediaAsync(mediaId); - var exploreGeed = result.Value; + var likeResult = await apiInstance.LikeMediaAsync(mediaId); + var unLikeResult = await apiInstance.UnLikeMediaAsync(mediaId); //assert - Assert.True(result.Succeeded); - Assert.NotNull(exploreGeed); - } - - [RunnableInDebugOnlyTheory] - [InlineData("1484832969772514291_196754384")] - public async void UnLikeTest(string mediaId) - { - //arrange - var apiInstance = - TestHelpers.GetDefaultInstaApiInstance(new UserSessionData - { - UserName = _username, - Password = _password - }); - //act - var loginSucceed = TestHelpers.Login(apiInstance, _output); - Assert.True(loginSucceed); - var result = await apiInstance.UnLikeMediaAsync(mediaId); - var exploreGeed = result.Value; - //assert - Assert.True(result.Succeeded); - Assert.NotNull(exploreGeed); + Assert.True(likeResult.Succeeded); + Assert.True(unLikeResult.Succeeded); } } } \ No newline at end of file diff --git a/InstaSharper.Tests/Endpoints/MediaTest.cs b/InstaSharper.Tests/Endpoints/MediaTest.cs index 8c9e67fa..ad9cd2d5 100644 --- a/InstaSharper.Tests/Endpoints/MediaTest.cs +++ b/InstaSharper.Tests/Endpoints/MediaTest.cs @@ -85,7 +85,7 @@ public async void GetMediaCommentsTest(string mediaId) } [RunnableInDebugOnlyTheory] - [InlineData("mohammadq74")] + [InlineData("alex_codegarage")] public async void GetUserMediaListTest(string userToFetch) { //arrange @@ -109,8 +109,32 @@ public async void GetUserMediaListTest(string userToFetch) //assert Assert.NotNull(posts); Assert.Equal(userToFetch, posts.Value[random.Next(0, posts.Value.Count)].User.UserName); - Assert.Equal(pages, posts.Value.Pages); Assert.False(anyDuplicate); } + + [RunnableInDebugOnlyTheory] + [InlineData("1484832969772514291_196754384")] + public async void PostDeleteCommentTest(string mediaId) + { + //arrange + var username = "alex_codegarage"; + var password = Environment.GetEnvironmentVariable("instaapiuserpassword"); + var apiInstance = TestHelpers.GetDefaultInstaApiInstance(new UserSessionData + { + UserName = username, + Password = password + }); + var text = "test comment"; + //act + if (!TestHelpers.Login(apiInstance, _output)) return; + + var postResult = await apiInstance.CommentMediaAsync(mediaId, text); + var delResult = await apiInstance.DeleteCommentAsync(mediaId, postResult.Value.Pk); + //assert + Assert.True(postResult.Succeeded); + Assert.Equal(text, postResult.Value.Text); + Assert.True(delResult.Succeeded); + + } } } \ No newline at end of file diff --git a/InstaSharper.Tests/Endpoints/UserInfoTest.cs b/InstaSharper.Tests/Endpoints/UserInfoTest.cs index 9db4d3f7..c87d4820 100644 --- a/InstaSharper.Tests/Endpoints/UserInfoTest.cs +++ b/InstaSharper.Tests/Endpoints/UserInfoTest.cs @@ -57,5 +57,26 @@ public async void GetUserTest() Assert.NotNull(user); Assert.Equal(user.UserName, _username); } + + [RunnableInDebugOnlyFact] + public async void SetAccountPrivacyTest() + { + //arrange + var apiInstance = + TestHelpers.GetDefaultInstaApiInstance(new UserSessionData + { + UserName = _username, + Password = _password + }); + //act + if (!TestHelpers.Login(apiInstance, _output)) return; + var resultSetPrivate = await apiInstance.SetAccountPrivateAsync(); + var resultSetPublic = await apiInstance.SetAccountPublicAsync(); + //assert + Assert.True(resultSetPrivate.Succeeded); + Assert.NotNull(resultSetPrivate.Value); + Assert.True(resultSetPublic.Succeeded); + Assert.NotNull(resultSetPrivate.Value); + } } } \ No newline at end of file diff --git a/InstaSharper.Tests/project.json b/InstaSharper.Tests/project.json index a17d8d36..53820ce9 100644 --- a/InstaSharper.Tests/project.json +++ b/InstaSharper.Tests/project.json @@ -3,7 +3,7 @@ "testRunner": "xunit", "dependencies": { "xunit": "2.2.0-beta2-build3300", - "InstaSharper": "1.2.3", + "InstaSharper": "1.2.4", "dotnet-test-xunit": "2.2.0-preview2-build1029" }, "frameworks": { diff --git a/InstaSharper/API/IInstaApi.cs b/InstaSharper/API/IInstaApi.cs index 4b35c87f..5c608006 100644 --- a/InstaSharper/API/IInstaApi.cs +++ b/InstaSharper/API/IInstaApi.cs @@ -58,11 +58,11 @@ public interface IInstaApi /// /// Get media by its id (code) /// - /// Maximum count of pages to retrieve + /// Maximum count of pages to retrieve /// /// /// - IResult GetMediaByCode(string mediaCode); + IResult GetMediaById(string mediaId); /// /// Get user info by its user name @@ -193,7 +193,38 @@ public interface IInstaApi /// /// User Id /// True i success - IResult FollowUser(long userId); + IResult FollowUser(long userId); + + /// + /// Stop follow user by its by id + /// + /// User Id + /// True i success + IResult UnFollowUser(long userId); + + /// + /// Set current account private + /// + IResult SetAccountPrivate(); + + /// + /// Set current account public + /// + IResult SetAccountPublic(); + + /// + /// Comment media + /// + /// Media id + /// Comment text + IResult CommentMedia(string mediaId, string text); + + /// + /// Delete comment from media + /// + /// Media id + /// Comment id + IResult DeleteComment(string mediaId, string commentId); #endregion @@ -221,7 +252,7 @@ public interface IInstaApi Task> GetUserTimelineFeedAsync(int maxPages = 0); /// - /// Get user explore feed asynchronously + /// Get user explore feed asynchronously (Explore tab info) /// /// Maximum count of pages to retrieve /// > @@ -370,7 +401,13 @@ public interface IInstaApi /// Follow user /// /// User id - Task> FollowUserAsync(long userId); + Task> FollowUserAsync(long userId); + + /// + /// Stop follow user + /// + /// User id + Task> UnFollowUserAsync(long userId); /// /// Get media comments @@ -384,6 +421,30 @@ public interface IInstaApi /// Media id Task> GetMediaLikersAsync(string mediaId); + /// + /// Set current account private + /// + Task> SetAccountPrivateAsync(); + + /// + /// Set current account public + /// + Task> SetAccountPublicAsync(); + + /// + /// Comment media + /// + /// Media id + /// Comment text + Task> CommentMediaAsync(string mediaId, string text); + + /// + /// Delete comment from media + /// + /// Media id + /// Comment id + Task> DeleteCommentAsync(string mediaId, string commentId); + #endregion } } \ No newline at end of file diff --git a/InstaSharper/API/InstaApi.cs b/InstaSharper/API/InstaApi.cs index 848405ed..a549918b 100644 --- a/InstaSharper/API/InstaApi.cs +++ b/InstaSharper/API/InstaApi.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Security.Cryptography; using System.Threading.Tasks; using InstaSharper.Classes; using InstaSharper.Classes.Android.DeviceInfo; @@ -11,12 +12,12 @@ using InstaSharper.Converters.Json; using InstaSharper.Helpers; using InstaSharper.Logger; -using InstaSharper.ResponseWrappers; -using InstaSharper.ResponseWrappers.BaseResponse; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using InstaRecentActivityConverter = InstaSharper.Converters.Json.InstaRecentActivityConverter; using System.Text; +using InstaSharper.Classes.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; namespace InstaSharper.API { @@ -58,12 +59,16 @@ public IResult Logout() return LogoutAsync().Result; } + public IResult GetMediaById(string mediaId) + { + return GetMediaByIdAsync(mediaId).Result; + } + public IResult GetMediaByCode(string mediaCode) { return GetMediaByIdAsync(mediaCode).Result; } - public IResult GetUserTimelineFeed(int maxPages = 0) { return GetUserTimelineFeedAsync(maxPages).Result; @@ -149,11 +154,36 @@ public IResult UnlikeMedia(string mediaId) return UnLikeMediaAsync(mediaId).Result; } - public IResult FollowUser(long userId) + public IResult FollowUser(long userId) { return FollowUserAsync(userId).Result; } + public IResult UnFollowUser(long userId) + { + return UnFollowUserAsync(userId).Result; + } + + public IResult SetAccountPrivate() + { + return SetAccountPrivateAsync().Result; + } + + public IResult SetAccountPublic() + { + return SetAccountPublicAsync().Result; + } + + public IResult CommentMedia(string mediaId, string text) + { + return CommentMediaAsync(mediaId, text).Result; + } + + public IResult DeleteComment(string mediaId, string commentId) + { + return DeleteCommentAsync(mediaId, commentId).Result; + } + #endregion #region async part @@ -653,6 +683,269 @@ public async Task> CheckpointAsync(string checkPointUrl) return Result.Fail(GetBadStatusFromJsonString(json).Message, false); } + + public async Task> LikeMediaAsync(string mediaId) + { + return await LikeUnlikeMediaInternal(mediaId, UriCreator.GetLikeMediaUri(mediaId)); + } + + public async Task> UnLikeMediaAsync(string mediaId) + { + return await LikeUnlikeMediaInternal(mediaId, UriCreator.GetUnLikeMediaUri(mediaId)); + } + + + public async Task> LikeUnlikeMediaInternal(string mediaId, Uri instaUri) + { + ValidateUser(); + ValidateLoggedIn(); + try + { + var fields = new Dictionary + { + {"_uuid", _deviceInfo.DeviceGuid.ToString()}, + {"_uid", _user.LoggedInUder.Pk}, + {"_csrftoken", _user.CsrfToken}, + {"media_id", mediaId} + + }; + var request = HttpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, fields); + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.StatusCode == HttpStatusCode.OK) + return Result.Success(true); + var status = GetBadStatusFromJsonString(json); + return Result.Fail(status.Message, false); + } + catch (Exception exception) + { + return Result.Fail(exception.Message, false); + } + } + + public async Task> GetMediaCommentsAsync(string mediaId, int maxPages = 0) + { + ValidateUser(); + ValidateLoggedIn(); + try + { + if (maxPages == 0) maxPages = int.MaxValue; + var commentsUri = UriCreator.GetMediaCommentsUri(mediaId); + var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, commentsUri, _deviceInfo); + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.StatusCode != HttpStatusCode.OK) + return Result.Fail($"Unexpected response status: {response.StatusCode}", (InstaCommentList) null); + var commentListResponse = JsonConvert.DeserializeObject(json); + var converter = ConvertersFabric.GetCommentListConverter(commentListResponse); + var instaComments = converter.Convert(); + instaComments.Pages++; + var nextId = commentListResponse.NextMaxId; + var moreAvailable = commentListResponse.MoreComentsAvailable; + while (moreAvailable && instaComments.Pages < maxPages) + { + if (string.IsNullOrEmpty(nextId)) break; + var nextComments = await GetCommentListWithMaxIdAsync(mediaId, nextId); + if (!nextComments.Succeeded) + Result.Success($"Not all pages was downloaded: {nextComments.Info.Message}", instaComments); + nextId = nextComments.Value.NextMaxId; + moreAvailable = nextComments.Value.MoreComentsAvailable; + converter = ConvertersFabric.GetCommentListConverter(nextComments.Value); + instaComments.Comments.AddRange(converter.Convert().Comments); + instaComments.Pages++; + } + return Result.Success(instaComments); + } + catch (Exception exception) + { + return Result.Fail(exception); + } + } + + public async Task> GetMediaLikersAsync(string mediaId) + { + ValidateUser(); + ValidateLoggedIn(); + try + { + var likersUri = UriCreator.GetMediaLikersUri(mediaId); + var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, likersUri, _deviceInfo); + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.StatusCode != HttpStatusCode.OK) return Result.Fail("", (InstaUserList) null); + var instaUsers = new InstaUserList(); + var mediaLikersResponse = JsonConvert.DeserializeObject(json); + if (mediaLikersResponse.UsersCount < 1) return Result.Success(instaUsers); + instaUsers.AddRange( + mediaLikersResponse.Users.Select(ConvertersFabric.GetUserConverter) + .Select(converter => converter.Convert())); + return Result.Success(instaUsers); + } + catch (Exception exception) + { + return Result.Fail(exception); + } + } + + public async Task> FollowUserAsync(long userId) + { + return await FollowUnfollowUserInternal(userId, UriCreator.GetFollowUserUri(userId)); + } + + public async Task> UnFollowUserAsync(long userId) + { + return await FollowUnfollowUserInternal(userId, UriCreator.GetUnFollowUserUri(userId)); + } + + + public async Task> SetAccountPrivateAsync() + { + ValidateUser(); + ValidateLoggedIn(); + try + { + var instaUri = UriCreator.GetUriSetAccountPrivate(); + var fields = new Dictionary + { + {"_uuid", _deviceInfo.DeviceGuid.ToString()}, + {"_uid", _user.LoggedInUder.Pk}, + {"_csrftoken", _user.CsrfToken} + }; + var hash = CryptoHelper.CalculateHash(InstaApiConstants.IG_SIGNATURE_KEY, + JsonConvert.SerializeObject(fields)); + var payload = JsonConvert.SerializeObject(fields); + var signature = $"{hash}.{Uri.EscapeDataString(payload)}"; + var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo); + request.Content = new FormUrlEncodedContent(fields); + request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature); + request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, + InstaApiConstants.IG_SIGNATURE_KEY_VERSION); + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.StatusCode == HttpStatusCode.OK) + { + var userInfoUpdated = JsonConvert.DeserializeObject(json); + if (!userInfoUpdated.IsOk()) + return Result.Fail(GetBadStatusFromJsonString(json).Message); + var converter = ConvertersFabric.GetUserConverter(userInfoUpdated); + return Result.Success(converter.Convert()); + } + var status = GetBadStatusFromJsonString(json); + return Result.Fail(status.Message, (InstaUser) null); + } + catch (Exception exception) + { + return Result.Fail(exception.Message, (InstaUser) null); + } + } + + public async Task> SetAccountPublicAsync() + { + ValidateUser(); + ValidateLoggedIn(); + try + { + var instaUri = UriCreator.GetUriSetAccountPublic(); + var fields = new Dictionary + { + {"_uuid", _deviceInfo.DeviceGuid.ToString()}, + {"_uid", _user.LoggedInUder.Pk}, + {"_csrftoken", _user.CsrfToken} + }; + var hash = CryptoHelper.CalculateHash(InstaApiConstants.IG_SIGNATURE_KEY, + JsonConvert.SerializeObject(fields)); + var payload = JsonConvert.SerializeObject(fields); + var signature = $"{hash}.{Uri.EscapeDataString(payload)}"; + var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo); + request.Content = new FormUrlEncodedContent(fields); + request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature); + request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, + InstaApiConstants.IG_SIGNATURE_KEY_VERSION); + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.StatusCode == HttpStatusCode.OK) + { + var userInfoUpdated = JsonConvert.DeserializeObject(json); + if (!userInfoUpdated.IsOk()) + return Result.Fail(GetBadStatusFromJsonString(json).Message); + var converter = ConvertersFabric.GetUserConverter(userInfoUpdated); + return Result.Success(converter.Convert()); + } + var status = GetBadStatusFromJsonString(json); + return Result.Fail(status.Message, (InstaUser) null); + } + catch (Exception exception) + { + return Result.Fail(exception.Message, (InstaUser) null); + } + } + + + public async Task> CommentMediaAsync(string mediaId, string text) + { + ValidateUser(); + ValidateLoggedIn(); + try + { + var instaUri = UriCreator.GetPostCommetUri(mediaId); + var breadcrumb = CryptoHelper.GetCommentBreadCrumbEncoded(text); + var fields = new Dictionary + { + {"user_breadcrumb", breadcrumb}, + {"idempotence_token", Guid.NewGuid().ToString()}, + {"_uuid", _deviceInfo.DeviceGuid.ToString()}, + {"_uid", _user.LoggedInUder.Pk}, + {"_csrftoken", _user.CsrfToken}, + {"comment_text", text}, + {"containermodule", "comments_feed_timeline"}, + {"radio_type", "wifi-none"} + }; + var request = HttpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, fields); + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.StatusCode == HttpStatusCode.OK) + { + var commentResponse = JsonConvert.DeserializeObject(json, + new InstaCommentDataConverter()); + var converter = ConvertersFabric.GetCommentConverter(commentResponse); + return Result.Success(converter.Convert()); + } + var status = GetBadStatusFromJsonString(json); + return Result.Fail(status.Message, (InstaComment) null); + } + catch (Exception exception) + { + return Result.Fail(exception.Message, (InstaComment) null); + } + } + + public async Task> DeleteCommentAsync(string mediaId, string commentId) + { + ValidateUser(); + ValidateLoggedIn(); + try + { + var instaUri = UriCreator.GetDeleteCommetUri(mediaId, commentId); + var fields = new Dictionary + { + {"_uuid", _deviceInfo.DeviceGuid.ToString()}, + {"_uid", _user.LoggedInUder.Pk}, + {"_csrftoken", _user.CsrfToken} + }; + var request = HttpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, fields); + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.StatusCode == HttpStatusCode.OK) + return Result.Success(true); + var status = GetBadStatusFromJsonString(json); + return Result.Fail(status.Message, false); + } + catch (Exception exception) + { + return Result.Fail(exception.Message, false); + } + } + #endregion #region private part @@ -679,7 +972,9 @@ private BadStatusResponse GetBadStatusFromJsonString(string json) var badStatus = new BadStatusResponse(); try { - badStatus = JsonConvert.DeserializeObject(json); + if (json == "Oops, an error occurred\n") + badStatus.Message = json; + else badStatus = JsonConvert.DeserializeObject(json); } catch (Exception ex) { @@ -838,139 +1133,39 @@ private async Task> GetCommentListWithMaxIdAsy return Result.Fail("", (InstaCommentListResponse) null); } - public async Task> LikeMediaAsync(string mediaId) + private async Task> FollowUnfollowUserInternal(long userId, Uri instaUri) { ValidateUser(); ValidateLoggedIn(); try { - var instaUri = UriCreator.GetLikeMediaUri(mediaId); - var signature = $"{_requestMessage.GenerateSignature()}.{_requestMessage.GetMessageString()}"; var fields = new Dictionary { - {InstaApiConstants.HEADER_IG_SIGNATURE, signature}, - {InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, InstaApiConstants.IG_SIGNATURE_KEY_VERSION} + {"_uuid", _deviceInfo.DeviceGuid.ToString()}, + {"_uid", _user.LoggedInUder.Pk}, + {"_csrftoken", _user.CsrfToken}, + {"user_id", userId.ToString()}, + {"radio_type", "wifi-none"} }; - var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo); - request.Content = new FormUrlEncodedContent(fields); - request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature); - request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, - InstaApiConstants.IG_SIGNATURE_KEY_VERSION); + var request = HttpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, fields); var response = await _httpClient.SendAsync(request); var json = await response.Content.ReadAsStringAsync(); - if (response.StatusCode == HttpStatusCode.OK) + if (response.StatusCode == HttpStatusCode.OK && !string.IsNullOrEmpty(json)) { - return Result.Success(true); + var friendshipStatus = JsonConvert.DeserializeObject(json, + new InstaFriendShipDataConverter()); + var converter = ConvertersFabric.GetFriendShipStatusConverter(friendshipStatus); + return Result.Success(converter.Convert()); } - var loginInfo = GetBadStatusFromJsonString(json); - return Result.Fail(loginInfo.Message, false); + var status = GetBadStatusFromJsonString(json); + return Result.Fail(status.Message, (InstaFriendshipStatus) null); } catch (Exception exception) { - return Result.Fail(exception.Message, false); + return Result.Fail(exception.Message, (InstaFriendshipStatus) null); } } - public async Task> UnLikeMediaAsync(string mediaId) - { - ValidateUser(); - ValidateLoggedIn(); - try - { - var signature = $"{_requestMessage.GenerateSignature()}.{_requestMessage.GetMessageString()}"; - var fields = new Dictionary - { - {InstaApiConstants.HEADER_IG_SIGNATURE, signature}, - {InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, InstaApiConstants.IG_SIGNATURE_KEY_VERSION} - }; - var instaUri = UriCreator.GetUnLikeMediaUri(mediaId); - var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo); - request.Content = new FormUrlEncodedContent(fields); - request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature); - request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, - InstaApiConstants.IG_SIGNATURE_KEY_VERSION); - var response = await _httpClient.SendAsync(request); - var json = await response.Content.ReadAsStringAsync(); - if (response.StatusCode == HttpStatusCode.OK) - return Result.Success(true); - var loginInfo = GetBadStatusFromJsonString(json); - return Result.Fail(loginInfo.Message, false); - } - catch (Exception exception) - { - return Result.Fail(exception.Message, false); - } - } - - public async Task> GetMediaCommentsAsync(string mediaId, int maxPages = 0) - { - ValidateUser(); - ValidateLoggedIn(); - try - { - if (maxPages == 0) maxPages = int.MaxValue; - var commentsUri = UriCreator.GetMediaCommentsUri(mediaId); - var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, commentsUri, _deviceInfo); - var response = await _httpClient.SendAsync(request); - var json = await response.Content.ReadAsStringAsync(); - if (response.StatusCode != HttpStatusCode.OK) - return Result.Fail($"Unexpected response status: {response.StatusCode}", (InstaCommentList) null); - var commentListResponse = JsonConvert.DeserializeObject(json); - var converter = ConvertersFabric.GetCommentListConverter(commentListResponse); - var instaComments = converter.Convert(); - instaComments.Pages++; - var nextId = commentListResponse.NextMaxId; - var moreAvailable = commentListResponse.MoreComentsAvailable; - while (moreAvailable && instaComments.Pages < maxPages) - { - if (string.IsNullOrEmpty(nextId)) break; - var nextComments = await GetCommentListWithMaxIdAsync(mediaId, nextId); - if (!nextComments.Succeeded) - Result.Success($"Not all pages was downloaded: {nextComments.Info.Message}", instaComments); - nextId = nextComments.Value.NextMaxId; - moreAvailable = nextComments.Value.MoreComentsAvailable; - converter = ConvertersFabric.GetCommentListConverter(nextComments.Value); - instaComments.Comments.AddRange(converter.Convert().Comments); - instaComments.Pages++; - } - return Result.Success(instaComments); - } - catch (Exception exception) - { - return Result.Fail(exception); - } - } - - public async Task> GetMediaLikersAsync(string mediaId) - { - ValidateUser(); - ValidateLoggedIn(); - try - { - var likersUri = UriCreator.GetMediaLikersUri(mediaId); - var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, likersUri, _deviceInfo); - var response = await _httpClient.SendAsync(request); - var json = await response.Content.ReadAsStringAsync(); - if (response.StatusCode != HttpStatusCode.OK) return Result.Fail("", (InstaUserList) null); - var instaUsers = new InstaUserList(); - var mediaLikersResponse = JsonConvert.DeserializeObject(json); - if (mediaLikersResponse.UsersCount < 1) return Result.Success(instaUsers); - instaUsers.AddRange( - mediaLikersResponse.Users.Select(ConvertersFabric.GetUserConverter) - .Select(converter => converter.Convert())); - return Result.Success(instaUsers); - } - catch (Exception exception) - { - return Result.Fail(exception); - } - } - - public async Task> FollowUserAsync(long userId) - { - throw new NotImplementedException(); - } - #endregion } } \ No newline at end of file diff --git a/InstaSharper/API/InstaApiConstants.cs b/InstaSharper/API/InstaApiConstants.cs index 5cc71972..281747b8 100644 --- a/InstaSharper/API/InstaApiConstants.cs +++ b/InstaSharper/API/InstaApiConstants.cs @@ -37,22 +37,29 @@ internal static class InstaApiConstants public const string MEDIA_COMMENTS = API_SUFFIX + "/v1/media/{0}/comments/"; public const string MEDIA_LIKERS = API_SUFFIX + "/v1/media/{0}/likers/"; public const string FOLLOW_USER = API_SUFFIX + "/v1/friendships/create/{0}/"; + public const string UNFOLLOW_USER = API_SUFFIX + "/v1/friendships/destroy/{0}/"; + public const string SET_ACCOUNT_PRIVATE = API_SUFFIX + "/v1/accounts/set_private/"; + public const string SET_ACCOUNT_PUBLIC = API_SUFFIX + "/v1/accounts/set_public/"; + public const string POST_COMMENT = API_SUFFIX + "/v1/media/{0}/comment/"; + public const string ALLOW_MEDIA_COMMENTS = API_SUFFIX + "/v1/media/{0}/enable_comments/"; + public const string DISABLE_MEDIA_COMMENTS = API_SUFFIX + "/v1/media/{0}/disable_comments/"; + public const string DELETE_COMMENT = API_SUFFIX + "/v1/media/{0}/comment/{1}/delete/"; public const string HEADER_USER_AGENT = "User-Agent"; public const string USER_AGENT = - "Instagram 10.8.0 Android (23/6.0.1; 640dpi; 1440x2560; samsung; SM-G935F; hero2lte; samsungexynos8890; en_NZ)"; + "Instagram 10.15.0 Android (23/6.0.1; 640dpi; 1440x2560; samsung; SM-G935F; hero2lte; samsungexynos8890; en_NZ)"; public const string HEADER_QUERY = "q"; public const string HEADER_RANK_TOKEN = "rank_token"; public const string HEADER_COUNT = "count"; - public const string IG_SIGNATURE_KEY = "68a04945eb02970e2e8d15266fc256f7295da123e123f44b88f09d594a5902df"; + public const string IG_SIGNATURE_KEY = "b03e0daaf2ab17cda2a569cace938d639d1288a1197f9ecf97efd0a4ec0874d7"; public const string HEADER_IG_SIGNATURE = "signed_body"; public const string IG_SIGNATURE_KEY_VERSION = "4"; public const string HEADER_IG_SIGNATURE_KEY_VERSION = "ig_sig_key_version"; - public const string IG_CAPABILITIES = "3ToAAA=="; + public const string IG_CAPABILITIES = "3boBAA=="; public const string HEADER_IG_CAPABILITIES = "X-IG-Capabilities"; public const string IG_CONNECTION_TYPE = "WIFI"; public const string HEADER_IG_CONNECTION_TYPE = "X-IG-Connection-Type"; @@ -64,6 +71,7 @@ internal static class InstaApiConstants public const string HEADER_PHONE_ID = "phone_id"; public const string HEADER_TIMEZONE = "timezone_offset"; public const string HEADER_XGOOGLE_AD_IDE = "X-Google-AD-ID"; + public const string COMMENT_BREADCRUMB_KEY = "iN4$aGr0m"; public const int TIMEZONE_OFFSET = 43200; } diff --git a/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs b/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs index fb8b0c07..49f53623 100644 --- a/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs +++ b/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs @@ -35,7 +35,7 @@ internal bool IsEmpty() internal static string GenerateDeviceId() { - var hashedGuid = CryptoHelper.CalculateMD5(Guid.NewGuid().ToString()); + var hashedGuid = CryptoHelper.CalculateMd5(Guid.NewGuid().ToString()); return $"android-{hashedGuid.Substring(0, 16)}"; } } diff --git a/InstaSharper/Classes/Models/Images.cs b/InstaSharper/Classes/Models/Images.cs index 9bb22e44..2e00813e 100644 --- a/InstaSharper/Classes/Models/Images.cs +++ b/InstaSharper/Classes/Models/Images.cs @@ -2,10 +2,10 @@ { public class Images { - public Image LowResolution { get; set; } + public MediaImage LowResolution { get; set; } - public Image Thumbnail { get; set; } + public MediaImage Thumbnail { get; set; } - public Image StandartResolution { get; set; } + public MediaImage StandartResolution { get; set; } } } \ No newline at end of file diff --git a/InstaSharper/Classes/Models/InstaCarousel.cs b/InstaSharper/Classes/Models/InstaCarousel.cs new file mode 100644 index 00000000..9ccc1254 --- /dev/null +++ b/InstaSharper/Classes/Models/InstaCarousel.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace InstaSharper.Classes.Models +{ + public class InstaCarousel : List + { + } +} \ No newline at end of file diff --git a/InstaSharper/Classes/Models/InstaCarouselItem.cs b/InstaSharper/Classes/Models/InstaCarouselItem.cs new file mode 100644 index 00000000..830fd254 --- /dev/null +++ b/InstaSharper/Classes/Models/InstaCarouselItem.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace InstaSharper.Classes.Models +{ + public class InstaCarouselItem + { + public string InstaIdentifier { get; set; } + + public InstaMediaType MediaType { get; set; } + + public List Images { get; set; } = new List(); + + public int Width { get; set; } + + public int Height { get; set; } + + public string Pk { get; set; } + + public string CarouselParentId { get; set; } + } +} \ No newline at end of file diff --git a/InstaSharper/Classes/Models/InstaFriendshipStatus.cs b/InstaSharper/Classes/Models/InstaFriendshipStatus.cs index afad47fc..1fa869fe 100644 --- a/InstaSharper/Classes/Models/InstaFriendshipStatus.cs +++ b/InstaSharper/Classes/Models/InstaFriendshipStatus.cs @@ -2,9 +2,10 @@ { public class InstaFriendshipStatus { - public bool Foolowing { get; set; } + public bool Following { get; set; } public bool IsPrivate { get; set; } - + public bool FollowedBy { get; set; } + public bool Blocking { get; set; } public bool IncomingRequest { get; set; } public bool OutgoingRequest { get; set; } diff --git a/InstaSharper/Classes/Models/InstaMedia.cs b/InstaSharper/Classes/Models/InstaMedia.cs index 5ec85af7..4112e0a1 100644 --- a/InstaSharper/Classes/Models/InstaMedia.cs +++ b/InstaSharper/Classes/Models/InstaMedia.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using InstaSharper.Converters; namespace InstaSharper.Classes.Models { @@ -19,7 +20,7 @@ public class InstaMedia public string FilterType { get; set; } - public List Images { get; set; } = new List(); + public List Images { get; set; } = new List(); public int Width { get; set; } @@ -50,5 +51,8 @@ public class InstaMedia public List Tags { get; set; } = new List(); public InstaUserList Likers { get; set; } = new InstaUserList(); + public InstaCarousel Carousel { get; set; } + + public bool IsMultiPost => Carousel != null; } } \ No newline at end of file diff --git a/InstaSharper/Classes/Models/InstaRecipients.cs b/InstaSharper/Classes/Models/InstaRecipients.cs index e4d1f34b..a252c4e0 100644 --- a/InstaSharper/Classes/Models/InstaRecipients.cs +++ b/InstaSharper/Classes/Models/InstaRecipients.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; namespace InstaSharper.Classes.Models { diff --git a/InstaSharper/Classes/Models/Image.cs b/InstaSharper/Classes/Models/MediaImage.cs similarity index 74% rename from InstaSharper/Classes/Models/Image.cs rename to InstaSharper/Classes/Models/MediaImage.cs index 4ff173fd..76e93259 100644 --- a/InstaSharper/Classes/Models/Image.cs +++ b/InstaSharper/Classes/Models/MediaImage.cs @@ -1,8 +1,8 @@ namespace InstaSharper.Classes.Models { - public class Image + public class MediaImage { - public Image(string url, string width, string height) + public MediaImage(string url, string width, string height) { Url = url; Width = width; diff --git a/InstaSharper/Classes/ResponseType.cs b/InstaSharper/Classes/ResponseType.cs new file mode 100644 index 00000000..5032efcc --- /dev/null +++ b/InstaSharper/Classes/ResponseType.cs @@ -0,0 +1,10 @@ +namespace InstaSharper.Classes +{ + public enum ResponseType + { + Unknown = 0, + LoginRequired = 1, + CheckPointRequired = 2, + RequestsLimit = 3 + } +} \ No newline at end of file diff --git a/InstaSharper/ResponseWrappers/BadStatusResponse.cs b/InstaSharper/Classes/ResponseWrappers/BadStatusResponse.cs similarity index 76% rename from InstaSharper/ResponseWrappers/BadStatusResponse.cs rename to InstaSharper/Classes/ResponseWrappers/BadStatusResponse.cs index 2645cc9c..a37c8d75 100644 --- a/InstaSharper/ResponseWrappers/BadStatusResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/BadStatusResponse.cs @@ -1,7 +1,7 @@ -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class BadStatusResponse : BaseStatusResponse { diff --git a/InstaSharper/ResponseWrappers/BaseResponse/BaseLoadableResponse.cs b/InstaSharper/Classes/ResponseWrappers/BaseResponse/BaseLoadableResponse.cs similarity index 90% rename from InstaSharper/ResponseWrappers/BaseResponse/BaseLoadableResponse.cs rename to InstaSharper/Classes/ResponseWrappers/BaseResponse/BaseLoadableResponse.cs index 42c73d3a..8f39ac44 100644 --- a/InstaSharper/ResponseWrappers/BaseResponse/BaseLoadableResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/BaseResponse/BaseLoadableResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers.BaseResponse +namespace InstaSharper.Classes.ResponseWrappers.BaseResponse { internal class BaseLoadableResponse : BaseStatusResponse { diff --git a/InstaSharper/Classes/ResponseWrappers/BaseResponse/BaseStatusResponse.cs b/InstaSharper/Classes/ResponseWrappers/BaseResponse/BaseStatusResponse.cs new file mode 100644 index 00000000..c8be7159 --- /dev/null +++ b/InstaSharper/Classes/ResponseWrappers/BaseResponse/BaseStatusResponse.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json; + +namespace InstaSharper.Classes.ResponseWrappers.BaseResponse +{ + public class BaseStatusResponse + { + [JsonProperty("status")] + public string Status { get; set; } + + public bool IsOk() + { + return !string.IsNullOrEmpty(Status) && Status.ToLower() == "ok"; + } + + public bool IsFail() + { + return !string.IsNullOrEmpty(Status) && Status.ToLower() == "fail"; + } + } +} \ No newline at end of file diff --git a/InstaSharper/ResponseWrappers/FollowedByResponse.cs b/InstaSharper/Classes/ResponseWrappers/FollowedByResponse.cs similarity index 75% rename from InstaSharper/ResponseWrappers/FollowedByResponse.cs rename to InstaSharper/Classes/ResponseWrappers/FollowedByResponse.cs index 66a38e40..3b07d147 100644 --- a/InstaSharper/ResponseWrappers/FollowedByResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/FollowedByResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class FollowedByResponse { diff --git a/InstaSharper/ResponseWrappers/ImageResponse.cs b/InstaSharper/Classes/ResponseWrappers/ImageResponse.cs similarity index 86% rename from InstaSharper/ResponseWrappers/ImageResponse.cs rename to InstaSharper/Classes/ResponseWrappers/ImageResponse.cs index efa259dd..c9a2a388 100644 --- a/InstaSharper/ResponseWrappers/ImageResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/ImageResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class ImageResponse { diff --git a/InstaSharper/ResponseWrappers/ImagesResponse.cs b/InstaSharper/Classes/ResponseWrappers/ImagesResponse.cs similarity index 88% rename from InstaSharper/ResponseWrappers/ImagesResponse.cs rename to InstaSharper/Classes/ResponseWrappers/ImagesResponse.cs index 4dfd6b7c..a091cebf 100644 --- a/InstaSharper/ResponseWrappers/ImagesResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/ImagesResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class ImagesResponse { diff --git a/InstaSharper/ResponseWrappers/InstaCaptionResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaCaptionResponse.cs similarity index 87% rename from InstaSharper/ResponseWrappers/InstaCaptionResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaCaptionResponse.cs index 33b83865..0a988a37 100644 --- a/InstaSharper/ResponseWrappers/InstaCaptionResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaCaptionResponse.cs @@ -1,7 +1,7 @@ -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaCaptionResponse : BaseStatusResponse { diff --git a/InstaSharper/Classes/ResponseWrappers/InstaCarouselItemResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaCarouselItemResponse.cs new file mode 100644 index 00000000..f9c4fac4 --- /dev/null +++ b/InstaSharper/Classes/ResponseWrappers/InstaCarouselItemResponse.cs @@ -0,0 +1,29 @@ +using InstaSharper.Classes.Models; +using Newtonsoft.Json; + +namespace InstaSharper.Classes.ResponseWrappers +{ + internal class InstaCarouselItemResponse + { + [JsonProperty("id")] + public string InstaIdentifier { get; set; } + + [JsonProperty("media_type")] + public InstaMediaType MediaType { get; set; } + + [JsonProperty("image_versions2")] + public InstaImageCandidatesResponse Images { get; set; } + + [JsonProperty("original_width")] + public string Width { get; set; } + + [JsonProperty("original_height")] + public string Height { get; set; } + + [JsonProperty("pk")] + public string Pk { get; set; } + + [JsonProperty("carousel_parent_id")] + public string CarouselParentId { get; set; } + } +} \ No newline at end of file diff --git a/InstaSharper/Classes/ResponseWrappers/InstaCarouselResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaCarouselResponse.cs new file mode 100644 index 00000000..70803cd4 --- /dev/null +++ b/InstaSharper/Classes/ResponseWrappers/InstaCarouselResponse.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace InstaSharper.Classes.ResponseWrappers +{ + internal class InstaCarouselResponse : List + { + } +} \ No newline at end of file diff --git a/InstaSharper/ResponseWrappers/InstaCommentListResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaCommentListResponse.cs similarity index 89% rename from InstaSharper/ResponseWrappers/InstaCommentListResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaCommentListResponse.cs index 0dd2f3d3..0c25e21e 100644 --- a/InstaSharper/ResponseWrappers/InstaCommentListResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaCommentListResponse.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaCommentListResponse : BaseStatusResponse { diff --git a/InstaSharper/ResponseWrappers/InstaCommentResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaCommentResponse.cs similarity index 95% rename from InstaSharper/ResponseWrappers/InstaCommentResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaCommentResponse.cs index 394764a8..bd95700c 100644 --- a/InstaSharper/ResponseWrappers/InstaCommentResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaCommentResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaCommentResponse { diff --git a/InstaSharper/ResponseWrappers/InstaCurrentUserResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaCurrentUserResponse.cs similarity index 63% rename from InstaSharper/ResponseWrappers/InstaCurrentUserResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaCurrentUserResponse.cs index d980e0f3..92c94638 100644 --- a/InstaSharper/ResponseWrappers/InstaCurrentUserResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaCurrentUserResponse.cs @@ -1,7 +1,7 @@ -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaCurrentUserResponse : BaseStatusResponse { diff --git a/InstaSharper/ResponseWrappers/InstaDirectInboxContainerResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxContainerResponse.cs similarity index 86% rename from InstaSharper/ResponseWrappers/InstaDirectInboxContainerResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaDirectInboxContainerResponse.cs index a2d3e440..8c18b544 100644 --- a/InstaSharper/ResponseWrappers/InstaDirectInboxContainerResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxContainerResponse.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaDirectInboxContainerResponse : BaseStatusResponse { diff --git a/InstaSharper/ResponseWrappers/InstaDirectInboxItemResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxItemResponse.cs similarity index 86% rename from InstaSharper/ResponseWrappers/InstaDirectInboxItemResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaDirectInboxItemResponse.cs index 33417575..28d81abb 100644 --- a/InstaSharper/ResponseWrappers/InstaDirectInboxItemResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxItemResponse.cs @@ -1,8 +1,8 @@ using System; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaDirectInboxItemResponse : BaseStatusResponse { diff --git a/InstaSharper/ResponseWrappers/InstaDirectInboxResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxResponse.cs similarity index 90% rename from InstaSharper/ResponseWrappers/InstaDirectInboxResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaDirectInboxResponse.cs index 6c2e8756..51c17d8f 100644 --- a/InstaSharper/ResponseWrappers/InstaDirectInboxResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxResponse.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaDirectInboxResponse { diff --git a/InstaSharper/ResponseWrappers/InstaDirectInboxSubscriptionResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxSubscriptionResponse.cs similarity index 89% rename from InstaSharper/ResponseWrappers/InstaDirectInboxSubscriptionResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaDirectInboxSubscriptionResponse.cs index 78c93e62..5a9573c7 100644 --- a/InstaSharper/ResponseWrappers/InstaDirectInboxSubscriptionResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxSubscriptionResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaDirectInboxSubscriptionResponse { diff --git a/InstaSharper/ResponseWrappers/InstaDirectInboxThreadResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxThreadResponse.cs similarity index 93% rename from InstaSharper/ResponseWrappers/InstaDirectInboxThreadResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaDirectInboxThreadResponse.cs index 1eabbdfe..65d97e7d 100644 --- a/InstaSharper/ResponseWrappers/InstaDirectInboxThreadResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaDirectInboxThreadResponse.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaDirectInboxThreadResponse : BaseStatusResponse { diff --git a/InstaSharper/ResponseWrappers/InstaFeedResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaFeedResponse.cs similarity index 79% rename from InstaSharper/ResponseWrappers/InstaFeedResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaFeedResponse.cs index 6965f268..99fd4063 100644 --- a/InstaSharper/ResponseWrappers/InstaFeedResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaFeedResponse.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaFeedResponse : BaseLoadableResponse { diff --git a/InstaSharper/ResponseWrappers/InstaFollowersResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaFollowersResponse.cs similarity index 84% rename from InstaSharper/ResponseWrappers/InstaFollowersResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaFollowersResponse.cs index 3f4da6eb..80b9d086 100644 --- a/InstaSharper/ResponseWrappers/InstaFollowersResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaFollowersResponse.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaFollowersResponse : BaseStatusResponse { diff --git a/InstaSharper/Classes/ResponseWrappers/InstaFriendshipStatusResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaFriendshipStatusResponse.cs new file mode 100644 index 00000000..116dce27 --- /dev/null +++ b/InstaSharper/Classes/ResponseWrappers/InstaFriendshipStatusResponse.cs @@ -0,0 +1,26 @@ +using InstaSharper.Classes.ResponseWrappers.BaseResponse; +using Newtonsoft.Json; + +namespace InstaSharper.Classes.ResponseWrappers +{ + internal class InstaFriendshipStatusResponse : BaseStatusResponse + { + [JsonProperty("following")] + public bool Following { get; set; } + + [JsonProperty("followed_by")] + public bool FollowedBy { get; set; } + + [JsonProperty("blocking")] + public bool Blocking { get; set; } + + [JsonProperty("is_private")] + public bool IsPrivate { get; set; } + + [JsonProperty("incoming_request")] + public bool IncomingRequest { get; set; } + + [JsonProperty("outgoing_request")] + public bool OutgoingRequest { get; set; } + } +} \ No newline at end of file diff --git a/InstaSharper/ResponseWrappers/InstaImageCandidatesResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaImageCandidatesResponse.cs similarity index 82% rename from InstaSharper/ResponseWrappers/InstaImageCandidatesResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaImageCandidatesResponse.cs index 42f2257a..19ea185f 100644 --- a/InstaSharper/ResponseWrappers/InstaImageCandidatesResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaImageCandidatesResponse.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaImageCandidatesResponse { diff --git a/InstaSharper/ResponseWrappers/InstaInlineFollowResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaInlineFollowResponse.cs similarity index 88% rename from InstaSharper/ResponseWrappers/InstaInlineFollowResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaInlineFollowResponse.cs index b132d067..26f6f2f6 100644 --- a/InstaSharper/ResponseWrappers/InstaInlineFollowResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaInlineFollowResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaInlineFollowResponse { diff --git a/InstaSharper/ResponseWrappers/InstaLinkResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaLinkResponse.cs similarity index 88% rename from InstaSharper/ResponseWrappers/InstaLinkResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaLinkResponse.cs index 82710099..b4aa1b3e 100644 --- a/InstaSharper/ResponseWrappers/InstaLinkResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaLinkResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaLinkResponse { diff --git a/InstaSharper/ResponseWrappers/InstaLoginResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaLoginResponse.cs similarity index 83% rename from InstaSharper/ResponseWrappers/InstaLoginResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaLoginResponse.cs index be5aeab5..4dc07064 100644 --- a/InstaSharper/ResponseWrappers/InstaLoginResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaLoginResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaLoginResponse { diff --git a/InstaSharper/ResponseWrappers/InstaMediaItemResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaMediaItemResponse.cs similarity index 93% rename from InstaSharper/ResponseWrappers/InstaMediaItemResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaMediaItemResponse.cs index 79cea2f4..71161e77 100644 --- a/InstaSharper/ResponseWrappers/InstaMediaItemResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaMediaItemResponse.cs @@ -2,7 +2,7 @@ using InstaSharper.Classes.Models; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaMediaItemResponse { @@ -72,5 +72,8 @@ internal class InstaMediaItemResponse [JsonProperty("likers")] public List Likers { get; set; } + + [JsonProperty("carousel_media")] + public InstaCarouselResponse CarouselMedia { get; set; } } } \ No newline at end of file diff --git a/InstaSharper/ResponseWrappers/InstaMediaLikersResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaMediaLikersResponse.cs similarity index 86% rename from InstaSharper/ResponseWrappers/InstaMediaLikersResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaMediaLikersResponse.cs index 761116a1..6940903e 100644 --- a/InstaSharper/ResponseWrappers/InstaMediaLikersResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaMediaLikersResponse.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaMediaLikersResponse : BadStatusResponse { diff --git a/InstaSharper/ResponseWrappers/InstaMediaListResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaMediaListResponse.cs similarity index 77% rename from InstaSharper/ResponseWrappers/InstaMediaListResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaMediaListResponse.cs index 4d116b8a..47d5a147 100644 --- a/InstaSharper/ResponseWrappers/InstaMediaListResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaMediaListResponse.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaMediaListResponse : BaseLoadableResponse { diff --git a/InstaSharper/ResponseWrappers/InstaRecentActivityFeedResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaRecentActivityFeedResponse.cs similarity index 87% rename from InstaSharper/ResponseWrappers/InstaRecentActivityFeedResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaRecentActivityFeedResponse.cs index 899fb34d..9d7b357a 100644 --- a/InstaSharper/ResponseWrappers/InstaRecentActivityFeedResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaRecentActivityFeedResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaRecentActivityFeedResponse { diff --git a/InstaSharper/ResponseWrappers/InstaRecentActivityResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaRecentActivityResponse.cs similarity index 77% rename from InstaSharper/ResponseWrappers/InstaRecentActivityResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaRecentActivityResponse.cs index 76b37a43..18fb5a23 100644 --- a/InstaSharper/ResponseWrappers/InstaRecentActivityResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaRecentActivityResponse.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaRecentActivityResponse : BaseLoadableResponse { diff --git a/InstaSharper/ResponseWrappers/InstaRecentActivityStoryItemResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaRecentActivityStoryItemResponse.cs similarity index 93% rename from InstaSharper/ResponseWrappers/InstaRecentActivityStoryItemResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaRecentActivityStoryItemResponse.cs index 795c529f..dabe325d 100644 --- a/InstaSharper/ResponseWrappers/InstaRecentActivityStoryItemResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaRecentActivityStoryItemResponse.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaRecentActivityStoryItemResponse { diff --git a/InstaSharper/ResponseWrappers/InstaRecipientsResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaRecipientsResponse.cs similarity index 75% rename from InstaSharper/ResponseWrappers/InstaRecipientsResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaRecipientsResponse.cs index 79cb9355..12e3d603 100644 --- a/InstaSharper/ResponseWrappers/InstaRecipientsResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaRecipientsResponse.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using InstaSharper.ResponseWrappers.BaseResponse; +using InstaSharper.Classes.ResponseWrappers.BaseResponse; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaRecipientsResponse : BaseStatusResponse { diff --git a/InstaSharper/ResponseWrappers/InstaSearchUserResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaSearchUserResponse.cs similarity index 88% rename from InstaSharper/ResponseWrappers/InstaSearchUserResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaSearchUserResponse.cs index c5535369..fd478469 100644 --- a/InstaSharper/ResponseWrappers/InstaSearchUserResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaSearchUserResponse.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaSearchUserResponse { diff --git a/InstaSharper/ResponseWrappers/InstaStoryResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaStoryResponse.cs similarity index 94% rename from InstaSharper/ResponseWrappers/InstaStoryResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaStoryResponse.cs index c211f3c1..1e31f442 100644 --- a/InstaSharper/ResponseWrappers/InstaStoryResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaStoryResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaStoryResponse { diff --git a/InstaSharper/ResponseWrappers/InstaTagFeedResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaTagFeedResponse.cs similarity index 82% rename from InstaSharper/ResponseWrappers/InstaTagFeedResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaTagFeedResponse.cs index 788af637..24b50e8d 100644 --- a/InstaSharper/ResponseWrappers/InstaTagFeedResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaTagFeedResponse.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaTagFeedResponse { diff --git a/InstaSharper/ResponseWrappers/InstaUserResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaUserResponse.cs similarity index 92% rename from InstaSharper/ResponseWrappers/InstaUserResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaUserResponse.cs index a676069a..814579ed 100644 --- a/InstaSharper/ResponseWrappers/InstaUserResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaUserResponse.cs @@ -1,8 +1,8 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { - internal class InstaUserResponse + internal class InstaUserResponse : BadStatusResponse { [JsonProperty("username")] public string UserName { get; set; } diff --git a/InstaSharper/ResponseWrappers/InstaUserTagListResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaUserTagListResponse.cs similarity index 83% rename from InstaSharper/ResponseWrappers/InstaUserTagListResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaUserTagListResponse.cs index ff3eadcf..a5c0ffc1 100644 --- a/InstaSharper/ResponseWrappers/InstaUserTagListResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaUserTagListResponse.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaUserTagListResponse { diff --git a/InstaSharper/ResponseWrappers/InstaUserTagResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaUserTagResponse.cs similarity index 87% rename from InstaSharper/ResponseWrappers/InstaUserTagResponse.cs rename to InstaSharper/Classes/ResponseWrappers/InstaUserTagResponse.cs index 54d3105e..4bbdbfec 100644 --- a/InstaSharper/ResponseWrappers/InstaUserTagResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaUserTagResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace InstaSharper.ResponseWrappers +namespace InstaSharper.Classes.ResponseWrappers { internal class InstaUserTagResponse { diff --git a/InstaSharper/Classes/Result.cs b/InstaSharper/Classes/Result.cs index ab5cc5b3..be178deb 100644 --- a/InstaSharper/Classes/Result.cs +++ b/InstaSharper/Classes/Result.cs @@ -28,38 +28,6 @@ public Result(bool succeeded, T value) public ResultInfo Info { get; } = new ResultInfo(""); } - public class ResultInfo - { - public ResultInfo(string message) - { - Message = message; - } - - public ResultInfo(Exception exception) - { - Exception = exception; - } - - public ResultInfo(ResponseType responseType) - { - ResponseType = responseType; - } - - public Exception Exception { get; } - - public string Message { get; } - - public ResponseType ResponseType { get; } - } - - public enum ResponseType - { - Unknown = 0, - LoginRequired = 1, - CheckPointRequired = 2, - RequestsLimit = 3 - } - public static class Result { public static IResult Success(T resValue) diff --git a/InstaSharper/Classes/ResultInfo.cs b/InstaSharper/Classes/ResultInfo.cs new file mode 100644 index 00000000..7cb8b268 --- /dev/null +++ b/InstaSharper/Classes/ResultInfo.cs @@ -0,0 +1,28 @@ +using System; + +namespace InstaSharper.Classes +{ + public class ResultInfo + { + public ResultInfo(string message) + { + Message = message; + } + + public ResultInfo(Exception exception) + { + Exception = exception; + } + + public ResultInfo(ResponseType responseType) + { + ResponseType = responseType; + } + + public Exception Exception { get; } + + public string Message { get; } + + public ResponseType ResponseType { get; } + } +} \ No newline at end of file diff --git a/InstaSharper/Converters/ConvertersFabric.cs b/InstaSharper/Converters/ConvertersFabric.cs index 086d1997..5b133326 100644 --- a/InstaSharper/Converters/ConvertersFabric.cs +++ b/InstaSharper/Converters/ConvertersFabric.cs @@ -1,5 +1,5 @@ using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { @@ -98,5 +98,17 @@ public static IObjectConverter GetCo { return new InstaCommentListConverter {SourceObject = commentList}; } + + public static IObjectConverter GetCarouselConverter( + InstaCarouselResponse carousel) + { + return new InstaCarouselConverter {SourceObject = carousel}; + } + + public static IObjectConverter GetCarouselItemConverter( + InstaCarouselItemResponse carouselItem) + { + return new InstaCarouselItemConverter {SourceObject = carouselItem}; + } } } \ No newline at end of file diff --git a/InstaSharper/Converters/InstaCaptionConverter.cs b/InstaSharper/Converters/InstaCaptionConverter.cs index 1d205963..ac91c897 100644 --- a/InstaSharper/Converters/InstaCaptionConverter.cs +++ b/InstaSharper/Converters/InstaCaptionConverter.cs @@ -1,6 +1,6 @@ using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Helpers; -using InstaSharper.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaCarouselConverter.cs b/InstaSharper/Converters/InstaCarouselConverter.cs new file mode 100644 index 00000000..4c71c3e0 --- /dev/null +++ b/InstaSharper/Converters/InstaCarouselConverter.cs @@ -0,0 +1,23 @@ +using System; +using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; + +namespace InstaSharper.Converters +{ + internal class InstaCarouselConverter : IObjectConverter + { + public InstaCarouselResponse SourceObject { get; set; } + + public InstaCarousel Convert() + { + var carousel = new InstaCarousel(); + if (SourceObject == null) throw new ArgumentNullException($"Source object"); + foreach (var item in SourceObject) + { + var carouselItem = ConvertersFabric.GetCarouselItemConverter(item); + carousel.Add(carouselItem.Convert()); + } + return carousel; + } + } +} \ No newline at end of file diff --git a/InstaSharper/Converters/InstaCarouselItemConverter.cs b/InstaSharper/Converters/InstaCarouselItemConverter.cs new file mode 100644 index 00000000..db038b6f --- /dev/null +++ b/InstaSharper/Converters/InstaCarouselItemConverter.cs @@ -0,0 +1,25 @@ +using System; +using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; + +namespace InstaSharper.Converters +{ + internal class InstaCarouselItemConverter : IObjectConverter + { + public InstaCarouselItemResponse SourceObject { get; set; } + + public InstaCarouselItem Convert() + { + if (SourceObject == null) throw new ArgumentNullException($"Source object"); + var carouselItem = new InstaCarouselItem + { + CarouselParentId = SourceObject.CarouselParentId, + Height = int.Parse(SourceObject.Height), + Width = int.Parse(SourceObject.Width) + }; + foreach (var image in SourceObject.Images.Candidates) + carouselItem.Images.Add(new MediaImage(image.Url, image.Width, image.Height)); + return carouselItem; + } + } +} \ No newline at end of file diff --git a/InstaSharper/Converters/InstaCommentConverter.cs b/InstaSharper/Converters/InstaCommentConverter.cs index 0655854f..b1bcf502 100644 --- a/InstaSharper/Converters/InstaCommentConverter.cs +++ b/InstaSharper/Converters/InstaCommentConverter.cs @@ -1,7 +1,7 @@ using System; using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Helpers; -using InstaSharper.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaCommentListConverter.cs b/InstaSharper/Converters/InstaCommentListConverter.cs index c4418435..f6363094 100644 --- a/InstaSharper/Converters/InstaCommentListConverter.cs +++ b/InstaSharper/Converters/InstaCommentListConverter.cs @@ -1,5 +1,5 @@ using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaDirectInboxConverter.cs b/InstaSharper/Converters/InstaDirectInboxConverter.cs index cd4930e3..c4ad0a3d 100644 --- a/InstaSharper/Converters/InstaDirectInboxConverter.cs +++ b/InstaSharper/Converters/InstaDirectInboxConverter.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaDirectInboxSubscriptionConverter.cs b/InstaSharper/Converters/InstaDirectInboxSubscriptionConverter.cs index ddf5df31..ba02e301 100644 --- a/InstaSharper/Converters/InstaDirectInboxSubscriptionConverter.cs +++ b/InstaSharper/Converters/InstaDirectInboxSubscriptionConverter.cs @@ -1,5 +1,5 @@ using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaDirectThreadConverter.cs b/InstaSharper/Converters/InstaDirectThreadConverter.cs index 143b4b63..070a34c8 100644 --- a/InstaSharper/Converters/InstaDirectThreadConverter.cs +++ b/InstaSharper/Converters/InstaDirectThreadConverter.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Helpers; -using InstaSharper.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaDirectThreadItemConverter.cs b/InstaSharper/Converters/InstaDirectThreadItemConverter.cs index 1aaeb57c..b23fc091 100644 --- a/InstaSharper/Converters/InstaDirectThreadItemConverter.cs +++ b/InstaSharper/Converters/InstaDirectThreadItemConverter.cs @@ -1,6 +1,6 @@ using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Helpers; -using InstaSharper.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaFeedConverter.cs b/InstaSharper/Converters/InstaFeedConverter.cs index 910064ca..e1ce9405 100644 --- a/InstaSharper/Converters/InstaFeedConverter.cs +++ b/InstaSharper/Converters/InstaFeedConverter.cs @@ -1,5 +1,5 @@ using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaFriendshipStatusConverter.cs b/InstaSharper/Converters/InstaFriendshipStatusConverter.cs index 1a8055fb..22520854 100644 --- a/InstaSharper/Converters/InstaFriendshipStatusConverter.cs +++ b/InstaSharper/Converters/InstaFriendshipStatusConverter.cs @@ -1,5 +1,5 @@ using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { @@ -10,10 +10,14 @@ internal class InstaFriendshipStatusConverter : public InstaFriendshipStatus Convert() { - var friendShip = new InstaFriendshipStatus(); - friendShip.Foolowing = SourceObject.Foolowing; - friendShip.IncomingRequest = SourceObject.IncomingRequest; - friendShip.OutgoingRequest = SourceObject.OutgoingRequest; + var friendShip = new InstaFriendshipStatus + { + Following = SourceObject.Following, + Blocking = SourceObject.Blocking, + FollowedBy = SourceObject.FollowedBy, + IncomingRequest = SourceObject.IncomingRequest, + OutgoingRequest = SourceObject.OutgoingRequest + }; friendShip.IncomingRequest = SourceObject.IncomingRequest; friendShip.IsPrivate = SourceObject.IsPrivate; return friendShip; diff --git a/InstaSharper/Converters/InstaMediaConverter.cs b/InstaSharper/Converters/InstaMediaConverter.cs index 05c77887..77f4b596 100644 --- a/InstaSharper/Converters/InstaMediaConverter.cs +++ b/InstaSharper/Converters/InstaMediaConverter.cs @@ -1,7 +1,7 @@ using System; using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Helpers; -using InstaSharper.ResponseWrappers; namespace InstaSharper.Converters { @@ -30,6 +30,8 @@ public InstaMedia Convert() FilterType = SourceObject.FilterType, Width = SourceObject.Width }; + if (SourceObject.CarouselMedia != null) + media.Carousel = ConvertersFabric.GetCarouselConverter(SourceObject.CarouselMedia).Convert(); if (SourceObject.User != null) media.User = ConvertersFabric.GetUserConverter(SourceObject.User).Convert(); if (SourceObject.Caption != null) media.Caption = ConvertersFabric.GetCaptionConverter(SourceObject.Caption).Convert(); @@ -42,7 +44,7 @@ public InstaMedia Convert() media.Tags.Add(ConvertersFabric.GetUserTagConverter(tag).Convert()); if (SourceObject.Images?.Candidates == null) return media; foreach (var image in SourceObject.Images.Candidates) - media.Images.Add(new Image(image.Url, image.Width, image.Height)); + media.Images.Add(new MediaImage(image.Url, image.Width, image.Height)); return media; } } diff --git a/InstaSharper/Converters/InstaMediaListConverter.cs b/InstaSharper/Converters/InstaMediaListConverter.cs index 2749f6e2..f6036476 100644 --- a/InstaSharper/Converters/InstaMediaListConverter.cs +++ b/InstaSharper/Converters/InstaMediaListConverter.cs @@ -1,7 +1,7 @@ using System; using System.Linq; using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaRecentActivityConverter.cs b/InstaSharper/Converters/InstaRecentActivityConverter.cs index 78eb8e8b..184aa11a 100644 --- a/InstaSharper/Converters/InstaRecentActivityConverter.cs +++ b/InstaSharper/Converters/InstaRecentActivityConverter.cs @@ -1,6 +1,6 @@ using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Helpers; -using InstaSharper.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaRecipientsConverter.cs b/InstaSharper/Converters/InstaRecipientsConverter.cs index 9f20cd51..46e461bc 100644 --- a/InstaSharper/Converters/InstaRecipientsConverter.cs +++ b/InstaSharper/Converters/InstaRecipientsConverter.cs @@ -1,5 +1,5 @@ using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaStoryConverter.cs b/InstaSharper/Converters/InstaStoryConverter.cs index 1c498677..710a729f 100644 --- a/InstaSharper/Converters/InstaStoryConverter.cs +++ b/InstaSharper/Converters/InstaStoryConverter.cs @@ -1,7 +1,7 @@ using System; using InstaSharper.Classes.Models; +using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Helpers; -using InstaSharper.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaUserTagConverter.cs b/InstaSharper/Converters/InstaUserTagConverter.cs index eeac6b22..5c002384 100644 --- a/InstaSharper/Converters/InstaUserTagConverter.cs +++ b/InstaSharper/Converters/InstaUserTagConverter.cs @@ -1,6 +1,6 @@ using System; using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/InstaUsersConverter.cs b/InstaSharper/Converters/InstaUsersConverter.cs index 874bfe77..04944f25 100644 --- a/InstaSharper/Converters/InstaUsersConverter.cs +++ b/InstaSharper/Converters/InstaUsersConverter.cs @@ -1,6 +1,6 @@ using System; using InstaSharper.Classes.Models; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; namespace InstaSharper.Converters { diff --git a/InstaSharper/Converters/Json/InstaCommentDataConverter.cs b/InstaSharper/Converters/Json/InstaCommentDataConverter.cs new file mode 100644 index 00000000..5270e8d2 --- /dev/null +++ b/InstaSharper/Converters/Json/InstaCommentDataConverter.cs @@ -0,0 +1,30 @@ +using System; +using InstaSharper.Classes.ResponseWrappers; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace InstaSharper.Converters.Json +{ + public class InstaCommentDataConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType == typeof(InstaCommentResponse); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, + JsonSerializer serializer) + { + var root = JToken.Load(reader); + var commentContainer = root["comment"]; + return commentContainer == null + ? root.ToObject() + : commentContainer.ToObject(); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + serializer.Serialize(writer, value); + } + } +} \ No newline at end of file diff --git a/InstaSharper/Converters/Json/InstaFeedResponseDataConverter.cs b/InstaSharper/Converters/Json/InstaFeedResponseDataConverter.cs index 6c1017f5..12132afd 100644 --- a/InstaSharper/Converters/Json/InstaFeedResponseDataConverter.cs +++ b/InstaSharper/Converters/Json/InstaFeedResponseDataConverter.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/InstaSharper/Converters/Json/InstaFriendShipDataConverter.cs b/InstaSharper/Converters/Json/InstaFriendShipDataConverter.cs new file mode 100644 index 00000000..3a6f40a1 --- /dev/null +++ b/InstaSharper/Converters/Json/InstaFriendShipDataConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using InstaSharper.Classes.ResponseWrappers; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace InstaSharper.Converters.Json +{ + public class InstaFriendShipDataConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType == typeof(InstaFriendshipStatusResponse); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, + JsonSerializer serializer) + { + var root = JToken.Load(reader); + var statusSubContainer = root["friendship_status"]; + return statusSubContainer == null + ? root.ToObject() + : statusSubContainer.ToObject(); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + serializer.Serialize(writer, value); + } + } +} \ No newline at end of file diff --git a/InstaSharper/Converters/Json/InstaMediaListDataConverter.cs b/InstaSharper/Converters/Json/InstaMediaListDataConverter.cs index ddf5d88b..0fcf6930 100644 --- a/InstaSharper/Converters/Json/InstaMediaListDataConverter.cs +++ b/InstaSharper/Converters/Json/InstaMediaListDataConverter.cs @@ -1,5 +1,5 @@ using System; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/InstaSharper/Converters/Json/InstaRecentActivityConverter.cs b/InstaSharper/Converters/Json/InstaRecentActivityConverter.cs index 957b463e..f03a815d 100644 --- a/InstaSharper/Converters/Json/InstaRecentActivityConverter.cs +++ b/InstaSharper/Converters/Json/InstaRecentActivityConverter.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/InstaSharper/Converters/Json/InstaRecipientsDataConverter.cs b/InstaSharper/Converters/Json/InstaRecipientsDataConverter.cs index 9c9f51bb..a7e60279 100644 --- a/InstaSharper/Converters/Json/InstaRecipientsDataConverter.cs +++ b/InstaSharper/Converters/Json/InstaRecipientsDataConverter.cs @@ -1,5 +1,5 @@ using System; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/InstaSharper/Converters/Json/InstaThreadDataConverter.cs b/InstaSharper/Converters/Json/InstaThreadDataConverter.cs index 39e76d2f..6ebd27bf 100644 --- a/InstaSharper/Converters/Json/InstaThreadDataConverter.cs +++ b/InstaSharper/Converters/Json/InstaThreadDataConverter.cs @@ -1,5 +1,5 @@ using System; -using InstaSharper.ResponseWrappers; +using InstaSharper.Classes.ResponseWrappers; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/InstaSharper/Helpers/CryptoHelper.cs b/InstaSharper/Helpers/CryptoHelper.cs index 79d8819c..02ef71d6 100644 --- a/InstaSharper/Helpers/CryptoHelper.cs +++ b/InstaSharper/Helpers/CryptoHelper.cs @@ -2,12 +2,30 @@ using System.Linq; using System.Security.Cryptography; using System.Text; +using InstaSharper.API; namespace InstaSharper.Helpers { internal class CryptoHelper { - public static string CalculateMD5(string message) + public static string ByteToString(byte[] buff) + { + return buff.Aggregate("", (current, item) => current + item.ToString("X2")); + } + + public static string Base64Encode(string plainText) + { + var plainTextBytes = Encoding.UTF8.GetBytes(plainText); + return Convert.ToBase64String(plainTextBytes); + } + + public static string Base64Decode(string base64EncodedData) + { + var base64EncodedBytes = Convert.FromBase64String(base64EncodedData); + return Encoding.UTF8.GetString(base64EncodedBytes); + } + + public static string CalculateMd5(string message) { var encoding = Encoding.UTF8; @@ -80,5 +98,27 @@ public static byte[] ByteConcat(byte[] left, byte[] right) return newBytes; } + + public static string GetCommentBreadCrumbEncoded(string text) + { + const string key = InstaApiConstants.COMMENT_BREADCRUMB_KEY; + + var date = Convert.ToInt64(DateTimeHelper.GetUnixTimestampMilliseconds(DateTime.Now)); + var rnd = new Random(DateTime.Now.Millisecond); + var msgSize = text.Length; + var term = rnd.Next(2, 3) * 1000 + msgSize * rnd.Next(15, 20) * 100; + var textChangeDeviceEventCount = Math.Round((decimal) (msgSize / rnd.Next(2, 3)), 0); + if (textChangeDeviceEventCount == 0) textChangeDeviceEventCount = 1; + var data = $"{msgSize} {term} {textChangeDeviceEventCount} {date}"; + + var keyByte = Encoding.UTF8.GetBytes(key); + string dataEncoded; + using (var hmacsha256 = new HMACSHA256(keyByte)) + { + dataEncoded = ByteToString(hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(data))); + } + + return $"{Base64Encode(dataEncoded)}\n{Base64Encode(data)}\n"; + } } } \ No newline at end of file diff --git a/InstaSharper/Helpers/DateTimeHelper.cs b/InstaSharper/Helpers/DateTimeHelper.cs index 972990fd..f7332585 100644 --- a/InstaSharper/Helpers/DateTimeHelper.cs +++ b/InstaSharper/Helpers/DateTimeHelper.cs @@ -4,6 +4,14 @@ namespace InstaSharper.Helpers { internal static class DateTimeHelper { + private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1); + + public static double GetUnixTimestampMilliseconds(DateTime dt) + { + var span = dt - UnixEpoch; + return span.TotalMilliseconds; + } + public static DateTime UnixTimestampToDateTime(double unixTime) { var time = (long) unixTime; @@ -26,8 +34,7 @@ public static DateTime FromUnixTimeSeconds(this long unixTime) { try { - var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - return epoch.AddSeconds(unixTime); + return UnixEpoch.AddSeconds(unixTime); } catch { @@ -39,8 +46,7 @@ public static DateTime FromUnixTimeMiliSeconds(this long unixTime) { try { - var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - return epoch.AddMilliseconds(unixTime); + return UnixEpoch.AddMilliseconds(unixTime); } catch { @@ -52,8 +58,7 @@ public static long ToUnixTime(this DateTime date) { try { - var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - return Convert.ToInt64((date - epoch).TotalSeconds); + return Convert.ToInt64((date - UnixEpoch).TotalSeconds); } catch { diff --git a/InstaSharper/Helpers/HttpHelper.cs b/InstaSharper/Helpers/HttpHelper.cs index c4301cb0..b3fdf7bd 100644 --- a/InstaSharper/Helpers/HttpHelper.cs +++ b/InstaSharper/Helpers/HttpHelper.cs @@ -3,6 +3,7 @@ using System.Net.Http; using InstaSharper.API; using InstaSharper.Classes.Android.DeviceInfo; +using Newtonsoft.Json; namespace InstaSharper.Helpers { @@ -19,5 +20,26 @@ public static HttpRequestMessage GetDefaultRequest(HttpMethod method, Uri uri, A deviceInfo.GoogleAdId.ToString())); return request; } + + public static HttpRequestMessage GetSignedRequest(HttpMethod method, Uri uri, AndroidDevice deviceInfo, + Dictionary data) + { + var hash = CryptoHelper.CalculateHash(InstaApiConstants.IG_SIGNATURE_KEY, + JsonConvert.SerializeObject(data)); + var payload = JsonConvert.SerializeObject(data); + var signature = $"{hash}.{payload}"; + + var fields = new Dictionary + { + {InstaApiConstants.HEADER_IG_SIGNATURE, signature}, + {InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, InstaApiConstants.IG_SIGNATURE_KEY_VERSION} + }; + var request = GetDefaultRequest(HttpMethod.Post, uri, deviceInfo); + request.Content = new FormUrlEncodedContent(fields); + request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature); + request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, + InstaApiConstants.IG_SIGNATURE_KEY_VERSION); + return request; + } } } \ No newline at end of file diff --git a/InstaSharper/Helpers/UriCreator.cs b/InstaSharper/Helpers/UriCreator.cs index d8b30253..4053ebff 100644 --- a/InstaSharper/Helpers/UriCreator.cs +++ b/InstaSharper/Helpers/UriCreator.cs @@ -222,5 +222,67 @@ public static Uri GetFollowUserUri(long userId) throw new Exception("Cant create URI for getting media likers"); return instaUri; } + + public static Uri GetUnFollowUserUri(long userId) + { + Uri instaUri; + if (!Uri.TryCreate(BaseInstagramUri, string.Format(InstaApiConstants.UNFOLLOW_USER, userId), out instaUri)) + throw new Exception("Cant create URI for getting media likers"); + return instaUri; + } + + public static Uri GetUriSetAccountPrivate() + { + Uri instaUri; + if (!Uri.TryCreate(BaseInstagramUri, InstaApiConstants.SET_ACCOUNT_PRIVATE, out instaUri)) + throw new Exception("Cant create URI for set account private"); + return instaUri; + } + + public static Uri GetUriSetAccountPublic() + { + Uri instaUri; + if (!Uri.TryCreate(BaseInstagramUri, InstaApiConstants.SET_ACCOUNT_PUBLIC, out instaUri)) + throw new Exception("Cant create URI for set account public"); + return instaUri; + } + + public static Uri GetPostCommetUri(string mediaId) + { + Uri instaUri; + if (!Uri.TryCreate(BaseInstagramUri, string.Format(InstaApiConstants.POST_COMMENT, mediaId), out instaUri)) + throw new Exception("Cant create URI for posting comment"); + return instaUri; + } + + public static Uri GetAllowMediaCommetsUri(string mediaId) + { + Uri instaUri; + if ( + !Uri.TryCreate(BaseInstagramUri, string.Format(InstaApiConstants.ALLOW_MEDIA_COMMENTS, mediaId), + out instaUri)) + throw new Exception("Cant create URI to allow comments on media"); + return instaUri; + } + + public static Uri GetDisableMediaCommetsUri(string mediaId) + { + Uri instaUri; + if ( + !Uri.TryCreate(BaseInstagramUri, string.Format(InstaApiConstants.DISABLE_MEDIA_COMMENTS, mediaId), + out instaUri)) + throw new Exception("Cant create URI to disable comments on media"); + return instaUri; + } + + public static Uri GetDeleteCommetUri(string mediaId, string commentId) + { + Uri instaUri; + if ( + !Uri.TryCreate(BaseInstagramUri, string.Format(InstaApiConstants.DELETE_COMMENT, mediaId, commentId), + out instaUri)) + throw new Exception("Cant create URI for delete comment"); + return instaUri; + } } } \ No newline at end of file diff --git a/InstaSharper/ResponseWrappers/BaseResponse/BaseStatusResponse.cs b/InstaSharper/ResponseWrappers/BaseResponse/BaseStatusResponse.cs deleted file mode 100644 index 637ca188..00000000 --- a/InstaSharper/ResponseWrappers/BaseResponse/BaseStatusResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace InstaSharper.ResponseWrappers.BaseResponse -{ - public class BaseStatusResponse - { - [JsonProperty("status")] - public string Status { get; set; } - } -} \ No newline at end of file diff --git a/InstaSharper/ResponseWrappers/InstaFriendshipStatusResponse.cs b/InstaSharper/ResponseWrappers/InstaFriendshipStatusResponse.cs deleted file mode 100644 index d719235f..00000000 --- a/InstaSharper/ResponseWrappers/InstaFriendshipStatusResponse.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Newtonsoft.Json; - -namespace InstaSharper.ResponseWrappers -{ - internal class InstaFriendshipStatusResponse - { - [JsonProperty("following")] - public bool Foolowing { get; set; } - - [JsonProperty("is_private")] - public bool IsPrivate { get; set; } - - [JsonProperty("incoming_request")] - public bool IncomingRequest { get; set; } - - [JsonProperty("outgoing_request")] - public bool OutgoingRequest { get; set; } - } -} \ No newline at end of file diff --git a/InstaSharper/project.json b/InstaSharper/project.json index 95046439..d2b63534 100644 --- a/InstaSharper/project.json +++ b/InstaSharper/project.json @@ -1,5 +1,5 @@ { - "version": "1.2.3", + "version": "1.2.4", "dependencies": { "NETStandard.Library": "1.6.0", From 75ad33787081eaf8f3b2226ac708042101dc713d Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Sun, 16 Apr 2017 20:15:27 +0300 Subject: [PATCH 02/15] fixed ci builds --- .travis.yml | 4 ++-- InstaSharper/API/InstaApi.cs | 1 - appveyor.yml | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 26eea1c3..cda4edb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,10 +8,10 @@ dist: trusty script: # dotnet info - dotnet --info - # Run dotnet new - - dotnet restore - cd InstaSharper + - dotnet restore - dotnet build - cd ../InstaSharper.Tests + - dotnet restore - dotnet build - dotnet test -parallel none \ No newline at end of file diff --git a/InstaSharper/API/InstaApi.cs b/InstaSharper/API/InstaApi.cs index a549918b..8b0f0fa9 100644 --- a/InstaSharper/API/InstaApi.cs +++ b/InstaSharper/API/InstaApi.cs @@ -707,7 +707,6 @@ public async Task> LikeUnlikeMediaInternal(string mediaId, Uri ins {"_uid", _user.LoggedInUder.Pk}, {"_csrftoken", _user.CsrfToken}, {"media_id", mediaId} - }; var request = HttpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, fields); var response = await _httpClient.SendAsync(request); diff --git a/appveyor.yml b/appveyor.yml index 85a67dd7..9677c730 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,11 +1,11 @@ -version: 1.2.1 ({build}) +version: 1.2.4 os: Visual Studio 2015 platform: Any CPU configuration: Release branches: only: - - release + - develop - master skip_commits: message: /skip ci/ # Regex for matching commit message @@ -19,8 +19,8 @@ build: build_script: - ps: dotnet --info - - ps: dotnet restore - ps: cd InstaSharper + - ps: dotnet restore - ps: dotnet build - ps: dotnet pack -o ../nugetpack -c release - ps: cd ../InstaSharper.Tests From 860170b706ac7478cc7fde4e72a89add2b332f4e Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Sun, 16 Apr 2017 20:29:36 +0300 Subject: [PATCH 03/15] vs 2017 as os in appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 9677c730..3b7c0c71 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ version: 1.2.4 -os: Visual Studio 2015 +os: Visual Studio 2017 platform: Any CPU configuration: Release From da00a8b2062de1c476cdc8cd8f1475690b3d1eae Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Sun, 16 Apr 2017 20:31:48 +0300 Subject: [PATCH 04/15] added appveyor build number --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 3b7c0c71..776c8f00 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 1.2.4 +version: 1.2.4.{build} os: Visual Studio 2017 platform: Any CPU configuration: Release From 739ec5a97634e4b424d864c1477588f337e156b0 Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Mon, 17 Apr 2017 21:10:15 +0300 Subject: [PATCH 05/15] migration to vs 2017, new csproj format --- .travis.yml | 10 ++----- InstaSharper.Tests/InstaSharper.Tests.csproj | 28 ++++++++++++++++++ InstaSharper.Tests/InstaSharper.Tests.xproj | 23 --------------- InstaSharper.Tests/project.json | 24 ---------------- InstaSharper.sln | 10 +++---- InstaSharper/API/InstaApi.cs | 2 -- InstaSharper/InstaSharper.csproj | 30 ++++++++++++++++++++ InstaSharper/InstaSharper.xproj | 21 -------------- InstaSharper/project.json | 17 ----------- appveyor.yml | 7 +---- 10 files changed, 67 insertions(+), 105 deletions(-) create mode 100644 InstaSharper.Tests/InstaSharper.Tests.csproj delete mode 100644 InstaSharper.Tests/InstaSharper.Tests.xproj delete mode 100644 InstaSharper.Tests/project.json create mode 100644 InstaSharper/InstaSharper.csproj delete mode 100644 InstaSharper/InstaSharper.xproj delete mode 100644 InstaSharper/project.json diff --git a/.travis.yml b/.travis.yml index cda4edb9..365a925c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,13 @@ language: csharp solution: InstaSharper.sln -dotnet: 1.0.0-preview2-003121 +dotnet: 1.0.3 sudo: required os: linux dist: trusty script: - # dotnet info - dotnet --info - - cd InstaSharper - - dotnet restore - - dotnet build - - cd ../InstaSharper.Tests - dotnet restore - dotnet build - - dotnet test -parallel none \ No newline at end of file + - cd InstaSharper + - dotnet pack -o ../nugetpack -c release \ No newline at end of file diff --git a/InstaSharper.Tests/InstaSharper.Tests.csproj b/InstaSharper.Tests/InstaSharper.Tests.csproj new file mode 100644 index 00000000..6d68055e --- /dev/null +++ b/InstaSharper.Tests/InstaSharper.Tests.csproj @@ -0,0 +1,28 @@ + + + + netcoreapp1.0 + InstaSharper.Tests + InstaSharper.Tests + true + 1.0.4 + false + false + false + + + + + + + + + PreserveNewest + + + + + + + + diff --git a/InstaSharper.Tests/InstaSharper.Tests.xproj b/InstaSharper.Tests/InstaSharper.Tests.xproj deleted file mode 100644 index 042194cb..00000000 --- a/InstaSharper.Tests/InstaSharper.Tests.xproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - dbe6fbb7-cde7-4cdf-ab08-989a43cc4d46 - InstaSharper.Tests - .\obj - .\bin\ - v4.5.2 - - - 2.0 - - - - - - - \ No newline at end of file diff --git a/InstaSharper.Tests/project.json b/InstaSharper.Tests/project.json deleted file mode 100644 index 53820ce9..00000000 --- a/InstaSharper.Tests/project.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "version": "1.0.0-*", - "testRunner": "xunit", - "dependencies": { - "xunit": "2.2.0-beta2-build3300", - "InstaSharper": "1.2.4", - "dotnet-test-xunit": "2.2.0-preview2-build1029" - }, - "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "type": "platform", - "version": "1.0.0" - } - } - } - }, - "buildOptions": { - "copyToOutput": { - "include": ["xunit.runner.json"] - } - } -} \ No newline at end of file diff --git a/InstaSharper.sln b/InstaSharper.sln index bd2eb111..5434cb35 100644 --- a/InstaSharper.sln +++ b/InstaSharper.sln @@ -1,11 +1,11 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26114.2 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "InstaSharper", "InstaSharper\InstaSharper.xproj", "{449A948D-CC65-4D1A-8159-6FA232F972D9}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstaSharper", "InstaSharper\InstaSharper.csproj", "{449A948D-CC65-4D1A-8159-6FA232F972D9}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "InstaSharper.Tests", "InstaSharper.Tests\InstaSharper.Tests.xproj", "{DBE6FBB7-CDE7-4CDF-AB08-989A43CC4D46}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstaSharper.Tests", "InstaSharper.Tests\InstaSharper.Tests.csproj", "{DBE6FBB7-CDE7-4CDF-AB08-989A43CC4D46}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/InstaSharper/API/InstaApi.cs b/InstaSharper/API/InstaApi.cs index 8b0f0fa9..7fbf8ac3 100644 --- a/InstaSharper/API/InstaApi.cs +++ b/InstaSharper/API/InstaApi.cs @@ -13,9 +13,7 @@ using InstaSharper.Helpers; using InstaSharper.Logger; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using InstaRecentActivityConverter = InstaSharper.Converters.Json.InstaRecentActivityConverter; -using System.Text; using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Classes.ResponseWrappers.BaseResponse; diff --git a/InstaSharper/InstaSharper.csproj b/InstaSharper/InstaSharper.csproj new file mode 100644 index 00000000..1643dba4 --- /dev/null +++ b/InstaSharper/InstaSharper.csproj @@ -0,0 +1,30 @@ + + + + 1.2.4 + netstandard1.6;net452 + true + InstaSharper + InstaSharper + 1.6.0 + $(PackageTargetFallback);dnxcore50 + false + false + false + + + + + + + + + + + + + + + + + diff --git a/InstaSharper/InstaSharper.xproj b/InstaSharper/InstaSharper.xproj deleted file mode 100644 index d167e9b1..00000000 --- a/InstaSharper/InstaSharper.xproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - 449a948d-cc65-4d1a-8159-6fa232f972d9 - InstaSharper - .\obj - .\bin\ - v4.5.2 - - - - 2.0 - - - diff --git a/InstaSharper/project.json b/InstaSharper/project.json deleted file mode 100644 index d2b63534..00000000 --- a/InstaSharper/project.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": "1.2.4", - - "dependencies": { - "NETStandard.Library": "1.6.0", - "Newtonsoft.Json": "9.0.1" - }, - - "frameworks": { - "netstandard1.6": { - "imports": "dnxcore50" - }, - "net452": { - - } - } -} diff --git a/appveyor.yml b/appveyor.yml index 776c8f00..fd1588ae 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,15 +19,10 @@ build: build_script: - ps: dotnet --info - - ps: cd InstaSharper - ps: dotnet restore - ps: dotnet build + - ps: cd InstaSharper - ps: dotnet pack -o ../nugetpack -c release - - ps: cd ../InstaSharper.Tests - - ps: dotnet restore - - ps: dotnet build - - ps: dotnet test -parallel none - - ps: cd .. environment: instaapiuserpassword: From 694357ce9c9bfdf9b94fe395ed1b3251da89ddcc Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Mon, 17 Apr 2017 21:19:45 +0300 Subject: [PATCH 06/15] myget feed added --- .travis.yml | 3 ++- appveyor.yml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 365a925c..0ed45492 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,12 @@ language: csharp solution: InstaSharper.sln -dotnet: 1.0.3 +dotnet: 1.0.2 sudo: required os: linux dist: trusty script: + - nuget sources add -Name MyGetXunit -Source https://www.myget.org/F/xunit/api/v3/index.json - dotnet --info - dotnet restore - dotnet build diff --git a/appveyor.yml b/appveyor.yml index fd1588ae..95e1e1f7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,6 +18,7 @@ build: include_nuget_references: true # add -IncludeReferencedProjects option while packaging NuGet artifacts build_script: + - ps: nuget sources add -Name MyGetXunit -Source https://www.myget.org/F/xunit/api/v3/index.json - ps: dotnet --info - ps: dotnet restore - ps: dotnet build From f07716477426cb3674eda7ca09ecffcf5f822a5b Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Mon, 17 Apr 2017 21:48:29 +0300 Subject: [PATCH 07/15] 1.0.1 dotnet for travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0ed45492..8ed15635 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: csharp solution: InstaSharper.sln -dotnet: 1.0.2 +dotnet: 1.0.1 sudo: required os: linux dist: trusty From 02c320f998128c91ab5c7ff2aa0defba9614712f Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Tue, 18 Apr 2017 18:25:19 +0300 Subject: [PATCH 08/15] 1.0.1 dotnet for travis v2 --- .travis.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8ed15635..9791fb21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,14 @@ language: csharp -solution: InstaSharper.sln -dotnet: 1.0.1 -sudo: required -os: linux dist: trusty +dotnet: 1.0.1 +mono: none +solution: InstaSharper.sln -script: +install: - nuget sources add -Name MyGetXunit -Source https://www.myget.org/F/xunit/api/v3/index.json + - nuget restore InstaSharper.sln + +script: - dotnet --info - dotnet restore - dotnet build From 4763903a4c84de5327f693d75621318a6bc4c236 Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Tue, 18 Apr 2017 18:28:08 +0300 Subject: [PATCH 09/15] 1.0.1 dotnet for travis v3 --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9791fb21..927f55b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,12 +4,10 @@ dotnet: 1.0.1 mono: none solution: InstaSharper.sln -install: - - nuget sources add -Name MyGetXunit -Source https://www.myget.org/F/xunit/api/v3/index.json - - nuget restore InstaSharper.sln - script: - dotnet --info + - nuget sources add -Name MyGetXunit -Source https://www.myget.org/F/xunit/api/v3/index.json + - nuget restore InstaSharper.sln - dotnet restore - dotnet build - cd InstaSharper From 6e6a7f0f1b30ab97bcad8ed73585966e8cd693f3 Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Tue, 18 Apr 2017 19:50:34 +0300 Subject: [PATCH 10/15] 1.0.1 dotnet and final improvements in travis --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 927f55b2..45a763fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,10 +5,8 @@ mono: none solution: InstaSharper.sln script: + - cd InstaSharper - dotnet --info - - nuget sources add -Name MyGetXunit -Source https://www.myget.org/F/xunit/api/v3/index.json - - nuget restore InstaSharper.sln - dotnet restore - dotnet build - - cd InstaSharper - - dotnet pack -o ../nugetpack -c release \ No newline at end of file + - dotnet build --framework netstandard1.6 \ No newline at end of file From b79d14b755dc13910f554934b54bec8b54a321e5 Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Tue, 18 Apr 2017 19:53:50 +0300 Subject: [PATCH 11/15] 1.0.1 dotnet and final improvements in travis v2 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 45a763fa..f7132f6b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,4 @@ script: - cd InstaSharper - dotnet --info - dotnet restore - - dotnet build - dotnet build --framework netstandard1.6 \ No newline at end of file From 95a1feeeeff03f0c46252f14da3203b665423bd1 Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Fri, 5 May 2017 13:55:10 +0300 Subject: [PATCH 12/15] Added upload photo method --- InstaSharper.Tests/Endpoints/UploadTest.cs | 48 +++++++ InstaSharper.Tests/InstaSharper.Tests.csproj | 6 + InstaSharper/API/IInstaApi.cs | 33 +++++ InstaSharper/API/InstaApi.cs | 128 +++++++++++++++++- InstaSharper/API/InstaApiConstants.cs | 6 +- .../Android/DeviceInfo/AndroidVersion.cs | 100 ++++++++++++++ .../Android/DeviceInfo/ApiRequestMessage.cs | 7 + InstaSharper/Classes/Models/MediaImage.cs | 14 +- .../Classes/ResponseWrappers/ImageResponse.cs | 2 +- .../Converters/InstaCarouselItemConverter.cs | 2 +- .../Converters/InstaMediaConverter.cs | 2 +- .../Converters/InstaUsersConverter.cs | 3 +- InstaSharper/Helpers/HttpHelper.cs | 22 +++ InstaSharper/Helpers/UriCreator.cs | 25 +++- 14 files changed, 378 insertions(+), 20 deletions(-) create mode 100644 InstaSharper.Tests/Endpoints/UploadTest.cs create mode 100644 InstaSharper/Classes/Android/DeviceInfo/AndroidVersion.cs diff --git a/InstaSharper.Tests/Endpoints/UploadTest.cs b/InstaSharper.Tests/Endpoints/UploadTest.cs new file mode 100644 index 00000000..40712061 --- /dev/null +++ b/InstaSharper.Tests/Endpoints/UploadTest.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using InstaSharper.Classes; +using InstaSharper.Classes.Models; +using InstaSharper.Tests.Utils; +using Xunit; +using Xunit.Abstractions; + +namespace InstaSharper.Tests.Endpoints +{ + [Collection("Endpoints")] + public class UploadTest + { + private readonly ITestOutputHelper _output; + + public UploadTest(ITestOutputHelper output) + { + _output = output; + } + + [RunnableInDebugOnlyFact] + public async void UploadImage() + { + var currentUsername = "alex_codegarage"; + var password = Environment.GetEnvironmentVariable("instaapiuserpassword"); + var apiInstance = TestHelpers.GetDefaultInstaApiInstance(new UserSessionData + { + UserName = currentUsername, + Password = password + }); + + if (!TestHelpers.Login(apiInstance, _output)) return; + var mediaImage = new MediaImage + { + Height = 1080, + Width = 1080, + URI = new Uri(@"D:\Dropbox\Public\Inspire.jpg", UriKind.Absolute).LocalPath + }; + var result = await apiInstance.UploadPhotoAsync(mediaImage, "inspire"); + + //assert + Assert.True(result.Succeeded); + Assert.NotNull(result.Value); + } + } +} diff --git a/InstaSharper.Tests/InstaSharper.Tests.csproj b/InstaSharper.Tests/InstaSharper.Tests.csproj index 6d68055e..00906169 100644 --- a/InstaSharper.Tests/InstaSharper.Tests.csproj +++ b/InstaSharper.Tests/InstaSharper.Tests.csproj @@ -13,6 +13,8 @@ + + @@ -25,4 +27,8 @@ + + + + diff --git a/InstaSharper/API/IInstaApi.cs b/InstaSharper/API/IInstaApi.cs index 5c608006..c21e06bb 100644 --- a/InstaSharper/API/IInstaApi.cs +++ b/InstaSharper/API/IInstaApi.cs @@ -226,6 +226,23 @@ public interface IInstaApi /// Comment id IResult DeleteComment(string mediaId, string commentId); + /// + /// Uploads photo + /// + /// Photo + /// Caption + /// + IResult UploadPhoto(MediaImage image, string caption); + + /// + /// Configures photo + /// + /// Photo + /// Upload id + /// Caption + /// + IResult ConfigurePhoto(MediaImage image, string uploadId, string caption); + #endregion #region Async Members @@ -445,6 +462,22 @@ public interface IInstaApi /// Comment id Task> DeleteCommentAsync(string mediaId, string commentId); + /// + /// Upload photo + /// + /// Photo to upload + /// Caption + Task> UploadPhotoAsync(MediaImage image, string caption); + + /// + /// Configure photo + /// + /// Photo to configure + /// Upload id + /// Caption + /// + Task> ConfigurePhotoAsync(MediaImage image, string uploadId, string caption); + #endregion } } \ No newline at end of file diff --git a/InstaSharper/API/InstaApi.cs b/InstaSharper/API/InstaApi.cs index 7fbf8ac3..4348acfa 100644 --- a/InstaSharper/API/InstaApi.cs +++ b/InstaSharper/API/InstaApi.cs @@ -16,6 +16,8 @@ using InstaRecentActivityConverter = InstaSharper.Converters.Json.InstaRecentActivityConverter; using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Classes.ResponseWrappers.BaseResponse; +using Newtonsoft.Json.Linq; +using System.IO; namespace InstaSharper.API { @@ -182,6 +184,16 @@ public IResult DeleteComment(string mediaId, string commentId) return DeleteCommentAsync(mediaId, commentId).Result; } + public IResult UploadPhoto(MediaImage image, string caption) + { + return UploadPhotoAsync(image, caption).Result; + } + + public IResult ConfigurePhoto(MediaImage image, string uploadId, string caption) + { + return ConfigurePhotoAsync(image, uploadId, caption).Result; + } + #endregion #region async part @@ -298,7 +310,8 @@ public async Task> GetUserTimelineFeedAsync(int maxPages = 0) nextId = nextFeed.Value.NextMaxId; moreAvailable = nextFeed.Value.MoreAvailable; feed.Medias.AddRange( - nextFeed.Value.Items.Select(ConvertersFabric.GetSingleMediaConverter).Select(conv => conv.Convert())); + nextFeed.Value.Items.Select(ConvertersFabric.GetSingleMediaConverter) + .Select(conv => conv.Convert())); feed.Pages++; } return Result.Success(feed); @@ -385,7 +398,7 @@ public async Task> GetMediaByIdAsync(string mediaId) new InstaMediaListDataConverter()); if (mediaResponse.Medias?.Count != 1) { - string errorMessage = $"Got wrong media count for request with media id={mediaId}"; + var errorMessage = $"Got wrong media count for request with media id={mediaId}"; _logger.Write(errorMessage); return Result.Fail(errorMessage); } @@ -403,7 +416,8 @@ public async Task> GetUserAsync(string username) request.Properties.Add(new KeyValuePair(InstaApiConstants.HEADER_TIMEZONE, InstaApiConstants.TIMEZONE_OFFSET.ToString())); request.Properties.Add(new KeyValuePair(InstaApiConstants.HEADER_COUNT, "1")); - request.Properties.Add(new KeyValuePair(InstaApiConstants.HEADER_RANK_TOKEN, _user.RankToken)); + request.Properties.Add( + new KeyValuePair(InstaApiConstants.HEADER_RANK_TOKEN, _user.RankToken)); var response = await _httpClient.SendAsync(request); var json = await response.Content.ReadAsStringAsync(); if (response.StatusCode == HttpStatusCode.OK) @@ -412,7 +426,7 @@ public async Task> GetUserAsync(string username) var user = userInfo.Users?.FirstOrDefault(u => u.UserName == username); if (user == null) { - string errorMessage = $"Can't find this user: {username}"; + var errorMessage = $"Can't find this user: {username}"; _logger.Write(errorMessage); return Result.Fail(errorMessage); } @@ -943,6 +957,106 @@ public async Task> DeleteCommentAsync(string mediaId, string comme } } + public async Task> UploadPhotoAsync(MediaImage image, string caption) + { + ValidateUser(); + ValidateLoggedIn(); + try + { + var instaUri = UriCreator.GetUploadPhotoUri(); + var uploadId = ApiRequestMessage.GenerateUploadId(); + var requestContent = new MultipartFormDataContent(uploadId) + { + {new StringContent(uploadId), "\"upload_id\""}, + {new StringContent(_deviceInfo.DeviceGuid.ToString()), "\"_uuid\""}, + {new StringContent(_user.CsrfToken), "\"_csrftoken\""}, + { + new StringContent("{\"lib_name\":\"jt\",\"lib_version\":\"1.3.0\",\"quality\":\"87\"}"), + "\"image_compression\"" + } + }; + var imageContent = new ByteArrayContent(File.ReadAllBytes(image.URI)); + imageContent.Headers.Add("Content-Transfer-Encoding", "binary"); + imageContent.Headers.Add("Content-Type", "application/octet-stream"); + requestContent.Add(imageContent, "photo", $"pending_media_{ApiRequestMessage.GenerateUploadId()}.jpg"); + var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo); + request.Content = requestContent; + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.IsSuccessStatusCode) + return await ConfigurePhotoAsync(image, uploadId, caption); + var status = GetBadStatusFromJsonString(json); + return Result.Fail(status.Message, (InstaMedia) null); + } + catch (Exception exception) + { + return Result.Fail(exception.Message, (InstaMedia) null); + } + } + + public async Task> ConfigurePhotoAsync(MediaImage image, string uploadId, string caption) + { + ValidateUser(); + ValidateLoggedIn(); + try + { + var instaUri = UriCreator.GetMediaConfigureUri(); + var androidVersion = + AndroidVersion.FromString(_deviceInfo.FirmwareFingerprint.Split('/')[2].Split(':')[1]); + if (androidVersion == null) + return Result.Fail("Unsupported android version", (InstaMedia) null); + var data = new JObject + { + {"_uuid", _deviceInfo.DeviceGuid.ToString()}, + {"_uid", _user.LoggedInUder.Pk}, + {"_csrftoken", _user.CsrfToken}, + {"media_folder", "Camera"}, + {"source_type", "4"}, + {"caption", caption}, + {"upload_id", uploadId}, + { + "device", new JObject + { + {"manufacturer", _deviceInfo.HardwareManufacturer}, + {"model", _deviceInfo.HardwareModel}, + {"android_version", androidVersion.VersionNumber}, + {"android_release", androidVersion.APILevel} + } + }, + { + "edits", new JObject + { + {"crop_original_size", new JArray {image.Width, image.Height}}, + {"crop_center", new JArray {0.0, -0.0}}, + {"crop_zoom", 1} + } + }, + { + "extra", new JObject + { + {"source_width", image.Width}, + {"source_height", image.Height} + } + } + }; + var request = HttpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, data); + var response = await _httpClient.SendAsync(request); + var json = await response.Content.ReadAsStringAsync(); + if (response.IsSuccessStatusCode) + { + var mediaResponse = JsonConvert.DeserializeObject(json); + var converter = ConvertersFabric.GetSingleMediaConverter(mediaResponse); + return Result.Success(converter.Convert()); + } + var status = GetBadStatusFromJsonString(json); + return Result.Fail(status.Message, (InstaMedia) null); + } + catch (Exception exception) + { + return Result.Fail(exception.Message, (InstaMedia) null); + } + } + #endregion #region private part @@ -1031,7 +1145,8 @@ private async Task> GetUserMediaListWithMaxIdAsy return Result.Fail("", (InstaMediaListResponse) null); } - private async Task> GetUserFollowersWithMaxIdAsync(string username, string maxId) + private async Task> GetUserFollowersWithMaxIdAsync(string username, + string maxId) { ValidateUser(); try @@ -1115,7 +1230,8 @@ private async Task> GetTagFeedWithMaxIdAsync(str } } - private async Task> GetCommentListWithMaxIdAsync(string mediaId, string nextId) + private async Task> GetCommentListWithMaxIdAsync(string mediaId, + string nextId) { var commentsUri = UriCreator.GetMediaCommentsUri(mediaId); var commentsUriMaxId = new UriBuilder(commentsUri) {Query = $"max_id={nextId}"}.Uri; diff --git a/InstaSharper/API/InstaApiConstants.cs b/InstaSharper/API/InstaApiConstants.cs index 281747b8..835714b0 100644 --- a/InstaSharper/API/InstaApiConstants.cs +++ b/InstaSharper/API/InstaApiConstants.cs @@ -44,12 +44,14 @@ internal static class InstaApiConstants public const string ALLOW_MEDIA_COMMENTS = API_SUFFIX + "/v1/media/{0}/enable_comments/"; public const string DISABLE_MEDIA_COMMENTS = API_SUFFIX + "/v1/media/{0}/disable_comments/"; public const string DELETE_COMMENT = API_SUFFIX + "/v1/media/{0}/comment/{1}/delete/"; - + public const string UPLOAD_PHOTO = API_SUFFIX + "/v1/upload/photo/"; + public const string MEDIA_CONFIGURE = API_SUFFIX + "/v1/media/configure/"; public const string HEADER_USER_AGENT = "User-Agent"; public const string USER_AGENT = - "Instagram 10.15.0 Android (23/6.0.1; 640dpi; 1440x2560; samsung; SM-G935F; hero2lte; samsungexynos8890; en_NZ)"; + "Instagram 10.15.0 Android (23/6.0.1; 640dpi; 1440x2560; samsung; SM-G935F; hero2lte; samsungexynos8890; en_NZ)" + ; public const string HEADER_QUERY = "q"; public const string HEADER_RANK_TOKEN = "rank_token"; diff --git a/InstaSharper/Classes/Android/DeviceInfo/AndroidVersion.cs b/InstaSharper/Classes/Android/DeviceInfo/AndroidVersion.cs new file mode 100644 index 00000000..796e4fcb --- /dev/null +++ b/InstaSharper/Classes/Android/DeviceInfo/AndroidVersion.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace InstaSharper.Classes.Android.DeviceInfo +{ + public class AndroidVersion + { + public static readonly List AndroidVersions = new List + { + new AndroidVersion + { + Codename = "Ice Cream Sandwich", + VersionNumber = "4.0", + APILevel = "14" + }, + new AndroidVersion + { + Codename = "Ice Cream Sandwich", + VersionNumber = "4.0.3", + APILevel = "15" + }, + new AndroidVersion + { + Codename = "Jelly Bean", + VersionNumber = "4.1", + APILevel = "16" + }, + new AndroidVersion + { + Codename = "Jelly Bean", + VersionNumber = "4.2", + APILevel = "17" + }, + new AndroidVersion + { + Codename = "Jelly Bean", + VersionNumber = "4.3", + APILevel = "18" + }, + new AndroidVersion + { + Codename = "KitKat", + VersionNumber = "4.4", + APILevel = "19" + }, + new AndroidVersion + { + Codename = "KitKat", + VersionNumber = "5.0", + APILevel = "21" + }, + new AndroidVersion + { + Codename = "Lollipop", + VersionNumber = "5.1", + APILevel = "22" + }, + new AndroidVersion + { + Codename = "Marshmallow", + VersionNumber = "6.0", + APILevel = "23" + }, + new AndroidVersion + { + Codename = "Nougat", + VersionNumber = "7.0", + APILevel = "23" + }, + new AndroidVersion + { + Codename = "Nougat", + VersionNumber = "7.1", + APILevel = "25" + } + }; + + private AndroidVersion() + { + } + + public string Codename { get; set; } + public string VersionNumber { get; set; } + public string APILevel { get; set; } + + public static AndroidVersion FromString(string versionString) + { + var version = new Version(versionString); + foreach (var androidVersion in AndroidVersions) + if (version.CompareTo(new Version(androidVersion.VersionNumber)) == 0 || + version.CompareTo(new Version(androidVersion.VersionNumber)) > 0 && + androidVersion != AndroidVersions.Last() && + version.CompareTo(new Version(AndroidVersions[AndroidVersions.IndexOf(androidVersion) + 1] + .VersionNumber)) < 0) + return androidVersion; + return null; + } + } +} \ No newline at end of file diff --git a/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs b/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs index 49f53623..b682d9b9 100644 --- a/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs +++ b/InstaSharper/Classes/Android/DeviceInfo/ApiRequestMessage.cs @@ -38,5 +38,12 @@ internal static string GenerateDeviceId() var hashedGuid = CryptoHelper.CalculateMd5(Guid.NewGuid().ToString()); return $"android-{hashedGuid.Substring(0, 16)}"; } + + internal static string GenerateUploadId() + { + var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0); + var uploadId = (long) timeSpan.TotalSeconds; + return uploadId.ToString(); + } } } \ No newline at end of file diff --git a/InstaSharper/Classes/Models/MediaImage.cs b/InstaSharper/Classes/Models/MediaImage.cs index 76e93259..2e2606e6 100644 --- a/InstaSharper/Classes/Models/MediaImage.cs +++ b/InstaSharper/Classes/Models/MediaImage.cs @@ -2,17 +2,21 @@ { public class MediaImage { - public MediaImage(string url, string width, string height) + public MediaImage(string uri, int width, int height) { - Url = url; + URI = uri; Width = width; Height = height; } - public string Url { get; set; } + public MediaImage() + { + } + + public string URI { get; set; } - public string Width { get; set; } + public int Width { get; set; } - public string Height { get; set; } + public int Height { get; set; } } } \ No newline at end of file diff --git a/InstaSharper/Classes/ResponseWrappers/ImageResponse.cs b/InstaSharper/Classes/ResponseWrappers/ImageResponse.cs index c9a2a388..e2aacfbe 100644 --- a/InstaSharper/Classes/ResponseWrappers/ImageResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/ImageResponse.cs @@ -4,7 +4,7 @@ namespace InstaSharper.Classes.ResponseWrappers { internal class ImageResponse { - [JsonProperty("url")] + [JsonProperty("uri")] public string Url { get; set; } [JsonProperty("width")] diff --git a/InstaSharper/Converters/InstaCarouselItemConverter.cs b/InstaSharper/Converters/InstaCarouselItemConverter.cs index db038b6f..2f817f45 100644 --- a/InstaSharper/Converters/InstaCarouselItemConverter.cs +++ b/InstaSharper/Converters/InstaCarouselItemConverter.cs @@ -18,7 +18,7 @@ public InstaCarouselItem Convert() Width = int.Parse(SourceObject.Width) }; foreach (var image in SourceObject.Images.Candidates) - carouselItem.Images.Add(new MediaImage(image.Url, image.Width, image.Height)); + carouselItem.Images.Add(new MediaImage(image.Url, int.Parse(image.Width), int.Parse(image.Height))); return carouselItem; } } diff --git a/InstaSharper/Converters/InstaMediaConverter.cs b/InstaSharper/Converters/InstaMediaConverter.cs index 77f4b596..0bc40a55 100644 --- a/InstaSharper/Converters/InstaMediaConverter.cs +++ b/InstaSharper/Converters/InstaMediaConverter.cs @@ -44,7 +44,7 @@ public InstaMedia Convert() media.Tags.Add(ConvertersFabric.GetUserTagConverter(tag).Convert()); if (SourceObject.Images?.Candidates == null) return media; foreach (var image in SourceObject.Images.Candidates) - media.Images.Add(new MediaImage(image.Url, image.Width, image.Height)); + media.Images.Add(new MediaImage(image.Url, int.Parse(image.Width), int.Parse(image.Height))); return media; } } diff --git a/InstaSharper/Converters/InstaUsersConverter.cs b/InstaSharper/Converters/InstaUsersConverter.cs index 04944f25..31789d73 100644 --- a/InstaSharper/Converters/InstaUsersConverter.cs +++ b/InstaSharper/Converters/InstaUsersConverter.cs @@ -20,7 +20,8 @@ public InstaUser Convert() if (!string.IsNullOrEmpty(SourceObject.UserName)) user.UserName = SourceObject.UserName; if (!string.IsNullOrEmpty(SourceObject.Pk)) user.Pk = SourceObject.Pk; if (SourceObject.Friendship != null) - user.FriendshipStatus = ConvertersFabric.GetFriendShipStatusConverter(SourceObject.Friendship).Convert(); + user.FriendshipStatus = ConvertersFabric.GetFriendShipStatusConverter(SourceObject.Friendship) + .Convert(); user.HasAnonymousProfilePicture = SourceObject.HasAnonymousProfilePicture; user.ProfilePictureId = SourceObject.ProfilePictureId; user.IsVerified = SourceObject.IsVerified; diff --git a/InstaSharper/Helpers/HttpHelper.cs b/InstaSharper/Helpers/HttpHelper.cs index b3fdf7bd..37d4ccbe 100644 --- a/InstaSharper/Helpers/HttpHelper.cs +++ b/InstaSharper/Helpers/HttpHelper.cs @@ -4,6 +4,7 @@ using InstaSharper.API; using InstaSharper.Classes.Android.DeviceInfo; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace InstaSharper.Helpers { @@ -41,5 +42,26 @@ public static HttpRequestMessage GetSignedRequest(HttpMethod method, Uri uri, An InstaApiConstants.IG_SIGNATURE_KEY_VERSION); return request; } + + public static HttpRequestMessage GetSignedRequest(HttpMethod method, Uri uri, AndroidDevice deviceInfo, + JObject data) + { + var hash = CryptoHelper.CalculateHash(InstaApiConstants.IG_SIGNATURE_KEY, + data.ToString(Formatting.None)); + var payload = data.ToString(Formatting.None); + var signature = $"{hash}.{payload}"; + + var fields = new Dictionary + { + {InstaApiConstants.HEADER_IG_SIGNATURE, signature}, + {InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, InstaApiConstants.IG_SIGNATURE_KEY_VERSION} + }; + var request = GetDefaultRequest(HttpMethod.Post, uri, deviceInfo); + request.Content = new FormUrlEncodedContent(fields); + request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature); + request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, + InstaApiConstants.IG_SIGNATURE_KEY_VERSION); + return request; + } } } \ No newline at end of file diff --git a/InstaSharper/Helpers/UriCreator.cs b/InstaSharper/Helpers/UriCreator.cs index 4053ebff..9ae6384d 100644 --- a/InstaSharper/Helpers/UriCreator.cs +++ b/InstaSharper/Helpers/UriCreator.cs @@ -140,7 +140,7 @@ public static Uri GetUserTagsUri(string userPk, string rankToken, string maxId = Uri instaUri; if (!Uri.TryCreate(BaseInstagramUri, string.Format(InstaApiConstants.GET_USER_TAGS, userPk), out instaUri)) throw new Exception("Cant create URI for get user tags"); - string query = $"rank_token={rankToken}&ranked_content=true"; + var query = $"rank_token={rankToken}&ranked_content=true"; if (!string.IsNullOrEmpty(maxId)) query += $"max_id={maxId}"; var uriBuilder = new UriBuilder(instaUri) {Query = query}; return uriBuilder.Uri; @@ -167,7 +167,7 @@ public static Uri GetRecentActivityUri() Uri instaUri; if (!Uri.TryCreate(BaseInstagramUri, InstaApiConstants.GET_RECENT_ACTIVITY, out instaUri)) throw new Exception("Cant create URI (get recent activity)"); - string query = $"activity_module=all"; + var query = $"activity_module=all"; var uriBuilder = new UriBuilder(instaUri) {Query = query}; return uriBuilder.Uri; } @@ -202,7 +202,8 @@ public static Uri GetLikeMediaUri(string mediaId) public static Uri GetMediaCommentsUri(string mediaId) { Uri instaUri; - if (!Uri.TryCreate(BaseInstagramUri, string.Format(InstaApiConstants.MEDIA_COMMENTS, mediaId), out instaUri)) + if (!Uri.TryCreate(BaseInstagramUri, string.Format(InstaApiConstants.MEDIA_COMMENTS, mediaId), + out instaUri)) throw new Exception("Cant create URI for getting media comments"); return instaUri; } @@ -284,5 +285,23 @@ public static Uri GetDeleteCommetUri(string mediaId, string commentId) throw new Exception("Cant create URI for delete comment"); return instaUri; } + + public static Uri GetUploadPhotoUri() + { + Uri instaUri; + if ( + !Uri.TryCreate(BaseInstagramUri, InstaApiConstants.UPLOAD_PHOTO, out instaUri)) + throw new Exception("Cant create URI for upload photo"); + return instaUri; + } + + public static Uri GetMediaConfigureUri() + { + Uri instaUri; + if ( + !Uri.TryCreate(BaseInstagramUri, InstaApiConstants.MEDIA_CONFIGURE, out instaUri)) + throw new Exception("Cant create URI for configuring media"); + return instaUri; + } } } \ No newline at end of file From 162f3002638194dfc43895710fcec1e85591e2f9 Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Fri, 5 May 2017 15:02:30 +0300 Subject: [PATCH 13/15] added view count for video --- InstaSharper/Classes/Models/InstaMedia.cs | 4 ++++ .../Classes/ResponseWrappers/InstaMediaItemResponse.cs | 6 ++++++ InstaSharper/Converters/InstaMediaConverter.cs | 5 ++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/InstaSharper/Classes/Models/InstaMedia.cs b/InstaSharper/Classes/Models/InstaMedia.cs index 4112e0a1..7a6fcc77 100644 --- a/InstaSharper/Classes/Models/InstaMedia.cs +++ b/InstaSharper/Classes/Models/InstaMedia.cs @@ -53,6 +53,10 @@ public class InstaMedia public InstaUserList Likers { get; set; } = new InstaUserList(); public InstaCarousel Carousel { get; set; } + public int ViewCount { get; set; } + + public bool HasAudio { get; set; } + public bool IsMultiPost => Carousel != null; } } \ No newline at end of file diff --git a/InstaSharper/Classes/ResponseWrappers/InstaMediaItemResponse.cs b/InstaSharper/Classes/ResponseWrappers/InstaMediaItemResponse.cs index 71161e77..55ab423e 100644 --- a/InstaSharper/Classes/ResponseWrappers/InstaMediaItemResponse.cs +++ b/InstaSharper/Classes/ResponseWrappers/InstaMediaItemResponse.cs @@ -67,6 +67,12 @@ internal class InstaMediaItemResponse [JsonProperty("type")] public int Type { get; set; } + [JsonProperty("view_count")] + public double ViewCount { get; set; } + + [JsonProperty("has_audio")] + public bool HasAudio { get; set; } + [JsonProperty("usertags")] public InstaUserTagListResponse UserTagList { get; set; } diff --git a/InstaSharper/Converters/InstaMediaConverter.cs b/InstaSharper/Converters/InstaMediaConverter.cs index 0bc40a55..e0ac89cb 100644 --- a/InstaSharper/Converters/InstaMediaConverter.cs +++ b/InstaSharper/Converters/InstaMediaConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using InstaSharper.Classes.Models; using InstaSharper.Classes.ResponseWrappers; using InstaSharper.Helpers; @@ -28,7 +29,9 @@ public InstaMedia Convert() LikesCount = SourceObject.LikesCount, MediaType = SourceObject.MediaType, FilterType = SourceObject.FilterType, - Width = SourceObject.Width + Width = SourceObject.Width, + HasAudio = SourceObject.HasAudio, + ViewCount = int.Parse(SourceObject.ViewCount.ToString(CultureInfo.InvariantCulture)) }; if (SourceObject.CarouselMedia != null) media.Carousel = ConvertersFabric.GetCarouselConverter(SourceObject.CarouselMedia).Convert(); From 904241013d1cf6021c70c0c2ee7917b6aafed409 Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Fri, 5 May 2017 23:49:31 +0300 Subject: [PATCH 14/15] 1.2.4 readme updates --- README.md | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 647bb983..b0ed0a58 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Note that: there is a simple [Instagram API](https://github.com/a-legotin/Instag [![Telegram chat](https://img.shields.io/badge/telegram-channel-blue.svg)](https://t.me/instasharper) [![GitHub stars](https://img.shields.io/github/stars/a-legotin/InstaSharper.svg)](https://github.com/a-legotin/InstaSharper/stargazers) -#### Current version: 1.2.3 [Stable], 1.2.4 [Under development] +#### Current version: 1.2.4 [Stable], 1.2.5 [Under development] ## Overview This project intends to provide all the features available in the Instagram API up to v10.3.2. It is being developed in C# for .NET Framework 4.5.2 and .NET Standart 1.6 @@ -52,20 +52,23 @@ Currently the library supports following coverage of the following Instagram API - [x] Get inbox thread - [x] Get recent activity - [x] Get recent following activity -- [x] Get followings list - [x] Like media - [x] Unlike media -- [ ] Follow user -- [ ] Unfollow user -- [ ] Send comment -- [ ] Edit comment -- [ ] Delete comment +- [x] Follow user +- [x] Unfollow user +- [x] Set account private +- [x] Set account public +- [x] Send comment +- [x] Delete comment +- [x] Upload photo + +- [] Get followings list * Get user list autocomplete * Register new user * Get megaphone log * Explore feed -* Upload photo + * Upload video * Upload story * Get full account backup @@ -107,13 +110,19 @@ IResult media = await api.GetUserMediaAsync(); #### Get media by its code: ```c# -IResult mediaItem = await api.GetMediaByCodeAsync(mediaCode); +IResult mediaItem = await api.GetMediaByIdAsync("1234567891234567891_123456789); ``` #### Get user timeline feed: ```c# IResult feed = await api.GetUserFeedAsync(); ``` + +#### Comment post: +```c# +IResult postResult = await apiInstance.CommentMediaAsync("1234567891234567891_123456789", "Hi there!"); +``` + ######for more samples you can look for [Examples folder](https://github.com/a-legotin/InstaSharper/tree/master/InstaSharper.Examples) From 54012fc69370adb0c2000ef8169b4b794033f8cf Mon Sep 17 00:00:00 2001 From: Alexander Legotin Date: Sat, 6 May 2017 00:12:06 +0300 Subject: [PATCH 15/15] some more samples added --- InstaSharper.Examples/Basics.cs | 90 ------------------- .../InstaSharper.Examples.csproj | 6 +- InstaSharper.Examples/Program.cs | 66 ++++++++++++++ InstaSharper.Examples/Samples/Basics.cs | 69 ++++++++++++++ InstaSharper.Examples/Samples/CommentMedia.cs | 23 +++++ InstaSharper.Examples/Samples/UploadPhoto.cs | 31 +++++++ InstaSharper.Examples/Utils/ConsoleUtils.cs | 18 ++++ .../Utils/StringExtensions.cs | 2 +- README.md | 5 +- 9 files changed, 215 insertions(+), 95 deletions(-) delete mode 100644 InstaSharper.Examples/Basics.cs create mode 100644 InstaSharper.Examples/Program.cs create mode 100644 InstaSharper.Examples/Samples/Basics.cs create mode 100644 InstaSharper.Examples/Samples/CommentMedia.cs create mode 100644 InstaSharper.Examples/Samples/UploadPhoto.cs create mode 100644 InstaSharper.Examples/Utils/ConsoleUtils.cs diff --git a/InstaSharper.Examples/Basics.cs b/InstaSharper.Examples/Basics.cs deleted file mode 100644 index 82e39647..00000000 --- a/InstaSharper.Examples/Basics.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Linq; -using InstaSharper.API; -using InstaSharper.API.Builder; -using InstaSharper.Classes; -using InstaSharper.Classes.Models; -using InstaSharper.Examples.Utils; - -namespace InstaSharper.Examples -{ - internal class Basics - { - /// - /// Api instance (one instance per Instagram user) - /// - private static IInstaApi _instaApi; - - /// - /// Config values - /// - private static int _maxDescriptionLength = 20; - - - private static void Main(string[] args) - { - // create user session data and provide login details - var userSession = new UserSessionData - { - UserName = "username", - Password = "password" - }; - // create new InstaApi instance using Builder - _instaApi = new InstaApiBuilder() - .SetUser(userSession) - .Build(); - // login - var logInResult = _instaApi.Login(); - if (!logInResult.Succeeded) { Console.WriteLine($"Unable to login: {logInResult.Info.Message}"); } - else - { - // get currently logged in user - var currentUser = _instaApi.GetCurrentUser().Value; - Console.WriteLine($"Logged in: username - {currentUser.UserName}, full name - {currentUser.FullName}"); - - // get self followers - var followers = _instaApi.GetUserFollowersAsync(currentUser.UserName, 5).Result.Value; - Console.WriteLine($"Count of followers [{currentUser.UserName}]:{followers.Count}"); - - // get self user's media, latest 5 pages - var currentUserMedia = _instaApi.GetUserMedia(currentUser.UserName, 5); - if (currentUserMedia.Succeeded) - { - Console.WriteLine($"Media count [{currentUser.UserName}]: {currentUserMedia.Value.Count}"); - foreach (var media in currentUserMedia.Value) PrintMedia("Self media", media); - } - - //get user time line feed, latest 5 pages - var userFeed = _instaApi.GetUserTimelineFeed(5); - if (userFeed.Succeeded) - { - Console.WriteLine($"Feed items (in {userFeed.Value.Pages} pages) [{currentUser.UserName}]: {userFeed.Value.Medias.Count}"); - foreach (var media in userFeed.Value.Medias) PrintMedia("Feed media", media); - //like first 10 medias from user timeline feed - foreach (var media in userFeed.Value.Medias.Take(10)) - { - var likeResult = _instaApi.LikeMedia(media.InstaIdentifier); - var resultString = likeResult.Value ? "liked" : "not like"; - Console.WriteLine($"Media {media.Code} {resultString}"); - } - } - - // get tag feed, latest 5 pages - var tagFeed = _instaApi.GetTagFeed("quadcopter", 5); - if (tagFeed.Succeeded) - { - Console.WriteLine($"Tag feed items (in {tagFeed.Value.Pages} pages) [{currentUser.UserName}]: {tagFeed.Value.Medias.Count}"); - foreach (var media in tagFeed.Value.Medias) PrintMedia("Tag feed", media); - } - var logoutResult = _instaApi.Logout(); - if (logoutResult.Value) Console.WriteLine("Logout succeed"); - } - Console.ReadKey(); - } - - private static void PrintMedia(string header, InstaMedia media) - { - Console.WriteLine($"{header} [{media.User.UserName}]: {media.Caption?.Text.Truncate(_maxDescriptionLength)}, {media.Code}, likes: {media.LikesCount}, multipost: {media.IsMultiPost}"); - } - } -} \ No newline at end of file diff --git a/InstaSharper.Examples/InstaSharper.Examples.csproj b/InstaSharper.Examples/InstaSharper.Examples.csproj index e1ae411e..d6720a57 100644 --- a/InstaSharper.Examples/InstaSharper.Examples.csproj +++ b/InstaSharper.Examples/InstaSharper.Examples.csproj @@ -46,8 +46,12 @@ - + + + + + diff --git a/InstaSharper.Examples/Program.cs b/InstaSharper.Examples/Program.cs new file mode 100644 index 00000000..3e4530a2 --- /dev/null +++ b/InstaSharper.Examples/Program.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using InstaSharper.API; +using InstaSharper.API.Builder; +using InstaSharper.Classes; +using InstaSharper.Examples.Samples; + +namespace InstaSharper.Examples +{ + public class Program + { + /// + /// Api instance (one instance per Instagram user) + /// + private static IInstaApi _instaApi; + + private static void Main(string[] args) + { + Console.WriteLine("Starting demo of InstaSharper project"); + // create user session data and provide login details + var userSession = new UserSessionData + { + UserName = "username", + Password = "password" + }; + // create new InstaApi instance using Builder + _instaApi = new InstaApiBuilder() + .SetUser(userSession) + .Build(); + // login + var logInResult = _instaApi.Login(); + if (!logInResult.Succeeded) + { + Console.WriteLine($"Unable to login: {logInResult.Info.Message}"); + } + else + { + Console.WriteLine("Press 1 to start basic demo samples"); + Console.WriteLine("Press 2 to start upload photo demo sample"); + Console.WriteLine("Press 3 to start comment media demo sample"); + + var key = Console.ReadKey(); + switch (key.Key) + { + case ConsoleKey.D1: + new Basics(_instaApi).DoShow(); + break; + case ConsoleKey.D2: + new UploadPhoto(_instaApi).DoShow(); + break; + case ConsoleKey.D3: + new CommentMedia(_instaApi).DoShow(); + break; + default: + break; + } + var logoutResult = _instaApi.Logout(); + if (logoutResult.Value) Console.WriteLine("Logout succeed"); + } + Console.ReadKey(); + } + } +} \ No newline at end of file diff --git a/InstaSharper.Examples/Samples/Basics.cs b/InstaSharper.Examples/Samples/Basics.cs new file mode 100644 index 00000000..f933dd71 --- /dev/null +++ b/InstaSharper.Examples/Samples/Basics.cs @@ -0,0 +1,69 @@ +using System; +using System.Linq; +using InstaSharper.API; +using InstaSharper.Examples.Utils; + +namespace InstaSharper.Examples.Samples +{ + internal class Basics + { + /// + /// Config values + /// + private static readonly int _maxDescriptionLength = 20; + + private readonly IInstaApi _instaApi; + + public Basics(IInstaApi instaApi) + { + _instaApi = instaApi; + } + + public void DoShow() + { + // get currently logged in user + var currentUser = _instaApi.GetCurrentUser().Value; + Console.WriteLine($"Logged in: username - {currentUser.UserName}, full name - {currentUser.FullName}"); + + // get self followers + var followers = _instaApi.GetUserFollowersAsync(currentUser.UserName, 5).Result.Value; + Console.WriteLine($"Count of followers [{currentUser.UserName}]:{followers.Count}"); + + // get self user's media, latest 5 pages + var currentUserMedia = _instaApi.GetUserMedia(currentUser.UserName, 5); + if (currentUserMedia.Succeeded) + { + Console.WriteLine($"Media count [{currentUser.UserName}]: {currentUserMedia.Value.Count}"); + foreach (var media in currentUserMedia.Value) + ConsoleUtils.PrintMedia("Self media", media, _maxDescriptionLength); + } + + //get user time line feed, latest 5 pages + var userFeed = _instaApi.GetUserTimelineFeed(5); + if (userFeed.Succeeded) + { + Console.WriteLine( + $"Feed items (in {userFeed.Value.Pages} pages) [{currentUser.UserName}]: {userFeed.Value.Medias.Count}"); + foreach (var media in userFeed.Value.Medias) + ConsoleUtils.PrintMedia("Feed media", media, _maxDescriptionLength); + //like first 10 medias from user timeline feed + foreach (var media in userFeed.Value.Medias.Take(10)) + { + var likeResult = _instaApi.LikeMedia(media.InstaIdentifier); + var resultString = likeResult.Value ? "liked" : "not liked"; + Console.WriteLine($"Media {media.Code} {resultString}"); + } + } + + // get tag feed, latest 5 pages + var tagFeed = _instaApi.GetTagFeed("quadcopter", 5); + if (tagFeed.Succeeded) + { + Console.WriteLine( + $"Tag feed items (in {tagFeed.Value.Pages} pages) [{currentUser.UserName}]: {tagFeed.Value.Medias.Count}"); + foreach (var media in tagFeed.Value.Medias) + ConsoleUtils.PrintMedia("Tag feed", media, _maxDescriptionLength); + } + } + } +} \ No newline at end of file diff --git a/InstaSharper.Examples/Samples/CommentMedia.cs b/InstaSharper.Examples/Samples/CommentMedia.cs new file mode 100644 index 00000000..b8e1c038 --- /dev/null +++ b/InstaSharper.Examples/Samples/CommentMedia.cs @@ -0,0 +1,23 @@ +using System; +using InstaSharper.API; + +namespace InstaSharper.Examples.Samples +{ + internal class CommentMedia + { + private readonly IInstaApi _instaApi; + + public CommentMedia(IInstaApi instaApi) + { + _instaApi = instaApi; + } + + public void DoShow() + { + var commentResult = _instaApi.CommentMedia("", "Hi there!"); + Console.WriteLine(commentResult.Succeeded + ? $"Comment created: {commentResult.Value.Pk}, text: {commentResult.Value.Text}" + : $"Unable to create comment: {commentResult.Info.Message}"); + } + } +} \ No newline at end of file diff --git a/InstaSharper.Examples/Samples/UploadPhoto.cs b/InstaSharper.Examples/Samples/UploadPhoto.cs new file mode 100644 index 00000000..b11915ca --- /dev/null +++ b/InstaSharper.Examples/Samples/UploadPhoto.cs @@ -0,0 +1,31 @@ +using System; +using System.IO; +using InstaSharper.API; +using InstaSharper.Classes.Models; + +namespace InstaSharper.Examples.Samples +{ + internal class UploadPhoto + { + private readonly IInstaApi _instaApi; + + public UploadPhoto(IInstaApi instaApi) + { + _instaApi = instaApi; + } + + public void DoShow() + { + var mediaImage = new MediaImage + { + Height = 1080, + Width = 1080, + URI = new Uri(Path.GetFullPath(@"c:\someawesomepicture.jpg"), UriKind.Absolute).LocalPath + }; + var result = _instaApi.UploadPhoto(mediaImage, "someawesomepicture"); + Console.WriteLine(result.Succeeded + ? $"Media created: {result.Value.Pk}, {result.Value.Caption}" + : $"Unable to upload photo: {result.Info.Message}"); + } + } +} \ No newline at end of file diff --git a/InstaSharper.Examples/Utils/ConsoleUtils.cs b/InstaSharper.Examples/Utils/ConsoleUtils.cs new file mode 100644 index 00000000..173f5476 --- /dev/null +++ b/InstaSharper.Examples/Utils/ConsoleUtils.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using InstaSharper.Classes.Models; + +namespace InstaSharper.Examples.Utils +{ + public static class ConsoleUtils + { + public static void PrintMedia(string header, InstaMedia media, int maxDescriptionLength) + { + Console.WriteLine( + $"{header} [{media.User.UserName}]: {media.Caption?.Text.Truncate(maxDescriptionLength)}, {media.Code}, likes: {media.LikesCount}, multipost: {media.IsMultiPost}"); + } + } +} \ No newline at end of file diff --git a/InstaSharper.Examples/Utils/StringExtensions.cs b/InstaSharper.Examples/Utils/StringExtensions.cs index 5b757da7..b8cad66f 100644 --- a/InstaSharper.Examples/Utils/StringExtensions.cs +++ b/InstaSharper.Examples/Utils/StringExtensions.cs @@ -13,4 +13,4 @@ public static string Truncate(this string value, int maxChars) return value.Length <= maxChars ? value : value.Substring(0, maxChars) + "..."; } } -} +} \ No newline at end of file diff --git a/README.md b/README.md index b0ed0a58..e7f5717d 100644 --- a/README.md +++ b/README.md @@ -62,13 +62,12 @@ Currently the library supports following coverage of the following Instagram API - [x] Delete comment - [x] Upload photo -- [] Get followings list +- [ ] Get followings list * Get user list autocomplete * Register new user * Get megaphone log * Explore feed - * Upload video * Upload story * Get full account backup @@ -123,7 +122,7 @@ IResult feed = await api.GetUserFeedAsync(); IResult postResult = await apiInstance.CommentMediaAsync("1234567891234567891_123456789", "Hi there!"); ``` -######for more samples you can look for [Examples folder](https://github.com/a-legotin/InstaSharper/tree/master/InstaSharper.Examples) +#####for more samples you can look for [Examples folder](https://github.com/a-legotin/InstaSharper/tree/master/InstaSharper.Examples) #### [Why two separate repos with same mission?](https://github.com/a-legotin/InstagramAPI-Web/wiki/Difference-between-API-Web-and-just-API-repositories)