@@ -0,0 +1,83 @@ | |||
name: Patch | |||
on: [pull_request, workflow_dispatch] | |||
jobs: | |||
test: | |||
runs-on: ubuntu-18.04 | |||
name: Patch Test | |||
services: | |||
mysql: | |||
image: mariadb:10.3 | |||
env: | |||
MYSQL_ALLOW_EMPTY_PASSWORD: YES | |||
ports: | |||
- 3306:3306 | |||
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 | |||
steps: | |||
- name: Clone | |||
uses: actions/checkout@v2 | |||
- name: Setup Python | |||
uses: actions/setup-python@v2 | |||
with: | |||
python-version: 3.7 | |||
- name: Add to Hosts | |||
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | |||
- name: Cache pip | |||
uses: actions/cache@v2 | |||
with: | |||
path: ~/.cache/pip | |||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} | |||
restore-keys: | | |||
${{ runner.os }}-pip- | |||
${{ runner.os }}- | |||
- name: Cache node modules | |||
uses: actions/cache@v2 | |||
env: | |||
cache-name: cache-node-modules | |||
with: | |||
path: ~/.npm | |||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} | |||
restore-keys: | | |||
${{ runner.os }}-build-${{ env.cache-name }}- | |||
${{ runner.os }}-build- | |||
${{ runner.os }}- | |||
- name: Get yarn cache directory path | |||
id: yarn-cache-dir-path | |||
run: echo "::set-output name=dir::$(yarn cache dir)" | |||
- uses: actions/cache@v2 | |||
id: yarn-cache | |||
with: | |||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | |||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} | |||
restore-keys: | | |||
${{ runner.os }}-yarn- | |||
- name: Install Dependencies | |||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | |||
env: | |||
BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | |||
AFTER: ${{ env.GITHUB_EVENT_PATH.after }} | |||
TYPE: server | |||
- name: Install | |||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | |||
env: | |||
DB: mariadb | |||
TYPE: server | |||
- name: Run Patch Tests | |||
run: | | |||
cd ~/frappe-bench/ | |||
wget https://frappeframework.com/files/v10-frappe.sql.gz | |||
bench --site test_site --force restore ~/frappe-bench/v10-frappe.sql.gz | |||
bench --site test_site migrate |
@@ -91,7 +91,6 @@ jobs: | |||
DB: mariadb | |||
TYPE: server | |||
- name: Run Tests | |||
run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --use-orchestrator --with-coverage | |||
env: | |||
@@ -1110,9 +1110,7 @@ def setup_module_map(): | |||
if not (local.app_modules and local.module_app): | |||
local.module_app, local.app_modules = {}, {} | |||
for app in get_all_apps(True): | |||
if app == "webnotes": | |||
app = "frappe" | |||
for app in get_all_apps(with_internal_apps=True): | |||
local.app_modules.setdefault(app, []) | |||
for module in get_module_list(app): | |||
module = scrub(module) | |||
@@ -572,22 +572,30 @@ def run_tests(context, app=None, module=None, doctype=None, test=(), profile=Fal | |||
# Generate coverage report only for app that is being tested | |||
source_path = os.path.join(get_bench_path(), 'apps', app or 'frappe') | |||
omit=[ | |||
'*.html', | |||
incl = [ | |||
'*.py', | |||
] | |||
omit = [ | |||
'*.js', | |||
'*.xml', | |||
'*.pyc', | |||
'*.css', | |||
'*.less', | |||
'*.scss', | |||
'*.vue', | |||
'*.pyc', | |||
'*.html', | |||
'*/test_*', | |||
'*/node_modules/*', | |||
'*/doctype/*/*_dashboard.py', | |||
'*/patches/*' | |||
'*/patches/*', | |||
] | |||
if not app or app == 'frappe': | |||
omit.append('*/tests/*') | |||
omit.append('*/commands/*') | |||
cov = Coverage(source=[source_path], omit=omit) | |||
cov = Coverage(source=[source_path], omit=omit, include=incl) | |||
cov.start() | |||
ret = frappe.test_runner.main(app, module, doctype, context.verbose, tests=tests, | |||
@@ -114,13 +114,30 @@ class ParallelTestRunner(): | |||
# Generate coverage report only for app that is being tested | |||
source_path = os.path.join(get_bench_path(), 'apps', self.app) | |||
omit=['*.html', '*.js', '*.xml', '*.css', '*.less', '*.scss', | |||
'*.vue', '*/doctype/*/*_dashboard.py', '*/patches/*'] | |||
incl = [ | |||
'*.py', | |||
] | |||
omit = [ | |||
'*.js', | |||
'*.xml', | |||
'*.pyc', | |||
'*.css', | |||
'*.less', | |||
'*.scss', | |||
'*.vue', | |||
'*.pyc', | |||
'*.html', | |||
'*/test_*', | |||
'*/node_modules/*', | |||
'*/doctype/*/*_dashboard.py', | |||
'*/patches/*', | |||
] | |||
if self.app == 'frappe': | |||
omit.append('*/tests/*') | |||
omit.append('*/commands/*') | |||
self.coverage = Coverage(source=[source_path], omit=omit) | |||
self.coverage = Coverage(source=[source_path], omit=omit, include=incl) | |||
self.coverage.start() | |||
def save_coverage(self): | |||
@@ -1,11 +1,5 @@ | |||
frappe.patches.v12_0.remove_deprecated_fields_from_doctype #3 | |||
execute:frappe.db.sql("""update `tabPatch Log` set patch=replace(patch, '.4_0.', '.v4_0.')""") #2014-05-12 | |||
frappe.patches.v5_0.convert_to_barracuda_and_utf8mb4 | |||
execute:frappe.utils.global_search.setup_global_search_table() | |||
frappe.patches.v8_0.update_global_search_table | |||
frappe.patches.v7_0.update_auth | |||
frappe.patches.v8_0.drop_in_dialog #2017-09-22 | |||
frappe.patches.v7_2.remove_in_filter | |||
execute:frappe.reload_doc('core', 'doctype', 'doctype_action', force=True) #2019-09-23 | |||
execute:frappe.reload_doc('core', 'doctype', 'doctype_link', force=True) #2020-10-17 | |||
execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2017-09-22 | |||
@@ -14,7 +8,6 @@ frappe.patches.v11_0.drop_column_apply_user_permissions | |||
execute:frappe.reload_doc('core', 'doctype', 'custom_docperm') | |||
execute:frappe.reload_doc('core', 'doctype', 'docperm') #2018-05-29 | |||
execute:frappe.reload_doc('core', 'doctype', 'comment') | |||
frappe.patches.v8_0.drop_is_custom_from_docperm | |||
execute:frappe.reload_doc('core', 'doctype', 'document_naming_rule', force=True) | |||
execute:frappe.reload_doc('core', 'doctype', 'module_def') #2020-08-28 | |||
execute:frappe.reload_doc('core', 'doctype', 'version') #2017-04-01 | |||
@@ -25,190 +18,40 @@ execute:frappe.reload_doc('core', 'doctype', 'communication') #2019-10-02 | |||
execute:frappe.reload_doc('core', 'doctype', 'server_script') | |||
frappe.patches.v11_0.replicate_old_user_permissions | |||
frappe.patches.v11_0.reload_and_rename_view_log #2019-01-03 | |||
frappe.patches.v7_1.rename_scheduler_log_to_error_log | |||
frappe.patches.v6_1.rename_file_data | |||
frappe.patches.v7_0.re_route #2016-06-27 | |||
frappe.patches.v8_0.update_records_in_global_search #11-05-2017 | |||
frappe.patches.v8_0.update_published_in_global_search | |||
frappe.patches.v11_0.copy_fetch_data_from_options | |||
frappe.patches.v11_0.change_email_signature_fieldtype | |||
execute:frappe.reload_doc('core', 'doctype', 'activity_log') | |||
execute:frappe.reload_doc('core', 'doctype', 'deleted_document') | |||
execute:frappe.reload_doc('core', 'doctype', 'domain_settings') | |||
frappe.patches.v13_0.rename_custom_client_script | |||
frappe.patches.v8_0.rename_page_role_to_has_role #2017-03-16 | |||
frappe.patches.v7_2.setup_custom_perms #2017-01-19 | |||
frappe.patches.v8_0.set_user_permission_for_page_and_report #2017-03-20 | |||
execute:frappe.reload_doc('core', 'doctype', 'role') #2017-05-23 | |||
execute:frappe.reload_doc('core', 'doctype', 'user') #2017-10-27 | |||
execute:frappe.reload_doc('custom', 'doctype', 'custom_field') #2015-10-19 | |||
execute:frappe.reload_doc('core', 'doctype', 'page') #2013-13-26 | |||
execute:frappe.reload_doc('core', 'doctype', 'report_column') | |||
execute:frappe.reload_doc('core', 'doctype', 'report_filter') | |||
execute:frappe.reload_doc('core', 'doctype', 'report') #2020-08-25 | |||
execute:frappe.reload_doc('core', 'doctype', 'translation') #2016-03-03 | |||
execute:frappe.reload_doc('email', 'doctype', 'email_alert') #2014-07-15 | |||
execute:frappe.reload_doc('desk', 'doctype', 'todo') #2014-12-31-1 | |||
execute:frappe.reload_doc('custom', 'doctype', 'property_setter') #2014-12-31-1 | |||
execute:frappe.reload_doc('core', 'doctype', 'patch_log') #2016-10-31 | |||
execute:frappe.reload_doctype("File") # 2015-10-19 | |||
execute:frappe.reload_doc('core', 'doctype', 'error_snapshot') | |||
execute:frappe.clear_cache() | |||
frappe.patches.v7_1.rename_scheduler_log_to_error_log | |||
frappe.patches.v7_1.sync_language_doctype | |||
frappe.patches.v7_0.rename_bulk_email_to_email_queue | |||
frappe.patches.v7_1.rename_chinese_language_codes | |||
execute:frappe.db.sql("alter table `tabSessions` modify `user` varchar(255), engine=InnoDB") | |||
execute:frappe.db.sql("delete from `tabDocField` where parent='0'") | |||
frappe.patches.v4_0.change_varchar_length | |||
frappe.patches.v6_4.reduce_varchar_length | |||
frappe.patches.v5_2.change_checks_to_not_null | |||
frappe.patches.v6_9.int_float_not_null #2015-11-25 | |||
frappe.patches.v5_0.v4_to_v5 | |||
frappe.patches.v5_0.remove_shopping_cart_app | |||
frappe.patches.v4_0.webnotes_to_frappe | |||
execute:frappe.permissions.reset_perms("Module Def") | |||
execute:import frappe.installer;frappe.installer.make_site_dirs() #2014-02-19 | |||
frappe.patches.v4_0.rename_profile_to_user | |||
frappe.patches.v4_0.deprecate_control_panel | |||
frappe.patches.v4_0.remove_old_parent | |||
frappe.patches.v4_0.rename_sitemap_to_route | |||
frappe.patches.v4_0.website_sitemap_hierarchy | |||
frappe.patches.v4_0.remove_index_sitemap | |||
frappe.patches.v4_0.set_website_route_idx | |||
frappe.patches.v4_0.add_delete_permission | |||
frappe.patches.v4_0.set_todo_checked_as_closed | |||
frappe.patches.v4_0.private_backups | |||
frappe.patches.v4_0.set_module_in_report | |||
frappe.patches.v4_0.update_datetime | |||
frappe.patches.v4_0.file_manager_hooks | |||
execute:frappe.get_doc("User", "Guest").save() | |||
frappe.patches.v4_0.update_custom_field_insert_after | |||
frappe.patches.v4_0.deprecate_link_selects | |||
frappe.patches.v4_0.set_user_gravatar | |||
frappe.patches.v4_0.set_user_permissions | |||
frappe.patches.v4_0.create_custom_field_for_owner_match | |||
frappe.patches.v4_0.enable_scheduler_in_system_settings | |||
execute:frappe.db.sql("update tabReport set apply_user_permissions=1") #2014-06-03 | |||
frappe.patches.v4_0.replace_deprecated_timezones | |||
execute:import frappe.website.render; frappe.website.render.clear_cache("login"); #2014-06-10 | |||
frappe.patches.v4_0.fix_attach_field_file_url | |||
execute:frappe.permissions.reset_perms("User") #2015-03-24 | |||
execute:frappe.db.sql("""delete from `tabUserRole` where ifnull(parentfield, '')='' or ifnull(`role`, '')=''""") #2014-08-18 | |||
frappe.patches.v4_0.remove_user_owner_custom_field | |||
execute:frappe.delete_doc("DocType", "Website Template") | |||
execute:frappe.db.sql("""update `tabProperty Setter` set property_type='Text' where property in ('options', 'default')""") #2014-06-20 | |||
frappe.patches.v4_1.enable_outgoing_email_settings | |||
execute:frappe.db.sql("""update `tabSingles` set `value`=`doctype` where `field`='name'""") #2014-07-04 | |||
frappe.patches.v4_1.enable_print_as_pdf #2014-06-17 | |||
execute:frappe.db.sql("""update `tabDocPerm` set email=1 where parent='User' and permlevel=0 and `role`='All' and `read`=1 and apply_user_permissions=1""") #2014-07-15 | |||
execute:frappe.db.sql("""update `tabPrint Format` set print_format_type='Client' where ifnull(print_format_type, '')=''""") #2014-07-28 | |||
frappe.patches.v4_1.file_manager_fix | |||
frappe.patches.v4_2.print_with_letterhead | |||
execute:frappe.delete_doc("DocType", "Control Panel", force=1) | |||
execute:frappe.reload_doc('website', 'doctype', 'web_form') #2014-09-04 | |||
execute:frappe.reload_doc('website', 'doctype', 'web_form_field') #2014-09-04 | |||
frappe.patches.v4_2.refactor_website_routing | |||
frappe.patches.v4_2.set_assign_in_doc | |||
frappe.patches.v4_3.remove_allow_on_submit_customization | |||
frappe.patches.v5_0.rename_table_fieldnames | |||
frappe.patches.v5_0.communication_parent | |||
frappe.patches.v5_0.clear_website_group_and_notifications | |||
frappe.patches.v5_0.update_shared | |||
execute:frappe.reload_doc("core", "doctype", "docshare") #2015-07-21 | |||
frappe.patches.v6_19.comment_feed_communication | |||
frappe.patches.v6_16.star_to_like | |||
frappe.patches.v5_0.bookmarks_to_stars | |||
frappe.patches.v5_0.style_settings_to_website_theme | |||
frappe.patches.v5_0.rename_ref_type_fieldnames | |||
frappe.patches.v5_0.fix_email_alert | |||
frappe.patches.v5_0.fix_null_date_datetime | |||
frappe.patches.v5_0.force_sync_website | |||
execute:frappe.delete_doc("DocType", "Tag") | |||
execute:frappe.db.sql("delete from `tabProperty Setter` where `property` in ('idx', '_idx')") | |||
frappe.patches.v5_0.move_scheduler_last_event_to_system_settings | |||
execute:frappe.db.sql("update tabUser set new_password='' where ifnull(new_password, '')!=''") | |||
frappe.patches.v5_0.fix_text_editor_file_urls | |||
frappe.patches.v5_0.modify_session | |||
frappe.patches.v5_0.expire_old_scheduler_logs | |||
execute:frappe.permissions.reset_perms("DocType") | |||
execute:frappe.db.sql("delete from `tabProperty Setter` where `property` = 'idx'") | |||
frappe.patches.v6_0.communication_status_and_permission | |||
frappe.patches.v6_0.make_task_log_folder | |||
frappe.patches.v6_0.document_type_rename | |||
frappe.patches.v6_0.fix_ghana_currency | |||
frappe.patches.v6_2.ignore_user_permissions_if_missing | |||
execute:frappe.db.sql("delete from tabSessions where user is null") | |||
frappe.patches.v6_2.rename_backup_manager | |||
execute:frappe.delete_doc("DocType", "Backup Manager") | |||
execute:frappe.db.sql("""update `tabCommunication` set parenttype=null, parent=null, parentfield=null""") #2015-10-22 | |||
execute:frappe.permissions.reset_perms("Web Page") | |||
frappe.patches.v6_6.user_last_active | |||
frappe.patches.v6_6.fix_file_url | |||
frappe.patches.v6_11.rename_field_in_email_account | |||
frappe.patches.v7_0.create_private_file_folder | |||
frappe.patches.v6_15.remove_property_setter_for_previous_field #2015-12-29 | |||
frappe.patches.v6_15.set_username | |||
execute:frappe.permissions.reset_perms("Error Snapshot") | |||
frappe.patches.v6_16.feed_doc_owner | |||
frappe.patches.v6_21.print_settings_repeat_header_footer | |||
frappe.patches.v6_24.set_language_as_code | |||
frappe.patches.v6_20x.update_insert_after | |||
frappe.patches.v6_20x.set_allow_draft_for_print | |||
frappe.patches.v6_20x.remove_roles_from_website_user | |||
frappe.patches.v7_0.set_user_fullname | |||
frappe.patches.v7_0.add_communication_in_doc | |||
frappe.patches.v7_0.update_send_after_in_bulk_email | |||
execute:frappe.db.sql('''delete from `tabSingles` where doctype="Email Settings"''') # 2016-06-13 | |||
execute:frappe.db.sql("delete from `tabWeb Page` where ifnull(template_path, '')!=''") | |||
frappe.patches.v7_0.rename_newsletter_list_to_email_group | |||
frappe.patches.v7_0.set_email_group | |||
frappe.patches.v7_1.setup_integration_services #2016-10-27 | |||
frappe.patches.v7_1.rename_chinese_language_codes | |||
execute:frappe.core.doctype.language.language.update_language_names() # 2017-04-12 | |||
execute:frappe.db.set_value("Print Settings", "Print Settings", "add_draft_heading", 1) | |||
frappe.patches.v7_0.cleanup_list_settings | |||
execute:frappe.db.set_default('language', '') | |||
frappe.patches.v7_1.refactor_integration_broker | |||
frappe.patches.v7_1.set_backup_limit | |||
frappe.patches.v7_2.set_doctype_engine | |||
frappe.patches.v7_2.merge_knowledge_base | |||
frappe.patches.v7_0.update_report_builder_json | |||
frappe.patches.v7_2.set_in_standard_filter_property #1 | |||
frappe.patches.v8_0.drop_unwanted_indexes | |||
execute:frappe.db.sql("update tabCommunication set communication_date = creation where time(communication_date) = 0") | |||
frappe.patches.v7_2.fix_email_queue_recipient | |||
frappe.patches.v7_2.update_feedback_request # 2017-02-27 | |||
execute:frappe.rename_doc('Country', 'Macedonia, Republic of', 'Macedonia', ignore_if_exists=True) | |||
execute:frappe.rename_doc('Country', 'Iran, Islamic Republic of', 'Iran', ignore_if_exists=True) | |||
execute:frappe.rename_doc('Country', 'Tanzania, United Republic of', 'Tanzania', ignore_if_exists=True) | |||
execute:frappe.rename_doc('Country', 'Syrian Arab Republic', 'Syria', ignore_if_exists=True) | |||
frappe.patches.v8_0.rename_listsettings_to_usersettings | |||
frappe.patches.v7_2.update_communications | |||
frappe.patches.v8_0.deprecate_integration_broker | |||
frappe.patches.v8_0.update_gender_and_salutation | |||
frappe.patches.v8_0.setup_email_inbox #2017-03-29 | |||
frappe.patches.v8_0.newsletter_childtable_migrate | |||
frappe.patches.v8_0.set_doctype_values_in_custom_role | |||
frappe.patches.v8_0.install_new_build_system_requirements | |||
frappe.patches.v8_0.set_currency_field_precision # 2017-05-09 | |||
execute:frappe.reload_doc('desk', 'doctype', 'notification_log') | |||
frappe.patches.v8_0.rename_print_to_printing | |||
frappe.patches.v7_1.disabled_print_settings_for_custom_print_format | |||
execute:frappe.db.sql('update tabReport set module="Desk" where name="ToDo"') | |||
frappe.patches.v8_1.enable_allow_error_traceback_in_system_settings | |||
frappe.patches.v8_1.update_format_options_in_auto_email_report | |||
frappe.patches.v8_1.delete_custom_docperm_if_doctype_not_exists | |||
frappe.patches.v8_5.delete_email_group_member_with_invalid_emails | |||
frappe.patches.v8_x.update_user_permission | |||
frappe.patches.v8_5.patch_event_colors | |||
frappe.patches.v8_10.delete_static_web_page_from_global_search | |||
frappe.patches.v9_1.add_sms_sender_name_as_parameters | |||
frappe.patches.v9_1.resave_domain_settings | |||
frappe.patches.v9_1.revert_domain_settings | |||
frappe.patches.v9_1.move_feed_to_activity_log | |||
execute:frappe.delete_doc('Page', 'data-import-tool', ignore_missing=True) | |||
frappe.patches.v10_0.reload_countries_and_currencies # 2021-02-03 | |||
frappe.patches.v10_0.refactor_social_login_keys | |||
@@ -8,7 +8,6 @@ def execute(): | |||
frappe.reload_doc('integrations', 'doctype', 'google_contacts') | |||
frappe.reload_doc('contacts', 'doctype', 'contact') | |||
frappe.reload_doc('core', 'doctype', 'dynamic_link') | |||
frappe.reload_doc('communication', 'doctype', 'call_log') | |||
contact_meta = frappe.get_meta("Contact") | |||
if contact_meta.has_field("phone_nos") and contact_meta.has_field("email_ids"): | |||
@@ -5,4 +5,3 @@ from frappe.model.rename_doc import rename_doc | |||
def execute(): | |||
if frappe.db.exists("DocType","Google Maps") and not frappe.db.exists("DocType","Google Maps Settings"): | |||
rename_doc('DocType', 'Google Maps', 'Google Maps Settings') | |||
frappe.reload_doc('integrations', 'doctype', 'google_maps_settings') |
@@ -1,13 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "docperm") | |||
# delete same as cancel (map old permissions) | |||
frappe.db.sql("""update tabDocPerm set `delete`=ifnull(`cancel`,0)""") | |||
# can't cancel if can't submit | |||
frappe.db.sql("""update tabDocPerm set `cancel`=0 where ifnull(`submit`,0)=0""") | |||
frappe.clear_cache() |
@@ -1,25 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
frappe.db.sql('update tabDocField set search_index=0 where fieldtype="Small Text"') | |||
frappe.db.sql('update tabDocField set in_list_view=0 where fieldtype="Image"') | |||
for dt in frappe.db.sql_list("""select name from `tabDocType` where issingle=0"""): | |||
desc = dict((d["Field"], d) for d in frappe.db.sql("desc `tab{}`".format(dt), as_dict=True)) | |||
alter_table = [] | |||
if desc["name"]["Type"] != "varchar(255)": | |||
alter_table.append("change `name` `name` varchar(255) not null") | |||
for fieldname in ("modified_by", "owner", "parent", "parentfield", "parenttype"): | |||
if desc[fieldname]["Type"] != "varchar(255)": | |||
alter_table.append("change `{fieldname}` `{fieldname}` varchar(255)".format(fieldname=fieldname)) | |||
if alter_table: | |||
alter_table_query = "alter table `tab{doctype}` {alter_table}".format(doctype=dt, alter_table=",\n".join(alter_table)) | |||
# print alter_table_query | |||
frappe.db.sql_ddl(alter_table_query) | |||
@@ -1,39 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field | |||
def execute(): | |||
if "match" in frappe.db.get_table_columns("DocPerm"): | |||
create_custom_field_for_owner_match() | |||
def create_custom_field_for_owner_match(): | |||
docperm_meta = frappe.get_meta('DocPerm') | |||
if docperm_meta.get_field('apply_user_permissions'): | |||
frappe.db.sql("""update `tabDocPerm` set apply_user_permissions=1 where `match`='owner'""") | |||
for dt in frappe.db.sql_list("""select distinct parent from `tabDocPerm` | |||
where `match`='owner' and permlevel=0 and parent != 'User'"""): | |||
# a link field pointing to User already exists | |||
if (frappe.db.get_value("DocField", {"parent": dt, "fieldtype": "Link", "options": "User", "default": "__user"}) | |||
or frappe.db.get_value("Custom Field", {"dt": dt, "fieldtype": "Link", "options": "User", "default": "__user"})): | |||
print("User link field already exists for", dt) | |||
continue | |||
fieldname = "{}_owner".format(frappe.scrub(dt)) | |||
create_custom_field(dt, frappe._dict({ | |||
"permlevel": 0, | |||
"label": "{} Owner".format(dt), | |||
"fieldname": fieldname, | |||
"fieldtype": "Link", | |||
"options": "User", | |||
"default": "__user" | |||
})) | |||
frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=owner""".format(doctype=dt, | |||
fieldname=fieldname)) | |||
# commit is required so that we don't lose these changes because of an error in next loop's ddl | |||
frappe.db.commit() |
@@ -1,9 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
frappe.db.sql("update `tabDefaultValue` set parenttype='__default' where parenttype='Control Panel'") | |||
frappe.db.sql("update `tabDefaultValue` set parent='__default' where parent='Control Panel'") | |||
frappe.clear_cache() |
@@ -1,12 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
for name in frappe.db.sql_list("""select name from `tabCustom Field` | |||
where fieldtype="Select" and options like "link:%" """): | |||
custom_field = frappe.get_doc("Custom Field", name) | |||
custom_field.fieldtype = "Link" | |||
custom_field.options = custom_field.options[5:] | |||
custom_field.save() |
@@ -1,13 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
from frappe.utils.scheduler import disable_scheduler, enable_scheduler | |||
from frappe.utils import cint | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "system_settings") | |||
if cint(frappe.db.get_global("disable_scheduler")): | |||
disable_scheduler() | |||
else: | |||
enable_scheduler() |
@@ -1,33 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
import os | |||
from frappe.core.doctype.file.file import get_content_hash | |||
def execute(): | |||
frappe.reload_doc('core', 'doctype', 'file_data') | |||
for name, file_name, file_url in frappe.db.sql( | |||
"""select name, file_name, file_url from `tabFile` | |||
where file_name is not null"""): | |||
b = frappe.get_doc('File', name) | |||
old_file_name = b.file_name | |||
b.file_name = os.path.basename(old_file_name) | |||
if old_file_name.startswith('files/') or old_file_name.startswith('/files/'): | |||
b.file_url = os.path.normpath('/' + old_file_name) | |||
else: | |||
b.file_url = os.path.normpath('/files/' + old_file_name) | |||
try: | |||
_file = frappe.get_doc("File", {"file_name": name}) | |||
content = _file.get_content() | |||
b.content_hash = get_content_hash(content) | |||
except IOError: | |||
print('Warning: Error processing ', name) | |||
_file_name = old_file_name | |||
b.content_hash = None | |||
try: | |||
b.save() | |||
except frappe.DuplicateEntryError: | |||
frappe.delete_doc(b.doctype, b.name) | |||
@@ -1,12 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
attach_fields = (frappe.db.sql("""select parent, fieldname from `tabDocField` where fieldtype in ('Attach', 'Attach Image')""") + | |||
frappe.db.sql("""select dt, fieldname from `tabCustom Field` where fieldtype in ('Attach', 'Attach Image')""")) | |||
for doctype, fieldname in attach_fields: | |||
frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=concat("/", `{fieldname}`) | |||
where `{fieldname}` like 'files/%'""".format(doctype=doctype, fieldname=fieldname)) |
@@ -1,10 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
from frappe.installer import make_site_dirs | |||
def execute(): | |||
make_site_dirs() | |||
if frappe.local.conf.backup_path and frappe.local.conf.backup_path.startswith("public"): | |||
raise Exception("Backups path in conf set to public directory") |
@@ -1,5 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
pass |
@@ -1,9 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
for doctype in frappe.db.sql_list("""select name from `tabDocType` where istable=1"""): | |||
frappe.db.sql("""delete from `tab{0}` where parent like "old_par%:%" """.format(doctype)) | |||
frappe.db.sql("""delete from `tabDocField` where parent="0" """) |
@@ -1,9 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
user_owner = frappe.db.get_value("Custom Field", {"fieldname": "user_owner"}) | |||
if user_owner: | |||
frappe.delete_doc("Custom Field", user_owner) |
@@ -1,15 +0,0 @@ | |||
import frappe | |||
from frappe.model.utils.rename_field import rename_field | |||
from frappe.model.meta import get_table_columns | |||
def execute(): | |||
tables = frappe.db.sql_list("show tables") | |||
if "tabUser" not in tables: | |||
frappe.rename_doc("DocType", "Profile", "User", force=True) | |||
frappe.reload_doc("website", "doctype", "blogger") | |||
if "profile" in get_table_columns("Blogger"): | |||
rename_field("Blogger", "profile", "user") |
@@ -1,25 +0,0 @@ | |||
import frappe | |||
from frappe.model.utils.rename_field import rename_field | |||
def execute(): | |||
tables = frappe.db.sql_list("show tables") | |||
for doctype in ("Website Sitemap", "Website Sitemap Config"): | |||
if "tab{}".format(doctype) in tables: | |||
frappe.delete_doc("DocType", doctype, force=1) | |||
frappe.db.sql("drop table `tab{}`".format(doctype)) | |||
for d in ("Blog Category", "Blog Post", "Web Page"): | |||
frappe.reload_doc("website", "doctype", frappe.scrub(d)) | |||
rename_field_if_exists(d, "parent_website_sitemap", "parent_website_route") | |||
for d in ("blog_category", "blog_post", "web_page", "post", "user_vote"): | |||
frappe.reload_doc("website", "doctype", d) | |||
def rename_field_if_exists(doctype, old_fieldname, new_fieldname): | |||
try: | |||
rename_field(doctype, old_fieldname, new_fieldname) | |||
except frappe.db.ProgrammingError as e: | |||
if not frappe.db.is_column_missing(e): | |||
raise |
@@ -1,20 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
from frappe.utils.momentjs import data as momentjs_data | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "user") | |||
ss = frappe.get_doc("System Settings", "System Settings") | |||
if ss.time_zone in momentjs_data.get("links"): | |||
ss.time_zone = momentjs_data["links"][ss.time_zone] | |||
ss.flags.ignore_mandatory = True | |||
ss.save() | |||
for user, time_zone in frappe.db.sql("select name, time_zone from `tabUser` where ifnull(time_zone, '')!=''"): | |||
if time_zone in momentjs_data.get("links"): | |||
user = frappe.get_doc("User", user) | |||
user.time_zone = momentjs_data["links"][user.time_zone] | |||
user.save() |
@@ -1,9 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "report") | |||
frappe.db.sql("""update `tabReport` r set r.module=(select d.module from `tabDocType` d | |||
where d.name=r.ref_doctype) where ifnull(r.module, '')=''""") |
@@ -1,9 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "todo") | |||
try: | |||
frappe.db.sql("""update tabToDo set status = if(ifnull(checked,0)=0, 'Open', 'Closed')""") | |||
except: | |||
pass |
@@ -1,10 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
for name in frappe.db.sql_list("select name from `tabUser` where ifnull(user_image, '')=''"): | |||
user = frappe.get_doc("User", name) | |||
user.update_gravatar() | |||
user.db_set("user_image", user.user_image) |
@@ -1,23 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
import frappe.permissions | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "docperm") | |||
table_columns = frappe.db.get_table_columns("DocPerm") | |||
if "restricted" in table_columns: | |||
frappe.db.sql("""update `tabDocPerm` set apply_user_permissions=1 where apply_user_permissions=0 | |||
and restricted=1""") | |||
if "match" in table_columns: | |||
frappe.db.sql("""update `tabDocPerm` set apply_user_permissions=1 | |||
where apply_user_permissions=0 and ifnull(`match`, '')!=''""") | |||
# change Restriction to User Permission in tabDefaultValue | |||
frappe.db.sql("""update `tabDefaultValue` set parenttype='User Permission' where parenttype='Restriction'""") | |||
frappe.clear_cache() | |||
@@ -1,25 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
pass | |||
# from frappe.website.doctype.website_template.website_template import \ | |||
# get_pages_and_generators, get_template_controller | |||
# | |||
# frappe.reload_doc("website", "doctype", "website_template") | |||
# frappe.reload_doc("website", "doctype", "website_route") | |||
# | |||
# for app in frappe.get_installed_apps(): | |||
# pages, generators = get_pages_and_generators(app) | |||
# for g in generators: | |||
# doctype = frappe.get_attr(get_template_controller(app, g["path"], g["fname"]) + ".doctype") | |||
# module = frappe.db.get_value("DocType", doctype, "module") | |||
# frappe.reload_doc(frappe.scrub(module), "doctype", frappe.scrub(doctype)) | |||
# | |||
# frappe.db.sql("""update `tabBlog Category` set `title`=`name` where ifnull(`title`, '')=''""") | |||
# frappe.db.sql("""update `tabWebsite Route` set idx=null""") | |||
# for doctype in ["Blog Category", "Blog Post", "Web Page", "Website Group"]: | |||
# frappe.db.sql("""update `tab{}` set idx=null""".format(doctype)) | |||
# | |||
# from frappe.website.doctype.website_template.website_template import rebuild_website_template | |||
# rebuild_website_template() |
@@ -1,17 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
for d in frappe.db.sql("""select name, dt, insert_after from `tabCustom Field` | |||
where docstatus < 2""", as_dict=1): | |||
dt_meta = frappe.get_meta(d.dt) | |||
if not dt_meta.get_field(d.insert_after): | |||
cf = frappe.get_doc("Custom Field", d.name) | |||
df = dt_meta.get("fields", {"label": d.insert_after}) | |||
if df: | |||
cf.insert_after = df[0].fieldname | |||
else: | |||
cf.insert_after = None | |||
cf.save() |
@@ -1,12 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
for table in frappe.db.sql_list("show tables"): | |||
for field in frappe.db.sql("desc `%s`" % table): | |||
if field[1]=="datetime": | |||
frappe.db.sql("alter table `%s` change `%s` `%s` datetime(6)" % \ | |||
(table, field[0], field[0])) | |||
elif field[1]=="time": | |||
frappe.db.sql("alter table `%s` change `%s` `%s` time(6)" % \ | |||
(table, field[0], field[0])) |
@@ -1,12 +0,0 @@ | |||
import frappe, json | |||
def execute(): | |||
frappe.clear_cache() | |||
installed = frappe.get_installed_apps() | |||
if "webnotes" in installed: | |||
installed.remove("webnotes") | |||
if "frappe" not in installed: | |||
installed = ["frappe"] + installed | |||
frappe.db.set_global("installed_apps", json.dumps(installed)) | |||
frappe.clear_cache() |
@@ -1,19 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
# frappe.db.sql("""update `tabWebsite Route` ws set ref_doctype=(select wsc.ref_doctype | |||
# from `tabWebsite Template` wsc where wsc.name=ws.website_template) | |||
# where ifnull(page_or_generator, '')!='Page'""") | |||
frappe.reload_doc("website", "doctype", "website_settings") | |||
# original_home_page = frappe.db.get_value("Website Settings", "Website Settings", "home_page") | |||
# | |||
# home_page = frappe.db.sql("""select name from `tabWebsite Route` | |||
# where (name=%s or docname=%s) and name!='index'""", (original_home_page, original_home_page)) | |||
# home_page = home_page[0][0] if home_page else original_home_page | |||
# | |||
# frappe.db.set_value("Website Settings", "Website Settings", "home_page", home_page) |
@@ -1,9 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "outgoing_email_settings") | |||
if (frappe.db.get_value("Outgoing Email Settings", "Outgoing Email Settings", "mail_server") or "").strip(): | |||
frappe.db.set_value("Outgoing Email Settings", "Outgoing Email Settings", "enabled", 1) |
@@ -1,25 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "print_settings") | |||
print_settings = frappe.get_doc("Print Settings") | |||
print_settings.print_style = "Modern" | |||
try: | |||
import pdfkit | |||
except ImportError: | |||
pass | |||
else: | |||
# if someone has already configured in Outgoing Email Settings | |||
outgoing_email_settings = frappe.db.get_singles_dict("Outgoing Email Settings") | |||
if "send_print_as_pdf" in outgoing_email_settings: | |||
print_settings.send_print_as_pdf = outgoing_email_settings.send_print_as_pdf | |||
print_settings.pdf_page_size = outgoing_email_settings.pdf_page_size | |||
else: | |||
print_settings.send_print_as_pdf = 1 | |||
print_settings.save() |
@@ -1,97 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
import os | |||
from frappe.core.doctype.file.file import get_content_hash, get_file_name | |||
from frappe.utils import get_files_path, get_site_path | |||
# The files missed by the previous patch might have been replaced with new files | |||
# with the same filename | |||
# | |||
# This patch does the following, | |||
# * Detect which files were replaced and rename them with name{hash:5}.extn and | |||
# update filedata record for the new file | |||
# | |||
# * make missing_files.txt in site dir with files that should be recovered from | |||
# a backup from a time before version 3 migration | |||
# | |||
# * Patch remaining unpatched File records. | |||
def execute(): | |||
frappe.db.auto_commit_on_many_writes = True | |||
rename_replacing_files() | |||
for name, file_name, file_url in frappe.db.sql( | |||
"""select name, file_name, file_url from `tabFile` | |||
where ifnull(file_name, '')!='' and ifnull(content_hash, '')=''"""): | |||
b = frappe.get_doc('File', name) | |||
old_file_name = b.file_name | |||
b.file_name = os.path.basename(old_file_name) | |||
if old_file_name.startswith('files/') or old_file_name.startswith('/files/'): | |||
b.file_url = os.path.normpath('/' + old_file_name) | |||
else: | |||
b.file_url = os.path.normpath('/files/' + old_file_name) | |||
try: | |||
_file = frappe.get_doc("File", {"file_name": name}) | |||
content = _file.get_content() | |||
b.content_hash = get_content_hash(content) | |||
except IOError: | |||
print('Warning: Error processing ', name) | |||
b.content_hash = None | |||
b.flags.ignore_duplicate_entry_error = True | |||
b.save() | |||
frappe.db.auto_commit_on_many_writes = False | |||
def get_replaced_files(): | |||
ret = [] | |||
new_files = dict(frappe.db.sql("select name, file_name from `tabFile` where file_name not like 'files/%'")) | |||
old_files = dict(frappe.db.sql("select name, file_name from `tabFile` where ifnull(content_hash, '')=''")) | |||
invfiles = invert_dict(new_files) | |||
for nname, nfilename in new_files.items(): | |||
if 'files/' + nfilename in old_files.values(): | |||
ret.append((nfilename, invfiles[nfilename])) | |||
return ret | |||
def rename_replacing_files(): | |||
replaced_files = get_replaced_files() | |||
if len(replaced_files): | |||
missing_files = [v[0] for v in replaced_files] | |||
with open(get_site_path('missing_files.txt'), 'w') as f: | |||
f.write(('\n'.join(missing_files) + '\n').encode('utf-8')) | |||
for file_name, file_datas in replaced_files: | |||
print ('processing ' + file_name) | |||
content_hash = frappe.db.get_value('File', file_datas[0], 'content_hash') | |||
if not content_hash: | |||
continue | |||
new_file_name = get_file_name(file_name, content_hash) | |||
if os.path.exists(get_files_path(new_file_name)): | |||
continue | |||
print('skipping ' + file_name) | |||
try: | |||
os.rename(get_files_path(file_name), get_files_path(new_file_name)) | |||
except OSError: | |||
print('Error renaming ', file_name) | |||
for name in file_datas: | |||
f = frappe.get_doc('File', name) | |||
f.file_name = new_file_name | |||
f.file_url = '/files/' + new_file_name | |||
f.save() | |||
def invert_dict(ddict): | |||
ret = {} | |||
for k,v in ddict.items(): | |||
if not ret.get(v): | |||
ret[v] = [k] | |||
else: | |||
ret[v].append(k) | |||
return ret | |||
def get_file_name(fname, hash): | |||
if '.' in fname: | |||
partial, extn = fname.rsplit('.', 1) | |||
else: | |||
partial = fname | |||
extn = '' | |||
return '{partial}{suffix}.{extn}'.format(partial=partial, extn=extn, suffix=hash[:5]) |
@@ -1,10 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "print_settings") | |||
print_settings = frappe.get_doc("Print Settings") | |||
print_settings.with_letterhead = 1 | |||
print_settings.save() |
@@ -1,8 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
# clear all static web pages | |||
frappe.delete_doc("DocType", "Website Route", force=1) | |||
frappe.delete_doc("Page", "sitemap-browser", force=1) | |||
frappe.db.sql("drop table if exists `tabWebsite Route`") |
@@ -1,11 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
for name in frappe.db.sql_list("""select name from `tabToDo` | |||
where ifnull(reference_type, '')!='' and ifnull(reference_name, '')!=''"""): | |||
try: | |||
frappe.get_doc("ToDo", name).on_update() | |||
except Exception as e: | |||
if not frappe.db.is_table_missing(e): | |||
raise |
@@ -1,10 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
for d in frappe.get_all("Property Setter", fields=["name", "doc_type"], | |||
filters={"doctype_or_field": "DocField", "property": "allow_on_submit", "value": "1"}): | |||
frappe.delete_doc("Property Setter", d.name) | |||
frappe.clear_cache(doctype=d.doc_type) |
@@ -1,32 +0,0 @@ | |||
import json | |||
import frappe | |||
import frappe.defaults | |||
from frappe.desk.like import _toggle_like | |||
def execute(): | |||
for user in frappe.get_all("User"): | |||
username = user["name"] | |||
bookmarks = frappe.db.get_default("_bookmarks", username) | |||
if not bookmarks: | |||
continue | |||
if isinstance(bookmarks, str): | |||
bookmarks = json.loads(bookmarks) | |||
for opts in bookmarks: | |||
route = (opts.get("route") or "").strip("#/ ") | |||
if route and route.startswith("Form"): | |||
try: | |||
view, doctype, docname = opts["route"].split("/") | |||
except ValueError: | |||
continue | |||
if frappe.db.exists(doctype, docname): | |||
if (doctype=="DocType" | |||
or int(frappe.db.get_value("DocType", doctype, "issingle") or 0) | |||
or not frappe.db.table_exists(doctype)): | |||
continue | |||
_toggle_like(doctype, docname, add="Yes", user=username) |
@@ -1,9 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.delete_doc("DocType", "Post") | |||
frappe.delete_doc("DocType", "Website Group") | |||
frappe.delete_doc("DocType", "Website Route Permission") | |||
frappe.delete_doc("DocType", "User Vote") | |||
frappe.delete_doc("DocType", "Notification Count") |
@@ -1,6 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "communication") | |||
frappe.db.sql("""update tabCommunication set reference_doctype = parenttype, reference_name = parent""") |
@@ -1,16 +0,0 @@ | |||
import frappe | |||
from frappe.database.mariadb.setup_db import check_database_settings | |||
from frappe.model.meta import trim_tables | |||
def execute(): | |||
check_database_settings() | |||
for table in frappe.db.get_tables(): | |||
frappe.db.sql_ddl("""alter table `{0}` ENGINE=InnoDB ROW_FORMAT=COMPRESSED""".format(table)) | |||
try: | |||
frappe.db.sql_ddl("""alter table `{0}` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci""".format(table)) | |||
except: | |||
# if row size gets too large, let it be old charset! | |||
pass | |||
@@ -1,8 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doctype("Error Log") | |||
from frappe.core.doctype.error_log.error_log import set_old_logs_as_seen | |||
set_old_logs_as_seen() |
@@ -1,14 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doctype("Notification") | |||
for e in frappe.get_all("Notification"): | |||
notification = frappe.get_doc("Notification", e.name) | |||
if notification.event == "Date Change": | |||
if notification.days_in_advance < 0: | |||
notification.event = "Days After" | |||
notification.days_in_advance = -email_alert.days_in_advance | |||
else: | |||
notification.event = "Days Before" | |||
notification.save() |
@@ -1,20 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
for table in frappe.db.get_tables(): | |||
changed = False | |||
desc = frappe.db.sql("desc `{table}`".format(table=table), as_dict=True) | |||
for field in desc: | |||
if field["Type"] == "date": | |||
frappe.db.sql("""update `{table}` set `{fieldname}`=null where `{fieldname}`='0000-00-00'""".format( | |||
table=table, fieldname=field["Field"])) | |||
changed = True | |||
elif field["Type"] == "datetime(6)": | |||
frappe.db.sql("""update `{table}` set `{fieldname}`=null where `{fieldname}`='0000-00-00 00:00:00.000000'""".format( | |||
table=table, fieldname=field["Field"])) | |||
changed = True | |||
if changed: | |||
frappe.db.commit() |
@@ -1,43 +0,0 @@ | |||
import frappe | |||
import re | |||
def execute(): | |||
"""Fix relative urls for image src="files/" to src="/files/" in DocTypes with text editor fields""" | |||
doctypes_with_text_fields = frappe.get_all("DocField", fields=["parent", "fieldname"], | |||
filters={"fieldtype": "Text Editor"}) | |||
done = [] | |||
for opts in doctypes_with_text_fields: | |||
if opts in done: | |||
continue | |||
try: | |||
result = frappe.get_all(opts.parent, fields=["name", opts.fieldname]) | |||
except frappe.db.SQLError: | |||
# bypass single tables | |||
continue | |||
for data in result: | |||
old_value = data[opts.fieldname] | |||
if not old_value: | |||
continue | |||
html = scrub_relative_urls(old_value) | |||
if html != old_value: | |||
# print_diff(html, old_value) | |||
frappe.db.set_value(opts.parent, data.name, opts.fieldname, html, update_modified=False) | |||
done.append(opts) | |||
def scrub_relative_urls(html): | |||
"""prepend a slash before a relative url""" | |||
try: | |||
return re.sub(r'src[\s]*=[\s]*[\'"]files/([^\'"]*)[\'"]', r'src="/files/\g<1>"', html) | |||
except: | |||
print("Error", html) | |||
raise | |||
def print_diff(html, old_value): | |||
import difflib | |||
diff = difflib.unified_diff(old_value.splitlines(1), html.splitlines(1), lineterm='') | |||
print('\n'.join(list(diff))) |
@@ -1,5 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
pass |
@@ -1,6 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
if "device" not in frappe.db.get_table_columns("Sessions"): | |||
frappe.db.sql("alter table tabSessions add column `device` varchar(255) default 'desktop'") |
@@ -1,8 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doctype('System Settings') | |||
last = frappe.db.get_global('scheduler_last_event') | |||
frappe.db.set_value('System Settings', 'System Settings', 'scheduler_last_event', last) | |||
@@ -1,5 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# License: GNU General Public License v3. See license.txt | |||
def execute(): | |||
from frappe.installer import remove_from_installed_apps | |||
remove_from_installed_apps("shopping_cart") |
@@ -1,18 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# See license.txt | |||
import frappe | |||
def execute(): | |||
try: | |||
frappe.db.sql("alter table `tabEmail Queue` change `ref_docname` `reference_name` varchar(255)") | |||
except Exception as e: | |||
if not frappe.db.is_table_or_column_missing(e): | |||
raise | |||
try: | |||
frappe.db.sql("alter table `tabEmail Queue` change `ref_doctype` `reference_doctype` varchar(255)") | |||
except Exception as e: | |||
if not frappe.db.is_table_or_column_missing(e): | |||
raise | |||
frappe.reload_doctype("Email Queue") |
@@ -1,29 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# License: GNU General Public License v3. See license.txt | |||
import frappe | |||
from frappe.model.utils.rename_field import rename_field | |||
from frappe.modules import scrub, get_doctype_module | |||
rename_map = { | |||
"Customize Form": [ | |||
["customize_form_fields", "fields"] | |||
], | |||
"Email Alert": [ | |||
["email_alert_recipients", "recipients"] | |||
], | |||
"Workflow": [ | |||
["workflow_document_states", "states"], | |||
["workflow_transitions", "transitions"] | |||
] | |||
} | |||
def execute(): | |||
frappe.reload_doc("custom", "doctype", "customize_form") | |||
frappe.reload_doc("email", "doctype", "notification") | |||
frappe.reload_doc("desk", "doctype", "event") | |||
frappe.reload_doc("workflow", "doctype", "workflow") | |||
for dt, field_list in rename_map.items(): | |||
for field in field_list: | |||
rename_field(dt, field[0], field[1]) |
@@ -1,59 +0,0 @@ | |||
import frappe | |||
from frappe import _ | |||
from frappe.utils import cint | |||
def execute(): | |||
frappe.reload_doc("website", "doctype", "website_theme") | |||
frappe.reload_doc("website", "website_theme", "standard") | |||
frappe.reload_doctype("Website Settings") | |||
migrate_style_settings() | |||
frappe.delete_doc("website", "doctype", "style_settings") | |||
def migrate_style_settings(): | |||
style_settings = frappe.db.get_singles_dict("Style Settings") | |||
standard_website_theme = frappe.get_doc("Website Theme", "Standard") | |||
website_theme = frappe.copy_doc(standard_website_theme) | |||
website_theme.custom = 1 | |||
website_theme.theme = _("Custom") | |||
if style_settings: | |||
map_color_fields(style_settings, website_theme) | |||
map_other_fields(style_settings, website_theme) | |||
website_theme.no_sidebar = cint(frappe.db.get_single_value("Website Settings", "no_sidebar")) | |||
website_theme.save() | |||
website_theme.set_as_default() | |||
def map_color_fields(style_settings, website_theme): | |||
color_fields_map = { | |||
"page_text": "text_color", | |||
"page_links": "link_color", | |||
"top_bar_background": "top_bar_color", | |||
"top_bar_foreground": "top_bar_text_color", | |||
"footer_background": "footer_color", | |||
"footer_color": "footer_text_color", | |||
} | |||
for from_fieldname, to_fieldname in color_fields_map.items(): | |||
from_value = style_settings.get(from_fieldname) | |||
if from_value: | |||
website_theme.set(to_fieldname, "#{0}".format(from_value)) | |||
def map_other_fields(style_settings, website_theme): | |||
other_fields_map = { | |||
"heading_text_as": "heading_style", | |||
"google_web_font_for_heading": "heading_webfont", | |||
"google_web_font_for_text": "text_webfont", | |||
"add_css": "css" | |||
} | |||
for from_fieldname, to_fieldname in other_fields_map.items(): | |||
website_theme.set(to_fieldname, style_settings.get(from_fieldname)) | |||
for fieldname in ("apply_style", "background_image", "background_color", | |||
"font_size"): | |||
website_theme.set(fieldname, style_settings.get(fieldname)) |
@@ -1,37 +0,0 @@ | |||
import frappe | |||
import frappe.share | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "docperm") | |||
frappe.reload_doc("core", "doctype", "docshare") | |||
frappe.reload_doc('email', 'doctype', 'email_account') | |||
# default share to all writes | |||
frappe.db.sql("""update tabDocPerm set `share`=1 where ifnull(`write`,0)=1 and ifnull(`permlevel`,0)=0""") | |||
# every user must have access to his / her own detail | |||
users = frappe.get_all("User", filters={"user_type": "System User"}) | |||
usernames = [user.name for user in users] | |||
for user in usernames: | |||
frappe.share.add("User", user, user, write=1, share=1) | |||
# move event user to shared | |||
if frappe.db.exists("DocType", "Event User"): | |||
for event in frappe.get_all("Event User", fields=["parent", "person"]): | |||
if event.person in usernames: | |||
if not frappe.db.exists("Event", event.parent): | |||
frappe.db.sql("delete from `tabEvent User` where parent = %s",event.parent) | |||
else: | |||
frappe.share.add("Event", event.parent, event.person, write=1) | |||
frappe.delete_doc("DocType", "Event User") | |||
# move note user to shared | |||
if frappe.db.exists("DocType", "Note User"): | |||
for note in frappe.get_all("Note User", fields=["parent", "user", "permission"]): | |||
perm = {"read": 1} if note.permission=="Read" else {"write": 1} | |||
if note.user in usernames: | |||
frappe.share.add("Note", note.parent, note.user, **perm) | |||
frappe.delete_doc("DocType", "Note User") |
@@ -1,17 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe | |||
def execute(): | |||
changed = ( | |||
("desk", ("feed", "event", "todo", "note")), | |||
("custom", ("custom_field", "custom_script", "customize_form", | |||
"customize_form_field", "property_setter")), | |||
("email", ("email_queue", "notification", "notification_recipient", "standard_reply")), | |||
("geo", ("country", "currency")), | |||
("print", ("letter_head", "print_format", "print_settings")) | |||
) | |||
for module in changed: | |||
for doctype in module[1]: | |||
frappe.reload_doc(module[0], "doctype", doctype) |
@@ -1,34 +0,0 @@ | |||
import frappe | |||
from frappe.utils import cint | |||
from frappe.model import default_fields | |||
def execute(): | |||
for table in frappe.db.get_tables(): | |||
doctype = table[3:] | |||
if frappe.db.exists("DocType", doctype): | |||
fieldnames = [df["fieldname"] for df in | |||
frappe.get_all("DocField", fields=["fieldname"], filters={"parent": doctype})] | |||
custom_fieldnames = [df["fieldname"] for df in | |||
frappe.get_all("Custom Field", fields=["fieldname"], filters={"dt": doctype})] | |||
else: | |||
fieldnames = custom_fieldnames = [] | |||
for column in frappe.db.sql("""desc `{0}`""".format(table), as_dict=True): | |||
if column["Type"]=="int(1)": | |||
fieldname = column["Field"] | |||
# only change for defined fields, ignore old fields that don't exist in meta | |||
if not (fieldname in default_fields or fieldname in fieldnames or fieldname in custom_fieldnames): | |||
continue | |||
# set 0 | |||
frappe.db.sql("""update `{table}` set `{column}`=0 where `{column}` is null"""\ | |||
.format(table=table, column=fieldname)) | |||
frappe.db.commit() | |||
# change definition | |||
frappe.db.sql_ddl("""alter table `{table}` | |||
modify `{column}` int(1) not null default {default}"""\ | |||
.format(table=table, column=fieldname, default=cint(column["Default"]))) |
@@ -1,12 +0,0 @@ | |||
# -*- coding: utf-8 -*- | |||
import frappe | |||
from frappe.translate import rename_language | |||
def execute(): | |||
language_map = { | |||
"中国(简体)": "簡體中文", | |||
"中國(繁體)": "正體中文" | |||
} | |||
for old_name, new_name in language_map.items(): | |||
rename_language(old_name, new_name) |
@@ -1,19 +0,0 @@ | |||
import frappe | |||
from frappe.permissions import reset_perms | |||
def execute(): | |||
frappe.reload_doctype("Communication") | |||
# set status = "Linked" | |||
frappe.db.sql("""update `tabCommunication` set status='Linked' | |||
where ifnull(reference_doctype, '')!='' and ifnull(reference_name, '')!=''""") | |||
frappe.db.sql("""update `tabCommunication` set status='Closed' | |||
where status='Archived'""") | |||
# reset permissions if owner of all DocPerms is Administrator | |||
if not frappe.db.sql("""select name from `tabDocPerm` | |||
where parent='Communication' and ifnull(owner, '')!='Administrator'"""): | |||
reset_perms("Communication") |
@@ -1,8 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.db.sql("""update tabDocType set document_type='Document' | |||
where document_type='Transaction'""") | |||
frappe.db.sql("""update tabDocType set document_type='Setup' | |||
where document_type='Master'""") |
@@ -1,6 +0,0 @@ | |||
def execute(): | |||
from frappe.geo.country_info import get_all | |||
import frappe.utils.install | |||
countries = get_all() | |||
frappe.utils.install.add_country_and_currency("Ghana", frappe._dict(countries["Ghana"])) |
@@ -1,7 +0,0 @@ | |||
import frappe.utils, os | |||
def execute(): | |||
path = frappe.utils.get_site_path('task-logs') | |||
if not os.path.exists(path): | |||
os.makedirs(path) |
@@ -1,37 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
from frappe.core.doctype.file.file import make_home_folder | |||
if not frappe.db.exists("DocType", "File"): | |||
frappe.rename_doc("DocType", "File Data", "File") | |||
frappe.reload_doctype("File") | |||
if not frappe.db.exists("File", {"is_home_folder": 1}): | |||
make_home_folder() | |||
# make missing folders and set parent folder | |||
for file in frappe.get_all("File", filters={"is_folder": 0}): | |||
file = frappe.get_doc("File", file.name) | |||
file.flags.ignore_folder_validate = True | |||
file.flags.ignore_file_validate = True | |||
file.flags.ignore_duplicate_entry_error = True | |||
file.flags.ignore_links = True | |||
file.set_folder_name() | |||
try: | |||
file.save() | |||
except: | |||
print(frappe.get_traceback()) | |||
raise | |||
from frappe.utils.nestedset import rebuild_tree | |||
rebuild_tree("File", "folder") | |||
# reset file size | |||
for folder in frappe.db.sql("""select name from tabFile f1 where is_folder = 1 and | |||
(select count(*) from tabFile f2 where f2.folder = f1.name and f2.is_folder = 1) = 0"""): | |||
folder = frappe.get_doc("File", folder[0]) | |||
folder.save() | |||
@@ -1,7 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("email", "doctype", "email_account") | |||
if frappe.db.has_column('Email Account', 'pop3_server'): | |||
frappe.db.sql("update `tabEmail Account` set email_server = pop3_server") |
@@ -1,86 +0,0 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
import frappe, json | |||
from frappe.utils import cstr | |||
def execute(): | |||
# deprecated on 2016-03-09 | |||
# using insert_after instead | |||
return | |||
frappe.db.sql("""delete from `tabProperty Setter` where property='previous_field'""") | |||
all_custom_fields = frappe._dict() | |||
for d in frappe.db.sql("""select name, dt, fieldname, insert_after from `tabCustom Field` | |||
where insert_after is not null and insert_after != ''""", as_dict=1): | |||
all_custom_fields.setdefault(d.dt, frappe._dict()).setdefault(d.fieldname, d.insert_after) | |||
for dt, custom_fields in all_custom_fields.items(): | |||
_idx = [] | |||
existing_ps = frappe.db.get_value("Property Setter", | |||
{"doc_type": dt, "property": "_idx"}, ["name", "value", "creation"], as_dict=1) | |||
# if no existsing property setter, build based on meta | |||
if not existing_ps: | |||
_idx = get_sorted_fields(dt, custom_fields) | |||
else: | |||
_idx = json.loads(existing_ps.value) | |||
idx_needs_to_be_fixed = False | |||
for fieldname, insert_after in custom_fields.items(): | |||
# Delete existing property setter if field is not there | |||
if fieldname not in _idx: | |||
idx_needs_to_be_fixed = True | |||
break | |||
else: | |||
previous_field = _idx[_idx.index(fieldname) - 1] | |||
if previous_field != insert_after and cstr(existing_ps.creation) >= "2015-12-28": | |||
idx_needs_to_be_fixed = True | |||
break | |||
if idx_needs_to_be_fixed: | |||
frappe.delete_doc("Property Setter", existing_ps.name) | |||
_idx = get_sorted_fields(dt, custom_fields) | |||
if _idx: | |||
frappe.make_property_setter({ | |||
"doctype":dt, | |||
"doctype_or_field": "DocType", | |||
"property": "_idx", | |||
"value": json.dumps(_idx), | |||
"property_type": "Text" | |||
}, validate_fields_for_doctype=False) | |||
def get_sorted_fields(doctype, custom_fields): | |||
"""sort on basis of insert_after""" | |||
fields_dict = frappe.get_meta(doctype).get("fields") | |||
standard_fields_count = frappe.db.sql("""select count(name) from `tabDocField` | |||
where parent=%s""", doctype)[0][0] | |||
newlist = [] | |||
pending = [d.fieldname for d in fields_dict] | |||
maxloops = len(custom_fields) + 20 | |||
while (pending and maxloops>0): | |||
maxloops -= 1 | |||
for fieldname in pending[:]: | |||
if fieldname in custom_fields and len(newlist) >= standard_fields_count: | |||
# field already added | |||
for n in newlist: | |||
if n==custom_fields.get(fieldname): | |||
newlist.insert(newlist.index(n)+1, fieldname) | |||
pending.remove(fieldname) | |||
break | |||
else: | |||
newlist.append(fieldname) | |||
pending.remove(fieldname) | |||
# recurring at end | |||
if pending: | |||
newlist += pending | |||
return newlist |
@@ -1,16 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doctype("User") | |||
# give preference to System Users | |||
users = frappe.db.sql_list("""select name from `tabUser` order by if(user_type='System User', 0, 1)""") | |||
for name in users: | |||
user = frappe.get_doc("User", name) | |||
if user.username or not user.first_name: | |||
continue | |||
username = user.suggest_username() | |||
if username: | |||
user.db_set("username", username, update_modified=False) |
@@ -1,31 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doctype("Communication") | |||
for doctype, name in frappe.db.sql("""select distinct reference_doctype, reference_name | |||
from `tabCommunication` | |||
where | |||
(reference_doctype is not null and reference_doctype != '') | |||
and (reference_name is not null and reference_name != '') | |||
and (reference_owner is null or reference_owner = '') | |||
for update"""): | |||
owner = frappe.db.get_value(doctype, name, "owner") | |||
if not owner: | |||
continue | |||
frappe.db.sql("""update `tabCommunication` | |||
set reference_owner=%(owner)s | |||
where | |||
reference_doctype=%(doctype)s | |||
and reference_name=%(name)s | |||
and (reference_owner is null or reference_owner = '')""".format(doctype=doctype), { | |||
"doctype": doctype, | |||
"name": name, | |||
"owner": owner | |||
}) | |||
frappe.db.commit() |
@@ -1,15 +0,0 @@ | |||
import frappe | |||
from frappe.database.schema import add_column | |||
def execute(): | |||
frappe.db.sql("""update `tabSingles` set field='_liked_by' where field='_starred_by'""") | |||
frappe.db.commit() | |||
for table in frappe.db.get_tables(): | |||
columns = [r[0] for r in frappe.db.sql("DESC `{0}`".format(table))] | |||
if "_starred_by" in columns and '_liked_by' not in columns: | |||
frappe.db.sql_ddl("""alter table `{0}` change `_starred_by` `_liked_by` Text """.format(table)) | |||
if not frappe.db.has_column("Communication", "_liked_by"): | |||
add_column("Communication", "_liked_by", "Text") |
@@ -1,307 +0,0 @@ | |||
import frappe | |||
from frappe import _ | |||
from frappe.model.rename_doc import get_link_fields | |||
from frappe.model.dynamic_links import dynamic_link_queries | |||
from frappe.permissions import reset_perms | |||
def execute(): | |||
# comments stay comments in v12 | |||
return | |||
frappe.reload_doctype("DocType") | |||
frappe.reload_doctype("Communication") | |||
reset_perms("Communication") | |||
migrate_comments() | |||
frappe.delete_doc("DocType", "Comment") | |||
# frappe.db.sql_ddl("drop table `tabComment`") | |||
migrate_feed() | |||
frappe.delete_doc("DocType", "Feed") | |||
# frappe.db.sql_ddl("drop table `tabFeed`") | |||
update_timeline_doc_for("Blogger") | |||
def migrate_comments(): | |||
from_fields = "" | |||
to_fields = "" | |||
if "reference_doctype" in frappe.db.get_table_columns("Comment"): | |||
from_fields = "reference_doctype as link_doctype, reference_name as link_name," | |||
to_fields = "link_doctype, link_name," | |||
# comments | |||
frappe.db.sql("""insert ignore into `tabCommunication` ( | |||
subject, | |||
content, | |||
sender, | |||
sender_full_name, | |||
comment_type, | |||
communication_date, | |||
reference_doctype, | |||
reference_name, | |||
{to_fields} | |||
name, | |||
user, | |||
owner, | |||
creation, | |||
modified_by, | |||
modified, | |||
status, | |||
sent_or_received, | |||
communication_type, | |||
seen | |||
) | |||
select | |||
substring(comment, 1, 100) as subject, | |||
comment as content, | |||
comment_by as sender, | |||
comment_by_fullname as sender_full_name, | |||
comment_type, | |||
ifnull(timestamp(comment_date, comment_time), creation) as communication_date, | |||
comment_doctype as reference_doctype, | |||
comment_docname as reference_name, | |||
{from_fields} | |||
name, | |||
owner as user, | |||
owner, | |||
creation, | |||
modified_by, | |||
modified, | |||
'Linked' as status, | |||
'Sent' as sent_or_received, | |||
'Comment' as communication_type, | |||
1 as seen | |||
from `tabComment` where comment_doctype is not null and comment_doctype not in ('Message', 'My Company')""" | |||
.format(to_fields=to_fields, from_fields=from_fields)) | |||
# chat and assignment notifications | |||
frappe.db.sql("""insert ignore into `tabCommunication` ( | |||
subject, | |||
content, | |||
sender, | |||
sender_full_name, | |||
comment_type, | |||
communication_date, | |||
reference_doctype, | |||
reference_name, | |||
{to_fields} | |||
name, | |||
user, | |||
owner, | |||
creation, | |||
modified_by, | |||
modified, | |||
status, | |||
sent_or_received, | |||
communication_type, | |||
seen | |||
) | |||
select | |||
case | |||
when parenttype='Assignment' then %(assignment)s | |||
else substring(comment, 1, 100) | |||
end | |||
as subject, | |||
comment as content, | |||
comment_by as sender, | |||
comment_by_fullname as sender_full_name, | |||
comment_type, | |||
ifnull(timestamp(comment_date, comment_time), creation) as communication_date, | |||
'User' as reference_doctype, | |||
comment_docname as reference_name, | |||
{from_fields} | |||
name, | |||
owner as user, | |||
owner, | |||
creation, | |||
modified_by, | |||
modified, | |||
'Linked' as status, | |||
'Sent' as sent_or_received, | |||
case | |||
when parenttype='Assignment' then 'Notification' | |||
else 'Chat' | |||
end | |||
as communication_type, | |||
1 as seen | |||
from `tabComment` where comment_doctype in ('Message', 'My Company')""" | |||
.format(to_fields=to_fields, from_fields=from_fields), {"assignment": _("Assignment")}) | |||
def migrate_feed(): | |||
# migrate delete feed | |||
for doctype in frappe.db.sql("""select distinct doc_type from `tabFeed` where subject=%(deleted)s""", {"deleted": _("Deleted")}): | |||
frappe.db.sql("""insert ignore into `tabCommunication` ( | |||
subject, | |||
sender, | |||
sender_full_name, | |||
comment_type, | |||
communication_date, | |||
reference_doctype, | |||
name, | |||
user, | |||
owner, | |||
creation, | |||
modified_by, | |||
modified, | |||
status, | |||
sent_or_received, | |||
communication_type, | |||
seen | |||
) | |||
select | |||
concat_ws(" ", %(_doctype)s, doc_name) as subject, | |||
owner as sender, | |||
full_name as sender_full_name, | |||
'Deleted' as comment_type, | |||
creation as communication_date, | |||
doc_type as reference_doctype, | |||
name, | |||
owner as user, | |||
owner, | |||
creation, | |||
modified_by, | |||
modified, | |||
'Linked' as status, | |||
'Sent' as sent_or_received, | |||
'Comment' as communication_type, | |||
1 as seen | |||
from `tabFeed` where subject=%(deleted)s and doc_type=%(doctype)s""", { | |||
"deleted": _("Deleted"), | |||
"doctype": doctype, | |||
"_doctype": _(doctype) | |||
}) | |||
# migrate feed type login or empty | |||
frappe.db.sql("""insert ignore into `tabCommunication` ( | |||
subject, | |||
sender, | |||
sender_full_name, | |||
comment_type, | |||
communication_date, | |||
reference_doctype, | |||
reference_name, | |||
name, | |||
user, | |||
owner, | |||
creation, | |||
modified_by, | |||
modified, | |||
status, | |||
sent_or_received, | |||
communication_type, | |||
seen | |||
) | |||
select | |||
subject, | |||
owner as sender, | |||
full_name as sender_full_name, | |||
case | |||
when feed_type='Login' then 'Info' | |||
else 'Updated' | |||
end as comment_type, | |||
creation as communication_date, | |||
doc_type as reference_doctype, | |||
doc_name as reference_name, | |||
name, | |||
owner as user, | |||
owner, | |||
creation, | |||
modified_by, | |||
modified, | |||
'Linked' as status, | |||
'Sent' as sent_or_received, | |||
'Comment' as communication_type, | |||
1 as seen | |||
from `tabFeed` where (feed_type in ('Login', '') or feed_type is null)""") | |||
def update_timeline_doc_for(timeline_doctype): | |||
"""NOTE: This method may be used by other apps for patching. It also has COMMIT after each update.""" | |||
# find linked doctypes | |||
# link fields | |||
update_for_linked_docs(timeline_doctype) | |||
# dynamic link fields | |||
update_for_dynamically_linked_docs(timeline_doctype) | |||
def update_for_linked_docs(timeline_doctype): | |||
for df in get_link_fields(timeline_doctype): | |||
if df.issingle: | |||
continue | |||
reference_doctype = df.parent | |||
if not is_valid_timeline_doctype(reference_doctype, timeline_doctype): | |||
continue | |||
for doc in frappe.get_all(reference_doctype, fields=["name", df.fieldname]): | |||
timeline_name = doc.get(df.fieldname) | |||
update_communication(timeline_doctype, timeline_name, reference_doctype, doc.name) | |||
def update_for_dynamically_linked_docs(timeline_doctype): | |||
dynamic_link_fields = [] | |||
for query in dynamic_link_queries: | |||
for df in frappe.db.sql(query, as_dict=True): | |||
dynamic_link_fields.append(df) | |||
for df in dynamic_link_fields: | |||
reference_doctype = df.parent | |||
if not is_valid_timeline_doctype(reference_doctype, timeline_doctype): | |||
continue | |||
try: | |||
docs = frappe.get_all(reference_doctype, fields=["name", df.fieldname], | |||
filters={ df.options: timeline_doctype }) | |||
except frappe.db.SQLError as e: | |||
if frappe.db.is_table_missing(e): | |||
# single | |||
continue | |||
else: | |||
raise | |||
for doc in docs: | |||
timeline_name = doc.get(df.fieldname) | |||
update_communication(timeline_doctype, timeline_name, reference_doctype, doc.name) | |||
def update_communication(timeline_doctype, timeline_name, reference_doctype, reference_name): | |||
if not timeline_name: | |||
return | |||
frappe.db.sql("""update `tabCommunication` set timeline_doctype=%(timeline_doctype)s, timeline_name=%(timeline_name)s | |||
where (reference_doctype=%(reference_doctype)s and reference_name=%(reference_name)s) | |||
and (timeline_doctype is null or timeline_doctype='') | |||
and (timeline_name is null or timeline_name='')""", { | |||
"timeline_doctype": timeline_doctype, | |||
"timeline_name": timeline_name, | |||
"reference_doctype": reference_doctype, | |||
"reference_name": reference_name | |||
}) | |||
frappe.db.commit() | |||
def is_valid_timeline_doctype(reference_doctype, timeline_doctype): | |||
# for reloading timeline_field | |||
frappe.reload_doctype(reference_doctype) | |||
# make sure the timeline field's doctype is same as timeline doctype | |||
meta = frappe.get_meta(reference_doctype) | |||
if not meta.timeline_field: | |||
return False | |||
doctype = meta.get_link_doctype(meta.timeline_field) | |||
if doctype != timeline_doctype: | |||
return False | |||
return True |
@@ -1,8 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doctype("System Settings") | |||
system_settings = frappe.get_doc("System Settings") | |||
system_settings.flags.ignore_mandatory = 1 | |||
system_settings.save() |
@@ -1,20 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
unset = False | |||
frappe.reload_doc("integrations", "doctype", "dropbox_backup") | |||
dropbox_backup = frappe.get_doc("Dropbox Backup", "Dropbox Backup") | |||
for df in dropbox_backup.meta.fields: | |||
value = frappe.db.get_single_value("Backup Manager", df.fieldname) | |||
if value: | |||
if df.fieldname=="upload_backups_to_dropbox" and value=="Never": | |||
value = "Daily" | |||
unset = True | |||
dropbox_backup.set(df.fieldname, value) | |||
if unset: | |||
dropbox_backup.set("send_backups_to_dropbox", 0) | |||
dropbox_backup.save() |
@@ -1,11 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doc("core", "doctype", "user_email") | |||
frappe.reload_doc("core", "doctype", "user") | |||
for user_name in frappe.get_all('User', filters={'user_type': 'Website User'}): | |||
user = frappe.get_doc('User', user_name) | |||
if user.roles: | |||
user.roles = [] | |||
user.save() |
@@ -1,5 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.db.set_value("Print Settings", "Print Settings", "allow_print_for_draft", 1) |
@@ -1,27 +0,0 @@ | |||
import frappe, json | |||
def execute(): | |||
for ps in frappe.get_all('Property Setter', filters={'property': '_idx'}, | |||
fields = ['doc_type', 'value']): | |||
custom_fields = frappe.get_all('Custom Field', | |||
filters = {'dt': ps.doc_type}, fields=['name', 'fieldname']) | |||
if custom_fields: | |||
_idx = json.loads(ps.value) | |||
for custom_field in custom_fields: | |||
if custom_field.fieldname in _idx: | |||
custom_field_idx = _idx.index(custom_field.fieldname) | |||
if custom_field_idx == 0: | |||
prev_fieldname = "" | |||
else: | |||
prev_fieldname = _idx[custom_field_idx - 1] | |||
else: | |||
prev_fieldname = _idx[-1] | |||
custom_field_idx = len(_idx) | |||
frappe.db.set_value('Custom Field', custom_field.name, 'insert_after', prev_fieldname) | |||
frappe.db.set_value('Custom Field', custom_field.name, 'idx', custom_field_idx) |
@@ -1,6 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doctype('Print Settings') | |||
frappe.db.set_value('Print Settings', 'Print Settings', 'repeat_header_footer', 1) |
@@ -1,8 +0,0 @@ | |||
import frappe | |||
from frappe.translate import get_lang_dict | |||
# migrate language from name to code | |||
def execute(): | |||
return |
@@ -1,36 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
for doctype in frappe.get_all("DocType", filters={"issingle": 0}): | |||
doctype = doctype.name | |||
if not frappe.db.table_exists(doctype): | |||
continue | |||
for column in frappe.db.sql("desc `tab{doctype}`".format(doctype=doctype), as_dict=True): | |||
fieldname = column["Field"] | |||
column_type = column["Type"] | |||
if not column_type.startswith("varchar"): | |||
continue | |||
max_length = frappe.db.sql("""select max(char_length(`{fieldname}`)) from `tab{doctype}`"""\ | |||
.format(fieldname=fieldname, doctype=doctype)) | |||
max_length = max_length[0][0] if max_length else None | |||
if max_length and 140 < max_length <= 255: | |||
print( | |||
"setting length of '{fieldname}' in '{doctype}' as {length}".format( | |||
fieldname=fieldname, doctype=doctype, length=max_length) | |||
) | |||
# create property setter for length | |||
frappe.make_property_setter({ | |||
"doctype": doctype, | |||
"fieldname": fieldname, | |||
"property": "length", | |||
"value": max_length, | |||
"property_type": "Int" | |||
}) | |||
frappe.clear_cache(doctype=doctype) |
@@ -1,6 +0,0 @@ | |||
# -*- coding: utf-8 -*- | |||
import frappe | |||
from frappe.translate import rename_language | |||
def execute(): | |||
rename_language("বাঙালি", "বাংলা") |
@@ -1,36 +0,0 @@ | |||
import frappe | |||
from frappe.model.meta import is_single | |||
def execute(): | |||
"""Fix old style file urls that start with files/""" | |||
fix_file_urls() | |||
fix_attach_field_urls() | |||
def fix_file_urls(): | |||
for file in frappe.db.sql_list("""select name from `tabFile` where file_url like 'files/%'"""): | |||
file = frappe.get_doc("File", file) | |||
file.db_set("file_url", "/" + file.file_url, update_modified=False) | |||
try: | |||
file.validate_file() | |||
file.db_set("file_name", file.file_name, update_modified=False) | |||
if not file.content_hash: | |||
file.generate_content_hash() | |||
file.db_set("content_hash", file.content_hash, update_modified=False) | |||
except IOError: | |||
pass | |||
def fix_attach_field_urls(): | |||
# taken from an old patch | |||
attach_fields = (frappe.db.sql("""select parent, fieldname from `tabDocField` where fieldtype in ('Attach', 'Attach Image')""") + | |||
frappe.db.sql("""select dt, fieldname from `tabCustom Field` where fieldtype in ('Attach', 'Attach Image')""")) | |||
for doctype, fieldname in attach_fields: | |||
if is_single(doctype): | |||
frappe.db.sql("""update `tabSingles` set value=concat("/", `value`) | |||
where doctype=%(doctype)s and field=%(fieldname)s | |||
and value like 'files/%%'""", {"doctype": doctype, "fieldname": fieldname}) | |||
else: | |||
frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=concat("/", `{fieldname}`) | |||
where `{fieldname}` like 'files/%'""".format(doctype=doctype, fieldname=fieldname)) |
@@ -1,6 +0,0 @@ | |||
# -*- coding: utf-8 -*- | |||
import frappe | |||
from frappe.translate import rename_language | |||
def execute(): | |||
rename_language("slovenčina", "slovenčina (Slovak)") |
@@ -1,6 +0,0 @@ | |||
import frappe | |||
def execute(): | |||
frappe.reload_doctype("User") | |||
frappe.db.sql("update `tabUser` set last_active=last_login") |