Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2015012351 #52

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,4 @@ target/

# Custom files
/configs.json
/static/media
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
sudo: required
language: python
python: '3.6'
branches:
only:
- master
env: "-DJANGO=1.9"
services:
- mysql
before_install:
- openssl aes-256-cbc -K $encrypted_0fbea918c27f_key -iv $encrypted_0fbea918c27f_iv
-in configs.json.enc -out configs.json -d
- mysql -e 'create database wechat_ticket_db;'
install:
- pip install -r requirements.txt
script:
- python manage.py makemigrations
- python manage.py migrate
- python manage.py test
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# WeChatTicket
[![Build Status](https://travis-ci.org/Altria-Ex/WeChatTicket.svg?branch=master)](https://travis-ci.org/Altria-Ex/WeChatTicket)<br><br>
Ticket management system based on WeChat public platform.
9 changes: 5 additions & 4 deletions WeChatTicket/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
WECHAT_APPID = CONFIGS['WECHAT_APPID']
WECHAT_SECRET = CONFIGS['WECHAT_SECRET']

ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*']


# Application definition
Expand Down Expand Up @@ -139,13 +139,13 @@

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = True
USE_TZ = False


# Static files (CSS, JavaScript, Images)
Expand All @@ -154,7 +154,8 @@
STATIC_URL = '/'

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
MEDIA_URL = 'static/media/'

# Site and URL
SITE_DOMAIN = CONFIGS['SITE_DOMAIN'].rstrip('/')
Expand Down
14 changes: 13 additions & 1 deletion adminpage/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
# -*- coding: utf-8 -*-
#
from django.conf.urls import url

from adminpage.views import *


__author__ = "Epsirom"


urlpatterns = []
urlpatterns = [
url(r'^login/?$', Login.as_view()),
url(r'^logout/?$', Logout.as_view()),
url(r'^activity/list/?$', ActivityList.as_view()),
url(r'^activity/create/?$', ActivityCreate.as_view()),
url(r'^activity/delete/?$', ActivityDelete.as_view()),
url(r'^activity/detail/?$', ActivityDetail.as_view()),
url(r'^activity/menu/?$', ActivityMenu.as_view()),
url(r'^image/upload/?$', ImageUpload.as_view()),
url(r'^activity/checkin/?$', ActivityCheckin.as_view()),
]
271 changes: 270 additions & 1 deletion adminpage/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,272 @@
from django.shortcuts import render

from codex.baseerror import *
from codex.baseview import APIView
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from wechat.models import Activity
from wechat.models import Ticket
from wechat.views import CustomWeChatView
from WeChatTicket.settings import SITE_DOMAIN
import time
from datetime import datetime, timedelta
# Create your views here.


class Login(APIView):

def get(self):
if not self.request.user.is_authenticated():
raise ValidateError('User not logged in')
return 0

def post(self):
self.check_input('username', 'password')
username = self.input['username']
password = self.input['password']
user = authenticate(username=username, password=password)

if not username:
raise ValidateError('Username is empty!')
if not password:
raise ValidateError('Password is empty!')
if not User.objects.filter(username=username):
raise ValidateError('Username does not exist!')
if not user:
raise ValidateError('Wrong password!')

if user.is_active:
login(self.request, user)
return 0


class Logout(APIView):

def post(self):
if self.request.user.is_authenticated():
logout(self.request)
else:
raise ValidateError('Logout failed!User has not logged in.')


class ActivityList(APIView):

def get(self):
if not self.request.user.is_authenticated():
raise ValidateError('User not logged in!')

activityList = Activity.objects.all()
data = []
for item in activityList:
if item.status >= 0:
temp = {
'id': item.id,
'name': item.name,
'description': item.description,
'startTime': int(time.mktime(item.start_time.timetuple())),
'endTime': int(time.mktime(item.end_time.timetuple())),
'place': item.place,
'bookStart': int(time.mktime(item.book_start.timetuple())),
'bookEnd': int(time.mktime(item.book_end.timetuple())),
'currentTime': int(time.time()),
'status': item.status,
}
data.append(temp)
else:
continue
return data


class ActivityDelete(APIView):

def post(self):
self.check_input('id')
activity = Activity.get_by_id(self.input['id'])
activity.delete()


class ActivityCreate(APIView):
def post(self):
self.check_input('name', 'key', 'place', 'description', 'picUrl', 'startTime', 'endTime', 'bookStart', 'bookEnd', 'totalTickets', 'status')
if not self.request.user.is_authenticated():
raise ValidateError('User not logged in!')
new_activity = Activity(
name = self.input['name'],
key = self.input['key'],
place = self.input['place'],
description = self.input['description'],
pic_url = self.input['picUrl'],
start_time = datetime.strptime(self.input['startTime'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8),
end_time = datetime.strptime(self.input['endTime'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8),
book_start = datetime.strptime(self.input['bookStart'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8),
book_end = datetime.strptime(self.input['bookEnd'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8),
remain_tickets = self.input['totalTickets'],
total_tickets = self.input['totalTickets'],
status = self.input['status']
)
new_activity.save()
return new_activity.id


class ActivityDetail(APIView):

def get(self):
self.check_input('id')
if not self.request.user.is_authenticated():
raise ValidateError('User has not logged in.')
activity = Activity.get_by_id(self.input['id'])
usedTickets = 0
for ticket in activity.ticket_set.all():
if ticket.status == Ticket.STATUS_USED:
usedTickets += 1
data = {
'name': activity.name,
'key': activity.key,
'description': activity.description,
'startTime': int(time.mktime(activity.start_time.timetuple())),
'endTime': int(time.mktime(activity.end_time.timetuple())),
'place': activity.place,
'bookStart': int(time.mktime(activity.book_start.timetuple())),
'bookEnd': int(time.mktime(activity.book_end.timetuple())),
'totalTickets': activity.total_tickets,
'picUrl': activity.pic_url,
'bookedTickets': activity.total_tickets - activity.remain_tickets,
'usedTickets': usedTickets,
'currentTime': int(time.time()),
'status': activity.status
}
return data

def post(self):
self.check_input('id', 'name', 'place', 'description', 'picUrl',
'startTime', 'endTime', 'bookStart', 'bookEnd',
'totalTickets', 'status')
if not self.request.user.is_authenticated():
raise ValidateError('User has not logged in.')
activity = Activity.get_by_id(self.input['id'])
if activity.status == Activity.STATUS_PUBLISHED:
if activity.name != self.input['name']:
raise LogicError('Cannot modify the name of a published activity ')
if activity.place != self.input['place']:
raise LogicError('Cannot modify the place of a published activity')
if activity.book_start != (datetime.strptime(self.input['bookStart'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8)):
raise LogicError('Cannot modify the bookStart time of a published activity')
if self.input['status'] != 1:
raise LogicError('you cannot stage published activity')

if int(time.mktime(activity.end_time.timetuple())) < int(time.time()):
if activity.start_time != (datetime.strptime(self.input['startTime'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8)):
raise LogicError('Cannot modify startTime of a activity ended')
if activity.end_time != (datetime.strptime(self.input['endTime'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8)):
raise LogicError('Cannot modify endTime of a activity ended')

if int(time.mktime(activity.start_time.timetuple())) < int(time.time()):
if activity.book_end != (datetime.strptime(self.input['bookEnd'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8)):
raise LogicError('Cannot modify bookEnd time of a activity started')

if int(time.mktime(activity.book_start.timetuple())) < int(time.time()):
if activity.total_tickets != self.input['totalTickets']:
raise LogicError('Cannot modify totalTickets after book_start')

activity.name = self.input['name']
activity.place = self.input['place']
activity.description = self.input['description']
activity.pic_url = self.input['picUrl']
activity.start_time = (datetime.strptime(self.input['startTime'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8))
activity.end_time = (datetime.strptime(self.input['endTime'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8))
activity.book_start = (datetime.strptime(self.input['bookStart'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8))
activity.book_end = (datetime.strptime(self.input['bookEnd'], "%Y-%m-%dT%H:%M:%S.%fZ") + timedelta(hours=8))
activity.total_tickets = self.input['totalTickets']
activity.status = self.input['status']

activity.save()


class ActivityMenu(APIView):

def get(self):
if not self.request.user.is_authenticated():
raise ValidateError('User has not logged in.')
activityListAll = Activity.objects.all()
wechat_menu = CustomWeChatView.lib.get_wechat_menu()
if len(wechat_menu) >= 2:
actiListInMenu = wechat_menu[1]['sub_button']
else:
actiListInMenu = []
data = []
for acti in activityListAll:
if acti.status == Activity.STATUS_DELETED:
continue
temp = {
'id': acti.id,
'name': acti.name,
'menuIndex': 0
}
i = 0
while i < len(actiListInMenu):
if actiListInMenu[i]['name'] == acti.name:
temp['menuIndex'] = i+1
break
i += 1

data.append(temp)
return data

def post(self):
if not self.request.user.is_authenticated():
raise ValidateError('User has not logged in.')
activityList = []
for activity_id in self.input:
activity = Activity.get_by_id(activity_id)
activity.status = Activity.STATUS_PUBLISHED
activity.save()
activityList.append(activity)
CustomWeChatView.update_menu(activityList)


class ImageUpload(APIView):

def post(self):
self.check_input('image')
if not self.request.user.is_authenticated():
raise ValidateError('User has not logged in.')
image = self.input['image'][0]
try:
with open('static/media/img/' + image.name, 'wb') as img_file:
for i in image.chunks():
img_file.write(i)
return SITE_DOMAIN + '/media/img/' + image.name
except:
raise ValidateError('Fail to upload image')


class ActivityCheckin(APIView):
def post(self):
if not self.request.user.is_authenticated():
raise ValidateError("User not logged in!")
self.check_input('actId')
try:
activity = Activity.objects.get(id=self.input['actId'])
except:
raise LogicError('actID error!Activity not found')
try:
if "ticket" in self.input:
ticket = Ticket.objects.get(activity=activity,unique_id=self.input['ticket'])
elif 'studentId' in self.input.keys():
ticket = Ticket.objects.get(activity=activity,student_id=self.input['studentId'])
except:
raise LogicError("no ticket!")

if ticket.status == Ticket.STATUS_CANCELLED:
raise LogicError(" ticket canceled!")
elif ticket.status == Ticket.STATUS_USED:
raise LogicError("ticket used!")
elif ticket.status == Ticket.STATUS_VALID:
data = {
'ticket': ticket.unique_id,
'studentId': ticket.student_id
}
ticket.status = Ticket.STATUS_USED
ticket.save()
return data
else:
raise ValidateError("fail to checkin!")
14 changes: 0 additions & 14 deletions configs.example.json

This file was deleted.

Binary file added configs.json.enc
Binary file not shown.
2 changes: 1 addition & 1 deletion templates/news.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<Title><![CDATA[{{ Article.Title }}]]></Title>
<Description><![CDATA[{{ Article.Description }}]]></Description>
<PicUrl><![CDATA[{{ Article.PicUrl }}]]></PicUrl>
<Url><![CDATA[{{ Article.Url }}]]></Url>
<Url><![CDATA[{{ Article.Url | safe}}]]></Url>
</item>
{% endfor %}
</Articles>
Expand Down
2 changes: 2 additions & 0 deletions userpage/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@

urlpatterns = [
url(r'^user/bind/?$', UserBind.as_view()),
url(r'^activity/detail/?$', ActivityDetail.as_view()),
url(r'^ticket/detail/?$', TicketDetail.as_view()),
]
Loading