@@ -15,27 +15,27 @@ import (
1515
1616// Run runs the command.
1717func (o Options ) Run (ctx context.Context , cfg config.Config ) error {
18+ workFunc := topicDone
19+ switch o .Strategy {
20+ case "topic-done" :
21+ workFunc = topicDone
22+ case "motion-state" :
23+ workFunc = motionState
24+ }
25+
1826 eg , ctx := errgroup .WithContext (ctx )
1927 for i := 0 ; i < o .Amount ; i ++ {
2028 eg .Go (func () error {
21- c , err := client .New (cfg )
29+ cli , err := client .New (cfg )
2230 if err != nil {
2331 return fmt .Errorf ("creating client: %w" , err )
2432 }
2533
26- if err := c .Login (ctx ); err != nil {
34+ if err := cli .Login (ctx ); err != nil {
2735 return fmt .Errorf ("login client: %w" , err )
2836 }
2937
30- f := topicDone
31- switch o .Strategy {
32- case "topic-done" :
33- f = topicDone
34- case "motion-state" :
35- f = motionState
36- }
37-
38- return f (ctx , c , o .MeetingID )
38+ return workFunc (ctx , cli , o .MeetingID )
3939 })
4040 }
4141
@@ -48,14 +48,19 @@ func motionState(ctx context.Context, client *client.Client, meetingID int) (err
4848 return fmt .Errorf ("creating motion: %w" , err )
4949 }
5050
51+ nextStateID , err := motionNextStateID (ctx , client , motionID )
52+ if err != nil {
53+ return fmt .Errorf ("getting id of next state: %w" , err )
54+ }
55+
5156 defer func () {
5257 deleteErr := deleteWorkerMotion (context .Background (), client , motionID )
5358 if err == nil && deleteErr != nil {
5459 err = fmt .Errorf ("deleting motion: %w" , err )
5560 }
5661 }()
5762
58- if err := toggleWorkerMotion (ctx , client , motionID ); err != nil {
63+ if err := toggleWorkerMotion (ctx , client , motionID , nextStateID ); err != nil {
5964 return fmt .Errorf ("toggle motion: %w" , err )
6065 }
6166
@@ -64,7 +69,7 @@ func motionState(ctx context.Context, client *client.Client, meetingID int) (err
6469
6570func createWorkerMotion (ctx context.Context , client * client.Client , meetingID int ) (int , error ) {
6671 body := fmt .Sprintf (
67- `[{"action":"motion.create","data":[{"meeting_id":%d,"title":"worker-motion","text":"<p>dummy</p>","workflow_id":1 }]}]` ,
72+ `[{"action":"motion.create","data":[{"meeting_id":%d,"title":"worker-motion","text":"<p>dummy</p>"}]}]` ,
6873 meetingID ,
6974 )
7075
@@ -86,18 +91,77 @@ func createWorkerMotion(ctx context.Context, client *client.Client, meetingID in
8691 return respBody .Results [0 ][0 ].MotionID , nil
8792}
8893
89- func toggleWorkerMotion (ctx context.Context , client * client.Client , motionID int ) error {
94+ func motionNextStateID (ctx context.Context , client * client.Client , motionID int ) (int , error ) {
95+ reqBody := fmt .Sprintf (
96+ `[{"collection":"motion","ids":[%d],"fields":{"state_id":{"type":"relation","collection":"motion_state","fields":{"next_state_ids":null}}}}]` ,
97+ motionID ,
98+ )
99+
100+ req , err := http .NewRequestWithContext (
101+ ctx ,
102+ "GET" ,
103+ "/system/autoupdate?single=1" ,
104+ strings .NewReader (reqBody ),
105+ )
106+ if err != nil {
107+ return 0 , fmt .Errorf ("creating request: %w" , err )
108+ }
109+
110+ resp , err := client .Do (req )
111+ if err != nil {
112+ return 0 , fmt .Errorf ("sending request: %w" , err )
113+ }
114+ defer resp .Body .Close ()
115+
116+ var body map [string ]json.RawMessage
117+ if err := json .NewDecoder (resp .Body ).Decode (& body ); err != nil {
118+ return 0 , fmt .Errorf ("decoding body: %w" , err )
119+ }
120+
121+ motionStateIDRaw , ok := body [fmt .Sprintf ("motion/%d/state_id" , motionID )]
122+ if ! ok {
123+ return 0 , fmt .Errorf ("motion does not exist: %d" , motionID )
124+ }
125+
126+ var motionStateID int
127+ if err := json .Unmarshal (motionStateIDRaw , & motionStateID ); err != nil {
128+ return 0 , fmt .Errorf ("decoding motion state id: %w" , err )
129+ }
130+
131+ nextStateIDsRaw , ok := body [fmt .Sprintf ("motion_state/%d/next_state_ids" , motionStateID )]
132+ if ! ok {
133+ return 0 , fmt .Errorf ("motion state does not exist: %d" , motionStateID )
134+ }
135+
136+ var nextStateIDs []int
137+ if err := json .Unmarshal (nextStateIDsRaw , & nextStateIDs ); err != nil {
138+ return 0 , fmt .Errorf ("decoding next state ids: %w" , err )
139+ }
140+
141+ if len (nextStateIDs ) == 0 {
142+ return 0 , fmt .Errorf ("no next state" )
143+ }
144+
145+ return nextStateIDs [0 ], nil
146+ }
147+
148+ func toggleWorkerMotion (ctx context.Context , client * client.Client , motionID int , nextStateID int ) error {
149+ bodyNextState := fmt .Sprintf (
150+ `[{"action":"motion.set_state","data":[{"id":%d,"state_id":%d}]}]` ,
151+ motionID ,
152+ nextStateID ,
153+ )
154+
155+ bodyReset := fmt .Sprintf (
156+ `[{"action":"motion.reset_state","data":[{"id":%d}]}]` ,
157+ motionID ,
158+ )
159+
90160 toggleState := false
91161 for {
92- body := fmt .Sprintf (
93- `[{"action":"motion.set_state","data":[{"id":%d,"state_id":2}]}]` ,
94- motionID ,
95- )
162+ body := bodyNextState
96163 if toggleState {
97- body = fmt .Sprintf (
98- `[{"action":"motion.reset_state","data":[{"id":%d}]}]` ,
99- motionID ,
100- )
164+ body = bodyReset
101165 }
102166
103167 var respBody struct {
@@ -146,15 +210,20 @@ func topicDone(ctx context.Context, client *client.Client, meetingID int) (err e
146210 return fmt .Errorf ("creating topic: %w" , err )
147211 }
148212
213+ aid , err := agendaID (ctx , client , topicID )
214+ if err != nil {
215+ return fmt .Errorf ("fetching agenda id for topic %d: %w" , topicID , err )
216+ }
217+
149218 defer func () {
150219 deleteErr := deleteWorkerTopic (context .Background (), client , topicID )
151220 if err == nil && deleteErr != nil {
152221 err = fmt .Errorf ("deleting topic: %w" , err )
153222 }
154223 }()
155224
156- if err := toggleWorkerTopic (ctx , client , topicID ); err != nil {
157- return fmt .Errorf ("toggle topic : %w" , err )
225+ if err := toggleWorkerAgendaItem (ctx , client , aid ); err != nil {
226+ return fmt .Errorf ("toggle agenda item : %w" , err )
158227 }
159228
160229 return nil
@@ -184,13 +253,57 @@ func createWorkerTopic(ctx context.Context, client *client.Client, meetingID int
184253 return respBody .Results [0 ][0 ].TopicID , nil
185254}
186255
187- func toggleWorkerTopic (ctx context.Context , client * client.Client , topicID int ) error {
188- toState := "true"
256+ func agendaID (ctx context.Context , client * client.Client , topicID int ) (int , error ) {
257+ key := fmt .Sprintf ("topic/%d/agenda_item_id" , topicID )
258+
259+ req , err := http .NewRequestWithContext (
260+ ctx ,
261+ "GET" ,
262+ fmt .Sprintf ("/system/autoupdate?k=%s&single=1" , key ),
263+ nil ,
264+ )
265+ if err != nil {
266+ return 0 , fmt .Errorf ("creating request: %w" , err )
267+ }
268+
269+ resp , err := client .Do (req )
270+ if err != nil {
271+ return 0 , fmt .Errorf ("sending request: %w" , err )
272+ }
273+ defer resp .Body .Close ()
274+
275+ var body map [string ]json.RawMessage
276+ if err := json .NewDecoder (resp .Body ).Decode (& body ); err != nil {
277+ return 0 , fmt .Errorf ("decoding body: %w" , err )
278+ }
279+
280+ val , ok := body [key ]
281+ if ! ok {
282+ return 0 , fmt .Errorf ("topic %d does not exist" , topicID )
283+ }
284+
285+ var agendaID int
286+ if err := json .Unmarshal (val , & agendaID ); err != nil {
287+ return 0 , fmt .Errorf ("decoding agenda id: %w" , err )
288+ }
289+
290+ return agendaID , nil
291+ }
292+
293+ func boolToStr (b bool ) string {
294+ if b {
295+ return "true"
296+ }
297+ return "false"
298+ }
299+
300+ func toggleWorkerAgendaItem (ctx context.Context , client * client.Client , topicID int ) error {
301+ toState := true
189302 for {
190303 body := fmt .Sprintf (
191304 `[{"action":"agenda_item.update","data":[{"id":%d,"closed":%s}]}]` ,
192305 topicID ,
193- toState ,
306+ boolToStr ( toState ) ,
194307 )
195308
196309 var respBody struct {
@@ -208,11 +321,7 @@ func toggleWorkerTopic(ctx context.Context, client *client.Client, topicID int)
208321 return fmt .Errorf ("backend returned no success" )
209322 }
210323
211- if toState == "true" {
212- toState = "false"
213- } else {
214- toState = "true"
215- }
324+ toState = ! toState
216325 }
217326}
218327
0 commit comments