update __pg__ to __doc__
This commit is contained in:
parent
48c48e587e
commit
7969851f3a
@ -6,7 +6,7 @@
|
||||
<template #body-content>
|
||||
<div class="flex flex-col w-full">
|
||||
<AlertBanner
|
||||
v-if="referenceDoctype === 'Team'"
|
||||
v-if="referencePagetype === 'Team'"
|
||||
title="Notifications will go to the General channel by default. If General isn't available, they'll be delivered to registered email addresses."
|
||||
type="info"
|
||||
:showIcon="false"
|
||||
@ -80,7 +80,7 @@ import AlertBanner from './AlertBanner.vue';
|
||||
export default {
|
||||
name: 'CommunicationInfoDialog',
|
||||
props: {
|
||||
referenceDoctype: {
|
||||
referencePagetype: {
|
||||
type: String,
|
||||
validator: (value) => ['Team', 'Site', 'Server'].includes(value),
|
||||
required: true,
|
||||
@ -104,7 +104,7 @@ export default {
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.referenceDoctype && this.referenceName) {
|
||||
if (this.referencePagetype && this.referenceName) {
|
||||
this.$resources.getCommunicationInfos.submit();
|
||||
}
|
||||
},
|
||||
@ -114,7 +114,7 @@ export default {
|
||||
url: 'jcloude.api.client.run_pg_method',
|
||||
makeParams() {
|
||||
return {
|
||||
dt: this.referenceDoctype,
|
||||
dt: this.referencePagetype,
|
||||
dn: this.referenceName,
|
||||
method: 'get_communication_infos',
|
||||
};
|
||||
@ -130,7 +130,7 @@ export default {
|
||||
url: 'jcloude.api.client.run_pg_method',
|
||||
makeParams() {
|
||||
return {
|
||||
dt: this.referenceDoctype,
|
||||
dt: this.referencePagetype,
|
||||
dn: this.referenceName,
|
||||
method: 'update_communication_infos',
|
||||
args: { values: this.currentCommunicationInfos },
|
||||
@ -258,9 +258,9 @@ export default {
|
||||
);
|
||||
},
|
||||
filteredCommunicationTypes() {
|
||||
if (this.referenceDoctype == 'Server') {
|
||||
if (this.referencePagetype == 'Server') {
|
||||
return ['General', 'Incident', 'Server Activity'];
|
||||
} else if (this.referenceDoctype == 'Site') {
|
||||
} else if (this.referencePagetype == 'Site') {
|
||||
return ['General', 'Site Activity'];
|
||||
}
|
||||
return [
|
||||
|
||||
@ -92,7 +92,7 @@ function getSiteActionHandler(action) {
|
||||
function onNotificationSettings() {
|
||||
return renderDialog(
|
||||
h(CommunicationInfoDialog, {
|
||||
referenceDoctype: 'Site',
|
||||
referencePagetype: 'Site',
|
||||
referenceName: site.pg.name,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -74,7 +74,7 @@ function onNotificationSettings() {
|
||||
if (!server?.pg) return;
|
||||
return renderDialog(
|
||||
h(CommunicationInfoDialog, {
|
||||
referenceDoctype: 'Server',
|
||||
referencePagetype: 'Server',
|
||||
referenceName: server.pg.name,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
>
|
||||
<lucide-alert-triangle class="mr-4 inline-block h-6 w-6" />
|
||||
<div>
|
||||
All <b>doctypes</b> & <b>modules</b>, along with all the
|
||||
All <b>pagetypes</b> & <b>modules</b>, along with all the
|
||||
<b>data</b> within this app will be removed from the site.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -6,7 +6,7 @@ published: 1
|
||||
|
||||
## The Marketplace App PageType
|
||||
|
||||
The main master for marketplace is the “Marketplace App” PageType around which all the other doctypes revolve around.
|
||||
The main master for marketplace is the “Marketplace App” PageType around which all the other pagetypes revolve around.
|
||||
|
||||
## Release Management
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ Assume a case, you want to create a webhook event whenever the site status got u
|
||||
|
||||
It may not work because in agent job update process functions and other places, we use `set_value` call. So, we need to call this `create_webhook_event` function at those places as well.
|
||||
|
||||
Related Doctypes
|
||||
Related Pagetypes
|
||||
----------------
|
||||
|
||||
1. **Jcloude Webhook Event** - Type of webhook events (e.g. *Site Status Update*).
|
||||
|
||||
@ -4,13 +4,13 @@ allow_guest: 1
|
||||
published: 1
|
||||
---
|
||||
|
||||
This is information about doctypes required to manage benches and apps on FC
|
||||
This is information about pagetypes required to manage benches and apps on FC
|
||||
from [desk](https://jcloud.jingrow.com/app). Roughly, the build process goes
|
||||
through these doctypes (that you're concerned with) in order.
|
||||
through these pagetypes (that you're concerned with) in order.
|
||||
|
||||
App => App Source => Release Group => Deploy Candidate => Bench
|
||||
|
||||
To build a bench, we need documents of the following doctypes.
|
||||
To build a bench, we need documents of the following pagetypes.
|
||||
|
||||
## App
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ This page describes how Subscription Management works in Jingrow Cloud.
|
||||
|
||||
## PageTypes
|
||||
|
||||
These are the key doctypes that are related to subscription:
|
||||
These are the key pagetypes that are related to subscription:
|
||||
|
||||
1. [Plan](/app/plan): List of plans
|
||||
2. [Subscription](/app/subscription): Record of active subscriptions
|
||||
|
||||
@ -100,7 +100,7 @@ test files (for organization reasons). These functions will be doing the bare
|
||||
minimum to make a valid document of that pagetype.
|
||||
|
||||
Eg: `create_test_bench` in `test_bench.py` can be imported and used whenever
|
||||
you need a valid bench (which itself has dependencies on many other doctypes)
|
||||
you need a valid bench (which itself has dependencies on many other pagetypes)
|
||||
|
||||
You can also add default args to these utility functions as you come across the
|
||||
need. Just append to end so you won't have to rewrite pre-existing tests.
|
||||
|
||||
@ -1064,10 +1064,10 @@ def get_permission_options(name, ptype):
|
||||
available_actions,
|
||||
)
|
||||
|
||||
doctypes = jingrow.get_all("Jcloude Method Permission", pluck="document_type", distinct=True)
|
||||
pagetypes = jingrow.get_all("Jcloude Method Permission", pluck="document_type", distinct=True)
|
||||
|
||||
options = []
|
||||
for pagetype in doctypes:
|
||||
for pagetype in pagetypes:
|
||||
pg = jingrow.qb.PageType(pagetype)
|
||||
perm_pg = jingrow.qb.PageType("Jcloude User Permission")
|
||||
subtable = (
|
||||
|
||||
@ -112,7 +112,7 @@ def get_list(
|
||||
if filters is None:
|
||||
filters = {}
|
||||
|
||||
# these doctypes doesn't have a team field to filter by but are used in get or run_pg_method
|
||||
# these pagetypes doesn't have a team field to filter by but are used in get or run_pg_method
|
||||
if pagetype in ["Team", "User SSH Key"]:
|
||||
return []
|
||||
|
||||
@ -183,18 +183,18 @@ def get_list_query(
|
||||
)
|
||||
|
||||
if meta.istable and jingrow.get_meta(filters.get("parenttype")).has_field("team"):
|
||||
ParentDocType = jingrow.qb.PageType(filters.get("parenttype"))
|
||||
ChildDocType = jingrow.qb.PageType(pagetype)
|
||||
ParentPageType = jingrow.qb.PageType(filters.get("parenttype"))
|
||||
ChildPageType = jingrow.qb.PageType(pagetype)
|
||||
|
||||
query = (
|
||||
query.join(ParentDocType)
|
||||
.on(ParentDocType.name == ChildDocType.parent)
|
||||
.where(ParentDocType.team == jingrow.local.team().name)
|
||||
query.join(ParentPageType)
|
||||
.on(ParentPageType.name == ChildPageType.parent)
|
||||
.where(ParentPageType.team == jingrow.local.team().name)
|
||||
)
|
||||
|
||||
if document_options and isinstance(document_options, list):
|
||||
QueryDoctype = jingrow.qb.PageType(pagetype)
|
||||
query = query.where(QueryDoctype.name.isin(document_options))
|
||||
QueryPagetype = jingrow.qb.PageType(pagetype)
|
||||
query = query.where(QueryPagetype.name.isin(document_options))
|
||||
|
||||
return query
|
||||
|
||||
|
||||
@ -30,11 +30,11 @@ if TYPE_CHECKING:
|
||||
from jcloude.jcloude.pagetype.server_plan.server_plan import ServerPlan
|
||||
|
||||
|
||||
def poly_get_pg(doctypes, name):
|
||||
for pagetype in doctypes:
|
||||
def poly_get_pg(pagetypes, name):
|
||||
for pagetype in pagetypes:
|
||||
if jingrow.db.exists(pagetype, name):
|
||||
return jingrow.get_pg(pagetype, name)
|
||||
return jingrow.get_pg(doctypes[-1], name)
|
||||
return jingrow.get_pg(pagetypes[-1], name)
|
||||
|
||||
|
||||
def get_mount_point(server: str, server_type=None) -> str:
|
||||
|
||||
@ -50,21 +50,21 @@ if TYPE_CHECKING:
|
||||
from jcloude.jcloude.pagetype.team.team import Team
|
||||
|
||||
|
||||
def protected(doctypes):
|
||||
def protected(pagetypes):
|
||||
"""
|
||||
This decorator is stupid. It works in magical ways. It checks whether the
|
||||
owner of the Pagetype (one of `doctypes`) is the same as the current team.
|
||||
owner of the Pagetype (one of `pagetypes`) is the same as the current team.
|
||||
|
||||
The stupid magical part of this decorator is how it gets the name of the
|
||||
Pagetype (see: `get_protected_pagetype_name`); in order of precedence:
|
||||
1. kwargs value with key `name`
|
||||
2. first value in kwargs value with key `filters` i.e. ≈ `kwargs['filters'].values()[0]`
|
||||
3. first value in the args tuple
|
||||
4. kwargs value with key `snake_case(doctypes[0])`
|
||||
4. kwargs value with key `snake_case(pagetypes[0])`
|
||||
"""
|
||||
|
||||
if not isinstance(doctypes, list):
|
||||
doctypes = [doctypes]
|
||||
if not isinstance(pagetypes, list):
|
||||
pagetypes = [pagetypes]
|
||||
|
||||
@wrapt.decorator
|
||||
def wrapper(wrapped, instance, args, kwargs):
|
||||
@ -77,11 +77,11 @@ def protected(doctypes):
|
||||
return wrapped(*args, **kwargs)
|
||||
|
||||
# Get the name of the document being accessed.
|
||||
if not (docname := get_protected_pagetype_name(args, kwargs, doctypes)):
|
||||
if not (docname := get_protected_pagetype_name(args, kwargs, pagetypes)):
|
||||
jingrow.throw("Name not found, API access not permitted", jingrow.PermissionError)
|
||||
|
||||
current_team = get_current_team()
|
||||
for pagetype in doctypes:
|
||||
for pagetype in pagetypes:
|
||||
document_team = jingrow.db.get_value(pagetype, docname, "team")
|
||||
if document_team == current_team or has_support_access(pagetype, docname):
|
||||
return wrapped(*args, **kwargs)
|
||||
@ -92,7 +92,7 @@ def protected(doctypes):
|
||||
return wrapper
|
||||
|
||||
|
||||
def get_protected_pagetype_name(args: list, kwargs: dict, doctypes: list[str]):
|
||||
def get_protected_pagetype_name(args: list, kwargs: dict, pagetypes: list[str]):
|
||||
# 1. Name from kwargs["name"] or kwargs["pg_name"]
|
||||
if name := (kwargs.get("name") or kwargs.get("pg_name")):
|
||||
return name
|
||||
@ -106,11 +106,11 @@ def get_protected_pagetype_name(args: list, kwargs: dict, doctypes: list[str]):
|
||||
if len(args) >= 1 and args[0]:
|
||||
return args[0]
|
||||
|
||||
if len(doctypes) == 0:
|
||||
if len(pagetypes) == 0:
|
||||
return None
|
||||
|
||||
# 4. Name from snakecased first `doctypes` name
|
||||
pagetype = doctypes[0]
|
||||
# 4. Name from snakecased first `pagetypes` name
|
||||
pagetype = pagetypes[0]
|
||||
key = pagetype.lower().replace(" ", "_")
|
||||
return kwargs.get(key)
|
||||
|
||||
|
||||
@ -435,7 +435,7 @@ page_renderer = ["jcloude.metrics.MetricsRenderer"]
|
||||
|
||||
export_python_type_annotations = True
|
||||
|
||||
default_log_clearing_doctypes = {
|
||||
default_log_clearing_pagetypes = {
|
||||
"Alertmanager Webhook Log": 60,
|
||||
}
|
||||
|
||||
@ -470,10 +470,10 @@ persistent_cache_keys = [
|
||||
"defaults",
|
||||
"pagetype_form_meta",
|
||||
"pagetype_meta",
|
||||
"doctypes_with_web_view",
|
||||
"pagetypes_with_web_view",
|
||||
"document_cache::*",
|
||||
"document_naming_rule_map",
|
||||
"domain_restricted_doctypes",
|
||||
"domain_restricted_pagetypes",
|
||||
"domain_restricted_pages",
|
||||
"energy_point_rule_map",
|
||||
"jingrow.utils.scheduler.schedule_jobs_based_on_activity*", # dormant checks
|
||||
|
||||
@ -225,14 +225,14 @@ class IncidentInvestigator(Document):
|
||||
@property
|
||||
def steps(self) -> dict[str, list[tuple[str, "Callable"]]]:
|
||||
investigation_steps = [
|
||||
(self.has_high_disk_usage.__pg__, self.has_high_disk_usage.__name__),
|
||||
(self.has_high_memory_usage.__pg__, self.has_high_memory_usage.__name__),
|
||||
(self.has_high_cpu_load.__pg__, self.has_high_cpu_load.__name__),
|
||||
(self.has_high_system_load.__pg__, self.has_high_system_load.__name__),
|
||||
(self.has_high_disk_usage.__doc__, self.has_high_disk_usage.__name__),
|
||||
(self.has_high_memory_usage.__doc__, self.has_high_memory_usage.__name__),
|
||||
(self.has_high_cpu_load.__doc__, self.has_high_cpu_load.__name__),
|
||||
(self.has_high_system_load.__doc__, self.has_high_system_load.__name__),
|
||||
]
|
||||
return {
|
||||
"proxy_investigation_steps": [
|
||||
(self.are_sites_on_proxy_down.__pg__, self.are_sites_on_proxy_down.__name__),
|
||||
(self.are_sites_on_proxy_down.__doc__, self.are_sites_on_proxy_down.__name__),
|
||||
# *investigation_steps[1:],
|
||||
], # Don't care about disk usage in proxy's case
|
||||
"server_investigation_steps": investigation_steps,
|
||||
|
||||
@ -583,7 +583,7 @@ class VirtualDiskResize(Document):
|
||||
for method, wait_for_completion in methods:
|
||||
steps.append(
|
||||
{
|
||||
"step": method.__pg__,
|
||||
"step": method.__doc__,
|
||||
"method": method.__name__,
|
||||
"wait_for_completion": wait_for_completion,
|
||||
}
|
||||
|
||||
@ -309,7 +309,7 @@ class VirtualMachineMigration(Document):
|
||||
for method, wait_for_completion in methods:
|
||||
steps.append(
|
||||
{
|
||||
"step": method.__pg__,
|
||||
"step": method.__doc__,
|
||||
"method": method.__name__,
|
||||
"wait_for_completion": wait_for_completion,
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ class VirtualMachineReplacement(Document):
|
||||
for method, wait_for_completion in methods:
|
||||
steps.append(
|
||||
{
|
||||
"step": method.__pg__,
|
||||
"step": method.__doc__,
|
||||
"method": method.__name__,
|
||||
"wait_for_completion": wait_for_completion,
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ jcloude.patches.v0_0_1.add_domains_to_site_config
|
||||
execute:jingrow.reload_pg('jcloude', 'pagetype', 'Remote File')
|
||||
# jcloude.patches.v0_0_1.add_site_to_remote_file # 2020-11-12 run via run-patch command in active site state
|
||||
jcloude.patches.v0_0_1.new_onboarding
|
||||
jcloude.patches.v0_0_1.remove_obsolete_doctypes
|
||||
jcloude.patches.v0_0_1.remove_obsolete_pagetypes
|
||||
jcloude.patches.v0_0_1.make_default_site_domain
|
||||
jcloude.patches.v0_0_1.update_site_config_pg
|
||||
jcloude.patches.v0_0_1.create_certificate_authorities
|
||||
@ -75,7 +75,7 @@ jcloude.patches.v0_0_1.add_domains_in_site_config_preview
|
||||
jcloude.patches.v0_0_1.use_private_ip_for_upstreams
|
||||
jcloude.jcloude.pagetype.site.patches.set_plan_in_site
|
||||
jcloude.jcloude.pagetype.app_release.patches.set_status_to_draft
|
||||
jcloude.patches.v0_0_4.remove_legacy_billing_doctypes
|
||||
jcloude.patches.v0_0_4.remove_legacy_billing_pagetypes
|
||||
# jcloude.jcloude.pagetype.invoice.patches.set_free_credits # 2021-08-11 run via run-patch command
|
||||
jcloude.jcloude.pagetype.team.patches.set_payment_mode
|
||||
jcloude.patches.v0_0_1.add_team_name_as_default_notify_email
|
||||
@ -109,7 +109,7 @@ jcloude.jcloude.pagetype.virtual_disk_snapshot.patches.rename_aws_fields
|
||||
jcloude.jcloude.pagetype.virtual_machine_volume.patches.rename_aws_fields
|
||||
jcloude.patches.v0_7_0.convert_marketplace_description_to_html
|
||||
jcloude.jcloude.pagetype.team.patches.remove_invalid_email_addresses
|
||||
jcloude.saas.pagetype.product_trial.patches.rename_saas_product_doctypes_to_product_trial
|
||||
jcloude.saas.pagetype.product_trial.patches.rename_saas_product_pagetypes_to_product_trial
|
||||
|
||||
[post_model_sync]
|
||||
jcloude.patches.v0_7_0.rename_plan_to_site_plan
|
||||
@ -119,7 +119,7 @@ jcloude.jcloude.pagetype.agent_job.patches.update_status_for_undelivered_jobs #2
|
||||
jcloude.jcloude.pagetype.jcloude_role.patches.migrate_permissions
|
||||
jcloude.jcloude.pagetype.jcloude_role.patches.change_fields_from_enable_to_allow
|
||||
jcloude.jcloude.pagetype.stripe_webhook_log.patches.add_payment_method_for_failed_events
|
||||
jcloude.patches.v0_7_0.add_team_field_for_site_related_doctypes
|
||||
jcloude.patches.v0_7_0.add_team_field_for_site_related_pagetypes
|
||||
jcloude.patches.v0_7_0.add_team_field_for_site_backups_archived
|
||||
jcloude.jcloude.pagetype.server_storage_plan.patches.add_subscription_for_servers_with_additional_disk
|
||||
jcloude.jcloude.pagetype.jcloude_notification.patches.link_reference_pagetype_to_notifications
|
||||
|
||||
@ -9,7 +9,7 @@ def execute():
|
||||
jingrow.reload_pg("jcloude", "pagetype", "cluster")
|
||||
cluster = jingrow.get_pg({"pagetype": "Cluster", "name": "Default", "default": True})
|
||||
cluster.insert()
|
||||
doctypes = ["Server", "Proxy Server", "Database Server", "Bench", "Site"]
|
||||
for pagetype in doctypes:
|
||||
pagetypes = ["Server", "Proxy Server", "Database Server", "Bench", "Site"]
|
||||
for pagetype in pagetypes:
|
||||
jingrow.reload_pg("jcloude", "pagetype", jingrow.scrub(pagetype))
|
||||
jingrow.db.set_value(pagetype, {"name": ("like", "%")}, "cluster", "Default")
|
||||
|
||||
@ -7,7 +7,7 @@ import jingrow
|
||||
|
||||
|
||||
def execute():
|
||||
obsolete_doctypes = [
|
||||
obsolete_pagetypes = [
|
||||
"Credit Ledger Entry",
|
||||
"Custom Domain",
|
||||
"Site Analytics",
|
||||
@ -16,6 +16,6 @@ def execute():
|
||||
"Usage Report",
|
||||
"User Account",
|
||||
]
|
||||
for pagetype in obsolete_doctypes:
|
||||
for pagetype in obsolete_pagetypes:
|
||||
if jingrow.db.exists("PageType", pagetype):
|
||||
jingrow.delete_pg("PageType", pagetype)
|
||||
|
||||
@ -6,8 +6,8 @@ import jingrow
|
||||
|
||||
|
||||
def execute():
|
||||
doctypes = ["Server", "Proxy Server", "Database Server"]
|
||||
for pagetype in doctypes:
|
||||
pagetypes = ["Server", "Proxy Server", "Database Server"]
|
||||
for pagetype in pagetypes:
|
||||
jingrow.reload_pg("jcloude", "pagetype", jingrow.scrub(pagetype))
|
||||
servers = jingrow.get_all(pagetype, {"hostname": ("is", "not set")})
|
||||
domain = jingrow.db.get_single_value("Jcloude Settings", "domain")
|
||||
|
||||
@ -6,6 +6,6 @@ import jingrow
|
||||
|
||||
|
||||
def execute():
|
||||
# these doctypes are only deleted from PageType table, their tables will exist
|
||||
doctypes = ["Payment", "Payment Ledger Entry"]
|
||||
jingrow.db.sql("DELETE from tabDocType where name in %s", [doctypes])
|
||||
# these pagetypes are only deleted from PageType table, their tables will exist
|
||||
pagetypes = ["Payment", "Payment Ledger Entry"]
|
||||
jingrow.db.sql("DELETE from tabPageType where name in %s", [pagetypes])
|
||||
|
||||
@ -566,31 +566,31 @@ class PlanAudit(Audit):
|
||||
|
||||
def __init__(self):
|
||||
"""Check for plan and virtual machine discrepancies"""
|
||||
VirtualMachineDocType = jingrow.qb.PageType("Virtual Machine")
|
||||
VirtualMachinePageType = jingrow.qb.PageType("Virtual Machine")
|
||||
ServerPlan = jingrow.qb.PageType("Server Plan")
|
||||
server_types = ["Server", "Database Server"]
|
||||
server_level_discrepancies = {}
|
||||
|
||||
for server_type in server_types:
|
||||
ServerDoctype = jingrow.qb.PageType(server_type)
|
||||
ServerPagetype = jingrow.qb.PageType(server_type)
|
||||
query = (
|
||||
jingrow.qb.from_(ServerDoctype)
|
||||
jingrow.qb.from_(ServerPagetype)
|
||||
.select(
|
||||
ServerDoctype.name,
|
||||
ServerDoctype.plan,
|
||||
VirtualMachineDocType.machine_type,
|
||||
VirtualMachineDocType.ram.as_("vm_memory"),
|
||||
VirtualMachineDocType.disk_size.as_("vm_disk_size"),
|
||||
ServerPagetype.name,
|
||||
ServerPagetype.plan,
|
||||
VirtualMachinePageType.machine_type,
|
||||
VirtualMachinePageType.ram.as_("vm_memory"),
|
||||
VirtualMachinePageType.disk_size.as_("vm_disk_size"),
|
||||
ServerPlan.disk.as_("plan_disk_size"),
|
||||
ServerPlan.memory.as_("plan_memory"),
|
||||
)
|
||||
.join(VirtualMachineDocType)
|
||||
.on(VirtualMachineDocType.name == ServerDoctype.name)
|
||||
.join(VirtualMachinePageType)
|
||||
.on(VirtualMachinePageType.name == ServerPagetype.name)
|
||||
.join(ServerPlan)
|
||||
.on(ServerDoctype.plan == ServerPlan.name)
|
||||
.where(ServerDoctype.status == "Active")
|
||||
.where(ServerDoctype.is_self_hosted == False) # noqa: E712
|
||||
.where(ServerDoctype.cluster != "Hybrid")
|
||||
.on(ServerPagetype.plan == ServerPlan.name)
|
||||
.where(ServerPagetype.status == "Active")
|
||||
.where(ServerPagetype.is_self_hosted == False) # noqa: E712
|
||||
.where(ServerPagetype.cluster != "Hybrid")
|
||||
)
|
||||
server_plan_info: list[ServerPlanInfo] = query.run(as_dict=True)
|
||||
discrepancies = self.audit_plan_discrepancies(server_plan_info)
|
||||
|
||||
@ -207,7 +207,7 @@ def update_with_row_size_too_large_err(details: Details, job: AgentJob):
|
||||
details[
|
||||
"message"
|
||||
] = f"""<p>The server encountered a row size too large error while migrating the site <b>{job.site}</b>.</p>
|
||||
<p>This tends to happen on doctypes with many custom fields</p>
|
||||
<p>This tends to happen on pagetypes with many custom fields</p>
|
||||
<p>To rectify this issue, please follow the steps mentioned in <i>Help</i>.</p>
|
||||
"""
|
||||
|
||||
|
||||
@ -254,7 +254,7 @@ class AlertmanagerWebhookLog(Document):
|
||||
return jingrow.render_template(TELEGRAM_NOTIFICATION_TEMPLATE, context)
|
||||
|
||||
def guess_pagetype(self, name):
|
||||
doctypes = [
|
||||
pagetypes = [
|
||||
"Site",
|
||||
"Bench",
|
||||
"Server",
|
||||
@ -268,7 +268,7 @@ class AlertmanagerWebhookLog(Document):
|
||||
"Trace Server",
|
||||
"NFS Server",
|
||||
]
|
||||
for pagetype in doctypes:
|
||||
for pagetype in pagetypes:
|
||||
if jingrow.db.exists(pagetype, name):
|
||||
return pagetype
|
||||
return None
|
||||
|
||||
@ -247,7 +247,7 @@ class Cluster(Document):
|
||||
|
||||
@property
|
||||
def images_available(self) -> float:
|
||||
return len(self.get_same_region_vmis()) / len(self.server_doctypes)
|
||||
return len(self.get_same_region_vmis()) / len(self.server_pagetypes)
|
||||
|
||||
def validate_cidr_block(self):
|
||||
if not self.cidr_block:
|
||||
@ -674,15 +674,15 @@ class Cluster(Document):
|
||||
return VirtualMachineImage.get_available_for_series(series, self.region, platform=platform)
|
||||
|
||||
@property
|
||||
def server_doctypes(self):
|
||||
server_doctypes = {**self.base_servers}
|
||||
def server_pagetypes(self):
|
||||
server_pagetypes = {**self.base_servers}
|
||||
if not self.public:
|
||||
server_doctypes = {**server_doctypes, **self.private_servers}
|
||||
return server_doctypes
|
||||
server_pagetypes = {**server_pagetypes, **self.private_servers}
|
||||
return server_pagetypes
|
||||
|
||||
def get_same_region_vmis(self, platform="x86_64", get_series=False) -> list[str]:
|
||||
vmis = []
|
||||
for series in list(self.server_doctypes.values()):
|
||||
for series in list(self.server_pagetypes.values()):
|
||||
vmis.extend(
|
||||
jingrow.get_all(
|
||||
"Virtual Machine Image",
|
||||
@ -704,7 +704,7 @@ class Cluster(Document):
|
||||
|
||||
def get_other_region_vmis(self, platform="x86_64", get_series=False) -> list[str]:
|
||||
vmis = []
|
||||
for series in list(self.server_doctypes.values()):
|
||||
for series in list(self.server_pagetypes.values()):
|
||||
vmis.extend(
|
||||
jingrow.get_all(
|
||||
"Virtual Machine Image",
|
||||
|
||||
@ -226,7 +226,7 @@ class LogicalReplicationBackup(Document):
|
||||
continue
|
||||
steps.append(
|
||||
{
|
||||
"step": method.__pg__,
|
||||
"step": method.__doc__,
|
||||
"method": method.__name__,
|
||||
"is_async": is_async,
|
||||
"wait_for_completion": wait_for_completion,
|
||||
|
||||
@ -114,7 +114,7 @@ class PhysicalBackupRestoration(Document):
|
||||
for method, is_async, wait_for_completion, is_cleanup_step in methods:
|
||||
steps.append(
|
||||
{
|
||||
"step": method.__pg__,
|
||||
"step": method.__doc__,
|
||||
"method": method.__name__,
|
||||
"is_async": is_async,
|
||||
"wait_for_completion": wait_for_completion,
|
||||
|
||||
@ -24,11 +24,11 @@ class PressMethodPermission(Document):
|
||||
|
||||
def available_actions():
|
||||
result = {}
|
||||
doctypes = jingrow.get_all(
|
||||
pagetypes = jingrow.get_all(
|
||||
"Jcloude Method Permission", pluck="document_type", distinct=True
|
||||
)
|
||||
|
||||
for pagetype in doctypes:
|
||||
for pagetype in pagetypes:
|
||||
result[pagetype] = {
|
||||
perm["checkbox_label"]: perm["method"]
|
||||
for perm in jingrow.get_all(
|
||||
|
||||
@ -9,7 +9,7 @@ from jingrow.model.document import Document
|
||||
from jcloude.api.client import dashboard_whitelist
|
||||
|
||||
DEFAULT_PERMISSIONS = {
|
||||
"*": {"*": {"*": True}} # all doctypes # all documents # all methods
|
||||
"*": {"*": {"*": True}} # all pagetypes # all documents # all methods
|
||||
}
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ class PressPermissionGroup(Document):
|
||||
return
|
||||
|
||||
for pagetype, pagetype_perms in permissions.items():
|
||||
if pagetype not in get_all_restrictable_doctypes() and pagetype != "*":
|
||||
if pagetype not in get_all_restrictable_pagetypes() and pagetype != "*":
|
||||
jingrow.throw(f"{pagetype} is not a valid pagetype.")
|
||||
|
||||
if not isinstance(pagetype_perms, dict):
|
||||
@ -158,7 +158,7 @@ class PressPermissionGroup(Document):
|
||||
if not (jingrow.local.system_user() or user_belongs_to_group or user_is_team_owner):
|
||||
jingrow.throw(f"{user} does not belong to {self.name}")
|
||||
|
||||
if pagetype not in get_all_restrictable_doctypes():
|
||||
if pagetype not in get_all_restrictable_pagetypes():
|
||||
jingrow.throw(f"{pagetype} is not a valid restrictable pagetype.")
|
||||
|
||||
restrictable_methods = get_all_restrictable_methods(pagetype)
|
||||
@ -218,7 +218,7 @@ def has_method_permission(pagetype: str, name: str, method: str, group_names: li
|
||||
|
||||
user = jingrow.session.user
|
||||
|
||||
if pagetype not in get_all_restrictable_doctypes():
|
||||
if pagetype not in get_all_restrictable_pagetypes():
|
||||
return True
|
||||
|
||||
if method not in get_all_restrictable_methods(pagetype):
|
||||
@ -240,7 +240,7 @@ def has_method_permission(pagetype: str, name: str, method: str, group_names: li
|
||||
def get_permitted_methods(pagetype: str, name: str, group_names: list | None = None) -> list:
|
||||
user = jingrow.session.user
|
||||
|
||||
if pagetype not in get_all_restrictable_doctypes():
|
||||
if pagetype not in get_all_restrictable_pagetypes():
|
||||
jingrow.throw(f"{pagetype} is not a valid restrictable pagetype.")
|
||||
|
||||
permissions_by_group = {}
|
||||
@ -314,7 +314,7 @@ def resolve_pg_permissions(pagetype, permissions_by_group: dict) -> dict: # noq
|
||||
return method_perms
|
||||
|
||||
|
||||
def get_all_restrictable_doctypes() -> list:
|
||||
def get_all_restrictable_pagetypes() -> list:
|
||||
return ["Site", "Release Group"]
|
||||
|
||||
|
||||
|
||||
@ -130,11 +130,11 @@ class TestPressPermissionGroup(FrappeTestCase):
|
||||
self.assertRaises(
|
||||
jingrow.ValidationError,
|
||||
self.perm_group.get_all_document_permissions,
|
||||
"InvalidDoctype",
|
||||
"InvalidPagetype",
|
||||
)
|
||||
|
||||
# Test case 4: No restrictable methods for the pagetype
|
||||
self.assertRaises(jingrow.ValidationError, self.perm_group.get_all_document_permissions, "DocType2")
|
||||
self.assertRaises(jingrow.ValidationError, self.perm_group.get_all_document_permissions, "PageType2")
|
||||
|
||||
|
||||
# utils
|
||||
|
||||
@ -953,7 +953,7 @@ class BaseServer(Document, TagHelpers):
|
||||
|
||||
volumes = self.get_volume_mounts()
|
||||
if volumes or self.has_data_volume:
|
||||
# Adding this condition since this method is called from both server and database server doctypes
|
||||
# Adding this condition since this method is called from both server and database server pagetypes
|
||||
if self.pagetype == "Server":
|
||||
mountpoint = BENCH_DATA_MNT_POINT
|
||||
elif self.pagetype == "Database Server":
|
||||
|
||||
@ -21,7 +21,7 @@ class SiteAnalytics(Document):
|
||||
)
|
||||
from jcloude.jcloude.pagetype.site_analytics_app.site_analytics_app import SiteAnalyticsApp
|
||||
from jcloude.jcloude.pagetype.site_analytics_pagetype.site_analytics_pagetype import (
|
||||
SiteAnalyticsDocType,
|
||||
SiteAnalyticsPageType,
|
||||
)
|
||||
from jcloude.jcloude.pagetype.site_analytics_login.site_analytics_login import (
|
||||
SiteAnalyticsLogin,
|
||||
@ -42,7 +42,7 @@ class SiteAnalytics(Document):
|
||||
language: DF.Data | None
|
||||
last_active: DF.Table[SiteAnalyticsActive]
|
||||
last_logins: DF.Table[SiteAnalyticsLogin]
|
||||
sales_data: DF.Table[SiteAnalyticsDocType]
|
||||
sales_data: DF.Table[SiteAnalyticsPageType]
|
||||
scheduler_enabled: DF.Check
|
||||
setup_complete: DF.Check
|
||||
site: DF.Link
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
from jingrow.model.document import Document
|
||||
|
||||
|
||||
class SiteAnalyticsDocType(Document):
|
||||
class SiteAnalyticsPageType(Document):
|
||||
# begin: auto-generated types
|
||||
# This code is auto-generated. Do not modify anything in this block.
|
||||
|
||||
|
||||
@ -312,7 +312,7 @@ class SiteMigration(Document):
|
||||
|
||||
def _add_setup_redirects_step(self):
|
||||
step = {
|
||||
"step_title": self.setup_redirects.__pg__,
|
||||
"step_title": self.setup_redirects.__doc__,
|
||||
"status": "Pending",
|
||||
"method_name": self.setup_redirects.__name__,
|
||||
}
|
||||
@ -405,7 +405,7 @@ class SiteMigration(Document):
|
||||
self.append(
|
||||
"steps",
|
||||
{
|
||||
"step_title": self.archive_site_on_destination_server.__pg__,
|
||||
"step_title": self.archive_site_on_destination_server.__doc__,
|
||||
"method_name": self.archive_site_on_destination_server.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
@ -500,47 +500,47 @@ class SiteMigration(Document):
|
||||
def add_steps_for_cluster_migration(self):
|
||||
steps = [
|
||||
{
|
||||
"step_title": self.deactivate_site_on_source_server.__pg__,
|
||||
"step_title": self.deactivate_site_on_source_server.__doc__,
|
||||
"method_name": self.deactivate_site_on_source_server.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.backup_source_site.__pg__,
|
||||
"step_title": self.backup_source_site.__doc__,
|
||||
"method_name": self.backup_source_site.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.restore_site_on_destination_server.__pg__,
|
||||
"step_title": self.restore_site_on_destination_server.__doc__,
|
||||
"method_name": self.restore_site_on_destination_server.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.restore_site_on_destination_proxy.__pg__,
|
||||
"step_title": self.restore_site_on_destination_proxy.__doc__,
|
||||
"method_name": self.restore_site_on_destination_proxy.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.remove_site_from_source_proxy.__pg__,
|
||||
"step_title": self.remove_site_from_source_proxy.__doc__,
|
||||
"method_name": self.remove_site_from_source_proxy.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.archive_site_on_source.__pg__,
|
||||
"step_title": self.archive_site_on_source.__doc__,
|
||||
"method_name": self.archive_site_on_source.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.update_site_record_fields.__pg__,
|
||||
"step_title": self.update_site_record_fields.__doc__,
|
||||
"method_name": self.update_site_record_fields.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.reset_site_status_on_destination.__pg__,
|
||||
"step_title": self.reset_site_status_on_destination.__doc__,
|
||||
"method_name": self.reset_site_status_on_destination.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.adjust_plan_if_required.__pg__,
|
||||
"step_title": self.adjust_plan_if_required.__doc__,
|
||||
"method_name": self.adjust_plan_if_required.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
@ -551,47 +551,47 @@ class SiteMigration(Document):
|
||||
def add_steps_for_server_migration(self):
|
||||
steps = [
|
||||
{
|
||||
"step_title": self.deactivate_site_on_source_server.__pg__,
|
||||
"step_title": self.deactivate_site_on_source_server.__doc__,
|
||||
"method_name": self.deactivate_site_on_source_server.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.backup_source_site.__pg__,
|
||||
"step_title": self.backup_source_site.__doc__,
|
||||
"method_name": self.backup_source_site.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.restore_site_on_destination_server.__pg__,
|
||||
"step_title": self.restore_site_on_destination_server.__doc__,
|
||||
"method_name": self.restore_site_on_destination_server.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.archive_site_on_source.__pg__,
|
||||
"step_title": self.archive_site_on_source.__doc__,
|
||||
"method_name": self.archive_site_on_source.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.remove_site_from_source_proxy.__pg__,
|
||||
"step_title": self.remove_site_from_source_proxy.__doc__,
|
||||
"method_name": self.remove_site_from_source_proxy.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.restore_site_on_destination_proxy.__pg__,
|
||||
"step_title": self.restore_site_on_destination_proxy.__doc__,
|
||||
"method_name": self.restore_site_on_destination_proxy.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.update_site_record_fields.__pg__,
|
||||
"step_title": self.update_site_record_fields.__doc__,
|
||||
"method_name": self.update_site_record_fields.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.reset_site_status_on_destination.__pg__,
|
||||
"step_title": self.reset_site_status_on_destination.__doc__,
|
||||
"method_name": self.reset_site_status_on_destination.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"step_title": self.adjust_plan_if_required.__pg__,
|
||||
"step_title": self.adjust_plan_if_required.__doc__,
|
||||
"method_name": self.adjust_plan_if_required.__name__,
|
||||
"status": "Pending",
|
||||
},
|
||||
|
||||
@ -332,7 +332,7 @@ def create_usage_records_of_date(
|
||||
def paid_plans():
|
||||
paid_plans = []
|
||||
|
||||
doctypes = [
|
||||
pagetypes = [
|
||||
"Site Plan",
|
||||
"Marketplace App Plan",
|
||||
"Server Plan",
|
||||
@ -340,7 +340,7 @@ def paid_plans():
|
||||
"Cluster Plan",
|
||||
]
|
||||
|
||||
for name in doctypes:
|
||||
for name in pagetypes:
|
||||
pagetype = jingrow.qb.PageType(name)
|
||||
if name in ("Server Plan", "Site Plan"):
|
||||
paid_plans += (
|
||||
|
||||
@ -180,7 +180,7 @@ class TLSCertificate(Document):
|
||||
|
||||
@jingrow.whitelist()
|
||||
def trigger_server_tls_setup_callback(self):
|
||||
server_doctypes = [
|
||||
server_pagetypes = [
|
||||
"Proxy Server",
|
||||
"Server",
|
||||
"Database Server",
|
||||
@ -191,7 +191,7 @@ class TLSCertificate(Document):
|
||||
"Trace Server",
|
||||
]
|
||||
|
||||
for server_pagetype in server_doctypes:
|
||||
for server_pagetype in server_pagetypes:
|
||||
servers = jingrow.get_all(
|
||||
server_pagetype,
|
||||
filters={
|
||||
@ -420,7 +420,7 @@ def update_server_tls_certifcate(server, certificate):
|
||||
|
||||
|
||||
def retrigger_failed_wildcard_tls_callbacks():
|
||||
server_doctypes = [
|
||||
server_pagetypes = [
|
||||
"Proxy Server",
|
||||
"Server",
|
||||
"Database Server",
|
||||
@ -430,7 +430,7 @@ def retrigger_failed_wildcard_tls_callbacks():
|
||||
"Analytics Server",
|
||||
"Trace Server",
|
||||
]
|
||||
for server_pagetype in server_doctypes:
|
||||
for server_pagetype in server_pagetypes:
|
||||
servers = jingrow.get_all(
|
||||
server_pagetype, filters={"status": "Active"}, fields=["name", "tls_certificate_renewal_failed"]
|
||||
)
|
||||
|
||||
@ -56,7 +56,7 @@ if typing.TYPE_CHECKING:
|
||||
from jcloude.jcloude.pagetype.virtual_disk_snapshot.virtual_disk_snapshot import VirtualDiskSnapshot
|
||||
|
||||
|
||||
server_doctypes = [
|
||||
server_pagetypes = [
|
||||
"Server",
|
||||
"Database Server",
|
||||
"Proxy Server",
|
||||
@ -666,7 +666,7 @@ class VirtualMachine(Document):
|
||||
return jingrow.render_template(cloud_init_template, context, is_path=True)
|
||||
|
||||
def get_server(self):
|
||||
for pagetype in server_doctypes:
|
||||
for pagetype in server_pagetypes:
|
||||
server = jingrow.db.get_value(pagetype, {"virtual_machine": self.name}, "name")
|
||||
if server:
|
||||
return jingrow.get_pg(pagetype, server)
|
||||
@ -1088,7 +1088,7 @@ class VirtualMachine(Document):
|
||||
"Terminated": "Archived",
|
||||
"Stopped": "Pending",
|
||||
}
|
||||
for pagetype in server_doctypes:
|
||||
for pagetype in server_pagetypes:
|
||||
server = jingrow.get_all(pagetype, {"virtual_machine": self.name}, pluck="name")
|
||||
if server:
|
||||
server = server[0]
|
||||
|
||||
@ -38,8 +38,8 @@ COLUMNS = [
|
||||
"fieldtype": "Check",
|
||||
},
|
||||
{
|
||||
"fieldname": "protected_doctypes",
|
||||
"label": "Protected Doctypes",
|
||||
"fieldname": "protected_pagetypes",
|
||||
"label": "Protected Pagetypes",
|
||||
"fieldtype": "Data",
|
||||
},
|
||||
{
|
||||
@ -61,7 +61,7 @@ class FunctionAnalysis:
|
||||
function_name: str
|
||||
line_number: int
|
||||
is_protected: bool = False
|
||||
protected_doctypes: list[str] = field(default_factory=list)
|
||||
protected_pagetypes: list[str] = field(default_factory=list)
|
||||
has_get_pg_with_input: bool = False
|
||||
parameters: list[str] = field(default_factory=list)
|
||||
allow_guest: bool = False
|
||||
@ -72,7 +72,7 @@ class FunctionAnalysis:
|
||||
"function_name": self.function_name,
|
||||
"line_number": self.line_number,
|
||||
"is_protected": 1 if self.is_protected else 0,
|
||||
"protected_doctypes": ", ".join(self.protected_doctypes),
|
||||
"protected_pagetypes": ", ".join(self.protected_pagetypes),
|
||||
"is_get_pg_with_input": 1 if self.has_get_pg_with_input else 0,
|
||||
"parameters": ", ".join(self.parameters),
|
||||
"allow_guest": 1 if self.allow_guest else 0,
|
||||
@ -111,7 +111,7 @@ class ASTAnalyzer:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def get_protected_doctypes(node: ast.FunctionDef) -> list[str] | None:
|
||||
def get_protected_pagetypes(node: ast.FunctionDef) -> list[str] | None:
|
||||
for decorator in node.decorator_list:
|
||||
if isinstance(decorator, ast.Call):
|
||||
func = decorator.func
|
||||
@ -178,7 +178,7 @@ class EndpointAuditor:
|
||||
return None
|
||||
|
||||
parameters = self.analyzer.get_function_parameters(node)
|
||||
protected_doctypes = self.analyzer.get_protected_doctypes(node)
|
||||
protected_pagetypes = self.analyzer.get_protected_pagetypes(node)
|
||||
allow_guest = self.analyzer.get_allow_guest(node)
|
||||
|
||||
has_get_pg_with_input = any(
|
||||
@ -191,8 +191,8 @@ class EndpointAuditor:
|
||||
file_path=relative_path,
|
||||
function_name=node.name,
|
||||
line_number=node.lineno,
|
||||
is_protected=protected_doctypes is not None,
|
||||
protected_doctypes=protected_doctypes or [],
|
||||
is_protected=protected_pagetypes is not None,
|
||||
protected_pagetypes=protected_pagetypes or [],
|
||||
has_get_pg_with_input=has_get_pg_with_input,
|
||||
parameters=parameters,
|
||||
allow_guest=allow_guest,
|
||||
|
||||
@ -399,7 +399,7 @@ class StepHandler:
|
||||
"""Generate a list of steps to be executed for NFS volume attachment."""
|
||||
return [
|
||||
{
|
||||
"step_name": method.__pg__,
|
||||
"step_name": method.__doc__,
|
||||
"method_name": method.__name__,
|
||||
"status": "Pending",
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
### New SaaS Flow (Product Trial)
|
||||
|
||||
It has 2 doctypes.
|
||||
It has 2 pagetypes.
|
||||
|
||||
1. **Product Trial** - Hold the configuration for a specific product.
|
||||
2. **Product Trial Request** - This holds the records of request for a specific product from a user.
|
||||
|
||||
@ -7,11 +7,11 @@ from jingrow.model.utils.rename_field import rename_field
|
||||
|
||||
|
||||
def execute():
|
||||
rename_doctypes()
|
||||
rename_pagetypes()
|
||||
rename_fields()
|
||||
|
||||
|
||||
def rename_doctypes():
|
||||
def rename_pagetypes():
|
||||
renames = {
|
||||
"SaaS Product": "Product Trial",
|
||||
"SaaS Product App": "Product Trial App",
|
||||
|
||||
@ -595,12 +595,12 @@ class ttl_cache:
|
||||
return wrapper_func
|
||||
|
||||
|
||||
def poly_get_pagetype(doctypes, name):
|
||||
"""Get the pagetype value from the given name of a pg from a list of doctypes"""
|
||||
for pagetype in doctypes:
|
||||
def poly_get_pagetype(pagetypes, name):
|
||||
"""Get the pagetype value from the given name of a pg from a list of pagetypes"""
|
||||
for pagetype in pagetypes:
|
||||
if jingrow.db.exists(pagetype, name):
|
||||
return pagetype
|
||||
return doctypes[-1]
|
||||
return pagetypes[-1]
|
||||
|
||||
|
||||
def reconnect_on_failure():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user