Рубрики
Без рубрики

Сокращение URL с Wxpython

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

Летом я наткнулся на Статья На ARS Technica об использовании PYGTK для создания коротководства URL. Я думал, что это было довольно интересно, но я не использую Pygtk. Поэтому в этот момент я решил написать свой собственный WXPYPHON и использовать код статьи, чтобы сделать сокращение. Я взломал что-то быстро, а затем положил эту статью на заднюю горелку и вроде забыл об этом. Сегодня я решил пойти дальше и закончить его, а также создать приложение, которое может сократить URL-адреса, используя другие популярные сокращения URL.

Arsing ARS.

Во-первых, я покажу вам свою оригинальную программу, которая в основном просто обещает ARS Technica One.

import re
import urllib
import urllib2
import wx

class ArsShortener(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          'wxArsShortner', size=(300,70))

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        
        self.txt = wx.TextCtrl(panel, wx.ID_ANY, "", size=(300, -1))
        self.txt.Bind(wx.EVT_TEXT, self.onTextChange)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.txt, 0, wx.EXPAND, 5)
        panel.SetSizer(sizer)
                
    #----------------------------------------------------------------------
    def onTextChange(self, event):
        """"""
        text = self.txt.GetValue()
        textLength = len(text)
        if re.match("^https?://[^ ]+", text) and textLength > 20:
            apiurl = "http://is.gd/api.php?" + urllib.urlencode(dict(longurl=text))
            shorturl = urllib2.urlopen(apiurl).read() 
            self.txt.SetValue(shorturl)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = ArsShortener()
    frame.Show()
    app.MainLoop()

Как видите, почти половина кода является WXPYPHON, в то время как другая половина взята из статьи ARS. Чтобы начать, мы импортируем модуль регулярных выражений Python Regular, для целей проверки. Он проверяет вставленный URL, чтобы убедиться, что он находится в правильном формате для URL, а не просто нежелателен (см. Метод OnTextChange). Модули Urllib используются для доступа к IS.GD Веб-сайт и передача его URL, который мы хотим сократить. Как только мы получим результат назад, мы называем метод SetValue текстового элемента управления для отображения его пользователю. Условное утверждение также проверяет, если длина URL достаточно длительной, чтобы оправдать его сокращение.

Вы заметите, что у меня три строки прокомментированы. Я делал это так, чтобы приложение могло быть изменено и иметь управление текстовым управлением вместе с рамкой, но затем думал, что может быть хромой. Таким образом, я прокомментировал это. Тем не менее, я думал, что ты, дорогой читатель, может найти его полезным, чтобы знать, как это достичь.

Сокращение URL с другими сайтами

Теперь мы рассмотрим мой расширенный пример. Он может использовать IS.GD, Bit.ly или почтенный Tinyurl для сокращения URL. Для этой части статьи вам понадобятся следующие модули в дополнение к WX:

Я уверен, что есть способы просто использовать модули Urllib для этих веб-сайтов, но я хотел посмотреть, если эти сторонние модули упростили вещи. Обратите внимание, что если вы хотите использовать Bit.ly, они требуют подписаться на ключ API. Я не буду публиковать мой, но я покажу вам, как использовать его в моей программе. Итак, без дальнейшего ADO, на шоу:

import re
import urllib
import urllib2
import wx

bitlyFlag = True
tinyurlFlag = True

try:
    import bitly
except ImportError:
    bitlyFlag = False
    
try:
    import tinyurl
except ImportError:
    tinyurlFlag = False
    
