Compare commits
11 Commits
dcd119db86
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5124b13e59 | |||
| 9d3b41f338 | |||
| 5e4a63af9c | |||
| cbc3cc26ed | |||
| a066142307 | |||
| 6a90b91f3a | |||
| 693749f1ea | |||
| 0a996ad14c | |||
| 63b3efaa9b | |||
| 8158c727bc | |||
| 96d31ba8d3 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -140,10 +140,6 @@ cython_debug/
|
||||
|
||||
# ---> VisualStudioCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
@@ -232,7 +228,8 @@ fabric.properties
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
8
.groovylintrc.json
Normal file
8
.groovylintrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "recommended",
|
||||
"rules": {
|
||||
"NestedBlockDepth": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
FROM python:3.10-alpine
|
||||
|
||||
WORKDIR /app
|
||||
WORKDIR /app/
|
||||
ENV PYTHONIOENCODING=utf-8
|
||||
|
||||
COPY Pipfile Pipfile.lock everybody.txt tweetbot.py /app
|
||||
COPY Pipfile Pipfile.lock everybody.txt tweetbot.py /app/
|
||||
|
||||
# Install pipenv and compilation dependencies
|
||||
RUN pip install pipenv && pipenv install --deploy --ignore-pipfile
|
||||
|
||||
95
Jenkinsfile
vendored
Normal file
95
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
pipeline {
|
||||
agent none
|
||||
|
||||
environment {
|
||||
HOME = "${env.WORKSPACE}"
|
||||
PYTHON_IMAGE = 'python:3.10-slim-bullseye'
|
||||
CREDENTIALS_ID = 'digital-ocean-ailuridae-registry'
|
||||
REGISTRY = 'https://registry.digitalocean.com'
|
||||
IMAGE_NAME = 'registry.digitalocean.com/ailuridae-registry/ailuridae.io/everybodymov'
|
||||
IMAGE_BUILD = ''
|
||||
APP_ID = credentials('digital-ocean-app-id')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Check') {
|
||||
agent {
|
||||
docker {
|
||||
image env.PYTHON_IMAGE
|
||||
args '--rm'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'python -m pip install --no-cache-dir --upgrade --user pip'
|
||||
sh 'python -m pip install --no-cache-dir --user pipenv'
|
||||
sh 'python -m pipenv install --dev --deploy'
|
||||
sh 'python -m pipenv check --clear'
|
||||
sh 'python -m pipenv run bandit *.py'
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
agent {
|
||||
label 'main'
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
IMAGE_BUILD = docker.build("${IMAGE_NAME}")
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Publish') {
|
||||
agent {
|
||||
label 'main'
|
||||
}
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
// withCredentials is annoyingly required to mask token occurrences.
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: env.CREDENTIALS_ID,
|
||||
usernameVariable: 'API_TOKEN_USER',
|
||||
passwordVariable: 'API_TOKEN_PASS'
|
||||
)]) {
|
||||
docker.withRegistry(env.REGISTRY, env.CREDENTIALS_ID) {
|
||||
IMAGE_BUILD.push("${BUILD_NUMBER}")
|
||||
IMAGE_BUILD.push('latest')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Deploy') {
|
||||
agent {
|
||||
label 'main'
|
||||
}
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: env.CREDENTIALS_ID,
|
||||
usernameVariable: 'API_TOKEN_USER',
|
||||
passwordVariable: 'API_TOKEN_PASS'
|
||||
)]) {
|
||||
sh '''
|
||||
curl -H "Authorization: Bearer $API_TOKEN_PASS" -H "Content-Type: application/json" \
|
||||
-X POST "https://api.digitalocean.com/v2/apps/$APP_ID/deployments" \
|
||||
-d "{ \\"force_build\\" : true }"
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
node('main') {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Pipfile
3
Pipfile
@@ -7,7 +7,8 @@ name = "pypi"
|
||||
tweepy = "==4.10.1"
|
||||
|
||||
[dev-packages]
|
||||
autopep8 = "==1.7.0"
|
||||
autopep8 = "*"
|
||||
bandit = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.10"
|
||||
|
||||
95
Pipfile.lock
generated
95
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "a94545d640dcc28fce0a26b5d40dfaebf886910d87df38ab7bbe4ab7ec69f066"
|
||||
"sha256": "e7a1785570cb6182573b0e15cae2ad2c86adb2c280e88ceaa9126c232b720c9c"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -21,7 +21,7 @@
|
||||
"sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d",
|
||||
"sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==2022.6.15"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
@@ -29,7 +29,7 @@
|
||||
"sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845",
|
||||
"sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"idna": {
|
||||
@@ -45,7 +45,7 @@
|
||||
"sha256:23a8208d75b902797ea29fd31fa80a15ed9dc2c6c16fe73f5d346f83f6fa27a2",
|
||||
"sha256:6db33440354787f9b7f3a6dbd4febf5d0f93758354060e802f6c06cb493022fe"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==3.2.0"
|
||||
},
|
||||
"requests": {
|
||||
@@ -90,6 +90,38 @@
|
||||
"index": "pypi",
|
||||
"version": "==1.7.0"
|
||||
},
|
||||
"bandit": {
|
||||
"hashes": [
|
||||
"sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2",
|
||||
"sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.7.4"
|
||||
},
|
||||
"gitdb": {
|
||||
"hashes": [
|
||||
"sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd",
|
||||
"sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.0.9"
|
||||
},
|
||||
"gitpython": {
|
||||
"hashes": [
|
||||
"sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704",
|
||||
"sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.27"
|
||||
},
|
||||
"pbr": {
|
||||
"hashes": [
|
||||
"sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a",
|
||||
"sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf"
|
||||
],
|
||||
"markers": "python_version >= '2.6'",
|
||||
"version": "==5.10.0"
|
||||
},
|
||||
"pycodestyle": {
|
||||
"hashes": [
|
||||
"sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785",
|
||||
@@ -98,6 +130,61 @@
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.9.1"
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293",
|
||||
"sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b",
|
||||
"sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57",
|
||||
"sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b",
|
||||
"sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4",
|
||||
"sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07",
|
||||
"sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba",
|
||||
"sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9",
|
||||
"sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287",
|
||||
"sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513",
|
||||
"sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0",
|
||||
"sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0",
|
||||
"sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92",
|
||||
"sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f",
|
||||
"sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2",
|
||||
"sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc",
|
||||
"sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c",
|
||||
"sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86",
|
||||
"sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4",
|
||||
"sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c",
|
||||
"sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34",
|
||||
"sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b",
|
||||
"sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c",
|
||||
"sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb",
|
||||
"sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737",
|
||||
"sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3",
|
||||
"sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d",
|
||||
"sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53",
|
||||
"sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78",
|
||||
"sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803",
|
||||
"sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a",
|
||||
"sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174",
|
||||
"sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==6.0"
|
||||
},
|
||||
"smmap": {
|
||||
"hashes": [
|
||||
"sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94",
|
||||
"sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==5.0.0"
|
||||
},
|
||||
"stevedore": {
|
||||
"hashes": [
|
||||
"sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8",
|
||||
"sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
|
||||
|
||||
10
README.md
10
README.md
@@ -1,2 +1,12 @@
|
||||
# everybody-mov
|
||||
In my dreams there is an intimacy I have never known.
|
||||
|
||||
## Building image
|
||||
```
|
||||
docker buildx build --platform linux/amd64 -t ailuridae.io/everybodymov .
|
||||
```
|
||||
|
||||
## Running container
|
||||
```
|
||||
docker run -e CONSUMER_KEY=mykey -e CONSUMER_SECRET=mysecret -e ACCESS_TOKEN=mytoken -e ACCESS_TOKEN_SECRET=mytokensecret ailuridae.io/everybodymov:latest
|
||||
```
|
||||
@@ -8,7 +8,7 @@ Feverish sensations fill my blood from matters of a violent and unfulfilled desi
|
||||
You are made of beets. I think this is wonderful. You are made of beets. I think this is wonderful.
|
||||
I wished for her to remove them one by one with her mouth.
|
||||
It would cause a hemorrhage, of this I am certain.
|
||||
When she is not around I do not exist at all.
|
||||
When she is not around, I do not exist at all.
|
||||
A pathological disorder, let's be honest.
|
||||
In my dreams there is an intimacy I have never known.
|
||||
These newfound discoveries are causing me to spray strange oily liquids.
|
||||
@@ -17,7 +17,7 @@ You are too needy, dripping with need. You should probably kill yourself before
|
||||
You paralyze me with disgust. You are spilling open like a gelatinous urchin belly.
|
||||
I am aware of this. Please tell me how I can make myself appear more desirable to others. I would like to know my surgical options.
|
||||
I hate you.
|
||||
I would like to end your life - but why? I know: meat. You are nothing but meat. You smell like diapers and sausage.
|
||||
I would like to end your life, but why? I know: meat. You are nothing but meat. You smell like diapers and sausage.
|
||||
I disagree. Your waxy face looks ashen like a cadaverous larva, but I am enamoured with your smell, like a cranal flower with a frankincense opening, steeped in the essence of leather and mimosa.
|
||||
You are a delight. If only I could remove your head altogether.
|
||||
I will perform the surgery at once. I hope you are not too sensitive to pain.
|
||||
|
||||
79
tweetbot.py
79
tweetbot.py
@@ -2,72 +2,95 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
from typing import Tuple
|
||||
from typing import List, Tuple
|
||||
import tweepy
|
||||
from time import sleep
|
||||
from random import shuffle
|
||||
|
||||
|
||||
def get_arguments() -> Tuple[str, str, str, str]:
|
||||
consumer_key = os.environ['CONSUMER_KEY']
|
||||
consumer_secret = os.environ['CONSUMER_SECRET']
|
||||
access_token = os.environ['ACCESS_TOKEN']
|
||||
access_token_secret = os.environ['ACCESS_TOKEN_SECRET']
|
||||
# Return our credentials from environment variables as UTF-8 bytes.
|
||||
def get_arguments() -> Tuple[bytes, bytes, bytes, bytes]:
|
||||
consumer_key: bytes = os.environ['CONSUMER_KEY'].encode('utf8')
|
||||
consumer_secret: bytes = os.environ['CONSUMER_SECRET'].encode('utf8')
|
||||
access_token: bytes = os.environ['ACCESS_TOKEN'].encode('utf8')
|
||||
access_token_secret: bytes = os.environ['ACCESS_TOKEN_SECRET'].encode('utf8')
|
||||
|
||||
return consumer_key, consumer_secret, access_token, access_token_secret
|
||||
|
||||
|
||||
def populate_array(file_lines) -> list:
|
||||
length = len(file_lines)
|
||||
|
||||
array = []
|
||||
|
||||
for i in range(length):
|
||||
array.append(i)
|
||||
# Copy the file lines to a new List[str] and shuffle it.
|
||||
def populate_array(file_lines: List[str]) -> List[str]:
|
||||
array: List[str] = file_lines.copy()
|
||||
|
||||
# Scramble like an egg.
|
||||
shuffle(array)
|
||||
|
||||
return array
|
||||
|
||||
|
||||
# Main function.
|
||||
def main() -> None:
|
||||
# Access and authorize our Twitter credentials
|
||||
consumer_key: bytes
|
||||
consumer_secret: bytes
|
||||
access_token: bytes
|
||||
access_token_secret: bytes
|
||||
|
||||
# Access and set authentication method to our Twitter credentials.
|
||||
consumer_key, consumer_secret, access_token, access_token_secret = get_arguments()
|
||||
auth = tweepy.OAuth1UserHandler(consumer_key=consumer_key, consumer_secret=consumer_secret,
|
||||
access_token=access_token, access_token_secret=access_token_secret)
|
||||
api = tweepy.API(auth=auth)
|
||||
auth: tweepy.OAuth1UserHandler = tweepy.OAuth1UserHandler(consumer_key=consumer_key, consumer_secret=consumer_secret,
|
||||
access_token=access_token, access_token_secret=access_token_secret)
|
||||
|
||||
# Creating an API object with our authentication method.
|
||||
api: tweepy.API = tweepy.API(auth=auth)
|
||||
|
||||
my_file = open('./everybody.txt', 'r', encoding='utf-8')
|
||||
array: List[str]
|
||||
with open('./everybody.txt', 'r', encoding='utf-8') as my_file:
|
||||
# Read lines one by one from my_file and assign to file_lines variable
|
||||
file_lines: List[str] = [x.strip() for x in my_file.readlines()]
|
||||
|
||||
# Read lines one by one from my_file and assign to file_lines variable
|
||||
file_lines = [x.strip() for x in my_file.readlines()]
|
||||
# Close file.
|
||||
my_file.close()
|
||||
|
||||
# Close file.
|
||||
my_file.close()
|
||||
|
||||
array = populate_array(file_lines)
|
||||
# Create List[str] from file_lines.
|
||||
array = populate_array(file_lines)
|
||||
|
||||
# Driving loop.
|
||||
while True:
|
||||
while array:
|
||||
tweet = file_lines[array.pop()]
|
||||
# Grab last element and then remove it.
|
||||
tweet: str = array.pop()
|
||||
|
||||
try:
|
||||
# Output the last element, which will be the tweet.
|
||||
print(tweet)
|
||||
|
||||
# Create a tweet through the API.
|
||||
api.update_status(tweet)
|
||||
|
||||
# Chill out for 1800 seconds.
|
||||
sleep(1800)
|
||||
except tweepy.Forbidden as fe:
|
||||
print(f"{fe.api_errors}")
|
||||
# We probably tried to create a duplicate tweet, but say what happened.
|
||||
print(fe.api_errors)
|
||||
|
||||
# Chill out for 30 seconds.
|
||||
sleep(30)
|
||||
except tweepy.BadRequest as be:
|
||||
print(f"{be.api_errors}")
|
||||
# Something is wrong with our client, so say what happened.
|
||||
print(be.api_errors)
|
||||
|
||||
# Bail. We shouldn't keep trying.
|
||||
sys.exit(1)
|
||||
except tweepy.TweepyException as te:
|
||||
# Something very unexpected happened, so say what happened.
|
||||
print(te)
|
||||
|
||||
# Bail. We shouldn't keep trying.
|
||||
sys.exit(1)
|
||||
|
||||
# Let's do the time warp again.
|
||||
array = populate_array(file_lines)
|
||||
|
||||
|
||||
# Do not delete.
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user