@@ -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 | DB: mariadb | ||||
TYPE: server | TYPE: server | ||||
- name: Run Tests | - name: Run Tests | ||||
run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --use-orchestrator --with-coverage | run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --use-orchestrator --with-coverage | ||||
env: | env: | ||||
@@ -1110,9 +1110,7 @@ def setup_module_map(): | |||||
if not (local.app_modules and local.module_app): | if not (local.app_modules and local.module_app): | ||||
local.module_app, local.app_modules = {}, {} | 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, []) | local.app_modules.setdefault(app, []) | ||||
for module in get_module_list(app): | for module in get_module_list(app): | ||||
module = scrub(module) | 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 | # Generate coverage report only for app that is being tested | ||||
source_path = os.path.join(get_bench_path(), 'apps', app or 'frappe') | source_path = os.path.join(get_bench_path(), 'apps', app or 'frappe') | ||||
omit=[ | |||||
'*.html', | |||||
incl = [ | |||||
'*.py', | |||||
] | |||||
omit = [ | |||||
'*.js', | '*.js', | ||||
'*.xml', | '*.xml', | ||||
'*.pyc', | |||||
'*.css', | '*.css', | ||||
'*.less', | '*.less', | ||||
'*.scss', | '*.scss', | ||||
'*.vue', | '*.vue', | ||||
'*.pyc', | |||||
'*.html', | |||||
'*/test_*', | |||||
'*/node_modules/*', | |||||
'*/doctype/*/*_dashboard.py', | '*/doctype/*/*_dashboard.py', | ||||
'*/patches/*' | |||||
'*/patches/*', | |||||
] | ] | ||||
if not app or app == 'frappe': | if not app or app == 'frappe': | ||||
omit.append('*/tests/*') | |||||
omit.append('*/commands/*') | omit.append('*/commands/*') | ||||
cov = Coverage(source=[source_path], omit=omit) | |||||
cov = Coverage(source=[source_path], omit=omit, include=incl) | |||||
cov.start() | cov.start() | ||||
ret = frappe.test_runner.main(app, module, doctype, context.verbose, tests=tests, | 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 | # Generate coverage report only for app that is being tested | ||||
source_path = os.path.join(get_bench_path(), 'apps', self.app) | 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': | if self.app == 'frappe': | ||||
omit.append('*/tests/*') | |||||
omit.append('*/commands/*') | omit.append('*/commands/*') | ||||
self.coverage = Coverage(source=[source_path], omit=omit) | |||||
self.coverage = Coverage(source=[source_path], omit=omit, include=incl) | |||||
self.coverage.start() | self.coverage.start() | ||||
def save_coverage(self): | def save_coverage(self): | ||||
@@ -1,11 +1,5 @@ | |||||
frappe.patches.v12_0.remove_deprecated_fields_from_doctype #3 | 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() | 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_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_link', force=True) #2020-10-17 | ||||
execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2017-09-22 | 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', 'custom_docperm') | ||||
execute:frappe.reload_doc('core', 'doctype', 'docperm') #2018-05-29 | execute:frappe.reload_doc('core', 'doctype', 'docperm') #2018-05-29 | ||||
execute:frappe.reload_doc('core', 'doctype', 'comment') | 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', 'document_naming_rule', force=True) | ||||
execute:frappe.reload_doc('core', 'doctype', 'module_def') #2020-08-28 | execute:frappe.reload_doc('core', 'doctype', 'module_def') #2020-08-28 | ||||
execute:frappe.reload_doc('core', 'doctype', 'version') #2017-04-01 | 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') | execute:frappe.reload_doc('core', 'doctype', 'server_script') | ||||
frappe.patches.v11_0.replicate_old_user_permissions | frappe.patches.v11_0.replicate_old_user_permissions | ||||
frappe.patches.v11_0.reload_and_rename_view_log #2019-01-03 | 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.copy_fetch_data_from_options | ||||
frappe.patches.v11_0.change_email_signature_fieldtype | frappe.patches.v11_0.change_email_signature_fieldtype | ||||
execute:frappe.reload_doc('core', 'doctype', 'activity_log') | execute:frappe.reload_doc('core', 'doctype', 'activity_log') | ||||
execute:frappe.reload_doc('core', 'doctype', 'deleted_document') | execute:frappe.reload_doc('core', 'doctype', 'deleted_document') | ||||
execute:frappe.reload_doc('core', 'doctype', 'domain_settings') | execute:frappe.reload_doc('core', 'doctype', 'domain_settings') | ||||
frappe.patches.v13_0.rename_custom_client_script | 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', 'role') #2017-05-23 | ||||
execute:frappe.reload_doc('core', 'doctype', 'user') #2017-10-27 | 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_column') | ||||
execute:frappe.reload_doc('core', 'doctype', 'report_filter') | execute:frappe.reload_doc('core', 'doctype', 'report_filter') | ||||
execute:frappe.reload_doc('core', 'doctype', 'report') #2020-08-25 | 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.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() | 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.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.delete_doc("DocType", "Tag") | ||||
execute:frappe.db.sql("delete from `tabProperty Setter` where `property` in ('idx', '_idx')") | 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, '')!=''") | 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.permissions.reset_perms("DocType") | ||||
execute:frappe.db.sql("delete from `tabProperty Setter` where `property` = 'idx'") | 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") | 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.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") | 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") | 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, '')!=''") | 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.core.doctype.language.language.update_language_names() # 2017-04-12 | ||||
execute:frappe.db.set_value("Print Settings", "Print Settings", "add_draft_heading", 1) | 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', '') | 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") | 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', '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', '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', 'Tanzania, United Republic of', 'Tanzania', ignore_if_exists=True) | ||||
execute:frappe.rename_doc('Country', 'Syrian Arab Republic', 'Syria', 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') | 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"') | 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) | 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.reload_countries_and_currencies # 2021-02-03 | ||||
frappe.patches.v10_0.refactor_social_login_keys | frappe.patches.v10_0.refactor_social_login_keys | ||||
@@ -8,7 +8,6 @@ def execute(): | |||||
frappe.reload_doc('integrations', 'doctype', 'google_contacts') | frappe.reload_doc('integrations', 'doctype', 'google_contacts') | ||||
frappe.reload_doc('contacts', 'doctype', 'contact') | frappe.reload_doc('contacts', 'doctype', 'contact') | ||||
frappe.reload_doc('core', 'doctype', 'dynamic_link') | frappe.reload_doc('core', 'doctype', 'dynamic_link') | ||||
frappe.reload_doc('communication', 'doctype', 'call_log') | |||||
contact_meta = frappe.get_meta("Contact") | contact_meta = frappe.get_meta("Contact") | ||||
if contact_meta.has_field("phone_nos") and contact_meta.has_field("email_ids"): | 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(): | def execute(): | ||||
if frappe.db.exists("DocType","Google Maps") and not frappe.db.exists("DocType","Google Maps Settings"): | if frappe.db.exists("DocType","Google Maps") and not frappe.db.exists("DocType","Google Maps Settings"): | ||||
rename_doc('DocType', 'Google Maps', '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") |