1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of GitterBot package. |
5
|
|
|
* |
6
|
|
|
* @author Serafim <[email protected]> |
7
|
|
|
* @date 24.09.2015 15:27 |
8
|
|
|
* |
9
|
|
|
* For the full copyright and license information, please view the LICENSE |
10
|
|
|
* file that was distributed with this source code. |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
namespace Interfaces\Console\Commands; |
14
|
|
|
|
15
|
|
|
use Interfaces\Gitter\Console\CircleProgress; |
16
|
|
|
use Domains\Karma; |
17
|
|
|
use Domains\User; |
18
|
|
|
use Domains\Room; |
19
|
|
|
use Domains\Message; |
20
|
|
|
use Interfaces\Gitter\Client; |
21
|
|
|
use InvalidArgumentException; |
22
|
|
|
use Interfaces\Gitter\Karma\Validator; |
23
|
|
|
use Illuminate\Console\Command; |
24
|
|
|
use Illuminate\Contracts\Config\Repository; |
25
|
|
|
use Illuminate\Contracts\Container\Container; |
26
|
|
|
use Symfony\Component\Finder\Finder; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Class GitterSync |
30
|
|
|
*/ |
31
|
|
|
class GitterSync extends Command |
32
|
|
|
{ |
33
|
|
|
/** |
34
|
|
|
* The name and signature of the console command. |
35
|
|
|
* |
36
|
|
|
* @var string |
37
|
|
|
*/ |
38
|
|
|
protected $signature = 'gitter:sync {room}'; |
39
|
|
|
|
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* The console command description. |
43
|
|
|
* |
44
|
|
|
* @var string |
45
|
|
|
*/ |
46
|
|
|
protected $description = 'Fill users karma from all messages of target room.'; |
47
|
|
|
|
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var Container |
51
|
|
|
*/ |
52
|
|
|
protected $container; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @var Validator |
56
|
|
|
*/ |
57
|
|
|
protected $karma; |
58
|
|
|
|
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Execute the console command. |
62
|
|
|
* |
63
|
|
|
* @param Repository $config |
64
|
|
|
* @param Container $container |
65
|
|
|
* |
66
|
|
|
* @return mixed |
67
|
|
|
* @throws \InvalidArgumentException |
68
|
|
|
* @throws \RuntimeException |
69
|
|
|
* @throws \LogicException |
70
|
|
|
* @throws \Exception |
71
|
|
|
*/ |
72
|
|
|
public function handle(Repository $config, Container $container) |
73
|
|
|
{ |
74
|
|
|
$this->syncUsers($config, $container); |
75
|
|
|
|
76
|
|
|
return; // Temporary fix |
77
|
|
|
$config->set('gitter.output', false); |
|
|
|
|
78
|
|
|
|
79
|
|
|
$client = Client::make($config->get('gitter.token'), $this->argument('room')); |
80
|
|
|
$room = $container->make(Room::class); |
81
|
|
|
|
82
|
|
|
$this->karma = new Validator(); |
83
|
|
|
|
84
|
|
|
|
85
|
|
|
$request = $this->cursor($client, $room); |
86
|
|
|
$count = 1; // Start number |
87
|
|
|
$page = 0; // Current page |
88
|
|
|
$chunk = 100; // Per page |
89
|
|
|
|
90
|
|
|
|
91
|
|
|
while (true) { |
92
|
|
|
$messageChunk = $request($chunk, $chunk * $page++); |
93
|
|
|
|
94
|
|
|
if (!count($messageChunk)) { |
|
|
|
|
95
|
|
|
$this->output->write(sprintf("\r Well done. <comment>%s</comment> Messages was be loaded.", $count)); |
96
|
|
|
break; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
|
100
|
|
|
foreach ($messageChunk as $m) { |
101
|
|
|
echo "\rLoad message: $count "; |
102
|
|
|
$count++; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
$name = 'sync/' . $page . '.json'; |
106
|
|
|
echo '...dump to ' . $name; |
107
|
|
|
file_put_contents( |
108
|
|
|
storage_path($name), |
109
|
|
|
json_encode($messageChunk) |
110
|
|
|
); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
|
114
|
|
|
echo "\n"; |
115
|
|
|
|
116
|
|
|
$this->output->write('Flush database karma increments'); |
117
|
|
|
Karma::query() |
118
|
|
|
->where('room_id', $room->id) |
119
|
|
|
->delete(); |
120
|
|
|
|
121
|
|
|
|
122
|
|
|
$this->output->write('Start message parsing.'); |
123
|
|
|
$finder = (new Finder()) |
124
|
|
|
->files() |
125
|
|
|
->in(storage_path('sync')) |
126
|
|
|
->name('*.json') |
127
|
|
|
->sort(function($a, $b) { |
128
|
|
|
$parse = function(\SplFileInfo $file) { |
129
|
|
|
return str_replace('.json', '', $file->getFilename()); |
130
|
|
|
}; |
131
|
|
|
|
132
|
|
|
return $parse($b) <=> $parse($a); |
133
|
|
|
}); |
134
|
|
|
|
135
|
|
|
|
136
|
|
|
$count = 1; |
137
|
|
|
foreach ($finder as $file) { |
138
|
|
|
$messages = json_decode($file->getContents(), true); |
139
|
|
|
foreach ($messages as $message) { |
140
|
|
|
$message = Message::fromGitterObject($message); |
141
|
|
|
|
142
|
|
|
echo "\r" . $count++ . ' messages parsing: ' . $message->created_at; |
143
|
|
|
usleep(100); |
144
|
|
|
$this->onMessage($message); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
unlink($file->getRealPath()); |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* @param Client $client |
153
|
|
|
* @param Room $room |
154
|
|
|
* @return \Closure |
155
|
|
|
* @throws \InvalidArgumentException |
156
|
|
|
*/ |
157
|
|
|
public function cursor(Client $client, Room $room) |
158
|
|
|
{ |
159
|
|
|
return function ($limit = 100, $skip = 0) use ($client, $room) { |
160
|
|
|
return $client->request('message.list', [ |
161
|
|
|
'roomId' => $room->id, |
162
|
|
|
'limit' => $limit, |
163
|
|
|
'skip' => $skip, |
164
|
|
|
]); |
165
|
|
|
}; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* @param Message $message |
170
|
|
|
* @throws InvalidArgumentException |
171
|
|
|
*/ |
172
|
|
|
protected function onMessage(Message $message) |
173
|
|
|
{ |
174
|
|
|
$collection = $this->karma->validate($message); |
175
|
|
|
|
176
|
|
|
foreach ($collection as $state) { |
177
|
|
|
$user = $state->getUser(); |
178
|
|
|
|
179
|
|
|
if ($state->isIncrement()) { |
180
|
|
|
$message->user->addKarmaTo($user, $message); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
if ($state->isIncrement() || $state->isTimeout() || $state->isSelf()) { |
184
|
|
|
echo "\r" . '[' . $message->created_at . '] ' . |
185
|
|
|
$state->getTranslation($user->karma_text) . "\n"; |
186
|
|
|
} |
187
|
|
|
} |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* @param Repository $config |
192
|
|
|
* @param Container $container |
193
|
|
|
*/ |
194
|
|
|
public function syncUsers(Repository $config, Container $container) |
195
|
|
|
{ |
196
|
|
|
$this->output->write('Start user sync...'); |
197
|
|
|
$config->set('gitter.output', false); |
198
|
|
|
|
199
|
|
|
$client = Client::make($config->get('gitter.token'), $this->argument('room')); |
200
|
|
|
$room = $container->make(Room::class); |
201
|
|
|
|
202
|
|
|
|
203
|
|
|
$users = $client->request('room.users', ['roomId' => $room->id]); |
204
|
|
|
$message = "\r<comment>[%s/%s]</comment> %s%80s"; |
205
|
|
|
|
206
|
|
|
$count = count($users); |
207
|
|
|
$current = 1; |
208
|
|
|
foreach ($users as $user) { |
209
|
|
|
$user = User::fromGitterObject($user); |
210
|
|
|
$this->output->write(sprintf($message, $current, $count, $user->login, '')); |
211
|
|
|
$current++; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
$this->output->write(sprintf($message, $count, $count, 'OK', '')); |
215
|
|
|
} |
216
|
|
|
} |
217
|
|
|
|
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.