├── .github ├── ISSUE_TEMPLATE │ └── QUESTION.yml └── workflows │ └── main.yml ├── .gitignore ├── CALIBRE_CLI_INSTRUCTIONS.md ├── CHANGELOG.md ├── DeDRM_plugin ├── DeDRM_ADE PassHash Key_Help.htm ├── DeDRM_Adobe Digital Editions Key_Help.htm ├── DeDRM_EInk Kindle Serial Number_Help.htm ├── DeDRM_Help.htm ├── DeDRM_Kindle for Android Key_Help.htm ├── DeDRM_Kindle for Mac and PC Key_Help.htm ├── DeDRM_Mobipocket PID_Help.htm ├── DeDRM_PDF passphrase_Help.htm ├── DeDRM_Readium LCP passphrase_Help.htm ├── DeDRM_eReader Key_Help.htm ├── __calibre_compat_code.py ├── __init__.py ├── __main__.py ├── __version.py ├── adobekey.py ├── adobekey_get_passhash.py ├── adobekey_winreg_unicode.py ├── aescbc.py ├── alfcrypto.py ├── androidkindlekey.py ├── argv_utils.py ├── config.py ├── convert2xml.py ├── epubfontdecrypt.py ├── epubtest.py ├── epubwatermark.py ├── erdr2pml.py ├── flatxml2html.py ├── flatxml2svg.py ├── genbook.py ├── ignoblekeyAndroid.py ├── ignoblekeyGenPassHash.py ├── ignoblekeyNookStudy.py ├── ignoblekeyWindowsStore.py ├── ineptepub.py ├── ineptpdf.py ├── ion.py ├── k4mobidedrm.py ├── kfxdedrm.py ├── kfxtables.py ├── kgenpids.py ├── kindlekey.py ├── kindlepid.py ├── lcpdedrm.py ├── mobidedrm.py ├── plugin-import-name-dedrm.txt ├── prefs.py ├── scriptinterface.py ├── standalone │ ├── __init__.py │ ├── jsonconfig.py │ ├── passhash.py │ └── remove_drm.py ├── stylexml2css.py ├── topazextract.py ├── utilities.py ├── wineutils.py ├── zeroedzipinfo.py ├── zipfilerugged.py └── zipfix.py ├── DeDRM_plugin_ReadMe.txt ├── FAQs.md ├── Obok_plugin ├── __init__.py ├── action.py ├── common_utils.py ├── config.py ├── dialogs.py ├── images │ └── obok.png ├── obok │ ├── __init__.py │ ├── legacy_obok.py │ └── obok.py ├── obok_dedrm_Help.htm ├── plugin-import-name-obok_dedrm.txt ├── translations │ ├── ar.mo │ ├── ar.po │ ├── de.mo │ ├── de.po │ ├── default.po │ ├── es.mo │ ├── es.po │ ├── nl.mo │ ├── nl.po │ ├── pt.mo │ ├── pt.po │ ├── sv.mo │ └── sv.po └── utilities.py ├── Other_Tools ├── B_and_N_Download_Helper │ ├── BN-Dload.user.js │ └── BN-Dload.user_ReadMe.txt ├── DRM_Key_Scripts │ ├── Adobe_Digital_Editions │ │ └── adobekey.pyw │ ├── Barnes_and_Noble_ePubs │ │ ├── ignoblekey.pyw │ │ ├── ignoblekeyfetch.pyw │ │ └── ignoblekeygen.pyw │ ├── Kindle_for_Android │ │ └── androidkindlekey.pyw │ ├── Kindle_for_Mac_and_PC │ │ └── kindlekey.pyw │ └── Kindle_for_iOS │ │ └── kindleiospidgen.pyw ├── Kindle_for_Android_Patches │ ├── A_Patching_Experience.txt │ ├── kindle_version_3.0.1.70 │ │ ├── ReadMe_K4Android.txt │ │ └── kindle3.0.1.70.patch │ ├── kindle_version_3.7.0.108 │ │ ├── ReadMe_K4Android.txt │ │ └── kindle3.7.0.108.patch │ ├── kindle_version_4.0.2.1 │ │ └── kindle4.0.2.1.patch │ └── kindle_version_4.8.1.10 │ │ ├── Notes on the Patch.txt │ │ └── kindle4.8.1.10.patch ├── Kobo │ └── obok.py ├── Rocket_ebooks │ ├── rebhack.zip │ └── rebhack_ReadMe.txt ├── Scuolabook_DRM │ └── Scuolabook_ReadMe.txt └── Tetrachroma_FileOpen_ineptpdf │ ├── ineptpdf_8.4.51_ReadMe.txt │ └── ineptpdf_fileopen.pyw ├── README.md ├── ReadMe_Overview.txt ├── make_release.py └── obok_plugin_ReadMe.txt /.github/ISSUE_TEMPLATE/QUESTION.yml: -------------------------------------------------------------------------------- 1 | name: Question 2 | description: Questions for DeDRM Project 3 | body: 4 | - type: textarea 5 | id: question 6 | attributes: 7 | label: Question / bug report 8 | description: Please enter your question / your bug report. 9 | - type: input 10 | id: calibre-version 11 | attributes: 12 | label: Which version of Calibre are you running? 13 | description: "Example: 6.23" 14 | placeholder: "6.23" 15 | validations: 16 | required: true 17 | - type: input 18 | id: plugin-version 19 | attributes: 20 | label: Which version of the DeDRM plugin are you running? 21 | description: "Example: v10.0.2" 22 | placeholder: "v10.0.2" 23 | validations: 24 | required: true 25 | - type: input 26 | id: kindle-version 27 | attributes: 28 | label: If applicable, which version of the Kindle software are you running? 29 | description: "Example: 1.24" 30 | placeholder: "Leave empty if unrelated to Kindle books" 31 | validations: 32 | required: false 33 | - type: textarea 34 | id: log 35 | attributes: 36 | label: Log output 37 | description: If applicable, please post your log output here - into the code block. 38 | value: | 39 | ```log 40 | Paste log output here. 41 | ``` -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Package plugin 2 | on: 3 | push: 4 | branches: [ master ] 5 | 6 | jobs: 7 | package: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | 13 | - name: Package 14 | run: python3 make_release.py 15 | 16 | - name: Upload 17 | uses: actions/upload-artifact@v4 18 | with: 19 | name: plugin 20 | path: | 21 | DeDRM_tools_*.zip 22 | DeDRM_tools.zip 23 | 24 | - name: Prepare release 25 | run: cp DeDRM_tools.zip DeDRM_alpha_${{ github.sha }}.zip 26 | 27 | 28 | - uses: dev-drprasad/delete-older-releases@v0.2.1 29 | with: 30 | repo: noDRM/DeDRM_tools_autorelease 31 | keep_latest: 0 32 | delete_tags: true 33 | env: 34 | GITHUB_TOKEN: ${{ secrets.AUTORELEASE_KEY }} 35 | 36 | - name: Auto-release 37 | id: autorelease 38 | uses: softprops/action-gh-release@v1 39 | with: 40 | tag_name: autorelease_${{ github.sha }} 41 | repository: noDRM/DeDRM_tools_autorelease 42 | token: ${{ secrets.AUTORELEASE_KEY }} 43 | name: Automatic alpha release with latest changes 44 | body: | 45 | This release is automatically generated by Github for each commit. 46 | 47 | This means, every time a change is made to the repo, a release with an untested copy of the plugin at that stage will be created. This will contain the most up-to-date code, but it's not tested at all and may be broken. 48 | 49 | Last update based on Git commit [${{ github.sha }}](https://github.com/noDRM/DeDRM_tools/commit/${{ github.sha }}). 50 | prerelease: true 51 | draft: false 52 | files: DeDRM_alpha_${{ github.sha }}.zip 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac files 2 | .DS_Store 3 | 4 | # local test data 5 | /user_data/ 6 | 7 | # Cache 8 | /DeDRM_plugin/__pycache__ 9 | /DeDRM_plugin/standalone/__pycache__ -------------------------------------------------------------------------------- /CALIBRE_CLI_INSTRUCTIONS.md: -------------------------------------------------------------------------------- 1 | # Using the DeDRM plugin with the Calibre command line interface 2 | 3 | If you prefer the Calibre CLI instead of the GUI, follow this guide to 4 | install and use the DeDRM plugin. 5 | 6 | This guide assumes you are on Linux, but it may very well work on other 7 | platforms. 8 | 9 | ## Step-by-step Tutorial 10 | 11 | #### Install Calibre 12 | - Follow [Calibre's installation instructions](https://calibre-ebook.com/download_linux) 13 | 14 | #### Install plugins 15 | - Download the DeDRM `.zip` archive from DeDRM_tools' 16 | [latest release](https://github.com/noDRM/DeDRM_tools/releases/latest). 17 | Then unzip it. 18 | - Add the DeDRM plugin to Calibre: 19 | ``` 20 | cd *the unzipped DeDRM_tools folder* 21 | calibre-customize --add DeDRM_plugin.zip 22 | ``` 23 | - Add the Obok plugin: 24 | ``` 25 | calibre-customize --add Obok_plugin.zip 26 | ``` 27 | 28 | #### Enter your keys 29 | - Figure out what format DeDRM wants your key in by looking in 30 | [the code that handles that](DeDRM_plugin/prefs.py). 31 | - For Kindle eInk devices, DeDRM expects you to put a list of serial 32 | numbers in the `serials` field: `"serials": ["012345689abcdef"]` or 33 | `"serials": ["1111111111111111", "2222222222222222"]`. 34 | - Now add your keys to `$CALIBRE_CONFIG_DIRECTORY/plugins/dedrm.json`. 35 | 36 | #### Import your books 37 | - Make a library folder 38 | ``` 39 | mkdir library 40 | ``` 41 | - Add your book(s) with this command: 42 | ``` 43 | calibredb add /path/to/book.format --with-library=library 44 | ``` 45 | 46 | The DRM should be removed from your book, which you can find in the `library` 47 | folder. 48 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_ADE PassHash Key_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 |
7 | 8 |Adobe PassHash is a variant of the Adobe DRM which is used by retailers like Barnes and Noble. Instead of using certificates and device-based authorization, this uses a username and password combination. In B&&Ns implementation however, the user never gets access to these credentials, just to the credential hash.
23 | 24 |Since 2014, Barnes & Noble is no longer using the default Adobe key generation algorithm, which used to be the full name as "username" and the full credit card number as "password" for the PassHash algorithm. 27 | Instead, they started generating a random key on their server and send that to the reading application during login. This means that the old method to decrypt these books will no longer work.
28 | 29 |There used to be a way to use the Android app's API to simulate a login to the Barnes and Noble servers, but that API has been shut down a while ago, too, and so far nobody has reverse-engineered the new one.
30 | 31 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog for entering the necessary data to generate a new key.
34 |Currently, the only known ways to access the key are the following:
35 |After you've selected a key retrieval method from the settings, the dialog may change and request some additional information depending on the key retrieval method. Enter that, then click the OK button to create and store the generated key. Or Cancel if you don’t want to create a key.
46 |New keys are checked against the current list of keys before being added, and duplicates are discarded.
47 | 48 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted key in the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
51 | 52 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a sheet of paper. Clicking this button will prompt you to enter a new name for the highlighted key in the list. Enter the new name for the encryption key and click the OK button to use the new name, or Cancel to revert to the old name..
55 | 56 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a computer’s hard-drive. Use this button to export the highlighted key to a file (with a ‘.b64’ file name extension). Used for backup purposes or to migrate key data to other computers/calibre installations. The dialog will prompt you for a place to save the file.
59 | 60 |At the bottom-left of the plugin’s customization dialog, you will see a button labeled "Import Existing Keyfiles". Use this button to import existing ‘.b64’ key files. Key files might come from being exported from this or older plugins, or may have been generated using the original i♥cabbages script, or you may have made it by following the instructions above.
63 | 64 |Once done creating/deleting/renaming/importing decryption keys, click Close to exit the customization dialogue. Your changes will only be saved permanently when you click OK in the main configuration dialog.
65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_Adobe Digital Editions Key_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |If you have upgraded from an earlier version of the plugin, any existing Adobe Digital Editions keys will have been automatically imported, so you might not need to do any more configuration. In addition, on Windows and Mac, the default Adobe Digital Editions key is added the first time the plugin is run. Continue reading for key generation and management instructions.
24 | 25 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog prompting you to enter a key name for the default Adobe Digital Editions key.
28 |Click the OK button to create and store the Adobe Digital Editions key for the current installation of Adobe Digital Editions. Or Cancel if you don’t want to create the key.
33 |New keys are checked against the current list of keys before being added, and duplicates are discarded.
34 | 35 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted key in the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
38 | 39 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a sheet of paper. Clicking this button will prompt you to enter a new name for the highlighted key in the list. Enter the new name for the encryption key and click the OK button to use the new name, or Cancel to revert to the old name..
42 | 43 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a computer’s hard-drive. Use this button to export the highlighted key to a file (with a ‘.der’ file name extension). Used for backup purposes or to migrate key data to other computers/calibre installations. The dialog will prompt you for a place to save the file.
46 | 47 |Under the list of keys, Linux users will see a text field labeled "WINEPREFIX". If you are use Adobe Digital Editions under Wine, and your wine installation containing Adobe Digital Editions isn't the default Wine installation, you may enter the full path to the correct Wine installation here. Leave blank if you are unsure.
50 | 51 |At the bottom-left of the plugin’s customization dialog, you will see a button labeled "Import Existing Keyfiles". Use this button to import existing ‘.der’ key files. Key files might come from being exported from this or older plugins, or may have been generated using the adobekey.pyw script running under Wine on Linux systems.
54 | 55 |Once done creating/deleting/renaming/importing decryption keys, click Close to exit the customization dialogue. Your changes will only be saved permanently when you click OK in the main configuration dialog.
56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_EInk Kindle Serial Number_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |If you have upgraded from an earlier version of the plugin, any existing eInk Kindle serial numbers will have been automatically imported, so you might not need to do any more configuration.
23 | 24 |Please note that Kindle serial numbers are only valid keys for eInk Kindles like the Kindle Touch and PaperWhite. The Kindle Fire and Fire HD do not use their serial number for DRM and it is useless to enter those serial numbers.
25 | 26 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog for entering a new Kindle serial number.
29 |Click the OK button to save the serial number. Or Cancel if you didn’t want to enter a serial number.
34 | 35 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted Kindle serial number from the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
38 | 39 |Once done creating/deleting serial numbers, click Close to exit the customization dialogue. Your changes will only be saved permanently when you click OK in the main configuration dialog.
40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |This plugin removes DRM from ebooks when they are imported into calibre. If you already have DRMed ebooks in your calibre library, you will need to remove them and import them again.
23 | 24 |It is a forked version created by NoDRM, based on the original plugin by Apprentice Alf and Apprentice Harper.
25 | 26 |You have obviously managed to install the plugin, as otherwise you wouldn’t be reading this help file. However, you should also delete any older DRM removal plugins, as this DeDRM plugin replaces the five older plugins: Kindle and Mobipocket DeDRM (K4MobiDeDRM), Ignoble Epub DeDRM (ignobleepub), Inept Epub DeDRM (ineptepub), Inept PDF DeDRM (ineptepub) and eReader PDB 2 PML (eReaderPDB2PML).
28 | 29 |This plugin (in versions v10.0.0 and above) will automatically replace the older 7.X and below versions from Apprentice Alf and Apprentice Harper.
30 | 31 |On Windows and Mac, the keys for ebooks downloaded for Kindle for Mac/PC and Adobe Digital Editions are automatically generated. If all your DRMed ebooks can be opened and read in Kindle for Mac/PC and/or Adobe Digital Editions on the same computer on which you are running calibre, you do not need to do any configuration of this plugin. On Linux, keys for Kindle for PC and Adobe Digital Editions need to be generated separately (see the Linux section below).
33 | 34 |If you are using the DeACSM / ACSM Input Plugin for Calibre, the keys will also automatically be dumped for you.
35 | 36 |If you have other DRMed ebooks, you will need to enter extra configuration information. The buttons in this dialog will open individual configuration dialogs that will allow you to enter the needed information, depending on the type and source of your DRMed eBooks. Additional help on the information required is available in each of the the dialogs.
37 | 38 |If you have used previous versions of the various DeDRM plugins on this machine, you may find that some of the configuration dialogs already contain the information you entered through those previous plugins.
39 | 40 |When you have finished entering your configuration information, you must click the OK button to save it. If you click the Cancel button, all your changes in all the configuration dialogs will be lost.
41 | 42 |If you find that it’s not working for you , you can save a lot of time by trying to add the ebook to Calibre in debug mode. This will print out a lot of helpful info that can be copied into any online help requests.
45 | 46 |Open a command prompt (terminal window) and type "calibre-debug -g" (without the quotes). Calibre will launch, and you can can add the problem ebook the usual way. The debug info will be output to the original command prompt (terminal window). Copy the resulting output and paste it into the comment you make at my blog.
47 |Note: The Mac version of Calibre doesn’t install the command line tools by default. If you go to the ‘Preferences’ page and click on the miscellaneous button, you’ll find the option to install the command line tools.
48 | 49 |If you install Kindle for PC and/or Adobe Digital Editions in Wine, you will be able to download DRMed ebooks to them under Wine. To be able to remove the DRM, you will need to generate key files and add them in the plugin's customisation dialogs.
71 | 72 |To generate the key files you will need to install Python and PyCrypto under the same Wine setup as your Kindle for PC and/or Adobe Digital Editions installations. (Kindle for PC, Python and Pycrypto installation instructions in the ReadMe.)
73 | 74 |Once everything's installed under Wine, you'll need to run the adobekey.pyw script (for Adobe Digital Editions) and kindlekey.pyw (For Kindle for PC) using the python installation in your Wine system. The scripts can be found in Other_Tools/Key_Retrieval_Scripts.
75 | 76 |Each script will create a key file in the same folder as the script. Copy the key files to your Linux system and then load the key files using the Adobe Digital Editions ebooks dialog and the Kindle for Mac/PC ebooks dialog.
77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_Kindle for Android Key_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |Amazon's Kindle for Android application uses an internal key equivalent to an eInk Kindle's serial number. Extracting that key is a little tricky, but worth it, as it then allows the DRM to be removed from any Kindle ebooks that have been downloaded to that Android device.
23 | 24 |Please note that it is not currently known whether the same applies to the Kindle application on the Kindle Fire and Fire HD.
25 | 26 |Obtain and install adb (Android Debug Bridge) on your computer. Details of how to do this are beyond the scope of this help file, but there are plenty of on-line guides.
29 |Enable developer mode on your Android device. Again, look for an on-line guide for your device.
30 |Once you have adb installed and your device in developer mode, connect your device to your computer with a USB cable and then open up a command line (Terminal on Mac OS X and cmd.exe on Windows) and enter "adb backup com.amazon.kindle" (without the quotation marks!) and press return. A file "backup.ab" should be created in your home directory. 31 | 32 |
On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog with two main controls. 35 |
Click the OK button to store the Kindle for Android key for the current list of Kindle for Android keys. Or click Cancel if you don’t want to store the key.
41 |New keys are checked against the current list of keys before being added, and duplicates are discarded.
42 | 43 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted key in the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
46 | 47 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a sheet of paper. Clicking this button will prompt you to enter a new name for the highlighted key in the list. Enter the new name for the key and click the OK button to use the new name, or Cancel to revert to the old name.
50 | 51 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a computer’s hard-drive. Use this button to export the highlighted key to a file (with a ‘.k4a' file name extension). Used for backup purposes or to migrate key data to other computers/calibre installations. The dialog will prompt you for a place to save the file.
54 | 55 |At the bottom-left of the plugin’s customization dialog, you will see a button labeled "Import Existing Keyfiles". Use this button to import any ‘.k4a’ file you obtained by using the androidkindlekey.py script manually, or by exporting from another copy of calibre.
58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_Kindle for Mac and PC Key_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |If you have upgraded from an earlier version of the plugin, any existing Kindle for Mac/PC keys will have been automatically imported, so you might not need to do any more configuration. In addition, on Windows and Mac, the default Kindle for Mac/PC key is added the first time the plugin is run. Continue reading for key generation and management instructions.
24 | 25 |Note that for best results, you should run Calibre / this plugin on the same machine where Kindle 4 PC / Kindle 4 Mac is running. It is possible to export/import the keys to another machine, but this may not always work, particularly with the newer DRM versions.
26 | 27 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog prompting you to enter a key name for the default Kindle for Mac/PC key.
30 |Click the OK button to create and store the Kindle for Mac/PC key for the current installation of Kindle for Mac/PC. Or Cancel if you don’t want to create the key.
35 |New keys are checked against the current list of keys before being added, and duplicates are discarded.
36 | 37 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted key in the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
40 | 41 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a sheet of paper. Clicking this button will prompt you to enter a new name for the highlighted key in the list. Enter the new name for the encryption key and click the OK button to use the new name, or Cancel to revert to the old name..
44 | 45 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a computer’s hard-drive. Use this button to export the highlighted key to a file (with a ‘.der’ file name extension). Used for backup purposes or to migrate key data to other computers/calibre installations. The dialog will prompt you for a place to save the file.
48 | 49 |Under the list of keys, Linux users will see a text field labeled "WINEPREFIX". If you are using the Kindle for PC under Wine, and your wine installation containing Kindle for PC isn't the default Wine installation, you may enter the full path to the correct Wine installation here. Leave blank if you are unsure.
52 | 53 |At the bottom-left of the plugin’s customization dialog, you will see a button labeled "Import Existing Keyfiles". Use this button to import existing ‘.k4i’ key files. Key files might come from being exported from this plugin, or may have been generated using the kindlekey.pyw script running under Wine on Linux systems.
56 | 57 |Once done creating/deleting/renaming/importing decryption keys, click Close to exit the customization dialogue. Your changes wil only be saved permanently when you click OK in the main configuration dialog.
58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_Mobipocket PID_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |If you have upgraded from an earlier version of the plugin, any existing Mobipocket PIDs will have been automatically imported, so you might not need to do any more configuration.
23 | 24 | 25 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog for entering a new Mobipocket PID.
28 |Click the OK button to save the PID. Or Cancel if you didn’t want to enter a PID.
33 | 34 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted Mobipocket PID from the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
37 | 38 |Once done creating/deleting PIDs, click Close to exit the customization dialogue. Your changes will only be saved permanently when you click OK in the main configuration dialog.
39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_PDF passphrase_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |PDF files can be protected with a password / passphrase that will be required to open the PDF file. Enter your passphrases in the plugin settings to have the plugin automatically remove this encryption / restriction from PDF files you import.
23 | 24 | 25 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog for entering a new passphrase.
28 | 29 |Just enter your passphrase for the PDF file, then click the OK button to save the passphrase.
30 | 31 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted passphrase from the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
34 | 35 |Once done entering/deleting passphrases, click Close to exit the customization dialogue. Your changes will only be saved permanently when you click OK in the main configuration dialog.
36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_Readium LCP passphrase_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |Readium LCP is a relatively new eBook DRM. It's also known under the names "CARE DRM" or "TEA DRM". It does not rely on any accounts or key data that's difficult to acquire. All you need to open (or decrypt) LCP eBooks is the account passphrase given to you by the eBook provider - the very same passphrase you'd have to enter into your eBook reader device (once) to read LCP-encrypted books.
23 | 24 |This plugin no longer supports removing the Readium LCP DRM due to a DMCA takedown request issued by Readium. Please read the takedown notice or this bug report for more information.
25 | 26 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog for entering a new passphrase.
29 | 30 |Just enter your passphrase as provided with the book, then click the OK button to save the passphrase.
31 | 32 |Usually, passphrases are identical for all books bought with the same account. So if you buy multiple LCP-protected eBooks, they'll usually all have the same passphrase if they've all been bought at the same store with the same account.
33 | 34 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted passphrase from the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
37 | 38 |Once done entering/deleting passphrases, click Close to exit the customization dialogue. Your changes will only be saved permanently when you click OK in the main configuration dialog.
39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /DeDRM_plugin/DeDRM_eReader Key_Help.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 |If you have upgraded from an earlier version of the plugin, any existing eReader (Fictionwise ‘.pdb’) keys will have been automatically imported, so you might not need to do any more configuration. Continue reading for key generation and management instructions.
23 | 24 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a green plus sign (+). Clicking this button will open a new dialog for entering the necessary data to generate a new key.
27 |Click the OK button to create and store the generated key. Or Cancel if you don’t want to create a key.
34 |New keys are checked against the current list of keys before being added, and duplicates are discarded.
35 | 36 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a red "X". Clicking this button will delete the highlighted key in the list. You will be prompted once to be sure that’s what you truly mean to do. Once gone, it’s permanently gone.
39 | 40 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a sheet of paper. Clicking this button will promt you to enter a new name for the highlighted key in the list. Enter the new name for the encryption key and click the OK button to use the new name, or Cancel to revert to the old name..
43 | 44 |On the right-hand side of the plugin’s customization dialog, you will see a button with an icon that looks like a computer’s hard-drive. Use this button to export the highlighted key to a file (with a ‘.b63’ file name extension). Used for backup purposes or to migrate key data to other computers/calibre installations. The dialog will prompt you for a place to save the file.
47 | 48 |At the bottom-left of the plugin’s customization dialog, you will see a button labeled "Import Existing Keyfiles". Use this button to import existing ‘.b63’ key files that have previously been exported.
51 | 52 |Once done creating/deleting/renaming/importing decryption keys, click Close to exit the customization dialogue. Your changes wil only be saved permanently when you click OK in the main configuration dialog.
53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /DeDRM_plugin/__calibre_compat_code.py: -------------------------------------------------------------------------------- 1 | 2 | #@@CALIBRE_COMPAT_CODE_START@@ 3 | import sys, os 4 | 5 | # Explicitly allow importing everything ... 6 | if os.path.dirname(os.path.dirname(os.path.abspath(__file__))) not in sys.path: 7 | sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 8 | if os.path.dirname(os.path.abspath(__file__)) not in sys.path: 9 | sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) 10 | 11 | # Bugfix for Calibre < 5: 12 | if "calibre" in sys.modules and sys.version_info[0] == 2: 13 | from calibre.utils.config import config_dir 14 | if os.path.join(config_dir, "plugins", "DeDRM.zip") not in sys.path: 15 | sys.path.insert(0, os.path.join(config_dir, "plugins", "DeDRM.zip")) 16 | 17 | if "calibre" in sys.modules: 18 | # Explicitly set the package identifier so we are allowed to import stuff ... 19 | __package__ = "calibre_plugins.dedrm" 20 | 21 | #@@CALIBRE_COMPAT_CODE_END@@ 22 | -------------------------------------------------------------------------------- /DeDRM_plugin/__main__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # __main__.py for DeDRM_plugin 5 | # (CLI interface without Calibre) 6 | # Copyright © 2021 NoDRM 7 | 8 | """ 9 | 10 | NOTE: This code is not functional (yet). I started working on it a while ago 11 | to make a standalone version of the plugins that could work without Calibre, 12 | too, but for now there's only a rough code structure and no working code yet. 13 | 14 | Currently, to use these plugins, you will need to use Calibre. Hopwfully that'll 15 | change in the future. 16 | 17 | """ 18 | 19 | __license__ = 'GPL v3' 20 | __docformat__ = 'restructuredtext en' 21 | 22 | # For revision history see CHANGELOG.md 23 | 24 | """ 25 | Run DeDRM plugin without Calibre. 26 | """ 27 | 28 | # Import __init__.py from the standalone folder so we can have all the 29 | # standalone / non-Calibre code in that subfolder. 30 | 31 | import standalone.__init__ as mdata 32 | import sys 33 | 34 | mdata.main(sys.argv) -------------------------------------------------------------------------------- /DeDRM_plugin/__version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | #@@CALIBRE_COMPAT_CODE@@ 5 | 6 | PLUGIN_NAME = "DeDRM" 7 | __version__ = '10.0.9' 8 | 9 | PLUGIN_VERSION_TUPLE = tuple([int(x) for x in __version__.split(".")]) 10 | PLUGIN_VERSION = ".".join([str(x)for x in PLUGIN_VERSION_TUPLE]) 11 | # Include an html helpfile in the plugin's zipfile with the following name. 12 | RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' -------------------------------------------------------------------------------- /DeDRM_plugin/adobekey_get_passhash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # adobekey_get_passhash.py, version 1 5 | # based on adobekey.pyw, version 7.2 6 | # Copyright © 2009-2021 i♥cabbages, Apprentice Harper et al. 7 | # Copyright © 2021 noDRM 8 | 9 | # Released under the terms of the GNU General Public Licence, version 3 10 | #The ususal method of Preferences -> Plugins -> Load plugin from file.
16 | 17 | 18 |There is no configuration (other than to choose what menus to add obok to)
21 | 22 | 23 |If you find that it’s not working for you, you can save a lot of time by using the plugin with Calibre in debug mode. This will print out a lot of helpful info that can be copied into any online help requests.
26 | 27 |Open a command prompt (terminal window) and type "calibre-debug -g" (without the quotes). Calibre will launch, and you can use the plugin the usual way. The debug info will be output to the original command prompt (terminal window). Copy the resulting output and paste it into the comment you make at Apprentice Alf's blog.
28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Obok_plugin/plugin-import-name-obok_dedrm.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noDRM/DeDRM_tools/7379b453199ed1ba91bf3a4ce4875d5ed3c309a9/Obok_plugin/plugin-import-name-obok_dedrm.txt -------------------------------------------------------------------------------- /Obok_plugin/translations/ar.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noDRM/DeDRM_tools/7379b453199ed1ba91bf3a4ce4875d5ed3c309a9/Obok_plugin/translations/ar.mo -------------------------------------------------------------------------------- /Obok_plugin/translations/de.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noDRM/DeDRM_tools/7379b453199ed1ba91bf3a4ce4875d5ed3c309a9/Obok_plugin/translations/de.mo -------------------------------------------------------------------------------- /Obok_plugin/translations/de.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHORDefault behavior when duplicates are detected. None of the choices will " 43 | "cause calibre ebooks to be overwritten" 44 | msgstr "" 45 | "
Standardverhalten, wenn Duplikate erkannt werden. Keine der "
46 | "Entscheidungen werden ebooks verursachen das sie überschrieben werden."
47 |
48 | #: dialogs.py:58
49 | msgid "Obok DeDRM"
50 | msgstr "Obok DeDRM"
51 |
52 | #: dialogs.py:68
53 | msgid "Help"
54 | msgstr "Hilfe"
55 |
56 | #: dialogs.py:82
57 | msgid "Select All"
58 | msgstr "Alles markieren"
59 |
60 | #: dialogs.py:83
61 | msgid "Select all books to add them to the calibre library."
62 | msgstr "Wählen Sie alle Bücher, um sie zu Calibre Bibliothek hinzuzufügen."
63 |
64 | #: dialogs.py:85
65 | msgid "All with DRM"
66 | msgstr "Alle mit DRM"
67 |
68 | #: dialogs.py:86
69 | msgid "Select all books with DRM."
70 | msgstr "Wählen Sie alle Bücher mit DRM."
71 |
72 | #: dialogs.py:88
73 | msgid "All DRM free"
74 | msgstr "Alle ohne DRM"
75 |
76 | #: dialogs.py:89
77 | msgid "Select all books without DRM."
78 | msgstr "Wählen Sie alle Bücher ohne DRM."
79 |
80 | #: dialogs.py:139
81 | msgid "Title"
82 | msgstr "Titel"
83 |
84 | #: dialogs.py:139
85 | msgid "Author"
86 | msgstr "Autor"
87 |
88 | #: dialogs.py:139
89 | msgid "Series"
90 | msgstr "Reihe"
91 |
92 | #: dialogs.py:362
93 | msgid "Copy to clipboard"
94 | msgstr "In Zwischenablage kopieren"
95 |
96 | #: dialogs.py:390
97 | msgid "View Report"
98 | msgstr "Bericht anzeigen"
99 |
100 | #: __init__.py:24
101 | msgid "Removes DRM from Kobo kepubs and adds them to the library."
102 | msgstr "Entfernt DRM von Kobo kepubs und fügt sie zu Bibliothek hinzu."
103 |
--------------------------------------------------------------------------------
/Obok_plugin/translations/es.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noDRM/DeDRM_tools/7379b453199ed1ba91bf3a4ce4875d5ed3c309a9/Obok_plugin/translations/es.mo
--------------------------------------------------------------------------------
/Obok_plugin/translations/nl.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noDRM/DeDRM_tools/7379b453199ed1ba91bf3a4ce4875d5ed3c309a9/Obok_plugin/translations/nl.mo
--------------------------------------------------------------------------------
/Obok_plugin/translations/nl.po:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the PACKAGE package.
4 | # FIRST AUTHOR Default behavior when duplicates are detected. None of the choices will "
43 | "cause calibre ebooks to be overwritten"
44 | msgstr ""
45 | " Standaard gedrag wanneer er duplicaten worden geconstateerd. Geen van de "
46 | "opties zal reeds bestaande ebooks in de Calibre bibliotheek overschrijven."
47 |
48 | #: dialogs.py:58
49 | msgid "Obok DeDRM"
50 | msgstr "Obok DeDRM"
51 |
52 | #: dialogs.py:68
53 | msgid "Help"
54 | msgstr "Help"
55 |
56 | #: dialogs.py:82
57 | msgid "Select All"
58 | msgstr "Alles selecteren"
59 |
60 | #: dialogs.py:83
61 | msgid "Select all books to add them to the calibre library."
62 | msgstr "Alle boeken selecteren om ze aan de Calibre bibliotheek toe te voegen."
63 |
64 | #: dialogs.py:85
65 | msgid "All with DRM"
66 | msgstr "Alle met DRM"
67 |
68 | #: dialogs.py:86
69 | msgid "Select all books with DRM."
70 | msgstr "Alle boeken met DRM selecteren."
71 |
72 | #: dialogs.py:88
73 | msgid "All DRM free"
74 | msgstr "Alle zonder DRM"
75 |
76 | #: dialogs.py:89
77 | msgid "Select all books without DRM."
78 | msgstr "Alle boeken zonder DRM selecteren."
79 |
80 | #: dialogs.py:139
81 | msgid "Title"
82 | msgstr "Titel"
83 |
84 | #: dialogs.py:139
85 | msgid "Author"
86 | msgstr "Auteur"
87 |
88 | #: dialogs.py:139
89 | msgid "Series"
90 | msgstr "Reeks/serie"
91 |
92 | #: dialogs.py:362
93 | msgid "Copy to clipboard"
94 | msgstr "Naar het Klembord kopiëren"
95 |
96 | #: dialogs.py:390
97 | msgid "View Report"
98 | msgstr "Rapport weergeven"
99 |
100 | #: __init__.py:24
101 | msgid "Removes DRM from Kobo kepubs and adds them to the library."
102 | msgstr "Verwijdert de DRM van Kobo kepubs en voegt ze toe aan de bibliotheek."
103 |
--------------------------------------------------------------------------------
/Obok_plugin/translations/pt.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noDRM/DeDRM_tools/7379b453199ed1ba91bf3a4ce4875d5ed3c309a9/Obok_plugin/translations/pt.mo
--------------------------------------------------------------------------------
/Obok_plugin/translations/sv.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noDRM/DeDRM_tools/7379b453199ed1ba91bf3a4ce4875d5ed3c309a9/Obok_plugin/translations/sv.mo
--------------------------------------------------------------------------------
/Obok_plugin/utilities.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
4 |
5 | __license__ = 'GPL v3'
6 | __docformat__ = 'restructuredtext en'
7 |
8 |
9 | import os, struct, time
10 | try:
11 | from StringIO import StringIO
12 | except ImportError:
13 | from io import StringIO
14 | from traceback import print_exc
15 |
16 | from PyQt5.Qt import (Qt, QDialog, QPixmap, QIcon, QLabel, QHBoxLayout, QFont, QTableWidgetItem)
17 |
18 | from calibre.utils.config import config_dir
19 | from calibre.constants import iswindows, DEBUG
20 | from calibre import prints
21 | from calibre.gui2 import (error_dialog, gprefs)
22 | from calibre.gui2.actions import menu_action_unique_name
23 |
24 | from calibre_plugins.obok_dedrm.__init__ import (PLUGIN_NAME,
25 | PLUGIN_SAFE_NAME, PLUGIN_VERSION, PLUGIN_DESCRIPTION)
26 |
27 | plugin_ID = None
28 | plugin_icon_resources = {}
29 |
30 | try:
31 | from calibre.gui2 import QVariant
32 | del QVariant
33 | except ImportError:
34 | is_qt4 = False
35 | convert_qvariant = lambda x: x
36 | else:
37 | is_qt4 = True
38 |
39 | def convert_qvariant(x):
40 | vt = x.type()
41 | if vt == x.String:
42 | return x.toString()
43 | if vt == x.List:
44 | return [convert_qvariant(i) for i in x.toList()]
45 | return x.toPyObject()
46 |
47 | BASE_TIME = None
48 | def debug_print(*args):
49 | global BASE_TIME
50 | if BASE_TIME is None:
51 | BASE_TIME = time.time()
52 | if DEBUG:
53 | prints('DEBUG: %6.1f'%(time.time()-BASE_TIME), *args)
54 |
55 | try:
56 | debug_print("obok::utilities.py - loading translations")
57 | load_translations()
58 | except NameError:
59 | debug_print("obok::utilities.py - exception when loading translations")
60 | pass # load_translations() added in calibre 1.9
61 |
62 | def format_plural(number, possessive=False):
63 | '''
64 | Cosmetic ditty to provide the proper string formatting variable to handle singular/plural situations
65 |
66 | :param: number: variable that represents the count/len of something
67 | '''
68 | if not possessive:
69 | return '' if number == 1 else 's'
70 | return '\'s' if number == 1 else 's\''
71 |
72 |
73 | def set_plugin_icon_resources(name, resources):
74 | '''
75 | Set our global store of plugin name and icon resources for sharing between
76 | the InterfaceAction class which reads them and the ConfigWidget
77 | if needed for use on the customization dialog for this plugin.
78 | '''
79 | global plugin_icon_resources, plugin_ID
80 | plugin_ID = name
81 | plugin_icon_resources = resources
82 |
83 | def get_icon(icon_name):
84 | '''
85 | Retrieve a QIcon for the named image from the zip file if it exists,
86 | or if not then from Calibre's image cache.
87 | '''
88 | if icon_name:
89 | pixmap = get_pixmap(icon_name)
90 | if pixmap is None:
91 | # Look in Calibre's cache for the icon
92 | return QIcon(I(icon_name))
93 | else:
94 | return QIcon(pixmap)
95 | return QIcon()
96 |
97 | def get_pixmap(icon_name):
98 | '''
99 | Retrieve a QPixmap for the named image
100 | Any icons belonging to the plugin must be prefixed with 'images/'
101 | '''
102 | if not icon_name.startswith('images/'):
103 | # We know this is definitely not an icon belonging to this plugin
104 | pixmap = QPixmap()
105 | pixmap.load(I(icon_name))
106 | return pixmap
107 |
108 | # Check to see whether the icon exists as a Calibre resource
109 | # This will enable skinning if the user stores icons within a folder like:
110 | # ...\AppData\Roaming\calibre\resources\images\Plugin Name\
111 | if plugin_ID:
112 | local_images_dir = get_local_images_dir(plugin_ID)
113 | local_image_path = os.path.join(local_images_dir, icon_name.replace('images/', ''))
114 | if os.path.exists(local_image_path):
115 | pixmap = QPixmap()
116 | pixmap.load(local_image_path)
117 | return pixmap
118 |
119 | # As we did not find an icon elsewhere, look within our zip resources
120 | if icon_name in plugin_icon_resources:
121 | pixmap = QPixmap()
122 | pixmap.loadFromData(plugin_icon_resources[icon_name])
123 | return pixmap
124 | return None
125 |
126 | def get_local_images_dir(subfolder=None):
127 | '''
128 | Returns a path to the user's local resources/images folder
129 | If a subfolder name parameter is specified, appends this to the path
130 | '''
131 | images_dir = os.path.join(config_dir, 'resources/images')
132 | if subfolder:
133 | images_dir = os.path.join(images_dir, subfolder)
134 | if iswindows:
135 | images_dir = os.path.normpath(images_dir)
136 | return images_dir
137 |
138 | def showErrorDlg(errmsg, parent, trcbk=False):
139 | '''
140 | Wrapper method for calibre's error_dialog
141 | '''
142 | if trcbk:
143 | error= ''
144 | f=StringIO()
145 | print_exc(file=f)
146 | error_mess = f.getvalue().splitlines()
147 | for line in error_mess:
148 | error = error + str(line) + '\n'
149 | errmsg = errmsg + '\n\n' + error
150 | return error_dialog(parent, _(PLUGIN_NAME + ' v' + PLUGIN_VERSION),
151 | _(errmsg), show=True)
152 |
153 | class SizePersistedDialog(QDialog):
154 | '''
155 | This dialog is a base class for any dialogs that want their size/position
156 | restored when they are next opened.
157 | '''
158 | def __init__(self, parent, unique_pref_name):
159 | QDialog.__init__(self, parent)
160 | self.unique_pref_name = unique_pref_name
161 | self.geom = gprefs.get(unique_pref_name, None)
162 | self.finished.connect(self.dialog_closing)
163 |
164 | def resize_dialog(self):
165 | if self.geom is None:
166 | self.resize(self.sizeHint())
167 | else:
168 | self.restoreGeometry(self.geom)
169 |
170 | def dialog_closing(self, result):
171 | geom = bytearray(self.saveGeometry())
172 | gprefs[self.unique_pref_name] = geom
173 | self.persist_custom_prefs()
174 |
175 | def persist_custom_prefs(self):
176 | '''
177 | Invoked when the dialog is closing. Override this function to call
178 | save_custom_pref() if you have a setting you want persisted that you can
179 | retrieve in your __init__() using load_custom_pref() when next opened
180 | '''
181 | pass
182 |
183 | def load_custom_pref(self, name, default=None):
184 | return gprefs.get(self.unique_pref_name+':'+name, default)
185 |
186 | def save_custom_pref(self, name, value):
187 | gprefs[self.unique_pref_name+':'+name] = value
188 |
189 | class ImageTitleLayout(QHBoxLayout):
190 | '''
191 | A reusable layout widget displaying an image followed by a title
192 | '''
193 | def __init__(self, parent, icon_name, title):
194 | '''
195 | :param parent: Parent gui
196 | :param icon_name: Path to plugin image resource
197 | :param title: String to be displayed beside the image
198 | '''
199 | QHBoxLayout.__init__(self)
200 | self.title_image_label = QLabel(parent)
201 | self.update_title_icon(icon_name)
202 | self.addWidget(self.title_image_label)
203 |
204 | title_font = QFont()
205 | title_font.setPointSize(16)
206 | shelf_label = QLabel(title, parent)
207 | shelf_label.setFont(title_font)
208 | self.addWidget(shelf_label)
209 | self.insertStretch(-1)
210 |
211 | def update_title_icon(self, icon_name):
212 | pixmap = get_pixmap(icon_name)
213 | if pixmap is None:
214 | error_dialog(self.parent(), _('Restart required'),
215 | _('Title image not found - you must restart Calibre before using this plugin!'), show=True)
216 | else:
217 | self.title_image_label.setPixmap(pixmap)
218 | self.title_image_label.setMaximumSize(32, 32)
219 | self.title_image_label.setScaledContents(True)
220 |
221 |
222 | class ReadOnlyTableWidgetItem(QTableWidgetItem):
223 |
224 | def __init__(self, text):
225 | if text is None:
226 | text = ''
227 | QTableWidgetItem.__init__(self, text, QTableWidgetItem.ItemType.UserType)
228 | self.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
229 |
--------------------------------------------------------------------------------
/Other_Tools/B_and_N_Download_Helper/BN-Dload.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name BN-Dload
3 | // @namespace http://www.mailinator.com/J-man
4 | // @include https://mynook.barnesandnoble.com/library.html*
5 | // @grant none
6 | // @version 20121119
7 | // ==/UserScript==
8 |
9 | function doIt() {
10 | if ($('#adl1').length == 0) {
11 | $('[action$="deleteItem"]').each(function(index) {
12 | if ($(this).parent().find('[action$="EDSDeliverItem.aspx"]').length == 0) {
13 | var delid = $(this).find('input').attr('value');
14 | $(this).after('