소스 검색

Merge pull request #13417 from gavindsouza/patch-tests

version-14
Suraj Shetty 4 년 전
committed by GitHub
부모
커밋
3b32f542a7
No known key found for this signature in database GPG 키 ID: 4AEE18F83AFDEB23
100개의 변경된 파일116개의 추가작업 그리고 1817개의 파일을 삭제
  1. +83
    -0
      .github/workflows/patch-mariadb-tests.yml
  2. +0
    -1
      .github/workflows/server-mariadb-tests.yml
  3. +1
    -3
      frappe/__init__.py
  4. +12
    -4
      frappe/commands/utils.py
  5. +20
    -3
      frappe/parallel_test_runner.py
  6. +0
    -157
      frappe/patches.txt
  7. +0
    -1
      frappe/patches/v11_0/create_contact_for_user.py
  8. +0
    -1
      frappe/patches/v11_0/rename_google_maps_doctype.py
  9. +0
    -0
      frappe/patches/v4_0/__init__.py
  10. +0
    -13
      frappe/patches/v4_0/add_delete_permission.py
  11. +0
    -25
      frappe/patches/v4_0/change_varchar_length.py
  12. +0
    -39
      frappe/patches/v4_0/create_custom_field_for_owner_match.py
  13. +0
    -9
      frappe/patches/v4_0/deprecate_control_panel.py
  14. +0
    -12
      frappe/patches/v4_0/deprecate_link_selects.py
  15. +0
    -13
      frappe/patches/v4_0/enable_scheduler_in_system_settings.py
  16. +0
    -33
      frappe/patches/v4_0/file_manager_hooks.py
  17. +0
    -12
      frappe/patches/v4_0/fix_attach_field_file_url.py
  18. +0
    -10
      frappe/patches/v4_0/private_backups.py
  19. +0
    -5
      frappe/patches/v4_0/remove_index_sitemap.py
  20. +0
    -9
      frappe/patches/v4_0/remove_old_parent.py
  21. +0
    -9
      frappe/patches/v4_0/remove_user_owner_custom_field.py
  22. +0
    -15
      frappe/patches/v4_0/rename_profile_to_user.py
  23. +0
    -25
      frappe/patches/v4_0/rename_sitemap_to_route.py
  24. +0
    -20
      frappe/patches/v4_0/replace_deprecated_timezones.py
  25. +0
    -9
      frappe/patches/v4_0/set_module_in_report.py
  26. +0
    -9
      frappe/patches/v4_0/set_todo_checked_as_closed.py
  27. +0
    -10
      frappe/patches/v4_0/set_user_gravatar.py
  28. +0
    -23
      frappe/patches/v4_0/set_user_permissions.py
  29. +0
    -25
      frappe/patches/v4_0/set_website_route_idx.py
  30. +0
    -17
      frappe/patches/v4_0/update_custom_field_insert_after.py
  31. +0
    -12
      frappe/patches/v4_0/update_datetime.py
  32. +0
    -12
      frappe/patches/v4_0/webnotes_to_frappe.py
  33. +0
    -19
      frappe/patches/v4_0/website_sitemap_hierarchy.py
  34. +0
    -0
      frappe/patches/v4_1/__init__.py
  35. +0
    -9
      frappe/patches/v4_1/enable_outgoing_email_settings.py
  36. +0
    -25
      frappe/patches/v4_1/enable_print_as_pdf.py
  37. +0
    -97
      frappe/patches/v4_1/file_manager_fix.py
  38. +0
    -0
      frappe/patches/v4_2/__init__.py
  39. +0
    -10
      frappe/patches/v4_2/print_with_letterhead.py
  40. +0
    -8
      frappe/patches/v4_2/refactor_website_routing.py
  41. +0
    -11
      frappe/patches/v4_2/set_assign_in_doc.py
  42. +0
    -0
      frappe/patches/v4_3/__init__.py
  43. +0
    -10
      frappe/patches/v4_3/remove_allow_on_submit_customization.py
  44. +0
    -0
      frappe/patches/v5_0/__init__.py
  45. +0
    -32
      frappe/patches/v5_0/bookmarks_to_stars.py
  46. +0
    -9
      frappe/patches/v5_0/clear_website_group_and_notifications.py
  47. +0
    -6
      frappe/patches/v5_0/communication_parent.py
  48. +0
    -16
      frappe/patches/v5_0/convert_to_barracuda_and_utf8mb4.py
  49. +0
    -8
      frappe/patches/v5_0/expire_old_scheduler_logs.py
  50. +0
    -14
      frappe/patches/v5_0/fix_email_alert.py
  51. +0
    -20
      frappe/patches/v5_0/fix_null_date_datetime.py
  52. +0
    -43
      frappe/patches/v5_0/fix_text_editor_file_urls.py
  53. +0
    -5
      frappe/patches/v5_0/force_sync_website.py
  54. +0
    -6
      frappe/patches/v5_0/modify_session.py
  55. +0
    -8
      frappe/patches/v5_0/move_scheduler_last_event_to_system_settings.py
  56. +0
    -5
      frappe/patches/v5_0/remove_shopping_cart_app.py
  57. +0
    -18
      frappe/patches/v5_0/rename_ref_type_fieldnames.py
  58. +0
    -29
      frappe/patches/v5_0/rename_table_fieldnames.py
  59. +0
    -59
      frappe/patches/v5_0/style_settings_to_website_theme.py
  60. +0
    -37
      frappe/patches/v5_0/update_shared.py
  61. +0
    -17
      frappe/patches/v5_0/v4_to_v5.py
  62. +0
    -0
      frappe/patches/v5_2/__init__.py
  63. +0
    -34
      frappe/patches/v5_2/change_checks_to_not_null.py
  64. +0
    -0
      frappe/patches/v5_3/__init__.py
  65. +0
    -12
      frappe/patches/v5_3/rename_chinese_languages.py
  66. +0
    -0
      frappe/patches/v6_0/__init__.py
  67. +0
    -19
      frappe/patches/v6_0/communication_status_and_permission.py
  68. +0
    -8
      frappe/patches/v6_0/document_type_rename.py
  69. +0
    -6
      frappe/patches/v6_0/fix_ghana_currency.py
  70. +0
    -7
      frappe/patches/v6_0/make_task_log_folder.py
  71. +0
    -0
      frappe/patches/v6_1/__init__.py
  72. +0
    -37
      frappe/patches/v6_1/rename_file_data.py
  73. +0
    -0
      frappe/patches/v6_11/__init__.py
  74. +0
    -7
      frappe/patches/v6_11/rename_field_in_email_account.py
  75. +0
    -0
      frappe/patches/v6_15/__init__.py
  76. +0
    -86
      frappe/patches/v6_15/remove_property_setter_for_previous_field.py
  77. +0
    -16
      frappe/patches/v6_15/set_username.py
  78. +0
    -0
      frappe/patches/v6_16/__init__.py
  79. +0
    -31
      frappe/patches/v6_16/feed_doc_owner.py
  80. +0
    -15
      frappe/patches/v6_16/star_to_like.py
  81. +0
    -0
      frappe/patches/v6_19/__init__.py
  82. +0
    -307
      frappe/patches/v6_19/comment_feed_communication.py
  83. +0
    -0
      frappe/patches/v6_2/__init__.py
  84. +0
    -8
      frappe/patches/v6_2/ignore_user_permissions_if_missing.py
  85. +0
    -20
      frappe/patches/v6_2/rename_backup_manager.py
  86. +0
    -0
      frappe/patches/v6_20x/__init__.py
  87. +0
    -11
      frappe/patches/v6_20x/remove_roles_from_website_user.py
  88. +0
    -5
      frappe/patches/v6_20x/set_allow_draft_for_print.py
  89. +0
    -27
      frappe/patches/v6_20x/update_insert_after.py
  90. +0
    -0
      frappe/patches/v6_21/__init__.py
  91. +0
    -6
      frappe/patches/v6_21/print_settings_repeat_header_footer.py
  92. +0
    -0
      frappe/patches/v6_24/__init__.py
  93. +0
    -8
      frappe/patches/v6_24/set_language_as_code.py
  94. +0
    -0
      frappe/patches/v6_4/__init__.py
  95. +0
    -36
      frappe/patches/v6_4/reduce_varchar_length.py
  96. +0
    -6
      frappe/patches/v6_4/rename_bengali_language.py
  97. +0
    -0
      frappe/patches/v6_6/__init__.py
  98. +0
    -36
      frappe/patches/v6_6/fix_file_url.py
  99. +0
    -6
      frappe/patches/v6_6/rename_slovak_language.py
  100. +0
    -6
      frappe/patches/v6_6/user_last_active.py

