From c1b827fba3aa45d91c3eb2c68288cd4af6a717c9 Mon Sep 17 00:00:00 2001 From: bel Date: Tue, 14 Sep 2021 06:20:35 -0600 Subject: [PATCH] archive --- 2try | 5 + fava/fava.sh | 10 ++ ff3-to-ledger/ff3.csv.tar | Bin 0 -> 59154 bytes ff3-to-ledger/to_ledger.py | 111 +++++++++++++++ firefly/compose-old/firefly-compose.yml | 46 ++++++ firefly/compose-old/firefly.sh | 25 ++++ firefly/postgres/.dockerignore | 1 + firefly/postgres/Dockerfile | 75 ++++++++++ firefly/postgres/backup.sh | 21 +++ firefly/postgres/build.sh | 15 ++ firefly/postgres/entrypoint.sh | 16 +++ firefly/postgres/env | 102 ++++++++++++++ firefly/postgres/firefly-iii.conf | 29 ++++ firefly/postgres/pause/main.c | 20 +++ firefly/postgres/restore.sh | 38 +++++ firefly/postgres/script.sh | 50 +++++++ firefly/ubuntu-old/Dockerfile | 107 ++++++++++++++ firefly/ubuntu-old/build.sh | 6 + firefly/ubuntu-old/env | 102 ++++++++++++++ firefly/ubuntu-old/firefly-iii.conf | 29 ++++ firefly/ubuntu-old/pause/main.c | 20 +++ firefly/ubuntu-old/script.sh | 50 +++++++ ledger/cli/Dockerfile | 6 + mizzer/economizzer | 23 +++ mizzer/economizzer-build.sh | 3 + silverstrike/.Dockerfile | 46 ++++++ silverstrike/fork/.dockerignore | 2 + silverstrike/fork/Dockerfile | 42 ++++++ silverstrike/fork/LICENSE | 21 +++ silverstrike/fork/docker-compose.yml | 21 +++ silverstrike/fork/manage.py | 22 +++ silverstrike/fork/master.zip | Bin 0 -> 5550 bytes silverstrike/fork/requirements.txt | 6 + silverstrike/fork/settings.py | 163 ++++++++++++++++++++++ silverstrike/fork/signupadapter.py | 6 + silverstrike/fork/urls.py | 9 ++ silverstrike/fork/wsgi.py | 16 +++ silverstrike/scratch/Dockerfile | 66 +++++++++ silverstrike/scratch/settings.py | 178 ++++++++++++++++++++++++ silverstrike/scratch/try | 1 + 40 files changed, 1509 insertions(+) create mode 100755 2try create mode 100755 fava/fava.sh create mode 100644 ff3-to-ledger/ff3.csv.tar create mode 100755 ff3-to-ledger/to_ledger.py create mode 100755 firefly/compose-old/firefly-compose.yml create mode 100755 firefly/compose-old/firefly.sh create mode 100755 firefly/postgres/.dockerignore create mode 100755 firefly/postgres/Dockerfile create mode 100755 firefly/postgres/backup.sh create mode 100755 firefly/postgres/build.sh create mode 100755 firefly/postgres/entrypoint.sh create mode 100755 firefly/postgres/env create mode 100755 firefly/postgres/firefly-iii.conf create mode 100755 firefly/postgres/pause/main.c create mode 100755 firefly/postgres/restore.sh create mode 100755 firefly/postgres/script.sh create mode 100755 firefly/ubuntu-old/Dockerfile create mode 100755 firefly/ubuntu-old/build.sh create mode 100755 firefly/ubuntu-old/env create mode 100755 firefly/ubuntu-old/firefly-iii.conf create mode 100755 firefly/ubuntu-old/pause/main.c create mode 100755 firefly/ubuntu-old/script.sh create mode 100755 ledger/cli/Dockerfile create mode 100755 mizzer/economizzer create mode 100755 mizzer/economizzer-build.sh create mode 100755 silverstrike/.Dockerfile create mode 100755 silverstrike/fork/.dockerignore create mode 100755 silverstrike/fork/Dockerfile create mode 100755 silverstrike/fork/LICENSE create mode 100755 silverstrike/fork/docker-compose.yml create mode 100755 silverstrike/fork/manage.py create mode 100755 silverstrike/fork/master.zip create mode 100755 silverstrike/fork/requirements.txt create mode 100755 silverstrike/fork/settings.py create mode 100755 silverstrike/fork/signupadapter.py create mode 100755 silverstrike/fork/urls.py create mode 100755 silverstrike/fork/wsgi.py create mode 100755 silverstrike/scratch/Dockerfile create mode 100755 silverstrike/scratch/settings.py create mode 100755 silverstrike/scratch/try diff --git a/2try b/2try new file mode 100755 index 0000000..5fd1328 --- /dev/null +++ b/2try @@ -0,0 +1,5 @@ +https://firefly-iii.readthedocs.io/en/latest/installation/docker.html +https://github.com/gugoan/economizzer#live-demo +http://www.economizzer.org +https://github.com/beancount/fava + diff --git a/fava/fava.sh b/fava/fava.sh new file mode 100755 index 0000000..a8fb1d0 --- /dev/null +++ b/fava/fava.sh @@ -0,0 +1,10 @@ +#! /bin/bash + +function clean() { + docker rm -f $(docker ps -a | grep fava | awk '{print $NF}') +} +trap clean EXIT + +echo 'touch /any.bean && fava -d --host 0.0.0.0 /any.bean' | docker run --rm -i -p 5000:5000 yegle/fava sh > /dev/null 2>&1 & +sleep 5 +docker logs --follow $(docker ps -a | grep fava | awk '{print $NF}') diff --git a/ff3-to-ledger/ff3.csv.tar b/ff3-to-ledger/ff3.csv.tar new file mode 100644 index 0000000000000000000000000000000000000000..974671e090558c556aa7bbcb954b829bd0641d80 GIT binary patch literal 59154 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

