Jump to content

Featured Replies

Всем привет.

Я думаю, что уже многие слышали о новом REST API, который добавляется в IPS Community Suite с версии 4.1.6. Хотелось бы рассказать, что это за зверь, зачем его добавляют, что он позволит делать с вашим форумом. Статья будет в форме вопрос-ответ.

Почему IPS добавляют REST API?
Всё очень просто. Они работают над мобильными приложениями IPS Community Suite для Android и iPhone. Поэтому для этих целей в любом случае нужен API. Тогда если они его сделали, то почему бы не включить в стандартную комплектацию? Что они и сделали с версии 4.1.6.

Для чего нужен этот REST API?
До версии 4.1.6 взаимодействие каких-либо скриптом с IPS Community Suite могло быть только в том случае, если они находились на одном хостинге и этот скрипт имел доступ к файлу init.php вашего форума. Т.е. в начале PHP-скрипта добавлялась строка require 'init.php'; и после этого ваш скрипт мог использовать все возможности фреймворка IPS. Теперь же будет возможным взаимодействие любых приложений на любых языках программирования с IPS Community Suite. Например, станет возможным создание клиента вашего сайта для Windows 10 с последующим его размещением в Windows Store.

Что можно сделать с помощью этого API?

Приведу пример только для Системы. Для каждого приложения есть свои методы API.

  • /core/hello
    • /core/hello - предоставляет общую информацию о сайте (название, адрес, версию IPS)
  • /core/members
    • GETindex - предоставляет список пользователей
    • GETitem( $id ) - предоставляет информацию о конкретном пользователе
    • _createOrUpdate( $member ) - создаёт или обновляет пользователя
    • POSTindex() - создаёт пользователя
    • POSTitem( $id ) - изменяет пользователя
    • DELETEitem( $id ) - удаляет пользователя

Что по поводу мостов?
Не хочу утверждать то, чего не знаю. Но скорее всего да, вы сможете ещё проще связать два сайта на разных системах.

Пример работы с форумом №2 по API, используя IPS Framework сайта №1

<?php

require 'init.php'; // Подключаем IPS Framework сайта № 1

$url = "http://localhost/suite-git/"; // Адрес сайта № 2
$key = "41e9e7788416acade51c60febb105f16"; // Ключ API сайта № 2

/* Получаем информацию о сайте (метод "hello") */
var_dump(
	\IPS\Http\Url::external( $url . "api/core/hello" )->request()->login( $key, "" )->get()->decodeJson()
	);

/* Получаем информацию о пользователе на основе его ID */
var_dump(
	\IPS\Http\Url::external( $url . "api/core/members/1" )->request()->login( $key, "" )->get()->decodeJson()
	);

/* Получаем список тем (вопросов) с выбранными лучшими ответами в определённом разделе */
$filters = array(
	'hasBestAnswer'		=> 1, // Есть лучший ответ
	'forums'			=> '9', // ID раздела
);
print_r(
	\IPS\Http\Url::external( $url . "api/forums/topics" )->setQueryString( $filters )->request()->login( $key, "" )->get()->decodeJson()
	);

/* Создаём новое сообщение */
var_dump(
	\IPS\Http\Url::external( $url . "api/forums/posts" )->request()->login( $key, "" )->post(
		array(
			'topic'		=> 288, // ID темы
			'author'	=> 1, // ID автора
			'post'		=> '<p>Testing a new post</p>' // HTML-код сообщения
			)
		)->decodeJson()
	);

exit; // Завершаем скрипт

Edited by Sanshalay

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/
Share on other sites
  • 1 месяц спустя...

Зашел в REST API, создал ключ (к примеру bae56487dd06e3e8530243bfd793bd66) и дал доступ ко всем контрольным точкам.
Отсылаю GET запрос в строке:

www.МОЙ_ФОРУМ.ru/api/core/hello&key=bae56487dd06e3e8530243bfd793bd66

В ответ INVALID_API_KEY

Или я как то "не так" сформировал запрос???))
Может кто нибудь показать рабочий пример запроса?

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101240
Share on other sites
3 часа назад, tim21701 сказал:

Зашел в REST API, создал ключ (к примеру bae56487dd06e3e8530243bfd793bd66) и дал доступ ко всем контрольным точкам.
Отсылаю GET запрос в строке:


www.МОЙ_ФОРУМ.ru/api/core/hello&key=bae56487dd06e3e8530243bfd793bd66

В ответ INVALID_API_KEY

Или я как то "не так" сформировал запрос???))
Может кто нибудь показать рабочий пример запроса?

Не так.

Пример запроса был выше.

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101242
Share on other sites
Только что, IAF сказал:

Пример запроса был выше.

Ткните носом) ПОЖАЛУЙСТА))

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101244
Share on other sites
В 17.12.2015 в 16:25, Sanshalay сказал:

/* Получаем информацию о сайте (метод "hello") */ var_dump( \IPS\Http\Url::external( $url . "api/core/hello" )->request()->login( $key, "" )->get()->decodeJson() );

 

9 минут назад, tim21701 сказал:

Ткните носом) ПОЖАЛУЙСТА))

 

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101245
Share on other sites

Если вы про api/core/hello$key= то это вообще не REST API)) $ и & Две разные вещи... Или я опять что то "недопонял"???
Можете привести пример уже сформированной строкой?

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101246
Share on other sites
44 минут назад, tim21701 сказал:

Если вы про api/core/hello$key= то это вообще не REST API)) $ и & Две разные вещи... Или я опять что то "недопонял"???
Можете привести пример уже сформированной строкой?

Перечитайте код, обратите внимание на ...login($key, ''), поймите, что login - это HTTP-авторизация, поймите, что key не указывается в запросе ни коим образом.

Как-то так.

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101247
Share on other sites

В общем ясно. Вы тоже этого не знаете. Уже не один раз, задавал вопрос и так и не могу нигде получить на него ответ - НИКТО НЕ ЗНАЕТ. И что самое интересное, все приводят свои мысли или догадки, но ни один - не привел в пример реально работающую (сформированную) строку с GET запросом.

 :/

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101253
Share on other sites
14 минут назад, tim21701 сказал:

В общем ясно. Вы тоже этого не знаете. Уже не один раз, задавал вопрос и так и не могу нигде получить на него ответ - НИКТО НЕ ЗНАЕТ. И что самое интересное, все приводят свои мысли или догадки, но ни один - не привел в пример реально работающую (сформированную) строку с GET запросом.

 :/

Повторю ещё раз: Ключ в GET-запросе НЕ передаётся.

Ключ передаётся как логин HTTP-авторизации и никак иначе.

Про HTTP-авторизацию читайте в гугле.

Edited by IAF

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101254
Share on other sites
10 минут назад, tim21701 сказал:

так и не могу нигде получить на него ответ - НИКТО НЕ ЗНАЕТ

Вы какой-то свой особый "велосипед" пытаетесь изобрести? :D

3 минуты назад, tim21701 сказал:

ни один - не привел в пример реально работающую (сформированную) строку с GET запросом

Я не совсем понимаю, зачем вам строка с GET запросом, вы с API собираетесь работать забивая ручками запросы в адресной строке? Мне кажется API совсем не для этого. Да и потом одно дело запросить таким макаром HELO, и совсем другое - что-нибудь посерьезней.  JSON в ответах вы тоже ручками будете разбирать?

5 минут назад, tim21701 сказал:

все приводят свои мысли или догадки

Зачем мысли и догадки, в референсе по REST API все достаточно ясно написано.

<?php
	
	$communityUrl = 'http://www.МОЙ_ФОРУМ.ru/';
	$apiKey = 'bae56487dd06e3e8530243bfd793bd66';
		
	$curl = curl_init( $communityUrl . 'api/core/hello' );
	curl_setopt_array( $curl, array(
		CURLOPT_RETURNTRANSFER	=> TRUE,
		CURLOPT_HTTPAUTH	=> CURLAUTH_BASIC,
		CURLOPT_USERPWD		=> "{$apiKey}:"
	) );
	$response = curl_exec( $curl );

	echo $response;

Соответственно $response вернет вам правильный ответ от REST API

Большинство API (в том числе и IPS4 REST API) предназначены для взаимодействия с удаленными скриптами, а не с адресной строкой, если что. ;)

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101256
Share on other sites

Наверное я говорю на марсианском языке, что меня никто не понял?))
Ок, давайте "объясню" более развернуто.

Включаем API для продаваемых товаров:
Создаем в корне файл constants.php с таким содержимым

<?php
define('NEXUS_LKEY_API_DISABLE', FALSE);

Далее, переходим в Магазин и добавляем/редактируем товар, выбрав тип ключа:

Screenshot_4.png.c22da43b0a63634eefe3b4f

После этого, у нас есть 4 типа запроса для взаимодействия с этим ключом: activatecheckinfo и updateExtra.
К примеру, что бы получить информацию об использовании ключа, необходимо отправить GET запрос:

http://www.МОЙ_ФОРУМ.ru/applications/nexus/interface/licenses/?info&key=4FPY-NR5K-BWV5-MC9S-0T45

