Sync Studio
by IT Projects Labs https://sync_studio.t.me/ , Ivan Yelizariev https://sync_studio.t.me/Required Apps |
Website (website)
|
Included Dependencies | Show |
Lines of code | 6054 |
Technical Name |
sync |
License | See License tab |
Website | https://t.me/sync_studio |
Also available in version | v 13.0 v 15.0 v 14.0 v 11.0 |
Required Apps |
Website (website)
|
Included Dependencies | Show |
Lines of code | 6054 |
Technical Name |
sync |
License | See License tab |
Website | https://t.me/sync_studio |
Also available in version | v 13.0 v 15.0 v 14.0 v 11.0 |
Sync Studio
Synchronize anything with anything
Version: v12.0.3.0.2
Tested and maintained by
IT Projects Labs
Assitance: help@itpp.dev
The most flexible integration tool
Easy to adjust for your needs!
Logs are available from UI
Easy to debug!

- Cron: execute custom code by cron schedule
- DB Handler: execute custom code on updates in database
- Incoming Webhook: process data/event send from external system
- Manual Triggering: execute custom code manually
- Trello-Github
- Odoo2odoo
- Telegram
Other
solutions
are published on Odoo Apps store and more are coming soon!
To
get further information and request an assitance, contact us by
email: help@itpp.dev
Open Source!
- a new module
- an update to existing module
- an issue with the data xml file attached (generate one via Action -> Export to XML button in project form)
- a bug report
- a feature request
- we will test the updates
- we will check bug reports
- we will document the modules
- we will port modules to the new Odoo versions
Sincerely,
Ivan Yelizariev
Let our expertise work for you!
(Doors and windows below are clickable)
/itpp-labs-1100.jpg)
/itpp-labs-930.jpg)
/itpp-labs-690.jpg)
Sync Studio
Installation
Make configuration required for queue_job module. In particular:
add queue_job to server wide modules, e.g.:
--load base,web,queue_job
Install this module in a usual way
Install python package that you need to use. For example, to try demo projects install following packages:
python3 -m pip install python-telegram-bot==12.8 PyGithub py-trello
If your Sync projects use webhooks (most likely), be sure that url opens correct database without asking to select one
User Access Levels
- Sync Studio: User: read-only access
- Sync Studio: Developer: restricted write access
- Sync Studio: Manager: same as Developer, but with access to Secrets
Project
Open menu [[ Sync Studio ]] >> Projects
Create a project
Name, e.g. Legacy migration
In the Parameters tab
- Params
- Key
- Value
- Texts: Translatable parameters
- Secrets: Parameters with restricted access: key values are visible for Managers only
- Params
In the Evaluation Context tab
- Evaluation context: predefined additional variables and methods
- Common_code: code that is executed before running any project's task. Can be used for initialization or for helpers. Any variables and functions that don't start with underscore symbol will be available in task's code.
In the Available Tasks tab
Name, e.g. Sync products
Code: code with at least one of the following functions
handle_cron()
handle_db(records)
- records: all records on which this task is triggered
handle_webhook(httprequest)
httprequest: contains information about request, e.g.
- httprequest.data: request data
- httprequest.files: uploaded files
- httprequest.remote_addr: ip address of the caller.
- see Werkzeug doc for more information.
optionally can return data as a response to the webhook request; any data transferred in this way are logged via log_transmission function:
for json webhook: * return json_data
for x-www-form-urlencoded webhook: * return data_str * return data_str, status * return data_str, status, headers
- status is a response code, e.g. 200, 403, etc.
- headers is a list of key-value tuples, e.g. [('Content-Type', 'text/html')]
handle_button()
Cron Triggers, DB Triggers, Webhook Triggers, Manual Triggers: when to execute the Code. See below for further information
Job Triggers
Cron
- Trigger Name, e.g. NIGHTLY_SYNC
- Execute Every: every 2 hours, every 1 week, etc.
- Next Execution Date
- Scheduler User
DB
- Trigger Name, e.g. PRODUCT_PRICE_CHANGE
- Model
- Trigger Condition
- On Creation
- On Update
- On Creation & Update
- On Deletion
- Based on Timed Condition
- Allows to trigger task before, after on in time of Date/Time fields, e.g. 1 day after Sale Order is closed
- Apply on: records filter
- Before Update Domain: additional records filter for On Update event
- Watched fields: fields list for On Update event
Webhook
- Trigger Name, e.g. ON_EXTERNAL_UPDATE
- Webhook Type: application/x-www-form-urlencoded or application/json
- Webhook URL: readonly.
Button
- Trigger Name, e.g. SYNC_ALL_PRODUCTS
Code
Available variables and functions:
Base
env: Odoo Environment
log(message, level=LOG_INFO): logging function to record debug information
log levels:
- LOG_DEBUG
- LOG_INFO
- LOG_WARNING
- LOG_ERROR
- LOG_CRITICAL
log_transmission(recipient_str, data_str): report on data transfer to external recipients
DEFAULT_SERVER_DATETIME_FORMAT
Links
- <record>.set_link(relation_name, external, sync_date=None, allow_many2many=False) -> link: makes link between Odoo and external resource
- allow_many2many: when False raises an error if there is a link for the record and relation_name or if there is a link for relation_name and external;
- <records>.search_links(relation_name, refs=[external_ref1, external_ref2, ...]) -> links
- get_link(relation_name, external_ref) -> link
Odoo Link usage:
- link.odoo: normal Odoo record
- link.odoo._name: model name, e.g. res.partner
- link.odoo.id: odoo record id
- link.odoo.<field>: some field of the record, e.g. link.odoo.email: partner email
- link.external: external reference, e.g. external id of a partner
- link.sync_date: last saved date-time information
- links.odoo: normal Odoo RecordSet
- links.external: list of all external references
- links.sync_date: minimal data-time among links
- links.update_links(sync_date=None): set new sync_date value; if value is not passed, then now() is used
- links.unlink(): delete links
- for link in links:: iterate over links
- if links: check that link set is not empty
- len(links): number of links in the set
- sets operations:
- links1 == links2: sets are equal
- links1 - links2: links that are in first set, but not in another
- links1 | links2: union
- links1 & links2: intersection
- links1 ^ links2: equal to (links1 | links2) - (links1 & links2)
You can also link external data with external data on syncing two different system (e.g. github and trello).
set_link(relation_name, {"github": github_issue_num, "trello": trello_card_num}, sync_date=None, allow_many2many=False) -> elink * refs is a dictionary with system name and references pairs, e.g.
{ "github": github_issue_num, "trello": trello_card_num, }
search_links(relation_name, refs) -> elinks: * refs may contain list of references as values, e.g.
{ "github": [github_issue_num], "trello": [trello_card_num], }
use None values to don't filter by referece value of that system, e.g.
{ "github": None, "trello": [trello_card_num], }
if references for both systems are passed, then elink is added to result only when its references are presented in both references lists
get_link(relation_name, refs) -> elink
- At least one of the reference should be not Falsy
- get_link raise error, if there are few odoo records linked to the references. Set work with multiple relations (one2many, many2one, many2many) use set_link(..., allow_many2many=False) and search_links
In place of github and trello you can use other labels depending on what you sync.
External Link is similar to Odoo link with the following differences:
- elink.get(<system>), e.g. elink.get("github"): reference value for system; it's a replacement for link.odoo and link.external in Odoo link
Sync Helpers
For one2one syncronization you can use following helpers.
- sync_odoo2x(src_list, sync_info, create=False, update=False)
- sync_info["x"]["create"](odoo_record) -> external_ref: create external record and return reference
- sync_info["x"]["update"](external_ref, odoo_record) -> external_ref: update external record
- sync_info["x"]["get_ref"](x): get reference for an item in src_list
- sync_x2odoo(src_list, sync_info, create=False, update=False)
- sync_info["odoo"]["create"](x) -> odoo_record: create odoo record from external data
- sync_info["odoo"]["update"](odoo_record, x) -> odoo_record: update odoo record according to providing external data
Common args:
- sync_info["relation"]: same as relation_name in set_link, get_link
- src_list: iterator of x or odoo_record values
- create: boolean value for "create record if it doesn't exist"
- update: boolean value for "update record if it exists"
To use helpers, create sync_info with all information, e.g.
EMPLOYEE_SYNC = { "relation": "my_system_and_odoo_employee_rel", "x": { "get_ref": employee2ref, "create": employee_create, "update": employee_update, }, "odoo": { "create": employee_create_odoo, "update": employee_update_odoo, } }
Then you can reuse in all syncronizations, e.g.
# on initial fetching records from external system sync_x2odoo(all_employees_x, EMPLOYEE_SYNC, create=True) # to push all updates to external system sync_odoo2x(all_employees_odoo, EMPLOYEE_SYNC, update=True) # on updating a single record push all updates to external system sync_odoo2x([employee_odoo], EMPLOYEE_SYNC, update=True)
There is a similar helper for syncronization between two external systems:
- sync_external(src_list, relation, src_info, dst_info, create=False, update=False)
- src_info["get_ref"](src_data): get reference for an item in src_list
- src_info["system"]: e.g. "github"
- src_info["update"](dst_ref, src_data)
- src_info["create"](src_data) -> dst_ref
- dst["system"]: e.g. "trello"
Project Values
- params.<PARAM_NAME>: project params
- webhooks.<WEBHOOK_NAME>: contains webhook url; only in tasks' code
Event
- trigger_name: available in tasks' code only
- user: user related to the event, e.g. who clicked a button
Asynchronous work
- add_job(func_name, **options)(*func_args, **func_kwargs): call a function asynchronously; options are similar to with_delay method of queue_job module:
- priority: Priority of the job, 0 being the higher priority. Default is 10.
- eta: Estimated Time of Arrival of the job. It will not be executed before this date/time.
- max_retries: maximum number of retries before giving up and set the job state to 'failed'. A value of 0 means infinite retries. Default is 5.
- description human description of the job. If None, description is computed from the function doc or name
- identity_key key uniquely identifying the job, if specified and a job with the same key has not yet been run, the new job will not be added.
Libs
- json
- time
- datetime
- dateutil
- timezone
- b64encode
- b64decode
Exceptions
- UserError
- ValidationError
- RetryableJobError: raise to restart job from beginning; e.g. in case of temporary errors like broken connection
- OSError
Evaluation context
Evaluation provides additional variables and methods for a project. For example, for telegram integration is could be method to send message to a telegram user. To make such additional context, you need to make a new module and make extension for sync.project model. Example:
import requests from odoo import api, fields, models class SyncProject(models.Model): _inherit = "sync.project" eval_context = fields.Selection(selection_add=[ ("my_project", "My Project"), ]) @api.model def _eval_context_my_project(self, secrets, eval_context): """Additional function to make http request * httpPost(url, **kwargs) """ log_transmission = eval_context["log_transmission"] log = eval_context["log"] def httpPOST(url, **kwargs): log_transmission(url, json.dumps(kwargs)) r = requests.request("POST", url, **kwargs) log("Response: %s" % r.text) return r.text return { "httpPost": httpPost }
Running Job
Depending on Trigger, a job may:
- be added to a queue or runs immediatly
- be retried in case of failure
- if RetryableJobError is raised, then job is retried automatically in following scheme:
- After first failure wait 5 minute
- If it's not succeeded again, then wait another 15 minutes
- If it's not succeeded again, then wait another 60 minutes
- If it's not succeeded again, then wait another 3 hours
- Try again for the fifth time and stop retrying if it's still failing
- if RetryableJobError is raised, then job is retried automatically in following scheme:
Cron
- job is added to the queue before run
- failed job can be retried if failed
DB
- job is added to the queue before run
- failed job can be retried if failed
Webhook
- runs immediately
- failed job cannot be retried via backend UI; the webhook should be called again.
Button
- runs immediately
- to retry click the button again
Execution Logs
In Project, Task and Job Trigger forms you can find Logs button in top-right hand corner. You can filter and group logs by following fields:
- Sync Project
- Sync Task
- Job Trigger
- Job Start Time
- Log Level
- Status (Success / Fail)
Demo Project: Odoo <-> Telegram
In this project we create new partners and attach messages sent to telegram bot. Odoo Messages prefixed with /telegram are sent back to telegram.
To try it, you need to install this module in demo mode. Also, your odoo instance must be accessible over internet to receive telegram webhooks. Due to telegram requirements, your web server must use http**s** connection.
How it works
Webhook Trigger waits for an update from telegram. Once it happened, the action depends on message text:
- for /start message (it's sent on first bot usage), we reply with welcome message (can be configured in project parameter TELEGRAM_WELCOME_MESSAGE) and create a partner with Internal Reference equal to <TELEGRAM_USER_ID>@telegram
- for any other message we attach a message copy to the partner with corresponding Internal Reference
DB trigger waits for a message attached to a telegram partner (telegram partners are filtered by Internal Reference field). If the message has /telegram prefix, task's code is run:
- a message copy (after removing the prefix) is sent to corresponding telegram user
- attach report message to the partner record
Configuration
In Telegram:
- send message /new to @BotFather and follow further instructions to create bot and get the bot token
In Odoo:
- Activate Developer Mode
- Open menu [[ Settings ]] >> Technical >> Parameters >> System Parameters
- Check that parameter web.base.url is properly set and it's accessible over internet (it should not localhost)
- Open menu [[ Sync Studio ]] >> Sync Projects
- Select Demo Telegram Integration project
- Go to Parameters tab
- Set Secrets:
- TELEGRAM_BOT_TOKEN
- Unarchive the project
- Open Manual Triggers Tab
- Click button [Run Now] near to Setup task
Usage
In Telegram:
- send some message to the created bot
In Odoo:
- Open Contacts/Customers menu
- RESULT: there is new partner with name Telegram:<YOUR TELEGRAM NAME> (the prefix can be configured in project parameter PARTNER_NAME_PREFIX)
- Open the partner and attach a log/message with prefix /telegram, e.g. /telegram Hello! How can I help you?
- Wait few seconds to get confirmation
- RESULT: you will see new attached message from Odoo Bot with confirmation that message is sent to telegram
In telegram:
- RESULT: the message is delivered via bot
You can continue chatting in this way
Demo Project: Odoo2odoo
In this project we push partners to external Odoo 12.0 and sync back avatar changes.
To try it, you need to install this module in demo mode.
How it works
DB trigger waits for partner creation. When it happens, task's code is run:
- creates a copy of partner on external Odoo
- XMLRPC is used as API
- gets back id of the partner copy on external Odoo
- attaches the id to the partner of our Odoo via set_link method
To sync changes on external Odoo we use Cron trigger. It runs every 15 minutes. You can also run it manually. The code works as following:
- call search_links function to get ids to sync and the oldest sync date
- request to the external Odoo for the partners, but filtered by sync time to don't load partner without new updates
- for each of the fetched partner compare its update time with sync date saved in the link
- if a partner is updated since last sync, then update partner and sync date
Configuration
- Open menu [[ Sync Studio ]] >> Sync Projects
- Select Demo Odoo2odoo integration project
- Go to Parameters tab
- Set Params: * URL, e.g. https://3674665-12-0.runbot41.odoo.com * DB, e.g. odoo
- Set Secrets:
- USERNAME, e.g. admin
- PASSWORD, e.g. admin
- Unarchive the project
Usage
Syncing new partner.
- Open Contacts/Customers menu
- Create new partner
- Go back to the project
- Click Logs button and check that there are no errors
- Open the external Odoo
- RESULT: the partner copy is on the external Odoo
- Update avatar image on it
- Go back to the Demo Odoo2odoo Integration project in our Odoo
- Click Available Tasks tab
- Click [Edit]
- Go to Sync Remote Partners Updates task
- Click on Available Triggers tab and go inside CHECK_EXTERNAL_ODOO trigger
- Configure cron
- Make trigger Active on the upper right corner
- Click [Save]
- Then you can trigger synchronization in some of the following ways:
- Click [Run Manually] inside the trigger
- Simply wait up to cron job will start on a schedule :)
- Now open the partner in our Odoo
- RESULT: avatar is synced from external Odoo
- You can try to change avatar on external Odoo again and should get the same results
Uploading all existing partners.
- Open menu [[ Sync Studio ]] >> Sync Projects
- Select Demo Odoo2odoo Integration project
- Choose Sync Task Sync Local Partners To Remote Odoo
- Click button [Run Now]
- Open the external Odoo
- RESULT: copies of all our partners are in the external Odoo; they have Sync Studio: prefix (can be configured in project parameter UPLOAD_ALL_PARTNER_PREFIX)
Demo project: GitHub <-> Trello
In this project we create copies of github issues/pull requests and their messages in trello cards. It's one side synchronization: new cards and message in trello are not published in github. Trello and Github labels are synchronized in both directions.
To try it, you need to install this module in demo mode. Also, your odoo instance must be accessible over internet to receive github and trello webhooks.
How it works
Github Webhook Trigger waits from GitHub for issue creation and new messages:
- if there is no trello card linked to the issue, then create trello card and link it with the issue
- if new message is posted in github issue, then post message copy in trello card
Github Webhook Trigger waits from GitHub for label attaching/detaching (Trello Webhook Trigger works in the same way)
- if label is attached in GitHub issue , then check for github label and trello label links and create trello label if there is no such link yet
- if label is attached in github issue, then attach corresponding label in trello card
- if label is detached in github issue, then detach corresponding label in trello card
Github Webhook Trigger waits from GitHub for label updating/deleting (Trello Webhook Trigger works in the same way):
- if label is changed and there is trello label linked to it, then update the label
- if label is changed and there is trello label linked to it, then delete the label
There is still possibility that labels are mismatch, e.g. due to github api temporary unavailability or misfunction (e.g. api request to add label responded with success, but label was not attached) or if odoo was stopped when github tried to notify about updates. In some cases, we can just retry the handler (e.g. there was an error on api request to github/trello, then the system tries few times to repeat label attaching/detaching). As a solution for cases when retrying didn't help (e.g. api is still not working) or cannot help (e.g. odoo didn't get webhook notification), we run a Cron Trigger at night to check for labels mismatch and synchronize them. In LABELS_MERGE_STRATEGY you can choose which strategy to use:
- USE_TRELLO -- ignore github labels and override them with trello labels
- USE_GITHUB -- ignore trello labels and override them with push github labels
- UNION -- add missed labels from both side
- INTERSECTION -- remove labels that are not attached on both side
Configuration
Open menu [[ Sync Studio ]] >> Sync Projects
Select Demo Github-Trello Integration project
In Parameters tab set Secrets (check Description and Documentation links near the parameters table about how to get the secret parameters):
- GITHUB_REPO
- GITHUB_TOKEN
- TRELLO_BOARD_ID
- TRELLO_KEY
- TRELLO_TOKEN
In Available Tasks tab:
- Click [Edit]
- Open Labels Conflict resolving task
- In Available Triggers tab:
- Open CONFLICT_RESOLVING Cron
- Change Next Execution Date in webhook to the night time
- Set Number of Calls, a negative value means no limit (e.g. -1)
- Make it active on the upper right corner
- Click [Save]
Make integration Active on the upper right corner
In project's Manual Triggers tab:
Click [Run Now] buttons in trigger SETUP_GITHUB
Click [Run Now] buttons in triggers SETUP_TRELLO. Note, that it doesn't work without one of the following workarounds:
open file sync/controllers/webhook.py and temporarily change type="json" to type="http". Revert the changes after successfully setting up trello
add header "Content-Type: application/json" via your web server. Example for nginx:
location /website/action-json/ { return 200 "{}"; }
After a successful SETUP_TRELLO trigger run, return everything to its original position, otherwise the project will not work correctly
Usage
Syncing new Github issue
- Open Github
- Create issue
- Open trello
- RESULT: you see a copy of the Github issue
- Go back to the Github issue
- Post a message
- Now go back to the trello card
- RESULT: you see a copy of the message
- You can also add/remove github issue labels or trello card labels (note that the name of the label must be added
in Trello so that there are no errors in the GitHub).
- RESULT: once you change them on one side, after short time, you will see the changes on another side
Labels syncing
- Open Github or Trello
- Rename or delete some label
- RESULT: the same happened in both systems
Conflict resolving
- Create a github issue and check that it's syncing to trello
- Stop Odoo
- Make different changes of labels both in github issue and trello card
- Start Odoo
- Open menu [[ Sync Studio ]] >> Projects
- Select Demo Trello-Github integration project
- Click [Edit] and open Labels Conflict Resolving task in Available Tasks tab
- Make CONFLICT_RESOLVING Cron Trigger run in one of the following ways
- Choose Cron Trigger and click [Run Manually]
- Change Next Execution Date to a past time and wait up to 1 minute
- RESULT: the github issue and corresponding trello card the same set of labels. The merging is done according to selected strategy in LABELS_MERGE_STRATEGY parameter.
Syncing all existing Github issues.
- Open menu [[ Sync Studio ]] >> Projects
- Select Demo Tello-Github Integration project
- Click button [Run Now] near to PUSH_ALL_ISSUES manual trigger
- It will start asynchronous jobs. You can check progress via button Jobs
- After some time open Trello
- RESULT: copies of all open github issues are in trello; they have GITHUB: prefix (can be configured in project parameter ISSUE_FROM_GITHUB_PREFIX)
Custom Integration
If you made a custom integration via UI and want to package it into a module, open the Sync Project and click [Actions] -> Export to XML button.
GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
Please log in to comment on this module