Skip to content
This repository has been archived by the owner on Apr 9, 2020. It is now read-only.

Commit

Permalink
Docker and NKUST version (#36)
Browse files Browse the repository at this point in the history
* Add Dockerfile and docker-compose.yml

* Fix flask import error

* Fix redis error and flask autodoc import

* Update feature news get content

* Fix bus and user info error

Remove:
 login limit
Add:
 bus data is None judgement

* Add login limit

* Add SSL setting

* Update host to nkust host

* Fix kuas to nkust

* Fix error text

* Fix python error

* Update for return is login

* Fix image path to nkust

* Add gunicorn and caddy

Add:
 fake ssl cert

* Update redis cookies rules

Update:
 caddy settings
 docker-compose.yml

* Reset gunicorn settings

Fix:
 nkust image path

* Fix docker-compose error

* Fix ssl port error

* Update redis setting

* Update feature get user info

* Update deploy config

* Update docker-compose.yml

Remove:
 docker-compose useless config
Update:
 docker-hub source for web image

* Fix http router error and update deploy config

* Update README.md

* Update README.md

* Fix get_semester_list error

* fix get_semester_list and use redis.

* fix import error in ap.py.

* fix leave login issues

* Fix leave approved >= 2

* Update README.md and docker-compose.yml

* Update README.md
  • Loading branch information
abc873693 authored Mar 10, 2019
1 parent 783bd36 commit 56d3716
Show file tree
Hide file tree
Showing 26 changed files with 374 additions and 85 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,9 @@ test_page.html
html/
src/config.py
src/gunicorn_cfg.py

\.vscode/

\.idea/
caddy/Caddyfile
\.env
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Base image
FROM python:3.6
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY . /usr/src/app

RUN pip3 install -r ./requirements.txt

RUN apt-get update && \
apt-get install -y nodejs

WORKDIR /usr/src/app/src
File renamed without changes.
74 changes: 69 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,89 @@
[![Build Status](https://travis-ci.org/kuastw/AP-API.svg?branch=master)](https://travis-ci.org/kuastw/AP-API)
[![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/release/python-360/)

KUAS - API
NKUST - API
==========

高雄應用科技大學 API Server
KUAS API Server
高雄科技大學 API Server NKUST API Server
---------------------------
Requirement
---
- Ubuntu (18.04 or previous version)
- Python 3.6
- Redis server
- NodeJS (if host by python venv)

How to use?
---
### Clone project
```
$ git clone https://github.com/kuastw/AP-API
$ git clone https://github.com/NKUST-ITC/AP-API
$ cd AP-API
```
By python venv
---
```
$ python -m venv venv
$ source venv/bin/activate
$ pip install -r requirement.txt
$ pip install -r requirements.txt
$ redis-server &
$ python src/web-server.py
```
By docker
---
Requirement
* Redis instance running on localhost

Need to add environment variable **-e REDIS_URL=redis://127.0.0.1:6379/0**

or by export

```
$ export REDIS_URL=redis://127.0.0.1:6379/0
```

And let docker run host network need add **--network="host"**

Otherwise redis config by docker network(see docker-compose.yml config)

Arguments **gunicorn_cfg.py web-server:app** is production flask uWSGI
```
$ sudo docker run --network="host" nkustitc/ap-api:latest gunicorn -c gunicorn_cfg.py web-server:app
```
or replace by **python3 web-server.py**
```
$ sudo docker run --network="host" nkustitc/ap-api:latest python3 web-server.py
```
By docker-compose
---
Copy .env example
- CADDY_HOST_HTTPS_PORT -> caddy https host port
- REDIS_URL -> python request redis url
```
$ cp env.example .env
```
Copy caddy host config example
```
$ cd caddy
$ cp Caddyfile.example Caddyfile
```
Edit **Caddyfile**'s host config**(Production)**
- line 1 **0.0.0.0:2087** replace by you want host domain and port
```
0.0.0.0:2087 {
proxy / https://web:14769 {
transparent
insecure_skip_verify
}
gzip
tls [email protected]
}
```
start docker-compose (if need re download package, can add **--build** build by Dockerfile)
```
$ sudo docker-compose up
```
---
Fixed APIBlueprint
---
You must fixed manually about flask_apiblueprint
Expand Down
8 changes: 8 additions & 0 deletions caddy/Caddyfile.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
0.0.0.0:2087 {
proxy / https://web:14769 {
transparent
insecure_skip_verify
}
gzip
tls [email protected]
}
46 changes: 46 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
version: '3.6'
services:
web:
image: "nkustitc/ap-api:latest"
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/usr/src/app
ports:
- "2087":2087"
environment:
- REDIS_URL=${REDIS_URL}
command: [ "gunicorn","-c","gunicorn_cfg.py","web-server:app"]
networks:
- redis-net
- front-end
depends_on:
- redis
redis:
image: "redis:alpine"
volumes:
- redis-data:/data
networks:
- redis-net
caddy:
image: "abiosoft/caddy:latest"
volumes:
- ./caddy/Caddyfile:/etc/Caddyfile
- ./caddy/path:/root/.caddy
ports:
- "2015:2015"
- "80:80"
- "443:443"
- "${CADDY_HOST_HTTPS_PORT}:2087"
environment:
- ACME_AGREE=true
depends_on:
- web
networks:
- front-end
networks:
redis-net:
front-end:
volumes:
redis-data:
5 changes: 5 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CADDY_HOST_HTTPS_PORT=2087

REDIS_URL=redis://redis:6379/0
# if use docker => redis://redis:6379/0
# else => redis://localhost:6379/0
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
flask
flask<1.0
flask_apiblueprint
flask_autodoc
flask_cors
Expand All @@ -12,3 +12,4 @@ lxml
pyexecjs
sphinxcontrib-httpdomain
gunicorn
pyopenssl
26 changes: 26 additions & 0 deletions src/cert/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEUjCCArqgAwIBAgIQKIdZXn4Uzzcwr6Wwj3SPMDANBgkqhkiG9w0BAQsFADB/
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExKjAoBgNVBAsMIXJhaW52
aXNpdG9yQFJheS1NYWNCb29rLVByby5sb2NhbDExMC8GA1UEAwwobWtjZXJ0IHJh
aW52aXNpdG9yQFJheS1NYWNCb29rLVByby5sb2NhbDAeFw0xOTAyMDUwOTE2MTha
Fw0yOTAyMDUwOTE2MThaMFcxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBj
ZXJ0aWZpY2F0ZTEsMCoGA1UECwwjcmFpbnZpc2l0b3JAUmF5LU1hY0Jvb2stUHJv
LTcubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC036vGvUvo
4sDPKmbPogPpEAlZm3wBrxqNpLmpwzLUpdLcNNQc76hJdIA0vQr3PTwrtJNKHSwk
2glgNNCvOPm2tkoTQ0nFUQftamcec5WFpEh9fIeSCQYp148ppCbrKFZzHjiaw5nv
KNi49nFvGl9lpiHaCpiX/EEblS1RVDFbfgR+i74YlKEm/+hgtYExuoBLpNY5wmM3
qe7oc0+H3qNH1YTIU33nF/w5IZy+3n+2oQ9CouO/I3sWVcBldRwaJm79QYcyPP8R
ubr/HfZXFmOh2FH4iPzjED8o+RZpJlWj5GV/nh9JbrS1ty7Nrm8rWRaPPcP0SUEp
3J5vjH220FZ9AgMBAAGjcjBwMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr
BgEFBQcDATAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFHdyNMG+3niwN+1Xxdbv
J6P0LPijMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsF
AAOCAYEAo4SrbX1gmZKUhP77W25TFiNyKXt9nGz2/QB3IKU++/MP3kLk0WduNkHT
HfAj//NHKcJSBsQ3HWTuLe2Qeei/qfeNUM8GTm2va0eOZKs4YynkILm05orfnbDb
bndz3VQ2Ee/5kvjX0xWAjouyV1Z/3z2nbhK6UNFZvc0oMYi/vkXQ7227Pc+MOs9K
KJcvyTwnOUDDLKpmrGi83XpiJKsaCm/7vwQ4V9Pom47mT0lFJ+YXUPBzCkLGpFiP
ax2tsJgdIaqkZK79Vs2B8f/vtgf+mshPUZ+7OFGcdlXHcK3LlzmpuoDJaz+4rvKu
Ox7JK0WU20tMNnYL36Pe9PV7CuTJpiwbZuOAtNbuaHy8E9QoHLeKmu8z2oQzWz17
C3CuTPaj7mhSEvcQoxywZJ0+y+CPPx5BNOHTfV+IHYIMSFymGDrJh9ge6McsUvP3
w8Jy8j30guFmgTA0Q3I2ohLe8uPhN0Fk9sSrV+I/sEYcIbQkrr2Z0bNOfISPl5fs
xgKfEVpC
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions src/cert/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC036vGvUvo4sDP
KmbPogPpEAlZm3wBrxqNpLmpwzLUpdLcNNQc76hJdIA0vQr3PTwrtJNKHSwk2glg
NNCvOPm2tkoTQ0nFUQftamcec5WFpEh9fIeSCQYp148ppCbrKFZzHjiaw5nvKNi4
9nFvGl9lpiHaCpiX/EEblS1RVDFbfgR+i74YlKEm/+hgtYExuoBLpNY5wmM3qe7o
c0+H3qNH1YTIU33nF/w5IZy+3n+2oQ9CouO/I3sWVcBldRwaJm79QYcyPP8Rubr/
HfZXFmOh2FH4iPzjED8o+RZpJlWj5GV/nh9JbrS1ty7Nrm8rWRaPPcP0SUEp3J5v
jH220FZ9AgMBAAECggEAVv28gDlK6Rcl5H1gNTyW5ODxnkdJvQWan8U6Bov7Ror6
fy5pVgFtzuZZQwQo4gBxkBOpQ1wEfzTejYbZV2zvrRC/T8RtFpmCVo12Sw8MOtpo
gvIBwhrU/ArQsBZjIXalHXjLgKPSxVO/6DWfGPB2MU1Vuqid+3s3VSzKPvNfScDj
Go64l1FiVD0rMOw4jVcjMNVOSB/HVfaaexHX+CeHaZ9cKHkGxxDUscBbJieKp2nc
dz4pFDZBsVVQx/jn1uF8p5FqLweJw5yMhVXovYZfQd/06ImDppTzHn/JUoadmMy+
U3eZOERIIm6tSw0kOWNuUTrPOth8ezRxuOiPG5DPgQKBgQDcuacCnPmy++7mYVLv
iH9q+AnMB4LfFjqpxW0nnESeyJtwIL1y6+vCx4WdsBLU5ia7mt3fWpCiIg9ZCzXP
YFyA+VGjm6SNkuxjrMIUD+crMpAJqUL23HcBUqPDUhXBRrhNiTpGOhOzn6sH0IaM
XgPKZA/B+07TUgMAoCpap+1Y1wKBgQDRx5uLnMqLGerOruLhwxfc3Sch3i/L8iZd
bHmn+BSxczdvS6t9mHq/h8onSgfTwcHEcTwMTO2iUFojioJ8KLCPmUOxKhLp/2aM
2HJheHFCw37vnYQKUDXAaICqAeIvybnPcvaWZal9heDhpZ1+8rJHUpwzb/L2Y8xB
spTAheu8ywKBgQCTgK2PHX/wkFOyOU/HKxybS26gnlRi6OQDGCA93DwvMDhP0lFI
P0iqPdOY8VVkWPmBXZjv7gHBl6lSBB/NmcO3nOVlxFlPEuROJ+D6rzX4tC11h1ts
xR/yDlvJ500KgEwh5JbA34bS/ty4uC1yGFHIKt4s79hZd/DxthcXxijiuQKBgH35
CswE5JAxiRKCbNY7rInB+CzbWwJysF0rtcaLMAn7cU+RNjMerJ91cIy1ZQvhb3WC
theA3ra439g15fOfD5+73q114ZPI/hEYLV+gzwrTkNddVJxI3G5lktYEeYpO7hjI
JZHdDLHHAmseY/yGy04PKqOs107kURUmozMVeKGPAoGAS+jcQ8cTUZDEH4L11SY2
Md5jmA7NMkPsz0Iz1xr6yDLMl4tc0NDLDcMp1P7ctZJlEV9gU88cKMhMfXxOJ+U7
1PBJJa5tRsYVzgXcbQX56Hmbte6PbQpWcmQ5Cu1ZP8kdmNL/QNmHxHNkWDto73NC
WHz8l7Z0xZnmpZO6amvlIrM=
-----END PRIVATE KEY-----
4 changes: 2 additions & 2 deletions src/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import os
#DEBUG = True
SECRET_KEY = "change secret key in production"
DEBUG = True
SECRET_KEY = "sdfsdhpmrgewf"
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = True
#PERMANENT_SESSION_LIFETIME = timedelta(minutes=10)
Expand Down
2 changes: 2 additions & 0 deletions src/gunicorn_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
bind = "0.0.0.0:14769"

# SSL
certfile="./cert/cert.pem"
keyfile="./cert/key.pem"

# Performance
workers = 3
Expand Down
6 changes: 4 additions & 2 deletions src/kuas_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from flask import Flask
import flask_admin as admin
from flask_sqlalchemy import SQLAlchemy
from flask.ext.compress import Compress
from flask_compress import Compress
import os

__version__ = "2.0"

Expand All @@ -26,7 +27,8 @@

# Let secret key go in
import redis
red = redis.StrictRedis(db=2)
red = redis.StrictRedis.from_url(url= os.environ['REDIS_URL'],db=2)

red.set("SECRET_KEY", str(app.config["SECRET_KEY"]))


Expand Down
34 changes: 19 additions & 15 deletions src/kuas_api/kuas/ap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import requests
from lxml import etree

# AP URL Setting
#: AP sytem base url
AP_BASE_URL = "http://webap.nkust.edu.tw"
Expand All @@ -27,7 +26,6 @@
# Timeout Setting
#: Login timeout
LOGIN_TIMEOUT = 5.0

#: Query timeout
QUERY_TIMEOUT = 5.0

Expand Down Expand Up @@ -110,15 +108,21 @@ def get_semester_list():
s = requests.Session()
login(s, AP_GUEST_ACCOUNT, AP_GUEST_PASSWORD)

content = query(s, "ag304_01")
content = cache.ap_query(s, "ag304_01")
if len(content)<3000:
return False
root = etree.HTML(content)

options = root.xpath("id('yms_yms')/option")
options = map(lambda x: {"value": x.values()[0].replace("#", ","),
"selected": 1 if "selected" in x.values() else 0,
"text": x.text},
root.xpath("id('yms_yms')/option")
)
#options = root.xpath("id('yms_yms')/option")
try:
options = map(lambda x: {"value": x.values()[0].replace("#", ","),
"selected": 1 if "selected" in x.values() else 0,
"text": x.text},
root.xpath("id('yms_yms')/option")
)
except:
return False

options = list(options)

return options
Expand Down Expand Up @@ -165,9 +169,9 @@ def query(session, qid, args={}):
"fncid": "", "uid": ""}

data['fncid'] = qid

for key in args:
data[key] = args[key]
if args != None:
for key in args:
data[key] = args[key]

try:
resp = session.post(AP_QUERY_URL % (qid[:2], qid),
Expand All @@ -178,10 +182,10 @@ def query(session, qid, args={}):
content = resp.text
except requests.exceptions.ReadTimeout:
content = ""

return content


if __name__ == "__main__":
import doctest
doctest.testmod()
#import doctest
#doctest.testmod()
print(get_semester_list())
16 changes: 9 additions & 7 deletions src/kuas_api/kuas/bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,15 @@ def reserve(session):
resource = json.loads(content)

rd = []
for i in resource['data']:
data = {}
data['time'] = _get_real_time(i['time'])
data['endTime'] = _get_real_time(i['endTime'])
data['cancelKey'] = i['key']
data['end'] = i['end']
rd.append(data)

if(resource['data'] is not None):
for i in resource['data']:
data = {}
data['time'] = _get_real_time(i['time'])
data['endTime'] = _get_real_time(i['endTime'])
data['cancelKey'] = i['key']
data['end'] = i['end']
rd.append(data)

result = sorted(rd, key=lambda k: k['time'])

Expand Down
Loading

0 comments on commit 56d3716

Please sign in to comment.