diff --git a/.github/workflows/update.yaml b/.github/workflows/update.yaml new file mode 100644 index 0000000..2b47a79 --- /dev/null +++ b/.github/workflows/update.yaml @@ -0,0 +1,54 @@ +name: Build and Push Docker Image + + +on: + push: + branches: + + - Project-Kinma-2 + + +jobs: + build: + runs-on: ubuntu-latest + env: + + project: "project-kinma" + architecture: "linux/arm64" + + steps: + + - name: Evaluate Commit Message + run: | + + commitMessage="${{ github.event.head_commit.message }}"; + + if [ "$commitMessage" != "Update" ]; then + + echo "Cancelling Workflow."; + exit 1; + + fi + + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUBUSERNAME }} + password: ${{ secrets.DOCKERHUBTOKEN }} + + - name: Build and Push Docker Image + uses: docker/build-push-action@v5 + with: + context: . + push: true + platforms: ${{ env.architecture }} + tags: ${{ secrets.DOCKERHUBUSERNAME }}/${{ env.project }}:latest \ No newline at end of file diff --git a/.gitignore b/.gitignore index 28f1ba7..4bdccf9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules -.DS_Store \ No newline at end of file +.DS_Store +.vscode +data \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e69de29..f0b1c1e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM node:18.16.0 + + +ENV tokenOctokit undefined +ENV tokenDiscord undefined + +ENV guildId undefined +ENV channelId undefined +ENV applicationId undefined + +ENV messageDepth undefined + +ENV settingLink undefined +ENV dataFilePath undefined +ENV reposFilePath undefined +ENV settingFilePath undefined +ENV channelsFilePath undefined + + +WORKDIR /app +COPY ./ /app +RUN npm install + + +CMD ["node", "index.js"] \ No newline at end of file diff --git a/config.json b/config.json deleted file mode 100644 index 5eb4343..0000000 --- a/config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "users" : [ - "ala2q6", - "lxRbckl" - ], - "channels" : [ - "1144058852824858756", - "1201816307570589716" - ] -} \ No newline at end of file diff --git a/data.json b/data.json deleted file mode 100644 index 9e26dfe..0000000 --- a/data.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 105b67e..e548e23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@octokit/rest": "^20.0.2", "discord.js": "^14.14.1", - "lxrbckl": "^6.5.0", + "lxrbckl": "^6.8.0", "node-cron": "^3.0.3" } }, @@ -1008,12 +1008,13 @@ } }, "node_modules/lxrbckl": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/lxrbckl/-/lxrbckl-6.5.0.tgz", - "integrity": "sha512-Lj6LoiIH697aNT5aPrL4WsezkXN79QgyA21U9icDnHvjkNqrdOTMDHqMeabekz34LQ2dgqC3biiWBUsxyIpKRQ==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/lxrbckl/-/lxrbckl-6.8.0.tgz", + "integrity": "sha512-3aubF5Y1jdNg7omJy3XLaBDZJhY916PvAmsBUPXTKVRosaWiXciAwDHlL6qMgcqICNashKf7M0GnWt2f3ay3+g==", "dependencies": { "@octokit/rest": "^20.0.2", "axios": "^1.5.1", + "lxrbckl": "^6.7.1", "mocha": "^10.2.0", "openai": "^4.19.1" } diff --git a/package.json b/package.json index f08f935..c06a315 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "dependencies": { "@octokit/rest": "^20.0.2", "discord.js": "^14.14.1", - "lxrbckl": "^6.5.0", + "lxrbckl": "^6.8.0", "node-cron": "^3.0.3" } } diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..b0dfde7 --- /dev/null +++ b/settings.json @@ -0,0 +1,9 @@ +{ + "users" : [ + "ala2q6", + "lxRbckl" + ], + "channels" : { + "V10" : "1199281939547435030" + } +} \ No newline at end of file diff --git a/source/client.js b/source/client.js index f20dce7..e158e81 100644 --- a/source/client.js +++ b/source/client.js @@ -26,15 +26,9 @@ class client { this.token = pToken; this.database = objDatabase; this.supervisor = objSupervisor; - this.guildId = '768020237139705857'; // process.env.guildId; - this.channelId = '1210158694919176222'; // process.env.channelId; - this.applicationId = '1210136647992344596'; // process.env.applicationId; // 1211692530069143552 - - this.commands = { - - 'update' : new update(this.supervisor) - - }; + this.guildId = process.env.guildId; + this.channelId = process.env.channelId; + this.applicationId = process.env.applicationId; this.client = new Client({ @@ -50,6 +44,18 @@ class client { }); + this.commands = { + + 'update' : new update({ + + objClient : this.client, + objDatabase : this.database, + objSupervisor : this.supervisor + + }) + + }; + } @@ -65,7 +71,9 @@ class client { this.client.on('interactionCreate', async (interaction) => { - // + let command = this.commands[interaction.commandName]; + let result = await command.run(); + this.message(result); }); @@ -76,18 +84,17 @@ class client { this.client.on('ready', async () => { - await this.supervisor.getChannels({ + cron.schedule('0 0 * * *', async () => { - objClient : this.client, - pConfig : await this.database.loadConfig() - - }); + let result = await this.supervisor.run({ - // cron.schedule('0 0 * * *', async () => { - - // // + objClient : this.client, + objDatabase : this.database + + }); + this.message(result); - // }); + }); }); @@ -111,7 +118,9 @@ class client { ); - // this.listen(); + await this.database.buildDatabase(); + + this.listen(); this.schedule(); } diff --git a/source/command/update.js b/source/command/update.js index a1d3d12..101fa21 100644 --- a/source/command/update.js +++ b/source/command/update.js @@ -1,7 +1,15 @@ class update { - constructor(objSupervisor) { - + constructor({ + + objClient, + objDatabase, + objSupervisor + + }) { + + this.client = objClient; + this.database = objDatabase; this.supervisor = objSupervisor; } @@ -20,7 +28,16 @@ class update { } - async run() {return await this.supervisor.run()} + async run() { + + return await this.supervisor.run({ + + objClient : this.client, + objDatabase : this.database + + }); + + } } diff --git a/source/database.js b/source/database.js index 759c36c..47cda93 100644 --- a/source/database.js +++ b/source/database.js @@ -1,5 +1,13 @@ // import < -const {fileGet, axiosGet} = require('lxrbckl'); +const { + + dirGet, + dirSet, + fileSet, + fileGet, + axiosGet + +} = require('lxrbckl'); // > @@ -8,27 +16,59 @@ class database { constructor() { - this.developerMode = true; - this.dataFilePath = 'data.json'; // process.env.dataFilePath; - this.configFilePath = 'config.json'; // process.env.cofigFilePath; - this.configLink = 'https://raw.githubusercontent.com/lxRbckl/Project-Kinma/Project-Kinma-2/settings.json'; // process.env.configLink; + this.developerMode = false; + this.settingLink = process.env.settingLink; + this.dataFilePath = process.env.dataFilePath; + this.reposFilePath = process.env.reposFilePath; + this.settingFilePath = process.env.settingFilePath; + this.channelsFilePath = process.env.channelsFilePath; } - async loadConfig() { + async loadSetting() { return await { - false : async () => {return axiosGet({pURL : this.configLink});}, - true : async () => {return fileGet({pFile : this.configFilePath});} + false : async () => {return axiosGet({pURL : this.settingLinks});}, + true : async () => {return fileGet({pFile : this.settingFilePath});} }[this.developerMode](); } - async loadData() {return await fileGet({pFile : this.dataFilePath});} + async setChannel({ + + pData, + pChannel + + }) { + + let fPath = `${this.channelsFilePath}/${pChannel}.json`; + let fIn = await fileGet({pFile : fPath, pErrorMessage : {}}); + + await fileSet({pFile : fPath, pData : {...fIn, ...pData}}); + + } + + + async buildDatabase() { + + let dir = await dirGet({pDir : ''}); + + // if (no data) { + if (!(dir.includes(this.dataFilePath))) { + + await dirSet({pDir : this.dataFilePath}); + await dirSet({pDir : this.reposFilePath}); + await dirSet({pDir : this.channelsFilePath}); + + } + + // > + + } } diff --git a/source/supervisor.js b/source/supervisor.js index 1e91e21..6a45bc3 100644 --- a/source/supervisor.js +++ b/source/supervisor.js @@ -1,5 +1,7 @@ // import < -const octokit = require('@octokit/rest'); +const {exec} = require('child_process'); +const {Octokit} = require('@octokit/rest'); +const {dirDel, getProjectPath} = require('lxrbckl'); // > @@ -8,49 +10,90 @@ class supervisor { constructor(pToken) { - this.depth = 100; // process.env.messageDepth; + this.depth = process.env.messageDepth; + this.octokit = new Octokit({auth : this.token}); } - async getRepositories({ + async setRepos({ + + pSetting, + objDatabase - pData, - objClient - }) { - var rData = {}; - // let users = (await objDatabase.loadData())['users']; + let day = new Date().getDay(); + let path = (getProjectPath() + objDatabase.reposFilePath + day); + + // remove outdated dir < + // add repos/user to new dir < + await dirDel({pPath : '', pDir : path}); + pSetting['users'].map(async u => { + + let query = `GET /users/${u}/repos`; + let repos = await this.octokit.paginate(query); + for (const r of repos) { + + await exec(`git clone ${r.clone_url} ${path}/${u}/${r.name}`); + + } + + }); + + // > } - async getChannels({ + async fetchChannel({ + + objClient, + pChannelId - pData, - pConfig, - objClient - }) { - pConfig['channels'].map(async c => { + let rData = {}; + let channel = await objClient.channels.fetch(pChannelId); + let messages = await channel.messages.fetch({limit : this.depth}); + + for (const m of messages) {rData[m[1].content] = null;} + return rData; - let channel = await objClient.channels.fetch(c); - let messages = await channel.messages.fetch({limit : this.depth}); - for (const m of messages.values()) { + } - console.log('====='); - console.log(c); - console.log(JSON.stringify(m.content)); - pData['channels'][c][JSON.stringify(m.content)] = 1; + async run({ - } + objClient, + objDatabase + + }) { + + let setting = await objDatabase.loadSetting(); + + // update channels < + // update repositories < + Object.entries(setting['channels']).map(async ([k, v]) => { + + objDatabase.setChannel({ + + pChannel : k, + pData : await this.fetchChannel({ + + pChannelId : v, + objClient : objClient + + }) + + }); }); + await this.setRepos({pSetting : setting, objDatabase : objDatabase}); + + // > - // console.log('data', pData); // remove + return 'File updated.'; }