MyYandeksFotki uploader (MYF) — загрузка фоток через Firefox в Я.Фотки и вставка в Textarea

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

    А процесс загрузки фотографий под Firefox следующий:
    • Выделяю фотографии на компьютере;
    • Перетаскиваю файлы в Окно Firefox (в область плагина Яндекс.фотки);
    • Жму кнопку «Загрузить», выбираю альбом и снова «Загрузить»;
    • Потом, открываю каждую фотографию и копирую прямую ссылку на Jpg файлы;
    • Скопированные ссылки вставляю в textarea в блоге или форуме, а потом вручную теги дописываю.

    Вижу процесс публикации в следующем виде:
    • Выделяю файлы на компьютере;
    • Перетаскиваю их в Textarea, куда нужно вставить html или bbcode;
    • Дописываю комментарии к каждой фографии и наслаждаюсь результатом.

    Может есть другой путь?
    На просторах Интернете есть хостинг картинок imageshack.us. Для него даже написан плагин, который выполняет вышеописанное действие, но невозможно шаблоны в нем поправить. Вторым его минусом считаю частую проблему отображения загруженных картинок.

    Мой путь
    Я подумал, а почему бы не написать плагин для Яндекс.Фоток. Нашел интересный пост Создание расширения для начинающих и начал постигать азы.

    Вечерами по 1-2 часа в течение 5 дней написал и изучал…

    На данный момент его особенности и возможности
    • Логин и пароль вписаны в JS файл;
    • RSA шифрование логина и парля у Яндекс.фоток НЕ стандартное. Поэтому в данный момент использую удаленное шифрование на стороне своего сервера, где удалось скомпилировать утилиту encrypt;
    • В качестве заголовка фотки используется ссылка, где располагается textarea, куда была закинута фотка;
    • Работает только под Firefox 3.6+ (Windows).


    Планы
    • Перенести утилиту encrypt внутрь плагины;
    • Сделать кросс-платформенный плагин;
    • Создание собственных шаблонов и определение типа шаблона в зависимости от ссылки (по домену или по имени скрипта);
    • Выбор альбома, в который нужно загружать фотки;
    • Автоматическое определение альбомов для загрузки в ЖЖ и на форумы (Необходимо создать у себя в Яндекс.фотках альбомы с именем «Livejournal.com» и «Форумы»);


    И вот результат: Видео демонстрация на Vimeo
    PS: Соберу XPI, как только создам окно с настройками для плагина.

    Цель этого поста:


    Хочу услышать от Вас пожелания по функционалу, а так-же буду рад помощи по следующим вопросам:
    • Как запустить программу с параметрами (внутри XPI плагина), что бы портом прочитать строчку, которую вернет программа?
    • … Еще что-то придумаю...


    Update: Получилось переписать скрипт шифрования на язык JS :-)

    Update2: Доработаю скрипт так, что бы он не хранил пароль от яндекса в настройках, а то это реальная дыра в безопасности получается.

    Часть 2 — читать тут:

    habrahabr.ru/blogs/firefox/83710
    Поделиться публикацией

    Похожие публикации

    Комментарии 61

      0
      Удобная идея. Я бы попользовал.

      Для удобства еще бы добавил в контектное меню textarea пункт «вставить локальную картинку». Запускать проводник и насиловать drag&drop не всегда удобно.
        0
        Интересненько. До такого я не додумался.
        Учтено.
          0
          пункт «вставить локальную картинку»

          Только чтоб в вылезшем окошке можно было выделит не один файл на добавление, а несколько.
        +1
        Если все так, как на видео, то все отлично. Свою функцию оно отлично делает. В «планах» все замечания есть. В ЖЖ конечно удобней всего писать через Semagic, и ему точно не хватает такого плагина.
          0
          Раньше пользовался Semagic, но постить фотографии замучился :-)

          Перешел на Plain text режим + плагин Livejournal addons (https://addons.mozilla.org/ru/firefox/addon/4536)

          По функциям не хуже семаджика.

          PS: Семаджик умеет загружать фотки, но немного по другому. (Журнал -> Изображения)
            0
            Загружает он их великолепно и очень удобно, таким же drag&drop, только нужно нам(а в данном случае Я.Фоток), там нет.
              0
              Согласен. Но мне хотелось такой функционал на только в рамках ЖЖ :-)

              Разработку веду по 1 часу в день, поэтому сложно большими скачками все разрабатывать.

              После основного этапа программирования выложу XPI, а потом приступлю к реинжинирингу кода.
          0
          encrypt — это да. Вчера тоже повозился с ним. Теперь вот думаю, как перенести сайтик на GAE. Вариант с удаленным шифрованием мне не нравится.

          Если портируете утилиту на какой-нибудь скриптовый язык — пните, пожалуйста. :)
            0
            на php не удалось портировать. очень сложно сопоставлять типы данных.
              +1
              Красивее делать не буду. И так весь вечер убил, чтобы понять че там к чему в этих сях.

              #-*- coding:utf-8 -*-

              import sys, copy

              if __name__ == '__main__':
                if len(sys.argv) != 3 : print "usage: python %s <public-key> <text>" % sys.argv[0]; sys.exit()
                NSTR,ESTR = sys.argv[1].split("#")
                DATA_ARR = [ord(x) for x in sys.argv[2]]
                N,E,STEP_SIZE = int(NSTR,16),int(ESTR,16), len(NSTR)/2-1
                
                prev_crypted = [0]*STEP_SIZE
                
                hex_out = ""
                for i in range(0,(len(DATA_ARR)-1)/STEP_SIZE+1):
                  tmp = DATA_ARR[i*STEP_SIZE:(i+1)*STEP_SIZE]
                  tmp = [tmp[i] ^ prev_crypted[i] for i in range(0,len(tmp))]
                  tmp.reverse()
                  plain = 0
                  for x in range(0,len(tmp)): plain+= tmp[x]*pow(256, x, N)
                  hex_result = "%x" % pow(plain,E,N)
                  if len(hex_result) % 2 == 1: hex_result = "0" + hex_result
                  for x in range(0,min(len(hex_result),len(prev_crypted)*2),2):
                    prev_crypted[x/2] = int(hex_result[x:x+2],16)
                  hex_out += ("0" if len(tmp) < 16 else "") + ("%x" % (len(tmp)*256)) + "4000" + hex_result
                
                print hex_out.decode("hex").encode("base64").replace("\n","")


                0
                > чтобы понять че там к чему в этих сях

                всмысле что там яндекс понаписал, а не вообще язык :)

                Кстати мой код будет работать (наверное) только с текущей длиной ключа. Если изменится, то нужно будет мелочь пофиксить.
                  0
                  Спасибо большое! Сегодня завтра попробую на практике. :)
                    0
                    Спасибо, авось получится под JS переписать =)
                      0
                      Получится. Взять внешние библиотеки BigInt, Base64 и переписать
                        0
                        Хм. Вы про обычный javascript? Браузерный? :)
                          0
                          Именно на него хочу.

                          Сейчас завис на создании Ord функции по JS :-)
                            +1
                            «a».charCodeAt(0)
                              0
                              Для русским символов из полученного кода вычитать 848 нужно.
                              Тогда результат Python/PHP oct функции Будет равен результату JS функции charCodeAt.
                                0
                                Насколько я понимаю в данной задаче появление русских символов исключено )
                                  0
                                  Ошибаетесь. Пароль с русскими символами может быть.
                                    0
                                    Мне почему-то не удалось сменить пароль на русский. Как и зарегистрировать аккаунт с русскими буквами в пароле.
                                      0
                                      Ладно. Не важно это. Делайте как нравится — так даже правильнее будет. Надежнее
                                        0
                                        Примите мои извинения. Действительно запрещено русские символы в пароле использовать :-)
                              +1
                              А чем Вам не нравится браузерный JS? Язык как язык.
                                0
                                Вполе нравится, просто уточнял. Если удастся портировать — это ведь будет замечательно. Не придется даже отправлять логин с паролем на сервер.
                                  0
                                  В рамках данного блога портирование именно на JS планируется, дабы не завязываться на конкретную платформу.
                            0
                            Ура, все работает! :-)
                            Спасибо!
                              0
                              Вам удалось портировать на другой язык?
                                0
                                Нет, я пока добрался только до GAE, о портировании еще не задумывался. Да и если буду портировать, разве что только на Tcl, других языков не знаю совсем. :(
                              0
                              Что эта строчка делает? ЧТО-то не очень понимаю =)?
                              tmp = [tmp[i] ^ prev_crypted[i] for i in range(0,len(tmp))]
                                +1
                                Побитный XOR с результатами, полученными на предыдущем шаге. Для первого шага с нулем
                                  0
                                  Вау =))) А я понять не мог, как возведение в степень ноль дает тоже самое число :-)))
                                    0
                                    тяжко Пайтон скрипт переделывать на JS :-) Производительность при замене pow(256, x, N) на (pow(256, x)%N) падает раз в 10-20 :-)
                                      +1
                                      НЕ НАДО делать такую замену — это ниразу не равнозначные алгоритмы! 10-20 раз это вам повезло.

                                      www.leemon.com/crypto/BigInt.js

                                      В этой и других библиотеках для реализации bigint есть специальная встроенная функция.
                                        0
                                        Вкрадце разница:

                                        pow(256,x,N) все промежуточные вычисления приводит к остатку по модулю N. Соответственно всегда манипулирует числами меньше N

                                        pow(256, x) тупо вычисляет степень. При этом ему придется манипулировать целыми числами длинной в несколько тысяч/миллионов знаков.
                                          0
                                          Почти дописал… Дошел до этапа
                                           print hex_out.decode("hex").encode("base64").replace("\n","")


                                          Строка hex_out из JS и Py скрипта совпадает.

                                          Но, скрипт для декодирования из HEX и последующим кодированием в BAse64 не могу нормальный найти.

                                          Тут взял функцию для декодирования hex: farhadi.ir/works/hex
                                          Тут для Base64: farhadi.ir/works/base64

                                          Результат JS и Py различный получается :/
                                          0
                                          Сорри.
                                          Нижний регистр решил проблему :)

                                          base64Encode(hexDecode(hex_out.toLowerCase()))

                                          Портировал Ваш скрипт на JS :-)

                                          Завтра почищу его и выложу.
                                            0
                                            Теперь портирование на PHP не кажется таким страшным? )
                                              0
                                              Признаюсь, не вижу практического смысла от портировании на PHP.

                                              Во вторых, Вы сами сказали:
                                              >Кстати мой код будет работать (наверное) только с текущей длиной ключа. Если изменится, то нужно будет мелочь пофиксить.

                                              Поэтому, создавать то, что нужно будет поддерживать в плане доработки, но использоваться мной не будет — не очень хочется.

                                              PHP это скорее серверный язык. И даже более логично портировать на просто Java, чем на PHP. Из PHP я в данный момент запускаю exec('encrypt key str') и доволен.

                                              JS вариант я с радостью буду поддерживать. Думаю надо на code.google разместить его будет.
                                                0
                                                Да я просто вспомнил ваше сообщение

                                                > на php не удалось портировать. очень сложно сопоставлять типы данных.

                                                и решил подколоть.

                                                По поводу длинны ключа — единственное, что может понадобиться изменить — строчку:
                                                hex_out += («0» if len(tmp) < 16 else "") + ("%x" % (len(tmp)*256)) + «4000» + hex_result
                                                Было лень вводить лишние константы.
                                                  0
                                                  256 это длина ключа, которая в данный момент используется. Я прав?
                                                    0
                                                    Вообще длина ключа 512. Но тут выяснилась проблема — запустил тест, запрашивающий ключи с яндекса и сравнивающий вывод моего скрипта и яндексовского encrypt.
                                                    На 1000 ключей нашлось 4 несовпадения. Где-то не учел что-то. Буду править.
                                                      0
                                                      Надо бы мой JS аналог прогнать и сравнить результаты потом :-)

                                                      У Вас случайно не сохранились эти ключи?
                              0
                              Надо бы мой JS аналог прогнать и сравнить результаты потом :-)

                              У Вас случайно не сохранились эти ключи?
                                +1
                                Ключ
                                81DA1AD21759F9B8160F737E717482C56AB7BBCA2A9280B223FD8283C5CCD286E7CAF4F765954B0B4BD0746DB040CD226E444E50567AF6563F964006A9A81D9F#10001

                                Строка
                                6dc8373faa9a424988341d3f2

                                В питон варианте для лечения бага заменил строку
                                if len(hex_result) % 2 == 1: hex_result = "0" + hex_result
                                на
                                hex_result = "".join(['0']*( len(NSTR)- len(hex_result))) + hex_result

                                Потестил ключи длиннее — работает вроде (только «4000» заменил на соответствующее вычисление этой костанты). Косяки с ключами короче текущего, что ожидаемо — я не копировал алгоритм яндекса, а пытался его воспроизвести с использованием стандартных для всех языков типов «строка» и «число» — мог где-то и не учесть варианты для других длин ключа.
                                  +1
                                  упс. строка была «6dc8373faa9a424988341d3f25ffeaec». Обрезалась при копировании из putty
                                    0
                                    Благодарю. :-) Внес соответствующие правки.

                                    А где-то исходник вашего актуального скрипта можно посмотреть? Думаю себе тоже 4000 заменить на вычисляемое число :-)
                                      +1
                                      #-*- coding:utf-8 -*-

                                      import sys, copy

                                      if __name__ == '__main__':
                                        if len(sys.argv) != 3 : print "usage: python %s <public-key> <text>" % sys.argv[0]; sys.exit()
                                        NSTR,ESTR = sys.argv[1].split("#")
                                        DATA_ARR = [ord(x) for x in sys.argv[2]]
                                        N,E,STEP_SIZE = int(NSTR,16),int(ESTR,16), len(NSTR)/2-1
                                        
                                        prev_crypted = [0]*STEP_SIZE
                                        
                                        hex_out = ""
                                        for i in range(0,(len(DATA_ARR)-1)/STEP_SIZE+1):
                                          tmp = DATA_ARR[i*STEP_SIZE:(i+1)*STEP_SIZE]
                                          tmp = [tmp[i] ^ prev_crypted[i] for i in range(0,len(tmp))]
                                          tmp.reverse()
                                          plain = 0
                                          for x in range(0,len(tmp)): plain+= tmp[x]*pow(256, x, N)
                                          hex_result = "%x" % pow(plain,E,N)
                                          hex_result = "".join(['0']*( len(NSTR)- len(hex_result))) + hex_result

                                          for x in range(0,min(len(hex_result),len(prev_crypted)*2),2):
                                            prev_crypted[x/2] = int(hex_result[x:x+2],16)
                                            
                                          hex_out += ("0" if len(tmp) < 16 else "") + ("%x" % len(tmp)) + "00" # current size
                                          ks = len(NSTR)/2
                                          hex_out += ("0" if ks < 16 else "") + ("%x" % ks) + "00" # key size
                                          hex_out += hex_result

                                        print hex_out.decode("hex").encode("base64").replace("\n","")


                                        0
                                        Может напишешь пост про свой скрипт?
                                          0
                                          Лучше ты пиши про свой — он сложнее (ввиду отсутствия базовой поддержки больших чисел в js, base64 и тд). Мне лень. Мой можешь вставлять и использовать как хочешь.
                                  0
                                  Понял почему, не работает для более мелких ключей. У яндекса библиотека с альтернативной математикой.

                                  Для мелких чисел периодически библиотека яндекса вычисляет неверно:

                                  Например:
                                  p = 3486775
                                  e = 65537
                                  n = 2279134640

                                  По мнению яндекса (p^e) mod n будет равно 1853620120

                                  По мнению всего остального человечества это равно 361606135.

                                  На больших числах вроде ошибок не было.

                                  Так что я могу воспроизвести алгоритм шифрации (и воспроизвел), но воспроизводить ошибки я не хочу.
                                    0
                                    Рома, ты как всегда гениален: о)
                                  0
                                  Это написали за меня. Жду готового xpi.
                                  Пожелания:
                                  1. Выложить код на GitHub для социального кодинга.
                                  2. При вставке картинки html прописывать пустой alt и высоту с шириной.
                                    0
                                    С ГитХаб что-то у меня непонимание. Зарегистрировался, но там только команды для юниксов. про виндовс клиент ни слова )
                                      0
                                      В тему про ГитХаб.
                                      habrahabr.ru/blogs/sfworld/83550/

                                      Есть еще идеи и нужно ли это вообще?
                                        0
                                        Нужен ли паблик репозиторий — нет. Достаточно самого расширения.
                                        Нужен ли проект — очень.
                                          0
                                          Я стараюсь как могу.

                                          Альфа версия готова.
                                          Но, в ней не работает определение шаблонов по адресам сйатов. т.е. нужно будет в альфе выбирать самоум шаблон :-)

                                          Сегодня в течение дня загружу на мозилу =)
                                      0
                                      так где взять плагин что бы потестить?

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

                                    Самое читаемое