В ответ, мы получаем массив JSON в котором будет отображена вся "подноготная" данного ключа и обрабатываем всю информацию как хотим, не забывая при этом что кириллические имена и даты у нас в юникоде...
К примеру, выводим эту информацию в окне About нашей программы:

Screenshot_2.png.3ad8f3d5939d2a1caa408fc

А теперь внимание, вопрос:
Объясните мне, старому и прокуренному паскальщику (в чем) в IPS отличается API (для продаваемых файлов) от API - о котором говорится в первом сообщении данного поста?
MIXOH, приведите пример того - что Вы мне показали (пожалуйста, если не затруднит)... 
IAF как Вы собираетесь получить какую либо информацию, не передав ключ?)) Какая нахрен HTTP-авторизация, мы про JSON говорим или Вы вообще о чем???

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101259
Share on other sites
39 минут назад, tim21701 сказал:

Наверное я говорю на марсианском языке, что меня никто не понял?))

Вы просто говорите совершенно не о том. (насколько я вижу, вопрос из первого вашего поста, и попытка нам "тупым" разжевать, то о чем вы спрашивали из последнего поста, ничего общего между собой не имеют (ну кроме слова API пожалуй)

Меньше пафоса!

42 минут назад, tim21701 сказал:

(в чем) в IPS отличается API (для продаваемых файлов) от API - о котором говорится в первом сообщении данного поста?

Начнем с того, что API продаваемых файлов (точнее лицензий), это во-первых давнишняя штука, появившаяся задолго до REST API, во-вторых ей для работы совершенно не нужен API ключ, относящийся к REST API. Функционал у этого API слишком узок, для необходимости использования ключей, и отсутствия необходимости в HTTP авторизации. ИМХО в будущем его могут полностью убрать, переложив на плечи "новог" API.

То есть, вкратце, разница между этими двумя механизмами, фактически в функционале и предоставляемых возможностях. Если "старый" API-лицензий, работает исключительно с этими самыми лицензиями, то "новый" API предоставляет доступ практически ко всем функциям движка. 

48 минут назад, tim21701 сказал:

приведите пример того - что Вы мне показали (пожалуйста, если не затруднит)..

Вам это все сохранить в PHP файл (заменив URL и ключ на ваши), залить на хост и запустить этот файлик?

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101266
Share on other sites
В 17.12.2015 в 15:25, Sanshalay сказал:

До версии 4.1.6 взаимодействие каких-либо скриптом с IPS Community Suite могло быть только в том случае, если они находились на одном хостинге и этот скрипт имел доступ к файлу init.php вашего форума. Т.е. в начале PHP-скрипта добавлялась строка require 'init.php'; и после этого ваш скрипт мог использовать все возможности фреймворка IPS. Теперь же будет возможным взаимодействие любых приложений на любых языках программирования с IPS Community Suite. Например, станет возможным создание клиента вашего сайта для Windows 10 с последующим его размещением в Windows Store.

Собственно, цитата из первого поста, как нельзя лучше характеризует отличия ;)

Именно по такому принципу и работает API для продаваемых файлов. 

Я имею ввиду его работу через require_once '../../../../init.php

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101269
Share on other sites
3 минуты назад, MIXOH сказал:

Меньше пафоса!

Интересно, где именно вы увидели пафос??)) Или Вас задело то, что я (как вы выразились) "разжевал"? Так это - извините, давно пора было сделать. Ещё автору первого сообщения, а не тупо переводить с инглиша. Или этот форум существует для чего то другого?

6 минут назад, MIXOH сказал:

Начнем с того, что API продаваемых файлов...

Я в курсе)) И знаю что они друг друга не затрагивают... Но смысл у них - один, предоставить JSON ответ на запросы. Зачем Вы мне это только что "разжевали" - не пойму, наверное в отместку моему предыдущему "мануалу"?))

Никого не хотел обидеть)) Всем хорошего настроения... 
Засим прощаюсь, так как смысл данной дискуссии сводится сводится на нет - если начинают объяснять "принципы, механизмы и их назначения", когда изначально вопрос был поставлен прямо: "привести рабочий код сформированного запроса". 
 

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101272
Share on other sites
4 минуты назад, tim21701 сказал:

Или Вас задело то, что я (как вы выразились) "разжевал"?

С чего-бы......просто разжевали вы совсем не то о чем шла речь как в этой теме, так и в вашем первом вопросе.

5 минут назад, tim21701 сказал:

Я в курсе)) И знаю что они друг друга не затрагивают...

Тогда тем более непонятен ваш вопрос, о том, как способом взаимодействия с одним API пытаться общаться совершенно с другим API.

6 минут назад, tim21701 сказал:

