mirror of
https://github.com/whyour/qinglong.git
synced 2026-06-30 20:35:09 +08:00
重构环境变量管理,添加脚本查看
This commit is contained in:
@@ -1,333 +0,0 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import winston from 'winston';
|
||||
import fetch from 'node-fetch';
|
||||
import { getFileContentByName } from '../config/util';
|
||||
import config from '../config';
|
||||
import * as fs from 'fs';
|
||||
import got from 'got';
|
||||
import DataStore from 'nedb';
|
||||
import { Cookie, CookieStatus, initCookiePosition } from '../data/cookie';
|
||||
|
||||
@Service()
|
||||
export default class CookieService {
|
||||
private cronDb = new DataStore({ filename: config.cookieDbFile });
|
||||
constructor(@Inject('logger') private logger: winston.Logger) {
|
||||
this.cronDb.loadDatabase((err) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
}
|
||||
|
||||
public async getCookies() {
|
||||
const content = getFileContentByName(config.cookieFile);
|
||||
return this.formatCookie(content.split('\n').filter((x) => !!x));
|
||||
}
|
||||
|
||||
public async addCookie(cookies: string[]) {
|
||||
let content = getFileContentByName(config.cookieFile);
|
||||
const originCookies = content.split('\n').filter((x) => !!x);
|
||||
const result = originCookies.concat(cookies);
|
||||
fs.writeFileSync(config.cookieFile, result.join('\n'));
|
||||
return '';
|
||||
}
|
||||
|
||||
public async updateCookie({ cookie, oldCookie }) {
|
||||
let content = getFileContentByName(config.cookieFile);
|
||||
const cookies = content.split('\n');
|
||||
const index = cookies.findIndex((x) => x === oldCookie);
|
||||
if (index !== -1) {
|
||||
cookies[index] = cookie;
|
||||
fs.writeFileSync(config.cookieFile, cookies.join('\n'));
|
||||
return '';
|
||||
} else {
|
||||
return '未找到要原有Cookie';
|
||||
}
|
||||
}
|
||||
|
||||
public async deleteCookie(cookie: string) {
|
||||
let content = getFileContentByName(config.cookieFile);
|
||||
const cookies = content.split('\n');
|
||||
const index = cookies.findIndex((x) => x === cookie);
|
||||
if (index !== -1) {
|
||||
cookies.splice(index, 1);
|
||||
fs.writeFileSync(config.cookieFile, cookies.join('\n'));
|
||||
return '';
|
||||
} else {
|
||||
return '未找到要删除的Cookie';
|
||||
}
|
||||
}
|
||||
|
||||
private async formatCookie(data: any[]) {
|
||||
const result = [];
|
||||
for (const x of data) {
|
||||
const { nickname, status } = await this.getJdInfo(x);
|
||||
if (/pt_pin=(.+?);/.test(x)) {
|
||||
result.push({
|
||||
pin: x.match(/pt_pin=(.+?);/)[1],
|
||||
cookie: x,
|
||||
status,
|
||||
nickname: nickname,
|
||||
});
|
||||
} else {
|
||||
result.push({
|
||||
pin: 'pin未匹配到',
|
||||
cookie: x,
|
||||
status,
|
||||
nickname: nickname,
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public async refreshCookie(_id: string) {
|
||||
const current = await this.get(_id);
|
||||
const { status, nickname } = await this.getJdInfo(current.value);
|
||||
return {
|
||||
...current,
|
||||
status,
|
||||
nickname,
|
||||
};
|
||||
}
|
||||
|
||||
private getJdInfo(cookie: string) {
|
||||
return fetch(
|
||||
`https://me-api.jd.com/user_new/info/GetJDUserInfoUnion?orgFlag=JD_PinGou_New&callSource=mainorder&channel=4&isHomewhite=0&sceneval=2&_=${Date.now()}&sceneval=2&g_login_type=1&g_ty=ls`,
|
||||
{
|
||||
method: 'get',
|
||||
headers: {
|
||||
Accept: '*/*',
|
||||
'Accept-Encoding': 'gzip, deflate, br',
|
||||
'Accept-Language': 'zh-cn',
|
||||
Connection: 'keep-alive',
|
||||
Cookie: cookie,
|
||||
Referer: 'https://home.m.jd.com/myJd/newhome.action',
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1',
|
||||
Host: 'me-api.jd.com',
|
||||
},
|
||||
},
|
||||
)
|
||||
.then((x) => x.json())
|
||||
.then((x) => {
|
||||
if (x.retcode === '0' && x.data && x.data.userInfo) {
|
||||
return {
|
||||
nickname: x.data.userInfo.baseInfo.nickname,
|
||||
status: CookieStatus.normal,
|
||||
};
|
||||
} else if (x.retcode === 13) {
|
||||
return { status: CookieStatus.invalid, nickname: '-' };
|
||||
}
|
||||
return { status: CookieStatus.abnormal, nickname: '-' };
|
||||
});
|
||||
}
|
||||
|
||||
private async formatCookies(cookies: Cookie[]) {
|
||||
const result = [];
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i];
|
||||
if (cookie.status !== CookieStatus.disabled) {
|
||||
const { status, nickname } = await this.getJdInfo(cookie.value);
|
||||
result.push({ ...cookie, status, nickname });
|
||||
} else {
|
||||
result.push({ ...cookie, nickname: '-' });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public async create(payload: string[]): Promise<Cookie[]> {
|
||||
const cookies = await this.cookies();
|
||||
let position = initCookiePosition;
|
||||
if (cookies && cookies.length > 0) {
|
||||
position = cookies[cookies.length - 1].position;
|
||||
}
|
||||
const tabs = payload.map((x) => {
|
||||
const cookie = new Cookie({ value: x, position });
|
||||
position = position / 2;
|
||||
cookie.position = position;
|
||||
return cookie;
|
||||
});
|
||||
const docs = await this.insert(tabs);
|
||||
await this.set_cookies();
|
||||
return await this.formatCookies(docs);
|
||||
}
|
||||
|
||||
public async insert(payload: Cookie[]): Promise<Cookie[]> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb.insert(payload, (err, docs) => {
|
||||
if (err) {
|
||||
this.logger.error(err);
|
||||
} else {
|
||||
resolve(docs);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async update(payload: Cookie): Promise<Cookie> {
|
||||
const { _id, ...other } = payload;
|
||||
const doc = await this.get(_id);
|
||||
const tab = new Cookie({ ...doc, ...other });
|
||||
const newDoc = await this.updateDb(tab);
|
||||
await this.set_cookies();
|
||||
const [newCookie] = await this.formatCookies([newDoc]);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
private async updateDb(payload: Cookie): Promise<Cookie> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb.update(
|
||||
{ _id: payload._id },
|
||||
payload,
|
||||
{ returnUpdatedDocs: true },
|
||||
(err, num, doc) => {
|
||||
if (err) {
|
||||
this.logger.error(err);
|
||||
} else {
|
||||
resolve(doc as Cookie);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async remove(ids: string[]) {
|
||||
return new Promise((resolve: any) => {
|
||||
this.cronDb.remove(
|
||||
{ _id: { $in: ids } },
|
||||
{ multi: true },
|
||||
async (err) => {
|
||||
await this.set_cookies();
|
||||
resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async move(
|
||||
_id: string,
|
||||
{
|
||||
fromIndex,
|
||||
toIndex,
|
||||
}: {
|
||||
fromIndex: number;
|
||||
toIndex: number;
|
||||
},
|
||||
) {
|
||||
let targetPosition: number;
|
||||
const isUpward = fromIndex > toIndex;
|
||||
const cookies = await this.cookies();
|
||||
if (toIndex === 0 || toIndex === cookies.length - 1) {
|
||||
targetPosition = isUpward
|
||||
? cookies[0].position * 2
|
||||
: cookies[toIndex].position / 2;
|
||||
} else {
|
||||
targetPosition = isUpward
|
||||
? (cookies[toIndex].position + cookies[toIndex - 1].position) / 2
|
||||
: (cookies[toIndex].position + cookies[toIndex + 1].position) / 2;
|
||||
}
|
||||
this.update({
|
||||
_id,
|
||||
position: targetPosition,
|
||||
});
|
||||
await this.set_cookies();
|
||||
}
|
||||
|
||||
public async cookies(
|
||||
searchText?: string,
|
||||
sort: any = { position: -1 },
|
||||
needDetail: boolean = false,
|
||||
): Promise<Cookie[]> {
|
||||
let query = {};
|
||||
if (searchText) {
|
||||
const reg = new RegExp(searchText);
|
||||
query = {
|
||||
$or: [
|
||||
{
|
||||
name: reg,
|
||||
},
|
||||
{
|
||||
command: reg,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
const newDocs = await this.find(query, sort);
|
||||
if (needDetail) {
|
||||
return await this.formatCookies(newDocs);
|
||||
} else {
|
||||
return newDocs;
|
||||
}
|
||||
}
|
||||
|
||||
private async find(query: any, sort: any): Promise<Cookie[]> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb
|
||||
.find(query)
|
||||
.sort({ ...sort })
|
||||
.exec((err, docs) => {
|
||||
resolve(docs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async get(_id: string): Promise<Cookie> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb.find({ _id }).exec((err, docs) => {
|
||||
resolve(docs[0]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async getBySort(sort: any): Promise<Cookie> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb
|
||||
.find({})
|
||||
.sort({ ...sort })
|
||||
.limit(1)
|
||||
.exec((err, docs) => {
|
||||
resolve(docs[0]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async disabled(ids: string[]) {
|
||||
return new Promise((resolve: any) => {
|
||||
this.cronDb.update(
|
||||
{ _id: { $in: ids } },
|
||||
{ $set: { status: CookieStatus.disabled } },
|
||||
{ multi: true },
|
||||
async (err) => {
|
||||
await this.set_cookies();
|
||||
resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async enabled(ids: string[]) {
|
||||
return new Promise((resolve: any) => {
|
||||
this.cronDb.update(
|
||||
{ _id: { $in: ids } },
|
||||
{ $set: { status: CookieStatus.noacquired } },
|
||||
{ multi: true },
|
||||
async (err, num) => {
|
||||
await this.set_cookies();
|
||||
resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async set_cookies() {
|
||||
const cookies = await this.cookies();
|
||||
let cookie_string = '';
|
||||
cookies.forEach((tab) => {
|
||||
if (tab.status !== CookieStatus.disabled) {
|
||||
cookie_string += tab.value;
|
||||
cookie_string += '\n';
|
||||
}
|
||||
});
|
||||
fs.writeFileSync(config.cookieFile, cookie_string);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import winston from 'winston';
|
||||
import { getFileContentByName } from '../config/util';
|
||||
import config from '../config';
|
||||
import * as fs from 'fs';
|
||||
import DataStore from 'nedb';
|
||||
import { Env, EnvStatus, initEnvPosition } from '../data/env';
|
||||
import _ from 'lodash';
|
||||
|
||||
@Service()
|
||||
export default class EnvService {
|
||||
private cronDb = new DataStore({ filename: config.envDbFile });
|
||||
constructor(@Inject('logger') private logger: winston.Logger) {
|
||||
this.cronDb.loadDatabase((err) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
}
|
||||
|
||||
public async create(payload: Env): Promise<Env> {
|
||||
const envs = await this.envs();
|
||||
let position = initEnvPosition;
|
||||
if (envs && envs.length > 0) {
|
||||
position = envs[envs.length - 1].position;
|
||||
}
|
||||
const tab = new Env({ ...payload, position: position / 2 });
|
||||
const doc = await this.insert(tab);
|
||||
await this.set_envs();
|
||||
return doc;
|
||||
}
|
||||
|
||||
public async insert(payload: Env): Promise<Env> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb.insert(payload, (err, doc) => {
|
||||
if (err) {
|
||||
this.logger.error(err);
|
||||
} else {
|
||||
resolve(doc);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async update(payload: Env): Promise<Env> {
|
||||
const { _id, ...other } = payload;
|
||||
const doc = await this.get(_id);
|
||||
const tab = new Env({ ...doc, ...other });
|
||||
const newDoc = await this.updateDb(tab);
|
||||
await this.set_envs();
|
||||
return newDoc;
|
||||
}
|
||||
|
||||
private async updateDb(payload: Env): Promise<Env> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb.update(
|
||||
{ _id: payload._id },
|
||||
payload,
|
||||
{ returnUpdatedDocs: true },
|
||||
(err, num, doc) => {
|
||||
if (err) {
|
||||
this.logger.error(err);
|
||||
} else {
|
||||
resolve(doc as Env);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async remove(ids: string[]) {
|
||||
return new Promise((resolve: any) => {
|
||||
this.cronDb.remove(
|
||||
{ _id: { $in: ids } },
|
||||
{ multi: true },
|
||||
async (err) => {
|
||||
await this.set_envs();
|
||||
resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async move(
|
||||
_id: string,
|
||||
{
|
||||
fromIndex,
|
||||
toIndex,
|
||||
}: {
|
||||
fromIndex: number;
|
||||
toIndex: number;
|
||||
},
|
||||
) {
|
||||
let targetPosition: number;
|
||||
const isUpward = fromIndex > toIndex;
|
||||
const envs = await this.envs();
|
||||
if (toIndex === 0 || toIndex === envs.length - 1) {
|
||||
targetPosition = isUpward
|
||||
? envs[0].position * 2
|
||||
: envs[toIndex].position / 2;
|
||||
} else {
|
||||
targetPosition = isUpward
|
||||
? (envs[toIndex].position + envs[toIndex - 1].position) / 2
|
||||
: (envs[toIndex].position + envs[toIndex + 1].position) / 2;
|
||||
}
|
||||
this.update({
|
||||
_id,
|
||||
position: targetPosition,
|
||||
});
|
||||
await this.set_envs();
|
||||
}
|
||||
|
||||
public async envs(
|
||||
searchText?: string,
|
||||
sort: any = { position: -1 },
|
||||
query: any = {},
|
||||
): Promise<Env[]> {
|
||||
let condition = { ...query };
|
||||
if (searchText) {
|
||||
const reg = new RegExp(searchText);
|
||||
condition = {
|
||||
$or: [
|
||||
{
|
||||
value: reg,
|
||||
},
|
||||
{
|
||||
name: reg,
|
||||
},
|
||||
{
|
||||
remarks: reg,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
const newDocs = await this.find(condition, sort);
|
||||
return newDocs;
|
||||
}
|
||||
|
||||
private async find(query: any, sort: any): Promise<Env[]> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb
|
||||
.find(query)
|
||||
.sort({ ...sort })
|
||||
.exec((err, docs) => {
|
||||
resolve(docs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async get(_id: string): Promise<Env> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb.find({ _id }).exec((err, docs) => {
|
||||
resolve(docs[0]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async getBySort(sort: any): Promise<Env> {
|
||||
return new Promise((resolve) => {
|
||||
this.cronDb
|
||||
.find({})
|
||||
.sort({ ...sort })
|
||||
.limit(1)
|
||||
.exec((err, docs) => {
|
||||
resolve(docs[0]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async disabled(ids: string[]) {
|
||||
return new Promise((resolve: any) => {
|
||||
this.cronDb.update(
|
||||
{ _id: { $in: ids } },
|
||||
{ $set: { status: EnvStatus.disabled } },
|
||||
{ multi: true },
|
||||
async (err) => {
|
||||
await this.set_envs();
|
||||
resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async enabled(ids: string[]) {
|
||||
return new Promise((resolve: any) => {
|
||||
this.cronDb.update(
|
||||
{ _id: { $in: ids } },
|
||||
{ $set: { status: EnvStatus.noacquired } },
|
||||
{ multi: true },
|
||||
async (err, num) => {
|
||||
await this.set_envs();
|
||||
resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async updateNames({ ids, name }: { ids: string[]; name: string }) {
|
||||
return new Promise((resolve: any) => {
|
||||
this.cronDb.update(
|
||||
{ _id: { $in: ids } },
|
||||
{ $set: { name } },
|
||||
{ multi: true },
|
||||
async (err, num) => {
|
||||
await this.set_envs();
|
||||
resolve();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async set_envs() {
|
||||
const envs = await this.envs(
|
||||
'',
|
||||
{ position: -1 },
|
||||
{ status: { $ne: EnvStatus.disabled }, name: { $exists: true } },
|
||||
);
|
||||
const groups = _.groupBy(envs, 'name');
|
||||
console.log(groups);
|
||||
let env_string = '';
|
||||
for (const key in groups) {
|
||||
if (Object.prototype.hasOwnProperty.call(groups, key)) {
|
||||
const group = groups[key];
|
||||
env_string += `export ${key}="${_.map(group, 'value').join('&')}"\n`;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(config.envFile, env_string);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user