Posts: 23
Threads: 2
Joined: Apr 2022
Hi,
I've got the next list:
channels = [
[ '#channel1', 0 ],
[ '#channel2', 0 ],
[ '#channel3', 0 ]
] I can change the values for each channel like:
channel1[1] = somevalue
channel2[1] = somevalue
channel3[1] = anothervalue That is working oke.
The problem is, the script is changed and now it uses a string like:
net.ipv6 "#channel1,#channel2,#channel3" I can call each channel separtly by:
for channel in channels.split(',') No problem for this part.
The big question is: How can i add the mutable values for each item (channel) in this string?
Posts: 7,317
Threads: 123
Joined: Sep 2016
Maybe a dictionary would work,but not sure what task you try to solve with it.
>>> ch = "#channel1,#channel2,#channel3"
>>> ch = ch.split(',')
>>> ch
['#channel1', '#channel2', '#channel3']
>>> values = (1, 42, 'spam')
>>> d = dict(zip(ch, values))
>>> d
{'#channel1': 1, '#channel2': 42, '#channel3': 'spam'}
>>> d['#channel2'] = 100
>>> d
{'#channel1': 1, '#channel2': 100, '#channel3': 'spam'}
>>> d.get('#channel3', 'No channel found')
'spam'
>>> d.get('#channel4', 'No channel found')
'No channel found'
Posts: 453
Threads: 16
Joined: Jun 2022
Does this do what you have in mind?
x = "#channel1,#channel2,#channel3"
x_list = []
x_string = ''
for item in x:
x_string += item
if item == ',':
x_list.append(x_string)
x_list.append(0)
x_string = ''
x_list.append(x_string)
x_list.append(0)
print(x_list) Output: ['#channel1,', 0, '#channel2,', 0, '#channel3', 0]
Sig:
>>> import this
The UNIX philosophy: "Do one thing, and do it well."
"The danger of computers becoming like humans is not as great as the danger of humans becoming like computers." :~ Konrad Zuse
"Everything should be made as simple as possible, but not simpler." :~ Albert Einstein
Posts: 6,788
Threads: 20
Joined: Feb 2020
I'm really confused because this:
channels = [
[ '#channel1', 0 ],
[ '#channel2', 0 ],
[ '#channel3', 0 ] Does not appear to have anything in common with this:
channel1[1] = somevalue
channel2[1] = somevalue
channel3[1] = anothervalue What are you starting with, and how do you want it to look after it has been processed?
Posts: 2,125
Threads: 11
Joined: May 2017
(Aug-21-2022, 08:06 PM)fozz Wrote: channels = [
['#channel1', 0],
['#channel2', 0],
['#channel3', 0],
]
Assigning the first element from channels to a name:
first = channels[0] Assigning a list to the first element of the list channels :
channels[0] = ["channel33", 33] If you do not want to use integer indices, then use a dict.
channels = {
'#channel1': 0,
'#channel2': 0,
'#channel3': 0,
}
channels['#channel4'] = 33
channels['#channel1'] = 1
for name, value in channels.items():
print(name, "->", value) Output: #channel1 -> 1
#channel2 -> 0
#channel3 -> 0
#channel4 -> 33
Getting all values, but not the channels (keys of the dict):
print(list(channels.values())) Output: [1, 0, 0, 33]
If you use for your program the wrong data structures, then handling the data is very complicated.
Posts: 23
Threads: 2
Joined: Apr 2022
Thank you for the help guys, but like i said in the first post, that is the old situation, maybe I wasn't clear.
The goal is to make a channel limiter for irc channels (protection against mass joins) and make it work for more channels ,in the old script it worked flawless on multiple channels because of the list, in the new situation the script works, but only on one channel, if I add more then one channel in the string of the script the timer keeps on looping because the script cannot determine which value for what channel, so my idea was to add a value (the setted limit on the channel) to an item(channel) of the string.
Maybe it's better to post the old and new scripts to clarify it:
OLD situation:
from weechat import (
WEECHAT_RC_OK, info_get, prnt, register,
string_eval_expression, command, hook_timer)
NAME = 'Limiter'
AUTHOR = 'fozz <fozz@someone>'
VERSION = '0.1'
LICENSE = 'GPL3'
DESCRIPTION = 'Channel limiter, protection against mass joining from clones/botnets'
register(NAME, AUTHOR, VERSION, LICENSE, DESCRIPTION, '', '')
# Configuration
limit_ = 5
min_offset_ = 2 #lowest diff
max_offset_ = 2 #highest diff
interval_ = 3
network_ = 'ircnet'
channels_ = [
[ '#python', 0 ],
[ '#forum', 0 ]
]
def limiter_cb(data, signal):
global limit_, min_offset_, max_offset_, network_, channels_
for channel in channels_:
buffer = info_get('irc_buffer', network_+',' + channel[0])
nc = int(string_eval_expression('${buffer.nicklist_visible_count}', {'buffer': buffer}, {}, {}))
nl = nc + limit_
minoff = nl - min_offset_
maxoff = nl + max_offset_
if channel[1] <= minoff or channel[1] >= maxoff:
command(buffer, '/mode ' + channel[0] + ' +l ' + f'{nl}')
channel[1] = nl
return WEECHAT_RC_OK
hook_timer(interval_ * 60000, 0, 0, 'limiter_cb', '') To be clear, the above script worked as it should (on multiple channels).
Now the new situation (is running also on more then one channel so that part is ok) but keeps on looping and setting the limit on the channel again and again (one channel added in the string is no problem)
# Simple Channel limiter version 0.1.
# Protection script against mass joining from clones/botnets on your channel.
''' /set plugins.var.python.limiter.limiter_chans.ircnet #python,#forum '''
from weechat import (
WEECHAT_RC_OK, register, infolist_get, infolist_string, buffer_search,
config_get_plugin, infolist_next, string_eval_expression, command, hook_timer, infolist_free)
NAME = 'limiter'
AUTHOR = 'fozz <[email protected]>'
VERSION = '0.1'
LICENSE = 'GPL3'
DESCRIPTION = 'Channel limiter, protection against mass joining from clones/botnets'
register(NAME, AUTHOR, VERSION, LICENSE, DESCRIPTION, '', '')
# Configuration
limit_ = 5
min_offset_ = 2 #lowest diff
max_offset_ = 2 #highest diff
interval_ = 1
offset_ = int()
def limiter_cb(data, signal):
global limit_, min_offset_, offset_, max_offset_
networks = infolist_get('irc_server', '', '')
while infolist_next(networks):
network = infolist_string(networks, 'name')
channels = config_get_plugin('limiter_chans.{}'.format(network))
if channels:
for channel in channels.split(','):
buffer = buffer_search('irc', '{}.{}'.format(network, channel))
if buffer:
nc = int(string_eval_expression('${buffer.nicklist_visible_count}', {'buffer': buffer}, {}, {}))
nl = nc + limit_
minoff = nl - min_offset_
maxoff = nl + max_offset_
if offset_ <= minoff or offset_ >= maxoff:
command(buffer, '/mode ' + channel + ' +l ' + f'{nl}')
offset_ = nl
infolist_free(networks)
return WEECHAT_RC_OK
hook_timer(interval_ * 60000, 0, 0, 'limiter_cb', '') Any help is very welcome, I stumbled upon setting the data for each channel separtly from the string to nest, that's why the idea with a list from the old situation or something.
The string is like this in the new situation:
limiter_chans.ircnet "#python,#forum"
Posts: 23
Threads: 2
Joined: Apr 2022
Any help please,
How can i write the channels found in the next string:
plugins.var.python.limiter.limiter_chans.ircnet #python,#forum to a file (maybe using pandas or csv) and can read the data (the limit for the specific channel) back?
i can retrieve the setted channels with:
channels = config_get_plugin('limiter_chans.{}'.format(network)) The goal is that i don't have edit that file manually, so the only setting i change in the program is with:
/set plugins.var.python.limiter.limiter_chans.ircnet #python,#forum It should look something like this in the file i guess
channels_ = [[ '#python', 0 ], [ '#forum', 0 ]] Or:
channel | limit
#python | 45
#forum | 64 (the #channels and llimits (45 and 64 in this example) should be modified by the script)
Posts: 4,787
Threads: 76
Joined: Jan 2018
Aug-29-2022, 03:24 PM
(This post was last modified: Aug-29-2022, 03:24 PM by Gribouillis.)
Here is code to store the list in a csv file and read it back. Hope it helps
import csv
import io
from pathlib import Path
source = "plugins.var.python.limiter.limiter_chans.ircnet #python,#forum"
# extract the list ['#python', '#forum']
ichan = [x.strip() for x in source.split(' ', 1)[1].strip().split(',')]
# create the list [["#python#, 0], ['#forum', 0]]
channels = [[x, 0] for x in ichan]
# serialize channels as csv content
ofh = io.StringIO()
csv.writer(ofh).writerows(channels)
content = ofh.getvalue()
# optional: save content to file
filename = Path(__file__).parent/'channels.csv'
filename.write_text(content)
# optional: read file to get content
content = filename.read_text()
# deserialize content as a list of list
channels = [[chan, int(num)] for (chan, num) in csv.reader(io.StringIO(content))]
print(channels) # prints [['#python', 0], ['#forum', 0]]
Posts: 6,788
Threads: 20
Joined: Feb 2020
Why do you suddenly need a file? Before you had a list that contained this information. Why can't you still use a list (or a dictionary)?
What string are you talking about here?
Quote:The string is like this in the new situation:
limiter_chans.ircnet "#python,#forum"
What command in your program is returning this string? Or are you trying to generate a string like this? Assume that I know nothing about weechat. I think that is mostly true for most of the people on the forum. A search for weechat only found posts in this thread and your other thread "Matching multiple parts in string". No results at all for "wechat"
Posts: 23
Threads: 2
Joined: Apr 2022
Thank you for this Gribouillis, i will try that tomorrow.
Quote:Why do you suddenly need a file? Before you had a list that contained this information. Why can't you still use a list (or a dictionary)?
|