+ 83
- 0
.github/workflows/patch-mariadb-tests.yml 파일 보기

@@ -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

+ 0
- 1
.github/workflows/server-mariadb-tests.yml 파일 보기

@@ -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:


+ 1
- 3
frappe/__init__.py 파일 보기

@@ -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)


+ 12
- 4
frappe/commands/utils.py 파일 보기

@@ -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,


+ 20
- 3
frappe/parallel_test_runner.py 파일 보기

@@ -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):


+ 0
- 157
frappe/patches.txt 파일 보기

@@ -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


+ 0
- 1
frappe/patches/v11_0/create_contact_for_user.py 파일 보기

@@ -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"):


+ 0
- 1
frappe/patches/v11_0/rename_google_maps_doctype.py 파일 보기

@@ -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')

+ 0
- 0
frappe/patches/v4_0/__init__.py 파일 보기


+ 0
- 13
frappe/patches/v4_0/add_delete_permission.py 파일 보기

@@ -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()

+ 0
- 25
frappe/patches/v4_0/change_varchar_length.py 파일 보기

@@ -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)


+ 0
- 39
frappe/patches/v4_0/create_custom_field_for_owner_match.py 파일 보기

@@ -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()

+ 0
- 9
frappe/patches/v4_0/deprecate_control_panel.py 파일 보기