########################################################################
class MainPanel(wx.Panel):
    """
    """

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
        self.frame = parent
        
        # create the widgets
        self.createLayout()
        
    #----------------------------------------------------------------------
    def createLayout(self):
        """
        Create widgets and lay them out
        """
        choices = ["is.gd"]
        if bitlyFlag:
            choices.append("bit.ly")
        if tinyurlFlag:
            choices.append("tinyurl")
        choices.sort()
        
        # create the widgets
        self.urlCbo = wx.ComboBox(self, wx.ID_ANY, "is.gd", 
                                  choices=choices,
                                  size=wx.DefaultSize,
                                  style=wx.CB_DROPDOWN)
        self.inputUrlTxt = wx.TextCtrl(self, value="Paste long url here")
        self.inputUrlTxt.Bind(wx.EVT_SET_FOCUS, self.onFocus)
        self.outputUrlTxt = wx.TextCtrl(self, style=wx.TE_READONLY)
        
        shortenBtn = wx.Button(self, label="Shorten URL")
        shortenBtn.Bind(wx.EVT_BUTTON, self.onShorten)
        copyBtn = wx.Button(self, label="Copy to Clipboard")
        copyBtn.Bind(wx.EVT_BUTTON, self.onCopy)
        
        # create the sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        
        # layout the widgets
        mainSizer.Add(self.urlCbo, 0, wx.ALL, 5)
        mainSizer.Add(self.inputUrlTxt, 0, 
                      wx.ALL|wx.EXPAND, 5)
        mainSizer.Add(self.outputUrlTxt, 0, 
                      wx.ALL|wx.EXPAND, 5)
        btnSizer.Add(shortenBtn, 0, wx.ALL|wx.CENTER, 5)
        btnSizer.Add(copyBtn, 0, wx.ALL|wx.CENTER, 5)
        mainSizer.Add(btnSizer, 0, wx.ALL|wx.CENTER, 5)
        self.SetSizer(mainSizer)
                
    #----------------------------------------------------------------------
    def onCopy(self, event):
        """
        Copies data to the clipboard or displays an error
        dialog if the clipboard is inaccessible.
        """
        text = self.outputUrlTxt.GetValue()
        self.do = wx.TextDataObject()
        self.do.SetText(text)
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(self.do)
            wx.TheClipboard.Close()
            status = "Copied %s to clipboard" % text
            self.frame.statusbar.SetStatusText(status)
        else:
            wx.MessageBox("Unable to open the clipboard", "Error")
            
    #----------------------------------------------------------------------
    def onFocus(self, event):
        """
        When control is given the focus, it is cleared
        """
        self.inputUrlTxt.SetValue("")

    #----------------------------------------------------------------------
    def onShorten(self, event):
        """
        Shortens a url using the service specified.
        Then sets the text control to the new url.
        """
        text = self.inputUrlTxt.GetValue()
        textLength = len(text)
        
        if re.match("^https?://[^ ]+", text) and textLength > 20:
            pass
        else:
            wx.MessageBox("URL is already tiny!", "Error")
            return
        
        url = self.urlCbo.GetValue()
        if url == "is.gd":
            self.shortenWithIsGd(text)
        elif url == "bit.ly":
            self.shortenWithBitly(text)
        elif url == "tinyurl":
            self.shortenWithTinyurl(text)
        
    #----------------------------------------------------------------------
    def shortenWithBitly(self, text):
        """
        Shortens the URL in the text control using bit.ly
        
        Requires a bit.ly account and API key
        """
        bitly.API_LOGIN = "username"
        bitly.API_KEY = "api_key"
        url = bitly.shorten(text)
        self.outputUrlTxt.SetValue(url)
    
    #----------------------------------------------------------------------
    def shortenWithIsGd(self, text):
        """
        Shortens the URL with is.gd using urllib and urllib2
        """
                
        apiurl = "http://is.gd/api.php?" + urllib.urlencode(dict(longurl=text))
        shorturl = urllib2.urlopen(apiurl).read() 
        self.outputUrlTxt.SetValue(shorturl)
    
    #----------------------------------------------------------------------
    def shortenWithTinyurl(self, text):
        """
        Shortens the URL with tinyurl
        """
        print "in tinyurl"
        url = tinyurl.create_one(text)
        self.outputUrlTxt.SetValue(url)

