Issues upgrading from wagtail 2.15.6 to 2.16 breaks all pages except home page - upgrade

I am experiencing an issue upgrading a site's wagtail installed version. I have successfully upgraded from 2.12 to 2.15.6 but am running into what seems to be an impassible issue with upgrading to 2.16 Specifically to do with this recent commit in 2.16 stable
https://github.com/wagtail/wagtail/commit/29a7f701611d22ab9c7f12f1134aeac1d31b9438
Every page except the root page of the site brings up the following error (including django and wagtail admins)
AttributeError at /django-admin/
'tuple' object has no attribute 'root_path'
Request Method: GET
Request URL: http://localhost:8000/django-admin/
Django Version: 3.2
Exception Type: AttributeError
Exception Value:
'tuple' object has no attribute 'root_path'
Exception Location: /usr/local/lib/python3.7/site-packages/wagtail/core/models/__init__.py, line 1109, in <genexpr>
Python Executable: /usr/local/bin/python
Python Version: 3.7.14
Python Path:
['/app',
'/usr/local/lib/python37.zip',
'/usr/local/lib/python3.7',
'/usr/local/lib/python3.7/lib-dynload',
'/usr/local/lib/python3.7/site-packages']
Server time: Fri, 09 Dec 2022 15:42:48 -0500
Environment:
Request Method: GET
Request URL: http://localhost:8000/django-admin/
Django Version: 3.2
Python Version: 3.7.14
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'globalapp.middleware.request.RequestMiddleware',
'django_user_agents.middleware.UserAgentMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'righttoplay.middleware.CustomCacheMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'wagtail.contrib.redirects.middleware.RedirectMiddleware']
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 204, in _get_response
response = response.render()
File "/usr/local/lib/python3.7/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/usr/local/lib/python3.7/site-packages/django/template/response.py", line 83, in rendered_content
return template.render(context, self._request)
File "/usr/local/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 168, in render
with context.bind_template(self):
File "/usr/local/lib/python3.7/contextlib.py", line 112, in __enter__
return next(self.gen)
File "/usr/local/lib/python3.7/site-packages/django/template/context.py", line 244, in bind_template
updates.update(processor(self.request))
File "/app/globalapp/context_processors.py", line 8, in site_settings
return {"settings" : national_office.serialized_data }
File "/app/globalapp/models.py", line 1542, in serialized_data
if self.privacy_page
File "/usr/local/lib/python3.7/site-packages/wagtail/core/models/__init__.py", line 1214, in get_url
url_parts = self.get_url_parts(request=request)
File "/usr/local/lib/python3.7/site-packages/wagtail/core/models/__init__.py", line 1130, in get_url_parts
possible_sites = self._get_relevant_site_root_paths(request)
File "/usr/local/lib/python3.7/site-packages/wagtail/core/models/__init__.py", line 1108, in _get_relevant_site_root_paths
for srp in self._get_site_root_paths(cache_object)
File "/usr/local/lib/python3.7/site-packages/wagtail/core/models/__init__.py", line 1109, in <genexpr>
if self.url_path.startswith(srp.root_path)
Exception Type: AttributeError at /django-admin/
Exception Value: 'tuple' object has no attribute 'root_path'
None of this was documented as a breaking change in the upgrade process I've been following here
https://docs.wagtail.org/en/stable/releases/2.16.html
Technical details
-Python Version is 3.7 running in a docker container
Im including the requirements.txt here if there are any further package or dependancy changes I need to make that arent outlined please let me know.
aiosignal==1.2.0
anyascii==0.3.1
async-timeout==4.0.2
attrs==22.1.0
azure-core==1.25.1
azure-storage-blob==12.13.1
beautifulsoup4==4.9.3
certifi==2022.9.24
cffi==1.15.1
charset-normalizer==2.1.1
cryptography==38.0.1
Deprecated==1.2.13
Django==3.2
django-ajax-selects==2.2.0
django-cogwheels==0.3
django-email-extras==0.3.4
django-extensions==3.1.5
django-filter==2.4.0
django-modelcluster==5.3
django-modeltranslation==0.18.2
django-redis==5.2.0
django-storages==1.12.3
django-taggit==2.0
django-treebeard==4.5.1
django-user-agents==0.4.0
djangorestframework==3.13.1
docopt==0.4.0
draftjs-exporter==2.1.7
et-xmlfile==1.1.0
frozenlist==1.3.1
future==0.18.2
geoip2==4.6.0
gunicorn==20.1.0
html5lib==1.1
idna==3.4
isodate==0.6.1
l18n==2021.3
mailchimp3==3.0.17
mandrill==1.0.60
maxminddb==2.2.0
msrest==0.7.1
multidict==6.0.2
oauthlib==3.2.1
openpyxl==3.0.10
packaging==21.3
Pillow==8.4.0
psycopg2==2.9.3
pycparser==2.21
pyparsing==3.0.9
python-gnupg==0.5.0
pytz==2022.2.1
redis==4.3.4
requests==2.28.1
requests-oauthlib==1.3.1
six==1.16.0
soupsieve==2.3.2.post1
sqlparse==0.4.3
tablib==3.2.1
telepath==0.3
typing_extensions==4.3.0
ua-parser==0.16.1
Unidecode==1.3.6
urllib3==1.26.12
user-agents==2.2.0
wagtail==2.16
wagtail-condensedinlinepanel==0.5.3
wagtail-clear-cache==0.0.1
wagtail-modeltranslation==0.10.18
wagtailgmaps==1.0.1
wagtailmedia==0.9.0
wagtailmenus==3.1.2
webencodings==0.5.1
whitenoise==6.2.0
Willow==1.4.1
wrapt==1.14.1
xlrd==2.0.1
XlsxWriter==1.4.5
xlwt==1.3.0
yarl==1.8.1
Following the upgrade docs https://docs.wagtail.org/en/stable/releases/2.16.html ran into this unexpected / undocumented issue.
Here is the context_processor that is causing the issue. which is getting a model of National Office which has on it multiple Pages that are foreign keys of wagtailcore.Page and the serialized_data method has some if statements checking for if the page foreign key exists and it is these checks that are triggering the wagtailcore code that is failing.
def site_settings(request):
domain = request.META['HTTP_HOST'].replace("www.", "")
try:
national_office = NationalOffice.objects.get(domain=domain)
return {"settings" : national_office.serialized_data }
except ObjectDoesNotExist:
print(" NO Not Found ")
return {}
The below is the serialized data method and it is erroring on the if self.privacy_page check which is the first occurrence of the model's foreign keys to the wagtailcore.Page in this serialized_data method
#property
def serialized_data(self):
global_settings = GlobalSiteSettings.objects.all()[0]
languages = []
for language in self.languages.all():
languages.append(language.serialized_data)
static_text = None
global_settings = GlobalSiteSettings.objects.all()[:1].get()
if global_settings:
static_text = global_settings.static_text
national_offices = []
for national_office in NationalOffice.objects.all():
national_offices.append(
{
"name": national_office.name,
"domain": national_office.domain,
"default_language_short_name": national_office.default_language.short_name
if national_office.default_language
else "en",
"current": True if national_office.id == self.id else False,
"flag": self.flag,
"append_to_url": "?no-redirect=true"
if national_office.redirect_by_geo_ip
else None,
}
)
data = {
# static
"static_text": static_text,
"national_offices": national_offices,
"name": self.name,
"flag": self.flag,
"domain": self.domain,
"gmt_code": self.gmt_code,
# language
"show_language_switcher": True if len(languages) > 1 else False,
"languages": languages,
"default_language_short_name": self.default_language.short_name,
# header
"announcement_text": self.announcement_text,
"announcement_link": self.announcement_link,
"join_nav_txt_1": self.join_nav_txt_1,
"join_nav_url_1": self.join_nav_url_1,
"join_nav_txt_2": self.join_nav_txt_2,
"join_nav_url_2": self.join_nav_url_2,
"join_nav_txt_3": self.join_nav_txt_3,
"join_nav_url_3": self.join_nav_url_3,
"footer_col_1_text_1": self.footer_col_1_text_1,
"footer_col_1_url_1": self.footer_col_1_url_1,
"footer_col_1_text_2": self.footer_col_1_text_2,
"footer_col_1_url_2": self.footer_col_1_url_2,
"footer_col_1_text_3": self.footer_col_1_text_3,
"footer_col_1_url_3": self.footer_col_1_url_3,
"footer_col_2_text_1": self.footer_col_2_text_1,
"footer_col_2_url_1": self.footer_col_2_url_1,
"footer_col_2_text_2": self.footer_col_2_text_2,
"footer_col_2_url_2": self.footer_col_2_url_2,
"footer_col_2_text_3": self.footer_col_2_text_3,
"footer_col_2_url_3": self.footer_col_2_url_3,
"footer_col_3_text_1": self.footer_col_3_text_1,
"footer_col_3_url_1": self.footer_col_3_url_1,
"footer_col_3_text_2": self.footer_col_3_text_2,
"footer_col_3_url_2": self.footer_col_3_url_2,
"footer_col_3_text_3": self.footer_col_3_text_3,
"footer_col_3_url_3": self.footer_col_3_url_3,
"primary_donation_url": self.primary_donation_url
if self.primary_donation_url
else None,
"primary_donation_page": self.primary_donation_page
if self.primary_donation_page
else None,
"show_fundraise_link": self.show_fundraise_link,
"show_events_link": self.show_events_link,
"show_get_involved_link": self.show_get_involved_link,
"show_third_party_events": self.show_third_party_events,
# footer
"facebook_url": self.facebook_url
if self.facebook_url
else global_settings.facebook_url,
"twitter_url": self.twitter_url
if self.twitter_url
else global_settings.twitter_url,
"instagram_url": self.instagram_url
if self.instagram_url
else global_settings.instagram_url,
"linkedin_url": self.linkedin_url
if self.linkedin_url
else global_settings.linkedin_url,
"youtube_url": self.youtube_url
if self.youtube_url
else global_settings.youtube_url,
"business_number_title": self.business_number_title
if self.business_number_title
else None,
"business_number_value": self.business_number_value
if self.business_number_value
else None,
"business_logo1": self.logo1 if self.logo1 else None,
"business_logo2": self.logo2 if self.logo2 else None,
"business_logo1_url": self.logo1_url if self.logo1_url else None,
"business_logo2_url": self.logo2_url if self.logo2_url else None,
"contact_director_name": self.contact_director_name
if self.contact_director_name
else None,
"contact_director_title": self.contact_director_title
if self.contact_director_title
else None,
"contact_address": self.contact_address if self.contact_address else None,
"contact_phone": self.contact_phone if self.contact_phone else None,
"contact_email": self.contact_email if self.contact_email else None,
"contact_show_program_offices": self.contact_show_program_offices
if self.contact_show_program_offices
else False,
"footer_subscribe_title": self.footer_subscribe_title
if self.footer_subscribe_title
else global_settings.footer_subscribe_title,
"shop_page_url": self.shop_page if self.shop_page else None,
"shop_page_title": self.shop_page_title if self.shop_page_title else None,
"privacy_page_url": self.privacy_page.url
if self.privacy_page
else global_settings.privacy_page.url
if global_settings.privacy_page
else None,
"privacy_page_title": self.privacy_page.title
if self.privacy_page
else global_settings.privacy_page.title
if global_settings.privacy_page
else None,
"terms_page_url": self.terms_page.url
if self.terms_page
else global_settings.terms_page.url
if global_settings.terms_page
else None,
"terms_page_title": self.terms_page.title
if self.terms_page
else global_settings.terms_page.title
if global_settings.terms_page
else None,
"faq_page_url": self.faq_page.url
if self.faq_page
else global_settings.faq_page.url
if global_settings.faq_page
else None,
"faq_page_title": self.faq_page.title
if self.faq_page
else global_settings.faq_page.title
if global_settings.faq_page
else None,
"contact_page_url": self.contact_page.url
if self.contact_page
else global_settings.contact_page.url
if global_settings.contact_page
else None,
"contact_page_title": self.contact_page.title
if self.contact_page
else global_settings.contact_page.title
if global_settings.contact_page
else None,
"search_page_url": global_settings.search_page.url
if global_settings.search_page
else None,
"resources_page_url": self.resources_page.url
if self.resources_page
else None,
"resources_page_title": self.resources_page.title
if self.resources_page
else None,
"more_ways_to_give_page_url": self.more_ways_to_give_page.url
if self.more_ways_to_give_page
else None,
"more_ways_to_give_page_title": self.more_ways_to_give_page.title
if self.more_ways_to_give_page
else None,
"more_ways_to_give_page": self.more_ways_to_give_page
if self.more_ways_to_give_page
else None,
"careers_page": self.careers_page if self.careers_page else None,
"media_center_page": self.media_center_page
if self.media_center_page
else None,
"campaign_page": self.campaign_page if self.campaign_page else None,
"we_rise_page": self.we_rise_page if self.we_rise_page else None,
"footer_accessibility_url": self.footer_accessibility_url
if self.footer_accessibility_url
else None,
"footer_accessibility_title": self.footer_accessibility_title
if self.footer_accessibility_title
else None,
"fundraise_page_url": self.fundraise_page.url
if self.fundraise_page
else None,
"fundraise_page_title": self.fundraise_page.title
if self.fundraise_page
else None,
# generic bottom cta
"generic_bottom_cta_title": self.generic_bottom_cta_title
if self.generic_bottom_cta_title
else None,
"generic_bottom_cta_body": self.generic_bottom_cta_body
if self.generic_bottom_cta_body
else None,
"generic_bottom_cta_button_text": self.generic_bottom_cta_button_text
if self.generic_bottom_cta_button_text
else None,
"generic_bottom_cta_button_page": self.generic_bottom_cta_button_page
if self.generic_bottom_cta_button_page
else None,
"generic_bottom_cta_button_url": self.generic_bottom_cta_button_url
if self.generic_bottom_cta_button_url
else None,
"cookie_text": self.cookie_text
if self.cookie_text
else global_settings.cookie_text,
"cookie_agree_text": self.cookie_agree_text
if self.cookie_agree_text
else global_settings.cookie_agree_text,
# homepage overrides
"top_carousel_type": self.top_carousel_type
if self.top_carousel_type is not "default"
else None,
"top_carousel_image": self.top_carousel_image
if self.top_carousel_image
else None,
"top_carousel_title": self.top_carousel_title
if self.top_carousel_title
else None,
"top_carousel_button_page": self.top_carousel_button_page
if self.top_carousel_button_page
else None,
"top_carousel_button_text": self.top_carousel_button_text
if self.top_carousel_button_text
else None,
"home_hide_top_carousel_text": self.home_hide_top_carousel_text,
"home_hide_top_carousel_button": self.home_hide_top_carousel_button,
"home_section_0_visible": self.home_section_0_visible,
"home_section_0_title": self.home_section_0_title
if self.home_section_0_title
else None,
"home_section_0_body": self.home_section_0_body
if self.home_section_0_body
else None,
"home_section_0_body_mobile": self.home_section_0_body_mobile
if self.home_section_0_body_mobile
else None,
"home_section_0_button_text": self.home_section_0_button_text
if self.home_section_0_button_text
else None,
"home_section_0_button_url": self.home_section_0_button_url
if self.home_section_0_button_url
else None,
"home_section_0_light_foreground": self.home_section_0_light_foreground
if self.home_section_0_light_foreground != "none"
else None,
"home_section_0_text_align": self.home_section_0_text_align
if self.home_section_0_text_align != "none"
else None,
"home_section_0_background_image": self.home_section_0_background_image
if self.home_section_0_background_image
else None,
"home_section_0_button_url": self.home_section_0_button_url
if self.home_section_0_button_url
else None,
"home_section_0_button_page": self.home_section_0_button_page
if self.home_section_0_button_page
else None,
"home_section_1_title": self.home_section_1_title
if self.home_section_1_title
else None,
"home_section_1_body": self.home_section_1_body
if self.home_section_1_body
else None,
"home_section_1_body_mobile": self.home_section_1_body_mobile
if self.home_section_1_body_mobile
else None,
"home_section_1_button_text": self.home_section_1_button_text
if self.home_section_1_button_text
else None,
"home_section_1_button_url": self.home_section_1_button_url
if self.home_section_1_button_url
else None,
"home_section_1_light_foreground": self.home_section_1_light_foreground
if self.home_section_1_light_foreground != "none"
else None,
"home_section_1_text_align": self.home_section_1_text_align
if self.home_section_1_text_align != "none"
else None,
"home_section_1_background_image": self.home_section_1_background_image
if self.home_section_1_background_image
else None,
"home_section_1_button_url": self.home_section_1_button_url
if self.home_section_1_button_url
else None,
"home_section_1_button_page": self.home_section_1_button_page
if self.home_section_1_button_page
else None,
"home_section_2_title": self.home_section_2_title
if self.home_section_2_title
else None,
"home_section_2_body": self.home_section_2_body
if self.home_section_2_body
else None,
"home_section_2_body_mobile": self.home_section_2_body_mobile
if self.home_section_2_body_mobile
else None,
"home_section_2_button_text": self.home_section_2_button_text
if self.home_section_2_button_text
else None,
"home_section_2_button_url": self.home_section_2_button_url
if self.home_section_2_button_url
else None,
"home_section_2_light_foreground": self.home_section_2_light_foreground
if self.home_section_2_light_foreground != "none"
else None,
"home_section_2_text_align": self.home_section_2_text_align
if self.home_section_2_text_align != "none"
else None,
"home_section_2_background_image": self.home_section_2_background_image
if self.home_section_2_background_image
else None,
"home_section_2_button_url": self.home_section_2_button_url
if self.home_section_2_button_url
else None,
"home_section_2_button_page": self.home_section_2_button_page
if self.home_section_2_button_page
else None,
"home_section_3_title": self.home_section_3_title
if self.home_section_3_title
else None,
"home_section_3_body": self.home_section_3_body
if self.home_section_3_body
else None,
"home_section_3_body_mobile": self.home_section_3_body_mobile
if self.home_section_3_body_mobile
else None,
"home_section_3_button_text": self.home_section_3_button_text
if self.home_section_3_button_text
else None,
"home_section_3_button_url": self.home_section_3_button_url
if self.home_section_3_button_url
else None,
"home_section_3_light_foreground": self.home_section_3_light_foreground
if self.home_section_3_light_foreground != "none"
else None,
"home_section_3_text_align": self.home_section_3_text_align
if self.home_section_3_text_align != "none"
else None,
"home_section_3_background_image": self.home_section_3_background_image
if self.home_section_3_background_image
else None,
"home_section_3_button_url": self.home_section_3_button_url
if self.home_section_3_button_url
else None,
"home_section_3_button_page": self.home_section_3_button_page
if self.home_section_3_button_page
else None,
"home_section_4_title": self.home_section_4_title
if self.home_section_4_title
else None,
"home_section_4_body": self.home_section_4_body
if self.home_section_4_body
else None,
"home_section_4_article": self.home_section_4_article
if self.home_section_4_article
else None,
"home_section_4_button_text": self.home_section_4_button_text
if self.home_section_4_button_text
else None,
"home_section_4_light_foreground": self.home_section_4_light_foreground
if self.home_section_4_light_foreground
else None,
"home_section_4_text_align": self.home_section_4_text_align
if self.home_section_4_text_align
else None,
"home_section_4_image_override": self.home_section_4_image_override
if self.home_section_4_image_override
else None,
"home_featured_article_1": self.home_featured_article_1
if self.home_featured_article_1
else None,
"home_featured_article_2": self.home_featured_article_2
if self.home_featured_article_2
else None,
"home_featured_article_3": self.home_featured_article_3
if self.home_featured_article_3
else None,
"home_bottom_cta_title": self.home_bottom_cta_title
if self.home_bottom_cta_title
else None,
"home_bottom_cta_button_text": self.home_bottom_cta_button_text
if self.home_bottom_cta_button_text
else None,
"home_bottom_cta_body": self.home_bottom_cta_body
if self.home_bottom_cta_body
else None,
"home_bottom_cta_button_page": self.home_bottom_cta_button_page
if self.home_bottom_cta_button_page
else None,
"home_bottom_cta_button_url": self.home_bottom_cta_button_url
if self.home_bottom_cta_button_url
else None,
"impact_featured_article": self.impact_featured_article
if self.impact_featured_article
else None,
"impact_featured_article_heading": self.impact_featured_article_heading
if self.impact_featured_article_heading
else None,
"impact_featured_article_title": self.impact_featured_article_title
if self.impact_featured_article_title
else None,
"impact_featured_article_button_text": self.impact_featured_article_button_text
if self.impact_featured_article_button_text
else None,
"impact_featured_article_excerpt": self.impact_featured_article_excerpt
if self.impact_featured_article_excerpt
else None,
"show_fundraise_inspiration_section": self.show_fundraise_inspiration_section,
"featured_event": self.featured_event if self.featured_event else None,
"featured_news": self.featured_news if self.featured_news else None,
"featured_story": self.featured_story if self.featured_story else None,
"share_twitter_handle": self.share_twitter_handle
if self.share_twitter_handle
else global_settings.share_twitter_handle
if global_settings.share_twitter_handle
else None,
"share_image": self.share_image
if self.share_image
else global_settings.share_image
if global_settings.share_image
else None,
"share_description": self.share_description
if self.share_description
else global_settings.share_description
if global_settings.share_description
else None,
"facebook_pixel": self.facebook_pixel,
}
return data
This is the code block in the wagtail 2.16 update that is causing my issues. It is trying to access a instance variable from the site root path but the get_site_root_paths() method is returning a list of site root paths causing the error
def _get_relevant_site_root_paths(self, cache_object=None):
"""
.. versionadded::2.16
Returns a tuple of root paths for all sites this page belongs to.
"""
return tuple(
srp
for srp in self._get_site_root_paths(cache_object)
if self.url_path.startswith(srp.root_path)
)

Related

why none of the clients are getting a tray

I am working on a buffet simulation of a buffet. So basically the client will first go through the payment. Then he should go to get his tray which is the part that does not work. After, he should go get his food.
I dont understand why the Clients are not going to the tray queue.
In fact, right-now the client is paying and then he his going directly to tale his food without taking a tray so something must be wrong in the class function but I can't figure what.
import threading
import random
import time
import concurrent.futures
import traceback
class Queue:
def __init__(self) -> None:
self.list_of_products = []
self.queue = []
self.lock = threading.Lock()
self.bill = 0
self.type_of_products = random.randrange(1, 4)
def add_client(self, client):
self.lock.acquire()
self.queue.append(client)
self.lock.release()
def remove_client(self, client):
self.lock.acquire()
self.queue.remove(client)
self.lock.release()
def check_if_client_in_queue(self, client) -> bool:
self.lock.acquire()
student_in_queue = True if client in self.queue else False
self.lock.release()
return student_in_queue
def check_if_empty(self) -> bool:
self.lock.acquire()
empty = len(self.queue) == 0
self.lock.release()
return empty
def get_first_client(self):
if not self.check_if_empty():
return self.queue.pop(0)
return None
def result_of_random_range(self):
x = self.type_of_products
return x
def paying(self):
self.lock.acquire()
if self.type_of_products == 1:
self.list_of_products.append(self.type_of_products)#i think it is not appending
self.bill = 1 * 25.90
elif self.type_of_products == 2:
self.list_of_products.append(self.type_of_products)
self.bill = 1 * 17.90
else:
self.list_of_products.append(self.type_of_products)
self.bill = 1 * 13.50
type_of_payment = random.randrange(1, 3)
if type_of_payment == 1:
print("Client has to pay", self.bill, "and he is paying in cash")
change = random.randrange(int(self.bill), round(int(self.bill) + 5)) - int(self.bill)
print("Amount to be returned", change, "€")
else:
print("Client has to pay", self.bill, "and he is paying with his credit card")
self.lock.release()
return self.bill
def tray(self):
self.lock.acquire()
random_fall = random.randrange(1,25)
if random_fall != 1:
print("Client got his Tray")
else:
print("Client dropped his tray")
time.sleep(10)
self.lock.release()
class Clients:
def __init__(self, id, queues):
self.id = id
self.queues = queues
if random.randrange(1, 3) == 1:
self.queues["clients_waiting_to_pay_manually"].add_client(self)
else:
self.queues["clients_waiting_to_pay_automatically"].add_client(self)
def __str__(self) -> str:
return f"{self.id}"
def change_queues(self) -> None:
try:
while True:
if not self.queues["clients_waiting_to_pay_manually"].check_if_client_in_queue(self) and not \
self.queues["clients_waiting_to_pay_automatically"].check_if_client_in_queue(self):
break
change_criteria = random.randrange(1, 10)
if change_criteria != 1:
time.sleep(1)
continue
print(f"Client with id {self.id} is gonna switch queue")
if self.queues["clients_waiting_to_pay_manually"].check_if_client_in_queue(self):
self.queues["clients_waiting_to_pay_manually"].remove_client(self)
self.queues["clients_waiting_to_pay_automatically"].add_client(self)
time.sleep(1)
continue
if self.queues["clients_waiting_to_pay_automatically"].check_if_client_in_queue(self):
self.queues["clients_waiting_to_pay_automatically"].remove_client(self)
self.queues["clients_waiting_to_pay_manually"].add_client(self)
time.sleep(1)
continue
except Exception:
traceback.print_exc()
class Station:
def __init__(self, id, queues):
self.id = id
self.queues = queues
def moving_station(self):
try:
while True:
if not self.queues["clients_waiting_to_pay_automatically"].check_if_empty():
client = self.queues["clients_waiting_to_pay_automatically"].get_first_client()
print(f"Cashier {self.id}: Serving the client {client} in the automatic queue")
self.queues["clients_waiting_to_pay_automatically"].paying()
print(f"Client {client} has paid and is going to another station ")
self.queues["clients_getting_main_food"].add_client(client)
print(f"Client {client} is getting his food ")
time.sleep(2)
elif not self.queues["clients_waiting_to_pay_manually"].check_if_empty():
client = self.queues["clients_waiting_to_pay_manually"].get_first_client()
print(f"Cashier {self.id}: Serving the client {client} in the manual queue")
self.queues["clients_waiting_to_pay_manually"].paying()
print(f"Client {client} has paid and is going to another station ")
self.queues["clients_getting_main_food"].add_client(client)
print(f"Client {client} is getting his food ")
time.sleep(2)
else:
break
except Exception:
traceback.print_exc()
class Trays:
def __init__(self,queues) -> None:
self.queues = queues
def giving_trays(self):
try:
while True:
if self.queues["clients_waiting_for_tray"].check_if_empty():
print(f"There is no more clients waiting for a tray")
break
elif not self.queues["clients_waiting_for_tray"].check_if_empty():
client = self.queues["clients_waiting_for_tray"].get_first_client()
print(f"{client} got his tray")
print(f"Client {client} just got his tray")
time.sleep(2)
else:
break
except Exception as e:
traceback.print_exc()
class Main_food:
def __init__(self,id,queues):
self.id = id
self.queues = queues
def getting_food(self):
pasta_menu = ["Carbonara ", "Pesto", "Basilico", "Bolognese", "Truffle", "Chicken Alfredo"]
protein_menu = ["Beef","Pork","Fish","chicken","Beyond Meat","turkey"]
pasta_stock = [2,1,4,5,6,3]
protein_stock = [2,1,4,5,6,3]
try:
if not self.queues["clients_getting_main_food"].check_if_empty():
client_getting_served = self.queues["clients_getting_main_food"].get_first_client()
if self.queues["clients_waiting_to_pay_automatically"].result_of_random_range() == 1:
self.queues["clients_getting_menu_1"].add_client(client_getting_served)
elif self.queues["clients_waiting_to_pay_manually"].result_of_random_range() == 1:
self.queues["clients_getting_menu_1"].add_client(client_getting_served)
if self.queues["clients_waiting_to_pay_automatically"].result_of_random_range() == 2:
self.queues["clients_getting_menu_2"].add_client(client_getting_served)
elif self.queues["clients_waiting_to_pay_manually"].result_of_random_range() == 2:
self.queues["clients_getting_menu_2"].add_client(client_getting_served)
elif self.queues["clients_waiting_to_pay_manually"].result_of_random_range() == 3:
self.queues["clients_getting_menu_3"].add_client(client_getting_served)
else:
self.queues["clients_getting_menu_3"].add_client(client_getting_served)
x = random.randrange(0,6)
y = random.randrange(0,6)
stock = pasta_stock[x]
stock1 = protein_stock[y]
if not self.queues["clients_getting_menu_1"].check_if_empty():
client_being_served_1 = self.queues["clients_getting_menu_1"].get_first_client()
if stock != 0:
pasta_stock[x] = pasta_stock[x]-1
if stock1 != 0:
protein_stock[y] = protein_stock[y]-1
print(f"Client {client_being_served_1} is getting Pasta : {pasta_menu[x]} and Protein : {protein_menu[y]}")
print(f"pasta {pasta_stock[x]} protein {protein_stock[y]} ")
self.queues["clients_getting_desert"].add_client(client_being_served_1)
if not self.queues["clients_getting_menu_2"].check_if_empty():
client_being_served_2 = self.queues["clients_getting_menu_2"].get_first_client()
if stock != 0:
pasta_stock[x] = pasta_stock[x]-1
print(f"Client {client_being_served_2} is getting Pasta :{pasta_menu[x]}")
print(f"pasta2 {pasta_stock[x]} ")
self.queues["clients_getting_desert"].add_client(client_being_served_2)
elif not self.queues["clients_getting_menu_3"].check_if_empty():
client_being_served_3 = self.queues["clients_getting_menu_3"].get_first_client()
if stock1 != 0:
protein_stock[y] = protein_stock[y]-1
print(f"Client {client_being_served_3} is getting Protein :{protein_menu[y]}")
print(f"protein3 {protein_stock[y]} ")
self.queues["clients_getting_desert"].add_client(client_being_served_3)
except Exception as e:
traceback.print_exc()
queues ={
"clients_waiting_to_pay_manually": Queue(),
"clients_waiting_to_pay_automatically": Queue(),
"clients_waiting_for_tray": Queue(),
"clients_getting_main_food": Queue(),
"clients_not_getting_main_food": Queue(),
"clients_getting_menu_1": Queue(),
"clients_getting_menu_2": Queue(),
"clients_getting_menu_3": Queue(),
"clients_getting_desert": Queue()
}
number_of_cashiers = 3
number_of_clients = 10
clients = [Clients(id, queues) for id in range(number_of_clients)]
stations = [Station(id, queues) for id in range(number_of_clients)]
trays = [Trays(queues) for id in range(number_of_clients)]
foods = [Main_food(id, queues) for id in range(number_of_clients)]
with concurrent.futures.ThreadPoolExecutor(max_workers=number_of_clients) as executor:
for client in clients:
executor.submit(client.change_queues)
with concurrent.futures.ThreadPoolExecutor(max_workers=number_of_clients) as executor:
for station in stations:
executor.submit(station.moving_station)
with concurrent.futures.ThreadPoolExecutor(max_workers=number_of_clients) as executor:
for tray in trays:
executor.submit(tray.giving_trays)
with concurrent.futures.ThreadPoolExecutor(max_workers=number_of_clients) as executor:
for food in foods:
executor.submit(food.getting_food)

when I use thread and win.Dispatch("SAPI.SpVoice") to make a book reader app i meet this question

my question is when i try to pause the speaker for a few minutes and i didn't do anything it will give me an error. Then i resume it, but it doesn't work.
I guess it might be a matter of releasing win.Dispatch("SAPI.SpVoice") from occupation.(For example, after a few minutes of idle he will automatically release the occupation)
is there anyone who can help me!!!
the error is there
Traceback (most recent call last):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/Administrator/Desktop/Learn/readBook/mainUI.py", line 158, in say
self.speaks[self.points['剑仙在此']].Speak(info)
File "<COMObject SAPI.SpVoice>", line 3, in Speak
pywintypes.com_error: (-2147352567, '发生意外。', (0, None, '没有注册类\r\n', None, 0, -2147201018), None)```
this is a part of my code.
def next(self):
self.speaks[self.points['剑仙在此']].pause()
self.points['剑仙在此'] += 1
self.uploadPoint()
self.start()
def last(self):
self.speaks[self.points['剑仙在此']].pause()
self.points['剑仙在此'] -= 1
self.uploadPoint()
self.start()
def start(self):
self.flishPoint()
for title, value in self.info[str(self.points['剑仙在此'])].items():
contents = value.split()
contents.insert(0, title)
self.readBook(contents)
def paused(self):
print(self.speaks[self.points['剑仙在此']])
if self.now:
self.now = False
self.speaks[self.points['剑仙在此']].pause()
else:
self.now = True
self.speaks[self.points['剑仙在此']].resume()
def speedAdd(self):
self.speed += 1
self.speaks[self.points['剑仙在此']].Rate = self.speed
def speedSub(self):
self.speed -= 1
self.speaks[self.points['剑仙在此']].Rate = self.speed
def readBook(self, contents):
self.ui.plainTextEdit.clear()
info = ''
for line in contents:
info += line + '\n'
self.thread = Thread(target=self.say, args=(info,), daemon=True)
self.thread.start()
self.ui.plainTextEdit.appendPlainText(info)
def say(self, info):
pythoncom.CoInitialize()
self.speaks[self.points['剑仙在此']] = win.Dispatch("SAPI.SpVoice")
self.speaks[self.points['剑仙在此']].Rate = self.speed
print(self.speaks[self.points['剑仙在此']])
self.speaks[self.points['剑仙在此']].Speak(info)

How do you post form data using pytest?

I'm trying to write a unit test that posts form data. The actual line in question is:
def test_create_request():
with app.test_client() as test_client:
app_url = '/requests/'
with app.app_context():
new_request = get_new_request()
form_data = json.dumps(new_request, default=str)
print('FORM DATA: ', form_data)
resp = test_client.post(app_url, data=form_data, headers={'Content-Type': 'application/json'})
assert resp.status_code == 200
s = json.loads(resp.data)
assert s['success'] == True
Where new_request is a dict representation of an object. The print statement yields (I've formatted it a bit):
FORM DATA: {
"request_id": "6",
"state_id": 1,
"orig_project_id": "1",
"orig_project_code": "QQQ",
"orig_allocated_funding": "123.45",
"orig_ytd_spend": "123.45",
"orig_ytd_commit": "123.45",
"orig_ytd_ocnr": "123.45",
"new_project_id": 2,
"new_funding_amount": 123.45,
"new_ytd_spend": 123.45,
"new_ytd_commit": 123.45,
"new_ytd_ocnr": 123.45,
"plan": "this is the plan",
"reason": "this is the reason",
"sm_director": "sm.dir#example.com",
"submitted_by": "xfgbn#vexample.com",
"created_on": "2021-09-14 16:32:55",
"meets_approval_guidelines": null
}
In the flask form, most fields are required. When I try to post the data, the form.validate_on_submit() function in the view's route returns False, and the 2nd assert fails. WTForms claims that none of the required orig_allocated_funding, orig_ytd_spend, orig_ytd_commit, orig_ytd_ocnr, new_project_id, new_funding_amount, new_ytd_spend, new_ytd_commit, new_ytd_ocnr, reason, plan, sm_director, or submitted_by fields are supplied.
I've read several tutorials, and I can't see what I'm doing wrong. Can anyone help?
What I was able to make work was scraping form_data altogether:
def test_create_request():
with app.test_client() as test_client:
app_url = '/requests/'
with app.app_context():
new_request = get_new_request()
resp = test_client.post(app_url, data=new_request)
assert resp.status_code == 200
s = json.loads(resp.data)
print(s['html'])
assert s['success'] == True

How to return connection from a JDBC connection class using Scala's exception handling?

I am trying to create a Scala JDBC program where a connection to Hive is being made. To do this, I wrote the below code.
var HIVECON: Connection = null
def hiveConnection(): Connection = {
val conf = new Configuration()
conf.set("hadoop.security.authentication", "Kerberos")
// DEV System Properties
System.setProperty("java.security.krb5.kdc", "ip-address.ec2.internal");
System.setProperty("java.security.krb5.realm", "DEV.COM");
// DEV System Properties
// DEV loginUserFromKeytab
UserGroupInformation.loginUserFromKeytab("username#DEV.COM", "/home/username/username.keytab");
// DEV loginUserFromKeytab
try {
Class.forName("org.apache.hive.jdbc.HiveDriver")
if(HIVECON == null || HIVECON.isClosed)
HIVECON = DriverManager.getConnection("jdbc:hive2://ip-address.ec2.internal:10500/dbname;principal=hive/ip-address.ec2.internal#DEV.COM", "username","password")
else HIVECON
} catch {
case s:SQLException => s.printStackTrace()
case e:Exception => e.printStackTrace()
}
}
But the code gives a compilation error at these lines:
With the way I wrote, the catch statements are returning UNIT where my method is trying to return CONNECTION. Is there any way to handle the exception better ?
I would handle the Exception in a functional way.
If you do not care about specific Exception use Option:
var HIVECON: Option[Connection] = None
def hiveConnection(): Option[Connection] = {
...
try {
Class.forName("org.apache.hive.jdbc.HiveDriver")
if(HIVECON == None || HIVECON.get.isClosed)
HIVECON = Some(DriverManager.getConnection("jdbc:hive2://ip-address.ec2.internal:10500/dbname;principal=hive/ip-address.ec2.internal#DEV.COM", "username","password"))
HIVECON // return Some(Connection)
} catch {
case s:Exception =>
s.printStackTrace()
None
}
If you care for the Exception use Try:
var HIVECON: Connection = null
def hiveConnection(): Try[Connection] = {
...
Try {
Class.forName("org.apache.hive.jdbc.HiveDriver")
if(HIVECON == null || HIVECON.isClosed)
HIVECON = DriverManager.getConnection("jdbc:hive2://ip-address.ec2.internal:10500/dbname;principal=hive/ip-address.ec2.internal#DEV.COM", "username","password")
HIVECON // return Success(Connection)
}
In case of a Failure it returns Failure(Exception).
See here the Docs: https://docs.scala-lang.org/overviews/scala-book/functional-error-handling.html

Unregistered task in Celery

tasks.py:
from celery import Celery
from django.http import HttpResponse
from anyjson import serialize
celery = Celery('tasks', broker='amqp://guest#localhost//')
##celery.task
def add(request):
x = int(request.GET['x'])
y = int(request.GET['y'])
result = x+y
response = {'status': 'success', 'retval': result}
return HttpResponse(serialize(response), mimetype='application/json')
after starting the worker,i tried http dispatcher:
from celery.task.http import URL
res = URL('http://localhost/add').get_async(x=10, y=10)
res.state
'PENDING'
and got error like,
[2013-04-03 06:39:54,791: ERROR/MainProcess] Received unregistered task of type u'celery.task.http.HttpDispatchTask'.
The message has been ignored and discarded.
Did you remember to import the module containing this task?
Or maybe you are using relative imports?
More: http://docs.celeryq.org/en/latest/userguide/tasks.html#names
The full contents of the message body was:
{u'utc': True, u'chord': None, u'args': [u'http://localhost/add', u'GET'], u'retries': 0, u'expires': None, u'task': u'celery.task.http.HttpDispatchTask', u'callbacks': None, u'errbacks': None, u'taskset': None, u'kwargs': {u'y': 10, u'x': 10}, u'eta': None, u'id': u'29f83cc9-ba5a-4008-9d2d-6f7bb24b0cfc'} (288b)
Traceback (most recent call last):
File "/usr/local/gdp/python2.7.2/lib/python2.7/site-packages/celery-3.0.13-py2.7.egg/celery/worker/consumer.py", line 435, in on_task_received
strategies[name](message, body, message.ack_log_error)
KeyError: u'celery.task.http.HttpDispatchTask'
Apologies if I'm stating the obvious, but the task decorator ##celery.task is commented out.