Но смысл у них - один, предоставить JSON ответ на запросы

Пожалуй это все что у них общего, не находите? А еще они оба относятся к IPS и т.д., но в корне, принцип взаимодействия с движком совершенно разный.

8 минут назад, tim21701 сказал:

когда изначально вопрос был поставлен прямо: "привести рабочий код сформированного запроса".

Так Вам изначально на ваш вопрос также прямо указали, что 

11 часов назад, tim21701 сказал:

www.МОЙ_ФОРУМ.ru/api/core/hello&key=bae56487dd06e3e8530243bfd793bd66

Для REST API не подходит

1 минуту назад, tim21701 сказал:

привести рабочий код сформированного запроса

Я привел вам в одной из предыдущих цитат, полный код запроса helo. Вставьте в пхп файлик, и будет вам и сформированный запрос и ответ на него от API.

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101273
Share on other sites
В 15.02.2016 в 16:20, tim21701 сказал:

привести рабочий код сформированного запроса

Для начала уточните, на какой языке программирования вы хотите отправлять запрос?

Для PHP запрос выглядит так (без использования IPS4 Framework):

<?php

$communityUrl = 'http://localhost:8888/ips4/';
$apiKey = 'c7a349a1629f02cd2855a58d77646f6d';

$curl = curl_init( $communityUrl . 'api/core/hello' );
curl_setopt_array( $curl, array(
	CURLOPT_RETURNTRANSFER	=> TRUE,
	CURLOPT_HTTPAUTH	=> CURLAUTH_BASIC,
	CURLOPT_USERPWD		=> "{$apiKey}:"
) );
$response = curl_exec( $curl );

echo $response;

Для PHP, но с использованием IPS4 Framework:

<?php

require 'init.php';

$url = "http://localhost:8888/ips4/";
$key = "41e9e7788416acade51c60febb105f16";

var_dump( \IPS\Http\Url::external( $url . "api/core/hello" )->request()->login( $key, "" )->get()->decodeJson() );

 

Edited by Sanshalay

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101358
Share on other sites
В Monday, February 15, 2016 в 12:16, tim21701 сказал:

но ни один - не привел в пример реально работающую (сформированную) строку с GET запросом

Хватит тупить, вам же сказали что $apikey это не параметр GET запроса, а логин для HTTP Basic Authentification. В паскале может вы и прокурены, а с протоколами веб аутентификации вы явно не знакомы и слушать что вам говорят не хотите. 

https://en.wikipedia.org/wiki/Basic_access_authentication#Client_side

GET: /uri HTTP/1.1

Host: domain.ru

Authorization: Basic base64_string

где base64_string - пользователь:пароль в base64

 

В Monday, February 15, 2016 в 12:28, MIXOH сказал:

Большинство API (в том числе и IPS4 REST API) предназначены для взаимодействия с удаленными скриптами, а не с адресной строкой, если что.

API это интерфейс, а каким образом с ним взаимодействуют - методом GET, POST, HEAD, REQUEST URI не имеет никакого отношения. А в остальном все правильно.

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101423
Share on other sites
4 часа назад, soka сказал:

API это интерфейс, а каким образом с ним взаимодействуют - методом GET, POST, HEAD, REQUEST URI не имеет никакого отношения

Согласен, но во-первых не все из методов удобны для применения прямо вот так вот в адресной строке, во-вторых, я же написал, "большинство API". Понятное дело конечно даже простенький скрипт, возвращающий в ответ на запрос, строчку "Hello world!" тоже в какой-то степени можно считать API, тем не менее, когда речь заходит о предоставлении более-менее широкого интерфейса взаимодействия, никто конечно всерьез не рассчитывает на то что все это будет происходить прямо в адресной строке, не так ли. Не говоря уже о том, что определенное множество из этого "большинства" API в принципе изначально базируется на аутентификации в той или иной степени. ИМХО мы прекрасно понимаем смысл беседы, но этими уточнениями уходим от темы :D 

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101455
Share on other sites
4 часа назад, MIXOH сказал:

когда речь заходит о предоставлении более-менее широкого интерфейса взаимодействия, никто конечно всерьез не рассчитывает на то что все это будет происходить прямо в адресной строке, не так ли

Широкий интерфейс взаимодействия понятие относительное, можно отправить один параметр и получить несколько мегабайт данных, а можно отправить кучу данных и получить только результат о проведения операции. И не имеет значения каким образом была отправлена эта переменная, методом GET или другим способом - все зависит от конкретной задачи и архитектуры API. Параметры в адресной строке передаются методом GET, но метод GET не является адресной строкой. Это названия метода GET адресной строкой очень сильно режет "слух" и создает ощущение мягко говоря дилетантства. Сам REST по спецификации использует разные методы - GET для чтения, POST для сохранения, DELETE для удаления и тд, что наглядно можно увидеть в примере. 

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101488
Share on other sites
6 часов назад, soka сказал:

