- Регистрация
- 18.12.2016
- Сообщения
- 53
- Реакции
- 38
- Баллы
- 18
Приветствую всех коллег по цеху!
Начну с благодарностей, спасибо @sibbora с его шикарными материалами из академии и @LaGir aka
@Klask с его разъяснениями и мини-обзорами!!!
Коротко о себе.
Новичок в теме ZennoPoster, как программист в баллах 0.1/100, работаю специалистом по интернет-рекламе на заводе))).
Для себя решил изучать работу в коде сразу, минуя кубики.
Тема заработка не стояла для меня приоритетом, а вот проблема экономии времени очень острая. И, соответственно, я решая эти проблемы и изучал C#.
Одна из проблем – это размещение картинок, видео и гифок на стену и альбомы в ВК. Стандартные сервисы меня не устраивали, так как надо было сидеть и вбивать посты и время для размещения, а мне надо, чтобы программа сама брала файл из папки, описание и текст поста из файла.
В этой статье будет простой шаблон для размещения фотографий на стену группы ВК.
В качестве инструментов мы берем:
1. Руки (какие есть те и берем)
2. Документацию API ВК -- https://vk.com/dev/photos
3. Библиотеку NewtonSoft.dll
4. C#
5. Зенку
Начинаем планировать.
Продумываем файловую систему и структуру кода
С файлами я решил сделать так.
И в папке "foto to upload" разместил файл с описанием к фото и его же использую для текста поста:
Для удобства организации пространства я использую такое расположение окон:
Как хочется чтобы в 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 и прописываем юзинги:
С переменными все должно быть просто. (Решил не использовать переменные уровня проекта)
Авторизацию я решил делать через официальное приложение вк для андроид.
Разумеется, если токен у нас заполнен и он рабочий, то авторизация не поднадобится
А теперь начинаем процедуру постинга:
Нам нужно получить адрес сервера куда будем грузить фото:
Сформировать запрос для загрузки на сервер:
В ответе мы забираем с помощью регулярок id фотографии, сервер и хэш.
И делаем запрос для сохранения фото:
Постим сохраненное фото на стену нашей группы:
Перемещаем отработанный файл в папку foto used:
А теперь смотрим, как это можно преобразовать в общий код, не будем усложнять, просто разобьем на две части: модуль авторизации и модуль для постинга. Разумеется можно разделить на более мелкие функции, но поскольку цель статьи просто понять что есть «общий код» lтак:
Для начала создадим свое пространство имен SocialBot (Можно писать и в ZennoLab.OwnCode)
Прописываем в юзингах и в общем коде
Продумаем структуру кода, я решил что надо сделать 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,
access_token – это строка, а значит нам надо этот модуль завернуть в конструкцию
public static string{}
, что и говорит о том что модуль=метод=функция возвращает нам строковое значение.
Как используем?
string strAccess_token = Acc.GetVkApiToken();
То есть мы создали метод, который прочтет файл и если не найдет там токен, то создаст его, запишет в файл и вернет в качестве строкового значения для переменной strAccess_token.
Модуль постинга не должен что-либо возвращать поэтому мы оборачиваем его в конструкцию
public static void ApiVkPhotoPost() – это просто процедура.
Теперь в сниппете прописываем код.
Некоторые внимательные читатели заметили, что я в обоих методах GetVkApiToken() и ApiVkPhotoPost() обращаюсь к входному файлу и это не есть хорошо. Как это исправить?
Ведь метод может вернуть только одну переменную!
Мы используем ключевое слово out
И прописываем в коде вот так:
И вызываем его:
Таким образом мы обращаемся к входному файлу только из метода ModGetVkApiToken.
А в процедуре ModApiVkPhotoPost() заранее создал пустые переменные которые будут наполнены после строки
Ну вот вроде все.
Начну с благодарностей, спасибо @sibbora с его шикарными материалами из академии и @LaGir aka
@Klask с его разъяснениями и мини-обзорами!!!
Коротко о себе.
Новичок в теме ZennoPoster, как программист в баллах 0.1/100, работаю специалистом по интернет-рекламе на заводе))).
Для себя решил изучать работу в коде сразу, минуя кубики.
Тема заработка не стояла для меня приоритетом, а вот проблема экономии времени очень острая. И, соответственно, я решая эти проблемы и изучал C#.
Одна из проблем – это размещение картинок, видео и гифок на стену и альбомы в ВК. Стандартные сервисы меня не устраивали, так как надо было сидеть и вбивать посты и время для размещения, а мне надо, чтобы программа сама брала файл из папки, описание и текст поста из файла.
В этой статье будет простой шаблон для размещения фотографий на стену группы ВК.
В качестве инструментов мы берем:
1. Руки (какие есть те и берем)
2. Документацию API ВК -- https://vk.com/dev/photos
3. Библиотеку NewtonSoft.dll
4. C#
5. Зенку
Начинаем планировать.
Продумываем файловую систему и структуру кода
С файлами я решил сделать так.
Для удобства организации пространства я использую такое расположение окон:
Как хочется чтобы в 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 и прописываем юзинги:
С переменными все должно быть просто. (Решил не использовать переменные уровня проекта)
C#:
//==Блок с переменными
Random rnd = new Random();
//Создаем пустой список куда в последствии помести пути к файлам из папки strSourceDirectoryPath
List<string> lstListFotoFiles = new List<string>();
//Присваиваем переменной путь к папке с файлами
string strSourceDirectoryPath = project.Directory + @"\foto to upload\";
//Directory.EnumerateFiles: получаем список файлов jpg в папке strSourceDirectoryPath
lstListFotoFiles.AddRange(Directory.EnumerateFiles(strSourceDirectoryPath, "*.jpg", SearchOption.AllDirectories));
//Берем логин и пароль из списка
//Считываем содержимое файла vkInput.txt
string strVkInput = File.ReadAllText(project.Directory + @"/vkInput.txt");
/*
Во входном файле у нас указанны данные в таком виде:
Log:Pass|GroupId|token
Используя разделитель '|' разбиваем текст на части в массив, затем первый элемент:
Log:Pass
тоже делим на части разделителем ':'.
и берем первый (нулевой) элемент массива Log.Так получаем логин.
Массивы и списки индексируются или как еще говорять нумеруются с нуля!!!!
*/
string strVKLogin = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[0];
/*
Во входном файле у нас указанны данные в таком виде:
Log:Pass|GroupId|token
Используя разделитель '|' разбиваем текст на части в массив, затем первый элемент:
Log:Pass
тоже делим на части разделителем ':'.
и берем второй (первый) элемент массива Pass. Так получаем пароль.
*/
string strVKPass = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[1];
string strIdFoto = String.Empty;
//Берем текст из файла caption.txt, это будет описанием к фото и текстом поста
string strCaption = File.ReadAllText(project.Directory + @"\foto to upload\caption.txt");
/*
Во входном файле у нас указанны данные в таком виде:
Log:Pass|GroupId|token
Используя разделитель '|' разбиваем текст на части в массив, затем второй элемент [1] и используем его как id группы вк GroupId.
*/
string strGroupId = strVkInput.Split('|').ToArray()[1];
/*
Во входном файле у нас указанны данные в таком виде:
Log:Pass|GroupId|token
Используя разделитель '|' разбиваем текст на части в массив, затем третий элемент [2] и используем его как токен вк token.
*/
string strAccess_token = strVkInput.Split('|').ToArray()[2];
//==Конец блока с переменными
Авторизацию я решил делать через официальное приложение вк для андроид.
C#:
//==Модуль авторизации и получения нового токена
if(strAccess_token.Contains("token")){
strAccess_token = "";
//Авторизация апи
string strOauthVk = String.Format("https://oauth.vk.com/token?grant_type=password"
+"&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH&username={0}&password={1}",strVKLogin,strVKPass);
string VkResp = ZennoPoster.HttpGet(strOauthVk);
JObject jsonVk = JObject.Parse(VkResp);
strAccess_token = jsonVk.SelectToken("access_token").ToString();
//Записываем обновленные входные данные с токеном в файл в туже строку
string inputData = strVkInput.Replace("token", strAccess_token);
File.WriteAllText(project.Directory + @"/vkInput.txt",inputData);
project.SendInfoToLog("Взяли новый токен: " + strAccess_token +"\n Он сохранен в файл vkInput.txt", true);
}else{
project.SendInfoToLog("Берем токен из файла");
}
//==Конец Модуля авторизации и получения нового токена
Разумеется, если токен у нас заполнен и он рабочий, то авторизация не поднадобится
А теперь начинаем процедуру постинга:
Нам нужно получить адрес сервера куда будем грузить фото:
C#:
//Формируем запрос на получение адреса сервера для загрузки и записываем его в переменную strGetServerUrl
string strGetServerUrl = String.Format(@"https://api.vk.com/method/photos.getWallUploadServer?v=5.69&access_token={0}&group_id={1}",
strAccess_token,strGroupId);
//Делаем запрос ZennoPoster.HttpGet и записываем его в переменную strServerResult
string strServerResult = ZennoPoster.HttpGet(strGetServerUrl);
//Забираем адрес из ответа strServerResult с помощью регулярок
string strUploadServer = new Regex(@"(?<=""upload_url"":"")[\w\W]*?(?=\"",""album_id)").Match(strServerResult).ToString().Replace(@"\","");
//Примитивная проверка. Если strUploadServer имеет пустое значение, то подставляем во входном файле слово "token" и останавливаем шаблон
if(strUploadServer==String.Empty){
//поправляем шаблон под корректный вид
File.WriteAllText(project.Directory + @"/vkInput.txt",String.Format(@"{0}:{1}|{2}|token",strVKLogin,strVKPass,strGroupId));
throw new Exception("Что-то не то с входным файлом. Останалвиваем шаблон. Проверьте логин, пароль и ид группы/n ПЕРЕЗАПУСТИТЕ ШАБЛОН");
}
project.SendWarningToLog("Забираем сервер: "+strUploadServer);
Сформировать запрос для загрузки на сервер:
C#:
//Формируем тело контент для загрузки на сервер
//Получение информации о файле для загрузки
FileInfo strFileInfo = new FileInfo(lstListFotoFiles[0]);
string FileName = strFileInfo.Name;
//==Формируем тело content для POST-запроса
string boundary = "------WebKitFormBoundary"+rnd.Next(100000000,999999999).ToString();
string post_data = "";
post_data += boundary + "\n";
post_data += string.Format("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\n", FileName);
post_data += "Content-Type: image/jpg\n";
post_data += lstListFotoFiles[0];
//==Конец формирования тела content для POST-запроса
//Загружаем фото на сервер ВК
project.SendInfoToLog("Второй этап - Грузим фото на сервер vk",true);
string uploadItemInfo = ZennoPoster.HttpPost(strUploadServer, post_data,
"multipart/form-data",
"",
"utf-8",
ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.BodyOnly,
30000);
//Забираем из ответа id фото, server и hash
string photo_id = new Regex(@"(?<=""photo"":"").*?(?="","")").Match(uploadItemInfo).ToString().Replace(@"\","");
string server = new Regex(@"(?<=""server"":).*?(?=,)").Match(uploadItemInfo).ToString();
string hash = new Regex(@"(?<=""hash"":"").*?(?="")").Match(uploadItemInfo).ToString();
project.SendWarningToLog("Забираем данные для отправки фото:" +Environment.NewLine+
"Фото id: "+photo_id +Environment.NewLine+
"Сервер: "+server +Environment.NewLine+
"Хэш: "+hash);
В ответе мы забираем с помощью регулярок id фотографии, сервер и хэш.
И делаем запрос для сохранения фото:
C#:
//Сохраняем фото на стену
project.SendInfoToLog("Третий этап - получаем адрес сервера для загрузки фото",true);
project.SendInfoToLog("Взяли для описания: " + strCaption);
//Формируем запрос для сохранения на стену
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",
strAccess_token,strGroupId,photo_id,server,hash,TextProcessing.UrlEncode(strCaption));
string PostRequest = ZennoPoster.HttpGet(PostRequestUrl);
project.SendInfoToLog("photos.saveWallPhoto " + PostRequest);
//Забираем ссылку на запись на стену PostRequest
string PhotoToWall = new Regex(@"(?<=\{""response"":\[\{""id"":)[\w\W]*?(?=,"")").Match(PostRequest).ToString();
string Owner_id = new Regex(@"(?<=owner_id"":)[\w\W]*?(?=,)").Match(PostRequest).ToString();
project.SendInfoToLog("id фото для размещения на стене " + PostRequest);
project.SendInfoToLog("photos.saveWallPhoto " + PhotoToWall);
string attach ="photo"+Owner_id+"_"+PhotoToWall;
Постим сохраненное фото на стену нашей группы:
C#:
string PostText = TextProcessing.UrlEncode(strCaption);
//Формируем запрос для размещения поста
string PostUrlWallGet = String.Format("https://api.vk.com/method/wall.post?"+
"access_token={0}"+
"&owner_id=-{1}"+
"&friends_only=0"+
"&from_group=1"+
"&attachments={2}"+
"&signed=0"+
"&message={3}"+
"&mark_as_ads=0"+
"&v=5.69",
strAccess_token,strGroupId,attach,PostText);
//Отправляем запрос
string PostId = ZennoPoster.HttpGet(PostUrlWallGet);
//Пауза 1 сек.
Thread.Sleep(1000);
//Забираем i поста из ответа PostId
string PostIdOnly = new Regex(@"(?<=""post_id"":).*?(?=}})").Match(PostId).ToString();
Перемещаем отработанный файл в папку foto used:
C#:
//Перемещаем использованный файл в папку used
File.Move(lstListFotoFiles[0],project.Directory+"/foto used/"+FileName);
//======+++Тут процес постинга закончен
//Формируем ссылку на пост
string FinishPostUrlForCheck = String.Format(@"https://vk.com/club{0}?w=wall-{0}_{1}",strGroupId,PostIdOnly);
project.SendInfoToLog("Ссылка на пост: " + FinishPostUrlForCheck, true);
А теперь смотрим, как это можно преобразовать в общий код, не будем усложнять, просто разобьем на две части: модуль авторизации и модуль для постинга. Разумеется можно разделить на более мелкие функции, но поскольку цель статьи просто понять что есть «общий код» lтак:
Для начала создадим свое пространство имен SocialBot (Можно писать и в ZennoLab.OwnCode)
Прописываем в юзингах и в общем коде
- В первом я храню процедуры и функции чисто технического характера
- Во втором авторизация и операция с токеном
- В третьем процедура размещения фото на стену
При работе с общим кодом есть также нюанс – это объекты 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,
access_token – это строка, а значит нам надо этот модуль завернуть в конструкцию
public static string{}
, что и говорит о том что модуль=метод=функция возвращает нам строковое значение.
Как используем?
string strAccess_token = Acc.GetVkApiToken();
То есть мы создали метод, который прочтет файл и если не найдет там токен, то создаст его, запишет в файл и вернет в качестве строкового значения для переменной strAccess_token.
Модуль постинга не должен что-либо возвращать поэтому мы оборачиваем его в конструкцию
public static void ApiVkPhotoPost() – это просто процедура.
Теперь в сниппете прописываем код.
Некоторые внимательные читатели заметили, что я в обоих методах GetVkApiToken() и ApiVkPhotoPost() обращаюсь к входному файлу и это не есть хорошо. Как это исправить?
Ведь метод может вернуть только одну переменную!
Мы используем ключевое слово out
И прописываем в коде вот так:
C#:
//Модифицированный метод получения токена, логина, пароля и прочих входных данных
public static void ModGetVkApiToken(out string strVKLogin, out string strVKPass, out string strGroupId, out string strAccess_token)
{
string strVkInput = File.ReadAllLines(project.Directory + @"/vkInput.txt").ToArray()[0];
strVKLogin = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[0];
strVKPass = strVkInput.Split('|').ToArray()[0].Split(':').ToArray()[1];
//Считаем id группы из файла
strGroupId = strVkInput.Split('|').ToArray()[1];
//Считаем token группы из файла
strAccess_token = strVkInput.Split('|').ToArray()[2];
if(!strAccess_token.Contains("token"))
{
project.SendInfoToLog("Взяли токен: " + strAccess_token, true);
}else{
strAccess_token = "";
//Авторизация апи
string strOauthVk = String.Format("https://oauth.vk.com/token?grant_type=password"
+"&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH&username={0}&password={1}",strVKLogin,strVKPass);
string VkResp = ZennoPoster.HttpGet(strOauthVk);
JObject jsonVk = JObject.Parse(VkResp);
strAccess_token = jsonVk.SelectToken("access_token").ToString();
//Записываем обновленные входные данные с токеном в файл в туже строку
string inputData = strVkInput.Replace("token", strAccess_token);
File.WriteAllText(project.Directory + @"/vkInput.txt",inputData);
project.SendInfoToLog("Взяли новый токен: " + strAccess_token +"\n Он сохранен в файл vkInput.txt", true);
}
}
И вызываем его:
C#:
string strVKLogin = String.Empty;
string strVKPass = String.Empty;
//Считаем id группы из файла
string strGroupId = String.Empty;
//Потом поднадобится
string strIdFoto = String.Empty;
//Считываем описание к фотографии
string strCaption = File.ReadAllText(project.Directory + @"\foto to upload\caption.txt");
//************** Считаем token группы из файла
string strAccess_token = String.Empty;
Acc.ModGetVkApiToken(out strVKLogin, out strVKPass, out strGroupId, out strAccess_token);//Блок получения токена перенесен в общий код
Таким образом мы обращаемся к входному файлу только из метода ModGetVkApiToken.
А в процедуре ModApiVkPhotoPost() заранее создал пустые переменные которые будут наполнены после строки
C#:
Acc.ModGetVkApiToken(out strVKLogin, out strVKPass, out strGroupId, out strAccess_token);
Ну вот вроде все.
- Номер конкурса статей
- Девятый конкурс статей
- Тема статьи
- Соц. сети
Последнее редактирование:




