Browse Source

Merge pull request #1 from pseudbot/discord

First meme generator test, modular command parser, various fixes
Pseudbot 7 months ago committed by GitHub
parent
commit
5cf2c77613
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      Makefile
  2. 100
      examples/post_meme.py
  3. BIN
      font/Cantarell-VF.otf
  4. BIN
      font/clacon.ttf
  5. BIN
      img/pseud-error.png
  6. BIN
      img/quality-box.png
  7. BIN
      media/bonk/E4chSR5WQAQ_Hn3.jpg
  8. BIN
      media/phew/EyeJ-4nWEAAFybq.jpg
  9. 99
      pastas.txt
  10. 17
      pseudbot/cli.py
  11. 89
      pseudbot/command.py
  12. 0
      pseudbot/meme/__init__.py
  13. 145
      pseudbot/meme/abc.py
  14. 184
      pseudbot/meme/phone_screenshot.py
  15. 126
      pseudbot/meme/post.py
  16. 81
      pseudbot/meme/post_styles.py
  17. 35
      pseudbot/meme/soyphone.py
  18. 8
      pseudbot/pastas.py
  19. 208
      pseudbot/tweet_bot.py
  20. 82
      pseudbot/util.py
  21. 1
      requirements.txt
  22. 2
      setup.py
  23. BIN
      templates/discord-phone/discord-heading-notxt-no-notification-notime.png
  24. BIN
      templates/discord-phone/discord-heading-notxt.png
  25. BIN
      templates/discord-phone/discord-iphone-bottom-bar.png
  26. BIN
      templates/iphone/icons/notification/grindr.png
  27. BIN
      templates/iphone/iphone-noti-grindr-text.png
  28. BIN
      templates/soyphone/soyphone-13.png

4
Makefile

