From 6c672cb45d540a61884e497b536b49fdcced7ba2 Mon Sep 17 00:00:00 2001 From: Pavel Gnedov Date: Mon, 14 Feb 2022 01:52:04 +0700 Subject: [PATCH] Sleep added between redmine api calls --- .editorconfig | 3 +++ .eslintrc | 32 ++++++++++++++++++++++++++- package.json | 2 +- src/logic/config.ts | 2 +- src/logic/open.ts | 9 +++++--- src/logic/save.ts | 38 ++++++++++++++++++------------- src/logic/utils.ts | 54 +++++++++++++++++++++++++-------------------- 7 files changed, 95 insertions(+), 45 deletions(-) diff --git a/.editorconfig b/.editorconfig index beffa30..f7e5c71 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,5 +7,8 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true +[src/logic/*] +indent_size = 4 + [*.md] trim_trailing_whitespace = false diff --git a/.eslintrc b/.eslintrc index 7b84619..84dcbf3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,5 +2,35 @@ "extends": [ "oclif", "oclif-typescript" - ] + ], + "rules": { + "quotes": "off", + "indent": "off", + "semi": "off", + "unicorn/prefer-node-protocol": "off", + "unicorn/prefer-ternary": "off", + "dot-notation": "off", + "padding-line-between-statements": "off", + "camelcase": "off", + "unicorn/no-console-spaces": "off", + "new-cap": "off", + "no-await-in-loop": "off", + "unicorn/no-for-loop": "off", + "comma-dangle": "off", + "node/no-missing-import": "off", + "no-else-return": "off", + "quote-props": "off", + "no-inner-declarations": "off", + "no-process-exit": "off", + "unicorn/no-process-exit": "off", + "eol-last": "off", + "no-prototype-builtins": "off", + "padded-blocks": "off", + "unicorn/prefer-number-properties": "off", + "operator-assignment": "off", + "no-negated-condition": "off", + "unicorn/catch-error-name": "off", + "@typescript-eslint/ban-ts-comment": "off", + "unicorn/prefer-includes": "off" + } } diff --git a/package.json b/package.json index d8cbffc..98f62cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redmine-time-manager", - "version": "0.1.0", + "version": "0.2.0", "description": "Redmine Time Manager", "author": "Pavel Gnedov @pavel-g", "bin": { diff --git a/src/logic/config.ts b/src/logic/config.ts index 906572a..1d830d5 100644 --- a/src/logic/config.ts +++ b/src/logic/config.ts @@ -40,7 +40,7 @@ export const defaultConfig: ConfigTypes.Config = { } }; -export function getConfig(force: boolean = false): ConfigTypes.Config { +export function getConfig(force = false): ConfigTypes.Config { if (!force && !Args.args['config']) { return defaultConfig; } diff --git a/src/logic/open.ts b/src/logic/open.ts index a01b33f..04a455d 100644 --- a/src/logic/open.ts +++ b/src/logic/open.ts @@ -1,16 +1,19 @@ import {config} from "./config"; import axios from "axios"; -export async function loadEntries(date: string): Promise> { +type TimeEntry = Record; +type TimeEntriesResponse = {time_entries: TimeEntry[]}; + +export async function loadEntries(date: string): Promise { const url = `${config.redmine.url}/time_entries.json`; const params = { user_id: config.redmine.user_id, from: date, to: date }; - const resp = await axios.get>(url, {params: params}); + const resp = await axios.get(url, {params: params}); if (!resp || resp.status !== 200 || !resp.data || !resp.data.time_entries) { throw new Error('Не удалось загрузить записи за дату'); } return resp.data.time_entries; -} \ No newline at end of file +} diff --git a/src/logic/save.ts b/src/logic/save.ts index 35dbb10..8b27bc5 100644 --- a/src/logic/save.ts +++ b/src/logic/save.ts @@ -5,7 +5,7 @@ import {config} from "./config"; import axios from "axios"; import {loadEntries} from "./open"; import {ColumnConverter, filterByQuery, getDate, getItemForRedmine, TimeEntryForRedmine} from "./csv"; -import {uniq} from "./utils"; +import {sleep, uniq} from './utils' function readContentFromFile(fileName: string): string { return fs.readFileSync(fileName, {encoding: 'utf8'}); @@ -13,7 +13,7 @@ function readContentFromFile(fileName: string): string { async function readContentFromStdin(): Promise { const GetStdin = await import('get-stdin'); - return await GetStdin.default(); + return GetStdin.default(); } async function readContent(): Promise { @@ -26,23 +26,24 @@ async function readContent(): Promise { return content; } -function backupEntries(entries: Record): void { +function backupEntries(entries: Record[]): void { const fileName = `entries-${args['date']}.json`; const content = JSON.stringify(entries); fs.writeFileSync(fileName, content, {encoding: "utf8"}); } -async function deleteEntries(entries: Record): Promise { - await Promise.all( - entries.map(async (entry: Record) => { - const url = `${config.redmine.url}/time_entries/${entry.id}.xml`; - if (args['dry']) { - console.log('Delete time entry:', {url, entry}); - } else { - await axios.delete(url); - } - }) - ); +async function deleteEntries(entries: Record[]): Promise { + let i: number; + for (i = 0; i < entries.length; i++) { + const entry = entries[i]; + const url = `${config.redmine.url}/time_entries/${entry.id}.xml`; + if (args['dry']) { + console.log('Delete time entry:', {url, entry}); + } else { + await axios.delete(url); + } + await sleep(100); + } } async function cleanTimeEntries(items: TimeEntryForRedmine[]): Promise { @@ -91,6 +92,7 @@ async function saveCsv(csvData: TimeEntryForRedmine[]): Promise { } const saveResult = await saveItem(item); if (saveResult) successCount++; + await sleep(100); } console.log(`Сохранено записей: ${successCount}`); } @@ -113,8 +115,14 @@ export async function save(): Promise { }) .map(item => item.item) as TimeEntryForRedmine[]; - if (args['rewrite']) await cleanTimeEntries(items); + if (args['rewrite']) { + console.log('Очистка существующих записей...') + await cleanTimeEntries(items); + console.log('Очистка существующих записей завершена') + } + console.log('Сохранение новых записей...'); await saveCsv(items); + console.log('Сохранение новых записей завершено'); } export function getUniqDates(items: TimeEntryForRedmine[]): string[] { diff --git a/src/logic/utils.ts b/src/logic/utils.ts index a99a682..b41dda6 100644 --- a/src/logic/utils.ts +++ b/src/logic/utils.ts @@ -1,34 +1,40 @@ export function invert(obj: Record): Record { - const newObj = {}; - let key; - for (key in obj) { - if (!obj.hasOwnProperty(key)) continue; - const value = obj[key]; - // @ts-ignore - newObj[value] = key; - } - return newObj; + const newObj = {} + let key + for (key in obj) { + if (!obj.hasOwnProperty(key)) continue + const value = obj[key] + // @ts-ignore + newObj[value] = key + } + return newObj } export function uniq(src: T[]): T[] { - const res = []; - let i: number; - for (i = 0; i < src.length; i++) { - const value = src[i]; - if (res.indexOf(value) < 0) { - res.push(value); + const res = [] + let i: number + for (i = 0; i < src.length; i++) { + const value = src[i] + if (res.indexOf(value) < 0) { + res.push(value) + } } - } - return res; + return res } export function assign(target: Record, src: Record): Record { - let key: string; - for (key in src) { - if (src.hasOwnProperty(key)) { - console.debug('rewrite key:', key, ' with value:', src[key]); // DEBUG - target[key] = src[key]; + let key: string + for (key in src) { + if (src.hasOwnProperty(key)) { + console.debug('rewrite key:', key, ' with value:', src[key]) // DEBUG + target[key] = src[key] + } } - } - return target; + return target +} + +export async function sleep(timeout: number): Promise { + return new Promise(resolve => { + setTimeout(resolve, timeout) + }); }