for_log generator returns no messages - python-3.x

I am trying to get this for_log coroutine to work, what im trying to do is delete all messages from a specific month, in this case August, I went around the Internet and documentation, and also with the help from another question I posted here and came up with this:
#Client.command(pass_context = True)
async def clear(ctx, number: int, month, year):
def around_month(month, year):
begin = datetime.strptime(f'1 {month} {year}', '%d %b %Y')
if begin.month == 12:
end = datetime(begin.year+1, 1, 1)
else:
end = datetime(begin.year, begin.month, 1)
return begin, end
if ctx.message.author.id not in AdminIDs:
await Client.send_message(ctx.message.channel, 'You do not have permission to use this command')
return
counter = 0
begin, end = around_month(month, year)
tmsg = await Client.send_message(ctx.message.channel, 'Progress: 0/' + str(number))
async for x in Client.logs_from(ctx.message.channel, limit = number, after=begin, before=end):
counter += 1
print(counter)
await Client.edit_message(tmsg, 'Progress:' + counter + '/' + str(number))
await Client.delete_messages(x)
await asyncio.sleep(1.5)
await Client.send_message(ctx.message.channel, 'Operation completed! ' + 'Cleared: ' + str(counter) + ' items')
and then use !fclear 100 AUG 2018
This looks fine at first glance, but for some reason, it does not delete any messages, I inserted a counter to see if the for loop actually goes through the counter, and it gets nothing, it's still zero, interestingly enough, I tried to print the counter while it was inside the for loop, and it didn't print it to the console, the only reason I could think for that to happen is if it doesn't go to the for loop at all which may be because it doesn't find any messages? I'm not sure. There are no errors in the console or anywhere else

It gets nothing
This is a correct deduction. Working back from this, you'll find that around_month returns a tuple of the same date.
begin, end = around_month(month, year)
begin == end # True
Taken from the Discord docs 1,
The before, after, and around keys are mutually exclusive, only one may be passed at a time.
Given your need to delete messages from a specific month, you will need to fetch messages in that month until you exhaust the list of messages created in that month.
Also you need to invoke Client.logs_from with the snowflake time. There is a handy utility function for converting datetime object to a time snowflake. 2
from discord.utils import time_snowflake
from datetime import time delta
# ...
def before_time(messages, before):
return [
message for message in messages
if message.id < before
]
after_dt = datetime.strptime(f'1 {month} {year}', '%d %b %Y')
before_dt = (after_dt + timedelta(days=31)).replace(day=1)
after = time_snowflake(after_dt)
before = time_snowflake(before_dt)
messages = await Client.logs_from(
ctx.message.channel, limit=number, after=after
)
marked_for_deletion = before_time(messages, before)
while marked_for_deletion:
await Client.delete_messages(marked_for_deletion)
messages = await Client.logs_from(
ctx.message.channel, limit=number, after=after
)
marked_for_deletion = before_time(messages, before)
await asyncio.sleep(1.5)

Related

Multicall taking 300 seconds to return result

