Skip to content

Commit

Permalink
feat: add versions (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
psincraian authored Apr 8, 2020
1 parent 77cda42 commit 211d970
Show file tree
Hide file tree
Showing 55 changed files with 799 additions and 790 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ services:

before_install:
- make start-containers
- make migrations

script:
- make tests

addons:
ssh_known_hosts: 174.138.5.205
ssh_known_hosts: 88.99.125.23

before_deploy:
- openssl aes-256-cbc -K $encrypted_c7065a1712c1_key -iv $encrypted_c7065a1712c1_iv -in infrastructure/playbooks/travis_secrets.tar.enc -out infrastructure/playbooks/travis_secrets.tar -d
Expand Down
8 changes: 1 addition & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,13 @@ start: install
start-containers:
$(DOCKER-COMPOSE) up -d
until curl --silent -XGET --fail http://localhost:5200/health-check; do printf '.'; sleep 1; done
$(DOCKER-COMPOSE) exec pepy pipenv run yoyo apply --database "postgresql://pepy:pepy@pgsql/pepy" infrastructure/migrations/ --no-config-file --batch
$(DOCKER-COMPOSE) exec pepy pipenv run yoyo apply --database "postgresql://pepy:pepy@pgsql/pepy_test" infrastructure/migrations/ --no-config-file --batch

stop-containers:
$(DOCKER-COMPOSE) stop

remove-containers:
$(DOCKER-COMPOSE) down

migrations:
$(DOCKER-COMPOSE) exec pepy pipenv run yoyo apply --database "postgresql://pepy:pepy@pgsql/pepy" infrastructure/migrations/ --no-config-file --batch
$(DOCKER-COMPOSE) exec pepy pipenv run yoyo apply --database "postgresql://pepy:pepy@pgsql/pepy_test" infrastructure/migrations/ --no-config-file --batch

unit-tests:
$(DOCKER-COMPOSE) exec pepy pipenv run pytest tests/unit

Expand All @@ -32,7 +26,7 @@ integration-tests:
acceptance-tests:
$(DOCKER-COMPOSE) exec pepy pipenv run behave tests/acceptance

tests: unit-tests integration-tests acceptance-tests
tests: unit-tests acceptance-tests

format-code:
$(DOCKER-COMPOSE) exec pepy pipenv run black -l 120 --exclude=".*\/node_modules" pepy/ tests/
Expand Down
7 changes: 3 additions & 4 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ click = "*"
commandbus = "*"
google-cloud-bigquery = "*"
gunicorn = "*"
psycopg2-binary = "*"
requests = "*"
yoyo-migrations = "*"
Flask = "*"
Flask-WTF = "*"
passlib = "*"
orator = "*"
pymongo = "*"
natsort = "*"

[dev-packages]
behave = "*"
Expand All @@ -24,7 +23,7 @@ black = "*"
pylint = "*"

[requires]
python_version = "3.7"
python_version = "3.8"

[pipenv]
allow_prereleases = true
341 changes: 77 additions & 264 deletions Pipfile.lock

Large diffs are not rendered by default.

19 changes: 9 additions & 10 deletions infrastructure/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: '3'

services:
pepy:
image: python:3.7
image: python:3.8
environment:
- APPLICATION_ENV=dev
- FLASK_DEBUG=1
Expand All @@ -14,20 +14,19 @@ services:
- .:/srv
working_dir: /srv
links:
- pgsql:pgsql
depends_on:
- pgsql
- mongodb:mongodb

pgsql:
image: postgres:9.6
mongodb:
image: mongo
volumes:
- pepy_pgsql:/var/lib/postgresql
- ./infrastructure/postgres:/docker-entrypoint-initdb.d
- mongodb_data:/datadb
ports:
- "127.0.0.1::5432"
- 27017:27017
hostname: pgsql-master
environment:
- POSTGRES_PASSWORD=test
- MONGO_INITDB_ROOT_USERNAME=pepy
- MONGO_INITDB_ROOT_PASSWORD=pepy

volumes:
pepy_pgsql: {}
mongodb_data: {}
11 changes: 0 additions & 11 deletions infrastructure/migrations/20180308_01_zvLE8-add-projects-table.py

This file was deleted.

This file was deleted.

9 changes: 9 additions & 0 deletions infrastructure/playbooks/group_vars/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,15 @@ admin_password_plain: !vault |
37626361663537323132616635373937363130373536383531633161396236303765
bigquery_credentials_file: "{{ project_directory }}/bigquery.json"

healthchecks_update_downloads_id: !vault |
$ANSIBLE_VAULT;1.1;AES256
37646231396466613638323836333963643165663136616333653237333239633439346133313230
3361346662313935663932306665633265393530333565330a316633393233353030633439326438
39666435353664613736633238386339636566363733656637623563313963383861343832313937
3938356130636133610a643436333634373965646430616464616330343431343337663836366634
66346237633336313666616238393866336334376237343061366632663434616637653338613430
3461323430623632393964623236393363326435643531643336
# Nginx
nginx_static_dir: "{{ project_directory }}/pepy/infrastructure/web/static/"
nginx_access_log_file: "{{ application_log_dir }}/nginx_access.log"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/playbooks/hosts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

[webservers]
root@174.138.5.205 ansible_python_interpreter=/usr/bin/python3
root@88.99.125.23 ansible_python_interpreter=/usr/bin/python3
2 changes: 1 addition & 1 deletion infrastructure/playbooks/provision.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
hosts: all
roles:
- { role: common, become: yes }
- { role: postgres, become: yes }
- { role: mongo, become: yes }
- { role: web, become: yes }
- { role: nginx, become: yes }
10 changes: 9 additions & 1 deletion infrastructure/playbooks/roles/common/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@

- name: Ensure packages are installed
apt:
name: ['supervisor', 'locales', 'python3-venv', 'python3-pip']
name: ['supervisor', 'locales', 'python3-venv', 'python3-pip', 'software-properties-common']
update_cache: yes

- name: add python repository
command: add-apt-repository -y ppa:deadsnakes/ppa

- name: Ensure python packages are installed
apt:
name: ['python3.8', 'python3.8-venv']
update_cache: yes

- name: Create .ssh folder
Expand Down
20 changes: 20 additions & 0 deletions infrastructure/playbooks/roles/mongo/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---

# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/
- block:
- name: Import MongoDB public GPG Key
apt_key:
url: https://www.mongodb.org/static/pgp/server-4.2.asc
- name: Add MongoDB repository into sources list
apt_repository:
repo: deb http://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse
state: present
- name: Install MongoDB package
apt:
name: mongodb-org
update_cache: yes
- name: Make sure mongo is running
systemd:
state: started
name: mongod
enabled: yes
10 changes: 8 additions & 2 deletions infrastructure/playbooks/roles/nginx/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@

- name: Ensure that the application site is enabled
file: src=/etc/nginx/sites-available/{{ project_name }}.conf
dest=/etc/nginx/sites-enabled/{{ project_name }}.conf
state=link
dest=/etc/nginx/sites-enabled/{{ project_name }}.conf
state=link
notify: reload nginx

- name: Ensure Nginx service is started
service: name=nginx state=started enabled=yes

- name: Remove default nginx config
file: name=/etc/nginx/sites-enabled/default state=absent

- name: Reload nginx
service: name=nginx state=restarted
27 changes: 0 additions & 27 deletions infrastructure/playbooks/roles/postgres/tasks/main.yml

This file was deleted.

2 changes: 1 addition & 1 deletion infrastructure/playbooks/roles/web/tasks/crons.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@
name: "update daily downloads"
minute: "0"
hour: "17"
job: "cd {{ project_directory }} && .venv/bin/python -m pepy import:downloads:day --password \"{{ admin_password_plain }}\" || dog event post --alert_type error --tags cli \"Update daily downloads cron failed\" \"Check the cli command or the logs for more info\""
job: "cd {{ project_directory }} && .venv/bin/python -m pepy import:downloads:day --password \"{{ admin_password_plain }}\" && curl -fsS --retry 3 https://hc-ping.com/{{ healthchecks_update_downloads_id }}"
user: "{{ pepy_user }}"
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
---
- name: Upgrade pip and setup tools
command: python3.8 -m pip install -U pip setuptools

- name: Install pipenv
command: pip install pipenv
command: python3.8 -m pip install pipenv

- name: Install dependencies
command: pipenv install
command: pipenv install --deploy
environment:
LC_ALL: C.UTF-8
LANG: C.UTF-8
PIPENV_MAX_SUBPROCESS: 2
PIPENV_VENV_IN_PROJECT: 1
become_user: "{{ gunicorn_user }}"
args:
chdir: "{{ project_directory }}"

- name: Copy bigquery credentials file
copy:
Expand Down
1 change: 0 additions & 1 deletion infrastructure/playbooks/roles/web/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
- include: copy_code.yml
- include: install_dependencies.yml
- include: migrations.yml
- include: webserver.yml
- include: supervisor.yml
- include: crons.yml
9 changes: 0 additions & 9 deletions infrastructure/playbooks/roles/web/tasks/migrations.yml

This file was deleted.

5 changes: 0 additions & 5 deletions infrastructure/postgres/users.sql

This file was deleted.

File renamed without changes.
50 changes: 22 additions & 28 deletions pepy/application/query.py → pepy/application/badge_service.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,57 @@
import math
from typing import List
from datetime import datetime, timedelta

import requests

from pepy.domain.exception import ProjectNotFoundException
from pepy.domain.model import Badge
from pepy.domain.read_model import ProjectProjection, ProjectListProjection
from pepy.domain.view import ProjectView
from pepy.domain.model import Badge, Project, Downloads
from pepy.domain.repository import ProjectRepository


class DownloadsNumberFormatter:
_METRIC_PREFIX = ["", "k", "M", "G", "T", "P"]

def format(self, downloads: int) -> str:
digits = int(math.log10(abs(downloads)) if downloads else 0)
def format(self, downloads: Downloads) -> str:
digits = int(math.log10(abs(downloads.value)) if downloads else 0)
millidx = max(0, min(len(self._METRIC_PREFIX) - 1, digits // 3))
rounded_value = downloads // (10 ** (3 * millidx))
rounded_value = downloads.value // (10 ** (3 * millidx))
return "{}{}".format(rounded_value, self._METRIC_PREFIX[millidx])


class BadgeProvider:
def __init__(self, project_view: ProjectView, downloads_formatter: DownloadsNumberFormatter):
self._project_repository = project_view
class BadgeService:
def __init__(self, project_repository: ProjectRepository, downloads_formatter: DownloadsNumberFormatter):
self._project_repository = project_repository
self._downloads_formatter = downloads_formatter

def generate_badge(self, project_name: str) -> Badge:
project = self._project_repository.find(project_name)
project = self._project_repository.get(project_name)
if project is None:
raise ProjectNotFoundException(project_name)
downloads = self._downloads_formatter.format(project.total_downloads)
r = requests.get("https://img.shields.io/badge/downloads-{}-blue.svg".format(downloads))
return Badge(project_name, r.content.decode("utf-8"))

def generate_last_30_days_badge(self, project_name: str) -> Badge:
project = self._project_repository.find(project_name)
project = self._project_repository.get(project_name)
if project is None:
raise ProjectNotFoundException(project_name)
downloads = self._downloads_formatter.format(project.total_downloads_last_30_days)
downloads = self._downloads_formatter.format(self._last_downloads(project, 30))
r = requests.get("https://img.shields.io/badge/downloads/month-{}-blue.svg".format(downloads))
return Badge(project_name, r.content.decode("utf-8"))

def generate_last_7_days_badge(self, project_name: str) -> Badge:
project = self._project_repository.find(project_name)
project = self._project_repository.get(project_name)
if project is None:
raise ProjectNotFoundException(project_name)
downloads = self._downloads_formatter.format(project.total_downloads_last_7_days)
downloads = self._downloads_formatter.format(self._last_downloads(project, 7))
r = requests.get("https://img.shields.io/badge/downloads/week-{}-blue.svg".format(downloads))
return Badge(project_name, r.content.decode("utf-8"))


class ProjectProvider:
def __init__(self, project_view: ProjectView):
self._project_view = project_view

def find(self, project_name: str) -> ProjectProjection:
project = self._project_view.find(project_name)
if project is None:
raise ProjectNotFoundException(project_name)
return project

def for_home(self) -> List[ProjectListProjection]:
return self._project_view.find_random_projects(10)
@staticmethod
def _last_downloads(project: Project, days: int) -> Downloads:
min_date = datetime.now().date() - timedelta(days=days)
total_downloads = 0
for d in project.last_downloads():
if d.date >= min_date:
total_downloads += d.downloads.value
return Downloads(total_downloads)
Loading

0 comments on commit 211d970

Please sign in to comment.