Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2017
420
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.91 KB | None | 0 0
  1. # PiTiVi , Non-linear video editor
  2. #
  3. #       ui/publishtoyoutubedialog.py
  4. #
  5. # Copyright (c) 2010, Mathieu Duponchelle <seeed@laposte.net>
  6. #
  7. # This program is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU Lesser General Public
  9. # License as published by the Free Software Foundation; either
  10. # version 2.1 of the License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. # Lesser General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Lesser General Public
  18. # License along with this program; if not, write to the
  19. # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20. # Boston, MA 02111-1307, USA.
  21.  
  22. """
  23. Dialog for publishing to YouTube
  24. """
  25.  
  26. import gtk
  27. import time
  28. import thread
  29. from gst import SECOND
  30. from pitivi.log.loggable import Loggable
  31. from pitivi.ui.glade import GladeWindow
  32. from pitivi.actioner import Renderer
  33. from pitivi.youtube_glib import YTUploader, DMUploader
  34. from gettext import gettext as _
  35. from gobject import timeout_add
  36. from string import ascii_lowercase, ascii_uppercase, maketrans, translate
  37. from pitivi.utils import beautify_length
  38. try :
  39.     import gnomekeyring as gk
  40.     unsecure_storing = False
  41. except :
  42.     unsecure_storing = True
  43. import pycurl
  44.  
  45. catlist = ['Film', 'Autos', 'Music', 'Animals', 'Sports', 'Travel', 'Games', 'Comedy', 'People', 'News', 'Entertainment', 'Education', 'Howto', 'Nonprofit', 'Tech']
  46.  
  47. class PublishToYouTubeDialog(GladeWindow, Renderer):
  48.     glade_file = 'publishtoyoutubedialog.glade'
  49.  
  50.     def __init__(self, app, project, pipeline=None):
  51.         Loggable.__init__(self)
  52.         GladeWindow.__init__(self)
  53.         self.app_settings = app.settings
  54.  
  55.         self.app = app
  56.         self.pipeline = pipeline
  57.         self.project = project
  58.  
  59.         # UI widgets
  60.         self.login = self.widgets["login"]
  61.         self.login_status = self.widgets["login_status"]
  62.         self.username = self.widgets["username"]
  63.         self.password = self.widgets["password"]
  64.         self.oldsettings = self.app.project.getSettings()
  65.         self.settings = self.oldsettings.copy()
  66.         self.settings.setEncoders(muxer='avimux', vencoder='xvidenc', aencoder="lamemp3enc")
  67.         self.app.project.setSettings(self.settings)
  68.         self.app.publish_button.set_sensitive(False)
  69.  
  70.         #Auto-completion
  71.         if unsecure_storing :
  72.             self.widgets["checkbutton1"].set_label("Remember me ! Warning : \
  73. storage will not be secure. Install python-gnomekeyring.")
  74.             if self.app_settings.login:
  75.                 self.username.set_text(self.app_settings.login)
  76.                 self.password.set_text(self.app_settings.password)
  77.         elif "pitivi" in gk.list_keyring_names_sync():
  78.             item_keys = gk.list_item_ids_sync('pitivi')
  79.             gk.unlock_sync('pitivi', 'gkpass')
  80.             item_info = gk.item_get_info_sync('pitivi', item_keys[0])
  81.             if item_info :
  82.                 self.username.set_text(item_info.get_display_name())
  83.                 self.password.set_text(item_info.get_secret())
  84.             gk.lock_sync('pitivi')
  85.  
  86.         self.uploader = YTUploader()
  87.         self.description = self.widgets["description"]
  88.         self.tags = self.widgets["tags"]
  89.         self.categories = gtk.combo_box_new_text()
  90.         self.widgets["table2"].attach(self.categories, 1, 2, 3, 4)
  91.         self.categories.show()
  92.         self.categories.set_title("Choose a category")
  93.         for e in catlist:
  94.             self.categories.append_text(e)
  95.  
  96.         self.renderbar = self.widgets["renderbar"]
  97.         self.uploadbar = gtk.ProgressBar()
  98.         self.stopbutton = gtk.ToolButton(gtk.STOCK_CANCEL)
  99.         self.hbox = gtk.HBox()
  100.         self.hbox.pack_start(self.uploadbar)
  101.         self.hbox.pack_end(self.stopbutton)
  102.         self.taglist = []
  103.  
  104.         self.fileentry = self.widgets["fileentry"]
  105.         self.updateFilename(self.project.name)
  106.         self.filebutton = gtk.FileChooserButton("Select a file")
  107.         self.widgets["table2"].attach(self.filebutton, 1, 2, 5, 6)
  108.         self.filebutton.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
  109.         self.filebutton.set_current_folder(self.app.settings.lastExportFolder)
  110.         self.filebutton.show()
  111.  
  112.         self.remember_me = False
  113.  
  114.         # Assistant pages
  115.         self.login_page = self.window.get_nth_page(0)
  116.         self.metadata_page = self.window.get_nth_page(1)
  117.         self.render_page = self.window.get_nth_page(2)
  118.         self.announce_page = self.window.get_nth_page(3)
  119.  
  120.         self.description.get_buffer().connect("changed", self._descriptionChangedCb)
  121.         self.categories.connect("changed", self._categoryChangedCb)
  122.         self.stopbutton.connect('clicked', self._finishCb)
  123.         self.mainquitsignal = self.app.connect('destroy', self._mainQuitCb)
  124.         self.connect("eos", self._renderingDoneCb)
  125.         self.window.connect("delete-event", self._deleteEventCb)
  126.  
  127.         self.metadata = {
  128.             "title": "",
  129.             "description": "",
  130.             "private": False,
  131.             "category": None,
  132.             "tags": "",
  133.         }
  134.         self.has_started_rendering = False
  135.  
  136.     def updateFilename(self, name):
  137.         self.fileentry.set_text(name + ".avi")
  138.  
  139.     def _storePassword(self):
  140.         if unsecure_storing:
  141.             self.app_settings.login = self.username.get_text()
  142.             self.app_settings.password = self.password.get_text()
  143.             self.app_settings.storeSettings()
  144.         else :
  145.             if "pitivi" not in gk.list_keyring_names_sync():
  146.                 gk.create_sync('pitivi', 'gkpass')
  147.             atts = {'username':'pitivi',
  148.                     'server':'Youtube',
  149.                     'service':'HTTP',
  150.                     'port':'80',
  151.                    }
  152.             a = gk.item_create_sync('pitivi', gk.ITEM_GENERIC_SECRET,
  153.                 self.username.get_text(), atts, self.password.get_text(), True)
  154.  
  155.     def _update_metadata_page_complete(self):
  156.         is_complete = all([
  157.             len(self.metadata["title"]) != 0,
  158.             len(self.metadata["description"]) != 0,
  159.         ])
  160.         self.window.set_page_complete(self.metadata_page, is_complete)
  161.  
  162.     def _startRendering(self):
  163.  
  164.         self.has_started_rendering = True
  165.  
  166.         # Start rendering:
  167.         self.filename = self.filebutton.get_uri() + "/" + self.fileentry.get_text()
  168.         Renderer.__init__(self, self.project, self.pipeline, outfile =
  169.                 self.filename)
  170.         self.app.set_sensitive(False)
  171.         self.startAction()
  172.         self.renderbar.set_fraction(0)
  173.         self.visible = True
  174.  
  175.     def updatePosition(self, fraction, estimated, uploading = False):
  176.         if not uploading:
  177.             self.renderbar.set_fraction(fraction)
  178.             self.app.set_title(_("%d%% Rendered") % int(100 * fraction))
  179.         else:
  180.             self.uploadbar.set_fraction(fraction)
  181.         if estimated and not uploading:
  182.             self.renderbar.set_text(_("About %s left in rendering") % estimated)
  183.         elif estimated and uploading:
  184.             self.uploadbar.set_text(_("About %s left in uploading") % estimated)
  185.  
  186.     def _shutDown(self):
  187.         self.debug("shutting down")
  188.         if self.uploader.uploader:
  189.             self.uploader.uploader.run = False
  190.         self.app.project.setSettings(self.oldsettings)
  191.         self.app.set_sensitive(True)
  192.         self.app.publish_button.set_sensitive(True)
  193.         self.app.handler_disconnect(self.mainquitsignal)
  194.  
  195.         # Abort recording
  196.         if self.has_started_rendering:
  197.             self.removeAction()
  198.         self.window.destroy()
  199.         self.destroy()
  200.  
  201.     def _rememberMeCb(self, button):
  202.         self.remember_me = False
  203.         if button.get_active():
  204.             self.remember_me = True
  205.  
  206.     def _loginClickedCb(self, *args):
  207.         self.debug("login clicked")
  208.         self.login_status.set_text("Logging in...")
  209.         # TODO: This should activate a throbber
  210.         thread.start_new_thread (self.uploader.authenticate_with_password, (self.username.get_text(),
  211.             self.password.get_text(), self._loginResultCb))
  212.  
  213.     def _loginResultCb(self, result):
  214.         # TODO: The throbber should now be deactivated
  215.         if result == 'good':
  216.             if self.remember_me:
  217.                 self._storePassword()
  218.             self.window.set_page_complete(self.login_page, True)
  219.             self.window.set_current_page(self.window.get_current_page() + 1)
  220.         else:
  221.             status, exception = result
  222.             self.login_status.set_text(str(exception))
  223.             self.window.set_page_complete(self.login_page, False)
  224.  
  225.     def _titleChangedCb(self, entry):
  226.         self.metadata["title"] = entry.get_text()
  227.         self._update_metadata_page_complete()
  228.  
  229.     def _descriptionChangedCb(self, buffer):
  230.         self.metadata["description"] = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter())
  231.         self._update_metadata_page_complete()
  232.  
  233.     def _newTagCb(self, entry):
  234.         letter_set = frozenset(ascii_lowercase + ascii_uppercase)
  235.         tab = maketrans(ascii_lowercase + ascii_uppercase, ascii_lowercase * 2)
  236.         deletions = ''.join(ch for ch in map(chr,range(256)) if ch not in letter_set)
  237.         text = translate(entry.get_text(), tab, deletions)
  238.         if len(text) < 2:
  239.             entry.set_sensitive(False)
  240.             entry.set_text(" One-letter tags ain't admitted")
  241.             timeout_add(1000, entry.set_text, "")
  242.             timeout_add (1000, entry.set_sensitive, True)
  243.             return
  244.  
  245.         if self.metadata["tags"] != "" and text != "" and self.metadata["tags"].count(",") < 6 and text not in self.taglist:
  246.             self.metadata["tags"] = self.metadata["tags"] + ", " + text
  247.             self.taglist.append(text)
  248.  
  249.         elif text != "" and self.metadata["tags"].count(",") < 6 and text not in self.taglist:
  250.             self.metadata["tags"] = text
  251.             self.taglist.append(text)
  252.         entry.set_text('')
  253.  
  254.     def _videositeChangedCb(self, combo):
  255.         if combo.get_active_text() == "YouTube":
  256.             self.uploader=YTUploader()
  257.         else:
  258.             self.uploader = DMUploader()
  259.  
  260.     def _categoryChangedCb(self, combo):
  261.         self.metadata["category"] = combo.get_active_text()
  262.  
  263.     def _changeStatusCb (self, button):
  264.         if button.get_active():
  265.             self.metadata["private"] = True
  266.         else:
  267.             self.metadata["private"] = False
  268.  
  269.     def _prepareCb(self, assistant, page):
  270.         if page == self.render_page and not self.has_started_rendering:
  271.             #self._startRendering() - cheat
  272.             self.app.set_sensitive(True)
  273.             self.app.set_title(_("PiTiVi"))
  274.             self.timestarted = time.time()
  275.             self.window.hide()
  276.             self.app.sourcelist.pack_end(self.hbox, False, False)
  277.             self.hbox.show_all()
  278.  
  279.             self.filename = self.filebutton.get_uri() + "/" + self.fileentry.get_text()
  280.             self.uploader.upload(self.filename[8:], self.metadata, self.on_upload_progress, self._uploadDoneCb)
  281.  
  282.     def _renderingDoneCb(self, data):
  283.         self.app.set_sensitive(True)
  284.         self.app.set_title(_("PiTiVi"))
  285.         self.timestarted = time.time()
  286.         self.window.hide()
  287.         self.app.sourcelist.pack_end(self.hbox, False, False)
  288.         self.hbox.show_all()
  289.         self.filename = self.filename.split("://")[1]
  290.         self.uploader.upload(self.filename, self.metadata, self._uploadProgressCb, self._uploadDoneCb)
  291.  
  292.     def _uploadProgressCb(self, done, total):
  293.         timediff = time.time() - self.timestarted
  294.         fraction = float(min(done, total)) / float(total)
  295.         if timediff > 3.0:
  296.             totaltime = (timediff * float(total) / float(done)) - timediff
  297.             text = beautify_length(int(totaltime * SECOND))
  298.             self.updatePosition(fraction, text, uploading = True)
  299.  
  300.     def _uploadDoneCb(self, video_entry):
  301.         print "done !"
  302.         self.entry = gtk.Entry()
  303.         link = video_entry.find_html_link().split("&")[0]
  304.         self.entry.set_text(link)
  305.         self.uploadbar.destroy()
  306.         self.hbox.pack_start (self.entry)
  307.         self.entry.show()
  308.  
  309.     def _mainQuitCb(self, ignored):
  310.         self.window.destroy()
  311.         self.destroy()
  312.  
  313.     def _deleteEventCb(self, window, event):
  314.         self.debug("delete event")
  315.         self._shutDown()
  316.  
  317.     def _cancelCb(self, ignored):
  318.         self.debug("cancel event")
  319.         self._shutDown()
  320.  
  321.     def _destroyCb (self, ignored):
  322.         self._shutDown()
  323.  
  324.     def _finishCb(self, unused):
  325.         self.hbox.destroy()
  326.         self._shutDown()
  327.  
  328. #different progress
  329.     def on_upload_progress(self, dt, dd, utotal, udone):
  330.         if utotal:
  331.             self.renderbar.set_fraction(float(udone) / float(utotal))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement