Compare commits

...

11 Commits

Author SHA1 Message Date
5124b13e59 Force deploy
All checks were successful
Apps/everybody-mov/pipeline/head This commit looks good
2022-09-04 01:31:08 -04:00
9d3b41f338 Performing better masking on credentials; renaming env variables; cleaning up after Docker agents.
All checks were successful
Apps/everybody-mov/pipeline/head This commit looks good
2022-09-03 23:44:14 -04:00
5e4a63af9c Only publish on main
All checks were successful
Apps/everybody-mov/pipeline/head This commit looks good
2022-09-02 00:39:07 -04:00
cbc3cc26ed Merge branch 'main' of https://ailuridae.io/git/amber/everybody-mov
All checks were successful
Apps/everybody-mov/pipeline/head This commit looks good
Merging main
2022-09-02 00:37:06 -04:00
a066142307 Adding Jenkinsfile for checking, building, and publishing 2022-09-02 00:35:32 -04:00
6a90b91f3a Undoing one grammatical edit in everybody.txt 2022-08-30 18:59:50 +00:00
693749f1ea Grammatical edits to everybody.txt 2022-08-30 18:53:33 +00:00
0a996ad14c Specifying how to build in README.md, in case I forget. 2022-08-28 22:51:40 -04:00
63b3efaa9b Styling changes and fixing some dumb dumb code. Also, some new dependencies for development. 2022-08-28 22:42:43 -04:00
8158c727bc Merge branch 'main' of https://ailuridae.io/git/amber/everybody-mov 2022-08-26 02:52:29 -04:00
96d31ba8d3 Fixing environment variable glitch 2022-08-26 02:52:09 -04:00
9 changed files with 263 additions and 42 deletions

5
.gitignore vendored
View File

@@ -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
@@ -234,6 +230,7 @@ fabric.properties
# Icon must end with two \r
Icon
# Thumbnails
._*

8
.groovylintrc.json Normal file
View File

@@ -0,0 +1,8 @@
{
"extends": "recommended",
"rules": {
"NestedBlockDepth": {
"enabled": false
}
}
}

View File

@@ -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
View 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()
}
}
}
}

View File

@@ -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
View File

@@ -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",

View File

@@ -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
```

View File

@@ -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.

View File

@@ -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,
auth: tweepy.OAuth1UserHandler = 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)
my_file = open('./everybody.txt', 'r', encoding='utf-8')
# Creating an API object with our authentication method.
api: tweepy.API = tweepy.API(auth=auth)
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 = [x.strip() for x in my_file.readlines()]
file_lines: List[str] = [x.strip() for x in my_file.readlines()]
# Close file.
my_file.close()
# 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()