@@ -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()

+ 0
- 12
frappe/patches/v4_0/deprecate_link_selects.py 파일 보기

@@ -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()

+ 0
- 13
frappe/patches/v4_0/enable_scheduler_in_system_settings.py 파일 보기

@@ -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()

+ 0
- 33
frappe/patches/v4_0/file_manager_hooks.py 파일 보기

@@ -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)


+ 0
- 12
frappe/patches/v4_0/fix_attach_field_file_url.py 파일 보기

@@ -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))

+ 0
- 10
frappe/patches/v4_0/private_backups.py 파일 보기

@@ -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")

+ 0
- 5
frappe/patches/v4_0/remove_index_sitemap.py 파일 보기

@@ -1,5 +0,0 @@

import frappe

def execute():
pass

+ 0
- 9
frappe/patches/v4_0/remove_old_parent.py 파일 보기

@@ -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" """)

+ 0
- 9
frappe/patches/v4_0/remove_user_owner_custom_field.py 파일 보기

@@ -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)

+ 0
- 15
frappe/patches/v4_0/rename_profile_to_user.py 파일 보기

@@ -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")

+ 0
- 25
frappe/patches/v4_0/rename_sitemap_to_route.py 파일 보기

@@ -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

+ 0
- 20
frappe/patches/v4_0/replace_deprecated_timezones.py 파일 보기

@@ -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()

+ 0
- 9
frappe/patches/v4_0/set_module_in_report.py 파일 보기

