Advertisement
catbarrage

main.py

Dec 2nd, 2023
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.57 KB | None | 0 0
  1. """
  2. CheapBotsDoneQuick-like python bot for Twitter
  3.  
  4. Why? Because of the recent suspension of CBDQ API Access, I am making a script that can
  5. simulate the same behavior as the CBDQ bots. This script is obviously a very wip.
  6. JSON schemas are exactly the same as the CBDQ bots, so you can just copy and paste the
  7. JSON files from the CBDQ bots into the same directory as this script and a few script
  8. changes and you're good to go.
  9.  
  10. - GuglioIsStupid - 2023
  11. """
  12. import os, json, tweepy, time, random, requests, re, sys
  13. import PIL.Image as Image
  14. from PIL import ImageFile
  15. from PIL import ImageDraw
  16. from PIL import ImageFont
  17. import keep_alive
  18. keep_alive.keep_alive()
  19.  
  20.  
  21. # By default, there's only gonna be one picture
  22. RandomImageErrors = [
  23. "unknown.png",
  24. "unknown.png"
  25. ]
  26.  
  27.  
  28. # Twitter API Keys
  29. # You will need to include your OWN Twitter API keys in a .env file in the same directory
  30. # as this script. You can get your own Twitter API keys at https://developer.twitter.com/
  31.  
  32. # get the API keys from the cred.json file
  33. # check if the cred.json file exists
  34. if os.path.exists("cred.json"):
  35. credjson = open("cred.json", "r")
  36. credjson = json.load(credjson)
  37. consumer_key = credjson["consumer_key"]
  38. consumer_secret = credjson["consumer_secret"]
  39. access_token = credjson["access_token"]
  40. access_token_secret = credjson["access_token_secret"]
  41. bearer_token = credjson["bearer_token"]
  42. print("Using cred.json file for API keys")
  43. else:
  44. consumer_key = os.getenv("consumer_key")
  45. consumer_secret = os.getenv("consumer_secret")
  46. access_token = os.getenv("access_token")
  47. access_token_secret = os.getenv("access_token_secret")
  48. bearer_token = os.getenv("bearer_token")
  49. print("Using .env file for API keys")
  50.  
  51. cur_version = "1.0.6"
  52. # if any of the keys are missing, get them from the .env file
  53. if consumer_key == "":
  54. consumer_key = os.getenv("consumer_key")
  55. if consumer_secret == "":
  56. consumer_secret = os.getenv("consumer_secret")
  57. if access_token == "":
  58. access_token = os.getenv("access_token")
  59. if access_token_secret == "":
  60. access_token_secret = os.getenv("access_token_secret")
  61. if bearer_token == "":
  62. bearer_token = os.getenv("bearer_token")
  63.  
  64. # Use twitter api V2
  65. Client = tweepy.Client(bearer_token=bearer_token,
  66. consumer_key=consumer_key,
  67. consumer_secret=consumer_secret,
  68. access_token=access_token,
  69. access_token_secret=access_token_secret
  70. )
  71. auth = tweepy.OAuth1UserHandler(consumer_key,
  72. consumer_secret,
  73. access_token,
  74. access_token_secret
  75. )
  76. # for media upload
  77. api = tweepy.API(auth, wait_on_rate_limit=True)
  78.  
  79. # Verify Credentials
  80. try:
  81. api.verify_credentials()
  82. print("Authentication OK")
  83. except:
  84. print("Error during authentication")
  85. sys.exit()
  86.  
  87. # The time between every new tweet
  88. # This is in seconds, so 3600 is 1 hour
  89. # Default is 30 minutes
  90. # You can change this to whatever you want, but I recommend keeping it at 30-60 minutes
  91. time_between_tweets = 3600
  92.  
  93. # read bot.json
  94. botjson = open("bot.json", "r", encoding="utf-8")
  95. botjson = json.load(botjson)
  96.  
  97. global blahList
  98. global mediaIDs
  99. global imgList
  100. global otherList
  101. global videoList
  102. blahList = []
  103. mediaIDs = []
  104. imgList = []
  105. otherList = []
  106. videoList = []
  107. numList = []
  108.  
  109. grayscale = False
  110. imgToGray = ""
  111.  
  112. global uppercase
  113. global lowercase
  114.  
  115. uppercase = False
  116. lowercase = False
  117.  
  118. def divide_string(string, DivisonAmount:int = 3):
  119. length = len(string)
  120. # change the value to change the amount of divisons you want
  121.  
  122. if length % DivisonAmount == 0:
  123. return [string[i:i+length//3] for i in range(0, length, length//3)]
  124. elif length % DivisonAmount == 1:
  125. return [string[:length//3+1], string[length//3+1//3*2], string[length//3+1//3*2+1:]]
  126. else:
  127. return [string[:length//3+2], string[length//3+2:length//3*2+2], string[length//3*2+2:]]
  128.  
  129.  
  130. def resetLists():
  131. blahList.clear()
  132. mediaIDs.clear()
  133. imgList.clear()
  134. otherList.clear()
  135. videoList.clear()
  136. numList.clear()
  137.  
  138. def generateTweet():
  139. tweet = random.choice(botjson["origin"])
  140. resetLists()
  141.  
  142. # get all the #blah# in the tweet,can also be given as a lowercase, uppercase, numbers, special characters, spaces, etc
  143. for blah in re.findall(r"#[a-zA-Z0-9]+#", tweet):
  144. blahList.append(blah)
  145.  
  146. # check if {grayscale} is anywhere in the tweet
  147. '''
  148. if "{grayscale}" in tweet:
  149. grayscale = True
  150. tweet = tweet.replace("{grayscale}", "")
  151. else:
  152. grayscale = False
  153. '''
  154. grayscale = False
  155. imgToGray = ""
  156. global uppercase, lowercase
  157.  
  158. lowercase = False # sets all the text to lowercase
  159. uppercase = False # sets all the text to uppercase
  160.  
  161. for lowercase_ in re.findall(r"{lowercase}", tweet):
  162. lowercase = True
  163. tweet = tweet.replace(lowercase_, "")
  164.  
  165. for uppercase_ in re.findall(r"{uppercase}", tweet):
  166. uppercase = True
  167. tweet = tweet.replace(uppercase_, "")
  168.  
  169. # replace the #blah# with a random word from the blah array
  170. for blah in blahList:
  171. choice = random.choice(botjson[blah[1:-1]])
  172.  
  173. while choice in otherList:
  174. choice = random.choice(botjson[blah[1:-1]])
  175.  
  176. otherList.append(choice)
  177.  
  178. print(tweet, blah, choice)
  179. tweet = tweet.replace(blah, choice, 1)
  180.  
  181. # check if theres another #blah# in the tweet, can be character, item, etc
  182. if re.findall(r"#[a-zA-Z0-9]+#", tweet):
  183. for blah in re.findall(r"#[a-zA-Z0-9]+#", tweet):
  184. choice = random.choice(botjson[blah[1:-1]])
  185.  
  186. while choice in otherList:
  187. choice = random.choice(botjson[blah[1:-1]])
  188.  
  189. otherList.append(choice)
  190.  
  191. tweet = tweet.replace(blah, choice, 1)
  192. #print(f"Replaced {blah} with {choice}")
  193.  
  194. # {grayscale, imgNum/all}, can be a number or all
  195. for grayscale_ in re.findall(r"{grayscale, \S+}", tweet):
  196.  
  197. grayscale = True
  198. imgToGray = str(grayscale_.split(", ")[1].replace("}", ""))
  199. tweet = tweet.replace(grayscale_, "")
  200.  
  201. # get all the {img link} in the tweet, stop at the first }, else its gonna try to do {{img link'}} and fail
  202. for img in re.findall(r"{img [^}]+}", tweet):
  203. imgList.append(img)
  204. # remove it from the tweet
  205. tweet = tweet.replace(img, "")
  206.  
  207. # get all the {vid link} in the tweet
  208. for vid in re.findall(r"{vid \S+}", tweet):
  209. videoList.append(vid)
  210. # remove it from the tweet
  211. tweet = tweet.replace(vid, "")
  212.  
  213. # {rand 1, 10} will give a random number between 1 and 10
  214. for num in re.findall(r"{rand \d+, \d+}", tweet):
  215. # generate a random number between the two numbers
  216. min_num = int(num.split(", ")[0].split("{rand ")[1])
  217. max_num = int(num.split(", ")[1].split("}")[0])
  218. num_n = random.randint(min_num, max_num)
  219. numList.append(num_n)
  220. # replace the {rand 1, 10} with the random number
  221. tweet = tweet.replace(num, str(num_n), 1)
  222.  
  223. # {grayscale, 'str lol'} # needs to have spaces, special characters, etc
  224. for divide_ in re.findall(r"{divide, [\S\s]+}", tweet):
  225. # remove the '' from the strin
  226. divided_ = divide_.replace("'", "")
  227. divided_ = divided_.replace("{divide, ", "")
  228. divided_ = divided_.replace("}", "")
  229. divided_ = divide_string(divided_)
  230. dividedConcat = ""
  231. for divided in divided_:
  232. # if its not the last item in the list, add a space
  233. if divided != divided_[-1]:
  234. dividedConcat += divided + ", "
  235. else:
  236. dividedConcat += divided
  237.  
  238. print(dividedConcat)
  239.  
  240. tweet = tweet.replace(divide_, dividedConcat)
  241.  
  242. curImg = 0
  243. # {text image, font, size, placement, text} (placement is a string, either top, middle, or bottom)
  244. # use PIL to add text to the image
  245. # everything after placement is the text
  246. for text in re.findall(r"{text \S+, \S+, \S+, \S+, '[\S\s]+'}", tweet):
  247. curImg += 1
  248. # get the text
  249. text_ = text.split("{text ")[1].split("}")[0]
  250. # get the image
  251. image = text_.split(", ")[0]
  252. # get the font
  253. font = text_.split(", ")[1]
  254. # get the font size
  255. size = int(text_.split(", ")[2])
  256. # get the placement
  257. placement = text_.split(", ")[3]
  258. # get the text
  259. text_2 = text_.split(", ")[4].replace("'", "")
  260. # download the image
  261. r = requests.get(image, allow_redirects=True)
  262. try:
  263. try:
  264. open("temp.png", "wb").write(r.content)
  265. except:
  266. image = "temp.png"
  267. open("temp.png", "wb").write(r.content)
  268. except:
  269. image = random.choice(RandomImageErrors)
  270. open("unknown.png", "wb").write(r.content)
  271. # open the image
  272. img = Image.open("temp.png")
  273.  
  274. # if grayscale is true, convert the image to grayscale
  275. if grayscale:
  276. if str(imgToGray) == "all":
  277. print("all")
  278. img = img.convert("L")
  279. elif str(imgToGray) == str(curImg):
  280. print("len")
  281. img = img.convert("L")
  282.  
  283. # get the width and height
  284. width, height = img.size
  285. # create a draw object
  286. draw = ImageDraw.Draw(img)
  287. # get the font
  288. font = ImageFont.truetype(font, size)
  289. # get the width and height of the text
  290. w, h = draw.textsize(text_2, font=font)
  291. # get the x and y coordinates
  292. if placement == "top":
  293. x = (width - w) / 2
  294. y = 0
  295. elif placement == "bottom":
  296. x = (width - w) / 2
  297. y = height - h
  298. elif placement == "topleft":
  299. x = 0
  300. y = 0
  301. elif placement == "topright":
  302. x = width - w
  303. y = 0
  304. elif placement == "bottomleft":
  305. x = 0
  306. y = height - h
  307. elif placement == "bottomright":
  308. x = width - w
  309. y = height - h
  310. else:
  311. x = (width - w) / 2
  312. y = (height - h) / 2
  313. # draw the text
  314. draw.text((x, y), text_2, font=font)
  315. # save the image
  316. img.save("temp.png")
  317. # upload the image to twitter
  318. try:
  319. media = api.media_upload("temp.png")
  320. except:
  321. media = api.media_upload(random.choice(RandomImageErrors))
  322. # add the media id to the mediaIDs list
  323. mediaIDs.append(media.media_id_string)
  324. # remove the {text image, font, size, placement, 'text'} from the tweet
  325. tweet = tweet.replace(text, "")
  326.  
  327. curImg = 0
  328.  
  329. for img in imgList:
  330. curImg += 1
  331. # download the image w/ requests
  332. image = img.split("{img ")[1]
  333. image = image.split("}")[0]
  334. image_name = image.split("/")[-1]
  335. # sometimes the image link can have a query string, so we need to remove it
  336. if "?" in image_name:
  337. image_name = image_name.split("?")[0]
  338.  
  339. r = requests.get(image, allow_redirects=True)
  340. try:
  341. try:
  342. open(image_name, "wb").write(r.content)
  343. except:
  344. image_name = "temp.png"
  345. open("temp.png", "wb").write(r.content)
  346. except:
  347. image_name = "unknown.png"
  348.  
  349. # if grayscale is true, convert the image to grayscale
  350. if grayscale:
  351. if str(imgToGray) == "all":
  352. img_ = Image.open(image_name)
  353. img_ = img_.convert("L")
  354. img_.save(image_name)
  355. elif str(imgToGray) == str(curImg):
  356. img_ = Image.open(image_name)
  357. img_ = img_.convert("L")
  358. img_.save(image_name)
  359.  
  360. # upload the image to twitter
  361. try:
  362. media = api.media_upload(image_name)
  363. except:
  364. image_name = random.choice(RandomImageErrors)
  365. media = api.media_upload(image_name)
  366. print(f"Uploaded image: {image_name}")
  367. mediaIDs.append(media.media_id)
  368.  
  369. # replace the {img link} with nothing
  370. tweet = tweet.replace(img, "")
  371.  
  372. for vid in videoList:
  373. # download the video w/ requests
  374. video = vid.split("{vid ")[1]
  375. video = video.split("}")[0]
  376. video_name = video.split("/")[-1]
  377. # sometimes the video link can have a query string, so we need to remove it
  378. if "?" in video_name:
  379. video_name = video_name.split("?")[0]
  380. r = requests.get(video, allow_redirects=True)
  381. try:
  382. try:
  383. open(video_name, "wb").write(r.content)
  384. except:
  385. video_name = "temp.mp4"
  386. open("temp.mp4", "wb").write(r.content)
  387. except:
  388. video_name = "unknown.mp4"
  389.  
  390. # upload the video to twitter
  391. media = api.media_upload(video_name)
  392. print(f"Uploaded video: {video_name}")
  393. mediaIDs.append(media.media_id)
  394.  
  395. # replace the {vid link} with nothing
  396. tweet = tweet.replace(vid, "")
  397.  
  398. return tweet
  399. now = 0
  400. while True:
  401. timer = time.time()
  402.  
  403. #print(f"Time since last tweet: {timer - (now or 0)}")
  404. if timer - (now or 0) >= time_between_tweets:
  405. try:
  406. # Check github version for every tweet
  407. r = requests.get("https://raw.githubusercontent.com/GuglioIsStupid/CBDQ-Python/master/version.txt")
  408. if r.status_code == 200:
  409. version = r.text
  410. if version != cur_version:
  411. print(f"New version available: {version}")
  412. print("Download it at https://github.com/GuglioIsStupid/CBDQ-Python")
  413. except:
  414. print("Couldn't get version from github")
  415.  
  416. # get a random tweet from the origin array
  417. tweet = generateTweet()
  418. if lowercase:
  419. tweet = tweet.lower()
  420. elif uppercase:
  421. tweet = tweet.upper()
  422. # tweet the tweet
  423. try:
  424. try:
  425. if len(mediaIDs) == 0:
  426. Client.create_tweet(text=tweet)
  427. else:
  428. Client.create_tweet(text=tweet, media_ids=mediaIDs)
  429.  
  430. print(f"Tweeted: {tweet}")
  431. except:
  432. tweet = generateTweet() # try again
  433. try:
  434. Client.create_tweet(text=tweet, media_ids=mediaIDs)
  435. print(f"Tweeted: {tweet}")
  436. except:
  437. print(f"Tweet failed: {tweet}")
  438. # print the error
  439. print(sys.exc_info()[0])
  440.  
  441. except:
  442. print(f"Tweet failed: {tweet}")
  443. # print the error
  444. print(sys.exc_info()[0])
  445.  
  446. # delete the images
  447. for image in imgList:
  448. image = image.split("{img ")[1]
  449. image = image.split("}")[0]
  450. image_name = image.split("/")[-1]
  451. # sometimes the image link can have a query string, so we need to remove it
  452. if "?" in image_name:
  453. image_name = image_name.split("?")[0]
  454. try:
  455. os.remove(image_name)
  456. except:
  457. try:
  458. os.remove("temp.png")
  459. except:
  460. print("Couldn't delete image; it probably doesn't exist")
  461.  
  462. # delete the videos
  463. for video in videoList:
  464. video = video.split("{vid ")[1]
  465. video = video.split("}")[0]
  466. video_name = video.split("/")[-1]
  467. # sometimes the video link can have a query string, so we need to remove it
  468. if "?" in video_name:
  469. video_name = video_name.split("?")[0]
  470. try:
  471. os.remove(video_name)
  472. except:
  473. try:
  474. os.remove("temp.mp4")
  475. except:
  476. print("Couldn't delete video; it probably doesn't exist")
  477. now = time.time()
  478. else:
  479. time.sleep(1)
  480. import tweepy
  481. consumer_key = os.environ['consumer_key']
  482. access_token_secret = os.environ['access_token_secret']
  483. access_token = os.environ['access_token']
  484. bearer_token = os.environ['bearer_token']
  485. consumer_secret = os.environ['consumer_secret']
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement