# Copyright (c) 2013 CEF Python, see the Authors file.
# All rights reserved. Licensed under BSD 3-clause license.
# Project website: https://github.com/cztomczak/cefpython
include "cefpython.pyx"
from task cimport *
# ------------------------------------------------------------------------------
# Tests
# ------------------------------------------------------------------------------
#cdef Cookie cookie = Cookie()
#cookie.SetName("asd1")
#print("cookie.cefCookie: %s" % cookie.cefCookie)
#print("cookie.GetName(): %s" % cookie.GetName())
#print("cookie.GetCreation(): %s" % cookie.GetCreation())
#cookie.SetCreation(datetime.datetime(2013,5,23))
#print("cookie.GetCreation(): %s" % cookie.GetCreation())
#print("cookie: %s" % cookie.Get())
# ------------------------------------------------------------------------------
# Globals
# ------------------------------------------------------------------------------
# noinspection PyUnresolvedReferences
cdef PyCookieManager g_globalCookieManager = None
# See StoreUserCookieVisitor().
import weakref
cdef object g_userCookieVisitors = weakref.WeakValueDictionary()
cdef int g_userCookieVisitorMaxId = 0
# ------------------------------------------------------------------------------
# Cookie
# ------------------------------------------------------------------------------
# noinspection PyUnresolvedReferences
ctypedef Cookie PyCookie
cdef PyCookie CreatePyCookie(CefCookie cefCookie):
cdef PyCookie pyCookie = Cookie()
pyCookie.cefCookie = cefCookie
return pyCookie
cdef class Cookie:
cdef CefCookie cefCookie
cpdef py_void Set(self, dict cookie):
for key in cookie:
if key == "name":
self.SetName(cookie[key])
elif key == "value":
self.SetValue(cookie[key])
elif key == "domain":
self.SetDomain(cookie[key])
elif key == "path":
self.SetPath(cookie[key])
elif key == "secure":
self.SetSecure(cookie[key])
elif key == "httpOnly":
self.SetHttpOnly(cookie[key])
elif key == "creation":
self.SetCreation(cookie[key])
elif key == "lastAccess":
self.SetLastAccess(cookie[key])
elif key == "hasExpires":
self.SetHasExpires(cookie[key])
elif key == "expires":
self.SetExpires(cookie[key])
else:
raise Exception("Invalid key: %s" % key)
cpdef dict Get(self):
return {
"name": self.GetName(),
"value": self.GetValue(),
"domain": self.GetDomain(),
"path": self.GetPath(),
"secure": self.GetSecure(),
"httpOnly": self.GetHttpOnly(),
"creation": self.GetCreation(),
"lastAccess": self.GetLastAccess(),
"hasExpires": self.GetHasExpires(),
"expires": self.GetExpires(),
}
cpdef py_void SetName(self, py_string name):
# This works:
# | CefString(&self.cefCookie.name).FromString(name)
# This does not work:
# | cdef CefString cefString = CefString(&self.cefCookie.name)
# | PyToCefString(name, cefString)
# Because it's a Copy Constructor, it does not reference the
# same underlying cef_string_t, instead it copies the value.
# "T a(b)" - direct initialization (not supported by cython)
# "T a = b" - copy initialization
# But this works:
# | cdef CefString* cefString = new CefString(&self.cefCookie.name)
# | PyToCefStringPointer(name, cefString)
# | del cefString
# Solution: use Attach() method to pass reference to cef_string_t.
cdef CefString cefString
cefString.Attach(&self.cefCookie.name, False)
PyToCefString(name, cefString)
cpdef str GetName(self):
cdef CefString cefString
cefString.Attach(&self.cefCookie.name, False)
return CefToPyString(cefString)
cpdef py_void SetValue(self, py_string value):
cdef CefString cefString
cefString.Attach(&self.cefCookie.value, False)
PyToCefString(value, cefString)
cpdef str GetValue(self):
cdef CefString cefString
cefString.Attach(&self.cefCookie.value, False)
return CefToPyString(cefString)
cpdef py_void SetDomain(self, py_string domain):
cdef CefString cefString
cefString.Attach(&self.cefCookie.domain, False)
PyToCefString(domain, cefString)
cpdef str GetDomain(self):
cdef CefString cefString
cefString.Attach(&self.cefCookie.domain, False)
return CefToPyString(cefString)
cpdef py_void SetPath(self, py_string path):
cdef CefString cefString
cefString.Attach(&self.cefCookie.path, False)
PyToCefString(path, cefString)
cpdef str GetPath(self):
cdef CefString cefString
cefString.Attach(&self.cefCookie.path, False)
return CefToPyString(cefString)
cpdef py_void SetSecure(self, py_bool secure):
# Need to wrap it with bool() to get rid of the C++ compiler
# warnings: "cefpython.cpp(24740) : warning C4800: 'int' :
# forcing value to bool 'true' or 'false' (performance warning)".
self.cefCookie.secure = bool(secure)
cpdef py_bool GetSecure(self):
return self.cefCookie.secure
cpdef py_void SetHttpOnly(self, py_bool httpOnly):
self.cefCookie.httponly = bool(httpOnly)
cpdef py_bool GetHttpOnly(self):
return self.cefCookie.httponly
cpdef py_void SetCreation(self, object creation):
DatetimeToCefTimeT(creation, self.cefCookie.creation)
cpdef object GetCreation(self):
return CefTimeTToDatetime(self.cefCookie.creation)
cpdef py_void SetLastAccess(self, object lastAccess):
DatetimeToCefTimeT(lastAccess, self.cefCookie.last_access)
cpdef object GetLastAccess(self):
return CefTimeTToDatetime(self.cefCookie.last_access)
cpdef py_void SetHasExpires(self, py_bool hasExpires):
self.cefCookie.has_expires = bool(hasExpires)
cpdef py_bool GetHasExpires(self):
return self.cefCookie.has_expires
cpdef py_void SetExpires(self, object expires):
DatetimeToCefTimeT(expires, self.cefCookie.expires)
cpdef object GetExpires(self):
return CefTimeTToDatetime(self.cefCookie.expires)
# ------------------------------------------------------------------------------
# CookieManager
# ------------------------------------------------------------------------------
class CookieManager(object):
"""Class used for managing cookies. To instantiate this class
call CreateManager() static method."""
@classmethod
def GetGlobalManager(cls):
global g_globalCookieManager
cdef CefRefPtr[CefCookieManager] cefCookieManager
if not g_globalCookieManager:
cefCookieManager = CefCookieManager_GetGlobalManager(
NULL)
g_globalCookieManager = CreatePyCookieManager(cefCookieManager)
return g_globalCookieManager
@classmethod
def GetBlockingManager(cls):
return CreatePyCookieManager(CefCookieManager_GetBlockingManager())
@classmethod
def CreateManager(cls, py_string path,
py_bool persist_session_cookies=False):
"""
Create a new cookie manager.
:param path:
:type path: str
:param persist_session_cookies:
:type path: bool
:return: CookieManager object
:rtype: CookieManager
"""
# When PyCharm generates a stub for the cefpython module
# it doesn't use the above docstring for code inspections.
# No idea why.
cdef CefRefPtr[CefCookieManager] cefCookieManager
cefCookieManager = CefCookieManager_CreateManager(
PyToCefStringValue(path), bool(persist_session_cookies),
NULL)
if cefCookieManager != NULL and cefCookieManager.get():
return CreatePyCookieManager(cefCookieManager)
return None
# ------------------------------------------------------------------------------
# PyCookieManager
# ------------------------------------------------------------------------------
cdef PyCookieManager CreatePyCookieManager(
CefRefPtr[CefCookieManager] cefCookieManager):
cdef PyCookieManager pyCookieManager = PyCookieManager()
pyCookieManager.cefCookieManager = cefCookieManager
return pyCookieManager
cdef class PyCookieManager:
cdef CefRefPtr[CefCookieManager] cefCookieManager
cpdef py_void SetSupportedSchemes(self, list schemes):
cdef cpp_vector[CefString] schemesVector
for scheme in schemes:
schemesVector.push_back(PyToCefStringValue(scheme))
self.cefCookieManager.get().SetSupportedSchemes(schemesVector,
NULL)
cdef py_void ValidateUserCookieVisitor(self, object userCookieVisitor):
if userCookieVisitor and hasattr(userCookieVisitor, "Visit") and (
callable(getattr(userCookieVisitor, "Visit"))):
# OK.
return
raise Exception("CookieVisitor object is missing Visit() method")
cpdef py_bool VisitAllCookies(self, object userCookieVisitor):
self.ValidateUserCookieVisitor(userCookieVisitor)
cdef int cookieVisitorId = StoreUserCookieVisitor(userCookieVisitor)
cdef CefRefPtr[CefCookieVisitor] cefCookieVisitor = (
new CookieVisitor(
cookieVisitorId))
return self.cefCookieManager.get().VisitAllCookies(
cefCookieVisitor)
cpdef py_bool VisitUrlCookies(self, py_string url,
py_bool includeHttpOnly, object userCookieVisitor):
self.ValidateUserCookieVisitor(userCookieVisitor)
cdef int cookieVisitorId = StoreUserCookieVisitor(userCookieVisitor)
cdef CefRefPtr[CefCookieVisitor] cefCookieVisitor = (
new CookieVisitor(
cookieVisitorId))
return self.cefCookieManager.get().VisitUrlCookies(
PyToCefStringValue(url), bool(includeHttpOnly),
cefCookieVisitor)
cpdef py_void SetCookie(self, py_string url, PyCookie cookie):
assert isinstance(cookie, Cookie), "cookie object is invalid"
CefPostTask(TID_IO, CreateTask_SetCookie(
self.cefCookieManager.get(),
PyToCefStringValue(url), cookie.cefCookie,
NULL))
cpdef py_void DeleteCookies(self, py_string url, py_string cookie_name):
CefPostTask(TID_IO, CreateTask_DeleteCookies(
self.cefCookieManager.get(),
PyToCefStringValue(url), PyToCefStringValue(cookie_name),
NULL))
cpdef py_bool SetStoragePath(self, py_string path,
py_bool persistSessionCookies=False):
return self.cefCookieManager.get().SetStoragePath(
PyToCefStringValue(path), bool(persistSessionCookies),
NULL)
cpdef py_bool FlushStore(self, callback=None):
return self.cefCookieManager.get().FlushStore(
NULL)
# ------------------------------------------------------------------------------
# PyCookieVisitor
# ------------------------------------------------------------------------------
cdef int StoreUserCookieVisitor(object userCookieVisitor) except *:
global g_userCookieVisitorMaxId
global g_userCookieVisitors
g_userCookieVisitorMaxId += 1
g_userCookieVisitors[g_userCookieVisitorMaxId] = userCookieVisitor
return g_userCookieVisitorMaxId
cdef PyCookieVisitor GetPyCookieVisitor(int cookieVisitorId):
global g_userCookieVisitors
cdef object userCookieVisitor
cdef PyCookieVisitor pyCookieVisitor
if cookieVisitorId in g_userCookieVisitors:
userCookieVisitor = g_userCookieVisitors[cookieVisitorId]
pyCookieVisitor = PyCookieVisitor(userCookieVisitor)
return pyCookieVisitor
cdef class PyCookieVisitor:
cdef object userCookieVisitor
def __init__(self, object userCookieVisitor):
self.userCookieVisitor = userCookieVisitor
cdef object GetCallback(self, str funcName):
if self.userCookieVisitor and (
hasattr(self.userCookieVisitor, funcName) and (
callable(getattr(self.userCookieVisitor, funcName)))):
return getattr(self.userCookieVisitor, funcName)
# ------------------------------------------------------------------------------
# C++ CookieVisitor
# ------------------------------------------------------------------------------
cdef public cpp_bool CookieVisitor_Visit(
int cookieVisitorId,
const CefCookie& cookie,
int count,
int total,
cpp_bool& deleteCookie
) except * with gil:
cdef PyCookieVisitor pyCookieVisitor
cdef object callback
cdef py_bool ret
cdef PyCookie pyCookie
cdef list pyDeleteCookie = [False]
try:
assert IsThread(TID_IO), "Must be called on the IO thread"
pyCookieVisitor = GetPyCookieVisitor(cookieVisitorId)
pyCookie = CreatePyCookie(cookie)
if pyCookieVisitor:
callback = pyCookieVisitor.GetCallback("Visit")
if callback:
ret = callback(
cookie=pyCookie,
count=count,
total=total,
delete_cookie_out=pyDeleteCookie)
(&deleteCookie)[0] = bool(pyDeleteCookie[0])
return bool(ret)
return False
except:
(exc_type, exc_value, exc_trace) = sys.exc_info()
sys.excepthook(exc_type, exc_value, exc_trace)