@@ -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, '')=''""")

+ 0
- 9
frappe/patches/v4_0/set_todo_checked_as_closed.py 파일 보기

@@ -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

+ 0
- 10
frappe/patches/v4_0/set_user_gravatar.py 파일 보기

@@ -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)

+ 0
- 23
frappe/patches/v4_0/set_user_permissions.py 파일 보기

@@ -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()


+ 0
- 25
frappe/patches/v4_0/set_website_route_idx.py 파일 보기

@@ -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()

+ 0
- 17
frappe/patches/v4_0/update_custom_field_insert_after.py 파일 보기

@@ -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()

+ 0
- 12
frappe/patches/v4_0/update_datetime.py 파일 보기

@@ -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]))

+ 0
- 12
frappe/patches/v4_0/webnotes_to_frappe.py 파일 보기

@@ -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()

+ 0
- 19
frappe/patches/v4_0/website_sitemap_hierarchy.py 파일 보기

@@ -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)

+ 0
- 0
frappe/patches/v4_1/__init__.py 파일 보기


+ 0
- 9
frappe/patches/v4_1/enable_outgoing_email_settings.py 파일 보기

@@ -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)

+ 0
- 25
frappe/patches/v4_1/enable_print_as_pdf.py 파일 보기

@@ -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()

+ 0
- 97
frappe/patches/v4_1/file_manager_fix.py 파일 보기

@@ -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])

+ 0
- 0
frappe/patches/v4_2/__init__.py 파일 보기


+ 0
- 10
frappe/patches/v4_2/print_with_letterhead.py 파일 보기

@@ -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()

+ 0
- 8
frappe/patches/v4_2/refactor_website_routing.py 파일 보기

@@ -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`")

+ 0
- 11
frappe/patches/v4_2/set_assign_in_doc.py 파일 보기

@@ -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

+ 0
- 0
frappe/patches/v4_3/__init__.py 파일 보기


+ 0
- 10
frappe/patches/v4_3/remove_allow_on_submit_customization.py 파일 보기

@@ -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)

+ 0
- 0
frappe/patches/v5_0/__init__.py 파일 보기


+ 0
- 32
frappe/patches/v5_0/bookmarks_to_stars.py 파일 보기

@@ -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)

+ 0
- 9
frappe/patches/v5_0/clear_website_group_and_notifications.py 파일 보기

@@ -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")

+ 0
- 6
frappe/patches/v5_0/communication_parent.py 파일 보기

@@ -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""")

+ 0
- 16
frappe/patches/v5_0/convert_to_barracuda_and_utf8mb4.py 파일 보기

@@ -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


+ 0
- 8
frappe/patches/v5_0/expire_old_scheduler_logs.py 파일 보기

@@ -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()

+ 0
- 14
frappe/patches/v5_0/fix_email_alert.py 파일 보기

@@ -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()

+ 0
- 20
frappe/patches/v5_0/fix_null_date_datetime.py 파일 보기

@@ -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()

+ 0
- 43
frappe/patches/v5_0/fix_text_editor_file_urls.py 파일 보기

@@ -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)))

+ 0
- 5
frappe/patches/v5_0/force_sync_website.py 파일 보기

@@ -1,5 +0,0 @@

import frappe

def execute():
pass

+ 0
- 6
frappe/patches/v5_0/modify_session.py 파일 보기

@@ -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'")

+ 0
- 8
frappe/patches/v5_0/move_scheduler_last_event_to_system_settings.py 파일 보기

@@ -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)


+ 0
- 5
frappe/patches/v5_0/remove_shopping_cart_app.py 파일 보기

@@ -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")

+ 0
- 18
frappe/patches/v5_0/rename_ref_type_fieldnames.py 파일 보기

@@ -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")

+ 0
- 29
frappe/patches/v5_0/rename_table_fieldnames.py 파일 보기

@@ -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])

+ 0
- 59
frappe/patches/v5_0/style_settings_to_website_theme.py 파일 보기

@@ -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))

+ 0
- 37
frappe/patches/v5_0/update_shared.py 파일 보기

@@ -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")

+ 0
- 17
frappe/patches/v5_0/v4_to_v5.py 파일 보기

@@ -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)

+ 0
- 0
frappe/patches/v5_2/__init__.py 파일 보기


+ 0
- 34
frappe/patches/v5_2/change_checks_to_not_null.py 파일 보기

@@ -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"])))

+ 0
- 0
frappe/patches/v5_3/__init__.py 파일 보기


+ 0
- 12
frappe/patches/v5_3/rename_chinese_languages.py 파일 보기

@@ -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)

+ 0
- 0
frappe/patches/v6_0/__init__.py 파일 보기


+ 0
- 19
frappe/patches/v6_0/communication_status_and_permission.py 파일 보기

@@ -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")