f0M)Aw*GFcPB!4@ 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 T>|+>@axX~ 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 literal 0 HcmV?d00001 diff --git a/ff3-to-ledger/to_ledger.py b/ff3-to-ledger/to_ledger.py new file mode 100755 index 0000000..8a54c80 --- /dev/null +++ b/ff3-to-ledger/to_ledger.py @@ -0,0 +1,111 @@ +#! /bin/python3 + +class FireflyIIITransaction(dict) : + def __init__(self, keys, line) : + for k, v in { keys[i]:line[i] for i in range(len(keys)) }.items() : + if not k in dir(self) : + setattr(self, k, v) + self.keys = keys[:] + dict.__init__(self, self.__dict__()) + + def __dict__(self) : + keys = [ + "user_id", + "group_id", + "journal_id", + "created_at", + "updated_at", + "group_title", + "type", + "amount", + "foreign_amount", + "currency_code", + "foreign_currency_code", + "description", + "date", + "source_name", + "source_iban", + "source_type", + "destination_name", + "destination_iban", + "destination_type", + "reconciled", + "category", + "budget", + "bill", + "tags", + ] + keys = [ + "type", + "amount", + "date", + "source_name", + "source_type", + "destination_name", + "destination_type", + "category", + "description", + ] + return { k:getattr(self, k) for k in keys if k in self.keys } + + def __str__(self) : + return self.ledger() + + def ledger(self) : + date = self.date.split("T")[0] + description = getattr(self, "description" if self.description and self.description != "(null)" else "source_name" if self.type in ["Withdrawl", "Transfer"] else "destination_name") + amount = float("{:0.2f}".format(float(self.amount)).strip("-")) + local = "" + remote = "" + if self.type.startswith("Withdraw") : + amount = -1.0 * amount + local = ":".join([self.source_type, self.source_name]).title().replace(" ", "") + remote = ":".join([self.type, self.category, self.destination_name]).title().replace(" ", "") + elif self.type == "Transfer" : + local = ":".join([self.destination_type, self.destination_name]).title().replace(" ", "") + remote = ":".join([self.source_type, self.source_name]).title().replace(" ", "") + elif self.type == "Deposit" : + local = ":".join([self.destination_type, self.destination_name]).title().replace(" ", "") + remote = ":".join([self.type, self.category, self.source_name]).title().replace(" ", "") + else : + raise Exception("unknown type: "+self.type) + return "\n".join([i for i in [ j for j in f'''{date} {description} + {"{:100s}".format(remote)} ${"{:0.2f}".format(-1.0 * amount)} + {"{:100s}".format(local)} ${"{:0.2f}".format(amount)} + '''.split("\n") if j.strip() ]]) + + +class FireflyIII() : + def __init__(self, path) : + import csv + lines = [ i for i in csv.reader(open(path)) ] + keys = lines[0] + lines = lines[1:] + self.transactions = [ FireflyIIITransaction(keys, i) for i in lines ] + + def __str__(self) : + import json + return json.dumps(self.transactions, indent=" ") + + def __getitem__(self, k) : + return self.transactions[k] + + def ledger(self) : + return sorted([i.ledger() for i in self.transactions]) + +def main(args) : + if not args : + args.append("./ff3.csv") + ff3 = FireflyIII(args[0]) + print(ff3) + print(ff3[0]) + print("\n".join(ff3.ledger())) + f = open("./ledger.dat", "w") + for ledger in ff3.ledger() : + f.write(ledger) + f.write("\n") + f.close() + +if __name__ == "__main__" : + from sys import argv + main(argv[1:]) diff --git a/firefly/compose-old/firefly-compose.yml b/firefly/compose-old/firefly-compose.yml new file mode 100755 index 0000000..3cd8234 --- /dev/null +++ b/firefly/compose-old/firefly-compose.yml @@ -0,0 +1,46 @@ +--- +networks: + firefly_iii_net: + driver: bridge +services: + firefly_iii_app: + environment: + - FF_DB_HOST=firefly_iii_db + - FF_DB_NAME=firefly + - FF_DB_USER=firefly + - FF_DB_PASSWORD=firefly + - FF_APP_KEY=S0m3R@nd0mStr1ngOf32Ch@rsEx@ctly + - FF_APP_ENV=local + - FF_DB_CONNECTION=pgsql + - TZ=Europe/Amsterdam + - APP_LOG_LEVEL=debug + image: jc5x/firefly-iii + links: + - firefly_iii_db + networks: + - firefly_iii_net + ports: + - "80:80" + #volumes: + # - + # source: firefly_iii_export + # target: /var/www/firefly-iii/storage/export + # type: volume + # - + # source: firefly_iii_upload + # target: /var/www/firefly-iii/storage/upload + # type: volume + firefly_iii_db: + environment: + - POSTGRES_PASSWORD=firefly + - POSTGRES_USER=firefly + image: "postgres:10" + networks: + - firefly_iii_net + #volumes: + # - "firefly_iii_db:/var/lib/postgresql/data" +version: "3.2" +#volumes: +# firefly_iii_db: ~ +# firefly_iii_export: ~ +# firefly_iii_upload: ~ diff --git a/firefly/compose-old/firefly.sh b/firefly/compose-old/firefly.sh new file mode 100755 index 0000000..eee37a9 --- /dev/null +++ b/firefly/compose-old/firefly.sh @@ -0,0 +1,25 @@ +#! /bin/bash + +cd "$(dirname "${BASH_SOURCE[0]}")" + +function clean() { + docker-compose -f firefly-compose.yml rm + docker rm -f $(docker ps -a | grep firefly | awk '{print $NF}') 2> /dev/null +} +trap clean EXIT + +docker-compose -f firefly-compose.yml up -d +sleep 20 +docker-compose -f firefly-compose.yml exec firefly_iii_app php artisan migrate --seed +sleep 5 +docker-compose -f firefly-compose.yml exec firefly_iii_app php artisan firefly:upgrade-database +sleep 5 +docker-compose -f firefly-compose.yml exec firefly_iii_app php artisan firefly:verify +sleep 5 +docker-compose -f firefly-compose.yml exec firefly_iii_app php artisan passport:install +sleep 5 +docker-compose -f firefly-compose.yml exec firefly_iii_app php artisan cache:clear +sleep 5 + +docker logs --follow $(docker ps -a | grep firefly | head -n 1 | awk '{print $NF}') + diff --git a/firefly/postgres/.dockerignore b/firefly/postgres/.dockerignore new file mode 100755 index 0000000..a9a5aec --- /dev/null +++ b/firefly/postgres/.dockerignore @@ -0,0 +1 @@ +tmp diff --git a/firefly/postgres/Dockerfile b/firefly/postgres/Dockerfile new file mode 100755 index 0000000..fd0c620 --- /dev/null +++ b/firefly/postgres/Dockerfile @@ -0,0 +1,75 @@ +FROM ubuntu:18.04 + +### APT +RUN apt -y update \ + && DEBIAN_FRONTEND=noninteractive apt -y install tzdata \ + && apt -y install locales language-pack-en-base \ + && echo '127.0.0.1 firefly-iii-domain.com firefly-iii localhost' >> /etc/hosts \ + && apt -y install \ + postgresql postgresql-contrib \ + nginx \ + php-fpm php7.3-pgsql php-curl php-gd php-bcmath php-zip php-intl php-mbstring php-xml php-ldap \ + curl \ + gcc \ + cron \ + rsync \ + sudo \ + && rm /etc/nginx/sites-enabled/default \ + && touch /etc/nginx/sites-available/firefly-iii.conf \ + && ln -s /etc/nginx/sites-available/firefly-iii.conf /etc/nginx/sites-enabled/firefly-iii.conf \ + && openssl dhparam 2048 > /etc/nginx/dhparam.pem + +USER postgres +RUN service postgresql start && sleep 5 \ + && psql --command "CREATE DATABASE fireflyiii WITH ENCODING 'UTF8' TEMPLATE='template0';" \ + && psql --command "CREATE USER ffly WITH SUPERUSER PASSWORD 'pwd';" \ + && psql --command "GRANT ALL PRIVILEGES ON DATABASE fireflyiii TO ffly;" \ + && service postgresql stop && sleep 5 + + #&& sed 's/^password .*/password = pwd/' /etc/mysql/debian.cnf > /tmp/cnf \ + #&& mv /tmp/cnf /etc/mysql/debian.cnf \ + #&& echo 'create database fireflyiii character set utf8 collate utf8_bin; ' \ + # 'grant all privileges on fireflyiii.* to fireflyiii@localhost identified by '"'"'pwd'"'"'; ' \ + # | mysql --user=root --password=pwd mysql && echo made fireflyiii +USER root + +### PHP +RUN service postgresql start && sleep 10 \ + && curl -sS https://getcomposer.org/installer \ + | php -- --install-dir=/usr/local/bin --filename=composer \ + && cd /opt \ + && composer create-project grumpydictator/firefly-iii --no-dev --prefer-dist firefly-iii 5.0.1 +COPY ./env /opt/firefly-iii/.env +RUN service postgresql start && sleep 10 \ + && cd /opt/firefly-iii \ + && php artisan migrate:refresh --seed \ + && php artisan passport:install \ + && chown -R www-data:www-data /opt/firefly-iii \ + && mkdir -p /run/php + +### WAIT +COPY ./pause /xfer/ +RUN cd /xfer && gcc main.c -o /xfer/pauser + +### CONFIG +COPY ./env /opt/firefly-iii/.env +COPY ./firefly-iii.conf /etc/nginx/sites-enabled/ + +RUN apt -y autoremove \ + && apt -y purge --auto-remove gcc curl \ + && rm -rf /var/lib/apt \ + && apt clean + +### CRON +RUN true \ + && echo '0 4,8,12,16,20 * * * bash /backup.sh >> /var/log/cronj.log 2>&1' > /etc/cron.d/backups \ + && echo '' >> /etc/cron.d/backups \ + && chmod 0644 /etc/cron.d/backups \ + && crontab /etc/cron.d/backups \ + && touch /var/log/cronj.log + +### COPY +COPY ./backup.sh ./restore.sh ./entrypoint.sh / + +### on enter/exit, rsync to/from /var/lib/mysql and /mnt +ENTRYPOINT bash /entrypoint.sh diff --git a/firefly/postgres/backup.sh b/firefly/postgres/backup.sh new file mode 100755 index 0000000..3965323 --- /dev/null +++ b/firefly/postgres/backup.sh @@ -0,0 +1,21 @@ +#! /bin/bash + +set -e +set -x +service postgresql start +thisback="/mnt/back/$(date -u +%Y%m%d%H%M%S).dump" +rm -rf "$thisback" || true +mkdir -p "$(dirname "$thisback")" +pg_dump postgres://ffly:pwd@localhost/fireflyiii --clean > "$thisback" +service postgresql start +n=$(ls /mnt/back | wc -l) +if ((n<=25)); then + echo "No old backups to purge" >&2 + exit 0 +fi +((m=n-25)) +stale=($(find /mnt/back/ -mindepth 1 -maxdepth 1 | sort | head -n $m)) +echo "Purging: rm -rf ${stale[@]}" >&2 +rm -rf "${stale[@]}" +remaining=($(find /mnt/back/ -mindepth 1 -maxdepth 1 | sort)) +echo "Remains: ${remaining[@]}" >&2 diff --git a/firefly/postgres/build.sh b/firefly/postgres/build.sh new file mode 100755 index 0000000..24bbacf --- /dev/null +++ b/firefly/postgres/build.sh @@ -0,0 +1,15 @@ +#! /bin/bash + +set -e + +mkdir -p $(pwd)/tmp + +docker build -t dev:dev . +docker run \ + --rm \ + -it \ + -p 9031:9031 \ + -v $PWD/tmp:/mnt \ + dev:dev + + # -v $(pwd)/tmp:/mnt \ diff --git a/firefly/postgres/entrypoint.sh b/firefly/postgres/entrypoint.sh new file mode 100755 index 0000000..951c75e --- /dev/null +++ b/firefly/postgres/entrypoint.sh @@ -0,0 +1,16 @@ +#! /bin/bash + +set -e + +echo " : servicing" >&2 +for s in postgresql nginx php7.3-fpm cron; do + service $s restart +done +echo " : restoring" >&2 +bash /restore.sh $i +echo " : backing" >&2 +bash /backup.sh +echo " : sleeping" >&2 +sleep 10 +echo " : pausering" >&2 +exec /xfer/pauser diff --git a/firefly/postgres/env b/firefly/postgres/env new file mode 100755 index 0000000..59ef944 --- /dev/null +++ b/firefly/postgres/env @@ -0,0 +1,102 @@ +# You can leave this on "local". If you change it to production most console commands will ask for extra confirmation. +# Never set it to "testing". +APP_ENV=local + +# Set to true if you want to see debug information in error screens. +APP_DEBUG=true + +# This should be your email address +SITE_OWNER=admin@email.com + +# The encryption key for your database and sessions. Keep this very secure. +# If you generate a new one all existing data must be considered LOST. +# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it +APP_KEY=11111111111111111111111111111111 + +# Change this value to your preferred time zone. +# Example: Europe/Amsterdam +TZ=America/Chicago + +# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. +APP_URL=http://localhost +TRUSTED_PROXIES= + +# The log channel defines where your log entries go to. +LOG_CHANNEL=daily + +# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III +# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html +DB_CONNECTION=pgsql +DB_HOST=127.0.0.1 +DB_PORT=5432 +DB_DATABASE=fireflyiii +DB_USERNAME=ffly +DB_PASSWORD=pwd + +# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/. +# Several other options exist. You can use 'single' for one big fat error log (not recommended). +# Also available are 'syslog' and 'errorlog' which will log to the system itself. +APP_LOG=daily + +# Log level. You can set this from least severe to most severe: +# debug, info, notice, warning, error, critical, alert, emergency +# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably +# nothing will get logged, ever. +APP_LOG_LEVEL=notice + +# If you're looking for performance improvements, you could install memcached. +CACHE_DRIVER=file +SESSION_DRIVER=file + +# Cookie settings. Should not be necessary to change these. +COOKIE_PATH="/" +COOKIE_DOMAIN= +COOKIE_SECURE=false + +# If you want Firefly III to mail you, update these settings +MAIL_DRIVER=smtp +MAIL_HOST=smtp.server.com +MAIL_PORT=587 +MAIL_FROM= +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_ENCRYPTION=tls + +# Firefly III can send you the following messages +SEND_REGISTRATION_MAIL=true +SEND_ERROR_MESSAGE=true + +# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. +MAPBOX_API_KEY= + +# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates. +# Please note that this will only work for paid fixer.io accounts because they severly limited +# the free API up to the point where you might as well offer nothing. +FIXER_API_KEY= + +# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here. +ANALYTICS_ID= + +# Most parts of the database are encrypted by default, but you can turn this off if you want to. +# This makes it easier to migrate your database. Not that some fields will never be decrypted. +USE_ENCRYPTION=true + +# Leave the following configuration vars as is. +# Unless you like to tinker and know what you're doing. +APP_NAME=FireflyIII +BROADCAST_DRIVER=log +QUEUE_DRIVER=sync +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 +CACHE_PREFIX=firefly +SEARCH_RESULT_LIMIT=50 +PUSHER_KEY= +PUSHER_SECRET= +PUSHER_ID= +DEMO_USERNAME= +DEMO_PASSWORD= +IS_DOCKER=true +IS_SANDSTORM=false +BUNQ_USE_SANDBOX=false +IS_HEROKU=false diff --git a/firefly/postgres/firefly-iii.conf b/firefly/postgres/firefly-iii.conf new file mode 100755 index 0000000..9a52dc2 --- /dev/null +++ b/firefly/postgres/firefly-iii.conf @@ -0,0 +1,29 @@ +server { + listen 9031; + listen [::]:9031; + + root /opt/firefly-iii/public; + + # Add index.php to the list if you are using PHP + client_max_body_size 300M; + index index.html index.htm index.php; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + location ~ \.php$ { + try_files $uri =404; + fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + + } + + index index.php index.htm index.html; + + location / { + try_files $uri $uri/ /index.php?$query_string; + autoindex on; + sendfile off; + } +} diff --git a/firefly/postgres/pause/main.c b/firefly/postgres/pause/main.c new file mode 100755 index 0000000..e9f68c7 --- /dev/null +++ b/firefly/postgres/pause/main.c @@ -0,0 +1,20 @@ +#include +#include +#include + +int main() { + int stat; + int sig; + sigset_t set; + sigemptyset(&set); + printf("add signal SIGINT: %i\n", sigaddset(&set, SIGINT)); + printf("add signal SIGKILL: %i\n", sigaddset(&set, SIGKILL)); + printf("add signal SIGTERM: %i\n", sigaddset(&set, SIGTERM)); + sigprocmask(SIG_BLOCK, &set, NULL); + printf("Waiting...\n"); + stat = sigwait(&set, &sig); + printf("Wait complete: %i (%i)\n", sig, stat); + printf("Backed: %i\n", system("bash /backup.sh")); + printf("Bye-bye!\n"); + return 0; +} diff --git a/firefly/postgres/restore.sh b/firefly/postgres/restore.sh new file mode 100755 index 0000000..e1c0452 --- /dev/null +++ b/firefly/postgres/restore.sh @@ -0,0 +1,38 @@ +#! /bin/bash + +skip=${1:-0} +set -x +set -e +backups="$(find /mnt/back/ -maxdepth 1 -mindepth 1 | grep -v '\/\.' | sort -r)" +if [ -z "${backups}" ]; then + echo "ERR: no backups to restore" >&2 + exit 0 +fi +tried=0 +echo Trying backups ${backups}... >&2 +for lastback in ${backups}; do + ((tried+=1)) + if ((tried<=skip)); then + continue + fi + if ( + echo Trying backup from $lastback >&2 + set -e + service postgresql start + psql postgres://ffly:pwd@localhost/fireflyiii < "$lastback" + service postgresql start + n=0 + until service postgresql status || ((n>10)); do + sleep 5 + ((n+=1)) + done + until service postgresql status | grep -E 'down|online'; do + sleep 5 + done + service postgresql status | grep online + ); then + exit 0 + fi +done +echo "ERR: could not load any backup" >&2 +exit 1 diff --git a/firefly/postgres/script.sh b/firefly/postgres/script.sh new file mode 100755 index 0000000..0437b2b --- /dev/null +++ b/firefly/postgres/script.sh @@ -0,0 +1,50 @@ +#! /bin/bash + +set -e +set -u + +apt -y update && apt -y upgrade && apt -y autoremove +DEBIAN_FRONTEND=noninteractive apt -y install tzdata +apt -y install vim locales language-pack-en-base + +echo '127.0.0.1 firefly-iii-domain.com firefly-iii localhost' >> /etc/hosts + +apt -y install fail2ban + +apt -y install mariadb-server nginx php-fpm php7.3-mysql php-curl php-gd php-bcmath php-zip php-intl php-mbstring php-xml + +service mysql start +echo 'FLUSH PRIVILEGES; ' \ + 'USE mysql; ' \ + 'UPDATE user SET authentication_string=PASSWORD("pwd") WHERE User='"'"'root'"'"'; ' \ + 'UPDATE user SET plugin="mysql_native_password" WHERE User='"'"'root'"'"'; ' \ + | mysql -u root || true +service mysql restart +sleep 5 + +echo 'create database fireflyiii character set utf8 collate utf8_bin; ' \ + 'grant all privileges on fireflyiii.* to fireflyiii@localhost identified by '"'"'pwd'"'"'; ' \ + | mysql -uroot -ppwd +service mysql restart + +apt -y install curl +curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +cd /opt +composer create-project grumpydictator/firefly-iii --no-dev --prefer-dist firefly-iii 4.7.4 + +cp /copied/env /opt/firefly-iii/.env + +cd firefly-iii +php artisan migrate:refresh --seed +php artisan passport:install + +chown -R www-data:www-data /opt/firefly-iii/ + +rm /etc/nginx/sites-enabled/default +touch /etc/nginx/sites-available/firefly-iii.conf +ln -s /etc/nginx/sites-available/firefly-iii.conf /etc/nginx/sites-enabled/firefly-iii.conf +openssl dhparam 2048 > /etc/nginx/dhparam.pem +cp /copied/firefly-iii.conf /etc/nginx/sites-enabled/firefly-iii.conf + +mkdir -p /run/php diff --git a/firefly/ubuntu-old/Dockerfile b/firefly/ubuntu-old/Dockerfile new file mode 100755 index 0000000..2c75ba8 --- /dev/null +++ b/firefly/ubuntu-old/Dockerfile @@ -0,0 +1,107 @@ +FROM ubuntu:18.10 + +### APT +RUN apt -y update \ + && DEBIAN_FRONTEND=noninteractive apt -y install tzdata \ + && apt -y install locales language-pack-en-base \ + && echo '127.0.0.1 firefly-iii-domain.com firefly-iii localhost' >> /etc/hosts \ + && apt -y install \ + mariadb-server \ + nginx \ + php-fpm php7.2-mysql php-curl php-gd php-bcmath php-zip php-intl php-mbstring php-xml \ + curl \ + gcc \ + cron \ + && rm /etc/nginx/sites-enabled/default \ + && touch /etc/nginx/sites-available/firefly-iii.conf \ + && ln -s /etc/nginx/sites-available/firefly-iii.conf /etc/nginx/sites-enabled/firefly-iii.conf \ + && openssl dhparam 2048 > /etc/nginx/dhparam.pem \ + && service mysql start && sleep 5 \ + && echo 'FLUSH PRIVILEGES; ' \ + 'USE mysql; ' \ + 'UPDATE user SET authentication_string=PASSWORD("pwd") WHERE User='"'"'root'"'"'; ' \ + 'UPDATE user SET plugin="mysql_native_password" WHERE User='"'"'root'"'"'; ' \ + | mysql --user=root mysql || true && echo made user \ + && service mysql stop && sleep 5 \ + && sed 's/^password .*/password = pwd/' /etc/mysql/debian.cnf > /tmp/cnf \ + && mv /tmp/cnf /etc/mysql/debian.cnf \ + && service mysql start && sleep 5 \ + && echo 'create database fireflyiii character set utf8 collate utf8_bin; ' \ + 'grant all privileges on fireflyiii.* to fireflyiii@localhost identified by '"'"'pwd'"'"'; ' \ + | mysql --user=root --password=pwd mysql && echo made fireflyiii + +### PHP +RUN service mysql start && sleep 10 \ + && curl -sS https://getcomposer.org/installer \ + | php -- --install-dir=/usr/local/bin --filename=composer \ + && cd /opt \ + && composer create-project grumpydictator/firefly-iii --no-dev --prefer-dist firefly-iii 4.7.4 +COPY ./env /opt/firefly-iii/.env +RUN service mysql start && sleep 10 \ + && cd /opt/firefly-iii \ + && php artisan migrate:refresh --seed \ + && php artisan passport:install \ + && chown -R www-data:www-data /opt/firefly-iii \ + && mkdir -p /run/php + +### WAIT +COPY ./pause /xfer/ +RUN cd /xfer && gcc main.c -o /xfer/pauser + +### CONFIG +COPY ./env /opt/firefly-iii/.env +COPY ./firefly-iii.conf /etc/nginx/sites-enabled/ + +RUN apt -y autoremove \ + && apt -y purge --auto-remove gcc curl \ + && rm -rf /var/lib/apt \ + && apt clean + +### CRON +RUN echo \ + 'lastback="$(find /mnt/back/ -maxdepth 1 -mindepth 1 | sort | tail -n 1)"; ' \ + 'mkdir -p $lastback/inc; ' \ + 'thisback="$lastback/inc/$(date -u +%Y%m%d%H%M)/"; ' \ + 'rm -rf $thisback; ' \ + 'mariabackup --backup --target-dir="$thisback" --user root --password=pwd --incremental-basedir $lastback/full; ' \ + > /backup-inc.sh \ + && echo \ + 'set -e; ' \ + 'service mysql start; ' \ + 'thisback="/mnt/back/$(date -u +%Y%m%d)"/full; ' \ + 'mkdir -p $thisback; ' \ + 'rm -rf "$(dirname "$thisback")"; ' \ + 'mkdir -p "$(dirname "$thisback")"; ' \ + 'mariabackup --backup --target-dir="$thisback" --user=root --password=pwd; ' \ + > /backup.sh \ + && echo \ + 'set -e; ' \ + 'rm -rf /var/lib/mysql-old; ' \ + 'mkdir -p /mnt/back; ' \ + 'lastback="$(find /mnt/back/ -maxdepth 1 -mindepth 1 | sort | tail -n 1)"; ' \ + 'if [ -z "$lastback" ]; then exit 0; fi; ' \ + 'service mysql stop || true; ' \ + 'restoring=/tmp/restoring; ' \ + 'cp -r "${lastback}/full" "$restoring"; ' \ + 'mariabackup --prepare --target-dir="$restoring" --user=root --password=pwd --apply-log-only || true; ' \ + 'inc_back="$(find $lastback/inc/ -maxdepth 1 -mindepth 1 | sort | tail -n 1)"; ' \ + 'echo --- inc restore $inc_back ---; ' \ + 'mariabackup --prepare --target-dir="$restoring" --user=root --password=pwd --incremental-dir "$inc_back" --apply-log-only || true; ' \ + 'mv /var/lib/mysql /var/lib/mysql-old; ' \ + 'mariabackup --copy-back --target-dir="$restoring" --user=root --password=pwd; ' \ + 'rm -rf "$restoring"; ' \ + 'chown -R mysql:mysql /var/lib/mysql; ' \ + 'service mysql start; ' \ + > /restore.sh \ + && echo '0 * * * * bash /backup-inc.sh >> /var/log/cronj.log 2>&1' > /etc/cron.d/backups \ + && echo '' >> /etc/cron.d/backups \ + && chmod 0644 /etc/cron.d/backups \ + && crontab /etc/cron.d/backups \ + && touch /var/log/cronj.log + +### on enter/exit, rsync to/from /var/lib/mysql and /mnt +ENTRYPOINT true \ + && bash /restore.sh \ + && bash /backup.sh \ + && for s in mysql nginx php7.2-fpm cron; do service $s restart ; done && sleep 10 \ + && exec /xfer/pauser diff --git a/firefly/ubuntu-old/build.sh b/firefly/ubuntu-old/build.sh new file mode 100755 index 0000000..261a8e0 --- /dev/null +++ b/firefly/ubuntu-old/build.sh @@ -0,0 +1,6 @@ +#! /bin/bash + +set -e + +docker build -t dev:dev . +docker run --rm -it -p 8031:8031 dev:dev diff --git a/firefly/ubuntu-old/env b/firefly/ubuntu-old/env new file mode 100755 index 0000000..98f8a5a --- /dev/null +++ b/firefly/ubuntu-old/env @@ -0,0 +1,102 @@ +# You can leave this on "local". If you change it to production most console commands will ask for extra confirmation. +# Never set it to "testing". +APP_ENV=local + +# Set to true if you want to see debug information in error screens. +APP_DEBUG=true + +# This should be your email address +SITE_OWNER=admin@email.com + +# The encryption key for your database and sessions. Keep this very secure. +# If you generate a new one all existing data must be considered LOST. +# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it +APP_KEY=11111111111111111111111111111111 + +# Change this value to your preferred time zone. +# Example: Europe/Amsterdam +TZ=America/Chicago + +# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy. +APP_URL=http://localhost +TRUSTED_PROXIES= + +# The log channel defines where your log entries go to. +LOG_CHANNEL=daily + +# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III +# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=fireflyiii +DB_USERNAME=fireflyiii +DB_PASSWORD=pwd + +# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/. +# Several other options exist. You can use 'single' for one big fat error log (not recommended). +# Also available are 'syslog' and 'errorlog' which will log to the system itself. +APP_LOG=daily + +# Log level. You can set this from least severe to most severe: +# debug, info, notice, warning, error, critical, alert, emergency +# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably +# nothing will get logged, ever. +APP_LOG_LEVEL=notice + +# If you're looking for performance improvements, you could install memcached. +CACHE_DRIVER=file +SESSION_DRIVER=file + +# Cookie settings. Should not be necessary to change these. +COOKIE_PATH="/" +COOKIE_DOMAIN= +COOKIE_SECURE=false + +# If you want Firefly III to mail you, update these settings +MAIL_DRIVER=smtp +MAIL_HOST=smtp.server.com +MAIL_PORT=587 +MAIL_FROM= +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_ENCRYPTION=tls + +# Firefly III can send you the following messages +SEND_REGISTRATION_MAIL=true +SEND_ERROR_MESSAGE=true + +# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. +MAPBOX_API_KEY= + +# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates. +# Please note that this will only work for paid fixer.io accounts because they severly limited +# the free API up to the point where you might as well offer nothing. +FIXER_API_KEY= + +# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here. +ANALYTICS_ID= + +# Most parts of the database are encrypted by default, but you can turn this off if you want to. +# This makes it easier to migrate your database. Not that some fields will never be decrypted. +USE_ENCRYPTION=true + +# Leave the following configuration vars as is. +# Unless you like to tinker and know what you're doing. +APP_NAME=FireflyIII +BROADCAST_DRIVER=log +QUEUE_DRIVER=sync +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 +CACHE_PREFIX=firefly +SEARCH_RESULT_LIMIT=50 +PUSHER_KEY= +PUSHER_SECRET= +PUSHER_ID= +DEMO_USERNAME= +DEMO_PASSWORD= +IS_DOCKER=true +IS_SANDSTORM=false +BUNQ_USE_SANDBOX=false +IS_HEROKU=false diff --git a/firefly/ubuntu-old/firefly-iii.conf b/firefly/ubuntu-old/firefly-iii.conf new file mode 100755 index 0000000..5ef095f --- /dev/null +++ b/firefly/ubuntu-old/firefly-iii.conf @@ -0,0 +1,29 @@ +server { + listen 8031; + listen [::]:8031; + + root /opt/firefly-iii/public; + + # Add index.php to the list if you are using PHP + client_max_body_size 300M; + index index.html index.htm index.php; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + location ~ \.php$ { + try_files $uri =404; + fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + + } + + index index.php index.htm index.html; + + location / { + try_files $uri $uri/ /index.php?$query_string; + autoindex on; + sendfile off; + } +} diff --git a/firefly/ubuntu-old/pause/main.c b/firefly/ubuntu-old/pause/main.c new file mode 100755 index 0000000..3528e94 --- /dev/null +++ b/firefly/ubuntu-old/pause/main.c @@ -0,0 +1,20 @@ +#include +#include +#include + +int main() { + int stat; + int sig; + sigset_t set; + sigemptyset(&set); + printf("add signal SIGINT: %i\n", sigaddset(&set, SIGINT)); + printf("add signal SIGKILL: %i\n", sigaddset(&set, SIGKILL)); + printf("add signal SIGTERM: %i\n", sigaddset(&set, SIGTERM)); + sigprocmask(SIG_BLOCK, &set, NULL); + printf("Waiting...\n"); + stat = sigwait(&set, &sig); + printf("Wait complete: %i (%i)\n", sig, stat); + printf("Backed incremental: %i\n", system("bash /backup-inc.sh")); + printf("Stopped mysql: %i\n", system("mysqladmin shutdown -ppwd")); + return 0; +} diff --git a/firefly/ubuntu-old/script.sh b/firefly/ubuntu-old/script.sh new file mode 100755 index 0000000..4d3adb2 --- /dev/null +++ b/firefly/ubuntu-old/script.sh @@ -0,0 +1,50 @@ +#! /bin/bash + +set -e +set -u + +apt -y update && apt -y upgrade && apt -y autoremove +DEBIAN_FRONTEND=noninteractive apt -y install tzdata +apt -y install vim locales language-pack-en-base + +echo '127.0.0.1 firefly-iii-domain.com firefly-iii localhost' >> /etc/hosts + +apt -y install fail2ban + +apt -y install mariadb-server nginx php-fpm php7.2-mysql php-curl php-gd php-bcmath php-zip php-intl php-mbstring php-xml + +service mysql start +echo 'FLUSH PRIVILEGES; ' \ + 'USE mysql; ' \ + 'UPDATE user SET authentication_string=PASSWORD("pwd") WHERE User='"'"'root'"'"'; ' \ + 'UPDATE user SET plugin="mysql_native_password" WHERE User='"'"'root'"'"'; ' \ + | mysql -u root || true +service mysql restart +sleep 5 + +echo 'create database fireflyiii character set utf8 collate utf8_bin; ' \ + 'grant all privileges on fireflyiii.* to fireflyiii@localhost identified by '"'"'pwd'"'"'; ' \ + | mysql -uroot -ppwd +service mysql restart + +apt -y install curl +curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +cd /opt +composer create-project grumpydictator/firefly-iii --no-dev --prefer-dist firefly-iii 4.7.4 + +cp /copied/env /opt/firefly-iii/.env + +cd firefly-iii +php artisan migrate:refresh --seed +php artisan passport:install + +chown -R www-data:www-data /opt/firefly-iii/ + +rm /etc/nginx/sites-enabled/default +touch /etc/nginx/sites-available/firefly-iii.conf +ln -s /etc/nginx/sites-available/firefly-iii.conf /etc/nginx/sites-enabled/firefly-iii.conf +openssl dhparam 2048 > /etc/nginx/dhparam.pem +cp /copied/firefly-iii.conf /etc/nginx/sites-enabled/firefly-iii.conf + +mkdir -p /run/php diff --git a/ledger/cli/Dockerfile b/ledger/cli/Dockerfile new file mode 100755 index 0000000..b31e69e --- /dev/null +++ b/ledger/cli/Dockerfile @@ -0,0 +1,6 @@ +FROM dcycle/ledger:1 + +RUN touch /tmp/test + +#CMD [] +#ENTRYPOINT ["./ledger", "-f", "/tmp/test", "reg"] diff --git a/mizzer/economizzer b/mizzer/economizzer new file mode 100755 index 0000000..6efa10d --- /dev/null +++ b/mizzer/economizzer @@ -0,0 +1,23 @@ +FROM centos:7.5.1804 + +RUN yum install -y epel-release yum-utils \ + && yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm \ + && yum-config-manager --enable remi-php72 \ + && yum install -y php php-common php-opcache php-mcrypt php-cli php-gd php-curl php-mysqlnd + +RUN yum install -y libapache2-mod-php php-mbstring php-xml git unzip + +RUN cd / \ + && curl -sS https://getcomposer.org/installer \ + | php + +RUN yum install -y php-pecl-zip + +RUN cd / \ + && git clone https://github.com/gugoan/economizzer.git \ + && ls \ + && cd /economizzer \ + && php /composer.phar global require "fxp/composer-asset-plugin:^1.3.1" phpoffice/phpspreadsheet ext-zip kartik-v/yii2-export \ + && php /composer.phar install + +ENTRYPOINT ["bash"] diff --git a/mizzer/economizzer-build.sh b/mizzer/economizzer-build.sh new file mode 100755 index 0000000..c4243ca --- /dev/null +++ b/mizzer/economizzer-build.sh @@ -0,0 +1,3 @@ +#! /bin/bash +cd "$(dirname "${BASH_SOURCE[0]}")" +docker build -f economizzer -t dev:dev . diff --git a/silverstrike/.Dockerfile b/silverstrike/.Dockerfile new file mode 100755 index 0000000..a1b4edd --- /dev/null +++ b/silverstrike/.Dockerfile @@ -0,0 +1,46 @@ +FROM ubuntu:18.04 as builder + +### SYS +RUN export DEBIAN_FRONTEND=noninteractive; \ + apt -y update || true; \ + apt -y install tzdata; \ + ln -fs /usr/share/zoneinfo/America/Denver /etc/localtime; \ + dpkg-reconfigure --frontend noninteractive tzdata; \ + apt -y install \ + curl \ + rsync \ + cron \ + postgresql postgresql-contrib \ + && mkdir -p /mnt/save + +### APP +RUN \ + apt install nginx postgresql uwsgi uwsgi-plugin-python3 python3-venv git + +### POSTGRES +RUN useradd -d /home/postgres -ms /bin/bash -g postgres -G sudo postgres +USER postgres +RUN service postgresql start && sleep 10 \ + && psql --command "CREATE USER ss WITH SUPERUSER PASSWORD 'ss';" \ + && createdb -O ss ss \ + && psql --command "CREATE DATABASE silverstrikedb;" \ + && psql --command "GRANT ALL PRIVILEGES ON DATABASE silverstrikedb TO ss;" +USER root + +### CRON BACKUPS +RUN true \ + && echo 'b=$(date +%Y%m%d%H%M%S) && mkdir -p /mnt/save/$b && pg_dump $DATABASE_URL --clean > /mnt/save/$b/pg.dump' > /backup.sh \ + && echo 'b=$(find /mnt/save -type f | sort | tail -n 1); if [ -n "$b" ]; then echo restoring $b; psql $DATABASE_URL < "$b"; fi && service postgresql start;' > /restore.sh \ + && echo '0 4,8,12,16,20 * * * bash /backup.sh >> /var/log/cronj.log 2>&1' > /etc/cron.d/backups \ + && echo '' >> /etc/cron.d/backups \ + && chmod 0644 /etc/cron.d/backups \ + && touch /var/log/cronj.log + +### FINAL +ENV DATABASE_URL=postgres://ss:ss@localhost/silverstrikedb?sslmode=disable +ENV SECRET_KEY=AimmBfzjdWcVN3rQs8YawbUowv5R8Eex +ENV ALLOWED_HOSTS=* +ENTRYPOINT \ + until psql $DATABASE_URL < /dev/null; do sleep 5; done \ + && bash /restore.sh \ + && sleep 5 && python manage.py migrate && exec uwsgi diff --git a/silverstrike/fork/.dockerignore b/silverstrike/fork/.dockerignore new file mode 100755 index 0000000..a6ca656 --- /dev/null +++ b/silverstrike/fork/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +**/*.sw* diff --git a/silverstrike/fork/Dockerfile b/silverstrike/fork/Dockerfile new file mode 100755 index 0000000..580658c --- /dev/null +++ b/silverstrike/fork/Dockerfile @@ -0,0 +1,42 @@ +FROM ubuntu:18.04 + +# Copy the code +ADD . /code +WORKDIR /code + +# install deps +RUN apt-get update && apt-get install -y gcc libmariadbclient-dev python3-dev python3-pip && \ + pip3 install --no-cache-dir -r requirements.txt && \ + apt-get remove -y gcc && apt-get autoremove -y + +# configure django +ENV DJANGO_SETTINGS_MODULE=settings + +# configure uwsgi +ENV UWSGI_WSGI_FILE=wsgi.py UWSGI_HTTP=:8000 UWSGI_MASTER=1 UWSGI_WORKERS=2 UWSGI_THREADS=8 UWSGI_UID=1000 UWSGI_GID=2000 UWSGI_LAZY_APPS=1 UWSGI_WSGI_ENV_BEHAVIOR=holy + +# collect static files +RUN python3 manage.py collectstatic + +#### POSTGRES +RUN \ + apt -y install \ + curl \ + rsync \ + cron \ + postgresql postgresql-contrib \ + sudo \ + && mkdir -p /mnt/save \ + && service postgresql start +USER postgres +RUN service postgresql start \ + && psql --command "CREATE USER ss WITH SUPERUSER PASSWORD 'ss';" \ + && psql --command "CREATE DATABASE silverstrikedb;" \ + && psql --command "GRANT ALL PRIVILEGES ON DATABASE silverstrikedb TO ss;" +USER root + +ENV ALLOWED_HOSTS=* +ENV DATABASE_URL=postgres://ss:ss@localhost/silverstrikedb +ENV SECRET_KEY=AimmBfzjdWcVN3rQs8YawbUowv5R8Eex + +CMD service postgresql start && (until psql $DATABASE_URL < /dev/null; do sleep 5; done) && python3 manage.py migrate && uwsgi diff --git a/silverstrike/fork/LICENSE b/silverstrike/fork/LICENSE new file mode 100755 index 0000000..b5430f8 --- /dev/null +++ b/silverstrike/fork/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 - 2018 Simon Hanna + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/silverstrike/fork/docker-compose.yml b/silverstrike/fork/docker-compose.yml new file mode 100755 index 0000000..4b97573 --- /dev/null +++ b/silverstrike/fork/docker-compose.yml @@ -0,0 +1,21 @@ +--- +version: "3.2" +services: + app: + environment: + - ALLOWED_HOSTS='*' + - DATABASE_URL=postgres://silverstrike:secretpass@database/silverstrikedb + - SECRET_KEY=PLprXpLzxemgLD57GPQQ84SBZdLVKFYg + image: simhnna/silverstrike + links: + - database:database + ports: + - 8000:8000 + database: + environment: + POSTGRES_DB: silverstrikedb + POSTGRES_USER: silverstrike + POSTGRES_PASSWORD: secretpass + image: postgres:10.3 + volumes: + - ./silverstrikedb:/var/lib/postgresql/data diff --git a/silverstrike/fork/manage.py b/silverstrike/fork/manage.py new file mode 100755 index 0000000..7646e46 --- /dev/null +++ b/silverstrike/fork/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) + raise + execute_from_command_line(sys.argv) diff --git a/silverstrike/fork/master.zip b/silverstrike/fork/master.zip new file mode 100755 index 0000000000000000000000000000000000000000..c021b414430c45e4e0f58b97419ca59e868d0955 GIT binary patch literal 5550 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 z z%X;Ix*vb-&VFzhkPvG=%7q#uTzNOtb)@M}`G1{>0I}62O7O3p5k;#4Zl4~*Nz`Cqs z25yFj zK9m+M&b-@r88~h~?56;nadRe0KF^@#rLecFDC_|1HfFR{5nq0V63yIQAgbpKM#=S8 z_<1|PE?NGOycW6uN%Za+Wm*AKSB<%bRCX9`LN{8%z(RBW0xwKbLo)0<2;Z^0%Z@MY zWF*M_U+Euh&1#E^k@IMQs#ZwyUd5p8CNi78Fv}D{`(@G(s?O_2Wp|J_h5ZGwANUbH z+E^}6Yr88SB#dm3fH+8wWGc+x=vXKFz{&hhd;F(Tn4r`gL7R_QWWsI8S~g?4;N-51XRjI{kS$ z^b7PKT;w&}A67+IaaY$Czj0zHQ(V^W>JsBB>*_T5o3(>lid<&>_urpp%U@V3j9*^( z&x@}PPyfU2gd3om-OJePqtsO;ulDNyqX7WII9F-^*tuVYUhTYpLtCyv|I~+H /mnt/save/$b/pg.dump' > /backup.sh \ + && echo 'b=$(find /mnt/save -type f | sort | tail -n 1); if [ -n "$b" ]; then echo restoring $b; psql $DATABASE_URL < "$b"; fi && service postgresql start;' > /restore.sh \ + && echo '0 4,8,12,16,20 * * * bash /backup.sh >> /var/log/cronj.log 2>&1' > /etc/cron.d/backups \ + && echo '' >> /etc/cron.d/backups \ + && chmod 0644 /etc/cron.d/backups \ + && touch /var/log/cronj.log + +### FINAL +ENV DATABASE_URL=postgres://www-data:password@localhost/silverstrikedb?sslmode=disable +ENV SECRET_KEY=AimmBfzjdWcVN3rQs8YawbUowv5R8Eex +ENV ALLOWED_HOSTS=* +ENTRYPOINT \ + until psql $DATABASE_URL < /dev/null; do sleep 5; done \ + && bash /restore.sh \ + && sleep 5 && python manage.py migrate && exec uwsgi diff --git a/silverstrike/scratch/settings.py b/silverstrike/scratch/settings.py new file mode 100755 index 0000000..4b51dcd --- /dev/null +++ b/silverstrike/scratch/settings.py @@ -0,0 +1,178 @@ +""" +Django settings for SilverStrike. + +Generated by 'django-admin startproject' using Django 1.10.3. + +For more information on this file, see +https://docs.djangoproject.com/en/1.10/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.10/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'AimmBfzjdWcVN3rQs8YawbUowv5R8Eex' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [ + "192.168.0.86", + "firefly2.scratch.com", + "silverstrike.scratch.com", +] + +SITE_ID = 1 + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.humanize', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django.contrib.sites', + 'widget_tweaks', + 'silverstrike', + 'allauth', + 'allauth.account', + 'allauth.socialaccount', + 'rest_framework', + 'rest_framework.authtoken', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.10/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } + #'default': { + # 'ENGINE': 'django.db.backends.postgresql_psycopg2', + # 'NAME': 'silverstrikedb', + # 'USER': 'www-data', + # 'PASSWORD': 'password', + #} + #'default': { + # 'ENGINE': 'django.db.backends.mysql', + # 'NAME': 'silverstrikedb', + # 'USER': 'silverstrike', + # 'PASSWORD': 'password', + #} +} + + +# Password validation +# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'allauth.account.auth_backends.AuthenticationBackend', +) + + +# Internationalization +# https://docs.djangoproject.com/en/1.10/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.10/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'public', 'static') + + +LOGIN_REDIRECT_URL = 'index' +LOGIN_URL = 'account_login' +LOGOUT_URL = 'account_logout' +ACCOUNT_LOGOUT_REDIRECT_URL = 'account_login' + +ACCOUNT_ADAPTER = 'signupadapter.SignupDisabledAdapter' + +LOGGING = { + 'version': 1, + 'filters': { + 'require_debug_true': { + '()': 'django.utils.log.RequireDebugTrue', + } + }, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'filters': ['require_debug_true'], + 'class': 'logging.StreamHandler', + } + } +} + diff --git a/silverstrike/scratch/try b/silverstrike/scratch/try new file mode 100755 index 0000000..9bdfcac --- /dev/null +++ b/silverstrike/scratch/try @@ -0,0 +1 @@ +docker build -t bel/silverstrike:v0.0 -f Dockerfile . && docker run --rm -it --name ss -p 51131:8000 --entrypoint bash bel/silverstrike:v0.0