basic-implementation #1

Open
florent wants to merge 8 commits from basic-implementation into master
Owner
No description provided.
florent added 2 commits 2021-05-23 16:23:40 +02:00
amaury.joly added 1 commit 2021-05-30 15:36:44 +02:00
amaury.joly added 1 commit 2021-06-04 13:20:06 +02:00
florent reviewed 2021-06-04 13:35:57 +02:00
@ -0,0 +38,4 @@
this.settingEvents();
});
}
Author
Owner
type Channels = {
  channelYtb: TextChannel;
  channelPeerTube: TextChannel;
};

static async instanciate(readonly config: DiscordParser.Config) {
  const client = new Client();
  client.login(this.token);
  await eventsOnce(client, 'ready');
  const channels = {
    channelYtb: this.client.channels.resolve("..."),
    channelPeerTube: ...
  };
  return new Discord({
    client,
    channels,
    keyword
  });
```ts type Channels = { channelYtb: TextChannel; channelPeerTube: TextChannel; }; ``` ```ts static async instanciate(readonly config: DiscordParser.Config) { const client = new Client(); client.login(this.token); await eventsOnce(client, 'ready'); const channels = { channelYtb: this.client.channels.resolve("..."), channelPeerTube: ... }; return new Discord({ client, channels, keyword }); ```
Owner

I made a thing like this

namespace DiscordParser {
    /*...*/
    export type ConstructorPattern = ImplementableApi.Config & {
        keyWord: string;
        channels: {
            ChannelYtb: TextChannel;
            ChannelPeerTube: TextChannel;
        };
        client: Client;
    };
}
/*...*/
class DiscordParser extends ImplementableApi {
    readonly keyWord: string;
    readonly channels: {
        [key: string]: TextChannel;
        ChannelYtb: TextChannel;
        ChannelPeerTube: TextChannel;
    };
    readonly client: Client;

    constructor(readonly config: DiscordParser.ConstructorPattern) {
        super(config);
        this.keyWord = config.keyWord;
        this.channels = config.channels;
        this.client = config.client;
        this.settingEvents();
    }

    static async instanciate(
            config: DiscordParser.Config
        ): Promise<DiscordParser.ConstructorPattern> {
            const client = new Client();
            client.login(config.token);
            await eventsOnce(client, 'ready');
            const channels: ChannelsType = {
                ChannelPeerTube: this.getTextChannel(
                    client,
                    config.channelsId.idChannelPeerTube
                ),
                ChannelYtb: this.getTextChannel(
                    client,
                    config.channelsId.idChannelYtb
                ),
            };

            return {
                name: config.name,
                channels: channels,
                client: client,
                keyWord: config.keyWord,
            };
        }

        private static getTextChannel(client: Client, id: string): TextChannel {
            const channel = client.channels.resolve(id);
            if (!channel || !(channel instanceof TextChannel))
                throw 'Bad token or bad channel id. Be careful, the channel must be a TextChannel';
            return channel;
        }
    /*...*/
};

The problem with this is for the usage inside the router.
I need to make a thing like this :

class Router {
    api_array: { [key: string]: ImplementableApi } = {};
    readonly routes: Router.Config;

    constructor(readonly config: Router.GlobalConfig) {
        this.routes = config.router;

        this.api_array[config.discord.name] = new DiscordParser(
            await DiscordParser.instanciate(config.discord)
        );
        this.api_array[config.peertubeRequester.name] = new PeerTubeRequester(
            config.peertubeRequester
        );
        this.api_array[config.logWriter.name] = new LogWriter(config.logWriter);
    }
	/*...*/
}

So I have again an async function inside my constructor, and to solved this I need to create the same pattern inside the router class.
And by extension i need to generalize this for my ImplementableAPI class. It's included to force all the users of the ImplementableAPI to make an Dependence Injection Pattern for their API. And it's look a little bit restrictive to me.

We could try maybe an events who's called at the the end of the constructor. (I took this idea from DiscordJS)
Like that we could imagine a thing like this :

class MyClass extends ImplementableAPI {
	constructor(...) {
		super(...);
		const promise = startAnAsynchronousTask(...);
        doSomeSynchronousTask(...);
        promise.then(() = > {
        	this.emit('ready');
        });
        
	}
    
    private startAnAsynchronousTask(...) : Promise<void> {
    	await something(..);
        await somethingElse();
        await events.once(anObject, 'ready');
	}
	/*...*/	
}

With this, the restriction is to call the event 'ready' at the end of the constrctor's tasks. It's looking more friendly than the Dependency Injection for a beginner who would to make his own ImplementableAPI.

I made a thing like this ```ts namespace DiscordParser { /*...*/ export type ConstructorPattern = ImplementableApi.Config & { keyWord: string; channels: { ChannelYtb: TextChannel; ChannelPeerTube: TextChannel; }; client: Client; }; } /*...*/ class DiscordParser extends ImplementableApi { readonly keyWord: string; readonly channels: { [key: string]: TextChannel; ChannelYtb: TextChannel; ChannelPeerTube: TextChannel; }; readonly client: Client; constructor(readonly config: DiscordParser.ConstructorPattern) { super(config); this.keyWord = config.keyWord; this.channels = config.channels; this.client = config.client; this.settingEvents(); } static async instanciate( config: DiscordParser.Config ): Promise<DiscordParser.ConstructorPattern> { const client = new Client(); client.login(config.token); await eventsOnce(client, 'ready'); const channels: ChannelsType = { ChannelPeerTube: this.getTextChannel( client, config.channelsId.idChannelPeerTube ), ChannelYtb: this.getTextChannel( client, config.channelsId.idChannelYtb ), }; return { name: config.name, channels: channels, client: client, keyWord: config.keyWord, }; } private static getTextChannel(client: Client, id: string): TextChannel { const channel = client.channels.resolve(id); if (!channel || !(channel instanceof TextChannel)) throw 'Bad token or bad channel id. Be careful, the channel must be a TextChannel'; return channel; } /*...*/ }; ``` The problem with this is for the usage inside the router. I need to make a thing like this : ```ts class Router { api_array: { [key: string]: ImplementableApi } = {}; readonly routes: Router.Config; constructor(readonly config: Router.GlobalConfig) { this.routes = config.router; this.api_array[config.discord.name] = new DiscordParser( await DiscordParser.instanciate(config.discord) ); this.api_array[config.peertubeRequester.name] = new PeerTubeRequester( config.peertubeRequester ); this.api_array[config.logWriter.name] = new LogWriter(config.logWriter); } /*...*/ } ``` So I have again an async function inside my constructor, and to solved this I need to create the same pattern inside the router class. And by extension i need to generalize this for my ImplementableAPI class. It's included to force all the users of the ImplementableAPI to make an Dependence Injection Pattern for their API. And it's look a little bit restrictive to me. We could try maybe an events who's called at the the end of the constructor. (I took this idea from DiscordJS) Like that we could imagine a thing like this : ```ts class MyClass extends ImplementableAPI { constructor(...) { super(...); const promise = startAnAsynchronousTask(...); doSomeSynchronousTask(...); promise.then(() = > { this.emit('ready'); }); } private startAnAsynchronousTask(...) : Promise<void> { await something(..); await somethingElse(); await events.once(anObject, 'ready'); } /*...*/ } ``` With this, the restriction is to call the event 'ready' at the end of the constrctor's tasks. It's looking more friendly than the Dependency Injection for a beginner who would to make his own ImplementableAPI.
Owner

Ok, my bad. I think I missunderstanded the Dependency Injection. Sleep on it.
I'm going to try another thing.
I keep my DiscordParser Class with the instantiate method. And I 'm going to insert the created object inside an method in Router who could be named 'inject' or something in this idea. And who could take an ImplementableAPI instance in params.

Ok, my bad. I think I missunderstanded the Dependency Injection. Sleep on it. I'm going to try another thing. I keep my DiscordParser Class with the instantiate method. And I 'm going to insert the created object inside an method in Router who could be named 'inject' or something in this idea. And who could take an ImplementableAPI instance in params.
@ -0,0 +75,4 @@
return {
ChannelPeerTube: resp.ChannelPeerTube,
ChannelYtb: resp.ChannelYtb,
};
Author
Owner
if (!resp.ChannelPeerTube || !resp.ChannelYtb) {
  throw new Error('Theres an issue concerned the channel check');
}
return {...};
```ts if (!resp.ChannelPeerTube || !resp.ChannelYtb) { throw new Error('Theres an issue concerned the channel check'); } return {...}; ```
amaury.joly marked this conversation as resolved
amaury.joly closed this pull request 2021-06-04 20:18:54 +02:00
amaury.joly reopened this pull request 2021-06-04 20:19:08 +02:00
amaury.joly added 1 commit 2021-06-12 15:13:41 +02:00
Owner

So i keep a thing like this :

namespace DiscordParser {
    /*...*/
    export type ConstructorPattern = ImplementableApi.Config & {
        keyWord: string;
        channels: {
            ChannelYtb: TextChannel;
            ChannelPeerTube: TextChannel;
        };
        client: Client;
    };
}
/*...*/
class DiscordParser extends ImplementableApi {
    readonly keyWord: string;
    readonly channels: {
        [key: string]: TextChannel;
        ChannelYtb: TextChannel;
        ChannelPeerTube: TextChannel;
    };
    readonly client: Client;

    constructor(readonly config: DiscordParser.ConstructorPattern) {
        super(config);
        this.keyWord = config.keyWord;
        this.channels = config.channels;
        this.client = config.client;
        this.settingEvents();
    }

    static async instanciate(
            config: DiscordParser.Config
        ): Promise<DiscordParser.ConstructorPattern> {
            const client = new Client();
            client.login(config.token);
            await eventsOnce(client, 'ready');
            const channels: ChannelsType = {
                ChannelPeerTube: this.getTextChannel(
                    client,
                    config.channelsId.idChannelPeerTube
                ),
                ChannelYtb: this.getTextChannel(
                    client,
                    config.channelsId.idChannelYtb
                ),
            };

            return {
                name: config.name,
                channels: channels,
                client: client,
                keyWord: config.keyWord,
            };
        }

        private static getTextChannel(client: Client, id: string): TextChannel {
            const channel = client.channels.resolve(id);
            if (!channel || !(channel instanceof TextChannel))
                throw 'Bad token or bad channel id. Be careful, the channel must be a TextChannel';
            return channel;
        }
    /*...*/
};

for the discordParser.ts file
And i custom the Router Class by adding the injectDepency(..) (Router.ts:34) method.
Now, we're needing to use the router like this :

let myRouter = new Router(config.router);
myRouter.injectDependency(new LogWriter(config.logWriter));
myRouter.injectDependency(new DiscordParser(await DiscordParser.instanciate(config.discord)));
So i keep a thing like this : ```ts namespace DiscordParser { /*...*/ export type ConstructorPattern = ImplementableApi.Config & { keyWord: string; channels: { ChannelYtb: TextChannel; ChannelPeerTube: TextChannel; }; client: Client; }; } /*...*/ class DiscordParser extends ImplementableApi { readonly keyWord: string; readonly channels: { [key: string]: TextChannel; ChannelYtb: TextChannel; ChannelPeerTube: TextChannel; }; readonly client: Client; constructor(readonly config: DiscordParser.ConstructorPattern) { super(config); this.keyWord = config.keyWord; this.channels = config.channels; this.client = config.client; this.settingEvents(); } static async instanciate( config: DiscordParser.Config ): Promise<DiscordParser.ConstructorPattern> { const client = new Client(); client.login(config.token); await eventsOnce(client, 'ready'); const channels: ChannelsType = { ChannelPeerTube: this.getTextChannel( client, config.channelsId.idChannelPeerTube ), ChannelYtb: this.getTextChannel( client, config.channelsId.idChannelYtb ), }; return { name: config.name, channels: channels, client: client, keyWord: config.keyWord, }; } private static getTextChannel(client: Client, id: string): TextChannel { const channel = client.channels.resolve(id); if (!channel || !(channel instanceof TextChannel)) throw 'Bad token or bad channel id. Be careful, the channel must be a TextChannel'; return channel; } /*...*/ }; ``` for the discordParser.ts file And i custom the Router Class by adding the injectDepency(..) (Router.ts:34) method. Now, we're needing to use the router like this : ```ts let myRouter = new Router(config.router); myRouter.injectDependency(new LogWriter(config.logWriter)); myRouter.injectDependency(new DiscordParser(await DiscordParser.instanciate(config.discord))); ```
florent reviewed 2021-06-13 19:14:52 +02:00
florent left a comment
Author
Owner

Encore quelques changements et go pour merger !

Encore quelques changements et go pour merger !
@ -0,0 +32,4 @@
class DiscordParser extends ImplementableApi {
readonly botPrefix: string;
readonly channels: {
[key: string]: TextChannel;
Author
Owner

Toujours utile ?

Toujours utile ?
@ -0,0 +34,4 @@
readonly channels: {
[key: string]: TextChannel;
ChannelYtb: TextChannel;
ChannelPeerTube: TextChannel;
Author
Owner

youtubeChannel / peertubeChannel comme nom

`youtubeChannel` / `peertubeChannel` comme nom
@ -0,0 +109,4 @@
id_arr.push(resolvedChannel[key].id);
if (this.channels)
if (id_arr.includes(message.channel.id)) {
Author
Owner

Je comprends pas la partie de ce code, il répond à quel cas d'utilisation ?

Sinon :

if ( Object.values(this.channels).some(channel => channel.id === message.channel.id) ) {
Je comprends pas la partie de ce code, il répond à quel cas d'utilisation ? Sinon : ```ts if ( Object.values(this.channels).some(channel => channel.id === message.channel.id) ) { ```
@ -0,0 +108,4 @@
}
const { access_token } = await response.json();
// Upload
Author
Owner

Un commentaire ici, c'est compenser à mon sens un problème sémantique dans le code.

J'aurais tendance à faire deux fonctions privées this.authenticate() et this.upload()

Un commentaire ici, c'est compenser à mon sens un problème sémantique dans le code. J'aurais tendance à faire deux fonctions privées `this.authenticate()` et `this.upload()`
amaury.joly added 1 commit 2021-06-25 16:22:00 +02:00
amaury.joly added 1 commit 2021-06-25 16:29:09 +02:00
This pull request can be merged automatically.
You are not authorized to merge this pull request.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin basic-implementation:basic-implementation
git checkout basic-implementation

Merge

Merge the changes and update on Gitea.
git checkout master
git merge --no-ff basic-implementation
git checkout master
git merge --ff-only basic-implementation
git checkout basic-implementation
git rebase master
git checkout master
git merge --no-ff basic-implementation
git checkout master
git merge --squash basic-implementation
git checkout master
git merge --ff-only basic-implementation
git checkout master
git merge basic-implementation
git push origin master
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Outils-PeerTube/routing#1
No description provided.