Это вторая часть нашего учебника по API Списка Твиттера в нашей расширенной серии Twitter API . В этом уроке мы рассмотрим создание функций List с помощью API. Примеры кода представлены в репозитории Github. Инструкции по установке описаны здесь более подробно (обязательно используйте репозиторий, представленный в этом руководстве, а не исходный репозиторий Birdcage, указанный на этой странице).
Обзор API Списка Твиттера
Опять же, существует около 19 API для списков Twitter , разделенных на три основные области:
Давайте начнем с интеграции некоторых основных функций разработки List API.
Создание списка
Когда вы загрузите Birdcage, вы увидите страницу управления списками . Выберите опцию « Создать список» в правом боковом меню.
Откроется форма Создать список . Я собираюсь создать список для отслеживания журналистов Сиэтла в Twitter:
Вот код создания в TwitterlistController.php
. Он обрабатывает код для отображения формы и после публикации формы код для обработки:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
public function actionCreate()
{
$model=new TwitterList;
$this->performAjaxValidation($model);
if(!isset($_POST[‘TwitterList’])) {
// initial load
// load the current selected account as a default
$model->account_id = Yii::app()->session[‘account_id’];
// display form
$this->render(‘create’,array(
‘model’=>$model,
));
} else {
// POSTed — process form
$model->attributes=$_POST[‘TwitterList’];
// load the account selected
$account = Account::model()->findByPK($model->account_id);
// connect to twitter
$twitter = Yii::app()->twitter->getTwitterTokened($account[‘oauth_token’], $account[‘oauth_token_secret’]);
// create remotely at Twitter
$new_list= $twitter->post(«lists/create»,array(‘name’=>$model->name,’description’=>$model->description,’mode’=>$model->getModeString($model->mode)));
if (TwitterList::model()->isError($new_list)) {
// to do — set flash error
var_dump($new_list);
yexit();
} else {
$model->owner_id =$account->twitter_id;
$model->list_id =$new_list->id_str;
$model->slug=$new_list->slug;
$model->full_name=$new_list->full_name;
$model->created_at = date( ‘Ymd H:i:s’, strtotime($new_list->created_at) );
$model->modified_at =new CDbExpression(‘NOW()’);
if($model->save())
$this->redirect(array(‘admin’));
}
}
}
|
Вы можете прочитать документацию по Twitter Lists / Create API здесь .
После отправки формы вы увидите что-то вроде этого:
Импорт членов в список
Одно из самых неприятных ограничений пользовательского интерфейса в Твиттере — насколько сложно добавлять участников. Вы должны посетить каждого участника и добавить их индивидуально в свои списки — процесс очень запутанный и медленный.
Мы собираемся реализовать функцию подписки через разделенный запятыми список учетных записей Twitter.
В представлении списка, если вы нажмете на значок « Управление списком» справа от « Сиэтлских журналистов» , вы увидите страницу « Просмотр списка» :
Нажмите на Импортировать участников в правом меню. Затем введите список учетных записей Twitter, которые вы хотите добавить в этот список:
Давайте рассмотрим код, который загружает участников в Twitter. Код для отображения формы выше начинается в ListMemberController.php
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/**
* Import members to a list
*/
public function actionImport($id)
{
$model = new Import();
$model->list_id = $id;
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if(isset($_POST[‘Import’]))
{
if($model->save()) {
$result = ListMember::model()->import($id,$_POST[‘Import’][‘member_list’]);
Yii::app()->user->setFlash(‘import_success’,’Thank you! Your members have been added.’);
$this->redirect(array(‘/twitterlist/view’,’id’=>$id));
} // end if save
// end if post
} else {
$this->render(‘import’,array(
‘model’=>$model,’list_id’=>$id,
));
}
}
|
В модели ListMember.php
код импорта выглядит следующим образом. Мы используем preg_split
для преобразования списка учетных записей в массив. Затем для каждой учетной записи мы извлекаем информацию об учетной записи в Users / Show и публикуем идентификатор Twitter в Списке участников .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public function import($id,$import_list) {
// retrieve account
$tl = TwitterList::model()->findByAttributes(array(‘id’=>$id));
$list_id = $tl[‘list_id’];
$account = Account::model()->findByPk($tl->account_id);
// retrieve members and add to list
$twitter = Yii::app()->twitter->getTwitterTokened($account[‘oauth_token’], $account[‘oauth_token_secret’]);
// convert post rows to array
$add_list = preg_split («(\r|\n|,)», $import_list, -1, PREG_SPLIT_NO_EMPTY);
$max_count = 0;
foreach ($add_list as $item) {
$item = trim($item);
$user_info= $twitter->get(«users/show»,array(‘screen_name’=>$item));
if (ErrorLog::model()->isError(‘getUserInfo’, $account[‘id’], $user_info)) {
continue;
}
if (ErrorLog::model()->isRateLimited($user_info)) {
continue;
}
// add remotely to list
$people= $twitter->post(«lists/members/create»,array(‘list_id’=>$list_id,’screen_name’=>$item));
// add locally to db
$this->remote_add($list_id,$user_info->id_str,$item);
$max_count+=1;
if ($max_count>=99) break;
}
}
public function remote_add($list_id,$member_id,$screen_name = ‘tbd’) {
TwitterUser::model()->setPlaceholder($member_id,$screen_name);
$lm = ListMember::model()->findByAttributes(array(‘list_id’=>$list_id,’member_id’=>$member_id));
if (empty($lm)) {
$lm = new ListMember;
$lm->list_id=$list_id;
$lm->member_id=$member_id;
$lm->save();
}
}
|
После отправки участников вы увидите что-то вроде этого:
tbd
представляет пользователя, которого еще нет в нашей базе данных; информация профиля будет извлечена (гидратирована) в фоновом режиме позже.
В Твиттере вы увидите что-то вроде этого:
Синхронизация списков
Теперь, когда мы создали список, давайте извлечем списки, которые уже существуют в нашей учетной записи, чтобы мы могли управлять ими из нашей консоли. Снова в меню « Управление списками» нажмите « Синхронизировать списки» .
Действие синхронизации закодировано в TwitterlistController.php
:
1
2
3
4
5
|
public function actionSync()
{
TwitterList::model()->sync();
$this->redirect(array(‘admin’));
}
|
TwitterList.php
синхронизации модели TwitterList.php
является относительно сложной, как показано ниже. Во-первых, модель синхронизации проходит по всем настроенным вами учетным записям и вызывает syncOne
запись syncOne
для получения списков.
SyncOne вызывает выборку списков / владельцев в API, чтобы найти все списки, принадлежащие каждой учетной записи.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public function sync() {
$users = User::model()->findAll();
foreach ($users as $user) {
$user_id = $user[‘id’];
$accounts = Account::model()->findAllByAttributes(array(‘user_id’=>$user_id));
// loop through Twitter accounts (may be multiple)
foreach ($accounts as $account) {
$this->syncOne($account[‘id’]);
} // end account loop
} // end user loop
}
public function syncOne($account_id) {
$account=Account::model()->findByPk($account_id);
$twitter = Yii::app()->twitter->getTwitterTokened($account[‘oauth_token’], $account[‘oauth_token_secret’]);
// fetch lists owned by this account
$twitter_lists= $twitter->get(«lists/ownerships»,array(‘count’=>100,’cursor’=>-1));
//print_r($twitter_lists);
if (count($twitter_lists->lists)==0) return;
foreach ($twitter_lists->lists as $tl) {
//echo $tl->id_str.’
$this->remote_add($account_id,$tl);
// spawn action to get list members
$this->addMembershipAction($account_id,$tl->id_str);
} // end loop of lists
}
|
Однако вместо того, чтобы пытаться извлекать участников для списка в режиме реального времени, что, вероятно, приведет к истечению времени ожидания, он создает фоновое действие для извлечения членов для данного списка.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
public function addMembershipAction($account_id,$item_id) {
// adds a background task action to retrieve memberships for a list id
$check_dup = Action::model()->findByAttributes(array(‘account_id’=>$account_id,’action’=>Action::ACTION_MEMBERSHIPS,’status’=>Action::STATUS_ACTIVE,’item_id’=>$item_id));
if (empty($check_dup)) {
$a = new Action();
$a->account_id = $account_id;
$a->action = Action::ACTION_MEMBERSHIPS;
$a->item_id = $item_id;
$a->last_tweet_id = 0;
$a->status = Action::STATUS_ACTIVE;
$a->created_at =new CDbExpression(‘NOW()’);
$a->modified_at =new CDbExpression(‘NOW()’);
$a->save();
}
}
|
Фоновая задача cron вызывает модель Action.php
которая вызывает getListMembership
для одного списка за раз.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
public function getListMembership($action,$limit = 50) {
// collect next $limit members of list
$account = Account::model()->findByPk($action->account_id);
// last_tweet_id is the cursor
$cursor = $action->last_tweet_id;
if ($cursor ==0 ) $cursor =-1;
$result = TwitterList::model()->getMemberships($account, $action->item_id, $cursor , $limit);
$a = Action::model()->findByPk($action->id);
if ($result->rateLimit) {
return false;
} else if ($result->complete) {
$a->status=self::STATUS_COMPLETE;
$a->save();
} else {
// set lowest cursor
$a->last_tweet_id = $result->cursor;
$a->save();
}
}
|
Когда задача выполняется, она вызывает метод TwitterList.php
модели getMemberships
. Этот метод использует курсоры для пролистывания записей участников без истечения времени ожидания или ограничения скорости. Последний курсор хранится в таблице действий, так что следующий фоновый вызов может продолжить добавление элементов, где он был остановлен ранее.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
public function getMemberships($account,$list_id, $cursor =-1,$limit = 200) {
echo ‘entering getMemberships: account_id:’.$account[‘id’].’
$result = new StdClass;
$result->cursor = -1;
$result->count =0;
$result->error =false;
$result->complete = false;
$result->rateLimit = false;
$count_people = 0;
// retrieve members and add to list
$twitter = Yii::app()->twitter->getTwitterTokened($account[‘oauth_token’], $account[‘oauth_token_secret’]);
echo ‘here’.$cursor;lb();
while ($cursor <>0 ) {
echo ‘inside’;lb();
$people= $twitter->get(«lists/members»,array(‘list_id’=>$list_id,’cursor’=>$cursor,’skip_status’=>true,’include_entities’=>false));
if (ErrorLog::model()->isError(‘getMemberships’, $account[‘id’], $people)) {
$result->error =false;
return $result;
}
if (ErrorLog::model()->isRateLimited($people)) {
$result->rateLimit = true;
return $result;
}
if (isset($people->next_cursor))
$cursor = $people->next_cursor;
else
$cursor = 0;
$result->cursor = $cursor;
$count_people+=count($people->users);
echo ‘Count people: ‘.count($people->users);lb();
foreach ($people->users as $u) {
//var_dump($u);lb();
echo ‘Member:’.$u->screen_name;lb();
if (isset($u->screen_name))
$screen_name = $u->screen_name;
else
$screen_name = ‘tbd’;
ListMember::model()->remote_add($list_id,$u->id_str,$screen_name);
}
if (count($people->users)==0 or $cursor==0) {
$result->complete = true;
return $result;
}
} // end while loop
echo ‘exiting getMemberships’;lb();
return $result;
}
|
Вы должны увидеть что-то вроде этого, когда операция завершится:
После завершения фоновых задач вы увидите участников для каждого списка, например:
Что дальше?
Надеюсь, вам понравилась эта серия API Twitter List. Я хотел бы услышать ваши предложения по поводу любимых сценариев API и запросов функций; пожалуйста, оставьте их в комментариях.
Если у вас есть какие-либо вопросы или предложения, пожалуйста, оставьте их в комментариях. Если вы хотите следить за моими будущими уроками Tuts + и другими сериями, пожалуйста, посетите мою страницу инструктора или следуйте @reifman .