In Fortsetzung von Teil 1 möchte ich im zweiten Teil auf verschiedene APIs verweisen und den BOT-Dienst betreiben. Der Quellcode wird unter GitBucket und das fertige Produkt unter hier betrieben.
Da die Verwendung der API zur Überwachung der Kampfaufzeichnungen jedes Benutzers und zur Veröffentlichung auf Twitter bei Aktualisierungen eingeschränkt ist, muss der auszuführende Prozess in Sekundenintervallen gesteuert werden. Da Cron, das später beschrieben wird, nur in einem Mindestintervall von 1 Minute aufgerufen werden kann, verwendet die Verarbeitung jedes Benutzers einen von GAE bereitgestellten Mechanismus namens Task Queue. Als Image der Task-Warteschlange werden die Tasks in einen Container namens Bucket geworfen, und die Tasks werden gemäß den Einstellungen in der Reihenfolge verarbeitet, in der sie zuerst platziert wurden. Wenn Sie die Bucket-Größe erhöhen, können Sie parallel verarbeiten. Die Konfigurationsdatei lautet `` `queue.yaml```.
queue.yaml
queue:
- name: tweet #Alles ist gut
rate: 0.8/s #0 pro Sekunde.8-mal verarbeiten
bucket_size: 1 #Nummer, die parallel verarbeitet werden soll
retry_parameters:
task_retry_limit: 0 #Anzahl der Wiederholungen, wenn die Verarbeitung fehlschlägt
Verwenden Sie nun `add ()`
, um eine Aufgabe aus Python tatsächlich in den Bucket zu werfen, der in `queue.yaml``` festgelegt ist. Geben Sie
name``` an, das in
queue.yaml``` für`
queue_name entsprechend` festgelegt ist. Geben Sie die Adresse des aufzurufenden Prozesses in "URL angemessen" an. Sie können auch Parameter übergeben.
launcher.py
from google.appengine.api.taskqueue import add
import webapp2
class modelTask(db.Model): #Aufgaben in die Warteschlange
resion = db.StringProperty()
summoner_name = db.StringProperty()
summoner_id = db.IntegerProperty()
latest_game = db.IntegerProperty()
access_key = db.StringProperty()
access_secret = db.StringProperty()
date_success = db.DateTimeProperty(auto_now_add=True)
date = db.DateTimeProperty(auto_now_add=True)
class mainHandler(webapp2.RequestHandler):
def get(self):
qs = modelTask.all().order('-date_success')
for q in qs: #Fügen Sie alle Aufgaben zur Warteschlange hinzu
add(queue_name='tweet', url='/tweet', params={'qid': q.key().id()})
app = webapp2.WSGIApplication([ ('/launcher', mainHandler) ])
Implementieren Sie als Nächstes den Prozess, der aufgerufen wird, wenn die Wende in der Task-Warteschlange erfolgt, die in "URL entsprechend" angegeben ist. Wird von der POST-Methode aus der Task-Warteschlange aufgerufen.
tweet.py
#! -*- coding: utf-8 -*-
from google.appengine.ext import db
from google.appengine.api.urlfetch import fetch
from django.utils.simplejson import loads
import webapp2, tweepy
from datetime import datetime
from laucher import modelTask
CONSUMER_KEY = '********************'
CONSUMER_SECRET = '**************************************'
RIOT_KEY = '***********************************'
class mainHandler(webapp2.RequestHandler):
def post(self):
getGame(long(self.request.get('qid')))
def getGame(qid):
q = modelTask().get_by_id(qid, parent=None)
#Rufen Sie die RIOT-API auf
result = fetch('https://prod.api.pvp.net/api/lol/'+q.resion+'/v1.3/game/by-summoner/'+str(q.summoner_id)+'/recent?api_key='+RIOT_KEY)
if result.status_code == 200:
#Legen Sie verschiedene Werte fest, die von der API erhalten wurden
j = loads(result.content)['games'][0]
if j['stats']['win'] == True:
win = 'Sieg'
else:
win = 'Niederlage'
try:
kill = str(j['stats']['championsKilled'])
except:
kill = '0'
try:
death = str(j['stats']['numDeaths'])
except:
death = '0'
try:
assist = str(j['stats']['assists'])
except:
assist = '0'
game_type = j['subType']
#Poste auf Twitter, wenn es in der letzten Kampfzeit ein Update gibt
if j['createDate'] > q.latest_game:
q.latest_game = j['createDate']
q.put()
if tweet(q.summoner_name+'Herr spätestens'+game_type+'Der Kampfrekord ist'+kill+'töten'+death+'Tod'+assist+'Helfen'+win+'ist. http://tol.orfx.jp #Tweet_of_Legends', q.access_key, q.access_secret):
q.date_success = datetime.now()
q.put()
#Twitter-Nachbearbeitung
def tweet(message, access_key, access_secret):
try:
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth_handler=auth, api_root='/1.1', secure=True)
api.update_status(status=message)
return True
except:
return False
app = webapp2.WSGIApplication([ ('/tweet', mainHandler) ])
Ich verwende Cron, weil ich den Vorgang des regelmäßigen Hinzufügens der obigen Aufgabe zur Warteschlange aufrufen möchte. Die Konfigurationsdatei lautet `` `cron.yaml```. Dieses Mal werde ich versuchen, es alle 10 Minuten von 1 bis 18 Uhr und ansonsten alle 5 Minuten auszuführen.
cron.yaml
cron:
- description: tweet job
url: /launcher
schedule: every 10 minutes from 1:00 to 17:59
timezone: Asia/Tokyo #Vergessen Sie nicht die Zeitzone, wenn Sie die Zeit angeben
- description: tweet job
url: /launcher
schedule: every 5 minutes from 18:00 to 0:59
timezone: Asia/Tokyo
Wenn Sie mit dieser Cron-Einstellung (alle 5 bis 10 Minuten) arbeiten, wird die Startzeit der Instanz übrigens in Schritten von 15 Minuten berechnet, sodass die Startzeit der Frontend-Instanz definitiv 24 Stunden oder mehr beträgt. Darüber hinaus wird die Verarbeitung der Registrierungsseite usw. hinzugefügt, sodass ich mir Sorgen über die 28 Stunden des kostenlosen Frames (Stand März 2014) mache. Nutzen wir also das Backend. Das Backend ist ursprünglich ein Mechanismus für Arbeiten hinter den Kulissen wie Stapelverarbeitung und asynchrone Verarbeitung. Dieses Mal wird es jedoch lediglich verwendet, um die Startzeit der Instanz (9 Stunden) zu verdienen. Die Konfigurationsdatei lautet `` `backend.yaml```.
backend.yaml
backends:
- name: tweet #Alles ist gut
class: B1 #Verarbeitungsressourcen minimieren
options: dynamic #Machen Sie die Instanz nicht resident
Wenn Cron den Prozess unterstützen soll, geben Sie `` `target``` an. Dieses Mal werde ich es mit Backend von 18 Uhr bis 1 Uhr morgens bearbeiten.
cron:
- description: tweet job
url: /launcher
schedule: every 10 minutes from 1:00 to 17:59
timezone: Asia/Tokyo
- description: tweet job
url: /launcher
schedule: every 5 minutes from 18:00 to 0:59
timezone: Asia/Tokyo
target: tweet #backend.Yaml Name
TaskQueue kann auch vom Backend verarbeitet werden, indem `add (target =)`
angegeben wird. Verwenden Sie get_backend (), um zu sehen, ob Sie mit Backend arbeiten. Wenn das Backend gestartet wird, wird `` `/ _ah / start``` zwangsweise aufgerufen. Da es zuerst aufgerufen wird, können Sie den Prozess beim Start beschreiben, aber dieses Mal werden wir den leeren Prozess beschreiben.
launcher.py
from google.appengine.api.taskqueue import add
from google.appengine.api.backends import get_backend
import webapp2
class modelTask(db.Model):
resion = db.StringProperty()
summoner_name = db.StringProperty()
summoner_id = db.IntegerProperty()
latest_game = db.IntegerProperty()
access_key = db.StringProperty()
access_secret = db.StringProperty()
date_success = db.DateTimeProperty(auto_now_add=True)
date = db.DateTimeProperty(auto_now_add=True)
class mainHandler(webapp2.RequestHandler):
def get(self):
qs = modelTask.all().order('-date_success')
target = get_backend()
if target is None: #Wenn es vom Backend gestartet wird, ist TaskQueue dasselbe.
for q in qs:
add(queue_name='tweet', url='/tweet', params={'qid': q.key().id()})
else:
for q in qs:
add(queue_name='tweet', url='/tweet', params={'qid': q.key().id()}, target='tweet')
class startHandler(webapp2.RequestHandler): #Wird beim Start des Backends aufgerufen
def get(self):
return
app = webapp2.WSGIApplication([ ('/launcher', mainHandler), ('/_ah/start', startHandler) ])
Memcache kann verwendet werden, um den Ressourcenverbrauch für Prozesse, die den Datenspeicher häufig durchsuchen, ihn jedoch selten aktualisieren, erheblich zu reduzieren. In RIOT API game-v1.3 wird Champion als ID zurückgegeben, daher müssen Sie die ID basierend auf den Informationen in champ-v1.1 in einen Namen konvertieren. Da Sie die API nicht häufig aufrufen können, werden die von champ-v1.1 erfassten Informationen einmal im Datenspeicher gespeichert. Kopieren Sie dann die in Memcache gespeicherten Informationen. Verwenden Sie `memcache.add (Schlüssel, Wert)`
, um Daten zu Memcache hinzuzufügen.
champion.py
from google.appengine.api import memcache
from google.appengine.ext import db
from google.appengine.api.urlfetch import fetch
from django.utils.simplejson import loads
import webapp2
RIOT_KEY = '***********************************'
class modelChampion(db.Model): #Champion Informationsspeichermodell
name = db.StringProperty()
date = db.DateTimeProperty(auto_now_add=True)
class mainHandler(webapp2.RequestHandler):
def get(self):
#Champion Informationsbeschaffung
result = fetch('https://prod.api.pvp.net/api/lol/na/v1.1/champion?api_key='+RIOT_KEY)
if result.status_code == 200:
js = loads(result.content)['champions']
for j in js:
#Champion Informationsspeicher
modelchampion = modelChampion().get_or_insert(str(j['id']))
modelchampion.name = j['name']
modelchampion.put()
#Kopieren Sie die Championinformationen in Memcache
memcache.add("champion_"+str(j['id']), j['name'], 86399)
app = webapp2.WSGIApplication([ ('/champion', mainHandler) ], debug=True)
Verwenden Sie `memcache.get (Schlüssel)`
, um auf die zu Memcache hinzugefügten Daten zu verweisen. Da die zu Memcache hinzugefügten Daten möglicherweise verloren gehen, muss die Verarbeitung zu diesem Zeitpunkt beschrieben werden. Fügen wir nun den Namen des Champions zum veröffentlichten Inhalt in tweet.py hinzu.
tweet.py
from google.appengine.api import memcache
from champion import modelChampion
def getGame(qid):
q = modelQueue().get_by_id(qid, parent=None)
result = fetch('https://prod.api.pvp.net/api/lol/'+q.resion+'/v1.3/game/by-summoner/'+str(q.summoner_id)+'/recent?api_key='+RIOT_KEY)
if result.status_code == 200:
j = loads(result.content)['games'][0]
if j['stats']['win'] == True:
win = 'Sieg'
else:
win = 'Niederlage'
try:
kill = str(j['stats']['championsKilled'])
except:
kill = '0'
try:
death = str(j['stats']['numDeaths'])
except:
death = '0'
try:
assist = str(j['stats']['assists'])
except:
assist = '0'
#Holen Sie sich Champion-Informationen von Memcache
champion = memcache.get("champion_"+str(j['championId']))
if champion is None: #Wenn Sie keine Championinformationen aus Memcache abrufen können, aus dem Datenspeicher
champion = modelChampion.get_by_key_name(str(j['championId'])).name
game_type = j['subType']
if j['createDate'] > q.latest_game:
q.latest_game = j['createDate']
q.put()
if tweet(q.summoner_name+'Herr spätestens'+game_type+'Der Kampfrekord ist'+champion+'damit'+kill+'töten'+death+'Tod'+assist+'Helfen'+win+'damitす 。 http://tol.orfx.jp #Tweet_of_Legends', q.access_key, q.access_secret):
q.date_success = datetime.now()
q.put()
Dies ist das erste mit GAE erstellte Memorandum of Application. Sobald Sie den Dreh raus haben, ist es sehr einfach, ab dem nächsten Mal eine App zu erstellen. Es wird daher empfohlen!
Recommended Posts