@ -16,6 +16,4 @@ readme-preview:
format:
black -v -l 80 pseudbot/*
black -v -l 80 scripts/*
# Uncomment below if we ever include code examples:
##black -v -l 80 examples/*.py
black -v -l 80 examples/*.py

100
examples/post_meme.py

@ -0,0 +1,100 @@
"""
Test of Discord fake post pixmap generator.
"""
from PIL import Image
from pseudbot.meme.post import Post
from pseudbot.meme.phone_screenshot import PhoneScreenshot
from pseudbot.meme.soyphone import SoyPhone
tt = {
"channel_name": "staff-feet-pics",
"posts": [
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "I walk up 4 flights of stairs every single day",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "I walk up 4 flights of stairs every single day",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "I walk up 4 flights of stairs every single day",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "I walk up 4 flights of stairs every single day",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "I walk up 4 flights of stairs every single day",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "I walk up 4 flights of stairs every single day",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "I walk up 4 flights of stairs every single day",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "I walk up 4 flights of stairs every single day",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/bonk/E4chSR5WQAQ_Hn3.jpg",
"text": "it has an orange tip",
"timestamp": "Today at 5:07 AM",
},
{
"screen_name": "Owen",
"pfp": "media/phew/EyeJ-4nWEAAFybq.jpg",
"text": "go look in the fields for it",
"timestamp": "Today at 5:07 AM",
},
],
}
bt = "Owen #1"
# p = Post(top_text=tt, bottom_text=bt, style="discord")
# pi = p.get_pixmap()
# pi.show()
# This Post() generates an error pixmap
# q = Post(top_text={}, bottom_text=bt, style="discord")
# qi = q.get_pixmap()
# qi.show()
# Makes a fake Discord iPhone screenshot
r = PhoneScreenshot(top_text=tt, bottom_text=bt)
ri = r.get_pixmap()
# ri.show()
# Puts the above screenshot pixmap in an iPhone
s = SoyPhone(screenshot=ri)
si = s.get_pixmap()
si.show()
# Puts an arbitrary pixmap in an iPhone
# i = Image.open("media/phew/EyeJ-4nWEAAFybq.jpg").convert("RGBA")
# t = SoyPhone(screenshot=i)
# ti = t.get_pixmap()
# ti.show()

BIN
font/Cantarell-VF.otf

Binary file not shown.

BIN
font/clacon.ttf

Binary file not shown.

BIN
img/pseud-error.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
img/quality-box.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 55 KiB

BIN
media/bonk/E4chSR5WQAQ_Hn3.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
media/phew/EyeJ-4nWEAAFybq.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

99
pastas.txt

@ -1,93 +1,42 @@
To be fair, you have to have a very high IQ to understand Rick and Morty. The humour is extremely subtle, and without a solid grasp of theoretical physics most of the jokes will go over a typical viewer's head.
There's also Rick's nihilistic outlook, which is deftly woven into his characterisation- his personal philosophy draws heavily from Narodnaya Volya literature, for instance. The fans understand this stuff;
they have the intellectual capacity to truly appreciate the depths of these jokes, to realise that they're not just funny- they say something deep about LIFE. As a consequence people who dislike Rick & Morty truly ARE idiots- of course they wouldn't appreciate,
for instance, the humour in Rick's existential catchphrase "Wubba Lubba Dub Dub," which itself is a cryptic reference to Turgenev's Russian epic Fathers and Sons.
I'm smirking right now just imagining one of those addlepated simpletons scratching their heads in confusion as Dan Harmon's genius wit unfolds itself on their television screens. What fools.. how I pity them.πŸ˜‚
And yes, by the way, i DO have a Rick & Morty tattoo. And no, you cannot see it. It's for the ladies' eyes only- and even then they have to demonstrate that they're within 5 IQ points of my own (preferably lower) beforehand. Nothin personnel kid 😎
To be fair, you have to have a very high IQ to understand Rick and Morty. The humour is extremely subtle, and without a solid grasp of theoretical physics most of the jokes will go over a typical viewer's head. There's also Rick's nihilistic outlook, which is deftly woven into his characterisation- his personal philosophy draws heavily from Narodnaya Volya literature, for instance. The fans understand this stuff; they have the intellectual capacity to truly appreciate the depths of these jokes, to realise that they're not just funny- they say something deep about LIFE. As a consequence people who dislike Rick & Morty truly ARE idiots- of course they wouldn't appreciate, for instance, the humour in Rick's existential catchphrase "Wubba Lubba Dub Dub," which itself is a cryptic reference to Turgenev's Russian epic Fathers and Sons. I'm smirking right now just imagining one of those addlepated simpletons scratching their heads in confusion as Dan Harmon's genius wit unfolds itself on their television screens. What fools.. how I pity them.πŸ˜‚ And yes, by the way, i DO have a Rick & Morty tattoo. And no, you cannot see it. It's for the ladies' eyes only- and even then they have to demonstrate that they're within 5 IQ points of my own (preferably lower) beforehand. Nothin personnel kid 😎
"Rick and Morty"? Only a plebeian worm such as yourself would engage in viewing broadcasts of such a sad and idiotic show. Unlike you low IQ apes, I please my optical sensors with only the finest of entertainment.
I'll bet that you're inquiring as to what source of entertainment I am referring to. Although I don't expect you to comprehend it, the television show in question is "Young Sheldon". You see, the humor is vastly superior to that of "Rick and Morty".
First of all "Rick and Morty" relies heavily on improvisional comedy, while the intellectual humor of "Young Sheldon" is scripted and well thought out before being presented to an audience.
Second of all "Rick and Morty" is extremely unfaithful to its source material (Back to the Future, for you simpletons) while "Young Sheldon" is just as good if not better than watching "The Big Bang Theory".
I could go on and on about how "Rick and Morty" is vastly inferior to "Young Sheldon" but I highly doubt that you have the mental capability to process such logic.
So if you'll excuse me, I'm going to pour a glass of brandy whilst I redigest the latest episode of "Young Sheldon" so I can make an entry about it to the "Young Sheldon" wikia. Hopefully, I can forget about ever having the displeasure of interacting with you.
*Sighs... How tedious.
"Rick and Morty"? Only a plebeian worm such as yourself would engage in viewing broadcasts of such a sad and idiotic show. Unlike you low IQ apes, I please my optical sensors with only the finest of entertainment. I'll bet that you're inquiring as to what source of entertainment I am referring to. Although I don't expect you to comprehend it, the television show in question is "Young Sheldon". You see, the humor is vastly superior to that of "Rick and Morty". First of all "Rick and Morty" relies heavily on improvisional comedy, while the intellectual humor of "Young Sheldon" is scripted and well thought out before being presented to an audience. Second of all "Rick and Morty" is extremely unfaithful to its source material (Back to the Future, for you simpletons) while "Young Sheldon" is just as good if not better than watching "The Big Bang Theory". I could go on and on about how "Rick and Morty" is vastly inferior to "Young Sheldon" but I highly doubt that you have the mental capability to process such logic. So if you'll excuse me, I'm going to pour a glass of brandy whilst I redigest the latest episode of "Young Sheldon" so I can make an entry about it to the "Young Sheldon" wikia. Hopefully, I can forget about ever having the displeasure of interacting with you. *Sighs... How tedious.
When you step into the Rick and Morty fandom realm, you're not going any old place. You're coming to the underground fight club of intellect. Prepare to be mentally battered.
But don't worry, after you've spent your newbie time being cognitively pummeled, you'll have joined the ranks of the mental elite. Then you'll see the world for what it truly is. All those people going around without a thought in their head.
You'll hate it. You'll become just like him. And you'll start loving it. The power of intelligence, of absolute intellectual superiority. It'll become a high you chase, constantly learning and experimenting. You'll finally be a Rick.
When you step into the Rick and Morty fandom realm, you're not going any old place. You're coming to the underground fight club of intellect. Prepare to be mentally battered. But don't worry, after you've spent your newbie time being cognitively pummeled, you'll have joined the ranks of the mental elite. Then you'll see the world for what it truly is. All those people going around without a thought in their head. You'll hate it. You'll become just like him. And you'll start loving it. The power of intelligence, of absolute intellectual superiority. It'll become a high you chase, constantly learning and experimenting. You'll finally be a Rick.
And yes, by the way, i DO have a Rick & Morty tattoo. And no, you cannot see it. It's for the ladies' eyes only- and even then they have to demonstrate that they're within 5 IQ points of my own (preferably lower) beforehand. Nothin personnel kid 😎
What you guys have no Szechuan sauce? I WANT SZECHUAN SAUCE! WHERE'S MY SZECHUAN SAUCE??!! I'M PICKLE RICK!!!!!!!! WUBBALUBBADUBDUB!!!!!! I'M PICKLE RICK!!!! REEEEEEEEE!!!! REEEEE!!!! REEEEE!!!! IM PICKLE REEEEEEEEE!!!! REEEEEE!!!!! REEEEE!!!!!!
Many people always ask me how I was able to get into Harvard as a 16 year old who skipped 3 grades of high school. They think I got in because of my scholarly records, but no the key is the interview.
As I sat in the Harvard Dean's office in front of the board of reviewers for my application, the Dean asks me "Why should you be a good candidate for this school?" They seemed bored but I replied
"Well I was born a child prodigy, placed 1st in my state spelling bee for three consecutive years,"
"I can speak eight different languages not counting Latin, play four different instruments, I skipped grades 4 through 6, and graduated my high school as valedictorian at the age of 14. I then worked as an intern at both Telsa, and NASA."
Suddenly the room burst into laughter and many of board instantly started scribbling down "No" near the application check marks. The Dean says "Sorry but you are just not the type we are looking for." But then I said
"Excuse me but I wasn't finished... I watch Rick and Morty" The Dean looked at me like an idiot and said "So....?" Then I replied with a smile "And I understand all the references and subtle jokes"
An audible gasp let out by the board was so loud the secretary had to come in.
You could hear a pin drop and then suddenly all at once the entire board clicked their pens on the "Approved Box" and I was instantly handed a diploma and now I'm teaching advanced physicals there. I guess you can say I'm pretty smart. :)
Many people always ask me how I was able to get into Harvard as a 16 year old who skipped 3 grades of high school. They think I got in because of my scholarly records, but no the key is the interview. As I sat in the Harvard Dean's office in front of the board of reviewers for my application, the Dean asks me "Why should you be a good candidate for this school?" They seemed bored but I replied "Well I was born a child prodigy, placed 1st in my state spelling bee for three consecutive years," "I can speak eight different languages not counting Latin, play four different instruments, I skipped grades 4 through 6, and graduated my high school as valedictorian at the age of 14. I then worked as an intern at both Telsa, and NASA." Suddenly the room burst into laughter and many of board instantly started scribbling down "No" near the application check marks. The Dean says "Sorry but you are just not the type we are looking for." But then I said "Excuse me but I wasn't finished... I watch Rick and Morty" The Dean looked at me like an idiot and said "So....?" Then I replied with a smile "And I understand all the references and subtle jokes" An audible gasp let out by the board was so loud the secretary had to come in. You could hear a pin drop and then suddenly all at once the entire board clicked their pens on the "Approved Box" and I was instantly handed a diploma and now I'm teaching advanced physicals there. I guess you can say I'm pretty smart. :)
You see, I have a very high IQ. Do you want to know why? Well, I'll tell you anyways, I have a high IQ because I watch this amazing television show (which to my surprise piqued my interest unlike many other television shows) Rick and Morty.
This show is remarkably intellectual (Like me, mind you) and not like any other animated shows. My most favorite joke from the show is "WUBALUBADUBDUB" it makes me giddy inside and knowing the common folk wont understand the joke makes me laugh even harder!
You see, I have a very high IQ. Do you want to know why? Well, I'll tell you anyways, I have a high IQ because I watch this amazing television show (which to my surprise piqued my interest unlike many other television shows) Rick and Morty. This show is remarkably intellectual (Like me, mind you) and not like any other animated shows. My most favorite joke from the show is "WUBALUBADUBDUB" it makes me giddy inside and knowing the common folk wont understand the joke makes me laugh even harder!
This is a manifestation of what it means to know the full euphoria of enlightenment. This is what peak intellectual performance looks like. I'm smirking right now just thinking of it. Oh how I pity those for whom these pleasures are unknown.
πŸ₯’ IM PIIICKLE πŸ₯’ RIIIIIICK!!! πŸ˜‚ πŸ‘Œ πŸ’― πŸ₯’ IM PIIICKLE πŸ₯’ RIIIIIICK!!! πŸ˜‚ πŸ‘Œ πŸ’― πŸ₯’ IM PIIICKLE πŸ₯’ RIIIIIICK!!! πŸ˜‚ πŸ‘Œ πŸ’―
"Hey, do you guys have szechuan sauce?", I ask the low IQ minimum wage slave. "N-no, sir. We just ran out", he muttered. I was overcome with a primal rage. I jump on the counter, screaming "I'm Pickle Rick!”.
The 200 IQ crowd chanted in unison, β€œWUBBALUBBA DUB DUB” whilst beating their chests towards the cowering worker. I put my shirt over my head and let out the purest REEE to show my devotion to Rick. Everyone else REEEs as well.
Yes, my brothers, let it all out. The manger comes in and calls the police, he doesn’t understand the mature and intellectual nature of our cries. We Naruto run to the next McDonalds store as we search endlessly for that sauce.
Today my 12 year old son and I walked into harvard to sign him up for college. The dean rudly asked what a 12 year old was doing signing up for such a prestigious institute like harvard. My son took of to reveal his Rick and Morty shirt and proclaimed
"Well you see sir I watch Rick and Morty". A look of confusion came over the deans face and I have never been so proud. The dean quickly made sure to appologize to my son but it was too late, the police rushed in and dragged him out.
My son passed all his classes with 4.0s and graduated top of his class in the first day of college.
When I was in school I used to have an IQ of 15. My classmates used to harass me for not being that smart. But since 2013, my life has changed. My IQ is now 195 and it increases by 5 every time I sit down on Saturday nights to watch this one show.
It is called Rick and Morty. Because of that, I get all the girls and people are always comparing me to Albert Einstein, some even say that I am the cure for cancer.
When the government found out that I watch Rick and Morty, they showed up to my residence and took me to a secret facility to take an exam.
The exam was about explaining all the jokes in Rick and Morty and I had to answer each question in all currently spoken languages. Since I watched Rick and Morty, I didn't have any problems and I completed it in 30 minutes.
The next day, I got to see the results and I passed the exam with a score of 100%. They gave me the title "Smartest Man in Existence." Guess I am out of this world.
Hi I'm 13 and I just started watching Rick and Morty and I can tell you for a fact it's my favorite show!!. Lik the one time Ricky said said there's probably like no good !!!!
i was agreeing so much I'am smarter then you're average fidget spinner teen at middle school to even though I have one.
I may be young but I'm smarter then every theist on earth basically the show is also really deep when they said like no one was born for a reason I was so blown away
as they must have big balls to say that on tv so I told my friends on minecraft and they agree too. LOL once when my mom took me to McDonald's I asked for the Mulan dipping sauce
and the dumb bitch didn't even get the reference XD One time in class i evan shouted "I'm PICKLE RIIIICK!" and Mrs.Janice told me to go outside i fucking hate that cunt school is for dumb ppl just like what Rick said, i m too smart for such imbicells.
But yeah I love Rick and Morty and I'm actually smart enough to get it to.
Teenagers and man children according to who? You? What is your standard? I'm a fan of Rick and Morty, and I've been watching since episode one.
Most of my friends who are scientists love the show, because it has a sense of humor and plot lines that you need a STEM mind simply to follow, let alone interpret and appreciate.
Most of the people who diss the show are standard literature, philosophy, sociology a business majors who would rather watch shit like The Office or How I Met Your Mother and other shit-tier shows. Get off your high horse
This copypasta was never even funny to begin with. I've never even seen the show, and it was obviously a joke. What kind of idiot do you have to be to think that was ever said seriously?
But it makes fun of something which is popular, and therefore popular to shit on among the contrarians on Reddit. Come on, really. I actually do have to wonder about the IQs of people who like that pretentious copypasta.
You know, I sometimes can't help but superiorly smirk as I imagine their dumb faces struggling to understand words on a mere internet webpage.
In fact, I sometimes find myself in paroxysms of ironic Schadenfreude as I envision the visages of the aforementioned Slow-in-the-minds waging war with the Cultural Artifact they proclaim to be analyzing,
only to fall, slack-jawed, back into their insensate stupor, the proverbial Undiscovered Country, "from whose bourn no traveler returns" .
My teacher said to my I'm a failure, that I'll never amount to anything. I scoffed at him. Shocked, my teacher asked what's so funny, my future is on the line. "Well...you see professor" I say as the teacher prepares to laugh at my answer, rebuttal at hand.
"I watch Rick and Morty." The class is shocked, they merely watch pleb shows like the big bang theory to feign intelligence, not grasping the humor. "...how? I can't even understand it's sheer nuance and subtlety." "Well you see...WUBBA LUBBA DUB DUB!"
One line student laughs in the back, I turn to see a who this fellow genius is. It's none other than Albert Einstein.
"Hey, do you guys have szechuan sauce?", I ask the low IQ minimum wage slave. "N-no, sir. We just ran out", he muttered. I was overcome with a primal rage. I jump on the counter, screaming "I'm Pickle Rick!”. The 200 IQ crowd chanted in unison, β€œWUBBALUBBA DUB DUB” whilst beating their chests towards the cowering worker. I put my shirt over my head and let out the purest REEE to show my devotion to Rick. Everyone else REEEs as well. Yes, my brothers, let it all out. The manger comes in and calls the police, he doesn’t understand the mature and intellectual nature of our cries. We Naruto run to the next McDonalds store as we search endlessly for that sauce.
Today my 12 year old son and I walked into harvard to sign him up for college. The dean rudly asked what a 12 year old was doing signing up for such a prestigious institute like harvard. My son took of to reveal his Rick and Morty shirt and proclaimed "Well you see sir I watch Rick and Morty". A look of confusion came over the deans face and I have never been so proud. The dean quickly made sure to appologize to my son but it was too late, the police rushed in and dragged him out. My son passed all his classes with 4.0s and graduated top of his class in the first day of college.
When I was in school I used to have an IQ of 15. My classmates used to harass me for not being that smart. But since 2013, my life has changed. My IQ is now 195 and it increases by 5 every time I sit down on Saturday nights to watch this one show. It is called Rick and Morty. Because of that, I get all the girls and people are always comparing me to Albert Einstein, some even say that I am the cure for cancer. When the government found out that I watch Rick and Morty, they showed up to my residence and took me to a secret facility to take an exam. The exam was about explaining all the jokes in Rick and Morty and I had to answer each question in all currently spoken languages. Since I watched Rick and Morty, I didn't have any problems and I completed it in 30 minutes. The next day, I got to see the results and I passed the exam with a score of 100%. They gave me the title "Smartest Man in Existence." Guess I am out of this world.
Hi I'm 13 and I just started watching Rick and Morty and I can tell you for a fact it's my favorite show!!. Lik the one time Ricky said said there's probably like no good !!!! i was agreeing so much I'am smarter then you're average fidget spinner teen at middle school to even though I have one. I may be young but I'm smarter then every theist on earth basically the show is also really deep when they said like no one was born for a reason I was so blown away as they must have big balls to say that on tv so I told my friends on minecraft and they agree too. LOL once when my mom took me to McDonald's I asked for the Mulan dipping sauce and the dumb bitch didn't even get the reference XD One time in class i evan shouted "I'm PICKLE RIIIICK!" and Mrs.Janice told me to go outside i fucking hate that cunt school is for dumb ppl just like what Rick said, i m too smart for such imbicells. But yeah I love Rick and Morty and I'm actually smart enough to get it to.
Teenagers and man children according to who? You? What is your standard? I'm a fan of Rick and Morty, and I've been watching since episode one. Most of my friends who are scientists love the show, because it has a sense of humor and plot lines that you need a STEM mind simply to follow, let alone interpret and appreciate. Most of the people who diss the show are standard literature, philosophy, sociology a business majors who would rather watch shit like The Office or How I Met Your Mother and other shit-tier shows. Get off your high horse
This copypasta was never even funny to begin with. I've never even seen the show, and it was obviously a joke. What kind of idiot do you have to be to think that was ever said seriously? But it makes fun of something which is popular, and therefore popular to shit on among the contrarians on Reddit. Come on, really. I actually do have to wonder about the IQs of people who like that pretentious copypasta. You know, I sometimes can't help but superiorly smirk as I imagine their dumb faces struggling to understand words on a mere internet webpage. In fact, I sometimes find myself in paroxysms of ironic Schadenfreude as I envision the visages of the aforementioned Slow-in-the-minds waging war with the Cultural Artifact they proclaim to be analyzing, only to fall, slack-jawed, back into their insensate stupor, the proverbial Undiscovered Country, "from whose bourn no traveler returns" .
My teacher said to my I'm a failure, that I'll never amount to anything. I scoffed at him. Shocked, my teacher asked what's so funny, my future is on the line. "Well...you see professor" I say as the teacher prepares to laugh at my answer, rebuttal at hand. "I watch Rick and Morty." The class is shocked, they merely watch pleb shows like the big bang theory to feign intelligence, not grasping the humor. "...how? I can't even understand it's sheer nuance and subtlety." "Well you see...WUBBA LUBBA DUB DUB!" One line student laughs in the back, I turn to see a who this fellow genius is. It's none other than Albert Einstein.
serendipity, n.: The process by which human knowledge is advanced.
πŸ’―πŸ’―πŸ’―πŸ’― RED πŸ”΄ IS SO SUSSSSS πŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ COME πŸ’¦πŸƒπŸƒβ€β™€οΈ TO MEDBAY AND WATCH πŸ‘€ ME SCAN πŸ‘€ πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯ πŸ₯πŸ₯πŸ₯πŸ₯ WHY πŸ˜‘πŸ€” IS NO ⚠🚫 ONE 1️⃣ FIXING πŸ‘Ύ O2 πŸ…Ύ 🀬😑🀬😑🀬😑🀬🀬😑🀬🀬😑 OH πŸ™€ YOUR πŸ‘‰ CREWMATE?
NAME πŸ“› EVERY πŸ’― TASK πŸ“‹ πŸ”«πŸ˜ πŸ”«πŸ˜ πŸ”«πŸ˜ πŸ”«πŸ˜ πŸ”«πŸ˜  Where Any sus!❓ ❓ Where!❓ ❓ Where! Any sus!❓ Where! ❓ Any sus!❓ ❓ Any sus πŸŒˆπŸ³οΈβ€πŸŒˆ! ❓ ❓ ❓ ❓ Where!Where!Where! Any sus!Where!Any sus πŸŒˆπŸ³οΈβ€πŸŒˆ Where!❓ Where! ❓ Where!Any sus❓ ❓ Any sus πŸ’¦! ❓ ❓ ❓ ❓ ❓ ❓ Where! ❓ Where! ❓ Any sus!❓ ❓ ❓ ❓
Any sus πŸŒˆπŸ³οΈβ€πŸŒˆ! ❓ ❓ Where!❓ Any sus πŸ’¦! ❓ ❓ Where!❓ ❓ Where! ❓ Where!Where! ❓ ❓ ❓ ❓ ❓ ❓ ❓ Any sus!❓ ❓ ❓ Any sus!❓ ❓ ❓ ❓ Where! ❓ Where! Where!Any sus!Where! Where! ❓ ❓ ❓ ❓ ❓ ❓
I πŸ‘₯ think πŸ€” it was purple!πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€It wasnt me I πŸ‘ was in vents!!!!!!!!!!!!!!πŸ˜‚πŸ€£πŸ˜‚πŸ€£πŸ˜‚πŸ€£πŸ˜‚πŸ˜‚πŸ˜‚πŸ€£πŸ€£πŸ€£πŸ˜‚πŸ˜‚πŸ˜‚
πŸ’―πŸ’―πŸ’―πŸ’― RED πŸ”΄ IS SO SUSSSSS πŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸ•΅οΈπŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯πŸŸ₯ COME πŸ’¦πŸƒπŸƒβ€β™€οΈ TO MEDBAY AND WATCH πŸ‘€ ME SCAN πŸ‘€ πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯πŸ₯ πŸ₯πŸ₯πŸ₯πŸ₯ WHY πŸ˜‘πŸ€” IS NO ⚠🚫 ONE 1️⃣ FIXING πŸ‘Ύ O2 πŸ…Ύ 🀬😑🀬😑🀬😑🀬🀬😑🀬🀬😑 OH πŸ™€ YOUR πŸ‘‰ CREWMATE? NAME πŸ“› EVERY πŸ’― TASK πŸ“‹ πŸ”«πŸ˜ πŸ”«πŸ˜ πŸ”«πŸ˜ πŸ”«πŸ˜ πŸ”«πŸ˜  Where Any sus!❓ ❓ Where!❓ ❓ Where! Any sus!❓ Where! ❓ Any sus!❓ ❓ Any sus πŸŒˆπŸ³οΈβ€πŸŒˆ! ❓ ❓ ❓ ❓ Where!Where!Where! Any sus!Where!Any sus πŸŒˆπŸ³οΈβ€πŸŒˆ Where!❓ Where! ❓ Where!Any sus❓ ❓ Any sus πŸ’¦! ❓ ❓ ❓ ❓ ❓ ❓ Where! ❓ Where! ❓ Any sus!❓ ❓ ❓ ❓ Any sus πŸŒˆπŸ³οΈβ€πŸŒˆ! ❓ ❓ Where!❓ Any sus πŸ’¦! ❓ ❓ Where!❓ ❓ Where! ❓ Where!Where! ❓ ❓ ❓ ❓ ❓ ❓ ❓ Any sus!❓ ❓ ❓ Any sus!❓ ❓ ❓ ❓ Where! ❓ Where! Where!Any sus!Where! Where! ❓ ❓ ❓ ❓ ❓ ❓ I πŸ‘₯ think πŸ€” it was purple!πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€πŸ‘€It wasnt me I πŸ‘ was in vents!!!!!!!!!!!!!!πŸ˜‚πŸ€£πŸ˜‚πŸ€£πŸ˜‚πŸ€£πŸ˜‚πŸ˜‚πŸ˜‚πŸ€£πŸ€£πŸ€£πŸ˜‚πŸ˜‚πŸ˜‚
No they're not paying me; they're not paying me to keep my mouth shut.🀐 I'm not gonna, I'm not just gonna sit here and be like, "Oh this, none of this happened," okay. βœ…
One Adult Swim executive πŸ‘ƒ (who shall remain nameless) that is recording πŸ”΄ adult women πŸ‘© taking a shit πŸ’© that he's paying for. She's blowing me and I'm digging in her in messy-ass pubic hair, she's got pubes about this long. 🀏
All, every wall -- every wall covered in images of children. There were two executives giggling doing coke, uh... There's a lot of satanic shit. I hope he fucking πŸ‘»πŸͺ¦βš°. I told him I was gonna make this video. I asked him if he wanted to make a comment,
he basically told me that he didn't want me doing any stuff. There's no chance corporate would stand for it. And I most certainly am not gonna cosign them with my silence if anything breaks out. @#!@$ these people!
It's like a known thing that $&($&$$(*$^ can't get hard if the girls over 18.
No they're not paying me; they're not paying me to keep my mouth shut.🀐 I'm not gonna, I'm not just gonna sit here and be like, "Oh this, none of this happened," okay. βœ… One Adult Swim executive πŸ‘ƒ (who shall remain nameless) that is recording πŸ”΄ adult women πŸ‘© taking a shit πŸ’© that he's paying for. She's blowing me and I'm digging in her in messy-ass pubic hair, she's got pubes about this long. 🀏 All, every wall -- every wall covered in images of children. There were two executives giggling doing coke, uh... There's a lot of satanic shit. I hope he fucking πŸ‘»πŸͺ¦βš°. I told him I was gonna make this video. I asked him if he wanted to make a comment, he basically told me that he didn't want me doing any stuff. There's no chance corporate would stand for it. And I most certainly am not gonna cosign them with my silence if anything breaks out. @#!@$ these people! It's like a known thing that $&($&$$(*$^ can't get hard if the girls over 18.
There's no chance corporate would stand for it. He gives me the old "Please don't do this, but if you feel that you really need to, then I guess you must." That old line. That's what you tell a girl when you want her to not do something.
That works all the time, right? Yeah. Well, I do feel like I need to do this cuz I don't wanna get (you know) people pissed at me. If your people, if your f**king f*g**t pedophile Dan Harmon and f*g**t pedophile Eric Wareheim get busted for doing something.
I'm not going to be the guy that was at Adult Swim and didn't say another executive -- okay well -- talks about how he's hired so many women because it helps them get away with murder. That's a direct quote.
There's no chance corporate would stand for it. He gives me the old "Please don't do this, but if you feel that you really need to, then I guess you must." That old line. That's what you tell a girl when you want her to not do something. That works all the time, right? Yeah. Well, I do feel like I need to do this cuz I don't wanna get (you know) people pissed at me. If your people, if your f**king f*g**t pedophile Dan Harmon and f*g**t pedophile Eric Wareheim get busted for doing something. I'm not going to be the guy that was at Adult Swim and didn't say another executive -- okay well -- talks about how he's hired so many women because it helps them get away with murder. That's a direct quote.
So now I think they give these women these sort of title positions and they don't have them do anything. I'm not a white knight; my opinion of women very low, my regard with women generally is... If Matt Forney is right here, I'm right about right here, okay.
RICK STUMBLES IN DRUNKENLY, AND TURNS ON THE LIGHTS. Morty! You gotta come on. Jus'... you gotta come with me.
@ -115,3 +64,9 @@ Shut the f*** up Jerry
The wind has something to say
...(whisper)-looser...
Rick and Morty is not the motherf***ing show that got you into a motherf***ing Tesla business you can tell Elon tusk to go grab his f****** front two tusks and scrape it against the f****** wall
It’s the present, future, and progress. Racism, Ageism, and Genderism is over. I love it.
This world isn’t a dead end joke. This is the one where true love won.
Congratulations. This was your choice as well as everyones.
Heaven on earth for all.
Thank you! I love you always, God.

17
pseudbot/cli.py

@ -72,10 +72,21 @@ def main(args: [str], name: str) -> int:
tcfg = j.loads(opts.cfg_json.read())["twitter"]
if opts.action == "run_bot":
pb = PseudBot(tcfg=tcfg, proxy_url=opts.proxy_url, debug=opts.debug)
pb = PseudBot(
tcfg=tcfg,
last_id=opts.reply_to_id,
proxy_url=opts.proxy_url,
debug=opts.debug,
)
elif opts.action == "list_actions":
pb = PseudBot(tcfg=tcfg, quiet=True, debug=opts.debug)
elif opts.action in ("pasta_tweet", "dump_tweet"):
elif opts.action in (
"pasta_tweet",
"dump_tweet",
"run_cmd_tweet",
"get_tweet_parents",
"test_parser",
):
if opts.reply_to_id is not None:
pb = PseudBot(
tcfg=tcfg,
@ -96,6 +107,7 @@ def main(args: [str], name: str) -> int:
pb = PseudBot(
tcfg=tcfg,
custom_welcome=custom_welcome,
last_id=opts.reply_to_id,
target_screen_name=opts.screen_name,
proxy_url=opts.proxy_url,
debug=opts.debug,
@ -110,6 +122,7 @@ def main(args: [str], name: str) -> int:
pb = PseudBot(
tcfg=tcfg,
custom_welcome=custom_welcome,
last_id=opts.reply_to_id,
proxy_url=opts.proxy_url,
debug=opts.debug,
)

89
pseudbot/command.py

@ -0,0 +1,89 @@
import random
import re
from .media import MEDIA
from .pastas import PASTAS
class Command:
def __init__(self, text: str, debug: bool = False):
self.text = re.sub(r"[\ufe0f]", "", text, re.UNICODE)
self.debug = debug
self.pasta = ""
self.media = []
self.target = None
self.error = False
self.reasons = []
self.parse()
def parse(self):
words = re.split(r'[\s.;():"]+', self.text, re.UNICODE)
if len(words[-1]) < 1:
words.pop()
if self.debug is True:
print('[DEBUG]: [WORDS]: "{}"'.format(words))
lexed = {
"all": [],
"media": [],
"url_media": [],
"soyphone": [],
}
do_pasta = True
for i in range(len(words)):
if words[i] == "πŸ–Ό":
lexed["media"].append(i)
lexed["all"].append(i)
media_category = ""
try:
media_category = words[i + 1]
i += 1
except IndexError:
do_pasta = False
break
if media_category in MEDIA:
self.media.append(random.choice(MEDIA[media_category]))
else:
self.error = True
self.reasons = 'Could not find media category: "{}"'.format(
media_category
)
if words[i] == "😲🀳":
lexed["soyphone"].append(i)
lexed["all"].append(i)
if len(self.media) == 0 and len(self.text) == 0:
do_pasta = True
if self.debug is True:
print("[DEBUG]: do_pasta: {}".format(do_pasta))
if do_pasta is True:
self.pick_pasta()
def pick_pasta(self):
while len(self.pasta) < 1:
self.pasta = random.choice(PASTAS)
def mk_commands(text: str, debug: bool = False) -> [Command]:
commands = []
split_input = text.split("|")
if debug is True:
print("[DEBUG]: split command input: {}".format(split_input))
for command_string in split_input:
commands.append(Command(text=command_string, debug=debug))
if debug is True:
print('[DEBUG]: self.pasta = "{}"'.format(commands[-1].pasta))
print("[DEBUG]: self.media = {}".format(commands[-1].media))
return commands

0
pseudbot/meme/__init__.py

145
pseudbot/meme/abc.py

@ -0,0 +1,145 @@
from abc import ABCMeta, abstractmethod
from PIL import Image, ImageDraw, ImageFont
import typing
from pseudbot.pastas import concat_pasta
from pseudbot.util import styled_wrap, text_wrap
class Meme(metaclass=ABCMeta):
fonts = {
"old_console": "font/clacon.ttf",
"phone_sans": "font/Cantarell-VF.otf",
}
styles = {}
style_methods = {}
offsets = {}
error = False
image = None
reason = ""
post = None
posts = None
def __init__(
self,
top_text: dict = None,
bottom_text: str = None,
):
self.top_text = top_text
self.bottom_text = bottom_text
def init_style_posts(self):
self.check_posts()
self.check_style()
def check_posts(self):
if not "posts" in self.top_text or len(self.top_text["posts"]) < 1:
self.error = True
self.reason = 'No "posts" in top_text!'
else:
self.posts = self.top_text["posts"]
self.post = self.top_text["posts"][0]
if not "screen_name" in self.post:
self.post["screen_name"] = "⁉"
if not "text" in self.post:
self.post["text"] = concat_pasta()
if not "timestamp" in self.post:
self.post["timestamp"] = "Today at time"
def check_style(self):
if self.style not in self.styles:
self.error = True
self.reason = "Invalid style!"
elif self.style not in self.style_methods:
self.error = True
self.reason = "Style not implemented!"
@abstractmethod
def help(self) -> str:
"""
User-callable help for meme generator.
"""
pass
@abstractmethod
def mk_pixmap(self):
pass
def get_styles(self) -> [str]:
return self.styles
def help(self) -> str:
"""
User-callable help for meme generator.
"""
return "TODO"
def get_text(self) -> tuple:
return (self.top_text, self.bottom_text)
def get_pixmap(self):
if self.image is None:
if self.error is True:
return self.error_pixmap(reason=self.reason)
else:
self.mk_pixmap()
return self.image
def draw_styled_text(
self, img: Image, text: str, style: dict, offset: tuple = None
) -> Image:
if offset is None:
offset = style["offset"]
if "wrap" in style:
text = styled_wrap(text, style["wrap"])
align = style["align"] if "align" in style else "left"
image = self.draw_text(
img=img,
text=text,
offset=offset,
size=style["size"],
fill=style["color"],
variation=style["style"],
fontname=style["font"],
align=align,
)
return image
def draw_text(
self,
img: Image,
text: str,
offset: tuple,
size: int,
fill: tuple,
variation: str = "Regular",
fontname: str = "phone_sans",
align="left",
) -> Image:
font = ImageFont.truetype(self.fonts[fontname], size)
font.set_variation_by_name(variation)
d = ImageDraw.Draw(img)
d.text(xy=offset, text=text, fill=fill, font=font, align=align)
return img
def error_pixmap(self, reason: str) -> Image:
efont = ImageFont.truetype("font/clacon.ttf", 70)
reason = text_wrap(text=reason, width=16, height=5)
with Image.open("img/pseud-error.png").convert("RGBA") as base_img:
text_img = Image.new("RGBA", base_img.size, (255, 255, 255, 0))
d = ImageDraw.Draw(text_img)
d.text((292, 466), reason, font=efont, fill=(0, 0, 0, 255))
out = Image.alpha_composite(base_img, text_img)
return out

184
pseudbot/meme/phone_screenshot.py

@ -0,0 +1,184 @@
from .abc import Meme
from PIL import Image, ImageDraw, ImageFont
import typing
from pseudbot.meme.post import Post
from pseudbot.util import (
alpha_comp_prep,
circle_pfp,
get_iphone_time_s,
text_wrap,
tuple_add,
)
class PhoneScreenshot(Meme):
from .post_styles import styles, time_style
def __init__(
self,
top_text: dict = None,
bottom_text: str = None,
style: str = "discord",
width: int = 1200,
height: int = 2340,
notification: str = None,
):
self.top_text = top_text
self.bottom_text = bottom_text
self.style = style
self.width = width
self.height = height
self.notification = notification
self.style_methods = {"discord": self.mk_pixmap}
self.init_style_posts()
if self.notification is not None:
self.notification_style = {
"offset": (102, 91),
"no_text_img": "templates/iphone/iphone-noti-grindr-text.png",
"icon": {
"offset": (26, 34),
"size": (62, 62),
"files": {
"grindr": "templates/iphone/icons/notification/grindr.png"
},
},
"text": {
"app_name": {
"font": "phone_sans",
"style": "Regular",
"size": 35,
"offset": (106, 53),
},
"heading": {
"font": "phone_sans",
"style": "Regular",
"size": 35,
"offset": (34, 128),
},
"body": {
"font": "phone_sans",
"style": "Regular",
"size": 35,
"offset": (34, 181),
},
},
}
def overlay_noti(base_img: Image) -> Image:
return base_img
def mk_bars(self) -> Image:
base_img = Image.new("RGBA", (self.width, self.height), (0, 0, 0, 0))
for bar in self.styles[self.style]["bars"]:
is_top = False
is_bottom = False
do_time = False
bg_img_path = bar["bg_img"]
if "top" in bar:
if bar["top"] is True:
is_top = True
do_time = True
if self.notification is not None:
do_time = False
if "alt_bg_img" in bar:
bg_img_path = self.bar["alt_bg_img"]
if "bottom" in bar:
if bar["bottom"] is True:
is_bottom = True
with Image.open(bg_img_path).convert("RGBA") as _bar_img:
with alpha_comp_prep(
Image.open(bg_img_path).convert("RGBA"),
size=base_img.size,
offset=bar["offset"],
) as bar_img:
if "text" in bar:
try:
if bar["text"]["content"] in self.top_text:
if "format" in bar["text"]:
bar_text = bar["text"]["format"].replace(
"%%%",
self.top_text[bar["text"]["content"]],
)
else:
bar_text = self.top_text[
bar["text"]["content"]
]
else:
bar_text = bar["text"]["default"]
except KeyError:
bar_text = "default text"
bar_img = self.draw_text(
img=bar_img,
text=bar_text,
offset=tuple_add(
bar["text"]["offset"], bar["offset"]
),
size=bar["text"]["size"],
fill=bar["text"]["color"],
variation=bar["text"]["style"],
fontname=bar["text"]["font"],
)
if do_time is True:
bar_img = self.draw_text(
img=bar_img,
text=get_iphone_time_s(),
offset=self.time_style["offset"],
size=self.time_style["size"],
fill=self.time_style["fill"][self.style],
variation=self.time_style["style"],
fontname=self.time_style["font"],
)
base_img = Image.alpha_composite(base_img, bar_img)
if is_bottom is True:
self.bottom_y_offset = 0 - _bar_img.size[1]
if self.notification is not None:
base_img = self.overlay_noti(base_img)
return base_img
def arrange_posts(self) -> Image:
post_base = Image.new(
"RGBA",
(self.width, self.height),
self.styles[self.style]["background"],
)
x_offset = 33
y_offset = self.height
if hasattr(self, "bottom_y_offset"):
y_offset = y_offset + self.bottom_y_offset
for post in reversed(self.posts):
p = Post(
top_text={"posts": [post]},
bottom_text=self.bottom_text,
style=self.style,
)
post_img = p.get_pixmap()
y_offset = y_offset - post_img.size[1]
post_base.paste(post_img, box=(x_offset, y_offset))
if y_offset < 0:
break
return post_base
def mk_pixmap(self):
bars = self.mk_bars() # Must be done before making posts!
posts = self.arrange_posts()
self.image = Image.alpha_composite(posts, bars)

126
pseudbot/meme/post.py

@ -0,0 +1,126 @@
from .abc import Meme
from PIL import Image, ImageDraw, ImageFont
import typing
from pseudbot.util import (
_text_wrap,
alpha_comp_prep,
circle_pfp,
styled_wrap,
text_wrap,
tuple_add,
)
class Post(Meme):
from .post_styles import styles
def __init__(
self,
top_text: dict = None,
bottom_text: str = None,
style: str = "discord",
):
self.top_text = top_text
self.bottom_text = bottom_text
self.style = style
self.style_methods = {"discord": self.draw_discord_post}
self.init_style_posts()
def get_post_dimens(self) -> int:
max_dimens = (0, 0)
offsets_add = {}
post_items = dict(
sorted(
self.styles[self.style]["fields"].items(),
key=lambda s: s[1]["offset"][1],
)
)
while len(post_items) > 0:
items = [k for k in post_items.keys()]
for k in items:
offset_add = (0, 0)
if "offset_add" in post_items[k]:
if k in offsets_add:
offset_add = offsets_add[k]
else:
continue
if k not in self.post:
if "default" in post_items[k]:
self.post[k] = post_items[k]["default"]
else:
self.post[k] = "default text"
wrap = post_items[k]["wrap"]
lines = _text_wrap(self.post[k], wrap[0], wrap[1])
font = ImageFont.truetype(
self.fonts[post_items[k]["font"]], post_items[k]["size"]
)
size = font.getsize("\n".join(lines))
if len(lines) > 1:
size = (size[0], size[1] * len(lines))
offset = tuple_add(post_items[k]["offset"], offset_add)
_max_dimens = tuple_add(offset, size)
max_dimens = (
max(_max_dimens[0], max_dimens[0]),
max(_max_dimens[1], max_dimens[1]),
)
if "offset_for" in post_items[k]:
for dependent in post_items[k]["offset_for"]:
add_x = 0
add_y = 0
if "x" in post_items[k]["offset_for"][dependent]:
add_x = _max_dimens[0]
if "y" in post_items[k]["offset_for"][dependent]:
add_y = _max_dimens[1]
offsets_add[dependent] = (add_x, add_y)
self.offsets[k] = offset
post_items.pop(k)
max_dimens = tuple_add(max_dimens, self.styles[self.style]["margin"])
return max_dimens
def draw_post(self) -> Image:
pass
def draw_discord_post(self) -> Image:
pfp_size = 132
if self.error is True:
return self.error_pixmap(self.reason)
else:
dimens = self.get_post_dimens()
post_base = Image.new(
"RGBA", dimens, self.styles[self.style]["background"]
)
# Draw circle profile pic
with alpha_comp_prep(
circle_pfp(
Image.open(self.post["pfp"]).convert("RGBA"),
size=pfp_size,
),
size=post_base.size,
) as pfp:
post_base = Image.alpha_composite(post_base, pfp)
for field in self.styles[self.style]["fields"].keys():
post_base = self.draw_styled_text(
img=post_base,
text=self.post[field],
style=self.styles[self.style]["fields"][field],
offset=self.offsets[field],
)
return post_base
def mk_pixmap(self):
self.image = self.style_methods[self.style]()

81
pseudbot/meme/post_styles.py

@ -0,0 +1,81 @@
styles = {
"discord": {
"margin": (0, 43),
"fields": {
"screen_name": {
"font": "phone_sans",
"style": "Extra Bold",
"offset": (169, 0),
"size": 59,
"color": (255, 255, 255, 255),
"default": "XxX_HungDaddy_XxX_69",
"offset_for": {
"timestamp": "x",
"text": "y",
},
"wrap": (30, 1),
},
"text": {
"font": "phone_sans",
"style": "Regular",
"offset": (169, 2),
"offset_add": True,
"size": 59,
"color": (255, 255, 255, 255),
"wrap": (40, 20),
},
"timestamp": {
"font": "phone_sans",
"style": "Regular",
"offset": (66, 17),
"offset_add": True,
"size": 35,
"color": (112, 115, 122, 255),
"default": "Today at 5:07 AM",
"wrap": (30, 1),
},
},
"background": (54, 57, 64, 255),
"bars": [
{
"top": True,
"bg_img": "templates/discord-phone/discord-heading-notxt-no-notification-notime.png",
"alt_bg_img": "templates/discord-phone/discord-heading-notxt.png",
"offset": (0, 0),
"text": {
"font": "phone_sans",
"style": "Bold",
"offset": (286, 174),
"size": 58,
"color": (255, 255, 255, 255),
"content": "channel_name",
"default": "chat",
},
},
{
"bottom": True,
"bg_img": "templates/discord-phone/discord-iphone-bottom-bar.png",
"offset": (0, 2080),
"text": {
"font": "phone_sans",
"style": "Regular",
"offset": (380, 62),
"size": 49,
"color": (112, 115, 122, 255),
"format": "Message #%%%",
"content": "channel_name",
"default": "Message #chat",
},
},
],
},
"twitter": {},
}
time_style = {
"size": 54,
"offset": (48, 38),
"font": "phone_sans",
"style": "Bold",
"fill": {"discord": (255, 255, 255, 255)},
}

35
pseudbot/meme/soyphone.py

@ -0,0 +1,35 @@
from .abc import Meme
from PIL import Image
import typing
from pseudbot.util import alpha_comp_prep
class SoyPhone(Meme):
def __init__(
self,
screenshot: Image = None,
):
self.screenshot = screenshot
if self.screenshot is None:
self.error = True
self.reason = 'No "screenshot" provided for iPhone!'
def mk_pixmap(self):
with Image.open("templates/soyphone/soyphone-13.png").convert(
"RGBA"
) as overlay_img:
self.image = Image.new("RGBA", overlay_img.size, (0, 0, 0, 255))
self.screenshot = self.screenshot.resize(
(378, 804), resample=Image.BICUBIC
)
self.screenshot = self.screenshot.rotate(
4.8, resample=Image.BICUBIC, expand=True
)
self.screenshot = alpha_comp_prep(
self.screenshot, size=overlay_img.size, offset=(27, 32)
)
overlay_img = Image.alpha_composite(self.screenshot, overlay_img)
self.image = Image.alpha_composite(self.image, overlay_img)

8
pseudbot/pastas.py

@ -6,10 +6,12 @@ def get_pastas() -> list:
pastas = pfile.read().split("\n\n")
pfile.close()
for n in range(len(pastas)):
pastas[n] = pastas[n].split("\n")
return pastas
PASTAS = get_pastas()
# TODO: make random picker only, rename
def concat_pasta(sep: str = " "):
return sep.join([random.choice(PASTAS)])

208
pseudbot/tweet_bot.py

@ -1,14 +1,13 @@
import random
import re
from sys import stderr
from textwrap import indent
from textwrap import wrap
from time import sleep, time
import tweepy as t
from tweepy.errors import Forbidden, TooManyRequests
import typing
from .command import Command, mk_commands
from .exceptions import *
from .media import MEDIA
from .pastas import PASTAS
from .util import (
get_timestamp_s,
@ -27,12 +26,14 @@ class PseudBot:
tcfg: dict,
custom_welcome: str = None,
last_id: int = None,
reply_all: bool = True,
target_screen_name: str = None,
proxy_url: str = None,
quiet: bool = False,
debug: bool = False,
):
self.debug = debug
self.reply_all = True
tauth = t.OAuthHandler(tcfg["consumer"], tcfg["consumer_secret"])
tauth.set_access_token(tcfg["tok"], tcfg["tok_secret"])
@ -130,12 +131,14 @@ class PseudBot:
jdump(jsons, extra_tag=self.screen_name)
def _tweet_media(
self, id_reply_to: int, parent_screen_name: str, media: [str] = []
self, id_reply_to: int, parent_screen_names: str, media: [str] = []
):
_stat = self.last_stat
if self.debug is True:
print("[DEBUG]: _tweet_media's media: {}".format(media))
try:
self.last_stat = self.tapi.update_status_with_media(
"@" + parent_screen_name,
parent_screen_names,
in_reply_to_status_id=id_reply_to,
filename=media.pop(0),
)
@ -144,8 +147,18 @@ class PseudBot:
if len(media) > 0:
sleep(2)
parent_screen_names = (
parent_screen_names
if parent_screen_names.startswith(
"@" + self.last_stat.user.screen_name
)
else "@"
+ self.last_stat.user.screen_name
+ " "
+ parent_screen_names
)
return self._tweet_media(
self.last_stat.id, self.last_stat.user.screen_name, media
self.last_stat.id, parent_screen_names, media
)
else:
return self.last_stat
@ -172,7 +185,6 @@ class PseudBot:
except Forbidden:
return _stat
if len(pasta) > 0:
pasta[0] = "@" + self.last_stat.user.screen_name + " " + pasta[0]
sleep(2)
return self._tweet_pasta(self.last_stat.id, pasta, media)
else:
@ -230,14 +242,15 @@ class PseudBot:
jdump(tweets_j)
def dump_tweet(self):
def dump_tweet(self, status_id: int = None):
"""
Dump the JSON data dictionary of a specific tweet.
If called from the CLI, requires ``-i`` to be set.
"""
tweets = self.tapi.lookup_statuses(
[self.last_id], tweet_mode="extended"
)
if status_id is None:
status_id = self.last_id
tweets = self.tapi.lookup_statuses([status_id], tweet_mode="extended")
jtweets = []
for tweet in tweets:
log_t_by_sname(tweet)
@ -247,13 +260,30 @@ class PseudBot:
def pasta_tweet(self):
"""
Insert a copy pasta in a Tweet chain manually starting from a specific
Insert a copy pasta in a Tweet chain manually under a specific
tweet ID. Requires ``-i`` to be set if calling from the CLI.
"""
pasta = []
tweet = self.tapi.lookup_statuses(
[self.last_id], tweet_mode="extended"
)[0]
parents = self._get_reply_parents(tweet)
parent_screen_names = " ".join(list(map(lambda p: "@" + p[1], parents)))
pasta = ""
while len(pasta) < 1:
pasta = random.choice(PASTAS)
noodles = self._make_pasta_chain(parent_screen_names, pasta)
self._tweet_pasta(self.last_id, noodles)
print("[INFO]: Inserting pasta under {}...".format(self.last_id))
def run_cmd_tweet(self):
"""
Parse a specific tweet for a command and post specified pasta(s).
Requires ``-i`` to be set if calling from the CLI.
"""
print("[INFO]: Replying to {}...".format(self.last_id))
tweets = self.tapi.lookup_statuses(
[self.last_id], tweet_mode="extended"
@ -261,88 +291,144 @@ class PseudBot:
for tweet in tweets:
self._parse_mention(tweet)
def _get_reply_parent(self, tweet) -> (int, str):
def get_tweet_parents(self):
"""
Print the parent tuple list (parent_id, reply_to_screen_name).
Requires ``-i`` to be set if calling from the CLI.
"""
print(
self._get_reply_parents(
self.tapi.lookup_statuses(
[self.last_id], tweet_mode="extended"
)[0]
)
)
def _get_reply_parents(self, tweet) -> [(int, str)]:
"""
Builds and returns the parent tuple list from a starting tweet:
(parent_id, reply_to_screen_name)
"""
if tweet.in_reply_to_screen_name is not None:
if tweet.in_reply_to_screen_name != self.screen_name:
parent_name = tweet.in_reply_to_screen_name
else:
parent_name = None
print(
"[INFO]: Replying to {}'s mention ".format(
"[INFO]: Replying to {}'s mention directly...".format(
tweet.user.screen_name
)
+ "instead of replying to myself..."
)
else:
parent_name = None
parents = []
if tweet.in_reply_to_status_id is not None and parent_name is not None:
reply_to_screen_name = tweet.in_reply_to_screen_name
parent_id = tweet.in_reply_to_status_id
parents = parents + self._get_reply_parents(
tweet=self.tapi.lookup_statuses(
[tweet.in_reply_to_status_id], tweet_mode="extended"
)[0]
)
else:
reply_to_screen_name = tweet.user.screen_name
parent_id = tweet.id
return (parent_id, reply_to_screen_name)
parents = [(parent_id, reply_to_screen_name)] + parents
def _parse_mention(self, tweet):
"""
Parse commands in tweet and do something
"""
(parent_id, parent_screen_name) = self._get_reply_parent(tweet)
text = get_tweet_text(tweet)
for command_string in text.split("|"):
words = re.split(r'[\s.;():"]+', command_string)
if len(words[-1]) < 1:
words.pop()
if self.debug is True:
print(words)
return parents
media = []
do_pasta = True
stupid_emoji = "πŸ–Ό" + b"\xef\xb8\x8f".decode()
if stupid_emoji in words or "πŸ–Ό" in words:
for i in range(len(words)):
if words[i] in ("πŸ–Ό", stupid_emoji):
try:
media_category = words[i + 1]
i += 1
except IndexError:
do_pasta = False
break
if media_category in MEDIA:
media.append(random.choice(MEDIA[media_category]))
def test_parser(self):
"""
Run the command parser in a dry run (e.g. without sending any tweets) on
a specific tweet.
if len(media) == 0:
do_pasta = True
Requires ``-i`` to be set if calling from the CLI.
"""
self._parse_mention(
self.tapi.lookup_statuses([self.last_id], tweet_mode="extended")[0],
wet_run=False,
)
if do_pasta is True:
pasta = self._make_pasta_chain(parent_screen_name)
self._tweet_pasta(parent_id, pasta, media)
elif len(media) > 0:
self._tweet_media(parent_id, parent_screen_name, media)
def _parse_mention(self, tweet, wet_run: bool = True):
"""
Parse commands in tweet and do something
"""
# Each parent in the list is a (parent_id, parent_screen_name) tuple.
parents = self._get_reply_parents(tweet)
parent_screen_names = " ".join(list(map(lambda p: "@" + p[1], parents)))
drybug = False if wet_run is True else True
if self.debug is True:
jdump(tweet._json, extra_tag="{}.debug".format(tweet.id))
drybug = True
commands = mk_commands(get_tweet_text(tweet), debug=drybug)
for ci in range(len(commands)):
command = commands[ci]
pasta = []
if len(command.pasta) > 0:
pasta = self._make_pasta_chain(
parent_screen_names, command.pasta
)
if wet_run is True:
self._tweet_pasta(parents[0][0], pasta, command.media)
else:
print("[DRY]: pasta: {}".format(pasta))
print("[DRY]: Such wow, very tweet!")
elif len(command.media) > 0:
if wet_run is True:
media = command.media
self._tweet_media(parents[0][0], parent_screen_names, media)
else:
# TODO: show media in dry mode?
print("[DRY]: Such wow, very media!")
else:
print(
'[WARN]: Unable to parse tweet segment: "{}"'.format(
command_string
command.text
),
file=stderr,
)
if self.debug is True:
print(
"[DEBUG]: error parsing text from "
+ "commands[{}]. ".format(ci)
+ "text: {}".format(
list(map(lambda c: c.text, commands))
)
)
self.dump_tweet(status_id=tweet.id)
def _make_pasta_chain(self, parent_screen_name: str) -> [str]:
def _make_pasta_chain(self, parent_screen_names: str, in_txt: str) -> [str]:
"""
Send a copypasta chain.
Make a text reply chain.
"""
pasta = []
while len(pasta) < 1:
pasta = random.choice(PASTAS)
pasta[0] = "@" + parent_screen_name + " " + pasta[0]
in_pasta = wrap(parent_screen_names + " " + in_txt, width=280)
pasta.append(in_pasta.pop(0))
while len(in_pasta) > 0:
tmp_pasta = wrap(
"@"
+ self.screen_name
+ " "
+ parent_screen_names
+ " "
+ in_pasta.pop(0),