Это названия метода GET адресной строкой очень сильно режет "слух"

С чего вы взяли что я отождествляю какой-то конкретный метод с адресной строкой, где я такое написал? Я говорю о том, что зачастую, обмен данными с API предоставляющими более широкий или возможно, более защищенный функционал как правило организованы при помощи удаленного скрипта (-ов), Неважно каким методом. Просто потому что в скрипте удобней обрабатывать различного рода Encoded-данные, массивы и т.д.

Адресная строка (как средство передачи того или иного запроса), затрагивается мной только потому, что автор вопроса пытается таким образом взаимодействовать с обсуждаемым здесь REST API. При этом пытаясь утверждать как раз обратное, по-типу "раз API продаваемых файлов так работает, значит и REST API тоже, ведь цель у них одна и та-же".

 

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101492
Share on other sites
6 часов назад, MIXOH сказал:

С чего вы взяли что я отождествляю какой-то конкретный метод с адресной строкой, где я такое написал?

 

В Monday, February 15, 2016 в 12:28, MIXOH сказал:

Я не совсем понимаю, зачем вам строка с GET запросом, вы с API собираетесь работать забивая ручками запросы в адресной строке?

 

6 часов назад, MIXOH сказал:

Адресная строка (как средство передачи того или иного запроса), затрагивается мной только потому, что автор вопроса пытается таким образом взаимодействовать с обсуждаемым здесь REST API

Автор написал что он взаимодействует с API посредством GET запроса, каким образом он это делает - из адресной строки, через сокеты или из другого интерфейса это не важно, в данном случае с одинаковым успехом можно отправить запрос из браузера пройти аутентификации и благополучно получить ответ. Он все правильно делает, за исключением того, что apikey не является параметром гет запроса, а логином для бейсик аутентификации с которой, к сожалению, он либо никогда не встречался либо не понимает суть ее работы. Аналогия, сравнения, отождествления с адресной строкой когда речь идет о методе запроса здесь абсолютно не корректно, оно мне кажется не к месту. Мне, если потребуется, проще будет передать из адресной строки числовой идентификатор нежели городить г-скрипты для этого. Автор не работает с адресной строкой, он работает с гет запросам, а каким образом он это осуществляет для нас не имеет значения, если ему так проще и он конечно знает как правильно формировать запрос, пусть делает хоть и из адресной строки, главное что ошибка у него в другом. Надеюсь он все таки что-то из этого понял.

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101551
Share on other sites

В чем смысл вышесказанного применительно к обсуждаемому здесь API?

Ну хорошо, предположим что вместо скрипта в несколько строк, вы запхнете нужный GET в адресную строку (не совсем понятно правда что будет проще), ну получите вы hello, дальше то что? Смысл?

Следующим его вопросом будет, как сделать тоже самое, но применительно к остальным доступным методам API?

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101555
Share on other sites
19 минут назад, MIXOH сказал:

Ну хорошо, предположим что вместо скрипта в несколько строк, вы запхнете нужный GET в адресную строку (не совсем понятно правда что будет проще), ну получите вы hello, дальше то что?

Ваше непонимаение в том, что вы путаете гет с адресной строкой. Автор написал что он работает с гет запросом и привел в пример код на каком-то языке. Он указал конкретную проблему - не может пройти аутентификацию. Адресная строка это ваше предположение, потому что она у вас ассоциируется с гет запросом. Он не говорил из какого интерфейса выполняет запрос, да это и не имеет в данном случае столь важного значения, потому что проблема у него была в другом - он не знает механизм работы аутентификации, а для этого сначала нужно прочитать документацию по этому протоколу и понять как он работает, для бейсик авторизации самое удобное сделать из браузера посредством отладчика хттп заголовках.  В скрипте тоже придется запихнуть и выполнять тот же самый ГЕТ запрос.

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101558
Share on other sites
13 минут назад, soka сказал:

Ваше непонимаение в том, что вы путаете гет с адресной строкой

Я прекрасно понимаю о чем вы :)

 

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=101560
Share on other sites
  • 1 year later...

поспорили, молодцы))) Теперь скажите, реально ли реализовать связку IPS и DLE с помощью этой штуки?

Link to comment
https://ipbmafia.ru/topic/13121-novyj-rest-api/?&do=findComment&comment=125284
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.


Guest
Ответить в этой теме...

Последние посетители 0

  • No registered users viewing this page.