|
@@ -278,10 +278,9 @@ export default class {
|
|
|
return this.queryUser(rawUserName)
|
|
|
.then(userNameId => {
|
|
|
const userId = userNameId.split(':')[1];
|
|
|
- if (Date.now() - new Date(this.cache[userId]?.updated ?? Date()).getTime() > this.workInterval * 1000 &&
|
|
|
- Object.keys(this.cache[userId].stories).length > 0) {
|
|
|
- return userId;
|
|
|
- }
|
|
|
+ const lastUpdated = new Date((this.cache[userId] || {}).updated || 0).getTime();
|
|
|
+ const storyCount = lastUpdated && Object.keys(this.cache[userId].stories || {}).length;
|
|
|
+ if (new Date().getTime() - lastUpdated > this.workInterval * 1000 && storyCount) return userId;
|
|
|
return this.client.feed.reelsMedia({userIds: [userId]}).items()
|
|
|
.then(storyItems => Promise.all(storyItems
|
|
|
.filter(item => !(item.pk in this.cache[userId].stories))
|
|
@@ -389,7 +388,7 @@ export default class {
|
|
|
this.pullOrders = Arr.shuffle(userIdCache);
|
|
|
fs.writeFileSync(path.resolve(this.cachefile), JSON.stringify(this.cache));
|
|
|
}
|
|
|
- const timeout = this.workInterval * 1000 / this.lock.feed.length;
|
|
|
+ const timeout = Math.max(1000, this.workInterval * 1000 / this.lock.feed.length);
|
|
|
setInterval(() => { this.pullOrders = Arr.shuffle(this.pullOrders); }, 21600000);
|
|
|
setTimeout(this.workForAll, timeout);
|
|
|
setTimeout(this.work, timeout * 1.2);
|
|
@@ -443,16 +442,21 @@ export default class {
|
|
|
|
|
|
private get pullOrders() {
|
|
|
const arr: number[] = [];
|
|
|
- Object.values(this.cache).forEach(item => { if (item.pullOrder > 0) arr[item.pullOrder - 1] = item.user.pk; });
|
|
|
+ Object.values(this.cache).forEach(item => {
|
|
|
+ if (item.pullOrder > 0) arr[item.pullOrder - 1] = item.user.pk;
|
|
|
+ });
|
|
|
return arr;
|
|
|
};
|
|
|
|
|
|
private set pullOrders(arr: number[]) {
|
|
|
- Object.values(this.cache).forEach(item => { item.pullOrder = arr.indexOf(item.user.pk) + 1; });
|
|
|
+ Object.values(this.cache).forEach(item => {
|
|
|
+ item.pullOrder = arr.indexOf(item.user.pk) + 1;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
private workForAll = () => {
|
|
|
- if (this.isInactiveTime) return;
|
|
|
+ const timeout = Math.max(1000, this.workInterval * 1000 / this.lock.feed.length);
|
|
|
+ if (this.isInactiveTime) { setTimeout(this.workForAll, timeout); return; }
|
|
|
logger.debug(`current cache: ${JSON.stringify(this.cache)}`);
|
|
|
chainPromises(Object.entries(this.lock.threads).map(([feed, thread]) => () => {
|
|
|
const id = thread.id;
|
|
@@ -511,7 +515,8 @@ export default class {
|
|
|
});
|
|
|
}) as unknown as Promise<void>;
|
|
|
}),
|
|
|
- (lp1, lp2) => () => lp1().then(() => promisify(setTimeout)(this.workInterval * 1000 / this.lock.feed.length).then(lp2))
|
|
|
+ (lp1, lp2) => () =>
|
|
|
+ lp1().then(() => promisify(setTimeout)(timeout).then(lp2))
|
|
|
);
|
|
|
})
|
|
|
.catch((error: IgClientError & Partial<RequestError>) => {
|
|
@@ -530,28 +535,29 @@ export default class {
|
|
|
})
|
|
|
.then(() => {
|
|
|
setTimeout(this.workForAll, this.workInterval * 1000);
|
|
|
- })
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
public get isInactiveTime() {
|
|
|
const timeToEpoch = (h = 0, m = 0) => new Date().setHours(h, m, 0, 0);
|
|
|
return this.inactiveHours
|
|
|
.map(rangeStr => ((start, end) => ({start, end}))(
|
|
|
- ...rangeStr.split('-', 2).map(timeStr => timeToEpoch(...timeStr.split(':', 2).map(Number))) as [number, number?]
|
|
|
+ ...rangeStr
|
|
|
+ .split('-', 2)
|
|
|
+ .map(timeStr => timeToEpoch(...timeStr.split(':', 2)
|
|
|
+ .map(Number))) as [number, number?]
|
|
|
))
|
|
|
- .some(range => (now => now >= range.start && now < range.end)(Date.now()));
|
|
|
+ .some(range => {
|
|
|
+ const now = new Date().getTime();
|
|
|
+ return now >= range.start && now < range.end;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
public work = () => {
|
|
|
const lock = this.lock;
|
|
|
- if (this.workInterval < 1) this.workInterval = 1;
|
|
|
- if (this.isInactiveTime || lock.feed.length === 0) {
|
|
|
- setTimeout(() => {
|
|
|
- this.workForAll();
|
|
|
- setTimeout(this.work, this.workInterval * 200);
|
|
|
- }, this.workInterval * 1000 / lock.feed.length);
|
|
|
- return;
|
|
|
- }
|
|
|
+ const timeout = Math.max(1000, this.workInterval * 1000 / lock.feed.length);
|
|
|
+ const nextTurn = () => { setTimeout(this.work, timeout); return; };
|
|
|
+ if (this.isInactiveTime || lock.feed.length === 0) return nextTurn();
|
|
|
if (lock.workon >= lock.feed.length) lock.workon = 0;
|
|
|
|
|
|
const currentFeed = lock.feed[lock.workon];
|
|
@@ -564,8 +570,7 @@ export default class {
|
|
|
fs.writeFileSync(path.resolve(this.cachefile), JSON.stringify(this.cache));
|
|
|
lock.feed.splice(lock.workon, 1);
|
|
|
fs.writeFileSync(path.resolve(this.lockfile), JSON.stringify(lock));
|
|
|
- this.work();
|
|
|
- return;
|
|
|
+ return this.work();
|
|
|
}
|
|
|
|
|
|
logger.debug(`searching for new items from ${currentFeed} in cache`);
|
|
@@ -573,13 +578,13 @@ export default class {
|
|
|
const match = /https:\/\/www\.instagram\.com\/([^\/]+)/.exec(currentFeed);
|
|
|
if (!match) {
|
|
|
logger.error(`current feed "${currentFeed}" is invalid, please remove this feed manually`);
|
|
|
- lock.workon++; setTimeout(this.work, this.workInterval * 1000 / lock.feed.length); return;
|
|
|
+ lock.workon++;
|
|
|
+ return nextTurn();
|
|
|
}
|
|
|
const cachedFeed = this.cache[lock.threads[currentFeed].id];
|
|
|
- if (!cachedFeed) {
|
|
|
- setTimeout(this.work, this.workInterval * 1000 / lock.feed.length); return;
|
|
|
- }
|
|
|
- const newer = (item: CachedMediaItem) => BigNumOps.compare(item.pk, lock.threads[currentFeed].offset) > 0;
|
|
|
+ if (!cachedFeed) return nextTurn();
|
|
|
+ const newer = (item: CachedMediaItem) =>
|
|
|
+ BigNumOps.compare(item.pk, lock.threads[currentFeed].offset) > 0;
|
|
|
const promise = Promise.resolve(Object.values(cachedFeed.stories)
|
|
|
.filter(newer)
|
|
|
.sort((i1, i2) => BigNumOps.compare(i2.pk, i1.pk))
|
|
@@ -595,10 +600,13 @@ export default class {
|
|
|
if (currentThread.offset === '-1') { updateOffset(); return; }
|
|
|
|
|
|
const questionIndex = mediaItems.findIndex(story => story.original.story_questions);
|
|
|
- if (questionIndex > -1) mediaItems.splice(0, questionIndex);
|
|
|
+ if (questionIndex > 0) mediaItems.splice(0, questionIndex);
|
|
|
if (currentThread.offset === '0') mediaItems.splice(1);
|
|
|
|
|
|
- return this.workOnMedia(mediaItems.reverse(), this.sendStories(`thread ${currentFeed}`, ...currentThread.subscribers))
|
|
|
+ return this.workOnMedia(
|
|
|
+ mediaItems.slice(0).reverse(),
|
|
|
+ this.sendStories(`thread ${currentFeed}`, ...currentThread.subscribers)
|
|
|
+ )
|
|
|
.then(updateOffset)
|
|
|
.then(() => {
|
|
|
if (questionIndex > -1) {
|
|
@@ -616,10 +624,8 @@ export default class {
|
|
|
})
|
|
|
.then(() => {
|
|
|
lock.workon++;
|
|
|
- let timeout = this.workInterval * 1000 / lock.feed.length;
|
|
|
- if (timeout < 1000) timeout = 1000;
|
|
|
fs.writeFileSync(path.resolve(this.lockfile), JSON.stringify(lock));
|
|
|
- setTimeout(this.work, timeout);
|
|
|
+ nextTurn();
|
|
|
});
|
|
|
};
|
|
|
}
|