vivier / phomemo-tools Goto Github PK
View Code? Open in Web Editor NEWCUPS driver for Phomemo M02 Label Printer
License: GNU General Public License v3.0
CUPS driver for Phomemo M02 Label Printer
License: GNU General Public License v3.0
Hello! Thank you so much for this repo. I'm trying to use it with my M02 pro.
The test page sort of prints, but only 1.5cm and then it stops. Any tips on how to add this version? If you point me in the right direction I can maybe try to contribute. <3
I acquired a little T02, hoping to replace my large thermal printer with it. I assumed from this repo that I would be able to use it, however it appears this may not be the case.
I have Ubuntu 22.04, and have cups, pybluez already installed on my system, no problems. Made and installed the cups driver from this repo, then went and paired the T02 device in bluetooth settings. But when I get to the Printer window, there is no T02 to be seen. I confirm the Phomemo driver is installed, as I can add a CUPS-BRK driver using the Phomemo M02 template, and tried to print to the T02 using that, but every time I print, it says it printed successfully then nothing at all happens.
Either I set up something wrongly, or the T02 is not supported?
Confirmed I have the prequisites;
cups is already the newest version (2.4.1op1-1ubuntu4.7).
Requirement already satisfied: pybluez in /usr/lib/python3/dist-packages (0.23)
The T02 does not show up in the printer devices when I try to add it here, as per the instructions;
So I tried to manually add it anyway, by creating a generic CUPS-BRF driver for M02 and named it T02;
This is the added printer info from localhost:631 CUPS interface;
Here is my cups access log;
localhost - - [03/Nov/2023:00:00:02 +0000] "POST / HTTP/1.1" 200 349 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:00:02 +0000] "POST / HTTP/1.1" 200 176 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:02:34 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:04:49 +0000] "POST / HTTP/1.1" 200 276 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:04:52 +0000] "POST / HTTP/1.1" 401 147 CUPS-Get-Devices successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:04:52 +0000] "POST / HTTP/1.1" 200 1549 CUPS-Get-Devices -
localhost - cups-pk-helper [03/Nov/2023:00:04:52 +0000] "POST / HTTP/1.1" 200 222 CUPS-Get-Devices -
localhost - - [03/Nov/2023:00:05:54 +0000] "POST / HTTP/1.1" 401 147 CUPS-Get-Devices successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:05:54 +0000] "POST / HTTP/1.1" 200 1549 CUPS-Get-Devices -
localhost - cups-pk-helper [03/Nov/2023:00:05:54 +0000] "POST / HTTP/1.1" 200 222 CUPS-Get-Devices -
localhost - - [03/Nov/2023:00:06:26 +0000] "GET /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - stubkan [03/Nov/2023:00:06:26 +0000] "GET /admin/conf/cupsd.conf HTTP/1.1" 200 4690 - -
localhost - - [03/Nov/2023:00:06:26 +0000] "GET /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - cups-pk-helper [03/Nov/2023:00:06:26 +0000] "GET /admin/conf/cupsd.conf HTTP/1.1" 200 4690 - -
localhost - - [03/Nov/2023:00:07:47 +0000] "POST / HTTP/1.1" 401 147 CUPS-Get-Devices successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:07:47 +0000] "POST / HTTP/1.1" 200 1549 CUPS-Get-Devices -
localhost - cups-pk-helper [03/Nov/2023:00:07:47 +0000] "POST / HTTP/1.1" 200 222 CUPS-Get-Devices -
localhost - cups-pk-helper [03/Nov/2023:00:07:52 +0000] "POST / HTTP/1.1" 200 1549 CUPS-Get-Devices -
localhost - cups-pk-helper [03/Nov/2023:00:07:52 +0000] "POST / HTTP/1.1" 200 222 CUPS-Get-Devices -
localhost - - [03/Nov/2023:00:07:53 +0000] "POST / HTTP/1.1" 200 5462486 CUPS-Get-PPDs -
localhost - - [03/Nov/2023:00:08:10 +0000] "POST / HTTP/1.1" 200 8498 CUPS-Get-PPD -
localhost - - [03/Nov/2023:00:08:41 +0000] "POST /admin/ HTTP/1.1" 401 8549 CUPS-Add-Modify-Printer successful-ok
localhost - stubkan [03/Nov/2023:00:08:41 +0000] "POST /admin/ HTTP/1.1" 200 8549 CUPS-Add-Modify-Printer successful-ok
localhost - - [03/Nov/2023:00:08:41 +0000] "POST /admin/ HTTP/1.1" 401 166 Resume-Printer successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:08:41 +0000] "POST /admin/ HTTP/1.1" 200 166 Resume-Printer successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:08:41 +0000] "POST /admin/ HTTP/1.1" 200 166 CUPS-Accept-Jobs successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:08:41 +0000] "POST /admin/ HTTP/1.1" 200 166 CUPS-Set-Default successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:08:41 +0000] "POST /admin/ HTTP/1.1" 200 188 CUPS-Add-Modify-Printer successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:08:41 +0000] "POST /admin/ HTTP/1.1" 200 203 CUPS-Add-Modify-Printer successful-ok
localhost - - [03/Nov/2023:00:08:44 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 415 Print-Job successful-ok
localhost - - [03/Nov/2023:00:08:44 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:11:46 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:11:46 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:17:02 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 316 Create-Job successful-ok
localhost - - [03/Nov/2023:00:17:02 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 274339 Send-Document successful-ok
localhost - - [03/Nov/2023:00:18:33 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 316 Create-Job successful-ok
localhost - - [03/Nov/2023:00:18:33 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 274336 Send-Document successful-ok
localhost - - [03/Nov/2023:00:22:23 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 316 Create-Job successful-ok
localhost - - [03/Nov/2023:00:22:23 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 274336 Send-Document successful-ok
localhost - - [03/Nov/2023:00:24:01 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:24:01 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:24:01 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:24:01 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:24:22 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:24:22 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:24:22 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:24:22 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:24:34 +0000] "POST /jobs/ HTTP/1.1" 200 142 Restart-Job successful-ok
localhost - - [03/Nov/2023:00:25:20 +0000] "POST /jobs/ HTTP/1.1" 200 157 Cancel-Job successful-ok
localhost - - [03/Nov/2023:00:25:27 +0000] "POST /jobs/ HTTP/1.1" 200 157 Cancel-Job successful-ok
localhost - - [03/Nov/2023:00:25:32 +0000] "POST /jobs/ HTTP/1.1" 200 157 Cancel-Job successful-ok
localhost - - [03/Nov/2023:00:25:53 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:25:53 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:25:53 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:25:53 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:25:54 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:25:54 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:25:54 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:25:54 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:25:54 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:25:54 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:25:54 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:25:54 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:25:59 +0000] "POST /jobs/ HTTP/1.1" 200 157 Cancel-Job successful-ok
localhost - - [03/Nov/2023:00:26:00 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:26:00 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:26:00 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:26:00 +0000] "POST / HTTP/1.1" 200 365 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:27:42 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 316 Create-Job successful-ok
localhost - - [03/Nov/2023:00:27:42 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 367503 Send-Document successful-ok
localhost - - [03/Nov/2023:00:27:54 +0000] "POST / HTTP/1.1" 200 276 Create-Printer-Subscriptions successful-ok
localhost - - [03/Nov/2023:00:27:56 +0000] "POST / HTTP/1.1" 401 147 CUPS-Get-Devices successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:27:56 +0000] "POST / HTTP/1.1" 200 1549 CUPS-Get-Devices -
localhost - cups-pk-helper [03/Nov/2023:00:27:56 +0000] "POST / HTTP/1.1" 200 222 CUPS-Get-Devices -
localhost - - [03/Nov/2023:00:34:00 +0000] "POST /printers/Phomemo-T02 HTTP/1.1" 200 415 Print-Job successful-ok
localhost - - [03/Nov/2023:00:35:48 +0000] "POST /admin/ HTTP/1.1" 200 66 - -
localhost - - [03/Nov/2023:00:35:48 +0000] "POST / HTTP/1.1" 401 75 CUPS-Get-Devices successful-ok
localhost - - [03/Nov/2023:00:35:48 +0000] "POST /admin/ HTTP/1.1" 200 1909 - -
localhost - - [03/Nov/2023:00:35:53 +0000] "POST /admin/ HTTP/1.1" 200 60 - -
localhost - - [03/Nov/2023:00:35:53 +0000] "POST / HTTP/1.1" 401 91 CUPS-Get-Devices successful-ok
localhost - - [03/Nov/2023:00:35:53 +0000] "POST /admin/ HTTP/1.1" 401 60 - -
localhost - - [03/Nov/2023:00:35:53 +0000] "POST /admin/ HTTP/1.1" 200 60 - -
localhost - stubkan [03/Nov/2023:00:35:58 +0000] "POST /admin/ HTTP/1.1" 200 60 - -
localhost - - [03/Nov/2023:00:35:58 +0000] "POST / HTTP/1.1" 401 91 CUPS-Get-Devices successful-ok
localhost - stubkan [03/Nov/2023:00:35:58 +0000] "POST / HTTP/1.1" 200 1493 CUPS-Get-Devices -
localhost - stubkan [03/Nov/2023:00:35:58 +0000] "POST /admin/ HTTP/1.1" 200 3360 - -
localhost - - [03/Nov/2023:00:36:41 +0000] "POST / HTTP/1.1" 401 147 CUPS-Get-Devices successful-ok
localhost - cups-pk-helper [03/Nov/2023:00:36:41 +0000] "POST / HTTP/1.1" 200 1549 CUPS-Get-Devices -
localhost - cups-pk-helper [03/Nov/2023:00:36:41 +0000] "POST / HTTP/1.1" 200 222 CUPS-Get-Devices -
localhost - - [03/Nov/2023:00:36:49 +0000] "POST / HTTP/1.1" 200 155 Cancel-Subscription successful-ok
localhost - - [03/Nov/2023:00:43:29 +0000] "POST / HTTP/1.1" 200 186 Renew-Subscription successful-ok
and the error log with debug turned on
E [03/Nov/2023:00:00:02 +0000] Unknown directive JobPrivateAccess on line 122 of /etc/cups/cupsd.conf.
E [03/Nov/2023:00:00:02 +0000] Unknown directive JobPrivateValues on line 123 of /etc/cups/cupsd.conf.
E [03/Nov/2023:00:00:02 +0000] Unknown directive SubscriptionPrivateAccess on line 124 of /etc/cups/cupsd.conf.
E [03/Nov/2023:00:00:02 +0000] Unknown directive SubscriptionPrivateValues on line 125 of /etc/cups/cupsd.conf.
E [03/Nov/2023:00:04:52 +0000] [cups-deviced] PID 49458 (phomemo) stopped with status 1!
E [03/Nov/2023:00:05:54 +0000] [cups-deviced] PID 49520 (phomemo) stopped with status 1!
E [03/Nov/2023:00:07:47 +0000] [cups-deviced] PID 49654 (phomemo) stopped with status 1!
E [03/Nov/2023:00:07:52 +0000] [cups-deviced] PID 49688 (phomemo) stopped with status 1!
E [03/Nov/2023:00:27:56 +0000] [cups-deviced] PID 53476 (phomemo) stopped with status 1!
E [03/Nov/2023:00:35:59 +0000] [cups-deviced] PID 54411 (phomemo) stopped with status 1!
E [03/Nov/2023:00:36:41 +0000] [cups-deviced] PID 54489 (phomemo) stopped with status 1!
Thank you a lot for your work, which I'm going to use as a base for what I'm trying to do (I don't really want a CUPS driver, but I'm trying to make a command line program so I can run label "Some String"
and get exactly that printed on one of the 1/3 or 1/2 width sticky labels.
Anyway, I just bought a Phonemo M02S, and it seemed that I just wasn't able to print anything - until I realized the M02S has 512 pixels full width, instead of the 384 that the M02 seems to have.
When I changed the 0300 in the initialization code to 0400, and the 384 from the width adjuster to 512, printing on the 1/3 width label worked great.
Unfortunately, there doesn't seem to be an easy way to autodetect if you have a M02 or a M02s - the lsusb
has exactly the same device identifier:
Bus 001 Device 099: ID 0493:b002 MAG Technology Co., Ltd
and it doesn't look like the log from plugging the printer in has any useful distinction either:
Aug 27 15:35:11 natascha kernel: [862343.900189] usb 1-1.4.4: new full-speed USB device number 99 using xhci_hcd
Aug 27 15:35:12 natascha kernel: [862344.275498] usb 1-1.4.4: New USB device found, idVendor=0493, idProduct=b002, bcdDevice= 3.00
Aug 27 15:35:12 natascha kernel: [862344.275505] usb 1-1.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Aug 27 15:35:12 natascha kernel: [862344.275508] usb 1-1.4.4: Product: USB Virtual COM
Aug 27 15:35:12 natascha kernel: [862344.275510] usb 1-1.4.4: Manufacturer: Nuvoton
Aug 27 15:35:12 natascha kernel: [862344.275512] usb 1-1.4.4: SerialNumber: A02014090305
Aug 27 15:35:12 natascha kernel: [862344.334555] cdc_acm 1-1.4.4:1.0: ttyACM0: USB ACM device
Aug 27 15:35:12 natascha kernel: [862344.338797] usblp 1-1.4.4:1.2: usblp1: USB Bidirectional printer dev 99 if 2 alt 0 proto 2 vid 0x0493 pid 0xB002
The MAC address for the BT interface is from a different range however, and the device name does include the S:
gbl@natascha$ hcitool scan
Scanning ...
04:7F:0E:56:12:17 M02S
If you're interested in supporting that printer, and want any more information, feel free to contact me. Else, feel just as free to just close and ignore this issue.
Thanks again for your work, it's going to help me a lot!
Hello. Thank you for your great work at first. Recently I've got a Phomemo M120 printer and tried your CUPS driver.
However, it only prints about 1/3 of a 30 mm long page. It seems that (at least) M120 requires slower data transfer. I tried a slow-transferring code (rastertoppm02.py
) like this:
< bytes = block.tobytes()
< for i in range(lines):
< stdout.write(bytes[image.width * i:image.width * (i + 1)])
< stdout.flush()
< time.sleep(0.05)
---
> stdout.write(block.tobytes())
It works fine with my M120.
In addition, I'm using "gap paper", with which your original driver feeds an extra page after printing. So I also modified rastertopm02.py
like this:
< print_and_feed(stdout, 0)
---
> print_and_feed(stdout, 2)
I hope this information helps you or others who use Phomemo printers.
Thank you.
It seems there's a few other repos that worked on different Phomemo printers we should be able to add more driver support by taking a look into these repos:
Phomemo D30 (should be able to derive headers footers from here): https://github.com/polskafan/phomemo_d30/blob/master/print_text.py
M02s (already made a PR for this): https://github.com/privatwolke/phomemo-tools
M02 Pro (seems to similar to the M02s both are 300 dpi): https://github.com/noullove/phomemo-tools
T02 (was reversed with help from this project): https://github.com/iamjackg/esp32-phomemo-gameboy-printer
P12Pro, D35, D30 and M220 (Not too sure how much we can derive from here): https://github.com/Knightro63/phomemo
M03 (should be able to derive headers/footers from here): https://github.com/whitechip4/Phomemo-M03-Mod/blob/master/phomemo_m03.py
P12 (should be able to derive headers/footers from here): https://github.com/S1artie/InternetOfTrash/blob/master/labelprinter/labelprinter.py
But yeah it's a good start and it'll be nice to get this repo supporting as many Phomemo printers as possible!
I got a new P3200 printer (similar to a p-touch) and I'd like to use it on Linux, I wanted to try modifying the M110 driver to start with, but my printer is an ACM device and not a usblp device, any ideas how I go around to try to get it working?
I'm a developer, but inexperienced with printer drivers.
Thanks
My printer is M02 Pro, it doesn't get recognized as /dev/usb/lp0 but as /dev/ttyACM0 instead. If I print over Bluetooth the speed varies throughout the print but it's generally fast (normal), however, when using the serial port it starts out fine and then slows down to the speed of ~2-3 lines per second. I tried playing with the baud rate but it doesn't seem to have any effect.
Would it be possible to add support for Phomemo T02?
I couldn't find any information about the Phomemo P12 so here are my notes from testing it. The Phomemo P12 USB protocol seems to be the same as the M110/M120/M220 so it was surprisingly easy to get it working.
The width is 12 bytes (96 pixels). I only have tape media so I'm using media 0b (Continuous).
The P12 must be powered on after connecting it to USB power by pressing the button. It will work if the button is held down continuously so the button can be clamped or glued to keep it on permanently (so it turns back on automatically after power is interrupted).
FCC ID: 2ASRB-P12
USB info:
idVendor: 0x4C4A = Vendor ID not listed with USB.org
idProduct: 0x4155
bcdDevice: 0x0100
iManufacturer: 0x01
English (United States) "Jieli Technology"
iProduct: 0x02
English (United States) "USB Composite Device"
iSerialNumber: 0x03
English (United States) "1234567890ABCDEF"
bNumConfigurations: 0x01
@vivier So I noticed we're currently using a GPL3 license? Maybe if switch to MIT will hopefully get more contributors for other printers
Hello sir,
I currently own the Phomemo M110 and my objective is to print a QR Code on a page (30*20mm).
Is it possible to print an image with specific settings or do I need to use another method (working on python)?
Many thanks
I have a M02 Pro and I'm only able to print images using the phomemo-filter.py or CUPS. IDK why Phomemo doesn't provide drivers for this printer when it does get recognized as a composite device and I'm able to print images using your script.
Thanks!
Forgive my ignorance (I know nothing about CUPS other than seeing it in /bar/spool/cups
), but could these tools be used to automate the formatting and printing of QR codes with a D30? I noticed you only had case clauses for M02 and M110 and otherwise reject. The QR code generation is straightforward, but I don't know what serialization format printers need.
Thanks for the repo! Cool that you put this up.
Hey I'm trying to connect the M120 printer via bluetooth but I'm having a hard time. I've tried to follow the guide and yes I can connect to the printer using the rfcomm connect command but I can't use the backend to connect to the printer via CUPS.
I've been trying to using this command sudo lpadmin -p M120 -E -v phomemo://047F0E775A68 -P /usr/share/cups/model/Phomemo/Phomemo-M110.ppd.gz
followed by echo "This is test" | lp -d M02 -o media=w50h60 -
to no avail
@daig0rian Any idea how to connect to bluetooth using the command line? As I know you have a M110, thanks!
I recently got an M220 and tried it with the M110 driver.
I found out that the M220 treats every GS v 0 as a separate print job introducing line feed and back feed resulting in a gap of approx. 6 mm.
I discovered that the M220 supports at most 1200 lines per GS v 0 command. Limiting the maximum printable size to 72 mm x 150 mm
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.