+ 0
- 8
frappe/patches/v6_0/document_type_rename.py 파일 보기

@@ -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'""")

+ 0
- 6
frappe/patches/v6_0/fix_ghana_currency.py 파일 보기

@@ -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"]))

+ 0
- 7
frappe/patches/v6_0/make_task_log_folder.py 파일 보기

@@ -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)

+ 0
- 0
frappe/patches/v6_1/__init__.py 파일 보기


+ 0
- 37
frappe/patches/v6_1/rename_file_data.py 파일 보기

@@ -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()




+ 0
- 0
frappe/patches/v6_11/__init__.py 파일 보기


+ 0
- 7
frappe/patches/v6_11/rename_field_in_email_account.py 파일 보기

@@ -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")

+ 0
- 0
frappe/patches/v6_15/__init__.py 파일 보기


+ 0
- 86
frappe/patches/v6_15/remove_property_setter_for_previous_field.py 파일 보기

@@ -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

+ 0
- 16
frappe/patches/v6_15/set_username.py 파일 보기

@@ -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)

+ 0
- 0
frappe/patches/v6_16/__init__.py 파일 보기


+ 0
- 31
frappe/patches/v6_16/feed_doc_owner.py 파일 보기

@@ -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()

+ 0
- 15
frappe/patches/v6_16/star_to_like.py 파일 보기

@@ -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")

+ 0
- 0
frappe/patches/v6_19/__init__.py 파일 보기


+ 0
- 307
frappe/patches/v6_19/comment_feed_communication.py 파일 보기

@@ -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

+ 0
- 0
frappe/patches/v6_2/__init__.py 파일 보기


+ 0
- 8
frappe/patches/v6_2/ignore_user_permissions_if_missing.py 파일 보기

@@ -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()

+ 0
- 20
frappe/patches/v6_2/rename_backup_manager.py 파일 보기

@@ -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()

+ 0
- 0
frappe/patches/v6_20x/__init__.py 파일 보기


+ 0
- 11
frappe/patches/v6_20x/remove_roles_from_website_user.py 파일 보기

@@ -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()

+ 0
- 5
frappe/patches/v6_20x/set_allow_draft_for_print.py 파일 보기

@@ -1,5 +0,0 @@

import frappe

def execute():
frappe.db.set_value("Print Settings", "Print Settings", "allow_print_for_draft", 1)

+ 0
- 27
frappe/patches/v6_20x/update_insert_after.py 파일 보기

@@ -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)

+ 0
- 0
frappe/patches/v6_21/__init__.py 파일 보기


+ 0
- 6
frappe/patches/v6_21/print_settings_repeat_header_footer.py 파일 보기

@@ -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)

+ 0
- 0
frappe/patches/v6_24/__init__.py 파일 보기


+ 0
- 8
frappe/patches/v6_24/set_language_as_code.py 파일 보기

@@ -1,8 +0,0 @@

import frappe

from frappe.translate import get_lang_dict

# migrate language from name to code
def execute():
return

+ 0
- 0
frappe/patches/v6_4/__init__.py 파일 보기


+ 0
- 36
frappe/patches/v6_4/reduce_varchar_length.py 파일 보기

@@ -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)

+ 0
- 6
frappe/patches/v6_4/rename_bengali_language.py 파일 보기

@@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
import frappe
from frappe.translate import rename_language

def execute():
rename_language("বাঙালি", "বাংলা")

+ 0
- 0
frappe/patches/v6_6/__init__.py 파일 보기


+ 0
- 36
frappe/patches/v6_6/fix_file_url.py 파일 보기

@@ -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))

+ 0
- 6
frappe/patches/v6_6/rename_slovak_language.py 파일 보기

@@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
import frappe
from frappe.translate import rename_language

def execute():
rename_language("slovenčina", "slovenčina (Slovak)")

+ 0
- 6
frappe/patches/v6_6/user_last_active.py 파일 보기

@@ -1,6 +0,0 @@

import frappe

def execute():
frappe.reload_doctype("User")
frappe.db.sql("update `tabUser` set last_active=last_login")

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.

불러오는 중...
취소
저장