Scribus根据光盘曲目创建光盘封面脚本

电脑技术 电脑技术 1884 人阅读 | 0 人回复 | 2022-04-18

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
http://fdubuy.free.fr/scribus/cddb_cover.py 原链接失效,这是备份

  1. """Written 04 august 2004 by Fred Dubuy <effediwhy@gmail.com>
  2. The CD template is from Yves Ceccone <yves@yeccoe.org>
  3. This work is released under the GNU GPL, version 2 or later.

  4. This script reads the ID of the CD in the drive
  5. and queries CDDB to get the album and song titles
  6. The songs are displayed in a frame text on the back side
  7. There are no font settings, they are up to you...
  8. This script only avoid having to type the songs titles
  9. It is possible to choose to add or not track number and track time

  10. 08/10/2004 : added multiple CDDB answers support

  11. 10/16/2004 - Petr Vanek <petr@yarpen.cz>
  12. Some strange artists use strange characters in names of their artworks.
  13. You need specify the right encoding for these texts. The system encoding
  14. is taken as default. If you're using Scribus 1.2.1cvs or later you
  15. can change it in the GUI dialog.
  16. Or set e.g.:
  17. encoding = 'utf8'
  18. or whatever on line 42

  19. 10/17/2004 - Fred Dubuy
  20. Put the encoding selection into the main dialog, and added tooltips, mainly for the encoding selection.
  21. The tooltip code is from Michael Lange <klappnase at 8ung dot at>, taken from Tkinter wiki (http://tkinter.unpythonic.net/wiki/)

  22. """


  23. # Make sure you have python-cddb installed
  24. # (http://cddb-py.sourceforge.net/)

  25. # Change the dev value below according to your configuration


  26. from scribus import *
  27. #following import moved at the end of the script with test
  28. #import DiscID, CDDB,cdrom
  29. from Tkinter import *

  30. import locale
  31. language, encoding = locale.getdefaultlocale()


  32. dev = "/dev/cdrom"

  33. class ToolTip:
  34.     def __init__(self, master, text='Your text here', delay=1000, **opts):
  35.         self.master = master
  36.         self._opts = {'anchor':'center', 'bd':1, 'bg':'lightyellow', 'delay':delay, 'fg':'black',\
  37.                       'follow_mouse':0, 'font':None, 'justify':'left', 'padx':4, 'pady':2,\
  38.                       'relief':'solid', 'state':'normal', 'text':text, 'textvariable':None,\
  39.                       'width':0, 'wraplength':150}
  40.         self.configure(**opts)
  41.         self._tipwindow = None
  42.         self._id = None
  43.         self._id1 = self.master.bind("<Enter>", self.enter, '+')
  44.         self._id2 = self.master.bind("<Leave>", self.leave, '+')
  45.         self._id3 = self.master.bind("<ButtonPress>", self.leave, '+')
  46.         self._follow_mouse = 0
  47.         if self._opts['follow_mouse']:
  48.             self._id4 = self.master.bind("<Motion>", self.motion, '+')
  49.             self._follow_mouse = 1
  50.    
  51.     def configure(self, **opts):
  52.         for key in opts:
  53.             if self._opts.has_key(key):
  54.                 self._opts[key] = opts[key]
  55.             else:
  56.                 KeyError = 'KeyError: Unknown option: "%s"' %key
  57.                 raise KeyError
  58.    
  59.     ##----these methods handle the callbacks on "<Enter>", "<Leave>" and "<Motion>"---------------##
  60.     ##----events on the parent widget; override them if you want to change the widget's behavior--##
  61.    
  62.     def enter(self, event=None):
  63.         self._schedule()
  64.         
  65.     def leave(self, event=None):
  66.         self._unschedule()
  67.         self._hide()
  68.    
  69.     def motion(self, event=None):
  70.         if self._tipwindow and self._follow_mouse:
  71.             x, y = self.coords()
  72.             self._tipwindow.wm_geometry("+%d+%d" % (x, y))
  73.    
  74.     ##------the methods that do the work:-----##
  75.    
  76.     def _schedule(self):
  77.         self._unschedule()
  78.         if self._opts['state'] == 'disabled':
  79.             return
  80.         self._id = self.master.after(self._opts['delay'], self._show)

  81.     def _unschedule(self):
  82.         id = self._id
  83.         self._id = None
  84.         if id:
  85.             self.master.after_cancel(id)

  86.     def _show(self):
  87.         if self._opts['state'] == 'disabled':
  88.             self._unschedule()
  89.             return
  90.         if not self._tipwindow:
  91.             self._tipwindow = tw = Toplevel(self.master)
  92.             # hide the window until we know the geometry
  93.             tw.withdraw()
  94.             tw.wm_overrideredirect(1)
  95.             self.create_contents()
  96.             tw.update_idletasks()
  97.             x, y = self.coords()
  98.             tw.wm_geometry("+%d+%d" % (x, y))
  99.             tw.deiconify()
  100.    
  101.     def _hide(self):
  102.         tw = self._tipwindow
  103.         self._tipwindow = None
  104.         if tw:
  105.             tw.destroy()
  106.                
  107.     ##----these methods might be overridden in derived classes:----##
  108.    
  109.     def coords(self):
  110.         # The tip window must be completely outside the master widget;
  111.         # otherwise when the mouse enters the tip window we get
  112.         # a leave event and it disappears, and then we get an enter
  113.         # event and it reappears, and so on forever :-(
  114.         # or we take care that the mouse pointer is always outside the tipwindow :-)
  115.         tw = self._tipwindow
  116.         twx, twy = tw.winfo_reqwidth(), tw.winfo_reqheight()
  117.         w, h = tw.winfo_screenwidth(), tw.winfo_screenheight()
  118.         # calculate the y coordinate:
  119.         if self._follow_mouse:
  120.             y = tw.winfo_pointery() + 20
  121.             # make sure the tipwindow is never outside the screen:
  122.             if y + twy > h:
  123.                 y = y - twy - 30
  124.         else:
  125.             y = self.master.winfo_rooty() + self.master.winfo_height() + 3
  126.             if y + twy > h:
  127.                 y = self.master.winfo_rooty() - twy - 3
  128.         # we can use the same x coord in both cases:
  129.         x = tw.winfo_pointerx() - twx / 2
  130.         if x < 0:
  131.             x = 0
  132.         elif x + twx > w:
  133.             x = w - twx
  134.         return x, y

  135.     def create_contents(self):
  136.         opts = self._opts.copy()
  137.         for opt in ('delay', 'follow_mouse', 'state'):
  138.             del opts[opt]
  139.         label = Label(self._tipwindow, **opts)
  140.         label.pack()

  141. class Warning2(Frame):
  142.         "class to display a message for import problems"
  143.         def __init__(self,parent,message):
  144.                 Frame.__init__(self)
  145.                 frame = Frame(parent)
  146.                 self.parent=parent
  147.                 lab2=Label(frame,text=message)
  148.                 lab2.pack()
  149.                 button=Button(frame,text='OK',command=self.parent.destroy)
  150.                 button.pack()
  151.                 frame.pack()

  152. class Warning(Toplevel):
  153.         "generic class to display a message in a new dialog"
  154.         def __init__(self,parent,message):
  155.                 Toplevel.__init__(self)
  156.                 lab2=Label(self,text=message)
  157.                 lab2.pack()
  158.                 button=Button(self,text='OK',command=self.quit)
  159.                 button.pack()
  160.                 self.geometry("+%d+%d" % ( (w-150)/2, (h-50)/2 ) )
  161.         def quit(self):
  162.                 app.only_once=0
  163.                 self.destroy()


  164. class Multiple(Toplevel):
  165.         "opens a dialog to choose between multiples CDDB answers"
  166.         def __init__(self,parent,query_info):
  167.                 Toplevel.__init__(self)
  168.                 self.parent=parent
  169.                 self.title=("Multiple choice")
  170.                 mlabel=Label(self,text="Multiple entries found, select one :")
  171.                 mlabel.pack()
  172.                 length=0
  173.                 count=0
  174.                 for i in query_info:
  175.                         count+=1
  176.                         if len(i['title'])>length:
  177.                                 length=len(i['title'])
  178.                 self.list = Listbox(self, height=count, width=length)
  179.                 for i in query_info:
  180.                         self.list.insert(END, i['title'])
  181.                 self.list.bind("<Double-Button-1>", self.choice2)
  182.                 self.list.pack()
  183.                 b1=Button(self,text='Select',command=self.choice)
  184.                 b1.pack(side=LEFT)
  185.                 b2=Button(self,text='Cancel',command=self.cancel_multiple)
  186.                 b2.pack(side=RIGHT)
  187.                 #wi=self.winfo_width()
  188.                 #hg=self.winfo_height()
  189.                 self.geometry("+%d+%d" % ( (w-300)/2, (h-150)/2 ) )
  190.         def choice(self):
  191.         #no current selection
  192.                 if len(map(int,self.list.curselection()))==0:
  193.                         return
  194.                 app.sel_index=map(int,self.list.curselection())[0]
  195.                 self.destroy()
  196.         def choice2(self,event):
  197.                 self.choice()
  198.         def cancel_multiple(self):
  199.                 app.only_once=0
  200.                 self.destroy()

  201. class Application(Frame):
  202.         def __init__(self, parent):
  203.                 Frame.__init__(self)
  204.                 self.parent=parent
  205.                 frame = Frame(parent)
  206.                 parent.title("CD Cover creation")
  207.                 lab_ent=Label(frame,text="Enter your CD device :")
  208.                 lab_ent.grid(row=0, columnspan=2)
  209.                 tt1 = ToolTip(lab_ent, follow_mouse=1, text="Specify your cdrom device file. The default is /dev/cdrom and can be changed by editing the script")
  210.                 self.ent=Entry(frame)
  211.                 self.ent.insert(0,dev)
  212.                 self.ent.icursor(len(dev))
  213.                 self.ent.grid(row=1,columnspan=2)
  214.                 lab_enc=Label(frame,text="Characters encoding :")
  215.                 lab_enc.grid(row=2, columnspan=2)
  216.                 tt2 = ToolTip(lab_enc, follow_mouse=1, text="If you are creating a cover for non-english record/artist, you may specify the right text encoding for the local characters. You can get some errors using wrong encoding.")
  217.                 self.enc=Entry(frame)
  218.                 self.enc.insert(0,encoding)
  219.                 self.enc.icursor(len(encoding))
  220.                 self.enc.grid(row=3,columnspan=2)
  221.                 self.numbering = IntVar()
  222.                 self.ttime = IntVar()
  223.                 self.sel_index = -1
  224.                 self.only_once = 0
  225.                 c1 = Checkbutton(frame, text="Add track number", variable=self.numbering)
  226.                 c1.grid(row=4,column=0)
  227.                 c1.select()
  228.                 t1 = ToolTip(c1, follow_mouse=1, text="If checked the track number will be put in front of the song name")
  229.                 c2 = Checkbutton(frame, text="Add track time", variable=self.ttime)
  230.                 c2.grid(row=4,column=1)
  231.                 t2 = ToolTip(c2, follow_mouse=1, text="If checked the track duration will be appended after the song name")
  232.                 b_valid=Button(frame,text='Create Cover',command=self.get_device)
  233.                 b_valid.grid(row=5,column=0)
  234.                 b_cancel=Button(frame,text='Cancel',command=self.quit)
  235.                 b_cancel.grid(row=5,column=1)
  236.                 frame.pack()
  237.         def get_device(self):
  238.                 #protection against multiple choice-window opening
  239.                 if self.only_once==1:
  240.                         return
  241.                 self.only_once=1
  242.                 self.build_cover(self.ent.get(),self.enc.get(),self.numbering.get(),self.ttime.get())

  243.         def quit(self):
  244.                 self.parent.destroy()

  245.         def build_cover(self,dev,char_enc,putnumber,puttime):
  246.                 #Get info from CD as in python-cddb examples
  247.                 cdrom = None
  248.                 try:
  249.                         if dev:
  250.                                 cdrom = DiscID.open(dev)
  251.                         else:
  252.                                 cdrom = DiscID.open()
  253.                 except:
  254.                         w=Warning(self,"Cannot access the device "+dev)
  255.                         return
  256.                 try:
  257.                         disc_id = DiscID.disc_id(cdrom)
  258.                 except:
  259.                         w=Warning(self,"Cannot read the device" +dev)
  260.                         return
  261.                 try:
  262.                         (query_stat, self.query_info) = CDDB.query(disc_id)
  263.                 except:
  264.                         w=Warning(self,"Cannot access to CDDB. Check your internet connection")
  265.                         return
  266.        
  267.                 if query_stat == 200:
  268.                         (read_stat, read_info) = CDDB.read(self.query_info['category'],
  269.                                                        self.query_info['disc_id'])
  270.                         if read_stat != 210:
  271.                                 w=Warning(self,"Disc ID not found in CDDB")
  272.                                 return
  273.                         else:
  274.                                 album=self.query_info['title']
  275.                 elif query_stat == 210 or query_stat == 211:
  276.                         m=Multiple(self,self.query_info)
  277.                         self.wait_window(m)
  278.                         #window close but no choice made
  279.                         if self.sel_index == -1:
  280.                                 return
  281.                         (read_stat, read_info) = CDDB.read(self.query_info[self.sel_index]['category'], self.query_info[self.sel_index]['disc_id'])
  282.                         album=self.query_info[self.sel_index]['title']
  283.                 else:
  284.                         w=Warning(self,"Disc ID not found in CDDB")
  285.                         return
  286.                 #here starts the template building
  287.                 SetUnit(1)
  288.                 Margins = (0, 0, 0, 0)
  289.                 Papier_A4 = (210, 297)
  290.                 if NewDoc(Papier_A4, Margins, Landscape, 1, Millimeters, NoFacingPages, FirstPageLeft):
  291.                         NewPage(-1)
  292.                         GotoPage(1)
  293.                         CreateLayer("crop")
  294.                         SetActiveLayer("crop")
  295.                         t1 = CreateLine(28.5, 38, 28.5, 43)
  296.                         SetLineWidth(0.1, t1)
  297.                         t2 = CreateLine(148.5, 38, 148.5, 43)
  298.                         SetLineWidth(0.1, t2)
  299.                         t3 = CreateLine(268.5, 38, 268.5, 43)
  300.                         SetLineWidth(0.1, t3)
  301.                         t4 = CreateLine(28.5, 172, 28.5, 167)
  302.                         SetLineWidth(0.1, t4)
  303.                         t5 = CreateLine(148.5, 172, 148.5, 167)
  304.                         SetLineWidth(0.1, t5)
  305.                         t6 = CreateLine(268.5, 172, 268.5, 167)
  306.                         SetLineWidth(0.1, t6)
  307.                         t7 = CreateLine(21.5, 45, 26.5, 45)
  308.                         SetLineWidth(0.1, t7)
  309.                         t8 = CreateLine(21.5, 165, 26.5, 165)
  310.                         SetLineWidth(0.1, t8)
  311.                         t9 = CreateLine(270.5, 45, 275.5, 45)
  312.                         SetLineWidth(0.1, t9)
  313.                         t10 = CreateLine(270.5, 165, 275.5, 165)
  314.                         SetLineWidth(0.1, t10)
  315.                         CreateLayer("bleed")
  316.                         SetActiveLayer("bleed")
  317.                         img1 = CreateImage(24.35, 41.25 , 124.20, 127.95,)
  318.                         img2 = CreateImage(148.55, 41.25 , 124.20, 127.95,)
  319.                         CreateLayer("normal")
  320.                         SetActiveLayer("normal")
  321.                         a = CreateText(98.5, 20, 100, 10)
  322.                         SetText("CD cover template - Front side", a)
  323.                         SetFontSize(11, a)
  324.                         SetTextAlignment(1, a)       
  325.                         b = CreateText(28.5, 45, 120, 120)
  326.                         SetFillColor("None", b)
  327.                         c = CreateText(148.5, 45, 120, 120)
  328.                         SetFillColor("None", c)
  329.                         GotoPage(2)
  330.                         SetActiveLayer("normal")
  331.                         a2 = CreateText(98.5, 20, 100, 10)
  332.                         SetText('CD cover template - Back side', a2)
  333.                         SetFontSize(11, a2)
  334.                         SetTextAlignment(1, a2)
  335.                         a2t = CreateText(204, 44, 78, 9)
  336.                         SetText("Instructions :", a2t)
  337.                         SetFontSize(13, a2t)
  338.                         SetTextAlignment(1, a2t)       
  339.                         a21 = CreateText(204, 54, 78, 87)
  340.                         SetText('Modify either the text on the Normal layer, or the pictures on the "bleed" layers, or both. You can change the frame types (image to text frame or text to image,...). The bleeds are wider than the CD size, which avoid any blank margin when cutting the printed document. The external crop marks will allow you to cut the cover and the internal crop marks are here for the folding.\nYou can get the front picture of your CD using your favorite search engine\'s image search feature', a21)
  341.                         SetFontSize(11, a21)
  342.                         SetTextAlignment(0, a21)
  343.                         b2 = CreateText(28.5, 162.10, 117, 6)
  344.                         SetText(unicode(album,char_enc), b2)
  345.                         SetFontSize(9, b2)
  346.                         SetTextAlignment(1, b2)
  347.                         RotateObjectAbs(90, b2)
  348.                         SetFillColor("None", b2)
  349.                         c2 = CreateText(34.5, 45, 137.5, 117)
  350.                         offset=0
  351.                         InsertText(unicode(album+"\n\n",char_enc),offset,c2)
  352.                         offset=offset+len(album)+2
  353.                         for i in range(0, disc_id[1]):
  354.                                 if putnumber == 1:
  355.                                         song='%d - %s' % (i+1, read_info['TTITLE' + `i`])
  356.                                 else:
  357.                                         song='%s' % read_info['TTITLE' + `i`]
  358.                                 if puttime == 1:
  359.                                         if i < (disc_id[1]-1):
  360.                                                 ttime=(disc_id[i+3]-disc_id[i+2])/75
  361.                                         else:
  362.                                                 ttime=disc_id[i+3]-disc_id[i+2]/75
  363.                                         song+=' - %d:%.2d' % ((ttime/60),(ttime%60))
  364.                                 InsertText(unicode(song+"\n",char_enc),offset,c2)
  365.                                 offset=offset+len(song)+1
  366.                         SetFillColor("None", c2)
  367.                         d2 = CreateText(28.5, 162.10, 117, 6)
  368.                         SetText(unicode(album,char_enc), d2)
  369.                         SetFontSize(9, d2)
  370.                         SetTextAlignment(1, d2)
  371.                         RotateObjectAbs(90, d2)
  372.                         SetFillColor("None", d2)
  373.                         MoveObject(143.5, 0, d2)
  374.                         SetActiveLayer("bleed")
  375.                         img3 = CreateImage(24.35, 41.25 , 157.50, 126.50,)
  376.                         SetActiveLayer("crop")
  377.                         t21 = CreateLine(28.5, 38, 28.5, 43)
  378.                         SetLineWidth(0.1, t21)
  379.                         t22 = CreateLine(34.5, 38, 34.5, 43)
  380.                         SetLineWidth(0.1, t22)
  381.                         t23 = CreateLine(172, 38, 172, 43)
  382.                         SetLineWidth(0.1, t23)
  383.                         t24 = CreateLine(178, 38, 178, 43)
  384.                         SetLineWidth(0.1, t24)
  385.                         t25 = CreateLine(28.5, 164.5, 28.5, 169.5)
  386.                         SetLineWidth(0.1, t25)
  387.                         t26 = CreateLine(34.5, 164, 34.5, 169.5)
  388.                         SetLineWidth(0.1, t26)
  389.                         t27 = CreateLine(172, 164, 172, 169.5)
  390.                         SetLineWidth(0.1, t27)
  391.                         t28 = CreateLine(178, 164, 178, 169.5)
  392.                         SetLineWidth(0.1, t28)
  393.                         t29 = CreateLine(22.5, 45, 27.5, 45)
  394.                         SetLineWidth(0.1, t29)
  395.                         t30 = CreateLine(22.5, 162, 27.5, 162)
  396.                         SetLineWidth(0.1, t30)
  397.                         t31 = CreateLine(179.5, 45, 184.5, 45)
  398.                         SetLineWidth(0.1, t31)
  399.                         t32 = CreateLine(179.5, 162, 184.5, 162)
  400.                         SetLineWidth(0.1, t32)
  401.                         self.quit()

  402. root=Tk()
  403. w=root.winfo_screenwidth()
  404. h=root.winfo_screenheight()
  405. root.geometry("+%d+%d" % ( (w-300)/2, (h-100)/2 ) )
  406. try:
  407.         import DiscID, CDDB, cdrom
  408. except:
  409.         app=Warning2(root,"You need to install python-cddb!\n"+
  410.                                         "see http://cddb-py.sourceforge.net/\n"
  411.                                         +"Gentoo : emerge cddb-py\n"
  412.                                         +"Debian : apt-get install python-cddb\n"
  413.                                         +"Mandrake : urpmi python-CDDB")
  414. else:
  415.         app=Application(root)
  416.        
  417. root.mainloop()
复制代码


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