__main__.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import gi
  2. gi.require_version("Gtk", "3.0")
  3. from gi.repository import GLib, Gio, Gtk
  4. import sys
  5. import os
  6. from ppublisher.file_item import FileItem
  7. from ppublisher.metadata import MetadataEditor
  8. from ppublisher.file_editor import FileEditor
  9. from PyPPUB import ppub_builder
  10. #
  11. # 1. our .glade file (may contain paths)
  12. #
  13. @Gtk.Template.from_file("ppublisher/ppublisher.ui")
  14. class AppWindow(Gtk.ApplicationWindow):
  15. #
  16. # 2. the GtkApplicationWindow class
  17. #
  18. __gtype_name__ = "ppublisher"
  19. #
  20. # 3. the Button id
  21. #
  22. editor: Gtk.Box = Gtk.Template.Child()
  23. file_list: Gtk.ListBox = Gtk.Template.Child()
  24. def __init__(self, **kwargs):
  25. super(Gtk.ApplicationWindow, self).__init__(**kwargs)
  26. self.current_editor = None
  27. def set_editor(self, child):
  28. if(self.current_editor != None):
  29. self.editor.remove(self.current_editor)
  30. self.current_editor = child
  31. self.editor.add(child)
  32. def get_all_items(self):
  33. return [x.get_child() for x in self.file_list.get_children()]
  34. def set_default_document(self, item):
  35. items = self.get_all_items()
  36. for i in items:
  37. i.set_main(False)
  38. if(item != None):
  39. item.set_main(True)
  40. def set_poster_document(self, item):
  41. items = self.get_all_items()
  42. for i in items:
  43. i.set_poster(False)
  44. if(item != None):
  45. item.set_poster(True)
  46. def get_default_document(self):
  47. items = self.get_all_items()
  48. for item in items:
  49. if(item.is_main):
  50. return item
  51. return None
  52. def get_poster_document(self):
  53. items = self.get_all_items()
  54. for item in items:
  55. if(item.is_poster):
  56. return item
  57. return None
  58. def get_metadata(self):
  59. items = self.get_all_items()
  60. for item in items:
  61. if(item.is_metadata):
  62. return item
  63. return None
  64. def build_ppub(self, path):
  65. metadata = self.get_metadata()
  66. default = self.get_default_document()
  67. if(metadata == None or default == None):
  68. raise Exception("No default document or metadata present!")
  69. builder = ppub_builder.PpubBuilder()
  70. builder.metadata = metadata.build_metadata()
  71. poster = self.get_poster_document()
  72. if(poster != None):
  73. builder.metadata.set_value("poster", poster.filename)
  74. self.add_asset(builder, default)
  75. for item in self.get_all_items():
  76. if(item == metadata or item == default):
  77. continue
  78. self.add_asset(builder, item)
  79. f = open(path, 'wb')
  80. builder.write_to_stream(f)
  81. f.close()
  82. def add_asset(self, builder, item):
  83. f = open(item.path, 'rb')
  84. builder.add_asset(item.filename, item.mimetype, f.read())
  85. def build_ppix(self, folder_path):
  86. from PyPPUB.ppix_builder import PpixBuilder
  87. from PyPPUB import ppub
  88. builder = PpixBuilder()
  89. import glob
  90. paths = glob.glob(folder_path + "/*.ppub")
  91. paths = sorted(paths, key= lambda p: os.stat(p).st_ctime, reverse=True)
  92. for path in paths:
  93. builder.add_publication(path.split("/")[-1], ppub.Ppub.from_stream(open(path, 'rb')))
  94. f = open(folder_path + "/lib.ppix", 'wb')
  95. builder.write_out(f)
  96. @Gtk.Template.Callback()
  97. def file_selected(self, widget, list_item):
  98. item = list_item.get_child()
  99. if(item.is_metadata):
  100. self.set_editor(MetadataEditor(item))
  101. else:
  102. self.set_editor(FileEditor(item, self))
  103. @Gtk.Template.Callback()
  104. def add_file_click(self, widget):
  105. dialog = Gtk.FileChooserDialog(title = "Add File", parent = self, action = Gtk.FileChooserAction.OPEN)
  106. dialog.add_buttons(
  107. Gtk.STOCK_CANCEL,
  108. Gtk.ResponseType.CANCEL,
  109. Gtk.STOCK_OPEN,
  110. Gtk.ResponseType.OK,
  111. )
  112. dialog.set_select_multiple(True)
  113. response = dialog.run()
  114. if response == Gtk.ResponseType.OK:
  115. files = dialog.get_filenames()
  116. for file in files:
  117. print(file)
  118. self.file_list.add(FileItem(file))
  119. dialog.destroy()
  120. @Gtk.Template.Callback()
  121. def save_click(self, widget):
  122. dialog = Gtk.FileChooserDialog(title = "Save PPUB", parent = self, action = Gtk.FileChooserAction.SAVE)
  123. dialog.add_buttons(
  124. Gtk.STOCK_CANCEL,
  125. Gtk.ResponseType.CANCEL,
  126. Gtk.STOCK_SAVE,
  127. Gtk.ResponseType.OK,
  128. )
  129. response = dialog.run()
  130. if response == Gtk.ResponseType.OK:
  131. try:
  132. self.build_ppub(dialog.get_filename())
  133. except Exception as ex:
  134. error = Gtk.MessageDialog(
  135. transient_for=dialog,
  136. flags=0,
  137. message_type=Gtk.MessageType.ERROR,
  138. buttons=Gtk.ButtonsType.CANCEL,
  139. text="Error exporting PPUB!",
  140. )
  141. error.format_secondary_text(str(ex))
  142. error.run()
  143. error.destroy()
  144. dialog.destroy()
  145. @Gtk.Template.Callback()
  146. def create_index_click(self, widget):
  147. dialog = Gtk.FileChooserDialog(title = "Choose a file to build a PPIX index in", parent = self, action = Gtk.FileChooserAction.SELECT_FOLDER)
  148. dialog.add_buttons(
  149. Gtk.STOCK_CANCEL,
  150. Gtk.ResponseType.CANCEL,
  151. "Build Index",
  152. Gtk.ResponseType.OK,
  153. )
  154. response = dialog.run()
  155. if response == Gtk.ResponseType.OK:
  156. try:
  157. self.build_ppix(dialog.get_filename())
  158. except Exception as ex:
  159. error = Gtk.MessageDialog(
  160. transient_for=dialog,
  161. flags=0,
  162. message_type=Gtk.MessageType.ERROR,
  163. buttons=Gtk.ButtonsType.CANCEL,
  164. text="Error creating PPIX!",
  165. )
  166. error.format_secondary_text(str(ex))
  167. error.run()
  168. error.destroy()
  169. dialog.destroy()
  170. @Gtk.Template.Callback()
  171. def remove_file_click(self, widget):
  172. item_container = self.file_list.get_selected_row()
  173. item = item_container.get_child()
  174. if(item.is_metadata):
  175. return
  176. self.file_list.remove(item_container)
  177. class Application(Gtk.Application):
  178. def __init__(self, *args, **kwargs):
  179. super().__init__(*args, application_id="com.pcthingz.ppublisher",
  180. flags=Gio.ApplicationFlags.FLAGS_NONE, **kwargs)
  181. self.window = None
  182. def do_activate(self):
  183. self.window = self.window or AppWindow(application=self)
  184. self.window.present()
  185. self.window.file_list.add(FileItem(None, True))
  186. if __name__ == '__main__':
  187. Application().run(sys.argv)