########################################################################
class UrlFrame(wx.Frame):
    """
    wx.Frame class
    """
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        title = "URL Shortener"
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          title=title, size=(650, 220))
        panel = MainPanel(self)
        self.statusbar = self.CreateStatusBar()
        self.SetMinSize((650, 220))       
        
#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = UrlFrame()
    frame.Show()
    app.MainLoop()

Этот кусок кода довольно длиннее, чем мой простой пример, но в него встроена намного больше логики. Сразу у меня, у меня есть некоторое обращение с исключением, реализованным в случае, если программист не имеет библиотеки или модулей Tinyurl. Если они этого не сделают, то флаг установлен, что предотвращает добавление этих вариантов. Вы увидите это в действии в классе Mainpanel Createlayout метод. Вот где мы добавляем варианты для Выбор список, который будет использовать наш Combobox. В зависимости от того, что вы установили, вы увидите от одного до трех вариантов в раскрывающемся списке.

Следующий интересный бит – это то, где управление текстом входного URL связан с событием фокусировки. Мы используем это для очистки текста управления при вставке URL в него. Также примите обратите внимание, что управление выходным текстом устанавливается в режим только для чтения. Это мешает пользователю запустить новый URL. Наконец, мы достигаем наших последних двух виджетов: Сократить URL и Скопируйте в буфер обмена Кнопки.

Давайте посмотрим на то, что происходит в методе oncopy, так как он следующий:

def onCopy(self, event):
    """
    Copies data to the clipboard or displays an error
    dialog if the clipboard is inaccessible.
    """
    text = self.outputUrlTxt.GetValue()
    self.do = wx.TextDataObject()
    self.do.SetText(text)
    if wx.TheClipboard.Open():
        wx.TheClipboard.SetData(self.do)
        wx.TheClipboard.Close()
        status = "Copied %s to clipboard" % text
        self.frame.statusbar.SetStatusText(status)
    else:
        wx.MessageBox("Unable to open the clipboard", "Error")

Как видите, это захватывает текущий текст из входного текста управления и создает из него TextDataObject. Затем мы пытаемся открыть буфер обмена, и если мы успешны, мы поместим текстовое устройствообъектировать в него, используя метод SetData Clipboard. Наконец, мы предупредим пользователя к тому, что мы сделали, изменив текст статуса кадра.

В методе Onshorten я повторно использую регулярное выражение из программы ARS, чтобы проверить, заполнил ли пользователь действительный URL, и мы также проверяем длину, чтобы увидеть, действительно ли нуждается ли URL-адрес укорочения. Мы получаем URL-адрес Worlener из Combobox, а затем используете условный условный URL, который мы хотим сократить до соответствующего метода укорочения. rocreenwittisgd Метод в основном такой же, как первый пример, поэтому мы пропустим это. сократить до смерти Способ показывает, что нам нужно установить свойства входа в систему и API_KEY, прежде чем мы сможем сократить URL. Как только мы сделаем это, мы просто называем Bitty’s сократить метод. В ornenwithtinyurl Метод, это даже проще: все, что вам нужно сделать, здесь называют Tinyurl create_one метод.

Обертывание

Теперь вы знаете основы для сокращения ваших длинных URL через несколько методов. Не стесняйтесь добавлять свои собственные функции или другие укороченные API для улучшения приложения для вашего собственного использования. Обратите внимание, что есть другой Python Битчо модуль. В то время как его домашняя страница говорит, что все, что ему нужно, это модуль SimpleJSON, если вы фактически пытаетесь использовать этот модуль, вы получите ошибку, если у вас тоже нет Джанго установлены. Кажется, они знают о проблеме, но по этой причине я решил использовать его блюдовый модуль Opie. Иметь веселье кодировать!

Примечание. Этот код был протестирован на Windows Vista с использованием WxPython 2.8.10.1 (Unicode) с Python 2.5.

Загрузки

  • сокращение
  • shortening.zip