Пытаемся понять как работать с общим кодом на основе постера картинок на стену ВК

Discussion in 'Девятый конкурс статей' started by Advert31337, May 9, 2018.

  1. Advert31337

    Advert31337 Client

    Joined:
    Dec 18, 2016
    Messages:
    36
    Likes Received:
    27
    Приветствую всех коллег по цеху!

    Начну с благодарностей, спасибо @sibbora с его шикарными материалами из академии и @LaGir aka
    @Klask с его разъяснениями и мини-обзорами!!!


    Коротко о себе.
    Новичок в теме ZennoPoster, как программист в баллах 0.1/100, работаю специалистом по интернет-рекламе на заводе))).
    Для себя решил изучать работу в коде сразу, минуя кубики.

    Тема заработка не стояла для меня приоритетом, а вот проблема экономии времени очень острая. И, соответственно, я решая эти проблемы и изучал C#.

    Одна из проблем – это размещение картинок, видео и гифок на стену и альбомы в ВК. Стандартные сервисы меня не устраивали, так как надо было сидеть и вбивать посты и время для размещения, а мне надо, чтобы программа сама брала файл из папки, описание и текст поста из файла.
    В этой статье будет простой шаблон для размещения фотографий на стену группы ВК.

    В качестве инструментов мы берем:
    1. Руки (какие есть те и берем)
    2. Документацию API ВК -- https://vk.com/dev/photos
    3. Библиотеку NewtonSoft.dll
    4. C#
    5. Зенку

    Начинаем планировать.
    Продумываем файловую систему и структуру кода

    С файлами я решил сделать так.
    upload_2018-5-9_17-23-24.png
    И в папке "foto to upload" разместил файл с описанием к фото и его же использую для текста поста:
    upload_2018-5-9_17-24-48.png

    Для удобства организации пространства я использую такое расположение окон:
    upload_2018-5-9_17-27-45.png
    Как хочется чтобы в PM появилась тёмная тема!

    Для начала читаем как работает API для постинга фото в ВК.
    Идем по ссылке ниже: VK API
    Оттуда мы узнаем, что нам нужны 3 метода:
    1. photos.getWallUploadServer – получаем ссылку на место, куда загрузим фотку и грузим фото
    2. photos.saveWallPhoto – загружаем фото на сервер вк
    3. photos.wall.post – размещаем фото на стену

    Структура кода будет такой:
    1. Блок с переменными
    2. Блок авторизации/получения токена
    3. Блок получения файла для постинга
    4. Постинг через API VK
    5. Будут добавлены модифицированные методы, которые слегка оптимизируют код

    Итак, поехали.
    Помещаем библиотеку NewtonSoft из папки progs в папку Progs\ExternalAssemblies и прописываем юзинги:
    upload_2018-5-9_18-7-21.png
    upload_2018-5-9_18-8-16.png
    upload_2018-5-9_18-9-7.png
    upload_2018-5-9_18-9-36.png
    upload_2018-5-9_18-4-15.png

    С переменными все должно быть просто. (Решил не использовать переменные уровня проекта)
    Code (Csharp):
    1. //==Блок с переменными
    2. Random rnd = new Random();
    3. //Создаем пустой список куда в последствии помести пути к файлам из папки strSourceDirectoryPath
    4. List<string> lstListFotoFiles = new List<string>();
    5. //Присваиваем переменной путь к папке с файлами
    6. string strSourceDirectoryPath = project.Directory + @"\foto to upload\";
    7. //Directory.EnumerateFiles: получаем список файлов jpg в папке strSourceDirectoryPath
    8. lstListFotoFiles.AddRange(Directory.EnumerateFiles(strSourceDirectoryPath, "*.jpg", SearchOption.AllDirectories));
    9. //Берем логин и пароль из списка
    10. //Считываем содержимое файла vkInput.txt
    11. string strVkInput = File.ReadAllText(project.Directory + @"/vkInput.txt");
    12. /*
    13. Во входном файле у нас указанны данные в таком виде:
    14. Log:Pass|GroupId|token
    15. Используя разделитель '|' разбиваем текст на части в массив, затем первый элемент:
    16. Log:Pass
    17. тоже делим на части разделителем ':'.
    18. и берем первый (нулевой) элемент массива Log.Так получаем логин.
    19. Массивы и списки индексируются или как еще говорять нумеруются с нуля!!!!
    20. */
    21. string strVKLogin = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[0];
    22. /*
    23. Во входном файле у нас указанны данные в таком виде:
    24. Log:Pass|GroupId|token
    25. Используя разделитель '|' разбиваем текст на части в массив, затем первый элемент:
    26. Log:Pass
    27. тоже делим на части разделителем ':'.
    28. и берем второй (первый) элемент массива Pass. Так получаем пароль.
    29. */
    30. string strVKPass = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[1];
    31. string strIdFoto = String.Empty;
    32. //Берем текст из файла caption.txt, это будет описанием к фото и текстом поста
    33. string strCaption = File.ReadAllText(project.Directory + @"\foto to upload\caption.txt");
    34. /*
    35. Во входном файле у нас указанны данные в таком виде:
    36. Log:Pass|GroupId|token
    37. Используя разделитель '|' разбиваем текст на части в массив, затем второй элемент [1] и используем его как id группы вк GroupId.
    38. */
    39. string strGroupId = strVkInput.Split('|').ToArray()[1];
    40. /*
    41. Во входном файле у нас указанны данные в таком виде:
    42. Log:Pass|GroupId|token
    43. Используя разделитель '|' разбиваем текст на части в массив, затем третий элемент [2] и используем его как токен вк token.
    44. */
    45. string strAccess_token = strVkInput.Split('|').ToArray()[2];
    46. //==Конец блока с переменными
    Авторизацию я решил делать через официальное приложение вк для андроид.
    Code (Csharp):
    1. //==Модуль авторизации и получения нового токена
    2. if(strAccess_token.Contains("token")){
    3.     strAccess_token = "";
    4.     //Авторизация апи
    5.     string strOauthVk = String.Format("https://oauth.vk.com/token?grant_type=password"
    6.         +"&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH&username={0}&password={1}",strVKLogin,strVKPass);
    7.     string VkResp = ZennoPoster.HttpGet(strOauthVk);
    8.     JObject jsonVk = JObject.Parse(VkResp);
    9.     strAccess_token = jsonVk.SelectToken("access_token").ToString();
    10.     //Записываем обновленные входные данные с токеном в файл в туже строку
    11.     string inputData = strVkInput.Replace("token", strAccess_token);
    12.     File.WriteAllText(project.Directory +  @"/vkInput.txt",inputData);
    13.     project.SendInfoToLog("Взяли новый токен: " + strAccess_token +"\n Он сохранен в файл vkInput.txt", true);
    14. }else{
    15.     project.SendInfoToLog("Берем токен из файла");
    16. }
    17. //==Конец Модуля авторизации и получения нового токена
    Разумеется, если токен у нас заполнен и он рабочий, то авторизация не поднадобится

    А теперь начинаем процедуру постинга:
    Нам нужно получить адрес сервера куда будем грузить фото:
    Code (Csharp):
    1. //Формируем запрос на получение адреса сервера для загрузки и записываем его в переменную strGetServerUrl
    2. string strGetServerUrl = String.Format(@"https://api.vk.com/method/photos.getWallUploadServer?v=5.69&access_token={0}&group_id={1}",
    3.     strAccess_token,strGroupId);
    4. //Делаем запрос ZennoPoster.HttpGet и записываем его в переменную strServerResult
    5. string strServerResult = ZennoPoster.HttpGet(strGetServerUrl);
    6.  
    7. //Забираем адрес из ответа strServerResult с помощью регулярок
    8. string strUploadServer = new Regex(@"(?<=""upload_url"":"")[\w\W]*?(?=\"",""album_id)").Match(strServerResult).ToString().Replace(@"\","");
    9. //Примитивная проверка. Если strUploadServer имеет пустое значение, то подставляем во входном файле слово "token"  и останавливаем шаблон
    10. if(strUploadServer==String.Empty){
    11.    //поправляем шаблон под корректный вид
    12.    File.WriteAllText(project.Directory +  @"/vkInput.txt",String.Format(@"{0}:{1}|{2}|token",strVKLogin,strVKPass,strGroupId));
    13.    throw new Exception("Что-то не то с входным файлом. Останалвиваем шаблон. Проверьте логин, пароль и ид группы/n ПЕРЕЗАПУСТИТЕ ШАБЛОН");
    14. }
    15. project.SendWarningToLog("Забираем сервер: "+strUploadServer);
    Сформировать запрос для загрузки на сервер:
    Code (Csharp):
    1. //Формируем тело контент для загрузки на сервер
    2. //Получение информации о файле для загрузки
    3. FileInfo strFileInfo = new FileInfo(lstListFotoFiles[0]);
    4. string FileName = strFileInfo.Name;
    5. //==Формируем тело content для POST-запроса
    6. string boundary = "------WebKitFormBoundary"+rnd.Next(100000000,999999999).ToString();
    7. string post_data = "";
    8. post_data += boundary + "\n";
    9. post_data += string.Format("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\n", FileName);
    10. post_data += "Content-Type: image/jpg\n";
    11. post_data += lstListFotoFiles[0];
    12. //==Конец формирования тела content для POST-запроса
    13.  
    14. //Загружаем фото на сервер ВК
    15. project.SendInfoToLog("Второй этап - Грузим фото на сервер vk",true);
    16. string uploadItemInfo = ZennoPoster.HttpPost(strUploadServer, post_data,
    17.     "multipart/form-data",
    18.     "",
    19.     "utf-8",
    20.     ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.BodyOnly,
    21.     30000);
    22. //Забираем из ответа id фото, server и hash
    23. string photo_id = new Regex(@"(?<=""photo"":"").*?(?="","")").Match(uploadItemInfo).ToString().Replace(@"\","");
    24. string server = new Regex(@"(?<=""server"":).*?(?=,)").Match(uploadItemInfo).ToString();
    25. string hash = new Regex(@"(?<=""hash"":"").*?(?="")").Match(uploadItemInfo).ToString();
    26. project.SendWarningToLog("Забираем данные для отправки фото:" +Environment.NewLine+
    27.     "Фото id: "+photo_id +Environment.NewLine+
    28.     "Сервер: "+server +Environment.NewLine+
    29.     "Хэш: "+hash);
    В ответе мы забираем с помощью регулярок id фотографии, сервер и хэш.

    И делаем запрос для сохранения фото:
    Code (Csharp):
    1. //Сохраняем фото на стену
    2. project.SendInfoToLog("Третий  этап - получаем адрес сервера для загрузки фото",true);
    3. project.SendInfoToLog("Взяли для описания: " + strCaption);
    4. //Формируем запрос для сохранения на стену
    5. string PostRequestUrl = String.Format("https://api.vk.com/method/photos.saveWallPhoto?access_token={0}&group_id={1}&photo={2}&server={3}&hash={4}&caption={5}&v=5.69",
    6.     strAccess_token,strGroupId,photo_id,server,hash,TextProcessing.UrlEncode(strCaption));
    7.  
    8. string PostRequest =  ZennoPoster.HttpGet(PostRequestUrl);
    9.  
    10. project.SendInfoToLog("photos.saveWallPhoto " + PostRequest);
    11. //Забираем ссылку на запись на стену PostRequest
    12. string PhotoToWall = new Regex(@"(?<=\{""response"":\[\{""id"":)[\w\W]*?(?=,"")").Match(PostRequest).ToString();
    13. string Owner_id = new Regex(@"(?<=owner_id"":)[\w\W]*?(?=,)").Match(PostRequest).ToString();
    14. project.SendInfoToLog("id фото для размещения на стене " + PostRequest);
    15. project.SendInfoToLog("photos.saveWallPhoto " + PhotoToWall);
    16.  
    17. string attach ="photo"+Owner_id+"_"+PhotoToWall;
    Постим сохраненное фото на стену нашей группы:
    Code (Csharp):
    1. string PostText = TextProcessing.UrlEncode(strCaption);
    2. //Формируем запрос для размещения поста
    3. string PostUrlWallGet = String.Format("https://api.vk.com/method/wall.post?"+
    4.     "access_token={0}"+
    5.     "&owner_id=-{1}"+
    6.     "&friends_only=0"+
    7.     "&from_group=1"+
    8.     "&attachments={2}"+
    9.     "&signed=0"+
    10.     "&message={3}"+
    11.     "&mark_as_ads=0"+
    12.     "&v=5.69",
    13.     strAccess_token,strGroupId,attach,PostText);
    14. //Отправляем запрос
    15. string PostId = ZennoPoster.HttpGet(PostUrlWallGet);
    16. //Пауза 1 сек.
    17. Thread.Sleep(1000);
    18. //Забираем i поста из ответа PostId
    19. string PostIdOnly = new Regex(@"(?<=""post_id"":).*?(?=}})").Match(PostId).ToString();
    Перемещаем отработанный файл в папку foto used:

    Code (Csharp):
    1. //Перемещаем использованный файл в папку used
    2. File.Move(lstListFotoFiles[0],project.Directory+"/foto used/"+FileName);
    3. //======+++Тут процес постинга закончен
    4. //Формируем ссылку на пост
    5. string FinishPostUrlForCheck = String.Format(@"https://vk.com/club{0}?w=wall-{0}_{1}",strGroupId,PostIdOnly);
    6. project.SendInfoToLog("Ссылка на пост: " + FinishPostUrlForCheck, true);
    А теперь смотрим, как это можно преобразовать в общий код, не будем усложнять, просто разобьем на две части: модуль авторизации и модуль для постинга. Разумеется можно разделить на более мелкие функции, но поскольку цель статьи просто понять что есть «общий код» lтак:

    Для начала создадим свое пространство имен SocialBot (Можно писать и в ZennoLab.OwnCode)
    upload_2018-5-9_18-11-20.png
    Прописываем в юзингах и в общем коде
    upload_2018-5-9_18-11-30.png
    upload_2018-5-9_18-12-0.png
    Продумаем структуру кода, я решил что надо сделать 3 класса кода по функциональности Tech, Acc, Poster.
    • В первом я храню процедуры и функции чисто технического характера
    • Во втором авторизация и операция с токеном
    • В третьем процедура размещения фото на стену


    При работе с общим кодом есть также нюанс – это объекты instance и project. Их нет в общем коде и их надо подключить.
    Для этого в классе Tech создаем глобальные переменные:
    public static IZennoPosterProjectModel project;
    public static Instance instance;

    В сниппете прописываем:
    Tech.project = project;
    Tech.instance = instance;

    И в каждом классе, где используются эти объекты, прописываем:
    public static Instance instance = Tech.instance;
    public static IZennoPosterProjectModel project= Tech.project;



    Поскольку все мы знаем, что такое кубики, то мы видели, что у них есть галочка «не возвращать значение». На примере модуля авторизации мы должны получить access_token,
    upload_2018-5-9_17-47-48.png
    access_token – это строка, а значит нам надо этот модуль завернуть в конструкцию
    public static string{}
    , что и говорит о том что модуль=метод=функция возвращает нам строковое значение.
    Как используем?
    string strAccess_token = Acc.GetVkApiToken();

    То есть мы создали метод, который прочтет файл и если не найдет там токен, то создаст его, запишет в файл и вернет в качестве строкового значения для переменной strAccess_token.

    Модуль постинга не должен что-либо возвращать поэтому мы оборачиваем его в конструкцию
    public static void ApiVkPhotoPost() – это просто процедура.
    Теперь в сниппете прописываем код.

    Некоторые внимательные читатели заметили, что я в обоих методах GetVkApiToken() и ApiVkPhotoPost() обращаюсь к входному файлу и это не есть хорошо. Как это исправить?
    Ведь метод может вернуть только одну переменную!

    Мы используем ключевое слово out
    И прописываем в коде вот так:
    Code (Csharp):
    1.         //Модифицированный метод получения токена, логина, пароля и прочих входных данных
    2.         public static void ModGetVkApiToken(out string strVKLogin, out string strVKPass, out string strGroupId, out string strAccess_token)
    3.         {
    4.             string strVkInput = File.ReadAllLines(project.Directory + @"/vkInput.txt").ToArray()[0];
    5.             strVKLogin = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[0];
    6.             strVKPass = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[1];
    7.             //Считаем id группы из файла
    8.             strGroupId = strVkInput.Split('|').ToArray()[1];
    9.             //Считаем token группы из файла
    10.             strAccess_token = strVkInput.Split('|').ToArray()[2];
    11.    
    12.             if(!strAccess_token.Contains("token"))
    13.             {
    14.                 project.SendInfoToLog("Взяли токен: " + strAccess_token, true);
    15.             }else{
    16.                 strAccess_token = "";
    17.                 //Авторизация апи
    18.                 string strOauthVk = String.Format("https://oauth.vk.com/token?grant_type=password"
    19.                     +"&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH&username={0}&password={1}",strVKLogin,strVKPass);
    20.  
    21.                 string VkResp = ZennoPoster.HttpGet(strOauthVk);
    22.                 JObject jsonVk = JObject.Parse(VkResp);
    23.                 strAccess_token = jsonVk.SelectToken("access_token").ToString();
    24.                 //Записываем обновленные входные данные с токеном в файл в туже строку
    25.                 string inputData = strVkInput.Replace("token", strAccess_token);
    26.                 File.WriteAllText(project.Directory +  @"/vkInput.txt",inputData);
    27.                 project.SendInfoToLog("Взяли новый токен: " + strAccess_token +"\n Он сохранен в файл vkInput.txt", true);
    28.             }
    29.  
    30.         }
    И вызываем его:
    Code (Csharp):
    1. string strVKLogin = String.Empty;
    2.             string strVKPass = String.Empty;
    3.             //Считаем id группы из файла
    4.             string strGroupId = String.Empty;
    5.             //Потом поднадобится
    6.             string strIdFoto = String.Empty;
    7.             //Считываем описание к фотографии
    8.             string strCaption = File.ReadAllText(project.Directory + @"\foto to upload\caption.txt");
    9.             //************** Считаем token группы из файла
    10.             string strAccess_token = String.Empty;
    11.             Acc.ModGetVkApiToken(out strVKLogin, out strVKPass, out strGroupId, out strAccess_token);//Блок получения токена перенесен в общий код
    Таким образом мы обращаемся к входному файлу только из метода ModGetVkApiToken.
    А в процедуре ModApiVkPhotoPost() заранее создал пустые переменные которые будут наполнены после строки
    Code (Csharp):
    1.  
    2. Acc.ModGetVkApiToken(out strVKLogin, out strVKPass, out strGroupId, out strAccess_token);
    3.  
    Ну вот вроде все.
     
    Last edited: May 11, 2018
    Belias, LaGir, iBotovod and 6 others like this.
  2. Advert31337

    Advert31337 Client

    Joined:
    Dec 18, 2016
    Messages:
    36
    Likes Received:
    27
    Вот так выглядит общий код:
    Code (Csharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Data;
    5. using System.Drawing;
    6. using System.Linq;
    7. using System.Text;
    8. using System.Threading;
    9. using System.IO;
    10. using System.Text.RegularExpressions;
    11. using ZennoLab.CommandCenter;
    12. using ZennoLab.InterfacesLibrary;
    13. using ZennoLab.InterfacesLibrary.ProjectModel;
    14. using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
    15. using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
    16. using ZennoLab.Macros;
    17. using Global.ZennoExtensions;
    18. using ZennoLab.Emulation;
    19. using Newtonsoft.Json;
    20. using Newtonsoft.Json.Linq;
    21. using System;
    22. using SocialBot;
    23.  
    24. namespace SocialBot{
    25.     //Технический блок, сюде я впихиваю логер, планировщик и операции с файлами
    26.     public class Tech
    27.     {
    28.         //Заклинание базовое
    29.         public static IZennoPosterProjectModel project;
    30.         public static Instance instance;
    31.  
    32.     }
    33.     //Тут действия связанные с авторизациями и токенами
    34.     public class Acc
    35.     {
    36.         //Подключаемся к базовому заклинанию
    37.         public static Instance instance = Tech.instance;
    38.         public static IZennoPosterProjectModel project= Tech.project;
    39.    
    40.         //Извлечь токен через собственное приложение вк. Браузерная авторизация.
    41.         public static string GetVkApiToken()
    42.         {
    43.             string strVkInput = File.ReadAllLines(project.Directory + @"/vkInput.txt").ToArray()[0];
    44.             string strVKLogin = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[0];
    45.             string strVKPass = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[1];
    46.             //Считаем id группы из файла
    47.             string strGroupId = strVkInput.Split('|').ToArray()[1];
    48.             //Считаем token группы из файла
    49.             string strAccess_token = strVkInput.Split('|').ToArray()[2];
    50.    
    51.             if(!strAccess_token.Contains("token"))
    52.             {
    53.                 project.SendInfoToLog("Взяли токен: " + strAccess_token, true);
    54.                 return strAccess_token;
    55.             }else{
    56.                 strAccess_token = "";
    57.                 //Авторизация апи
    58.                 string strOauthVk = String.Format("https://oauth.vk.com/token?grant_type=password"
    59.                     +"&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH&username={0}&password={1}",strVKLogin,strVKPass);
    60.  
    61.                 string VkResp = ZennoPoster.HttpGet(strOauthVk);
    62.                 JObject jsonVk = JObject.Parse(VkResp);
    63.                 strAccess_token = jsonVk.SelectToken("access_token").ToString();
    64.                 //Записываем обновленные входные данные с токеном в файл в туже строку
    65.                 string inputData = strVkInput.Replace("token", strAccess_token);
    66.                 File.WriteAllText(project.Directory +  @"/vkInput.txt",inputData);
    67.                 project.SendInfoToLog("Взяли новый токен: " + strAccess_token +"\n Он сохранен в файл vkInput.txt", true);
    68.                 return strAccess_token;
    69.             }
    70.  
    71.         }
    72.         //Модифицированный метод получения токена, логина, пароля и прочих входных данных
    73.         public static void ModGetVkApiToken(out string strVKLogin, out string strVKPass, out string strGroupId, out string strAccess_token)
    74.         {
    75.             string strVkInput = File.ReadAllLines(project.Directory + @"/vkInput.txt").ToArray()[0];
    76.             strVKLogin = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[0];
    77.             strVKPass = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[1];
    78.             //Считаем id группы из файла
    79.             strGroupId = strVkInput.Split('|').ToArray()[1];
    80.             //Считаем token группы из файла
    81.             strAccess_token = strVkInput.Split('|').ToArray()[2];
    82.    
    83.             if(!strAccess_token.Contains("token"))
    84.             {
    85.                 project.SendInfoToLog("Взяли токен: " + strAccess_token, true);
    86.             }else{
    87.                 strAccess_token = "";
    88.                 //Авторизация апи
    89.                 string strOauthVk = String.Format("https://oauth.vk.com/token?grant_type=password"
    90.                     +"&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH&username={0}&password={1}",strVKLogin,strVKPass);
    91.  
    92.                 string VkResp = ZennoPoster.HttpGet(strOauthVk);
    93.                 JObject jsonVk = JObject.Parse(VkResp);
    94.                 strAccess_token = jsonVk.SelectToken("access_token").ToString();
    95.                 //Записываем обновленные входные данные с токеном в файл в туже строку
    96.                 string inputData = strVkInput.Replace("token", strAccess_token);
    97.                 File.WriteAllText(project.Directory +  @"/vkInput.txt",inputData);
    98.                 project.SendInfoToLog("Взяли новый токен: " + strAccess_token +"\n Он сохранен в файл vkInput.txt", true);
    99.             }
    100.  
    101.         }
    102.         //Удаление токена
    103.         public static void DeleteToken()
    104.         {
    105.             string strVkInput = File.ReadAllLines(project.Directory + @"/vkInput.txt").ToArray()[0];
    106.             string strVKLogin = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[0];
    107.             string strVKPass = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[1];
    108.             //Считаем id группы из файла
    109.             string strGroupId = strVkInput.Split('|').ToArray()[1];
    110.             //поправляем шаблон под корректный вид
    111.             File.WriteAllText(project.Directory +  @"/vkInput.txt",String.Format(@"{0}:{1}|{2}|token",strVKLogin,strVKPass,strGroupId));
    112.         }
    113.     }
    114.     //Блок-постер всего и вся на стену
    115.     public class Poster
    116.     {
    117.         //Подключаемся к базовому заклинанию
    118.         public static Instance instance = Tech.instance;
    119.         public static IZennoPosterProjectModel project= Tech.project;
    120.         public static void ApiVkPhotoPost()
    121.         {
    122.             //==Блок с переменными
    123.             Random rnd = new Random();
    124.             //*************** Файлы для отправки
    125.             //Создаем пустой список куда в последствии помести пути к файлам из папки strSourceDirectoryPath
    126.             List<string> lstListFotoFiles = new List<string>();
    127.             //Присваиваем переменной путь к папке с файлами
    128.             string strSourceDirectoryPath = project.Directory + @"\foto to upload\";
    129.             //Directory.EnumerateFiles: получаем список файлов jpg в папке strSourceDirectoryPath
    130.             lstListFotoFiles.AddRange(Directory.EnumerateFiles(strSourceDirectoryPath, "*.jpg", SearchOption.AllDirectories));
    131.  
    132.             //Берем логин и пароль из списка
    133.             string strVkInput = File.ReadAllLines(project.Directory + @"/vkInput.txt")[0];
    134.             //Считаем id группы из файла
    135.             string strGroupId = strVkInput.Split('|').ToArray()[1];
    136.             //Потом поднадобится
    137.             string strIdFoto = String.Empty;
    138.             //Считываем описание к фотографии
    139.             string strCaption = File.ReadAllText(project.Directory + @"\foto to upload\caption.txt");
    140.             //************** Считаем token группы из файла
    141.             string strAccess_token = Acc.GetVkApiToken();//Блок получения токена перенесен в общий код
    142.             //*******************************************
    143.             //==Конец блока с переменными
    144.  
    145.             //Загрузка фото в ВК
    146.             //Запрос на получение адреса сервера для загрузки
    147.             project.SendInfoToLog("Первый этап - получаем адрес сервера для загрузки фото",true);
    148.             string strGetServerUrl = String.Format(@"https://api.vk.com/method/photos.getWallUploadServer?v=5.69&access_token={0}&group_id={1}",
    149.                 strAccess_token,strGroupId);
    150.             string strServerResult = ZennoPoster.HttpGet(strGetServerUrl);
    151.             //Забираем адрес из ответа
    152.             string strUploadServer = new Regex(@"(?<=""upload_url"":"")[\w\W]*?(?=\"",""album_id)").Match(strServerResult).ToString().Replace(@"\","");
    153.            //Если в ответе strServerResult имеет пустое значение, то удаляем токен и останавливаем шаблон
    154.            if(strUploadServer==String.Empty)
    155.            {
    156.                Acc.DeleteToken();
    157.                throw new Exception("Что-то не то с входным файлом. Останалвиваем шаблон. Проверьте логин, пароль и ид группы/n ПЕРЕЗАПУСТИТЕ ШАБЛОН");
    158.            }
    159.    
    160.            project.SendWarningToLog("Забираем сервер: "+strUploadServer);
    161.            //************** Формируем тело контент для загрузки на сервер
    162.            //Получение информации о файле для загрузки
    163.            FileInfo strFileInfo = new FileInfo(lstListFotoFiles[0]);
    164.            string FileName = strFileInfo.Name;
    165.            //==Формируем тело content для POST-запроса
    166.            string boundary = "------WebKitFormBoundary"+rnd.Next(100000000,999999999).ToString();
    167.            string post_data = "";
    168.            post_data += boundary + "\n";
    169.            post_data += string.Format("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\n", FileName);
    170.             post_data += "Content-Type: image/jpg\n";
    171.             post_data += lstListFotoFiles[0];
    172.             //============== Конец формирования тела content для POST-запроса
    173.  
    174.             project.SendInfoToLog("Второй этап - Грузим фото на сервер vk",true);
    175.             //Загружаем фото на сервер ВК
    176.             string uploadItemInfo = ZennoPoster.HttpPost(strUploadServer, post_data,
    177.                 "multipart/form-data",
    178.                 "",
    179.                 "utf-8",
    180.                 ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.BodyOnly,
    181.                 30000);
    182.             //Забираем из ответа id фото, server и hash
    183.             string photo_id = new Regex(@"(?<=""photo"":"").*?(?="","")").Match(uploadItemInfo).ToString().Replace(@"\","");
    184.             string server = new Regex(@"(?<=""server"":).*?(?=,)").Match(uploadItemInfo).ToString();
    185.             string hash = new Regex(@"(?<=""hash"":"").*?(?="")").Match(uploadItemInfo).ToString();
    186.             project.SendWarningToLog("Забираем данные для отправки фото:" +Environment.NewLine+
    187.                 "Фото id: "+photo_id +Environment.NewLine+
    188.                 "Сервер: "+server +Environment.NewLine+
    189.                 "Хэш: "+hash);
    190.  
    191.             //Сохраняем фото на стену
    192.             project.SendInfoToLog("Третий  этап - получаем адрес сервера для загрузки фото",true);
    193.             project.SendInfoToLog("Взяли для описания: " + strCaption);
    194.             //Формируем запрос для сохранения на стену
    195.             string PostRequestUrl = String.Format("https://api.vk.com/method/photos.saveWallPhoto?access_token={0}&group_id={1}&photo={2}&server={3}&hash={4}&caption={5}&v=5.69",
    196.                 strAccess_token,strGroupId,photo_id,server,hash,TextProcessing.UrlEncode(strCaption));
    197.  
    198.             string PostRequest =  ZennoPoster.HttpGet(PostRequestUrl);
    199.  
    200.             project.SendInfoToLog("photos.saveWallPhoto " + PostRequest);
    201.             //Забираем ссылку на запись на стену PostRequest
    202.             string PhotoToWall = new Regex(@"(?<=\{""response"":\[\{""id"":)[\w\W]*?(?=,"")").Match(PostRequest).ToString();
    203.             string Owner_id = new Regex(@"(?<=owner_id"":)[\w\W]*?(?=,)").Match(PostRequest).ToString();
    204.             project.SendInfoToLog("id фото для размещения на стене " + PostRequest);
    205.             project.SendInfoToLog("photos.saveWallPhoto " + PhotoToWall);
    206.  
    207.             string attach ="photo"+Owner_id+"_"+PhotoToWall;
    208.  
    209.             //Формируем запрос для постинга на стену
    210.             //Берем текст поста
    211.             string PostText = TextProcessing.UrlEncode(strCaption);
    212.             //Формируем запрос для размещения поста
    213.             string PostUrlWallGet = String.Format("https://api.vk.com/method/wall.post?"+
    214.                 "access_token={0}"+
    215.                 "&owner_id=-{1}"+
    216.                 "&friends_only=0"+
    217.                 "&from_group=1"+
    218.                 "&attachments={2}"+
    219.                 "&signed=0"+
    220.                 "&message={3}"+
    221.                 "&mark_as_ads=0"+
    222.                 "&v=5.69",
    223.                 strAccess_token,strGroupId,attach,PostText);
    224.             //Отправляем запрос
    225.             string PostId = ZennoPoster.HttpGet(PostUrlWallGet);
    226.             //Пауза 1 сек.
    227.             Thread.Sleep(1000);
    228.             //Забираем i поста из ответа PostId
    229.             string PostIdOnly = new Regex(@"(?<=""post_id"":).*?(?=}})").Match(PostId).ToString();
    230.  
    231.             //Перемещаем использованный файл в папку used
    232.             File.Move(lstListFotoFiles[0],project.Directory+"/foto used/"+FileName);
    233.             //======+++Тут процес постинга закончен
    234.             //Формируем ссылку на пост
    235.             string FinishPostUrlForCheck = String.Format(@"https://vk.com/club{0}?w=wall-{0}_{1}",strGroupId,PostIdOnly);
    236.             project.SendInfoToLog("Ссылка на пост: " + FinishPostUrlForCheck, true);
    237.         }
    238.         //Модифицированный постер
    239.         public static void ModApiVkPhotoPost()
    240.         {
    241.             //==Блок с переменными
    242.             Random rnd = new Random();
    243.             //*************** Файлы для отправки
    244.             //Создаем пустой список куда в последствии помести пути к файлам из папки strSourceDirectoryPath
    245.             List<string> lstListFotoFiles = new List<string>();
    246.             //Присваиваем переменной путь к папке с файлами
    247.             string strSourceDirectoryPath = project.Directory + @"\foto to upload\";
    248.             //Directory.EnumerateFiles: получаем список файлов jpg в папке strSourceDirectoryPath
    249.             lstListFotoFiles.AddRange(Directory.EnumerateFiles(strSourceDirectoryPath, "*.jpg", SearchOption.AllDirectories));
    250.    
    251.             string strVKLogin = String.Empty;
    252.             string strVKPass = String.Empty;
    253.             //Считаем id группы из файла
    254.             string strGroupId = String.Empty;
    255.             //Потом поднадобится
    256.             string strIdFoto = String.Empty;
    257.             //Считываем описание к фотографии
    258.             string strCaption = File.ReadAllText(project.Directory + @"\foto to upload\caption.txt");
    259.             //************** Считаем token группы из файла
    260.             string strAccess_token = String.Empty;
    261.             Acc.ModGetVkApiToken(out strVKLogin, out strVKPass, out strGroupId, out strAccess_token);//Блок получения токена перенесен в общий код
    262.             //*******************************************
    263.             //==Конец блока с переменными
    264.  
    265.             //Загрузка фото в ВК
    266.             //Запрос на получение адреса сервера для загрузки
    267.             project.SendInfoToLog("Первый этап - получаем адрес сервера для загрузки фото",true);
    268.             string strGetServerUrl = String.Format(@"https://api.vk.com/method/photos.getWallUploadServer?v=5.69&access_token={0}&group_id={1}",
    269.                 strAccess_token,strGroupId);
    270.             string strServerResult = ZennoPoster.HttpGet(strGetServerUrl);
    271.             //Забираем адрес из ответа
    272.             string strUploadServer = new Regex(@"(?<=""upload_url"":"")[\w\W]*?(?=\"",""album_id)").Match(strServerResult).ToString().Replace(@"\","");
    273.            //Если в ответе strServerResult имеет пустое значение, то удаляем токен и останавливаем шаблон
    274.            if(strUploadServer==String.Empty)
    275.            {
    276.                Acc.DeleteToken();
    277.                throw new Exception("Что-то не то с входным файлом. Останалвиваем шаблон. Проверьте логин, пароль и ид группы/n ПЕРЕЗАПУСТИТЕ ШАБЛОН");
    278.            }
    279.    
    280.            project.SendWarningToLog("Забираем сервер: "+strUploadServer);
    281.            //************** Формируем тело контент для загрузки на сервер
    282.            //Получение информации о файле для загрузки
    283.            FileInfo strFileInfo = new FileInfo(lstListFotoFiles[0]);
    284.            string FileName = strFileInfo.Name;
    285.            //==Формируем тело content для POST-запроса
    286.            string boundary = "------WebKitFormBoundary"+rnd.Next(100000000,999999999).ToString();
    287.            string post_data = "";
    288.            post_data += boundary + "\n";
    289.            post_data += string.Format("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\n", FileName);
    290.             post_data += "Content-Type: image/jpg\n";
    291.             post_data += lstListFotoFiles[0];
    292.             //============== Конец формирования тела content для POST-запроса
    293.  
    294.             project.SendInfoToLog("Второй этап - Грузим фото на сервер vk",true);
    295.             //Загружаем фото на сервер ВК
    296.             string uploadItemInfo = ZennoPoster.HttpPost(strUploadServer, post_data,
    297.                 "multipart/form-data",
    298.                 "",
    299.                 "utf-8",
    300.                 ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.BodyOnly,
    301.                 30000);
    302.             //Забираем из ответа id фото, server и hash
    303.             string photo_id = new Regex(@"(?<=""photo"":"").*?(?="","")").Match(uploadItemInfo).ToString().Replace(@"\","");
    304.             string server = new Regex(@"(?<=""server"":).*?(?=,)").Match(uploadItemInfo).ToString();
    305.             string hash = new Regex(@"(?<=""hash"":"").*?(?="")").Match(uploadItemInfo).ToString();
    306.             project.SendWarningToLog("Забираем данные для отправки фото:" +Environment.NewLine+
    307.                 "Фото id: "+photo_id +Environment.NewLine+
    308.                 "Сервер: "+server +Environment.NewLine+
    309.                 "Хэш: "+hash);
    310.  
    311.             //Сохраняем фото на стену
    312.             project.SendInfoToLog("Третий  этап - получаем адрес сервера для загрузки фото",true);
    313.             project.SendInfoToLog("Взяли для описания: " + strCaption);
    314.             //Формируем запрос для сохранения на стену
    315.             string PostRequestUrl = String.Format("https://api.vk.com/method/photos.saveWallPhoto?access_token={0}&group_id={1}&photo={2}&server={3}&hash={4}&caption={5}&v=5.69",
    316.                 strAccess_token,strGroupId,photo_id,server,hash,TextProcessing.UrlEncode(strCaption));
    317.  
    318.             string PostRequest =  ZennoPoster.HttpGet(PostRequestUrl);
    319.  
    320.             project.SendInfoToLog("photos.saveWallPhoto " + PostRequest);
    321.             //Забираем ссылку на запись на стену PostRequest
    322.             string PhotoToWall = new Regex(@"(?<=\{""response"":\[\{""id"":)[\w\W]*?(?=,"")").Match(PostRequest).ToString();
    323.             string Owner_id = new Regex(@"(?<=owner_id"":)[\w\W]*?(?=,)").Match(PostRequest).ToString();
    324.             project.SendInfoToLog("id фото для размещения на стене " + PostRequest);
    325.             project.SendInfoToLog("photos.saveWallPhoto " + PhotoToWall);
    326.  
    327.             string attach ="photo"+Owner_id+"_"+PhotoToWall;
    328.  
    329.             //Формируем запрос для постинга на стену
    330.             //Берем текст поста
    331.             string PostText = TextProcessing.UrlEncode(strCaption);
    332.             //Формируем запрос для размещения поста
    333.             string PostUrlWallGet = String.Format("https://api.vk.com/method/wall.post?"+
    334.                 "access_token={0}"+
    335.                 "&owner_id=-{1}"+
    336.                 "&friends_only=0"+
    337.                 "&from_group=1"+
    338.                 "&attachments={2}"+
    339.                 "&signed=0"+
    340.                 "&message={3}"+
    341.                 "&mark_as_ads=0"+
    342.                 "&v=5.69",
    343.                 strAccess_token,strGroupId,attach,PostText);
    344.             //Отправляем запрос
    345.             string PostId = ZennoPoster.HttpGet(PostUrlWallGet);
    346.             //Пауза 1 сек.
    347.             Thread.Sleep(1000);
    348.             //Забираем i поста из ответа PostId
    349.             string PostIdOnly = new Regex(@"(?<=""post_id"":).*?(?=}})").Match(PostId).ToString();
    350.  
    351.             //Перемещаем использованный файл в папку used
    352.             File.Move(lstListFotoFiles[0],project.Directory+"/foto used/"+FileName);
    353.             //======+++Тут процес постинга закончен
    354.             //Формируем ссылку на пост
    355.             string FinishPostUrlForCheck = String.Format(@"https://vk.com/club{0}?w=wall-{0}_{1}",strGroupId,PostIdOnly);
    356.             project.SendInfoToLog("Ссылка на пост: " + FinishPostUrlForCheck, true);
    357.         }
    358.  
    359.     }
    360. }
    361.  
    Вот так сниппет
    Code (Csharp):
    1. //Эти две строки обязательно прописать во всех сниппетах.
    2. Tech.project = project;
    3. Tech.instance = instance;
    4. //а эта строчка постит фото на стену группы
    5. Poster.ApiVkPhotoPost();
     

    Attached Files:

    Last edited: May 9, 2018
    Belias, LaGir, iBotovod and 6 others like this.
  3. Zymlex

    Zymlex Client

    Joined:
    Oct 24, 2016
    Messages:
    1,406
    Likes Received:
    715
    Code (Csharp):
    1. [CODE=Csharp]
     
    Advert31337 likes this.
  4. Advert31337

    Advert31337 Client

    Joined:
    Dec 18, 2016
    Messages:
    36
    Likes Received:
    27
    Круто, не знал о такой штуке. Спасибо.
     
  5. Astraport

    Astraport Client

    Joined:
    May 1, 2015
    Messages:
    2,750
    Likes Received:
    1,812
    А зачем?
     
  6. Advert31337

    Advert31337 Client

    Joined:
    Dec 18, 2016
    Messages:
    36
    Likes Received:
    27
    Ну если этот проект рассматривать как постер картинок, то смысла нет. Ту вы правы. А вот для большого проекта, где размещаются не только фото и со своими алгоритмами, общий код, на мой взгляд, более полезен.
    Но это сугубо мое мнение.
     
  7. Astraport

    Astraport Client

    Joined:
    May 1, 2015
    Messages:
    2,750
    Likes Received:
    1,812
    Для социалок, где постоянно что-то меняется и отваливается, важен удобный дебаг. Запихнуть весь код в общий и потом страдать?
    В больших проектах наоборот стараешься в кубиках C# не более 100 строк делать для удобства и разбивать их.
    В общий только часто используемые в неск. кубиках надежные утилиты ИМХО.
     
    iBotovod, zombie, SergSh and 2 others like this.
  8. Advert31337

    Advert31337 Client

    Joined:
    Dec 18, 2016
    Messages:
    36
    Likes Received:
    27
    Ну тут используется официальное API VK и тема не спамная. Соответственно изменения делаются очень редко.
    Что касается количества строк, тут вы абсолютно правы и это касается не только кубиков, но и методов в общем коде.
    Тут я нарочно пошел на нарушение этого правила, исключительно для демострации сути работы с объектами простым способом.

    В моем комбайне такие модули также не содержат более 100 строк кода.

    Про дебаг. Поскольку работа идет с апи, то можно использовать Visual Studio.
     
  9. inilim

    inilim Client

    Joined:
    Sep 16, 2017
    Messages:
    239
    Likes Received:
    68
    Не все поймут. zennoposter в сторонке.
     
  10. Advert31337

    Advert31337 Client

    Joined:
    Dec 18, 2016
    Messages:
    36
    Likes Received:
    27
    Почему вы так считаете?
     
  11. AZANIR

    AZANIR Client

    Joined:
    Jun 9, 2014
    Messages:
    260
    Likes Received:
    104
    в общий код есть смысл выносить то что повторяется часто, очень часто , а как познавательная статья очень даже неплохо.
     
    Advert31337 likes this.
  12. surrealmix

    surrealmix Client

    Joined:
    Mar 7, 2013
    Messages:
    706
    Likes Received:
    351
    Если шаблон предназначен для многопоточного выполнения, то так делать категорически нельзя.
     
    doc likes this.
  13. Advert31337

    Advert31337 Client

    Joined:
    Dec 18, 2016
    Messages:
    36
    Likes Received:
    27
    Спасибо, вы уловили самую суть)))

    В многопоток пока еще особо не вникал - не смогу прокомментировать. Данный шаблон выбрал исключительно для примера, на мой взгляд, достаточно простого и понятного.
    Опять же можно создать классы в которых нет надобности использовать project и instance.
     
  14. doc

    doc Client

    Joined:
    Mar 30, 2012
    Messages:
    6,908
    Likes Received:
    3,237
    Нужно использовать instance или project - просто пропиши эти переменные в методах и передавай туда эти объекты при вызове
     
    Advert31337 likes this.
  15. Zymlex

    Zymlex Client

    Joined:
    Oct 24, 2016
    Messages:
    1,406
    Likes Received:
    715
    Advert31337 likes this.
  16. nvmds

    nvmds Client

    Joined:
    May 4, 2016
    Messages:
    54
    Likes Received:
    3
    А сколько времени в итоге ушло? на кубиках такое накидать 10 мин макс
     
  17. Advert31337

    Advert31337 Client

    Joined:
    Dec 18, 2016
    Messages:
    36
    Likes Received:
    27
    Поскольку я изучаю C# с нуля, то долго.
    Разумеется я не предлагаю немедленно бросить кубики и бежать осваивать свой код)
    И все таки, для более сложных проектов комфортнее работать с кодом, а не с покрывалом из простых кубиков.
    А данный простой шаблон по функционалу предназначен для наглядного примера.
     
  18. radv

    radv Client

    Joined:
    May 11, 2015
    Messages:
    213
    Likes Received:
    114
    Я тоже с нуля изучаю, и пока без общего кода работал. Буду пробовать применять на примере.
     
  19. iBotovod

    iBotovod Client

    Joined:
    Jul 1, 2017
    Messages:
    52
    Likes Received:
    14
    Годно. Узнал несколько новых вещей для себя в работе с токенами и файлОм. Спасибо.
    PS: Сиборра рулез :-)
     
    Advert31337 likes this.
  20. Belias

    Belias Client

    Joined:
    Jun 25, 2013
    Messages:
    11
    Likes Received:
    6
    Отличная статья, для начинающих самое то.
     
    Advert31337 likes this.

Пользователи просматривающие тему (Пользователей: 0, Гостей: 0)