I am using python multicall library (https://github.com/banteg/multicall.py) to get the ERC20 balances with multiple wallet addresses at once with multiprocessing.
Once the process starts multicall returns the result in less than 1 sec, but once this process continues & run for hours it starts giving results in more than 1 min sometime it takes up to 300 secs too.
Can anyone answer the reason behind the latency in response by time.
Below is the code sample:
block_number = 11374651
GET_BALANCE_FN = "balanceOf(address)(uint256)"
def call_back_obj(success, value):
"""
Callback to process results from multicall for a function.
If call fails returns False (if changed to string throws error)
"""
if success is True and type(value) == bytes:
return value.decode("utf-8")
elif success is True:
return value
else:
return False
def get_instance():
web3_instance = Web3(
Web3.HTTPProvider(
node_provider,
request_kwargs={"timeout": 10},
)
)
web3_instance.middleware_onion.inject(geth_poa_middleware, layer=0)
return web3_instance
w3 = get_instance()
def token_balance_handler(addresses, block_number=None):
calls = []
for address_map in addresses:
contract_addr = address_map.get("tokenAddress")
wallet_addr = address_map.get("walletAddress")
calls.append(
Call(
contract_addr,
[GET_BALANCE_FN, (wallet_addr)],
[[f"{wallet_addr}-{contract_addr}", call_back_obj]],
)
)
return Multicall(
calls, _w3=w3, block_id=block_number, require_success=False
)
print(token_balance_handler(addresses, block_number)())

Send message from random date

I am trying to make my discord bot send a message from a random date in the server's history but the around argument doesn't seem to work properly
def random_date():
d1 = date(year=2020, month=3,day=16)
d2= date.today()
delta = d2 - d1
int_delta = delta.days
random_number_of_days = random.randrange(int_delta)
ran = random_number_of_days
global day
day = d1 + timedelta(ran)
# en = d1 + timedelta(ran + 1)
return day
#commands.command(name='quote')
async def quote(self,message):
day = random_date()
messages = await message.channel.history(around=day).flatten()
msg = random.choice(messages)
embed = discord.Embed(description=f'{msg.content}' , color=message.author.color, timestamp=msg.created_at)
embed.set_author(name=f"{msg.author.name}#{msg.author.discriminator}", icon_url=msg.author.avatar_url)
embed.add_field(name = 'Source' , value = f"[Jump]({msg.jump_url})")
embed.set_footer(text=f"Found in : #{message.channel.name}")
await message.channel.send(embed=embed)
See https://discordpy.readthedocs.io/en/latest/api.html?highlight=channel%20history#discord.TextChannel.history
You need to use datetime.datetime()
Also see: https://docs.python.org/3/library/datetime.html#datetime.datetime if you need help with that

Getting the number of old issues and the table (login and number of commits) of the most active members of the repository

I can not get the above information using github.api. Reading the documentation did not help much. There is still no complete understanding of the work with dates. Here is an example of my code for getting open issues:
import requests
import json
from datetime import datetime
username = '\'
password = '\'
another_page = True
opened = 0
closed = 0
api_oldest = 'https://api.github.com/repos/grpc/grpc/issues?
per_page=5&q=sort=created:>`date -v-14d "+%Y-%m-%d"`&order=asc'
api_issue = 'https://api.github.com/repos/grpc/grpc/issues?
page=1&per_page=5000'
api_pulls = 'https://api.github.com/repos/grpc/grpc/pulls?page=1'
datetime.now()
while another_page:
r = requests.get(api_issue, auth=(username, password))
#json_response = json.loads(r.text)
#results.append(json_response)
if 'next' in r.links:
api_issue = r.links['next']['url']
if item['state'] == 'open':
opened += 1
else:
closed += 1
else:
another_page=False
datetime.now()
print(opened)
There are a few issues with your code. For example, what does item represent ?. Your code can be modified as follows to iterate and get the number of open issues .
import requests
username = '/'
password = '/'
another_page = True
opened = 0
closed = 0
api_issue = "https://api.github.com/repos/grpc/grpc/issues?page=1&per_page=5000"
while another_page:
r = requests.get(api_issue, auth=(username, password))
json_response = r.json()
#results.append(json_response)
for item in json_response:
if item['state'] == 'open':
opened += 1
else:
closed += 1
if 'next' in r.links:
api_issue = r.links['next']['url']
else:
another_page=False
print(opened)
If you want issues that were created in the last 14 days, you could make the api request using the following URL.
api_oldest = "https://api.github.com/repos/grpc/grpc/issues?q=sort=created:>`date -d '14 days ago'`&order=asc"

Boto3/Lambda - Join multiple outputs from a loop and send in one email using AWS SNS

New to Python/Boto3, this should be an easy one but still learning :)
I have a Lambda function which creates a number of snapshots and works fine:
def create_snapshot():
volumes = ec2_client.describe_volumes(
Filters=[
{'N'...
...
for volume in volumes...
....
snap_name = 'Backup of ' + snap_desc
....
snap = ec2_client.create_snapshot(
VolumeId=vol_id,
Description=snap_desc
)
I then want to receive an email from AWS SNS to let me know which snapshots the function created, which I do using:
message = sns.publish(
TopicArn=SNSARN,
Subject=("Function executed"),
Message=("%s created" % snap_name)
)
The issue is that this creates an email for each snapshot, instead of one email listing all the snapshots. Should I create another function that calls all values produced by snap_desc, or can I send all values for snap_desc in the function? And most importantly what's the best way of doing this?
Cheers!
Scott
####################### UPDATE (Thanks #omuthu) #######################
I set an array inside and outside the loop, and put the string into the message. This produced the following being sent in one message:
The following snapshots have been created:
['vol-0e0b9a5dfb8379fc0 (Instance 1 - /dev/sda1)', 'vol-03aac6b65df64661e (Instance 4 - /dev/sda1)', 'vol-0fdde765dfg452631 (Instance 2 - /dev/sda1)', 'vol-0693a9568b11f625f (Instance 3 - /dev/sda1)', etc.
Okay got it sorted, finally!
def create_snapshot():
volumes = ec2_client.describe_volumes(
Filters=[
{'N'...
...
inst_list = []
for volume in volumes...
vol_id = volume['VolumeId']
....
snap_desc = vol_id
for name in volume['Tags']:
tag_key = name['Key']
tag_val = name['Value']
if tag_key == 'Name':
snap_desc = vol_id + ' (' + tag_val + ')'
....
....
....
if backup_mod is False or (current_hour + 10) % backup_mod != 0:
...
continue
else:
print("%s is scheduled this hour" % vol_id)
for name in volume['Tags']:
inst_tag_key = name['Key']
inst_tag_val = name['Value']
if inst_tag_key == 'Name':
inst_list.append(inst_tag_val)
snap = ec2_client.create_snapshot(
VolumeId=vol_id,
Description=snap_desc,
)
print("%s created" % snap['SnapshotId'])
msg = str("\n".join(inst_list))
if len(inst_list) != 0:
message = sns.publish(
TopicArn=SNSARN,
Subject=("Daily Lambda snapshot function complete"),
Message=("The following snapshots have been created today:\n\n" + msg + "\n")
)
print("Response: {}".format(message))

Groovy : Dates not being calculated correctly? Using TimeCategory

can anyone tell me why these aren't being calculated correctly. I'm trying to add 1 second to the time and it seems to be adding 60 milliseconds when I apply formatting?
import java.text.*
import java.util.*
import groovy.time.TimeCategory
def xmlSlurper = new groovy.util.XmlSlurper()
// Get the previous total for number of journals
def journalCountProp = testRunner.testCase.getTestStepByName("Properties")
def journalCountTotal = journalCountProp.getPropertyValue( "journalCount" )
log.info " 1. Previous JournalCount from last run: "+journalCountTotal
def lastDateProp = testRunner.testCase.getTestStepByName("Properties")
def lastDateHolder = lastDateProp.getPropertyValue( "journalQueryDate" )
log.info " 2. Previous lastDate from last run: "+lastDateHolder
// Get the response for a given timeline
def response = xmlSlurper.parseText(context.expand('${GET Journal using JournalDate#Response}'));
def currentJournalCount = response.Journals.Journal.size()
log.info " 3. Number of Journals in this Run: "+currentJournalCount
//Getting the date from the last Journal (including an offset as the array count starts at 0)
def lastDate = response.Journals.Journal[currentJournalCount-1].CreatedDateUTC
log.info " 4. CreatedDate from last journal in this response: "+lastDate
//log.info response.Journals.Journal[currentJournalCount-1].CreatedDateUTC
def newdate = Date.parse("yyyy-MM-dd'T'HH:mm:ss.mmm",lastDate.toString())
log.info "dateBeforeChange: "+newdate.format("yyyy-MM-dd'T'HH:mm:ss.mmm")
use(TimeCategory){
newdate = newdate+1.seconds
}
log.info "date After Change: "+newdate.format("yyyy-MM-dd'T'hh:mm:ss.mmm")
log.info " 5. "+newdate.format("yyyy-MM-dd'T'HH:ss:mmm")
OUTPUT:
CreatedDate from last journal in this response: 2007-03-29T23:19:52.073
dateBeforeChange: 2007-03-30T00:13:52.013
date After Change: 2007-03-30T12:13:53.013
I can't figure it out?!!
Cheers,
- Richard
HH means "hour in a day (0-23)", whereas hh means "hour in am/pm (1-12)".
See the SimpleDateFormat ApiDoc for a reference (SimpleDateFormat is used under the hood).

Resources