-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBiliSpaceDynamic.cs
More file actions
356 lines (335 loc) · 13.2 KB
/
BiliSpaceDynamic.cs
File metadata and controls
356 lines (335 loc) · 13.2 KB
1
2
3
4
5
6
7
8
9
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
using BiliApi.Auth;
using BiliApi.Exceptions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Threading;
namespace BiliApi
{
//使用API:
//https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?host_uid=5659864&offset_dynamic_id=0&need_top=1
/// <summary>
/// Bilibili空间动态获取工具类
/// </summary>
public class BiliSpaceDynamic
{
private readonly long uid = -1;
private List<Dyncard> dyns = new List<Dyncard>();
private readonly List<long> checked_ids = new List<long>();
private BiliSession sess;
public BiliSpaceDynamic(long uid, BiliSession sess)
{
this.sess = sess;
this.uid = uid;
}
public BiliSpaceDynamic(long uid, IAuthBase auth)
{
this.sess = new BiliSession(auth.GetLoginCookies());
this.uid = uid;
}
public bool refresh()
{
return refresh(getLatest());
}
public bool refresh(List<Dyncard> rawdata)
{
try
{
List<Dyncard> d = new List<Dyncard>(rawdata);
d.AddRange(dyns);
dyns = d;
while (dyns.Count > 5)
{
dyns.RemoveAt(5);
}
while (checked_ids.Count > 20)
{
dyns.RemoveAt(0);
}
return true;
}
catch
{
return false;
}
}
public List<Dyncard> fetchDynamics()
{
List<Dyncard> dynss = new List<Dyncard>();
string jstring = sess.getBiliUserDynamicJson(uid);
try
{
JObject jb = (JObject)JsonConvert.DeserializeObject(jstring);
if (jb.Value<int>("code") != 0)
{
throw new ApiRemoteException(jb);
}
if (jb == null || jb["data"] == null || jb["data"]["cards"] == null)
{
return new List<Dyncard>();
}
ExceptionCollection excpts = new ExceptionCollection();
foreach (JToken jobj in jb["data"]["cards"])
{
try
{
JObject j = (JObject)jobj;
JObject card = (JObject)JsonConvert.DeserializeObject(j["card"].ToString());
Dyncard dyn = new Dyncard
{
dynid = j["desc"].Value<long>("dynamic_id"),
sendtime = TimestampHandler.GetDateTime(j["desc"].Value<long>("timestamp")),
type = j["desc"].Value<int>("type"),
view = j["desc"].Value<int>("view"),
repost = j["desc"].Value<int>("repost"),
like = j["desc"].Value<int>("like"),
rid = j["desc"].Value<long>("rid")
};
if (j["desc"]["user_profile"]["info"]["uname"] != null)//如果给了更多信息,就直接用上
{
dyn.sender = new BiliUser(j["desc"]["user_profile"]["info"].Value<long>("uid"),
j["desc"]["user_profile"]["info"].Value<string>("uname"),
"未知",
j["desc"]["user_profile"].Value<string>("sign"),
false,
0,
j["desc"]["user_profile"]["info"].Value<string>("face"),
j["desc"]["user_profile"]["level_info"].Value<int>("current_level"),
0,
new BiliUser.OfficialInfo(),
sess);
}
else//如果没有信息就从缓存抓取
if (BiliUser.userlist.ContainsKey(j["desc"]["user_profile"]["info"].Value<long>("uid")))
{
dyn.sender = BiliUser.getUser(j["desc"]["user_profile"]["info"].Value<long>("uid"), sess);
//使用用户数据缓存来提高速度
//因为监听的是同一个账号,所以缓存命中率超高
}
else//如果缓存未命中,就拿获得的UID抓取剩余信息
{
dyn.sender = BiliUser.getUser(j["desc"]["user_profile"]["info"].Value<long>("uid"), sess);
}
if (j["desc"]["orig_type"] != null)
{
dyn.origintype = j["desc"].Value<int>("orig_type");
}
if (card["origin"] != null)
{
dyn.card_origin = (JObject)JsonConvert.DeserializeObject(card["origin"].ToString());
}
switch (dyn.type)
{
case 1://普通动态
case 4://?出现在转发和普通动态
dyn.dynamic = card["item"].Value<string>("content");
if (dyn.dynamic.Length > 23)
{
dyn.short_dynamic = dyn.dynamic.Substring(0, 20) + "...";
}
else
{
dyn.short_dynamic = dyn.dynamic;
}
break;
case 2://图片
dyn.dynamic = card["item"].Value<string>("description");
if (dyn.dynamic.Length > 23)
{
dyn.short_dynamic = dyn.dynamic.Substring(0, 20) + "...";
}
else
{
dyn.short_dynamic = dyn.dynamic;
}
break;
case 256://音频
break;
case 8://视频
dyn.vinfo = new Videoinfo
{
bvid = j["desc"].Value<string>("bvid"),
title = card.Value<string>("title"),
discription = card.Value<string>("desc")
};
if (dyn.vinfo.discription.Length > 23)
{
dyn.vinfo.short_discription = dyn.vinfo.discription.Substring(0, 20) + "...";
}
else
{
dyn.vinfo.short_discription = dyn.vinfo.discription;
}
dyn.vinfo.av = j["desc"].Value<long>("rid");
dyn.dynamic = card.Value<string>("dynamic");
break;
default:
break;
}
dynss.Add(dyn);
}
catch (Exception err)
{
excpts.Add(err);
}
}
if (excpts.Count > 0) throw excpts;
//while (dynss.Count > 5)
//{
// dynss.RemoveAt(5);
//}
return dynss;
}
catch (ExceptionCollection)
{
throw;
}
catch (Exception err)
{
throw new UnexpectedResultException(jstring, err);
}
}
public List<Dyncard> getLatest()
{
List<Dyncard> fetched = fetchDynamics();
List<Dyncard> latese = new List<Dyncard>();
foreach (Dyncard dync in fetched)
{
if (dyns.Contains(dync))
{
continue;
}
if (checked_ids.Contains(dync.dynid))
{
continue;
}
latese.Add(dync);
checked_ids.Add(dync.dynid);
}
return latese;
}
public List<ShareCard> GetAllDynCardShares(Dyncard card, out int count, string offset = "")
{
var id = card.dynid;
string url = @"https://api.vc.bilibili.com/dynamic_repost/v1/dynamic_repost/repost_detail?dynamic_id=" + id +
(offset.Length > 1 ? ("&offset=" + offset) : "");
string jstr = sess._get_with_cookies(url);
JObject jb = JObject.Parse(jstr);
List<ShareCard> dyn = new List<ShareCard>();
foreach (JObject j in (JArray)jb["data"]["items"])
{
dyn.Add(
new ShareCard
{
Uid = j["desc"].Value<long>("uid"),
UName = j["desc"]["user_profile"]["info"].Value<string>("uname"),
UFace = j["desc"]["user_profile"]["info"].Value<string>("face"),
Content = GetShareTextContent(j.Value<string>("card"))
}
);
}
bool hasmore = jb["data"].Value<bool>("has_more");
if (hasmore)
{
var offs = jb["data"].Value<string>("offset");
dyn.AddRange(GetAllDynCardShares(card, out _, offs));
}
count = jb["data"].Value<int>("total");
return dyn;
}
public static List<ShareCard> GetPageDynCardShares(long id, out int count, ref string offset,out bool more)
{
string url = @"https://api.vc.bilibili.com/dynamic_repost/v1/dynamic_repost/repost_detail?dynamic_id=" + id +
(offset.Length > 1 ? ("&offset=" + offset) : "");
string jstr = BiliSession._get(url);
JObject jb = JObject.Parse(jstr);
List<ShareCard> dyn = new List<ShareCard>();
foreach (JObject j in (JArray)jb["data"]["items"])
{
dyn.Add(
new ShareCard
{
Uid = j["desc"].Value<long>("uid"),
UName = j["desc"]["user_profile"]["info"].Value<string>("uname"),
UFace = j["desc"]["user_profile"]["info"].Value<string>("face"),
Content = GetShareTextContent(j.Value<string>("card"))
}
);
}
more = jb["data"].Value<bool>("has_more");
if (more)
{
offset = jb["data"].Value<string>("offset");
}
count = jb["data"].Value<int>("total");
return dyn;
}
public static string GetShareTextContent(string json)
{
JObject jb = JObject.Parse(json);
return jb["item"].Value<string>("content");
}
}
public struct Dyncard
{
public long dynid, rid;
public int type, view, repost, like, origintype;
public string dynamic;
public string short_dynamic;
public BiliUser sender;
public DateTime sendtime;
public Videoinfo vinfo;
public JObject card_origin;
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (obj is Dyncard)
{
Dyncard b = (Dyncard)obj;
return dynid == b.dynid;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
DateTime dt_1970 = new DateTime(1970, 1, 1, 8, 0, 0);
return (int)(sendtime - dt_1970).TotalSeconds;
}
}
public struct ShareCard
{
public long Uid;
public string UName;
public string UFace;
public string Content;
}
public struct Videoinfo
{
public string discription;
public string short_discription;
public string bvid;
public string title;
public long av;
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (obj is Videoinfo)
{
Videoinfo b = (Videoinfo)obj;
return bvid == b.bvid;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return av.GetHashCode();
}
}
}